Skip to content

Commit 7ee5afe

Browse files
pi-anldpgeorge
authored andcommitted
drivers/bus: Detect QSPI transfer errors and pass up to spiflash driver.
This changes the signatures of QSPI write_cmd_data, write_cmd_addr_data and read_cmd_qaddr_qdata so they return an error code. The softqspi and stm32 hardware qspi driver are updated to follow this new signature. Also the spiflash driver is updated to use these new return values. Signed-off-by: Damien George <damien@micropython.org>
1 parent ab0258f commit 7ee5afe

File tree

6 files changed

+117
-53
lines changed

6 files changed

+117
-53
lines changed

drivers/bus/qspi.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ enum {
4141

4242
typedef struct _mp_qspi_proto_t {
4343
int (*ioctl)(void *self, uint32_t cmd);
44-
void (*write_cmd_data)(void *self, uint8_t cmd, size_t len, uint32_t data);
45-
void (*write_cmd_addr_data)(void *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src);
44+
int (*write_cmd_data)(void *self, uint8_t cmd, size_t len, uint32_t data);
45+
int (*write_cmd_addr_data)(void *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src);
4646
uint32_t (*read_cmd)(void *self, uint8_t cmd, size_t len);
47-
void (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest);
47+
int (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest);
4848
} mp_qspi_proto_t;
4949

5050
typedef struct _mp_soft_qspi_obj_t {

drivers/bus/softqspi.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,22 +158,24 @@ STATIC void mp_soft_qspi_qwrite(mp_soft_qspi_obj_t *self, size_t len, const uint
158158
//mp_hal_pin_input(self->io1);
159159
}
160160

161-
STATIC void mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, uint32_t data) {
161+
STATIC int mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, uint32_t data) {
162162
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
163163
uint32_t cmd_buf = cmd | data << 8;
164164
CS_LOW(self);
165165
mp_soft_qspi_transfer(self, 1 + len, (uint8_t*)&cmd_buf, NULL);
166166
CS_HIGH(self);
167+
return 0;
167168
}
168169

169-
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) {
170+
STATIC int mp_soft_qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src) {
170171
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
171172
uint8_t cmd_buf[5] = {cmd};
172173
uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr);
173174
CS_LOW(self);
174175
mp_soft_qspi_transfer(self, addr_len + 1, cmd_buf, NULL);
175176
mp_soft_qspi_transfer(self, len, src, NULL);
176177
CS_HIGH(self);
178+
return 0;
177179
}
178180

179181
STATIC uint32_t mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len) {
@@ -185,7 +187,7 @@ STATIC uint32_t mp_soft_qspi_read_cmd(void *self_in, uint8_t cmd, size_t len) {
185187
return cmd_buf >> 8;
186188
}
187189

188-
STATIC void mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
190+
STATIC int mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) {
189191
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
190192
uint8_t cmd_buf[7] = {cmd};
191193
uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr);
@@ -194,6 +196,7 @@ STATIC void mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32
194196
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)
195197
mp_soft_qspi_qread(self, len, dest);
196198
CS_HIGH(self);
199+
return 0;
197200
}
198201

199202
const mp_qspi_proto_t mp_soft_qspi_proto = {

drivers/memory/spiflash.c

Lines changed: 63 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,22 @@ STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) {
7070
}
7171
}
7272

73-
STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) {
73+
STATIC int mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) {
74+
int ret = 0;
7475
const mp_spiflash_config_t *c = self->config;
7576
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
7677
// Note: len/data are unused for standard SPI
7778
mp_hal_pin_write(c->bus.u_spi.cs, 0);
7879
c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL);
7980
mp_hal_pin_write(c->bus.u_spi.cs, 1);
8081
} else {
81-
c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data);
82+
ret = c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data);
8283
}
84+
return ret;
8385
}
8486

