[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