[rtems commit] bsp/atsam: Move XDMA IRQ handler to XDMA module

Sebastian Huber sebh at rtems.org
Thu Dec 15 10:05:31 UTC 2016


Module:    rtems
Branch:    master
Commit:    d1c771cc8b1988916f1eb926986d9ab74873ba37
Changeset: http://git.rtems.org/rtems/commit/?id=d1c771cc8b1988916f1eb926986d9ab74873ba37

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Dec 15 09:56:12 2016 +0100

bsp/atsam: Move XDMA IRQ handler to XDMA module

The XDMA is shared by all DMA capable modules.  Placing the XDMA
interrupt handler into the SPI module is wrong.

---

 .../arm/atsam/libraries/libchip/include/xdmad.h    |   4 +-
 .../arm/atsam/libraries/libchip/source/xdmad.c     | 125 +++++----
 c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c     | 311 +++++++++------------
 c/src/lib/libbsp/shared/include/fatal.h            |   5 +-
 4 files changed, 203 insertions(+), 242 deletions(-)

diff --git a/c/src/lib/libbsp/arm/atsam/libraries/libchip/include/xdmad.h b/c/src/lib/libbsp/arm/atsam/libraries/libchip/include/xdmad.h
index 37d9b94..5d4d424 100644
--- a/c/src/lib/libbsp/arm/atsam/libraries/libchip/include/xdmad.h
+++ b/c/src/lib/libbsp/arm/atsam/libraries/libchip/include/xdmad.h
@@ -225,7 +225,7 @@ typedef struct _LinkedListDescriporView3 {
 extern void XDMAD_Initialize(sXdmad *pXdmad,
 							  uint8_t bPollingMode);
 
-extern void XDMAD_Handler(sXdmad *pDmad);
+extern void XDMAD_Handler(void *arg);
 
 extern uint32_t XDMAD_AllocateChannel(sXdmad *pXdmad,
 									   uint8_t bSrcID, uint8_t bDstID);
@@ -244,6 +244,8 @@ extern eXdmadRC XDMAD_IsTransferDone(sXdmad *pXdmad, uint32_t dwChannel);
 
 extern eXdmadRC XDMAD_StartTransfer(sXdmad *pXdmad, uint32_t dwChannel);
 
+extern void XDMAD_DoNothingCallback(uint32_t Channel, void *pArg);
+
 extern eXdmadRC XDMAD_SetCallback(sXdmad *pXdmad,
 								   uint32_t dwChannel,
 								   XdmadTransferCallback fCallback,
diff --git a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c
index 972b0e7..a2dd3a7 100644
--- a/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c
+++ b/c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c
@@ -64,6 +64,8 @@
 #include "chip.h"
 #ifdef __rtems__
 #include "../../../utils/utility.h"
+#include <rtems/irq-extension.h>
+#include <bsp/fatal.h>
 #endif /* __rtems__ */
 #include <assert.h>
 static uint8_t xDmad_Initialized = 0;
@@ -129,6 +131,11 @@ static uint32_t XDMAD_AllocateXdmacChannel(sXdmad *pXdmad,
 	return XDMAD_ALLOC_FAILED;
 }
 
+void XDMAD_DoNothingCallback(uint32_t Channel, void *pArg)
+{
+	/* Do nothing */
+}
+
 /*----------------------------------------------------------------------------
  *        Exported functions
  *----------------------------------------------------------------------------*/
@@ -144,6 +151,7 @@ void XDMAD_Initialize(sXdmad *pXdmad, uint8_t bPollingMode)
 {
 	uint32_t j;
 	uint32_t volatile timer = 0x7FF;
+	rtems_status_code sc;
 
 	assert(pXdmad);
 	LockMutex(pXdmad->xdmaMutex, timer);
@@ -159,16 +167,18 @@ void XDMAD_Initialize(sXdmad *pXdmad, uint8_t bPollingMode)
 	pXdmad->numChannels    = (XDMAC_GTYPE_NB_CH(XDMAC_GetType(XDMAC)) + 1);
 
 	for (j = 0; j < pXdmad->numChannels; j ++) {
-		pXdmad->XdmaChannels[j].fCallback = 0;
-		pXdmad->XdmaChannels[j].pArg      = 0;
-		pXdmad->XdmaChannels[j].bIrqOwner    = 0;
-		pXdmad->XdmaChannels[j].bSrcPeriphID = 0;
-		pXdmad->XdmaChannels[j].bDstPeriphID = 0;
-		pXdmad->XdmaChannels[j].bSrcTxIfID   = 0;
-		pXdmad->XdmaChannels[j].bSrcRxIfID   = 0;
-		pXdmad->XdmaChannels[j].bDstTxIfID   = 0;
-		pXdmad->XdmaChannels[j].bDstRxIfID   = 0;
-		pXdmad->XdmaChannels[j].state = XDMAD_STATE_FREE;
+		pXdmad->XdmaChannels[j].fCallback = XDMAD_DoNothingCallback;
+	}
+
+	sc = rtems_interrupt_handler_install(
+		ID_XDMAC,
+		"XDMA",
+		RTEMS_INTERRUPT_UNIQUE,
+		XDMAD_Handler,
+		pXdmad
+	);
+	if (sc != RTEMS_SUCCESSFUL) {
+		bsp_fatal(ATSAM_FATAL_XDMA_IRQ_INSTALL);
 	}
 
 	xDmad_Initialized = 1;
@@ -302,79 +312,74 @@ eXdmadRC XDMAD_PrepareChannel(sXdmad *pXdmad, uint32_t dwChannel)
 
 /**
  * \brief xDMA interrupt handler
- * \param pxDmad Pointer to DMA driver instance.
+ * \param arg Pointer to DMA driver instance.
  */
-void XDMAD_Handler(sXdmad *pDmad)
+void XDMAD_Handler(void *arg)
 {
+	sXdmad *pDmad;
 	Xdmac *pXdmac;
 	sXdmadChannel *pCh;
 	uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus, xdmaGlobalChStatus;
-	uint8_t bExec = 0;
+	uint8_t bExec;
 	uint8_t _iChannel;
-	assert(pDmad != NULL);
 
+	pDmad = arg;
 	pXdmac = pDmad->pXdmacs;
-	xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac);
-
-	if ((xdmaGlobaIntStatus & 0xFFFFFF) != 0) {
-		xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);
+	xdmaGlobaIntStatus = XDMAC_GetGIsr(pXdmac) & 0xFFFFFF;
+	xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(pXdmac);
 
-		for (_iChannel = 0; _iChannel < pDmad->numChannels; _iChannel ++) {
-			if (!(xdmaGlobaIntStatus & (1 << _iChannel))) continue;
+	while (xdmaGlobaIntStatus != 0) {
+		_iChannel = 31 - __builtin_clz(xdmaGlobaIntStatus);
+		xdmaGlobaIntStatus &= ~(UINT32_C(1) << _iChannel);
 
-			pCh = &pDmad->XdmaChannels[_iChannel];
+		pCh = &pDmad->XdmaChannels[_iChannel];
+		bExec = 0;
 
-			if (pCh->state == XDMAD_STATE_FREE) return;
+		if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << _iChannel)) == 0) {
+			xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(pXdmac, _iChannel);
 
-			if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << _iChannel)) == 0) {
-				bExec = 0;
-				xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(pXdmac, _iChannel);
-
-				if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
-					if ((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM)
-						== 0) {
-						pCh->state = XDMAD_STATE_DONE;
-						bExec = 1;
-					}
-
-					TRACE_DEBUG("XDMAC_CIS_BIS\n\r");
+			if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
+				if ((XDMAC_GetChannelItMask(pXdmac, _iChannel) & XDMAC_CIM_LIM) == 0) {
+					pCh->state = XDMAD_STATE_DONE;
+					bExec = 1;
 				}
 
-				if (xdmaChannelIntStatus & XDMAC_CIS_FIS)
-					TRACE_DEBUG("XDMAC_CIS_FIS\n\r");
+				TRACE_DEBUG("XDMAC_CIS_BIS\n\r");
+			}
 
