From 5ec8107d65a5811b4353636178b3745ef84883b4 Mon Sep 17 00:00:00 2001 From: Joy Date: Fri, 19 Aug 2022 17:23:51 +0800 Subject: [PATCH 1/2] Optimize ADC DMA code. --- os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c | 11 ++++++----- os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c | 10 +++++----- os/hal/ports/WB32/LLD/DMAv1/wb32_dma.h | 23 ++++++++++++++++++----- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c b/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c index 9881b521..05e40cc6 100644 --- a/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c +++ b/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c @@ -58,19 +58,19 @@ ADCDriver ADCD1; static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { /* DMA errors handling.*/ - if ((flags & WB32_DMAC_IT_ERR) != 0) { + if ((flags & WB32_DMAC_IT_STATE_ERR) != 0) { /* DMA, this could help only if the DMA tries to access an unmapped address space or violates alignment rules.*/ _adc_isr_error_code(adcp, ADC_ERR_DMAFAILURE); } else { - if ((flags & WB32_DMAC_IT_TFR) != 0) { + if ((flags & WB32_DMAC_IT_STATE_TFR) != 0) { /* Transfer complete processing.*/ _adc_isr_full_code(adcp); } /* Because WB32 DMAC hasn't half transfer interrupt, so it use transfer complete interrupt. */ - else if ((flags & WB32_DMAC_IT_TFR) != 0) { + else if ((flags & WB32_DMAC_IT_STATE_BLOCK) != 0) { /* Half transfer processing.*/ _adc_isr_half_code(adcp); } @@ -104,7 +104,8 @@ void adc_lld_init(void) { WB32_DMA_CHCFG_MSIZE_HWORD | \ WB32_DMA_CHCFG_DIR_P2M | \ WB32_DMA_CHCFG_MINC | \ - WB32_DMA_CHCFG_CIRC; + WB32_DMA_CHCFG_TCIE | \ + WB32_DMAC_INTERRUPT_EN; /* Temporary activation.*/ rccEnableADC(); @@ -227,7 +228,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { if (adcp->depth > 1) { /* If circular buffer depth > 1, then the half transfer interrupt is enabled in order to allow streaming processing.*/ - mode |= WB32_DMA_CHCFG_TCIE; + mode |= WB32_DMA_CHCFG_HTIE; } } dmaStreamSetDestination(adcp->dmastp, adcp->samples); diff --git a/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c b/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c index c58b867d..fd9bbcf1 100644 --- a/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c +++ b/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c @@ -425,7 +425,7 @@ void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) { uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_TFR); if ((*((__I uint32_t *)(regaddr))) & mask) { - IT_flag = WB32_DMAC_IT_TFR; + IT_flag = WB32_DMAC_IT_STATE_TFR; if (dma.streams[selfindex].func) { dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag); } @@ -434,7 +434,7 @@ void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) { regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_BLOCK); if ((*((__I uint32_t *)(regaddr))) & mask) { - IT_flag = WB32_DMAC_IT_BLOCK; + IT_flag = WB32_DMAC_IT_STATE_BLOCK; if (dma.streams[selfindex].func) { dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag); } @@ -443,7 +443,7 @@ void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) { regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_SRCTRAN); if ((*((__I uint32_t *)(regaddr))) & mask) { - IT_flag = WB32_DMAC_IT_SRCTRAN; + IT_flag = WB32_DMAC_IT_STATE_SRCTRAN; if (dma.streams[selfindex].func) { dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag); } @@ -452,7 +452,7 @@ void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) { regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_DSTTRAN); if ((*((__I uint32_t *)(regaddr))) & mask) { - IT_flag = WB32_DMAC_IT_DSTTRAN; + IT_flag = WB32_DMAC_IT_STATE_DSTTRAN; if (dma.streams[selfindex].func) { dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag); } @@ -461,7 +461,7 @@ void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) { regaddr = ((uint32_t)(&((dmastp)->dmac->StatusTfr)) + WB32_DMAC_IT_ERR); if ((*((__I uint32_t *)(regaddr))) & mask) { - IT_flag = WB32_DMAC_IT_ERR; + IT_flag = WB32_DMAC_IT_STATE_ERR; if (dma.streams[selfindex].func) { dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag); } diff --git a/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.h b/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.h index 2cde4192..6bfc2aec 100644 --- a/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.h +++ b/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.h @@ -322,6 +322,15 @@ #define WB32_DMAC_IT_SRCTRAN (0x2U << 3) #define WB32_DMAC_IT_DSTTRAN (0x3U << 3) #define WB32_DMAC_IT_ERR (0x4U << 3) + +/** @defgroup DMAC_interrupts_states_definitions + * @{ + */ +#define WB32_DMAC_IT_STATE_TFR (0x1U << 0) +#define WB32_DMAC_IT_STATE_BLOCK (0x1U << 1) +#define WB32_DMAC_IT_STATE_SRCTRAN (0x1U << 2) +#define WB32_DMAC_IT_STATE_DSTTRAN (0x1U << 3) +#define WB32_DMAC_IT_STATE_ERR (0x1U << 4) /** * @} */ @@ -641,10 +650,14 @@ typedef struct { (dmastp)->dmac->Ch[(dmastp)->channel].CFGL = (((mode) & WB32_DMA_CHCFG_PL_MASK) >> 8) | \ (((mode) & WB32_DMA_CHCFG_CIRC) << 24) | \ (((mode) & WB32_DMA_CHCFG_CIRC) << 25); \ - if ((mode) & (WB32_DMA_CHCFG_TCIE | WB32_DMA_CHCFG_HTIE)) { \ + if ((mode) & (WB32_DMA_CHCFG_TCIE)) { \ (dmastp)->dmac->Ch[(dmastp)->channel].CTLL |= WB32_DMAC_INTERRUPT_EN; \ dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_TFR); \ } \ + if ((mode) & (WB32_DMA_CHCFG_HTIE)) { \ + (dmastp)->dmac->Ch[(dmastp)->channel].CTLL |= WB32_DMAC_INTERRUPT_EN; \ + dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_BLOCK); \ + } \ if ((mode) & WB32_DMA_CHCFG_TEIE) { \ (dmastp)->dmac->Ch[(dmastp)->channel].CTLL |= WB32_DMAC_INTERRUPT_EN; \ dmaStreamEnableInterrupt(dmastp, WB32_DMAC_IT_ERR); \ @@ -692,7 +705,7 @@ typedef struct { #define dmaStreamEnableInterrupt(dmastp, it_flag) { \ uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \ uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->MaskTfr)) + it_flag); \ - *((__O uint32_t *)(regaddr)) = (mask << 8) | mask; \ + *((__O uint32_t *)(regaddr)) |= (mask << 8) | mask; \ } /** @@ -709,7 +722,7 @@ typedef struct { #define dmaStreamDisableInterrupt(dmastp, it_flag) { \ uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \ uint32_t regaddr = ((uint32_t)(&((dmastp)->dmac->MaskTfr)) + it_flag); \ - *((__O uint32_t *)(regaddr)) = (mask << 8); \ + *((__O uint32_t *)(regaddr)) &= ~(mask); \ } /** @@ -784,7 +797,7 @@ typedef struct { */ #define dmaStreamEnable(dmastp) { \ uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \ - (dmastp)->dmac->ChEnReg = (mask << 8) | mask; \ + (dmastp)->dmac->ChEnReg |= (mask << 8) | mask; \ } /** @@ -803,7 +816,7 @@ typedef struct { */ #define dmaStreamDisable(dmastp) { \ uint32_t mask = (uint32_t)(0x01U << ((dmastp)->channel)); \ - (dmastp)->dmac->ChEnReg = (mask << 8); \ + (dmastp)->dmac->ChEnReg &= ~(mask); \ dmaStreamDisableInterruptAll(dmastp); \ dmaStreamClearInterrupt(dmastp); \ } From 8cd207b805df8baafd29388d1cca89ab32399ae2 Mon Sep 17 00:00:00 2001 From: Joy Date: Mon, 22 Aug 2022 15:15:46 +0800 Subject: [PATCH 2/2] Optimize the code. --- os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c | 2 +- os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c b/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c index 05e40cc6..e1f6de0f 100644 --- a/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c +++ b/os/hal/ports/WB32/LLD/ADCv1/hal_adc_lld.c @@ -265,7 +265,7 @@ void adc_lld_start_conversion(ADCDriver *adcp) { void adc_lld_stop_conversion(ADCDriver *adcp) { dmaStreamDisable(adcp->dmastp); - adcp->adc->CR2 = 0; + rccResetADC(); } #endif /* HAL_USE_ADC */ diff --git a/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c b/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c index fd9bbcf1..4d1a7400 100644 --- a/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c +++ b/os/hal/ports/WB32/LLD/DMAv1/wb32_dma.c @@ -466,6 +466,8 @@ void dmaServeInterrupt(const wb32_dma_stream_t *dmastp) { dma.streams[selfindex].func(dma.streams[selfindex].param, IT_flag); } } + + dmaStreamClearInterrupt(dmastp); } #endif /* WB32_DMA_REQUIRED */