85-
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) {
87+
STATIC int 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) {
88+
int ret = 0;
8689
const mp_spiflash_config_t *c = self->config;
8790
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
8891
uint8_t buf[5] = {cmd, 0};
@@ -98,11 +101,12 @@ STATIC void mp_spiflash_transfer_cmd_addr_data(mp_spiflash_t *self, uint8_t cmd,
98101
mp_hal_pin_write(c->bus.u_spi.cs, 1);
99102
} else {
100103
if (dest != NULL) {
101-
c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, cmd, addr, len, dest);
104+
ret = c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, cmd, addr, len, dest);
102105
} else {
103-
c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src);
106+
ret = c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src);
104107
}
105108
}
109+
return ret;
106110
}
107111

108112
STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t len) {
@@ -119,19 +123,19 @@ STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t le
119123
}
120124
}
121125

122-
STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
126+
STATIC int mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
123127
const mp_spiflash_config_t *c = self->config;
124128
uint8_t cmd;
125129
if (c->bus_kind == MP_SPIFLASH_BUS_SPI) {
126130
cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_READ_32 : CMD_READ;
127131
} else {
128132
cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_C4READ_32 : CMD_C4READ;
129133
}
130-
mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, NULL, dest);
134+
return mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, NULL, dest);
131135
}
132136

133-
STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) {
134-
mp_spiflash_write_cmd_data(self, cmd, 0, 0);
137+
STATIC int mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) {
138+
return mp_spiflash_write_cmd_data(self, cmd, 0, 0);
135139
}
136140

137141
STATIC int mp_spiflash_wait_sr(mp_spiflash_t *self, uint8_t mask, uint8_t val, uint32_t timeout) {
@@ -208,36 +212,50 @@ void mp_spiflash_deepsleep(mp_spiflash_t *self, int value) {
208212
}
209213

210214
STATIC int mp_spiflash_erase_block_internal(mp_spiflash_t *self, uint32_t addr) {
215+
int ret = 0;
211216
// enable writes
212-
mp_spiflash_write_cmd(self, CMD_WREN);
217+
ret = mp_spiflash_write_cmd(self, CMD_WREN);
218+
if (ret != 0) {
219+
return ret;
220+
}
213221

214222
// wait WEL=1
215-
int ret = mp_spiflash_wait_wel1(self);
223+
ret = mp_spiflash_wait_wel1(self);
216224
if (ret != 0) {
217225
return ret;
218226
}
219227

220228
// erase the sector
221229
uint8_t cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_SEC_ERASE_32 : CMD_SEC_ERASE;
222-
mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, 0, NULL, NULL);
230+
ret = mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, 0, NULL, NULL);
231+
if (ret != 0) {
232+
return ret;
233+
}
223234

224235
// wait WIP=0
225236
return mp_spiflash_wait_wip0(self);
226237
}
227238

228239
STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
240+
int ret = 0;
229241
// enable writes
230-
mp_spiflash_write_cmd(self, CMD_WREN);
242+
ret = mp_spiflash_write_cmd(self, CMD_WREN);
243+
if (ret != 0) {
244+
return ret;
245+
}
231246

232247
// wait WEL=1
233-
int ret = mp_spiflash_wait_wel1(self);
248+
ret = mp_spiflash_wait_wel1(self);
234249
if (ret != 0) {
235250
return ret;
236251
}
237252

238253
// write the page
239254
uint8_t cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_WRITE_32 : CMD_WRITE;
240-
mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, src, NULL);
255+
ret = mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, src, NULL);
256+
if (ret != 0) {
257+
return ret;
258+
}
241259

242260
// wait WIP=0
243261
return mp_spiflash_wait_wip0(self);
@@ -253,13 +271,14 @@ int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr) {
253271
return ret;
254272
}
255273

256-
void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
274+
int mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
257275
if (len == 0) {
258-
return;
276+
return 0;
259277
}
260278
mp_spiflash_acquire_bus(self);
261-
mp_spiflash_read_data(self, addr, len, dest);
279+
int ret = mp_spiflash_read_data(self, addr, len, dest);
262280
mp_spiflash_release_bus(self);
281+
return ret;
263282
}
264283

265284
int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
@@ -289,9 +308,9 @@ int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint
289308

290309
#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
291310