-				if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS)
-					TRACE_DEBUG("XDMAC_CIS_RBEIS\n\r");
+			if (xdmaChannelIntStatus & XDMAC_CIS_FIS)
+				TRACE_DEBUG("XDMAC_CIS_FIS\n\r");
 
-				if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS)
-					TRACE_DEBUG("XDMAC_CIS_WBEIS\n\r");
+			if (xdmaChannelIntStatus & XDMAC_CIS_RBEIS)
+				TRACE_DEBUG("XDMAC_CIS_RBEIS\n\r");
 
-				if (xdmaChannelIntStatus & XDMAC_CIS_ROIS)
-					TRACE_DEBUG("XDMAC_CIS_ROIS\n\r");
+			if (xdmaChannelIntStatus & XDMAC_CIS_WBEIS)
+				TRACE_DEBUG("XDMAC_CIS_WBEIS\n\r");
 
-				if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
-					TRACE_DEBUG("XDMAC_CIS_LIS\n\r");
-					pCh->state = XDMAD_STATE_DONE;
-					bExec = 1;
-				}
+			if (xdmaChannelIntStatus & XDMAC_CIS_ROIS)
+				TRACE_DEBUG("XDMAC_CIS_ROIS\n\r");
 
-				if (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
-					pCh->state = XDMAD_STATE_DONE;
-					bExec = 1;
-				}
+			if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
+				TRACE_DEBUG("XDMAC_CIS_LIS\n\r");
+				pCh->state = XDMAD_STATE_DONE;
+				bExec = 1;
+			}
 
