Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions cmake/stm32f7.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -91,6 +94,7 @@ set(STM32F7_DEFINITIONS
${CORTEX_M7_DEFINITIONS}
USE_HAL_DRIVER
USE_FULL_LL_DRIVER
MAX_MPU_REGIONS=8
)

function(target_stm32f7xx)
Expand Down
4 changes: 4 additions & 0 deletions src/main/build/build_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/main/config/config_streamer_stm32f7.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/main/drivers/adc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/main/drivers/adc_stm32f7xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
50 changes: 50 additions & 0 deletions src/main/drivers/memprot_stm32f7xx.c
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

#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
6 changes: 5 additions & 1 deletion src/main/drivers/pwm_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/main/drivers/sdcard/sdcard_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 6 additions & 5 deletions src/main/drivers/sdcard/sdmmc_sdio_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Comment thread
qodo-free-for-open-source-projects[bot] marked this conversation as resolved.
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);
Expand All @@ -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;
}

Expand All @@ -646,18 +646,19 @@ 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;

sdReadParameters.buffer = buffer;
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;
Expand Down
7 changes: 4 additions & 3 deletions src/main/io/asyncfatfs/asyncfatfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down
12 changes: 6 additions & 6 deletions src/main/msc/usbd_storage_sd_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion src/main/target/link/stm32_flash_f722xe.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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"
4 changes: 3 additions & 1 deletion src/main/target/link/stm32_flash_f722xe_for_bl.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
4 changes: 3 additions & 1 deletion src/main/target/link/stm32_flash_f745xg.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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"
4 changes: 3 additions & 1 deletion src/main/target/link/stm32_flash_f745xg_for_bl.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/main/target/link/stm32_flash_f765xg.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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"
1 change: 1 addition & 0 deletions src/main/target/link/stm32_flash_f765xg_for_bl.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions src/main/target/link/stm32_flash_f765xi.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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"
1 change: 1 addition & 0 deletions src/main/target/link/stm32_flash_f765xi_for_bl.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
11 changes: 11 additions & 0 deletions src/main/target/link/stm32_flash_f7_split.ld
Original file line number Diff line number Diff line change
Expand Up @@ -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__ = .;
Expand Down
10 changes: 9 additions & 1 deletion src/main/target/system_stm32f7xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include <string.h>
#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 */
Expand Down Expand Up @@ -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();
Expand Down
Loading