diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/bus/qspi.h | 6 | ||||
| -rw-r--r-- | drivers/bus/softqspi.c | 9 | ||||
| -rw-r--r-- | drivers/memory/spiflash.c | 94 | ||||
| -rw-r--r-- | drivers/memory/spiflash.h | 6 |
4 files changed, 75 insertions, 40 deletions
diff --git a/drivers/bus/qspi.h b/drivers/bus/qspi.h index 7dfaaf3d4..33f482127 100644 --- a/drivers/bus/qspi.h +++ b/drivers/bus/qspi.h @@ -41,10 +41,10 @@ enum { typedef struct _mp_qspi_proto_t { int (*ioctl)(void *self, uint32_t cmd); - void (*write_cmd_data)(void *self, uint8_t cmd, size_t len, uint32_t data); - void (*write_cmd_addr_data)(void *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src); + int (*write_cmd_data)(void *self, uint8_t cmd, size_t len, uint32_t data); + int (*write_cmd_addr_data)(void *self, uint8_t cmd, uint32_t addr, size_t len, const uint8_t *src); uint32_t (*read_cmd)(void *self, uint8_t cmd, size_t len); - void (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest); + int (*read_cmd_qaddr_qdata)(void *self, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest); } mp_qspi_proto_t; typedef struct _mp_soft_qspi_obj_t { diff --git a/drivers/bus/softqspi.c b/drivers/bus/softqspi.c index 71ab55976..6ede29dcd 100644 --- a/drivers/bus/softqspi.c +++ b/drivers/bus/softqspi.c @@ -158,15 +158,16 @@ STATIC void mp_soft_qspi_qwrite(mp_soft_qspi_obj_t *self, size_t len, const uint //mp_hal_pin_input(self->io1); } -STATIC void mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, uint32_t data) { +STATIC int mp_soft_qspi_write_cmd_data(void *self_in, uint8_t cmd, size_t len, uint32_t data) { mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in; uint32_t cmd_buf = cmd | data << 8; CS_LOW(self); mp_soft_qspi_transfer(self, 1 + len, (uint8_t*)&cmd_buf, NULL); CS_HIGH(self); + return 0; } -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) { +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) { mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in; uint8_t cmd_buf[5] = {cmd}; uint8_t addr_len = mp_spi_set_addr_buff(&cmd_buf[1], addr); @@ -174,6 +175,7 @@ STATIC void mp_soft_qspi_write_cmd_addr_data(void *self_in, uint8_t cmd, uint32_ mp_soft_qspi_transfer(self, addr_len + 1, cmd_buf, NULL); mp_soft_qspi_transfer(self, len, src, NULL); CS_HIGH(self); + return 0; } 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) { return cmd_buf >> 8; } -STATIC void mp_soft_qspi_read_cmd_qaddr_qdata(void *self_in, uint8_t cmd, uint32_t addr, size_t len, uint8_t *dest) { +STATIC int 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}; 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 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); + return 0; } const mp_qspi_proto_t mp_soft_qspi_proto = { 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 |
