[rtems commit] bsp/atsam: Optimize SPI DMA transfer setup

Sebastian Huber sebh at rtems.org
Wed Dec 14 12:10:18 UTC 2016


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Dec 14 08:32:02 2016 +0100

bsp/atsam: Optimize SPI DMA transfer setup

---

 c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c | 121 ++++++++++---------------
 1 file 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 e18e1a8..cf4d446 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(



More information about the vc mailing list