diff --git a/firmware/global.h b/firmware/global.h index d0f818bd7a..1e7ec93e4a 100644 --- a/firmware/global.h +++ b/firmware/global.h @@ -64,7 +64,8 @@ typedef unsigned int time_t; // CCM memory is 64k #define CCM_OPTIONAL __attribute__((section(".ram4"))) #define SDRAM_OPTIONAL __attribute__((section(".ram7"))) -#define NO_CACHE // F4 has no cache, do nothing +#define NO_CACHE // F4 has no cache, do nothing +#define SDMMC_MEMORY // F4 has no cache, do nothing #elif defined(STM32F7XX) // DTCM memory is 128k #define CCM_OPTIONAL __attribute__((section(".ram3"))) @@ -72,6 +73,7 @@ typedef unsigned int time_t; #define SDRAM_OPTIONAL __attribute__((section(".ram7"))) // SRAM2 is 16k and set to disable dcache #define NO_CACHE __attribute__((section(".ram2"))) +#define SDMMC_MEMORY NO_CACHE #elif defined(STM32H7XX) // DTCM memory is 128k #define CCM_OPTIONAL __attribute__((section(".ram5"))) @@ -79,9 +81,12 @@ typedef unsigned int time_t; #define SDRAM_OPTIONAL __attribute__((section(".ram8"))) // SRAM3 is 32k and set to disable dcache #define NO_CACHE __attribute__((section(".ram3"))) +// On H7, SDMMC1 can only talk to AXI +#define SDMMC_MEMORY __attribute__((section(".ram0"))) #else /* this MCU doesn't need these */ #define CCM_OPTIONAL #define NO_CACHE +#define SDMMC_MEMORY #endif #define UNIT_TEST_BUSY_WAIT_CALLBACK() {} diff --git a/firmware/hw_layer/mmc_card.cpp b/firmware/hw_layer/mmc_card.cpp index 832a905658..88098dcf18 100644 --- a/firmware/hw_layer/mmc_card.cpp +++ b/firmware/hw_layer/mmc_card.cpp @@ -85,10 +85,21 @@ static MMCConfig mmccfg = { NULL, &mmc_ls_spicfg, &mmc_hs_spicfg }; #endif /* HAL_USE_MMC_SPI */ -/** - * fatfs MMC/SPI - */ -static NO_CACHE FATFS MMC_FS; +// On STM32H7, these objects need their own MPU region if using SDMMC1 +struct { + struct { + FATFS fs; + FIL file; + } usedPart; + + static_assert(sizeof(usedPart) <= 2048); + + // Fill the struct out to a full MPU region + uint8_t padding[2048 - sizeof(usedPart)]; +} mmcCardCacheControlledStorage SDMMC_MEMORY; + +static FATFS& MMC_FS = mmcCardCacheControlledStorage.usedPart.fs; +static FIL& FDLogFile = mmcCardCacheControlledStorage.usedPart.file; static int fatFsErrors = 0; @@ -108,8 +119,6 @@ static void printError(const char *str, FRESULT f_error) { efiPrintf("FATfs Error \"%s\" %d", str, f_error); } -static FIL FDLogFile NO_CACHE; - // 10 because we want at least 4 character name #define MIN_FILE_INDEX 10 static int logFileIndex = MIN_FILE_INDEX; @@ -313,6 +322,29 @@ static BaseBlockDevice* initializeMmcBlockDevice() { return nullptr; } + // STM32H7 SDMMC1 needs the filesystem object to be in AXI + // SRAM, but excluded from the cache + #ifdef STM32H7XX + { + void* base = &mmcCardCacheControlledStorage; + static_assert(sizeof(mmcCardCacheControlledStorage) == 2048); + uint32_t size = MPU_RASR_SIZE_2K; + + mpuConfigureRegion(MPU_REGION_5, + base, + MPU_RASR_ATTR_AP_RW_RW | + MPU_RASR_ATTR_NON_CACHEABLE | + MPU_RASR_ATTR_S | + size | + MPU_RASR_ENABLE); + mpuEnable(MPU_CTRL_PRIVDEFENA); + + /* Invalidating data cache to make sure that the MPU settings are taken + immediately.*/ + SCB_CleanInvalidateDCache(); + } + #endif + return reinterpret_cast(&EFI_SDC_DEVICE); } #endif /* EFI_SDC_DEVICE */ diff --git a/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h b/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h index 2231726750..b8fe24c3db 100644 --- a/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h +++ b/firmware/hw_layer/ports/stm32/stm32h7/cfg/mcuconf.h @@ -115,7 +115,7 @@ #define STM32_PLL2_FRACN_VALUE 0 #define STM32_PLL2_DIVP_VALUE 10 #define STM32_PLL2_DIVQ_VALUE 12 -#define STM32_PLL2_DIVR_VALUE 20 +#define STM32_PLL2_DIVR_VALUE 40 #define STM32_PLL3_ENABLED TRUE #define STM32_PLL3_P_ENABLED TRUE #define STM32_PLL3_Q_ENABLED TRUE @@ -389,8 +389,9 @@ #define STM32_SDC_USE_SDMMC1 TRUE #define STM32_SDC_USE_SDMMC2 FALSE #define STM32_SDC_SDMMC_UNALIGNED_SUPPORT TRUE -#define STM32_SDC_SDMMC_WRITE_TIMEOUT 1000000 -#define STM32_SDC_SDMMC_READ_TIMEOUT 1000000 +// Timeout of ~100ms at 24MHz +#define STM32_SDC_SDMMC_WRITE_TIMEOUT 2400000 +#define STM32_SDC_SDMMC_READ_TIMEOUT 2400000 #define STM32_SDC_SDMMC_CLOCK_DELAY 10 #define STM32_SDC_SDMMC_PWRSAV TRUE