diff options
author | Damien George <damien@micropython.org> | 2025-03-13 11:09:01 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-04-09 22:36:55 +1000 |
commit | aa0945698b714c25f85b1234e0b03f34ac76c24c (patch) | |
tree | ba93cda3b13836bf7e559f40d2f8baeb9e347d6a | |
parent | 1d83c8175680b911ab24ba834b7f8bcadaa5aa79 (diff) | |
download | micropython-aa0945698b714c25f85b1234e0b03f34ac76c24c.tar.gz micropython-aa0945698b714c25f85b1234e0b03f34ac76c24c.zip |
stm32/qspi: Allow SPI flash size to be decided at runtime.
Allows `MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2` and
`MICROPY_HW_QSPI_MPU_REGION_SIZE` to be arbitrary expressions, eg function
calls.
The `storage.h` header needs to be included in case access to `spi_bdev_t`
is needed by the macros.
Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r-- | ports/stm32/qspi.c | 77 |
1 files changed, 41 insertions, 36 deletions
diff --git a/ports/stm32/qspi.c b/ports/stm32/qspi.c index 1360d9b490..781aae803e 100644 --- a/ports/stm32/qspi.c +++ b/ports/stm32/qspi.c @@ -31,6 +31,7 @@ #include "mpu.h" #include "qspi.h" #include "pin_static_af.h" +#include "storage.h" #if defined(MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2) @@ -50,18 +51,11 @@ #define MICROPY_HW_QSPI_CS_HIGH_CYCLES 2 // nCS stays high for 2 cycles #endif +// Region size in units of 1024*1024 bytes. #ifndef MICROPY_HW_QSPI_MPU_REGION_SIZE #define MICROPY_HW_QSPI_MPU_REGION_SIZE ((1 << (MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 - 3)) >> 20) #endif -#if (MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 - 3 - 1) >= 24 -#define QSPI_CMD 0xec -#define QSPI_ADSIZE 3 -#else -#define QSPI_CMD 0xeb -#define QSPI_ADSIZE 2 -#endif - static uint8_t qspi_num_dummy; static inline void qspi_mpu_disable_all(void) { @@ -83,32 +77,32 @@ static inline void qspi_mpu_enable_mapped(void) { // other enabled region overlaps the disabled subregion, and the access is // unprivileged or the background region is disabled, the MPU issues a fault. uint32_t irq_state = mpu_config_start(); - #if MICROPY_HW_QSPI_MPU_REGION_SIZE > 128 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0xFF, MPU_REGION_SIZE_256MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 64 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_256MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 32 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_256MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 16 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 8 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); - mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 4 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); - mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_32MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 2 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); - mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB)); - #elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 1 - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); - mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB)); - mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_16MB)); - #else - mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); - mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB)); - mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_4MB)); - #endif + if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 128) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0xFF, MPU_REGION_SIZE_256MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 64) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_256MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 32) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_256MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 16) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 8) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); + mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 4) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); + mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_32MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 2) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); + mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB)); + } else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 1) { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); + mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB)); + mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_16MB)); + } else { + mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB)); + mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB)); + mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_4MB)); + } mpu_config_end(irq_state); } @@ -155,6 +149,17 @@ void qspi_init(uint8_t num_dummy) { void qspi_memory_map(void) { // Enable memory-mapped mode + // Work out command to use for reads, based on size of the memory. + uint8_t cmd; + uint8_t adsize; + if ((MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 - 3 - 1) >= 24) { + cmd = 0xec; + adsize = 3; + } else { + cmd = 0xeb; + adsize = 2; + } + QUADSPI->ABR = 0; // disable continuous read mode QUADSPI->CCR = @@ -165,10 +170,10 @@ void qspi_memory_map(void) { | (2 * qspi_num_dummy) << QUADSPI_CCR_DCYC_Pos // 2N dummy cycles | 0 << QUADSPI_CCR_ABSIZE_Pos // 8-bit alternate byte | 3 << QUADSPI_CCR_ABMODE_Pos // alternate byte on 4 lines - | QSPI_ADSIZE << QUADSPI_CCR_ADSIZE_Pos + | adsize << QUADSPI_CCR_ADSIZE_Pos | 3 << QUADSPI_CCR_ADMODE_Pos // address on 4 lines | 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line - | QSPI_CMD << QUADSPI_CCR_INSTRUCTION_Pos + | cmd << QUADSPI_CCR_INSTRUCTION_Pos ; qspi_mpu_enable_mapped(); |