summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-14 11:52:01 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-12-14 13:09:30 +0100
commit8dd83d39b43ba0829d5129e82d4e40b4b19be127 (patch)
tree05e7e6c638e38b54ed01b820cd32b808010daab9
parent9686c6140f11268c52735b62fa3353c32b47460e (diff)
downloadrtems-8dd83d39b43ba0829d5129e82d4e40b4b19be127.tar.bz2
bsp/atsam: Optimize SPI interrupt
-rw-r--r--c/src/lib/libbsp/arm/atsam/spi/atsam_spi_bus.c76
1 files 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 7c3855de44..2bc61665ea 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);
+ }
}
}