summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-15 09:56:12 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-15 11:05:09 +0100
commitd1c771cc8b1988916f1eb926986d9ab74873ba37 (patch)
tree5e6f182ebe9f86090bf0c9eabcebf9479d234857
parentbsp/atsam: Use _Assert() instead of assert() (diff)
downloadrtems-d1c771cc8b1988916f1eb926986d9ab74873ba37.tar.bz2
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.
-rw-r--r--c/src/lib/libbsp/arm/atsam/libraries/libchip/include/xdmad.h4
-rw-r--r--c/src/lib/libbsp/arm/atsam/libraries/libchip/source/xdmad.c125
-rw-r--r--c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c311
-rw-r--r--c/src/lib/libbsp/shared/include/fatal.h5
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 37d9b94c67..5d4d424cea 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 972b0e7ec3..a2dd3a7458 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 2bc61665ea..77a1e9bb4f 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 fdb7797650..1336c78392 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