diff options
| author | Andrew Leech | 2020-01-28 14:59:05 +1100 |
|---|---|---|
| committer | Damien George | 2020-01-30 13:18:38 +1100 |
| commit | 30501d3f54fa642770faefa117b4c39d95aff549 (patch) | |
| tree | eb2c16166bec7b7d8273193fb7bc696a00c89d00 /drivers/bus | |
| parent | b72cb0ca1bb27396a5dcba9ce8a6f00dbd3d5f19 (diff) | |
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 'drivers/bus')
| -rw-r--r-- | drivers/bus/qspi.h | 17 | ||||
| -rw-r--r-- | drivers/bus/softqspi.c | 10 |
2 files changed, 23 insertions, 4 deletions
diff --git a/drivers/bus/qspi.h b/drivers/bus/qspi.h index 31c9d14fc..c82796fac 100644 --- a/drivers/bus/qspi.h +++ b/drivers/bus/qspi.h @@ -28,6 +28,8 @@ #include "py/mphal.h" +#define MP_SPI_ADDR_IS_32B(addr) (addr & 0xff000000) + enum { MP_QSPI_IOCTL_INIT, MP_QSPI_IOCTL_DEINIT, @@ -54,4 +56,19 @@ typedef struct _mp_soft_qspi_obj_t { extern const mp_qspi_proto_t mp_soft_qspi_proto; +static inline uint8_t mp_spi_set_addr_buff(uint8_t *buf, uint32_t addr) { + if (MP_SPI_ADDR_IS_32B(addr)) { + buf[0] = addr >> 24; + buf[1] = addr >> 16; + buf[2] = addr >> 8; + buf[3] = addr; + return 4; + } else { + buf[0] = addr >> 16; + buf[1] = addr >> 8; + buf[2] = addr; + return 3; + } +} + #endif // MICROPY_INCLUDED_DRIVERS_BUS_QSPI_H diff --git a/drivers/bus/softqspi.c b/drivers/bus/softqspi.c index 10c599246..71ab55976 100644 --- a/drivers/bus/softqspi.c +++ b/drivers/bus/softqspi.c @@ -168,9 +168,10 @@ STATIC void mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, STATIC void mp_soft_qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) { mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in; - uint8_t cmd_buf[4] = {cmd, addr >> 16, addr >> 8, addr}; + uint8_t cmd_buf[5] = {cmd}; + uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr); CS_LOW(self); - mp_soft_qspi_transfer(self, 4, cmd_buf, NULL); + mp_soft_qspi_transfer(self, addr_len + 1, cmd_buf, NULL); mp_soft_qspi_transfer(self, len, src, NULL); CS_HIGH(self); } @@ -186,10 +187,11 @@ STATIC uint32_t mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len) { STATIC void mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) { mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in; - uint8_t cmd_buf[7] = {cmd, addr >> 16, addr >> 8, addr}; + uint8_t cmd_buf[7] = {cmd}; + uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr); CS_LOW(self); mp_soft_qspi_transfer(self, 1, cmd_buf, NULL); - mp_soft_qspi_qwrite(self, 6, &cmd_buf[1]); // 3 addr bytes, 1 extra byte (0), 2 dummy bytes (4 dummy cycles) + mp_soft_qspi_qwrite(self, addr_len + 3, &cmd_buf[1]); // 3/4 addr bytes, 1 extra byte (0), 2 dummy bytes (4 dummy cycles) mp_soft_qspi_qread(self, len, dest); CS_HIGH(self); } |
