From de062e140b93b455fb6370a61d08b559bfe25d0d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 16 Apr 2021 12:55:54 +0000 Subject: [PATCH] DMA code, to be tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14201 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/RP/LLD/DMAv1/rp_dma.c | 129 ++++++++++++++++++++++++++--- os/hal/ports/RP/LLD/DMAv1/rp_dma.h | 11 +-- 2 files changed, 119 insertions(+), 21 deletions(-) diff --git a/os/hal/ports/RP/LLD/DMAv1/rp_dma.c b/os/hal/ports/RP/LLD/DMAv1/rp_dma.c index 13db1687a..9b3b31bd1 100644 --- a/os/hal/ports/RP/LLD/DMAv1/rp_dma.c +++ b/os/hal/ports/RP/LLD/DMAv1/rp_dma.c @@ -28,8 +28,6 @@ #include "hal.h" -#define RP_DMA_REQUIRED - /* The following macro is only defined if some driver requiring DMA services has been enabled.*/ #if defined(RP_DMA_REQUIRED) || defined(__DOXYGEN__) @@ -95,10 +93,126 @@ const rp_dma_channel_t __rp_dma_channels[RP_DMA_CHANNELS] = { /* Driver local functions. */ /*===========================================================================*/ +void serve_interrupt(const rp_dma_channel_t *dmachp) { + + if (dma.channels[dmachp->chnidx].func != NULL) { + dma.channels[dmachp->chnidx].func(dma.channels[dmachp->chnidx].param, + dmachp->channel->CTRL_TRIG); + } +} + /*===========================================================================*/ /* Driver interrupt handlers. */ /*===========================================================================*/ +/** + * @brief DMA shared ISR for core 0. + * + * @isr + */ +OSAL_IRQ_HANDLER(RP_DMA_IRQ_0_HANDLER) { + uint32_t ints; + + OSAL_IRQ_PROLOGUE(); + + /* Getting and clearing pending interrupts for core 0.*/ + ints = DMA->C[0].INTS; + DMA->C[0].INTS = ints; + + if ((ints & (1U << 0)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(0U)); + } + if ((ints & (1U << 1)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(1U)); + } + if ((ints & (1U << 2)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(2U)); + } + if ((ints & (1U << 3)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(3U)); + } + if ((ints & (1U << 4)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(4U)); + } + if ((ints & (1U << 5)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(5U)); + } + if ((ints & (1U << 6)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(6U)); + } + if ((ints & (1U << 7)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(7U)); + } + if ((ints & (1U << 8)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(8U)); + } + if ((ints & (1U << 9)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(9U)); + } + if ((ints & (1U << 10)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(10U)); + } + if ((ints & (1U << 11)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(11U)); + } + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief DMA shared ISR for core 1. + * + * @isr + */ +OSAL_IRQ_HANDLER(RP_DMA_IRQ_1_HANDLER) { + uint32_t ints; + + OSAL_IRQ_PROLOGUE(); + + /* Getting and clearing pending interrupts for core 0.*/ + ints = DMA->C[1].INTS; + DMA->C[1].INTS = ints; + + if ((ints & (1U << 0)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(0U)); + } + if ((ints & (1U << 1)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(1U)); + } + if ((ints & (1U << 2)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(2U)); + } + if ((ints & (1U << 3)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(3U)); + } + if ((ints & (1U << 4)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(4U)); + } + if ((ints & (1U << 5)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(5U)); + } + if ((ints & (1U << 6)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(6U)); + } + if ((ints & (1U << 7)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(7U)); + } + if ((ints & (1U << 8)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(8U)); + } + if ((ints & (1U << 9)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(9U)); + } + if ((ints & (1U << 10)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(10U)); + } + if ((ints & (1U << 11)) != 0U) { + serve_interrupt(RP_DMA_CHANNEL(11U)); + } + + OSAL_IRQ_EPILOGUE(); +} + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -238,6 +352,7 @@ void dmaChannelFreeI(const rp_dma_channel_t *dmachp) { /* Check if the streams is not taken.*/ osalDbgAssert(((dma.c0_allocated_mask | dma.c1_allocated_mask) & dmachp->chnmask) != 0U, "not allocated"); + osalDbgAssert(dmaChannelIsBusyX(dmachp) == false, "channel is busy"); /* Putting the stream in a known state.*/ dmaChannelDisableX(dmachp); @@ -282,16 +397,6 @@ void dmaChannelFree(const rp_dma_channel_t *dmachp) { osalSysUnlock(); } -/** - * @brief Serves a DMA IRQ. - * - * @param[in] dmachp pointer to a rp_dma_channel_t structure - * - * @special - */ -void dmaServeInterrupt(const rp_dma_channel_t *dmachp) { -} - #endif /* RP_DMA_REQUIRED */ /** @} */ diff --git a/os/hal/ports/RP/LLD/DMAv1/rp_dma.h b/os/hal/ports/RP/LLD/DMAv1/rp_dma.h index 249e4edff..b076dc34c 100644 --- a/os/hal/ports/RP/LLD/DMAv1/rp_dma.h +++ b/os/hal/ports/RP/LLD/DMAv1/rp_dma.h @@ -75,10 +75,9 @@ * @brief Type of a DMA callback. * * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the ISR register, the bits - * are aligned to bit zero + * @param[in] ct content of the CTRL_TRIG register */ -typedef void (*rp_dmaisr_t)(void *p, uint32_t flags); +typedef void (*rp_dmaisr_t)(void *p, uint32_t ct); /** * @brief RP DMA channel descriptor structure. @@ -94,12 +93,6 @@ typedef struct { /* Driver macros. */ /*===========================================================================*/ -/** - * @name Macro Functions - * @{ - */ -/** @} */ - /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/