From b9b4f184a7a014ec324f50fabdc4c6539e676b10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= Date: Wed, 22 Mar 2017 11:12:17 -0700 Subject: [PATCH] stm32: Add workaround for flash data cache corruption on read-while-write This is a know hardware issue on some STM32 see the errata of your model and if you make use of both memory banks you should enable it. --- arch/arm/src/stm32/Kconfig | 6 ++++++ arch/arm/src/stm32/stm32_flash.c | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig index de2c8fe23be..72f8a17fbb6 100644 --- a/arch/arm/src/stm32/Kconfig +++ b/arch/arm/src/stm32/Kconfig @@ -2633,6 +2633,12 @@ config STM32_FLASH_PREFETCH on F1 parts). Some early revisions of F4 parts do not support FLASH pre-fetch properly and enabling this option may interfere with ADC accuracy. +config STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW + bool "Enable the workaround to fix flash data cache corruption when reading from one flash bank while writing on other flash bank" + default n + ---help--- + See your STM32 errata to check if your STM32 is affected by this problem. + choice prompt "JTAG Configuration" default STM32_JTAG_DISABLE diff --git a/arch/arm/src/stm32/stm32_flash.c b/arch/arm/src/stm32/stm32_flash.c index 7f0b53ee607..4907aa9f0af 100644 --- a/arch/arm/src/stm32/stm32_flash.c +++ b/arch/arm/src/stm32/stm32_flash.c @@ -130,6 +130,20 @@ static void flash_lock(void) modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_LOCK); } +static void data_cache_disable(void) +{ + modifyreg32(STM32_FLASH_ACR, FLASH_ACR_DCEN, 0); +} + +static void data_cache_enable(void) +{ + /* reset data cache */ + modifyreg32(STM32_FLASH_ACR, 0, FLASH_ACR_DCRST); + + /* enable data cache */ + modifyreg32(STM32_FLASH_ACR, 0, FLASH_ACR_DCEN); +} + /************************************************************************************ * Public Functions ************************************************************************************/ @@ -384,6 +398,10 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) flash_unlock(); +#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) + data_cache_disable(); +#endif + modifyreg32(STM32_FLASH_CR, 0, FLASH_CR_PG); #if defined(CONFIG_STM32_STM32F40XX) @@ -417,6 +435,11 @@ ssize_t up_progmem_write(size_t addr, const void *buf, size_t count) } modifyreg32(STM32_FLASH_CR, FLASH_CR_PG, 0); + +#if defined(CONFIG_STM32_FLASH_WORKAROUND_DATA_CACHE_CORRUPTION_ON_RWW) + data_cache_enable(); +#endif + sem_unlock(); return written; }