diff options
author | edolomb <none@example.com> | 2017-09-21 16:05:39 +0000 |
---|---|---|
committer | edolomb <none@example.com> | 2017-09-21 16:05:39 +0000 |
commit | 35e4fdb94348db3507abc28cc07aa0df11f0ce7c (patch) | |
tree | 7f0209dd3c3a398978234ead77d812e4414be670 | |
parent | 4e1a7dc365ecaca142de2a845a216d169be582b5 (diff) | |
download | ChibiOS-35e4fdb94348db3507abc28cc07aa0df11f0ce7c.tar.gz ChibiOS-35e4fdb94348db3507abc28cc07aa0df11f0ce7c.tar.bz2 ChibiOS-35e4fdb94348db3507abc28cc07aa0df11f0ce7c.zip |
Removed GS check status in DMAHandler
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10659 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r-- | os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c | 80 |
1 files changed, 58 insertions, 22 deletions
diff --git a/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c b/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c index 1e4dc15f7..43e591440 100644 --- a/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c +++ b/os/hal/ports/SAMA/LLD/DMAv1/sama_xdmac.c @@ -117,7 +117,7 @@ OSAL_IRQ_HANDLER(dmaHandler) { OSAL_IRQ_PROLOGUE();
for (cont = 0; cont < XDMAC_CONTROLLERS; cont++) {
- uint32_t chan, gis, gcs, cis;
+ uint32_t chan, gis, flags;
Xdmac *xdmac = dmaControllerSelect(cont);
@@ -128,11 +128,9 @@ OSAL_IRQ_HANDLER(dmaHandler) { /* There is no interrupt pending for this xdmac controller */
continue;
- /* Read Global Status Register */
- gcs = dmaGetGlobal(xdmac);
for (chan = 0; chan < XDMAC_CHANNELS; chan++) {
sama_dma_channel_t *channel = &_sama_dma_channel_t[(cont * XDMAC_CHANNELS) + chan];
- bool pendingInt = 0;
+ bool pendingInt = FALSE;
if (!(gis & (0x1 << chan)))
/* There is no pending interrupt for this channel */
@@ -142,29 +140,30 @@ OSAL_IRQ_HANDLER(dmaHandler) { /* Channel is free */
continue;
- if (!(gcs & (0x1 << chan))) {
- cis = dmaGetChannelInt(channel);
+ uint32_t cis = dmaGetChannelInt(channel);
- if (cis & XDMAC_CIS_BIS) {
- if (!(dmaGetChannelIntMask(channel) & XDMAC_CIM_LIM)) {
- pendingInt = 1;
- }
+ if (cis & XDMAC_CIS_BIS) {
+ if (!(dmaGetChannelIntMask(channel) & XDMAC_CIM_LIM)) {
+ pendingInt = TRUE;
}
+ }
- if (cis & XDMAC_CIS_LIS) {
- pendingInt = 1;
- }
+ if (cis & XDMAC_CIS_LIS) {
+ pendingInt = TRUE;
+ }
- if (cis & XDMAC_CIS_DIS) {
- pendingInt = 1;
- }
+ if (cis & XDMAC_CIS_DIS) {
+ pendingInt = TRUE;
}
+ flags = cis;
+
/* Execute callback */
if (pendingInt && channel->dma_func) {
- channel->dma_func(channel->dma_param,cis);
+ channel->dma_func(channel->dma_param,flags);
}
}
}
+ aicAckInt();
OSAL_IRQ_EPILOGUE();
}
@@ -198,9 +197,47 @@ void dmaInit(void) { dmaGetChannelInt(channel);
}
- uint32_t id = dmaGetControllerId(xdmac);
- /* set aic source handler */
- aicSetSourceHandler(id, dmaHandler);
+ uint32_t id = dmaGetControllerId(xdmac);
+ /* set aic source handler */
+ aicSetSourceHandler(id, dmaHandler);
+ }
+}
+
+/**
+ * @brief Sets the number of transfers to be performed.
+ * @note This function can be invoked in both ISR or thread context.
+ *
+ * @pre The channel must have been allocated using @p dmaChannelAllocate().
+ * @post After use the channel can be released using @p dmaChannelRelease().
+ *
+ * @param[in] dmastp pointer to a sama_dma_channel_t structure
+ * @param[in] size value to be written in the XDMAC_CUBC register
+ *
+ * @special
+ */
+void dmaChannelSetTransactionSize(sama_dma_channel_t *dmachp, size_t n) {
+
+uint32_t i;
+uint32_t divisor;
+ /* Single block single microblock */
+ if (n <= XDMAC_MAX_BT_SIZE) {
+ (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(n);
+ }
+ /* Single block multiple microblocks */
+ else {
+ /* If n exceeds XDMAC_MAX_BT_SIZE, split the transfer in microblocks */
+ for (i = 2; i < XDMAC_MAX_BT_SIZE; i++) {
+ divisor = XDMAC_MAX_BT_SIZE / i;
+ if (n % divisor)
+ continue;
+ if ((n / divisor) <= XDMAC_MAX_BLOCK_LEN) {
+ (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CUBC = XDMAC_CUBC_UBLEN(i);
+ (dmachp)->xdmac->XDMAC_CHID[(dmachp)->chid].XDMAC_CBC =
+ XDMAC_CBC_BLEN((n / divisor) - 1);
+ break;
+ }
+ }
+ osalDbgAssert(n == XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size");
}
}
@@ -259,8 +296,7 @@ sama_dma_channel_t* dmaChannelAllocate(uint32_t priority, }
/* Enable channel interrupt */
- /* Only works for single block transfer */
- channel->xdmac->XDMAC_CHID[channel->chid].XDMAC_CIE = XDMAC_CIE_BIE;
+ channel->xdmac->XDMAC_CHID[channel->chid].XDMAC_CIE = XDMAC_CIE_BIE;
channel->xdmac->XDMAC_GIE = XDMAC_GIE_IE0 << (channel->chid);
}
return channel;
|