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>
This commit is contained in:
parent
1d83c81756
commit
aa0945698b
1 changed files with 41 additions and 36 deletions
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in a new issue