From 8dd83d39b43ba0829d5129e82d4e40b4b19be127 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 14 Dec 2016 11:52:01 +0100 Subject: 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 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); + } } } -- cgit v1.2.3