Skip to content

Commit aa09456

Browse files
committed
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 <[email protected]>
1 parent 1d83c81 commit aa09456

File tree

1 file changed

+41
-36
lines changed

1 file changed

+41
-36
lines changed

ports/stm32/qspi.c

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "mpu.h"
3232
#include "qspi.h"
3333
#include "pin_static_af.h"
34+
#include "storage.h"
3435

3536
#if defined(MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2)
3637

@@ -50,18 +51,11 @@
5051
#define MICROPY_HW_QSPI_CS_HIGH_CYCLES 2 // nCS stays high for 2 cycles
5152
#endif
5253

54+
// Region size in units of 1024*1024 bytes.
5355
#ifndef MICROPY_HW_QSPI_MPU_REGION_SIZE
5456
#define MICROPY_HW_QSPI_MPU_REGION_SIZE ((1 << (MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 - 3)) >> 20)
5557
#endif
5658

57-
#if (MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 - 3 - 1) >= 24
58-
#define QSPI_CMD 0xec
59-
#define QSPI_ADSIZE 3
60-
#else
61-
#define QSPI_CMD 0xeb
62-
#define QSPI_ADSIZE 2
63-
#endif
64-
6559
static uint8_t qspi_num_dummy;
6660

6761
static inline void qspi_mpu_disable_all(void) {
@@ -83,32 +77,32 @@ static inline void qspi_mpu_enable_mapped(void) {
8377
// other enabled region overlaps the disabled subregion, and the access is
8478
// unprivileged or the background region is disabled, the MPU issues a fault.
8579
uint32_t irq_state = mpu_config_start();
86-
#if MICROPY_HW_QSPI_MPU_REGION_SIZE > 128
87-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0xFF, MPU_REGION_SIZE_256MB));
88-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 64
89-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_256MB));
90-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 32
91-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_256MB));
92-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 16
93-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
94-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 8
95-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
96-
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB));
97-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 4
98-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
99-
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_32MB));
100-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 2
101-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
102-
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB));
103-
#elif MICROPY_HW_QSPI_MPU_REGION_SIZE > 1
104-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
105-
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB));
106-
mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_16MB));
107-
#else
108-
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
109-
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB));
110-
mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_4MB));
111-
#endif
80+
if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 128) {
81+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0xFF, MPU_REGION_SIZE_256MB));
82+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 64) {
83+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_256MB));
84+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 32) {
85+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_256MB));
86+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 16) {
87+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
88+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 8) {
89+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
90+
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB));
91+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 4) {
92+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
93+
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_32MB));
94+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 2) {
95+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
96+
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB));
97+
} else if (MICROPY_HW_QSPI_MPU_REGION_SIZE > 1) {
98+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
99+
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x0F, MPU_REGION_SIZE_32MB));
100+
mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_16MB));
101+
} else {
102+
mpu_config_region(MPU_REGION_QSPI1, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_256MB));
103+
mpu_config_region(MPU_REGION_QSPI2, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x01, MPU_REGION_SIZE_32MB));
104+
mpu_config_region(MPU_REGION_QSPI3, QSPI_MAP_ADDR, MPU_CONFIG_NOACCESS(0x03, MPU_REGION_SIZE_4MB));
105+
}
112106
mpu_config_end(irq_state);
113107
}
114108

@@ -155,6 +149,17 @@ void qspi_init(uint8_t num_dummy) {
155149
void qspi_memory_map(void) {
156150
// Enable memory-mapped mode
157151

152+
// Work out command to use for reads, based on size of the memory.
153+
uint8_t cmd;
154+
uint8_t adsize;
155+
if ((MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 - 3 - 1) >= 24) {
156+
cmd = 0xec;
157+
adsize = 3;
158+
} else {
159+
cmd = 0xeb;
160+
adsize = 2;
161+
}
162+
158163
QUADSPI->ABR = 0; // disable continuous read mode
159164

160165
QUADSPI->CCR =
@@ -165,10 +170,10 @@ void qspi_memory_map(void) {
165170
| (2 * qspi_num_dummy) << QUADSPI_CCR_DCYC_Pos // 2N dummy cycles
166171
| 0 << QUADSPI_CCR_ABSIZE_Pos // 8-bit alternate byte
167172
| 3 << QUADSPI_CCR_ABMODE_Pos // alternate byte on 4 lines
168-
| QSPI_ADSIZE << QUADSPI_CCR_ADSIZE_Pos
173+
| adsize << QUADSPI_CCR_ADSIZE_Pos
169174
| 3 << QUADSPI_CCR_ADMODE_Pos // address on 4 lines
170175
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
171-
| QSPI_CMD << QUADSPI_CCR_INSTRUCTION_Pos
176+
| cmd << QUADSPI_CCR_INSTRUCTION_Pos
172177
;
173178

174179
qspi_mpu_enable_mapped();

0 commit comments

Comments
 (0)