diff --git a/os/hal/ports/STM32/LLD/ADCv2/adc_lld.c b/os/hal/ports/STM32/LLD/ADCv2/adc_lld.c index e8a2e87d9..04162b2f7 100644 --- a/os/hal/ports/STM32/LLD/ADCv2/adc_lld.c +++ b/os/hal/ports/STM32/LLD/ADCv2/adc_lld.c @@ -85,11 +85,6 @@ static void adc_lld_serve_rx_interrupt(ADCDriver *adcp, uint32_t flags) { ADC error handler, in this case this interrupt is spurious.*/ if (adcp->grpp != NULL) { - /* DMA buffer invalidation because data cache.*/ - dmaBufferInvalidate(adcp->samples, - adcp->samples + - (adcp->depth * adcp->grpp->num_channels)); - if ((flags & STM32_DMA_ISR_TCIF) != 0) { /* Transfer complete processing.*/ _adc_isr_full_code(adcp); diff --git a/os/hal/ports/STM32/LLD/DMAv2/notes.txt b/os/hal/ports/STM32/LLD/DMAv2/notes.txt index 28e2a7ce4..4c01d8309 100644 --- a/os/hal/ports/STM32/LLD/DMAv2/notes.txt +++ b/os/hal/ports/STM32/LLD/DMAv2/notes.txt @@ -5,6 +5,7 @@ Driver capability: - The driver supports the STM32 enhanced DMA controller found on F2, F4 and F7 sub-families. - Support for automatic the channel selection. +- Support for cache flushing and invalidation. The file registry must export: diff --git a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h index 49139f831..fdc76ee59 100644 --- a/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h +++ b/os/hal/ports/STM32/LLD/DMAv2/stm32_dma.h @@ -240,6 +240,9 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); #if defined(STM32F7XX) || defined(__DOXYGEN__) /** * @brief Invalidates the data cache lines overlapping a DMA buffer. + * @details This function is meant to make sure that data written in + * data cache is invalidated. It is used for DMA buffers that + * must have been written by a DMA stream. * @note On devices without data cache this function does nothing. * @note The function takes care of cache lines alignment. * @@ -249,6 +252,31 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); * @api */ #define dmaBufferInvalidate(saddr, eaddr) { \ + uint8_t *start = (uint8_t *)(((uint32_t)(saddr)) & ~0x1FU); \ + uint8_t *end = (uint8_t *)(((((uint32_t)(eaddr)) - 1U) | 0x1FU) + 1U); \ + __DSB(); \ + while (start < end) { \ + SCB->DCIMVAC = (uint32_t)start; \ + start += 32U; \ + } \ + __DSB(); \ + __ISB(); \ +} + +/** + * @brief Flushes the data cache lines overlapping a DMA buffer. + * @details This function is meant to make sure that data written in + * data cache is flushed to RAM. It is used for DMA buffers that + * must be read by a DMA stream. + * @note On devices without data cache this function does nothing. + * @note The function takes care of cache lines alignment. + * + * @param[in] saddr start address of the DMA buffer, inclusive + * @param[in] eaddr end address of the DMA buffer, not inclusive + * + * @api + */ +#define dmaBufferFlush(saddr, eaddr) { \ uint8_t *start = (uint8_t *)(((uint32_t)(saddr)) & ~0x1FU); \ uint8_t *end = (uint8_t *)(((((uint32_t)(eaddr)) - 1U) | 0x1FU) + 1U); \ __DSB(); \ @@ -264,6 +292,10 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); (void)(addr); \ (void)(size); \ } +#define dmaBufferFlush(addr, size) { \ + (void)(addr); \ + (void)(size); \ +} #endif /** diff --git a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c index 8704e5a21..a31563ef4 100644 --- a/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c +++ b/os/hal/ports/STM32/LLD/SPIv2/spi_lld.c @@ -549,9 +549,6 @@ void spi_lld_ignore(SPIDriver *spip, size_t n) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { - /* DMA buffer invalidation because data cache.*/ - dmaBufferInvalidate(rxbuf, (uint8_t *)rxbuf + (n * spip->fsize)); - dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); @@ -606,9 +603,6 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - /* DMA buffer invalidation because data cache.*/ - dmaBufferInvalidate(rxbuf, (uint8_t *)rxbuf + (n * spip->fsize)); - dmaStreamSetMemory0(spip->dmarx, rxbuf); dmaStreamSetTransactionSize(spip->dmarx, n); dmaStreamSetMode(spip->dmarx, spip->rxdmamode | STM32_DMA_CR_MINC); diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.c b/os/hal/ports/STM32/STM32F7xx/hal_lld.c index 4b4a98851..84e27a251 100644 --- a/os/hal/ports/STM32/STM32F7xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.c @@ -129,7 +129,7 @@ void hal_lld_init(void) { #if defined(STM32_DMA_REQUIRED) dmaInit(); -#if defined(STM32F7XX) +#if 0 /*defined(STM32F7XX)*/ /* If the DMA is in use then the DMA-accessible RAM must be programmed as Write Through using the MPU, region zero is used with a size of 512kB, the sub-regions are programmed as follow: