summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-14 08:32:02 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-14 13:09:29 +0100
commitb52513b3a439853bf6cd6bcf92059b8924ac8d11 (patch)
tree06274b0d9690205396e76c7553de4364a9472b57
parentf104bd342f6981edbab8d8fc5e0336fa6b9d226b (diff)
downloadrtems-b52513b3a439853bf6cd6bcf92059b8924ac8d11.tar.bz2
bsp/atsam: Optimize SPI DMA transfer setup
-rw-r--r--c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c121
1 files changed, 48 insertions, 73 deletions
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 e18e1a8c69..cf4d4462e1 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
@@ -182,6 +182,9 @@ static void atsam_configure_spi(atsam_spi_bus *bus)
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(
@@ -203,62 +206,21 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus)
rc = XDMAD_PrepareChannel(&bus->xdma, bus->dma_tx_channel);
assert(rc == XDMAD_OK);
-}
-static void atsam_spi_start_dma_transfer(
- atsam_spi_bus *bus,
- const spi_ioc_transfer *msg
-)
-{
- sXdmadCfg xdmadRxCfg, xdmadTxCfg;
- uint32_t xdmaInt;
- uint8_t rx_channel;
- uint8_t tx_channel;
- eXdmadRC rc;
-
- /* Setup TX */
-
- xdmadTxCfg.mbr_sa = (uint32_t)msg->tx_buf;
-
- xdmadTxCfg.mbr_da = (uint32_t)&bus->SpiDma.pSpiHw->SPI_TDR;
-
- xdmadTxCfg.mbr_ubc =
- XDMA_UBC_NVIEW_NDV0 |
- XDMA_UBC_NDE_FETCH_DIS |
- XDMA_UBC_NSEN_UPDATED |
- msg->len;
-
- tx_channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_TX);
- xdmadTxCfg.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(tx_channel);
-
- xdmadTxCfg.mbr_bc = 0;
- xdmadTxCfg.mbr_sus = 0;
- xdmadTxCfg.mbr_dus = 0;
-
- /* Setup RX Link List */
-
- xdmadRxCfg.mbr_ubc =
- XDMA_UBC_NVIEW_NDV0 |
- XDMA_UBC_NDE_FETCH_DIS |
- XDMA_UBC_NDEN_UPDATED |
- msg->len;
-
- xdmadRxCfg.mbr_da = (uint32_t)msg->rx_buf;
-
- xdmadRxCfg.mbr_sa = (uint32_t)&bus->SpiDma.pSpiHw->SPI_RDR;
+ /* 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);
- rx_channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_RX);
- xdmadRxCfg.mbr_cfg =
+ /* 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 |
@@ -268,43 +230,56 @@ static void atsam_spi_start_dma_transfer(
XDMAC_CC_DIF_AHB_IF1 |
XDMAC_CC_SAM_FIXED_AM |
XDMAC_CC_DAM_INCREMENTED_AM |
- XDMAC_CC_PERID(rx_channel);
-
- xdmadRxCfg.mbr_bc = 0;
- xdmadRxCfg.mbr_sus = 0;
- xdmadRxCfg.mbr_dus = 0;
-
- /* 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);
-
+ XDMAC_CC_PERID(channel);
rc = XDMAD_ConfigureTransfer(
&bus->xdma,
bus->dma_rx_channel,
- &xdmadRxCfg,
+ &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,
- &xdmadTxCfg,
+ &cfg,
0,
0,
xdmaInt
);
assert(rc == XDMAD_OK);
+}
- XDMAC_StartTransfer(bus->xdma.pXdmacs, bus->dma_rx_channel);
- XDMAC_StartTransfer(bus->xdma.pXdmacs, bus->dma_tx_channel);
+static void atsam_spi_start_dma_transfer(
+ atsam_spi_bus *bus,
+ const spi_ioc_transfer *msg
+)
+{
+ Xdmac *pXdmac = bus->xdma.pXdmacs;
+
+ XDMAC_SetDestinationAddr(pXdmac, bus->dma_rx_channel, (uint32_t)msg->rx_buf);
+ XDMAC_SetSourceAddr(pXdmac, bus->dma_tx_channel, (uint32_t)msg->tx_buf);
+ XDMAC_SetMicroblockControl(pXdmac, bus->dma_rx_channel, msg->len);
+ XDMAC_SetMicroblockControl(pXdmac, bus->dma_tx_channel, msg->len);
+ XDMAC_StartTransfer(pXdmac, bus->dma_rx_channel);
+ XDMAC_StartTransfer(pXdmac, bus->dma_tx_channel);
}
static void atsam_spi_do_transfer(