8000 spiflash: Support spi/qspi flash chips over 16MB. · micropython/micropython@4bd0643 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4bd0643

Browse files
andrewleechpi-anl
authored andcommitted
spiflash: Support spi/qspi flash chips over 16MB.
Over 16MB, 32-bit addressing is required rather than the standard 24-bit.
1 parent 3032ae1 commit 4bd0643

File tree

4 files changed

+64
-27
lines changed

4 files changed

+64
-27
lines changed

drivers/bus/qspi.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@ typedef struct _mp_soft_qspi_obj_t {
5252
mp_hal_pin_obj_t io3;
5353
} mp_soft_qspi_obj_t;
5454

55+
#define MP_SPI_ADDR_32B(addr) (addr & 0xF000)
56+
57+
STATIC inline uint8_t mp_spi_set_addr_buff(uint8_t *buf, uint32_t addr) {
58+
if(MP_SPI_ADDR_32B(addr)) {
59+
buf[0] = addr >> 24;
60+
buf[1] = addr >> 16;
61+
buf[2] = addr >> 8;
62+
buf[3] = addr;
63+
return 4;
64+
} else {
65+
buf[0] = addr >> 16;
66+
buf[1] = addr >> 8;
67+
buf[2] = addr;
68+
return 3;
69+
}
70+
}
5571
extern const mp_qspi_proto_t mp_soft_qspi_proto;
5672

5773
#endif // MICROPY_INCLUDED_DRIVERS_BUS_QSPI_H

drivers/bus/softqspi.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,9 +168,10 @@ STATIC void mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len,
168168

169169
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) {
170170
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
171-
uint8_t cmd_buf[4] = {cmd, addr >> 16, addr >> 8, addr};
171+
uint8_t cmd_buf[4] = {cmd};
172+
uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr);
172173
CS_LOW(self);
173-
mp_soft_qspi_transfer(self, 4, cmd_buf, NULL);
174+
mp_soft_qspi_transfer(self, addr_len+1, cmd_buf, NULL);
174175
mp_soft_qspi_transfer(self, len, src, NULL);
175176
CS_HIGH(self);
176177
}
@@ -186,10 +187,11 @@ STATIC uint32_t mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len) {
186187

187188
STATIC void mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
188189
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
189-
uint8_t cmd_buf[7] = {cmd, addr >> 16, addr >> 8, addr};
190+
uint8_t cmd_buf[7] = {cmd};
191+
uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr);
190192
CS_LOW(self);
191193
mp_soft_qspi_transfer(self, 1, cmd_buf, NULL);
192-
mp_soft_qspi_qwrite(self, 6, &cmd_buf[1]); // 3 addr bytes, 1 extra byte (0), 2 dummy bytes (4 dummy cycles)
194+
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)
193195
mp_soft_qspi_qread(self, len, dest);
194196
CS_HIGH(self);
195197
}

drivers/memory/spiflash.c

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@
4444
#define CMD_RD_DEVID (0x9f)
4545
#define CMD_CHIP_ERASE (0xc7)
4646
#define CMD_C4READ (0xeb)
47+
// 32 bit addressing commands
48+
#define CMD_WRITE_32 (0x12)
49+
#define CMD_READ_32 (0x13)
50+
#define CMD_SEC_ERASE_32 (0x21)
51+
#define CMD_C4READ_32 (0xec)
4752

4853
#define WAIT_SR_TIMEOUT (1000000)
4954

@@ -76,18 +81,26 @@ STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t
7681
}
7782
}
7883