292-
void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
311+
int mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
293312
if (len == 0) {
294-
return;
313+
return 0;
295314
}
296315
mp_spiflash_acquire_bus(self);
297316
mp_spiflash_cache_t *cache = self->config->cache;
@@ -304,7 +323,11 @@ void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uin
304323
if (bis < cache->block) {
305324
// Read direct from flash for first part
306325
rest = cache->block * SECTOR_SIZE - addr;
307-
mp_spiflash_read_data(self, addr, rest, dest);
326+
int ret = mp_spiflash_read_data(self, addr, rest, dest);
327+
if (ret != 0) {
328+
mp_spiflash_release_bus(self);
329+
return ret;
330+
}
308331
len -= rest;
309332
dest += rest;
310333
addr += rest;
@@ -318,21 +341,22 @@ void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uin
318341
len -= rest;
319342
if (len == 0) {
320343
mp_spiflash_release_bus(self);
321-
return;
344+
return 0;
322345
}
323346
dest += rest;
324347
addr += rest;
325348
}
326349
}
327350
// Read rest direct from flash
328-
mp_spiflash_read_data(self, addr, len, dest);
351+
int ret = mp_spiflash_read_data(self, addr, len, dest);
329352
mp_spiflash_release_bus(self);
353+
return ret;
330354
}
331355

332-
STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {
356+
STATIC int mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {
333357
#if USE_WR_DELAY
334358
if (!(self->flags & 1)) {
335-
return;
359+
return 0;
336360
}
337361

338362
self->flags &= ~1;
@@ -342,24 +366,26 @@ STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {
342366
// Erase sector
343367
int ret = mp_spiflash_erase_block_internal(self, cache->block * SECTOR_SIZE);
344368
if (ret != 0) {
345-
return;
369+
return ret;
346370
}
347371

348372
// Write
349373
for (int i = 0; i < 16; i += 1) {
350374
uint32_t addr = cache->block * SECTOR_SIZE + i * PAGE_SIZE;
351375
int ret = mp_spiflash_write_page(self, addr, PAGE_SIZE, cache->buf + i * PAGE_SIZE);
352376
if (ret != 0) {
353-
return;
377+
return ret;
354378
}
355379
}
356380
#endif
381+
return 0;
357382
}
358383

359-
void mp_spiflash_cache_flush(mp_spiflash_t *self) {
384+
int mp_spiflash_cache_flush(mp_spiflash_t *self) {
360385
mp_spiflash_acquire_bus(self);
361-
mp_spiflash_cache_flush_internal(self);
386+
int ret = mp_spiflash_cache_flush_internal(self);
362387
mp_spiflash_release_bus(self);
388+
return ret;
363389
}
364390

365391
STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
@@ -389,10 +415,16 @@ STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, siz
389415
// Read sector
390416
#if USE_WR_DELAY
391417
if (cache->block != 0xffffffff) {
392-
mp_spiflash_cache_flush_internal(self);
418+
int ret = mp_spiflash_cache_flush_internal(self);
419+
if (ret != 0) {
420+
return ret;
421+
}
393422
}
394423
#endif
395-
mp_spiflash_read_data(self, addr, SECTOR_SIZE, cache->buf);
424+
int ret = mp_spiflash_read_data(self, addr, SECTOR_SIZE, cache->buf);
425+
if (ret != 0) {
426+
return ret;
427+
}
396428
}
397429

398430
#if USE_WR_DELAY

drivers/memory/spiflash.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,13 @@ void mp_spiflash_deepsleep(mp_spiflash_t *self, int value);
7676

7777
// These functions go direct to the SPI flash device
7878
int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr);
79-
void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest);
79+
int mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest);
8080
int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src);
8181

8282
#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
8383
// These functions use the cache (which must already be configured)
84-
void mp_spiflash_cache_flush(mp_spiflash_t *self);
85-
void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest);
84+
int mp_spiflash_cache_flush(mp_spiflash_t *self);
85+
int mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest);
8686
int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src);
8787
#endif
8888

0 commit comments

Comments
 (0)