[rtems commit] bsp/atsam: Optimize SPI interrupt

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


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

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

bsp/atsam: Optimize SPI interrupt

---

 c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c | 76 ++++++++++++--------------
 1 file changed, 36 insertions(+), 40 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 7c3855d..2bc6166 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
@@ -313,61 +313,57 @@ static void atsam_spi_interrupt(void *arg)
   assert(xdma != NULL);
 
   xdmac = xdma->pXdmacs;
-  xdmaGlobaIntStatus = XDMAC_GetGIsr(xdmac);
+  xdmaGlobaIntStatus = XDMAC_GetGIsr(xdmac) & 0xFFFFFF;
+  xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(xdmac);
 
-  if ((xdmaGlobaIntStatus & 0xFFFFFF) != 0) {
-    xdmaGlobalChStatus = XDMAC_GetGlobalChStatus(xdmac);
+  while (xdmaGlobaIntStatus != 0) {
+    channel = 31 - __builtin_clz(xdmaGlobaIntStatus);
+    xdmaGlobaIntStatus &= ~(UINT32_C(1) << channel);
 
-    for (channel = 0; channel < xdma->numChannels; channel ++) {
-      if (!(xdmaGlobaIntStatus & (1 << channel))) {
-        continue;
-      }
-
-      ch = &xdma->XdmaChannels[channel];
+    ch = &xdma->XdmaChannels[channel];
 
-      if (ch->state == XDMAD_STATE_FREE) {
-        return;
-      }
+    if (ch->state == XDMAD_STATE_FREE) {
+      continue;
+    }
 
-      if ((xdmaGlobalChStatus & (XDMAC_GS_ST0 << channel)) == 0) {
-        bExec = 0;
-        xdmaChannelIntStatus = XDMAC_GetMaskChannelIsr(xdmac, channel);
+    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) {
+      if (xdmaChannelIntStatus & XDMAC_CIS_BIS) {
+        if ((XDMAC_GetChannelItMask(xdmac, channel) & XDMAC_CIM_LIM) == 0) {
           ch->state = XDMAD_STATE_DONE;
           bExec = 1;
         }
+      }
 
-      } else {
-        /* Block end interrupt for LLI dma mode */
-        if (XDMAC_GetChannelIsr(xdmac, channel) & XDMAC_CIS_BIS) {
-        }
+      if (xdmaChannelIntStatus & XDMAC_CIS_LIS) {
+        ch->state = XDMAD_STATE_DONE;
+        bExec = 1;
       }
 
-      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 (xdmaChannelIntStatus & XDMAC_CIS_DIS) {
+        ch->state = XDMAD_STATE_DONE;
+        bExec = 1;
       }
 
-      if (bus->transfer_status == 0) {
-        atsam_spi_setup_transfer(bus);
+    } else {
+      /* Block end interrupt for LLI dma mode */
+      if (XDMAC_GetChannelIsr(xdmac, channel) & XDMAC_CIS_BIS) {
       }
     }
+
+    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);
+    }
   }
 }
 



More information about the vc mailing list