79-
STATIC void mp_spiflash_write_cmd_addr_data(mp_spiflash_t *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
84+
STATIC void mp_spiflash_transfer_cmd_addr_data(mp_spiflash_t *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src, uint8_t *dest) {
8085
const mp_spiflash_config_t *c = self->config;
8186
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
82-
uint8_t buf[4] = {cmd, addr >> 16, addr >> 8, addr};
87+
uint8_t buf[5] = {cmd, 0};
88+
uint8_t buff_len = 1 + mp_spi_set_addr_buff(&buf[1], addr);
8389
mp_hal_pin_write(c->bus.u_spi.cs, 0);
84-
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL);
85-
if (len) {
90+
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, buff_len, buf, NULL);
91+
if (len && (src != NULL)) {
8692
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, src, NULL);
93+
} else if (len && (dest != NULL)) {
94+
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, dest, dest);
8795
}
96+
8897
mp_hal_pin_write(c->bus.u_spi.cs, 1);
8998
} else {
90-
c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src);
99+
if (dest != NULL) {
100+
c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, cmd, addr, len, dest);
101+
} else {
102+
c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src);
103+
}
91104
}
92105
}
93106

@@ -108,24 +121,16 @@ STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t le
108121
STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
109122
const mp_spiflash_config_t *c = self->config;
110123
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
111-
uint8_t buf[4] = {CMD_READ, addr >> 16, addr >> 8, addr};
112-
mp_hal_pin_write(c->bus.u_spi.cs, 0);
113-
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 4, buf, NULL);
114-
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, len, dest, dest);
115-
mp_hal_pin_write(c->bus.u_spi.cs, 1);
124+
mp_spiflash_transfer_cmd_addr_data(self, MP_SPI_ADDR_32B(addr)?CMD_READ_32:CMD_READ, addr, len, NULL, dest);
116125
} else {
117-
c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, CMD_C4READ, addr, len, dest);
126+
mp_spiflash_transfer_cmd_addr_data(self, MP_SPI_ADDR_32B(addr)?CMD_C4READ_32:CMD_C4READ, addr, len, NULL, dest);
118127
}
119128
}
120129

121130
STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) {
122131
mp_spiflash_write_cmd_data(self, cmd, 0, 0);
123132
}
124133

125-
STATIC void mp_spiflash_write_cmd_addr(mp_spiflash_t *self, uint8_t cmd, uint32_t addr) {
126-
mp_spiflash_write_cmd_addr_data(self, cmd, addr, 0, NULL);
127-
}
128-
129134
STATIC int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) {
130135
uint8_t sr;
131136
do {
@@ -210,7 +215,7 @@ STATIC int mp_spiflash_erase_block_internal(mp_spiflash_t *self, uint32_t addr)
210215
}
211216

212217
// erase the sector
213-
mp_spiflash_write_cmd_addr(self, CMD_SEC_ERASE, addr);
218+
mp_spiflash_transfer_cmd_addr_data(self, MP_SPI_ADDR_32B(addr)?CMD_SEC_ERASE_32:CMD_SEC_ERASE, addr, 0, NULL, NULL);
214219

215220
// wait WIP=0
216221
return mp_spiflash_wait_wip0(self);
@@ -227,7 +232,7 @@ STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len
227232
}
228233

229234
// write the page
230-
mp_spiflash_write_cmd_addr_data(self, CMD_WRITE, addr, len, src);
235+
mp_spiflash_transfer_cmd_addr_data(self, MP_SPI_ADDR_32B(addr)?CMD_WRITE_32:CMD_WRITE, addr, len, src, NULL);
231236

232237
// wait WIP=0
233238
return mp_spiflash_wait_wip0(self);

ports/stm32/qspi.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252
#define MICROPY_HW_QSPI_CS_HIGH_CYCLES 2 // nCS stays high for 2 cycles
5353
#endif
5454