-			} else {
-				/* Block end interrupt for LLI dma mode */
-				if (XDMAC_GetChannelIsr(pXdmac, _iChannel) & XDMAC_CIS_BIS) {
-					/* Execute callback */
-					pCh->fCallback(_iChannel, pCh->pArg);
-				}
+			if (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
+				pCh->state = XDMAD_STATE_DONE;
+				bExec = 1;
 			}
 
-			/* Execute callback */
-			if (bExec && pCh->fCallback)
-				pCh->fCallback(_iChannel, pCh->pArg);
+		} else {
+			/* Block end interrupt for LLI dma mode */
+			if (XDMAC_GetChannelIsr(pXdmac, _iChannel) & XDMAC_CIS_BIS) {
+				bExec = 1;
+			}
 		}
+
+		/* Execute callback */
+		if (bExec)
+			pCh->fCallback(_iChannel, pCh->pArg);
 	}
 }
 
diff --git a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
index 2bc6166..77a1e9b 100644
--- a/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
+++ b/c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c
@@ -30,16 +30,10 @@
 
 #include <bsp/atsam-spi.h>
 
-#include <rtems/irq-extension.h>
-
 #include <dev/spi/spi.h>
 
 #define MAX_SPI_FREQUENCY 50000000
 
-#define TX_IN_PROGRESS 0x1
-
-#define RX_IN_PROGRESS 0x2
-
 typedef struct {
   spi_bus base;
   bool msg_cs_change;
@@ -51,7 +45,7 @@ typedef struct {
   Spid SpiDma;
   uint32_t dma_tx_channel;
   uint32_t dma_rx_channel;
-  int transfer_status;
+  int transfer_in_progress;
   bool chip_select_active;
 } atsam_spi_bus;
 
@@ -120,93 +114,6 @@ static void atsam_configure_spi(atsam_spi_bus *bus)
   SPI_ConfigureNPCS(bus->SpiDma.pSpiHw, bus->base.cs, csr);
 }
 
