summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/atsam
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 /c/src/lib/libbsp/arm/atsam
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.
Diffstat (limited to 'c/src/lib/libbsp/arm/atsam')
-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
3 files changed, 199 insertions, 241 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);
}