55+
#if (MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2 -3 -1) >= 24
56+
#define QSPI_CMD 0xec
57+
#define QSPI_ADSIZE 3
58+
#else
59+
#define QSPI_CMD 0xeb
60+
#define QSPI_ADSIZE 2
61+
#endif
62+
5563
static inline void qspi_mpu_disable_all(void) {
5664
// Configure MPU to disable access to entire QSPI region, to prevent CPU
5765
// speculative execution from accessing this region and modifying QSPI registers.
@@ -112,10 +120,11 @@ void qspi_init(void) {
112120
;
113121
}
114122

115-
void qspi_memory_map(void) {
123+
void qspi_memory_map() {
116124
// Enable memory-mapped mode
117125

118126
QUADSPI->ABR = 0; // disable continuous read mode
127+
119128
QUADSPI->CCR =
120129
0 << QUADSPI_CCR_DDRM_Pos // DDR mode disabled
121130
| 0 << QUADSPI_CCR_SIOO_Pos // send instruction every transaction
@@ -124,10 +133,10 @@ void qspi_memory_map(void) {
124133
| 4 << QUADSPI_CCR_DCYC_Pos // 4 dummy cycles
125134
| 0 << QUADSPI_CCR_ABSIZE_Pos // 8-bit alternate byte
126135
| 3 << QUADSPI_CCR_ABMODE_Pos // alternate byte on 4 lines
127-
| 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
136+
| QSPI_ADSIZE << QUADSPI_CCR_ADSIZE_Pos
128137
| 3 << QUADSPI_CCR_ADMODE_Pos // address on 4 lines
129138
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
130-
| 0xeb << QUADSPI_CCR_INSTRUCTION_Pos // quad read opcode
139+
| QSPI_CMD << QUADSPI_CCR_INSTRUCTION_Pos
131140
;
132141

133142
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
203212
STATIC void qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
204213
(void)self_in;
205214

215+
uint8_t adsize = MP_SPI_ADDR_32B(addr)? 3:2;
216+
206217
QUADSPI->FCR = QUADSPI_FCR_CTCF; // clear TC flag
207218

208219
if (len == 0) {
@@ -213,7 +224,7 @@ STATIC void qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr,
213224
| 0 << QUADSPI_CCR_DMODE_Pos // no data
214225
| 0 << QUADSPI_CCR_DCYC_Pos // 0 dummy cycles
215226
| 0 << QUADSPI_CCR_ABMODE_Pos // no alternate byte
216-
| 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
227+
| adsize << QUADSPI_CCR_ADSIZE_Pos // 32/24-bit address size
217228
| 1 << QUADSPI_CCR_ADMODE_Pos // address on 1 line
218229
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
219230
| 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,
230241
| 1 << QUADSPI_CCR_DMODE_Pos // data on 1 line
231242
| 0 << QUADSPI_CCR_DCYC_Pos // 0 dummy cycles
232243
| 0 << QUADSPI_CCR_ABMODE_Pos // no alternate byte
233-
| 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
244+
| adsize << QUADSPI_CCR_ADSIZE_Pos // 32/24-bit address size
234245
| 1 << QUADSPI_CCR_ADMODE_Pos // address on 1 line
235246
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
236247
| 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) {
285296

286297
STATIC void qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
287298
(void)self_in;
299+
300+
uint8_t adsize = MP_SPI_ADDR_32B(addr)? 3:2;
301+
288302
QUADSPI->FCR = QUADSPI_FCR_CTCF; // clear TC flag
289303

290304
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,
297311
| 4 << QUADSPI_CCR_DCYC_Pos // 4 dummy cycles
298312
| 0 << QUADSPI_CCR_ABSIZE_Pos // 8-bit alternate byte
299313
| 3 << QUADSPI_CCR_ABMODE_Pos // alternate byte on 4 lines
300-
| 2 << QUADSPI_CCR_ADSIZE_Pos // 24-bit address size
314+
| adsize << QUADSPI_CCR_ADSIZE_Pos // 32 or 24-bit address size
301315
| 3 << QUADSPI_CCR_ADMODE_Pos // address on 4 lines
302316
| 1 << QUADSPI_CCR_IMODE_Pos // instruction on 1 line
303317
| cmd << QUADSPI_CCR_INSTRUCTION_Pos // quad read opcode

0 commit comments

Comments
 (0)
0