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

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


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

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

bsp/atsam: Simplify SPI DMA transfer setup

---

 c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c | 108 +++++++++----------------
 1 file changed, 38 insertions(+), 70 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 5160ec1..e18e1a8 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
@@ -205,27 +205,22 @@ static void atsam_spi_init_xdma(atsam_spi_bus *bus)
   assert(rc == XDMAD_OK);
 }
 
-static uint8_t atsam_configure_link_list(
-  Spi *pSpiHw,
-  void *pXdmad,
-  uint32_t dma_tx_channel,
-  uint32_t dma_rx_channel,
+static void atsam_spi_start_dma_transfer(
+  atsam_spi_bus *bus,
   const spi_ioc_transfer *msg
 )
 {
   sXdmadCfg xdmadRxCfg, xdmadTxCfg;
-  uint32_t xdmaCndc, xdmaInt;
-  uint32_t spiId;
-
-  if ((unsigned int)pSpiHw == (unsigned int)SPI0) spiId = ID_SPI0;
-
-  if ((unsigned int)pSpiHw == (unsigned int)SPI1) spiId = ID_SPI1;
+  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)&pSpiHw->SPI_TDR;
+  xdmadTxCfg.mbr_da = (uint32_t)&bus->SpiDma.pSpiHw->SPI_TDR;
 
   xdmadTxCfg.mbr_ubc =
     XDMA_UBC_NVIEW_NDV0 |
@@ -233,6 +228,7 @@ static uint8_t atsam_configure_link_list(
     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 |
@@ -243,7 +239,7 @@ static uint8_t atsam_configure_link_list(
     XDMAC_CC_DIF_AHB_IF1 |
     XDMAC_CC_SAM_INCREMENTED_AM |
     XDMAC_CC_DAM_FIXED_AM |
-    XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(spiId, XDMAD_TRANSFER_TX));
+    XDMAC_CC_PERID(tx_channel);
 
   xdmadTxCfg.mbr_bc = 0;
   xdmadTxCfg.mbr_sus = 0;
@@ -259,7 +255,9 @@ static uint8_t atsam_configure_link_list(
 
   xdmadRxCfg.mbr_da = (uint32_t)msg->rx_buf;
 
-  xdmadRxCfg.mbr_sa = (uint32_t)&pSpiHw->SPI_RDR;
+  xdmadRxCfg.mbr_sa = (uint32_t)&bus->SpiDma.pSpiHw->SPI_RDR;
+
+  rx_channel = XDMAIF_Get_ChannelNumber(bus->SpiDma.spiId, XDMAD_TRANSFER_RX);
   xdmadRxCfg.mbr_cfg =
     XDMAC_CC_TYPE_PER_TRAN |
     XDMAC_CC_MBSIZE_SINGLE |
@@ -270,14 +268,12 @@ static uint8_t atsam_configure_link_list(
     XDMAC_CC_DIF_AHB_IF1 |
     XDMAC_CC_SAM_FIXED_AM |
     XDMAC_CC_DAM_INCREMENTED_AM |
-    XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber(spiId, XDMAD_TRANSFER_RX));
+    XDMAC_CC_PERID(rx_channel);
 
   xdmadRxCfg.mbr_bc = 0;
   xdmadRxCfg.mbr_sus = 0;
   xdmadRxCfg.mbr_dus = 0;
 
-  xdmaCndc = 0;
-
   /* Put all interrupts on for non LLI list setup of DMA */
   xdmaInt =  (
     XDMAC_CIE_BIE |
@@ -287,68 +283,45 @@ static uint8_t atsam_configure_link_list(
     XDMAC_CIE_WBIE |
     XDMAC_CIE_ROIE);
 
-  if (
-    XDMAD_ConfigureTransfer(
-      pXdmad,
-      dma_rx_channel,
-      &xdmadRxCfg,
-      xdmaCndc,
-      0,
-      xdmaInt
-    )
-  ) {
-    return SPID_ERROR;
-  }
+  rc = XDMAD_ConfigureTransfer(
+    &bus->xdma,
+    bus->dma_rx_channel,
+    &xdmadRxCfg,
+    0,
+    0,
+    xdmaInt
+  );
+  assert(rc == XDMAD_OK);
 
-  if (
-    XDMAD_ConfigureTransfer(
-      pXdmad,
-      dma_tx_channel,
-      &xdmadTxCfg,
-      xdmaCndc,
-      0,
-      xdmaInt
-    )
-  ) {
-    return SPID_ERROR;
-  }
+  rc = XDMAD_ConfigureTransfer(
+    &bus->xdma,
+    bus->dma_tx_channel,
+    &xdmadTxCfg,
+    0,
+    0,
+    xdmaInt
+  );
+  assert(rc == XDMAD_OK);
 
-  return 0;
+  XDMAC_StartTransfer(bus->xdma.pXdmacs, bus->dma_rx_channel);
+  XDMAC_StartTransfer(bus->xdma.pXdmacs, bus->dma_tx_channel);
 }
 
-static uint32_t atsam_send_command(
+static void atsam_spi_do_transfer(
   atsam_spi_bus *bus,
   const spi_ioc_transfer *msg
 )
 {
-  Spid *spid = &bus->SpiDma;
-  Spi *pSpiHw = spid->pSpiHw;
-  Xdmac *pXdmac = bus->SpiDma.pXdmad->pXdmacs;
-
-  if (
-    atsam_configure_link_list(
-      pSpiHw,
-      spid->pXdmad,
-      bus->dma_tx_channel,
-      bus->dma_rx_channel,
-      msg
-    )
-  ) {
-    return SPID_ERROR_LOCK;
-  }
-
   if (!bus->chip_select_active){
+    Spi *pSpiHw = bus->SpiDma.pSpiHw;
+
     bus->chip_select_active = true;
 
     SPI_ChipSelect(pSpiHw, 1 << msg->cs);
     SPI_Enable(pSpiHw);
   }
 
-  /* Start DMA */
-  XDMAC_StartTransfer(pXdmac, bus->dma_rx_channel);
-  XDMAC_StartTransfer(pXdmac, bus->dma_tx_channel);
-
-  return 0;
+  atsam_spi_start_dma_transfer(bus, msg);
 }
 
 static int atsam_check_configure_spi(atsam_spi_bus *bus, const spi_ioc_transfer *msg)
@@ -385,7 +358,6 @@ static int atsam_spi_setup_transfer(atsam_spi_bus *bus)
   const spi_ioc_transfer *msgs = bus->msgs;
   uint32_t msg_todo = bus->msg_todo;
   uint32_t i;
-  uint32_t rv_command;
   int error;
 
   for (i = 0; i < msg_todo; ++i) {
@@ -394,11 +366,7 @@ static int atsam_spi_setup_transfer(atsam_spi_bus *bus)
       return error;
     }
 
-    rv_command = atsam_send_command(bus, &msgs[i]);
-    if (rv_command != 0) {
-      return -EIO;
-    }
-
+    atsam_spi_do_transfer(bus, &msgs[i]);
     rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
 
     bus->rx_transfer_done = false;



More information about the vc mailing list