-static void atsam_spi_init_xdma(atsam_spi_bus *bus)
-{
-  sXdmadCfg cfg;
-  uint32_t xdmaInt;
-  uint8_t channel;
-  eXdmadRC rc;
-
-  bus->dma_tx_channel = XDMAD_AllocateChannel(
-    &bus->xdma,
-    XDMAD_TRANSFER_MEMORY,
-    bus->SpiDma.spiId
-  );
-  assert(bus->dma_tx_channel != XDMAD_ALLOC_FAILED);
-
-  bus->dma_rx_channel = XDMAD_AllocateChannel(
-    &bus->xdma,
-    bus->SpiDma.spiId,
-    XDMAD_TRANSFER_MEMORY
-  );
-  assert(bus->dma_rx_channel != XDMAD_ALLOC_FAILED);
-
-  rc = XDMAD_PrepareChannel(&bus->xdma, bus->dma_rx_channel);
-  assert(rc == XDMAD_OK);
-
-  rc = XDMAD_PrepareChannel(&bus->xdma, bus->dma_tx_channel);
-  assert(rc == XDMAD_OK);
-
-  /* Put all interrupts on for non LLI list setup of DMA */
-  xdmaInt =  (
-    XDMAC_CIE_BIE |
-    XDMAC_CIE_DIE |
-    XDMAC_CIE_FIE |
-    XDMAC_CIE_RBIE |
-    XDMAC_CIE_WBIE |
-    XDMAC_CIE_ROIE);
-
-  /* Setup RX */
-  memset(&cfg, 0, sizeof(cfg));
-  channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_RX);
-  cfg.mbr_sa = (uint32_t)&bus->SpiDma.pSpiHw->SPI_RDR;
-  cfg.mbr_cfg =
-    XDMAC_CC_TYPE_PER_TRAN |
-    XDMAC_CC_MBSIZE_SINGLE |
-    XDMAC_CC_DSYNC_PER2MEM |
-    XDMAC_CC_CSIZE_CHK_1 |
-    XDMAC_CC_DWIDTH_BYTE |
-    XDMAC_CC_SIF_AHB_IF1 |
-    XDMAC_CC_DIF_AHB_IF1 |
-    XDMAC_CC_SAM_FIXED_AM |
-    XDMAC_CC_DAM_INCREMENTED_AM |
-    XDMAC_CC_PERID(channel);
-  rc = XDMAD_ConfigureTransfer(
-    &bus->xdma,
-    bus->dma_rx_channel,
-    &cfg,
-    0,
-    0,
-    xdmaInt
-  );
-  assert(rc == XDMAD_OK);
-
-  /* Setup TX  */
-  memset(&cfg, 0, sizeof(cfg));
-  channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_TX);
-  cfg.mbr_da = (uint32_t)&bus->SpiDma.pSpiHw->SPI_TDR;
-  cfg.mbr_cfg =
-    XDMAC_CC_TYPE_PER_TRAN |
-    XDMAC_CC_MBSIZE_SINGLE |
-    XDMAC_CC_DSYNC_MEM2PER |
-    XDMAC_CC_CSIZE_CHK_1 |
-    XDMAC_CC_DWIDTH_BYTE |
-    XDMAC_CC_SIF_AHB_IF1 |
-    XDMAC_CC_DIF_AHB_IF1 |
-    XDMAC_CC_SAM_INCREMENTED_AM |
-    XDMAC_CC_DAM_FIXED_AM |
-    XDMAC_CC_PERID(channel);
-  rc = XDMAD_ConfigureTransfer(
-    &bus->xdma,
-    bus->dma_tx_channel,
-    &cfg,
-    0,
-    0,
-    xdmaInt
-  );
-  assert(rc == XDMAD_OK);
-}
-
 static void atsam_spi_start_dma_transfer(
   atsam_spi_bus *bus,
   const spi_ioc_transfer *msg
@@ -272,7 +179,7 @@ static void atsam_spi_setup_transfer(atsam_spi_bus *bus)
 {
   uint32_t msg_todo = bus->msg_todo;
 
-  bus->transfer_status = RX_IN_PROGRESS | TX_IN_PROGRESS;
+  bus->transfer_in_progress = 2;
 
   if (bus->msg_cs_change) {
     bus->chip_select_active = false;
@@ -300,70 +207,14 @@ static void atsam_spi_setup_transfer(atsam_spi_bus *bus)
   }
 }
 
-static void atsam_spi_interrupt(void *arg)
+static void atsam_spi_dma_callback(uint32_t channel, void *arg)
 {
   atsam_spi_bus *bus = (atsam_spi_bus *)arg;
-  sXdmad *xdma = &bus->xdma;
-  Spid *spid = &bus->SpiDma;
-  Xdmac *xdmac;
-  sXdmadChannel *ch;
-  uint32_t xdmaChannelIntStatus, xdmaGlobaIntStatus, xdmaGlobalChStatus;
-  uint8_t channel;
-  uint8_t bExec = 0;
-  assert(xdma != NULL);
 
-  xdmac = xdma->pXdmacs;
-  xdmaGlobaIntStatus = XDMAC_GetGIsr(xdmac) & 0xFFFFFF;
-  xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(xdmac);
-
-  while (xdmaGlobaIntStatus != 0) {
-    channel = 31 - __builtin_clz(xdmaGlobaIntStatus);
-    xdmaGlobaIntStatus &= ~(UINT32_C(1) << channel);
-
-    ch = &xdma->XdmaChannels[channel];
-
-    if (ch->state == XDMAD_STATE_FREE) {
-      continue;
-    }
-
-    if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << channel)) == 0) {
-      bExec = 0;
-      xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(xdmac, channel);
-
-      if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
-        if ((XDMAC_GetChannelItMask(xdmac, channel) & XDMAC_CIM_LIM) == 0) {
-          ch->state = XDMAD_STATE_DONE;
-          bExec = 1;
-        }
-      }
-
-      if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
-        ch->state = XDMAD_STATE_DONE;
-        bExec = 1;
-      }
-
-      if (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
-        ch->state = XDMAD_STATE_DONE;
-        bExec = 1;
-      }
-
-    } else {
-      /* Block end interrupt for LLI dma mode */
-      if (XDMAC_GetChannelIsr(xdmac, channel) & XDMAC_CIS_BIS) {
-      }
-    }
+  --bus->transfer_in_progress;
 
