diff options
Diffstat (limited to 'drivers/memory')
| -rw-r--r-- | drivers/memory/spiflash.c | 94 | ||||
| -rw-r--r-- | drivers/memory/spiflash.h | 6 |
2 files changed, 66 insertions, 34 deletions
diff --git a/drivers/memory/spiflash.c b/drivers/memory/spiflash.c index 9f8dc29a7..a71ef41f4 100644 --- a/drivers/memory/spiflash.c +++ b/drivers/memory/spiflash.c @@ -70,7 +70,8 @@ STATIC void mp_spiflash_release_bus(mp_spiflash_t *self) { } } -STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) { +STATIC int mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t len, uint32_t data) { + int ret = 0; const mp_spiflash_config_t *c = self->config; if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { // Note: len/data are unused for standard SPI @@ -78,11 +79,13 @@ STATIC void mp_spiflash_write_cmd_data(mp_spiflash_t *self, uint8_t cmd, size_t c->bus.u_spi.proto->transfer(c->bus.u_spi.data, 1, &cmd, NULL); mp_hal_pin_write(c->bus.u_spi.cs, 1); } else { - c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data); + ret = c->bus.u_qspi.proto->write_cmd_data(c->bus.u_qspi.data, cmd, len, data); } + return ret; } -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) { +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) { + int ret = 0; const mp_spiflash_config_t *c = self->config; if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { 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, mp_hal_pin_write(c->bus.u_spi.cs, 1); } else { if (dest != NULL) { - c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, cmd, addr, len, dest); + ret = c->bus.u_qspi.proto->read_cmd_qaddr_qdata(c->bus.u_qspi.data, cmd, addr, len, dest); } else { - c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src); + ret = c->bus.u_qspi.proto->write_cmd_addr_data(c->bus.u_qspi.data, cmd, addr, len, src); } } + return ret; } STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t len) { @@ -119,7 +123,7 @@ STATIC uint32_t mp_spiflash_read_cmd(mp_spiflash_t *self, uint8_t cmd, size_t le } } -STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { +STATIC int mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { const mp_spiflash_config_t *c = self->config; uint8_t cmd; if (c->bus_kind == MP_SPIFLASH_BUS_SPI) { @@ -127,11 +131,11 @@ STATIC void mp_spiflash_read_data(mp_spiflash_t *self, uint32_t addr, size_t len } else { cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_C4READ_32 : CMD_C4READ; } - mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, NULL, dest); + return mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, NULL, dest); } -STATIC void mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) { - mp_spiflash_write_cmd_data(self, cmd, 0, 0); +STATIC int mp_spiflash_write_cmd(mp_spiflash_t *self, uint8_t cmd) { + return mp_spiflash_write_cmd_data(self, cmd, 0, 0); } 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) { } STATIC int mp_spiflash_erase_block_internal(mp_spiflash_t *self, uint32_t addr) { + int ret = 0; // enable writes - mp_spiflash_write_cmd(self, CMD_WREN); + ret = mp_spiflash_write_cmd(self, CMD_WREN); + if (ret != 0) { + return ret; + } // wait WEL=1 - int ret = mp_spiflash_wait_wel1(self); + ret = mp_spiflash_wait_wel1(self); if (ret != 0) { return ret; } // erase the sector uint8_t cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_SEC_ERASE_32 : CMD_SEC_ERASE; - mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, 0, NULL, NULL); + ret = mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, 0, NULL, NULL); + if (ret != 0) { + return ret; + } // wait WIP=0 return mp_spiflash_wait_wip0(self); } STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) { + int ret = 0; // enable writes - mp_spiflash_write_cmd(self, CMD_WREN); + ret = mp_spiflash_write_cmd(self, CMD_WREN); + if (ret != 0) { + return ret; + } // wait WEL=1 - int ret = mp_spiflash_wait_wel1(self); + ret = mp_spiflash_wait_wel1(self); if (ret != 0) { return ret; } // write the page uint8_t cmd = MICROPY_HW_SPI_ADDR_IS_32BIT(addr) ? CMD_WRITE_32 : CMD_WRITE; - mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, src, NULL); + ret = mp_spiflash_transfer_cmd_addr_data(self, cmd, addr, len, src, NULL); + if (ret != 0) { + return ret; + } // wait WIP=0 return mp_spiflash_wait_wip0(self); @@ -253,13 +271,14 @@ int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr) { return ret; } -void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { +int mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { if (len == 0) { - return; + return 0; } mp_spiflash_acquire_bus(self); - mp_spiflash_read_data(self, addr, len, dest); + int ret = mp_spiflash_read_data(self, addr, len, dest); mp_spiflash_release_bus(self); + return ret; } 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 #if MICROPY_HW_SPIFLASH_ENABLE_CACHE -void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { +int mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) { if (len == 0) { - return; + return 0; } mp_spiflash_acquire_bus(self); 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 if (bis < cache->block) { // Read direct from flash for first part rest = cache->block * SECTOR_SIZE - addr; - mp_spiflash_read_data(self, addr, rest, dest); + int ret = mp_spiflash_read_data(self, addr, rest, dest); + if (ret != 0) { + mp_spiflash_release_bus(self); + return ret; + } len -= rest; dest += rest; addr += rest; @@ -318,21 +341,22 @@ void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uin len -= rest; if (len == 0) { mp_spiflash_release_bus(self); - return; + return 0; } dest += rest; addr += rest; } } // Read rest direct from flash - mp_spiflash_read_data(self, addr, len, dest); + int ret = mp_spiflash_read_data(self, addr, len, dest); mp_spiflash_release_bus(self); + return ret; } -STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) { +STATIC int mp_spiflash_cache_flush_internal(mp_spiflash_t *self) { #if USE_WR_DELAY if (!(self->flags & 1)) { - return; + return 0; } self->flags &= ~1; @@ -342,7 +366,7 @@ STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) { // Erase sector int ret = mp_spiflash_erase_block_internal(self, cache->block * SECTOR_SIZE); if (ret != 0) { - return; + return ret; } // Write @@ -350,16 +374,18 @@ STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) { uint32_t addr = cache->block * SECTOR_SIZE + i * PAGE_SIZE; int ret = mp_spiflash_write_page(self, addr, PAGE_SIZE, cache->buf + i * PAGE_SIZE); if (ret != 0) { - return; + return ret; } } #endif + return 0; } -void mp_spiflash_cache_flush(mp_spiflash_t *self) { +int mp_spiflash_cache_flush(mp_spiflash_t *self) { mp_spiflash_acquire_bus(self); - mp_spiflash_cache_flush_internal(self); + int ret = mp_spiflash_cache_flush_internal(self); mp_spiflash_release_bus(self); + return ret; } 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 // Read sector #if USE_WR_DELAY if (cache->block != 0xffffffff) { - mp_spiflash_cache_flush_internal(self); + int ret = mp_spiflash_cache_flush_internal(self); + if (ret != 0) { + return ret; + } } #endif - mp_spiflash_read_data(self, addr, SECTOR_SIZE, cache->buf); + int ret = mp_spiflash_read_data(self, addr, SECTOR_SIZE, cache->buf); + if (ret != 0) { + return ret; + } } #if USE_WR_DELAY diff --git a/drivers/memory/spiflash.h b/drivers/memory/spiflash.h index c4162ff21..5ccf7d44c 100644 --- a/drivers/memory/spiflash.h +++ b/drivers/memory/spiflash.h @@ -76,13 +76,13 @@ void mp_spiflash_deepsleep(mp_spiflash_t *self, int value); // These functions go direct to the SPI flash device int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr); -void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); +int mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src); #if MICROPY_HW_SPIFLASH_ENABLE_CACHE // These functions use the cache (which must already be configured) -void mp_spiflash_cache_flush(mp_spiflash_t *self); -void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); +int mp_spiflash_cache_flush(mp_spiflash_t *self); +int mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest); int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src); #endif |
