Skip to content

Commit bdc875e

Browse files
committed
drivers/memory/spiflash: Fix bugs in and clean up read/write functions.
mp_spiflash_read had a bug in it where "dest" and "addr" were incremented twice for a certain special case. This was fixed, which then allowed the function to be simplified to reduce code size. mp_spiflash_write had a bug in it where "src" was not incremented correctly for the case where the data to be written included the caching buffer as well as some bytes after this buffer. This was fixed and the resulting code simplified.
1 parent e0bc438 commit bdc875e

1 file changed

Lines changed: 55 additions & 70 deletions

File tree

drivers/memory/spiflash.c

Lines changed: 55 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -233,50 +233,32 @@ void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *d
233233
mp_spiflash_acquire_bus(self);
234234
if (bufuser == self && bufsec != 0xffffffff) {
235235
uint32_t bis = addr / SECTOR_SIZE;
236-
int rest = 0;
237-
if (bis < bufsec) {
238-
rest = bufsec * SECTOR_SIZE - addr;
239-
if (rest > len) {
240-
rest = len;
241-
}
242-
mp_spiflash_read_data(self, addr, rest, dest);
243-
len -= rest;
244-
if (len <= 0) {
245-
mp_spiflash_release_bus(self);
246-
return;
247-
} else {
248-
// Something from buffer...
249-
addr = bufsec * SECTOR_SIZE;
250-
dest += rest;
251-
if (len > SECTOR_SIZE) {
252-
rest = SECTOR_SIZE;
253-
} else {
254-
rest = len;
255-
}
256-
memcpy(dest, buf, rest);
236+
uint32_t bie = (addr + len - 1) / SECTOR_SIZE;
237+
if (bis <= bufsec && bufsec <= bie) {
238+
// Read straddles current buffer
239+
size_t rest = 0;
240+
if (bis < bufsec) {
241+
// Read direct from flash for first part
242+
rest = bufsec * SECTOR_SIZE - addr;
243+
mp_spiflash_read_data(self, addr, rest, dest);
257244
len -= rest;
258-
if (len <= 0) {
259-
mp_spiflash_release_bus(self);
260-
return;
261-
}
262245
dest += rest;
263246
addr += rest;
264247
}
265-
} else if (bis == bufsec) {
266-
uint32_t offset = addr & (SECTOR_SIZE-1);
248+
uint32_t offset = addr & (SECTOR_SIZE - 1);
267249
rest = SECTOR_SIZE - offset;
268250
if (rest > len) {
269251
rest = len;
270252
}
271253
memcpy(dest, &buf[offset], rest);
272254
len -= rest;
273-
if (len <= 0) {
255+
if (len == 0) {
274256
mp_spiflash_release_bus(self);
275257
return;
276258
}
259+
dest += rest;
260+
addr += rest;
277261
}
278-
dest += rest;
279-
addr += rest;
280262
}
281263
// Read rest direct from flash
282264
mp_spiflash_read_data(self, addr, len, dest);
@@ -395,64 +377,67 @@ int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint
395377
uint32_t bie = (addr + len - 1) / SECTOR_SIZE;
396378

397379
mp_spiflash_acquire_bus(self);
380+
398381
if (bufuser == self && bis <= bufsec && bie >= bufsec) {
399-
// Current buffer affected, handle this part first
400-
uint32_t taddr = (bufsec + 1) * SECTOR_SIZE;
401-
int32_t offset = addr - bufsec * SECTOR_SIZE;
402-
int32_t pre = bufsec * SECTOR_SIZE - addr;
403-
if (offset < 0) {
382+
// Write straddles current buffer
383+
uint32_t pre;
384+
uint32_t offset;
385+
if (bufsec * SECTOR_SIZE >= addr) {
386+
pre = bufsec * SECTOR_SIZE - addr;
404387
offset = 0;
405388
} else {
406389
pre = 0;
390+
offset = addr - bufsec * SECTOR_SIZE;
407391
}
408-
int32_t rest = len - pre;
409-
int32_t trail = 0;
410-
if (rest > SECTOR_SIZE - offset) {
411-
trail = rest - (SECTOR_SIZE - offset);
412-
rest = SECTOR_SIZE - offset;
392+
393+
// Write buffered part first
394+
uint32_t len_in_buf = len - pre;
395+
len = 0;
396+
if (len_in_buf > SECTOR_SIZE - offset) {
397+
len = len_in_buf - (SECTOR_SIZE - offset);
398+
len_in_buf = SECTOR_SIZE - offset;
413399
}
414-
memcpy(&buf[offset], &src[pre], rest);
400+
memcpy(&buf[offset], &src[pre], len_in_buf);
415401
self->flags |= 1; // Mark dirty
416-
if ((pre | trail) == 0) {
417-
mp_spiflash_release_bus(self);
418-
return 0;
419-
}
420-
const uint8_t *p = src;
402+
403+
// Write part before buffer sector
421404
while (pre) {
422405
int rest = pre & (SECTOR_SIZE - 1);
423406
if (rest == 0) {
424407
rest = SECTOR_SIZE;
425408
}
426-
mp_spiflash_write_part(self, addr, rest, p);
427-
p += rest;
409+
int ret = mp_spiflash_write_part(self, addr, rest, src);
410+
if (ret != 0) {
411+
mp_spiflash_release_bus(self);
412+
return ret;
413+
}
414+
src += rest;
428415
addr += rest;
429416
pre -= rest;
430417
}
431-
while (trail) {
432-
int rest = trail;
433-
if (rest > SECTOR_SIZE) {
434-
rest = SECTOR_SIZE;
435-
}
436-
mp_spiflash_write_part(self, taddr, rest, src);
437-
src += rest;
438-
taddr += rest;
439-
trail -= rest;
418+
src += len_in_buf;
419+
addr += len_in_buf;
420+
421+
// Fall through to write remaining part
422+
}
423+
424+
uint32_t offset = addr & (SECTOR_SIZE - 1);
425+
while (len) {
426+
int rest = SECTOR_SIZE - offset;
427+
if (rest > len) {
428+
rest = len;
440429
}
441-
} else {
442-
// Current buffer not affected, business as usual
443-
uint32_t offset = addr & (SECTOR_SIZE - 1);
444-
while (len) {
445-
int rest = SECTOR_SIZE - offset;
446-
if (rest > len) {
447-
rest = len;
448-
}
449-
mp_spiflash_write_part(self, addr, rest, src);
450-
len -= rest;
451-
addr += rest;
452-
src += rest;
453-
offset = 0;
430+
int ret = mp_spiflash_write_part(self, addr, rest, src);
431+
if (ret != 0) {
432+
mp_spiflash_release_bus(self);
433+
return ret;
454434
}
435+
len -= rest;
436+
addr += rest;
437+
src += rest;
438+
offset = 0;
455439
}
440+
456441
mp_spiflash_release_bus(self);
457442
return 0;
458443
}

0 commit comments

Comments
 (0)