-    if (bExec == 1 && (channel == bus->dma_rx_channel)) {
-      bus->transfer_status &= ~RX_IN_PROGRESS;
-      XDMAC_DisableGIt(spid->pXdmad->pXdmacs, bus->dma_rx_channel);
-    } else if (bExec == 1 && (channel == bus->dma_tx_channel)) {
-      bus->transfer_status &= ~TX_IN_PROGRESS;
-      XDMAC_DisableGIt(spid->pXdmad->pXdmacs, bus->dma_tx_channel);
-    }
-
-    if (bus->transfer_status == 0) {
-      atsam_spi_setup_transfer(bus);
-    }
+  if (bus->transfer_in_progress == 0) {
+    atsam_spi_setup_transfer(bus);
   }
 }
 
@@ -389,14 +240,26 @@ static int atsam_spi_transfer(
 static void atsam_spi_destroy(spi_bus *base)
 {
   atsam_spi_bus *bus = (atsam_spi_bus *)base;
-  rtems_status_code sc;
+  eXdmadRC rc;
 
-  /* Free XDMAD Channels */
-  XDMAD_FreeChannel(bus->SpiDma.pXdmad, 0);
-  XDMAD_FreeChannel(bus->SpiDma.pXdmad, 1);
+  rc = XDMAD_SetCallback(
+    &bus->xdma,
+    bus->dma_rx_channel,
+    XDMAD_DoNothingCallback,
+    NULL
+  );
+  assert(rc == XDMAD_OK);
 
-  sc = rtems_interrupt_handler_remove(ID_XDMAC, atsam_spi_interrupt, bus);
-  assert(sc == RTEMS_SUCCESSFUL);
+  rc = XDMAD_SetCallback(
+    &bus->xdma,
+    bus->dma_tx_channel,
+    XDMAD_DoNothingCallback,
+    NULL
+  );
+  assert(rc == XDMAD_OK);
+
+  XDMAD_FreeChannel(bus->SpiDma.pXdmad, bus->dma_rx_channel);
+  XDMAD_FreeChannel(bus->SpiDma.pXdmad, bus->dma_tx_channel);
 
   SPI_Disable(bus->SpiDma.pSpiHw);
   PMC_DisablePeripheral(bus->SpiDma.spiId);
@@ -419,6 +282,109 @@ static int atsam_spi_setup(spi_bus *base)
   return 0;
 }
 
+static void atsam_spi_init_xdma(atsam_spi_bus *bus)
+{
+  sXdmadCfg cfg;
+  uint32_t xdmaInt;
+  uint8_t channel;
+  eXdmadRC rc;
+
+  bus->dma_tx_channel = XDMAD_AllocateChannel(
+    &bus->xdma,
+    XDMAD_TRANSFER_MEMORY,
+    bus->SpiDma.spiId
+  );
+  assert(bus->dma_tx_channel != XDMAD_ALLOC_FAILED);
+
+  bus->dma_rx_channel = XDMAD_AllocateChannel(
+    &bus->xdma,
+    bus->SpiDma.spiId,
+    XDMAD_TRANSFER_MEMORY
+  );
+  assert(bus->dma_rx_channel != XDMAD_ALLOC_FAILED);
+
+  rc = XDMAD_SetCallback(
+    &bus->xdma,
+    bus->dma_rx_channel,
+    atsam_spi_dma_callback,
+    bus
+  );
+  assert(rc == XDMAD_OK);
+
+  rc = XDMAD_SetCallback(
+    &bus->xdma,
+    bus->dma_tx_channel,
+    atsam_spi_dma_callback,
+    bus
+  );
+  assert(rc == XDMAD_OK);
+
+  rc = XDMAD_PrepareChannel(&bus->xdma, bus->dma_rx_channel);
+  assert(rc == XDMAD_OK);
+
+  rc = XDMAD_PrepareChannel(&bus->xdma, bus->dma_tx_channel);
+  assert(rc == XDMAD_OK);
+
+  /* Put all interrupts on for non LLI list setup of DMA */
+  xdmaInt =  (
+    XDMAC_CIE_BIE |
+    XDMAC_CIE_DIE |
+    XDMAC_CIE_FIE |
+    XDMAC_CIE_RBIE |
+    XDMAC_CIE_WBIE |
+    XDMAC_CIE_ROIE);
+
+  /* Setup RX */
+  memset(&cfg, 0, sizeof(cfg));
+  channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_RX);
+  cfg.mbr_sa = (uint32_t)&bus->SpiDma.pSpiHw->SPI_RDR;
+  cfg.mbr_cfg =
+    XDMAC_CC_TYPE_PER_TRAN |
+    XDMAC_CC_MBSIZE_SINGLE |
+    XDMAC_CC_DSYNC_PER2MEM |
+    XDMAC_CC_CSIZE_CHK_1 |
+    XDMAC_CC_DWIDTH_BYTE |
+    XDMAC_CC_SIF_AHB_IF1 |
+    XDMAC_CC_DIF_AHB_IF1 |
+    XDMAC_CC_SAM_FIXED_AM |
+    XDMAC_CC_DAM_INCREMENTED_AM |
+    XDMAC_CC_PERID(channel);
+  rc = XDMAD_ConfigureTransfer(
+    &bus->xdma,
+    bus->dma_rx_channel,
+    &cfg,
+    0,
+    0,
+    xdmaInt
+  );
+  assert(rc == XDMAD_OK);
+
+  /* Setup TX  */
+  memset(&cfg, 0, sizeof(cfg));
+  channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_TX);
+  cfg.mbr_da = (uint32_t)&bus->SpiDma.pSpiHw->SPI_TDR;
+  cfg.mbr_cfg =
+    XDMAC_CC_TYPE_PER_TRAN |
+    XDMAC_CC_MBSIZE_SINGLE |
+    XDMAC_CC_DSYNC_MEM2PER |
+    XDMAC_CC_CSIZE_CHK_1 |
+    XDMAC_CC_DWIDTH_BYTE |
+    XDMAC_CC_SIF_AHB_IF1 |
+    XDMAC_CC_DIF_AHB_IF1 |
+    XDMAC_CC_SAM_INCREMENTED_AM |
+    XDMAC_CC_DAM_FIXED_AM |
+    XDMAC_CC_PERID(channel);
+  rc = XDMAD_ConfigureTransfer(
+    &bus->xdma,
+    bus->dma_tx_channel,
+    &cfg,
+    0,
+    0,
+    xdmaInt
+  );
+  assert(rc == XDMAD_OK);
+}
+
 int spi_bus_register_atsam(
   const char *bus_path,
   uint8_t     spi_peripheral_id,
@@ -428,13 +394,16 @@ int spi_bus_register_atsam(
 )
 {
   atsam_spi_bus *bus;
-  rtems_status_code sc;
 
   bus = (atsam_spi_bus *) spi_bus_alloc_and_init(sizeof(*bus));
   if (bus == NULL) {
     return -1;
   }
 
+  bus->base.transfer = atsam_spi_transfer;
+  bus->base.destroy = atsam_spi_destroy;
+  bus->base.setup = atsam_spi_setup;
+  bus->base.max_speed_hz = MAX_SPI_FREQUENCY;
   bus->base.bits_per_word = 8;
   bus->base.speed_hz = bus->base.max_speed_hz;
   bus->base.delay_usecs = 1;
@@ -448,23 +417,5 @@ int spi_bus_register_atsam(
   atsam_configure_spi(bus);
   atsam_spi_init_xdma(bus);
 
-  sc = rtems_interrupt_handler_install(
-    ID_XDMAC,
-    "SPI",
-    RTEMS_INTERRUPT_UNIQUE,
-    atsam_spi_interrupt,
-    bus
-  );
-  if (sc != RTEMS_SUCCESSFUL) {
-    (*bus->base.destroy)(&bus->base);
-
-    rtems_set_errno_and_return_minus_one(EIO);
-  }
-
-  bus->base.transfer = atsam_spi_transfer;
-  bus->base.destroy = atsam_spi_destroy;
-  bus->base.setup = atsam_spi_setup;
-  bus->base.max_speed_hz = MAX_SPI_FREQUENCY;
-
   return spi_bus_register(&bus->base, bus_path);
 }
diff --git a/c/src/lib/libbsp/shared/include/fatal.h b/c/src/lib/libbsp/shared/include/fatal.h
index fdb7797..1336c78 100644
--- a/c/src/lib/libbsp/shared/include/fatal.h
+++ b/c/src/lib/libbsp/shared/include/fatal.h
@@ -124,7 +124,10 @@ typedef enum {
   QORIQ_FATAL_FDT_NO_TIMEBASE_FREQUENCY,
   QORIQ_FATAL_RESTART_FAILED,
   QORIQ_FATAL_RESTART_INSTALL_INTERRUPT,
-  QORIQ_FATAL_RESTART_INTERRUPT_FAILED
+  QORIQ_FATAL_RESTART_INTERRUPT_FAILED,
+
+  /* ATSAM fatal codes */
+  ATSAM_FATAL_XDMA_IRQ_INSTALL = BSP_FATAL_CODE_BLOCK(11)
 } bsp_fatal_code;
 
 RTEMS_NO_RETURN static inline void




More information about the vc mailing list