aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--os/hal/ports/common/ARMCMx/cache.h26
-rw-r--r--testhal/STM32/multi/ADC/main.c15
2 files changed, 37 insertions, 4 deletions
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. */
/*===========================================================================*/
@@ -48,6 +57,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
* data cache is invalidated.
@@ -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