summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/memory/spiflash.c56
-rw-r--r--drivers/memory/spiflash.h7
2 files changed, 55 insertions, 8 deletions
diff --git a/drivers/memory/spiflash.c b/drivers/memory/spiflash.c
index d750d87be..c0b55591b 100644
--- a/drivers/memory/spiflash.c
+++ b/drivers/memory/spiflash.c
@@ -187,7 +187,7 @@ void mp_spiflash_init(mp_spiflash_t *self) {
mp_spiflash_release_bus(self);
}
-STATIC int mp_spiflash_erase_sector(mp_spiflash_t *self, uint32_t addr) {
+STATIC int mp_spiflash_erase_block_internal(mp_spiflash_t *self, uint32_t addr) {
// enable writes
mp_spiflash_write_cmd(self, CMD_WREN);
@@ -204,7 +204,7 @@ STATIC int mp_spiflash_erase_sector(mp_spiflash_t *self, uint32_t addr) {
return mp_spiflash_wait_wip0(self);
}
-STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, const uint8_t *src) {
+STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
// enable writes
mp_spiflash_write_cmd(self, CMD_WREN);
@@ -215,13 +215,54 @@ STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, const uint
}
// write the page
- mp_spiflash_write_cmd_addr_data(self, CMD_WRITE, addr, PAGE_SIZE, src);
+ mp_spiflash_write_cmd_addr_data(self, CMD_WRITE, addr, len, src);
// wait WIP=0
return mp_spiflash_wait_wip0(self);
}
/******************************************************************************/
+// Interface functions that go direct to the SPI flash device
+
+int mp_spiflash_erase_block(mp_spiflash_t *self, uint32_t addr) {
+ mp_spiflash_acquire_bus(self);
+ int ret = mp_spiflash_erase_block_internal(self, addr);
+ mp_spiflash_release_bus(self);
+ return ret;
+}
+
+void mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
+ if (len == 0) {
+ return;
+ }
+ mp_spiflash_acquire_bus(self);
+ mp_spiflash_read_data(self, addr, len, dest);
+ mp_spiflash_release_bus(self);
+}
+
+int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
+ mp_spiflash_acquire_bus(self);
+ int ret = 0;
+ uint32_t offset = addr & (PAGE_SIZE - 1);
+ while (len) {
+ size_t rest = PAGE_SIZE - offset;
+ if (rest > len) {
+ rest = len;
+ }
+ ret = mp_spiflash_write_page(self, addr, rest, src);
+ if (ret != 0) {
+ break;
+ }
+ len -= rest;
+ addr += rest;
+ src += rest;
+ offset = 0;
+ }
+ mp_spiflash_release_bus(self);
+ return ret;
+}
+
+/******************************************************************************/
// Interface functions that use the cache
void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
@@ -275,14 +316,15 @@ STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {
mp_spiflash_cache_t *cache = self->config->cache;
// Erase sector
- int ret = mp_spiflash_erase_sector(self, cache->block * SECTOR_SIZE);
+ int ret = mp_spiflash_erase_block_internal(self, cache->block * SECTOR_SIZE);
if (ret != 0) {
return;
}
// Write
for (int i = 0; i < 16; i += 1) {
- int ret = mp_spiflash_write_page(self, cache->block * SECTOR_SIZE + i * PAGE_SIZE, cache->buf + i * PAGE_SIZE);
+ 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;
}
@@ -344,7 +386,7 @@ STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, siz
if (cache->buf[offset + i] != src[i]) {
if (cache->buf[offset + i] != 0xff) {
// Erase sector
- int ret = mp_spiflash_erase_sector(self, addr);
+ int ret = mp_spiflash_erase_block_internal(self, addr);
if (ret != 0) {
return ret;
}
@@ -363,7 +405,7 @@ STATIC int mp_spiflash_cached_write_part(mp_spiflash_t *self, uint32_t addr, siz
// Write sector in pages of 256 bytes
for (size_t i = 0; i < 16; ++i) {
if (dirty & (1 << i)) {
- int ret = mp_spiflash_write_page(self, addr + i * PAGE_SIZE, cache->buf + i * PAGE_SIZE);
+ int ret = mp_spiflash_write_page(self, addr + i * PAGE_SIZE, PAGE_SIZE, cache->buf + i * PAGE_SIZE);
if (ret != 0) {
return ret;
}
diff --git a/drivers/memory/spiflash.h b/drivers/memory/spiflash.h
index 4837fe3f9..a5b8a1dca 100644
--- a/drivers/memory/spiflash.h
+++ b/drivers/memory/spiflash.h
@@ -59,7 +59,7 @@ typedef struct _mp_spiflash_config_t {
const mp_qspi_proto_t *proto;
} u_qspi;
} bus;
- mp_spiflash_cache_t *cache;
+ mp_spiflash_cache_t *cache; // can be NULL if cache functions not used
} mp_spiflash_config_t;
typedef struct _mp_spiflash_t {
@@ -69,6 +69,11 @@ typedef struct _mp_spiflash_t {
void mp_spiflash_init(mp_spiflash_t *self);
+// 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_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src);
+
// 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);