diff --git a/os/hal/ports/common/ARMCMx/cache.h b/os/hal/ports/common/ARMCMx/cache.h index d3d0b5477..52a92e740 100644 --- a/os/hal/ports/common/ARMCMx/cache.h +++ b/os/hal/ports/common/ARMCMx/cache.h @@ -29,6 +29,15 @@ /* Driver constants. */ /*===========================================================================*/ +#if defined(__DCACHE_PRESENT) || defined(__DOXYGEN__) +/** + * @brief Data cache line size, zero if there is no data cache. + */ +#define CACHE_LINE_SIZE 32U +#else +#define CACHE_LINE_SIZE 0U +#endif + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ @@ -47,6 +56,17 @@ #if defined(__DCACHE_PRESENT) || defined(__DOXYGEN__) #if (__DCACHE_PRESENT != 0) || defined(__DOXYGEN__) +/** + * @brief Aligns the specified size to a multiple of cache line size. + * @note This macros assumes that the size of the type @p t is a power of + * two and not greater than @p CACHE_LINE_SIZE. + * + * @param[in] t type of the buffer element + * @param[in] n number of buffer elements + */ +#define CACHE_SIZE_ALIGN(t, n) \ + ((((((n) * sizeof (t)) - 1U) | (CACHE_LINE_SIZE - 1U)) + 1U) / sizeof (t)) + /** * @brief Invalidates the data cache lines overlapping a memory buffer. * @details This function is meant to make sure that data written in @@ -67,7 +87,7 @@ __DSB(); \ while (start < end) { \ SCB->DCIMVAC = (uint32_t)start; \ - start += 32U; \ + start += CACHE_LINE_SIZE; \ } \ __DSB(); \ __ISB(); \ @@ -93,7 +113,7 @@ __DSB(); \ while (start < end) { \ SCB->DCCIMVAC = (uint32_t)start; \ - start += 32U; \ + start += CACHE_LINE_SIZE; \ } \ __DSB(); \ __ISB(); \ @@ -111,6 +131,8 @@ #endif #else /* !defined(__DCACHE_PRESENT) */ +#define CACHE_SIZE_ALIGN(t, n) (n) + #define cacheBufferInvalidate(addr, size) { \ (void)(addr); \ (void)(size); \ diff --git a/testhal/STM32/multi/ADC/main.c b/testhal/STM32/multi/ADC/main.c index 68d5f3130..5464bd7c5 100644 --- a/testhal/STM32/multi/ADC/main.c +++ b/testhal/STM32/multi/ADC/main.c @@ -16,6 +16,7 @@ #include "ch.h" #include "hal.h" +#include "ccportab.h" #include "portab.h" @@ -26,8 +27,17 @@ #define ADC_GRP1_BUF_DEPTH 1 #define ADC_GRP2_BUF_DEPTH 64 -adcsample_t samples1[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH]; -adcsample_t samples2[ADC_GRP2_NUM_CHANNELS * ADC_GRP2_BUF_DEPTH]; +/* Buffers are allocated with size and address aligned to the cache + line size.*/ +#if CACHE_LINE_SIZE > 0 +CC_ALIGN(CACHE_LINE_SIZE) +#endif +adcsample_t samples1[CACHE_SIZE_ALIGN(adcsample_t, ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH)]; + +#if CACHE_LINE_SIZE > 0 +CC_ALIGN(CACHE_LINE_SIZE) +#endif +adcsample_t samples2[CACHE_SIZE_ALIGN(adcsample_t, ADC_GRP2_NUM_CHANNELS * ADC_GRP2_BUF_DEPTH)]; /* * ADC streaming callback. @@ -110,6 +120,7 @@ int main(void) { /* Performing a one-shot conversion on two channels.*/ adcConvert(&PORTAB_ADC1, &portab_adcgrpcfg1, samples1, ADC_GRP1_BUF_DEPTH); + cacheBufferInvalidate(samples1, sizeof (samples1) / sizeof (adcsample_t)); /* * Normal main() thread activity, if the button is pressed then the