summaryrefslogtreecommitdiffstatshomepage
path: root/ports/stm32/qspi.c
diff options
context:
space:
mode:
authorAndrew Leech <andrew.leech@planetinnovation.com.au>2020-01-28 14:59:05 +1100
committerDamien George <damien.p.george@gmail.com>2020-01-30 13:18:38 +1100
commit30501d3f54fa642770faefa117b4c39d95aff549 (patch)
treeeb2c16166bec7b7d8273193fb7bc696a00c89d00 /ports/stm32/qspi.c
parentb72cb0ca1bb27396a5dcba9ce8a6f00dbd3d5f19 (diff)
downloadmicropython-30501d3f54fa642770faefa117b4c39d95aff549.tar.gz
micropython-30501d3f54fa642770faefa117b4c39d95aff549.zip
drivers, stm32: Support SPI/QSPI flash chips over 16MB.
With a SPI flash that has more than 16MB, 32-bit addressing is required rather than the standard 24-bit. This commit adds support for 32-bit addressing so that the SPI flash commands (read/write/erase) are selected automatically depending on the size of the address being used at each operation.
Diffstat (limited to 'ports/stm32/qspi.c')
-rw-r--r--ports/stm32/qspi.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/ports/stm32/qspi.c b/ports/stm32/qspi.c
index 30ee2c9ea7..20cdafb00d 100644
--- a/ports/stm32/qspi.c
+++ b/ports/stm32/qspi.c
@@ -52,6 +52,14 @@
#define MICROPY_HW_QSPI_CS_HIGH_CYCLES 2 // nCS stays high for 2 cycles
#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 inline void qspi_mpu_disable_all(void) {
// Configure MPU to disable access to entire QSPI region, to prevent CPU
// speculative execution from accessing this region and modifying QSPI registers.
@@ -116,6 +124,7 @@ void qspi_memory_map(void) {
// Enable memory-mapped mode
QUADSPI->ABR = 0; // disable continuous read mode
+
QUADSPI->CCR =
0 << QUADSPI_CCR_DDRM_Pos // DDR mode disabled
| 0 << QUADSPI_CCR_SIOO_Pos // send instruction every transaction
@@ -124,10 +133,10 @@ void qspi_memory_map(void) {
| 4 << QUADSPI_CCR_DCYC_Pos // 4 dummy cycles
| 0 << QUADSPI_CCR_ABSIZE_Pos // 8-bit alternate byte
| 3 << QUADSPI_CCR_ABMODE_Pos // alternate byte on 4 lines
- | 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
+ | QSPI_ADSIZE << QUADSPI_CCR_ADSIZE_Pos
| 3 << QUADSPI_CCR_ADMODE_Pos // address on 4 lines
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
- | 0xeb << QUADSPI_CCR_INSTRUCTION_Pos // quad read opcode
+ | QSPI_CMD << QUADSPI_CCR_INSTRUCTION_Pos
;
qspi_mpu_enable_mapped();
@@ -203,6 +212,8 @@ STATIC void qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, uint32_t
STATIC void qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
(void)self_in;
+ uint8_t adsize = MP_SPI_ADDR_IS_32B(addr) ? 3 : 2;
+
QUADSPI->FCR = QUADSPI_FCR_CTCF; // clear TC flag
if (len == 0) {
@@ -213,7 +224,7 @@ STATIC void qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr,
| 0 << QUADSPI_CCR_DMODE_Pos // no data
| 0 << QUADSPI_CCR_DCYC_Pos // 0 dummy cycles
| 0 << QUADSPI_CCR_ABMODE_Pos // no alternate byte
- | 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
+ | adsize << QUADSPI_CCR_ADSIZE_Pos // 32/24-bit address size
| 1 << QUADSPI_CCR_ADMODE_Pos // address on 1 line
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
| cmd << QUADSPI_CCR_INSTRUCTION_Pos // write opcode
@@ -230,7 +241,7 @@ STATIC void qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr,
| 1 << QUADSPI_CCR_DMODE_Pos // data on 1 line
| 0 << QUADSPI_CCR_DCYC_Pos // 0 dummy cycles
| 0 << QUADSPI_CCR_ABMODE_Pos // no alternate byte
- | 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
+ | adsize << QUADSPI_CCR_ADSIZE_Pos // 32/24-bit address size
| 1 << QUADSPI_CCR_ADMODE_Pos // address on 1 line
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
| cmd << QUADSPI_CCR_INSTRUCTION_Pos // write opcode
@@ -285,6 +296,9 @@ STATIC uint32_t qspi_read_cmd(void *self_in, uint8_t cmd, size_t len) {
STATIC void qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
(void)self_in;
+
+ uint8_t adsize = MP_SPI_ADDR_IS_32B(addr) ? 3 : 2;
+
QUADSPI->FCR = QUADSPI_FCR_CTCF; // clear TC flag
QUADSPI->DLR = len - 1; // number of bytes to read
@@ -297,7 +311,7 @@ STATIC void qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr,
| 4 << QUADSPI_CCR_DCYC_Pos // 4 dummy cycles
| 0 << QUADSPI_CCR_ABSIZE_Pos // 8-bit alternate byte
| 3 << QUADSPI_CCR_ABMODE_Pos // alternate byte on 4 lines
- | 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
+ | adsize << QUADSPI_CCR_ADSIZE_Pos // 32 or 24-bit address size
| 3 << QUADSPI_CCR_ADMODE_Pos // address on 4 lines
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
| cmd << QUADSPI_CCR_INSTRUCTION_Pos // quad read opcode