diff --git a/AGENTS.md b/AGENTS.md
index b2c077191d5..ab9ab5fd6cb 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -86,7 +86,7 @@ INAV uses special memory attributes for performance-critical code on resource-co
```c
FASTRAM // Fast RAM section (aligned)
EXTENDED_FASTRAM // Extended fast RAM (STM32F4/F7 only)
-DMA_RAM // DMA-accessible RAM (STM32H7, AT32F43x)
+DMA_RAM // DMA-accessible RAM, not cached on F7/H7 (STM32F7, STM32H7, AT32F43x)
SLOW_RAM // Slower external RAM - deprecated, o not use
STATIC_FASTRAM // Static variable in fast RAM
STATIC_FASTRAM_UNIT_TESTED // Static fast RAM variable visible in unit tests
diff --git a/cmake/stm32f7.cmake b/cmake/stm32f7.cmake
index d8f52de333f..a0da095fc51 100644
--- a/cmake/stm32f7.cmake
+++ b/cmake/stm32f7.cmake
@@ -75,6 +75,9 @@ main_sources(STM32F7_SRC
drivers/timer_impl_hal.c
drivers/timer_stm32f7xx.c
drivers/system_stm32f7xx.c
+ drivers/memprot.h
+ drivers/memprot_hal.c
+ drivers/memprot_stm32f7xx.c
drivers/serial_uart_stm32f7xx.c
drivers/serial_uart_hal.c
drivers/sdcard/sdmmc_sdio_hal.c
@@ -91,6 +94,7 @@ set(STM32F7_DEFINITIONS
${CORTEX_M7_DEFINITIONS}
USE_HAL_DRIVER
USE_FULL_LL_DRIVER
+ MAX_MPU_REGIONS=8
)
function(target_stm32f7xx)
diff --git a/src/main/build/build_config.h b/src/main/build/build_config.h
index 75bb46668d7..959267fc2d2 100644
--- a/src/main/build/build_config.h
+++ b/src/main/build/build_config.h
@@ -57,6 +57,10 @@
#elif defined (AT32F43x)
#define DMA_RAM __attribute__ ((section(".DMA_RAM")))
#define SLOW_RAM __attribute__ ((section(".SLOW_RAM")))
+#elif defined (STM32F7)
+#define DMA_RAM __attribute__ ((section(".DMA_RAM")))
+#define DMA_RAM_UNCACHED // the UART receive rings move here only then
+#define SLOW_RAM
#else
#define DMA_RAM
#define SLOW_RAM
diff --git a/src/main/config/config_streamer_stm32f7.c b/src/main/config/config_streamer_stm32f7.c
index 61b148fce57..867e86972a0 100644
--- a/src/main/config/config_streamer_stm32f7.c
+++ b/src/main/config/config_streamer_stm32f7.c
@@ -106,6 +106,8 @@ void config_streamer_impl_unlock(void)
void config_streamer_impl_lock(void)
{
HAL_FLASH_Lock();
+ // The D-cache keeps lines from before the erase, and erratum 1259864 can serve stale write-through data
+ SCB_InvalidateDCache_by_Addr((uint32_t *)&__config_start, &__config_end - &__config_start);
}
int config_streamer_impl_write_word(config_streamer_t *c, config_streamer_buffer_align_type_t *buffer)
diff --git a/src/main/drivers/adc_impl.h b/src/main/drivers/adc_impl.h
index 32f4414e83f..146d65e404c 100644
--- a/src/main/drivers/adc_impl.h
+++ b/src/main/drivers/adc_impl.h
@@ -28,7 +28,7 @@
#define ADC_TAG_MAP_COUNT 10
#endif
-#if defined(STM32H7)
+#if defined(STM32H7) || defined(STM32F7)
#define ADC_VALUES_ALIGNMENT(def) DMA_RAM def __attribute__ ((aligned (32)))
#else
#define ADC_VALUES_ALIGNMENT(def) def
diff --git a/src/main/drivers/adc_stm32f7xx.c b/src/main/drivers/adc_stm32f7xx.c
index 4b5aae88384..a18dd6f4289 100644
--- a/src/main/drivers/adc_stm32f7xx.c
+++ b/src/main/drivers/adc_stm32f7xx.c
@@ -83,6 +83,9 @@ static void adcInstanceInit(ADCDevice adcDevice)
{
adcDevice_t * adc = &adcHardware[adcDevice];
+ // DMA_RAM is not zeroed at startup: read 0, not leftovers, if the DMA never starts
+ memset((void *)adcValues[adcDevice], 0, sizeof(adcValues[adcDevice]));
+
RCC_ClockCmd(adc->rccDMA, ENABLE);
RCC_ClockCmd(adc->rccADC, ENABLE);
diff --git a/src/main/drivers/memprot_stm32f7xx.c b/src/main/drivers/memprot_stm32f7xx.c
new file mode 100644
index 00000000000..5dfb4eec0ca
--- /dev/null
+++ b/src/main/drivers/memprot_stm32f7xx.c
@@ -0,0 +1,50 @@
+/*
+ * This file is part of Cleanflight and Betaflight.
+ *
+ * Cleanflight and Betaflight are free software. You can redistribute
+ * this software and/or modify this software under the terms of the
+ * GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * Cleanflight and Betaflight are distributed in the hope that they
+ * will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software.
+ *
+ * If not, see .
+ */
+
+#include "platform.h"
+
+#include "common/utils.h"
+
+#include "memprot.h"
+
+#ifndef BOOTLOADER
+
+// Defined in linker script
+extern uint8_t dmaram_start;
+
+mpuRegion_t mpuRegions[] = {
+ {
+ // The whole 16 KB SRAM2 bank, where DMA_RAM is the only section: shareable, which the Cortex-M7 does not cache
+ .start = (uint32_t)&dmaram_start,
+ .end = 0,
+ .size = MPU_REGION_SIZE_16KB,
+ .perm = MPU_REGION_FULL_ACCESS,
+ .exec = MPU_INSTRUCTION_ACCESS_ENABLE,
+ .shareable = MPU_ACCESS_SHAREABLE,
+ .cacheable = MPU_ACCESS_CACHEABLE,
+ .bufferable = MPU_ACCESS_NOT_BUFFERABLE,
+ },
+};
+
+unsigned mpuRegionCount = ARRAYLEN(mpuRegions);
+
+STATIC_ASSERT(ARRAYLEN(mpuRegions) <= MAX_MPU_REGIONS, MPU_region_count_exceeds_limit);
+
+#endif
diff --git a/src/main/drivers/pwm_output.c b/src/main/drivers/pwm_output.c
index 20aed6c7264..17136b26a36 100644
--- a/src/main/drivers/pwm_output.c
+++ b/src/main/drivers/pwm_output.c
@@ -91,7 +91,7 @@
typedef void (*pwmWriteFuncPtr)(uint8_t index, uint16_t value); // function pointer used to write motors
#ifdef USE_DSHOT_DMAR
- timerDMASafeType_t dmaBurstBuffer[MAX_DMA_TIMERS][DSHOT_DMA_BUFFER_SIZE * 4];
+static DMA_RAM timerDMASafeType_t dmaBurstBuffer[MAX_DMA_TIMERS][DSHOT_DMA_BUFFER_SIZE * 4];
#endif
#ifdef USE_DSHOT
@@ -437,6 +437,10 @@ static pwmOutputPort_t * motorConfigDshot(const timerHardware_t * timerHardware,
return NULL;
}
+ // DMA_RAM is NOLOAD: a channel of this timer that drives no motor must read zero, not leftovers
+ if (!burstDmaTimers[burstDmaTimerIndex].dmaBurstBuffer) {
+ ZERO_FARRAY(dmaBurstBuffer[burstDmaTimerIndex]);
+ }
port->dmaBurstBuffer = &dmaBurstBuffer[burstDmaTimerIndex][0];
burstDmaTimer_t *burstDmaTimer = &burstDmaTimers[burstDmaTimerIndex];
burstDmaTimer->dmaBurstBuffer = port->dmaBurstBuffer;
diff --git a/src/main/drivers/sdcard/sdcard_sdio.c b/src/main/drivers/sdcard/sdcard_sdio.c
index f76377550a7..78838c976cc 100644
--- a/src/main/drivers/sdcard/sdcard_sdio.c
+++ b/src/main/drivers/sdcard/sdcard_sdio.c
@@ -54,7 +54,7 @@
#if defined(USE_SDCARD_SDIO_CACHE)
// Use this to speed up writing to SDCARD... asyncfatfs has limited support for multiblock write
#define FATFS_BLOCK_CACHE_SIZE 16
-uint8_t writeCache[512 * FATFS_BLOCK_CACHE_SIZE] __attribute__ ((aligned (4)));
+uint8_t writeCache[512 * FATFS_BLOCK_CACHE_SIZE] __attribute__ ((aligned (32))); // SDIO DMA with the D-cache
uint32_t cacheCount = 0;
void cache_write(uint8_t *buffer)
diff --git a/src/main/drivers/sdcard/sdmmc_sdio_hal.c b/src/main/drivers/sdcard/sdmmc_sdio_hal.c
index 23b9c34678c..f9ec8c88bee 100644
--- a/src/main/drivers/sdcard/sdmmc_sdio_hal.c
+++ b/src/main/drivers/sdcard/sdmmc_sdio_hal.c
@@ -600,17 +600,14 @@ SD_Error_t SD_CheckRead(void) {
SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t BlockSize, uint32_t NumberOfBlocks)
{
SD_Error_t ErrorState = SD_OK;
- SD_Handle.TXCplt = 1;
if (BlockSize != 512) {
return SD_ERROR; // unsupported.
}
-#ifndef STM32F7
if ((uint32_t)buffer & 0x1f) {
return SD_ADDR_MISALIGNED;
}
-#endif
// Ensure the data is flushed to main memory
SCB_CleanDCache_by_Addr(buffer, NumberOfBlocks * BlockSize);
@@ -623,7 +620,10 @@ SD_Error_t SD_WriteBlocks_DMA(uint64_t WriteAddress, uint32_t *buffer, uint32_t
}
}
#endif
+ // Busy only once a transfer really starts: a rejected write must not leave the card reported busy
+ SD_Handle.TXCplt = 1;
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)buffer, WriteAddress, NumberOfBlocks) != HAL_OK) {
+ SD_Handle.TXCplt = 0;
return SD_ERROR;
}
@@ -646,11 +646,9 @@ SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t Bl
return SD_ERROR; // unsupported.
}
-#ifndef STM32F7
if ((uint32_t)buffer & 0x1f) {
return SD_ADDR_MISALIGNED;
}
-#endif
SD_Handle.RXCplt = 1;
@@ -658,6 +656,9 @@ SD_Error_t SD_ReadBlocks_DMA(uint64_t ReadAddress, uint32_t *buffer, uint32_t Bl
sdReadParameters.BlockSize = BlockSize;
sdReadParameters.NumberOfBlocks = NumberOfBlocks;
+ // A dirty line evicted during the transfer would overwrite what the DMA wrote
+ SCB_InvalidateDCache_by_Addr(buffer, NumberOfBlocks * BlockSize);
+
#ifdef STM32F7
if (sd_dma.Init.Direction != DMA_PERIPH_TO_MEMORY) {
sd_dma.Init.Direction = DMA_PERIPH_TO_MEMORY;
diff --git a/src/main/io/asyncfatfs/asyncfatfs.c b/src/main/io/asyncfatfs/asyncfatfs.c
index cfa7da71ae8..57ec1cccad7 100644
--- a/src/main/io/asyncfatfs/asyncfatfs.c
+++ b/src/main/io/asyncfatfs/asyncfatfs.c
@@ -437,7 +437,7 @@ typedef struct afatfs_t {
} initState;
#endif
-#ifdef STM32H7
+#if defined(STM32H7) || defined(STM32F7)
uint8_t *cache;
#else
uint8_t cache[AFATFS_SECTOR_SIZE * AFATFS_NUM_CACHE_SECTORS];
@@ -487,7 +487,8 @@ typedef struct afatfs_t {
uint32_t rootDirectorySectors; // Zero on FAT32, for FAT16 the number of sectors that the root directory occupies
} afatfs_t;
-#ifdef STM32H7
+#if defined(STM32H7) || defined(STM32F7)
+// SD DMA with the D-cache on: cache maintenance works on whole 32-byte lines
static uint8_t afatfs_cache[AFATFS_SECTOR_SIZE * AFATFS_NUM_CACHE_SECTORS] __attribute__((aligned(32)));
#endif
@@ -3675,7 +3676,7 @@ bool afatfs_isCurrentDirRoot(void)
void afatfs_init(void)
{
-#ifdef STM32H7
+#if defined(STM32H7) || defined(STM32F7)
afatfs.cache = afatfs_cache;
#endif
afatfs.filesystemState = AFATFS_FILESYSTEM_STATE_INITIALIZATION;
diff --git a/src/main/msc/usbd_storage_sd_spi.c b/src/main/msc/usbd_storage_sd_spi.c
index 26a38e00b6a..d6c50caf19f 100644
--- a/src/main/msc/usbd_storage_sd_spi.c
+++ b/src/main/msc/usbd_storage_sd_spi.c
@@ -58,9 +58,9 @@
#define STORAGE_BLK_NBR 0x10000
#define STORAGE_BLK_SIZ 0x200
-// H7 SDIO DMA requires 32-byte aligned buffers
+// SDIO DMA with the D-cache on (F7, H7) requires 32-byte aligned buffers
// USB MSC bot_data buffer is only 16-byte aligned, so we need an intermediate buffer
-#if defined(STM32H7) && defined(USE_SDCARD_SDIO)
+#if (defined(STM32H7) || defined(STM32F7)) && defined(USE_SDCARD_SDIO)
__attribute__((aligned(32))) static uint8_t alignedBuffer[512];
#endif
@@ -233,8 +233,8 @@ static int8_t STORAGE_Read (uint8_t lun,
LED1_ON;
for (int i = 0; i < blk_len; i++) {
uint32_t timeout;
-#if defined(STM32H7) && defined(USE_SDCARD_SDIO)
- // H7 SDIO DMA requires 32-byte aligned buffers
+#if (defined(STM32H7) || defined(STM32F7)) && defined(USE_SDCARD_SDIO)
+ // SDIO DMA requires 32-byte aligned buffers
// USB MSC buffer may not be aligned, so use intermediate buffer
timeout = 0;
while (sdcard_readBlock(blk_addr + i, alignedBuffer, NULL, 0) == 0) {
@@ -293,8 +293,8 @@ static int8_t STORAGE_Write (uint8_t lun,
LED1_ON;
for (int i = 0; i < blk_len; i++) {
uint32_t timeout;
-#if defined(STM32H7) && defined(USE_SDCARD_SDIO)
- // H7 SDIO DMA requires 32-byte aligned buffers
+#if (defined(STM32H7) || defined(STM32F7)) && defined(USE_SDCARD_SDIO)
+ // SDIO DMA requires 32-byte aligned buffers
// USB MSC buffer may not be aligned, so use intermediate buffer
memcpy(alignedBuffer, buf + (i * 512), 512);
timeout = 0;
diff --git a/src/main/target/link/stm32_flash_f722xe.ld b/src/main/target/link/stm32_flash_f722xe.ld
index 3a9094ed81f..739b24056a5 100644
--- a/src/main/target/link/stm32_flash_f722xe.ld
+++ b/src/main/target/link/stm32_flash_f722xe.ld
@@ -38,11 +38,13 @@ MEMORY
FLASH1 (rx) : ORIGIN = 0x08008000, LENGTH = 480K
TCM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
- RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 192K
+ RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 176K
+ SRAM2 (rwx) : ORIGIN = 0x2003C000, LENGTH = 16K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
REGION_ALIAS("STACKRAM", TCM)
REGION_ALIAS("FASTRAM", TCM)
+REGION_ALIAS("DMARAM", SRAM2)
INCLUDE "stm32_flash_f7_split.ld"
diff --git a/src/main/target/link/stm32_flash_f722xe_for_bl.ld b/src/main/target/link/stm32_flash_f722xe_for_bl.ld
index 83c9a43fc5e..581c5d34015 100644
--- a/src/main/target/link/stm32_flash_f722xe_for_bl.ld
+++ b/src/main/target/link/stm32_flash_f722xe_for_bl.ld
@@ -38,12 +38,14 @@ MEMORY
FLASH1 (rx) : ORIGIN = 0x08010000, LENGTH = 448K
TCM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
- RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 192K
+ RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 176K
+ SRAM2 (rwx) : ORIGIN = 0x2003C000, LENGTH = 16K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
REGION_ALIAS("STACKRAM", TCM)
REGION_ALIAS("FASTRAM", TCM)
+REGION_ALIAS("DMARAM", SRAM2)
__firmware_start = ORIGIN(FLASH);
diff --git a/src/main/target/link/stm32_flash_f745xg.ld b/src/main/target/link/stm32_flash_f745xg.ld
index ddb73a4dc50..54981a7ae1e 100644
--- a/src/main/target/link/stm32_flash_f745xg.ld
+++ b/src/main/target/link/stm32_flash_f745xg.ld
@@ -38,11 +38,13 @@ MEMORY
FLASH1 (rx) : ORIGIN = 0x08010000, LENGTH = 960K
TCM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
- RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 256K
+ RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 240K
+ SRAM2 (rwx) : ORIGIN = 0x2004C000, LENGTH = 16K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
/* note CCM could be used for stack */
REGION_ALIAS("STACKRAM", TCM)
REGION_ALIAS("FASTRAM", TCM)
+REGION_ALIAS("DMARAM", SRAM2)
INCLUDE "stm32_flash_f7_split.ld"
diff --git a/src/main/target/link/stm32_flash_f745xg_for_bl.ld b/src/main/target/link/stm32_flash_f745xg_for_bl.ld
index c7667d1dc26..54a5bddcb7d 100644
--- a/src/main/target/link/stm32_flash_f745xg_for_bl.ld
+++ b/src/main/target/link/stm32_flash_f745xg_for_bl.ld
@@ -38,12 +38,14 @@ MEMORY
FLASH1 (rx) : ORIGIN = 0x08018000, LENGTH = 928K
TCM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
- RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 256K
+ RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 240K
+ SRAM2 (rwx) : ORIGIN = 0x2004C000, LENGTH = 16K
MEMORY_B1 (rx) : ORIGIN = 0x60000000, LENGTH = 0K
}
/* note CCM could be used for stack */
REGION_ALIAS("STACKRAM", TCM)
REGION_ALIAS("FASTRAM", TCM)
+REGION_ALIAS("DMARAM", SRAM2)
__firmware_start = ORIGIN(FLASH);
diff --git a/src/main/target/link/stm32_flash_f765xg.ld b/src/main/target/link/stm32_flash_f765xg.ld
index ea548ed4ff3..2dc4e906677 100644
--- a/src/main/target/link/stm32_flash_f765xg.ld
+++ b/src/main/target/link/stm32_flash_f765xg.ld
@@ -48,5 +48,6 @@ MEMORY
REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM)
REGION_ALIAS("RAM", SRAM1)
+REGION_ALIAS("DMARAM", SRAM2)
INCLUDE "stm32_flash_f7_split.ld"
diff --git a/src/main/target/link/stm32_flash_f765xg_for_bl.ld b/src/main/target/link/stm32_flash_f765xg_for_bl.ld
index b50247b015d..9405858f04d 100644
--- a/src/main/target/link/stm32_flash_f765xg_for_bl.ld
+++ b/src/main/target/link/stm32_flash_f765xg_for_bl.ld
@@ -48,6 +48,7 @@ MEMORY
REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM)
REGION_ALIAS("RAM", SRAM1)
+REGION_ALIAS("DMARAM", SRAM2)
__firmware_start = ORIGIN(FLASH);
diff --git a/src/main/target/link/stm32_flash_f765xi.ld b/src/main/target/link/stm32_flash_f765xi.ld
index 130169290ea..c1165c25dbc 100644
--- a/src/main/target/link/stm32_flash_f765xi.ld
+++ b/src/main/target/link/stm32_flash_f765xi.ld
@@ -51,5 +51,6 @@ REGION_ALIAS("FLASH1", AXIM_FLASH1)
REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM)
REGION_ALIAS("RAM", SRAM1)
+REGION_ALIAS("DMARAM", SRAM2)
INCLUDE "stm32_flash_f7_split.ld"
diff --git a/src/main/target/link/stm32_flash_f765xi_for_bl.ld b/src/main/target/link/stm32_flash_f765xi_for_bl.ld
index 14f2a4bedff..eb9c3a820cd 100644
--- a/src/main/target/link/stm32_flash_f765xi_for_bl.ld
+++ b/src/main/target/link/stm32_flash_f765xi_for_bl.ld
@@ -51,6 +51,7 @@ REGION_ALIAS("FLASH1", AXIM_FLASH1)
REGION_ALIAS("STACKRAM", DTCM_RAM)
REGION_ALIAS("FASTRAM", DTCM_RAM)
REGION_ALIAS("RAM", SRAM1)
+REGION_ALIAS("DMARAM", SRAM2)
__firmware_start = ORIGIN(AXIM_FLASH);
diff --git a/src/main/target/link/stm32_flash_f7_split.ld b/src/main/target/link/stm32_flash_f7_split.ld
index 4738eb7af5e..bbd5cf5f99c 100644
--- a/src/main/target/link/stm32_flash_f7_split.ld
+++ b/src/main/target/link/stm32_flash_f7_split.ld
@@ -140,6 +140,17 @@ SECTIONS
__bss_end__ = _ebss;
} >RAM
+ /* DMA buffers, in a region the MPU keeps out of the D-cache (memprot_stm32f7xx.c) */
+ .DMA_RAM (NOLOAD) :
+ {
+ . = ALIGN(32);
+ PROVIDE(dmaram_start = .);
+ *(.DMA_RAM)
+ *(.DMA_RAM*)
+ . = ALIGN(32);
+ PROVIDE(dmaram_end = .);
+ } >DMARAM
+
.fastram_bss (NOLOAD) :
{
__fastram_bss_start__ = .;
diff --git a/src/main/target/system_stm32f7xx.c b/src/main/target/system_stm32f7xx.c
index ea974199681..c1de7010047 100644
--- a/src/main/target/system_stm32f7xx.c
+++ b/src/main/target/system_stm32f7xx.c
@@ -66,6 +66,7 @@
#include
#include "stm32f7xx.h"
#include "drivers/system.h"
+#include "drivers/memprot.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */
@@ -296,11 +297,18 @@ void SystemInit(void)
SCB->VTOR = (uint32_t) &isr_vector_table_base;
#endif
+#ifndef BOOTLOADER
+ // DMA buffers sit in a region the MPU keeps out of the D-cache
+ memProtConfigure(mpuRegions, mpuRegionCount);
+#endif
+
/* Enable I-Cache */
SCB_EnableICache();
+#ifndef BOOTLOADER
/* Enable D-Cache */
- //SCB_EnableDCache();
+ SCB_EnableDCache();
+#endif
/* Configure the system clock to 216 MHz */
SystemClock_Config();