kopia lustrzana https://github.com/micropython/micropython
drivers/memory/spiflash: Add functions for direct erase/read/write.
These new API functions do not use the cache.pull/3892/head
rodzic
cc5a94044a
commit
b78ca32476
|
@ -187,7 +187,7 @@ void mp_spiflash_init(mp_spiflash_t *self) {
|
||||||
mp_spiflash_release_bus(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
|
// enable writes
|
||||||
mp_spiflash_write_cmd(self, CMD_WREN);
|
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);
|
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
|
// enable writes
|
||||||
mp_spiflash_write_cmd(self, CMD_WREN);
|
mp_spiflash_write_cmd(self, CMD_WREN);
|
||||||
|
|
||||||
|
@ -215,12 +215,53 @@ STATIC int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, const uint
|
||||||
}
|
}
|
||||||
|
|
||||||
// write the page
|
// 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
|
// wait WIP=0
|
||||||
return mp_spiflash_wait_wip0(self);
|
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
|
// Interface functions that use the cache
|
||||||
|
|
||||||
|
@ -275,14 +316,15 @@ STATIC void mp_spiflash_cache_flush_internal(mp_spiflash_t *self) {
|
||||||
mp_spiflash_cache_t *cache = self->config->cache;
|
mp_spiflash_cache_t *cache = self->config->cache;
|
||||||
|
|
||||||
// Erase sector
|
// 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) {
|
if (ret != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write
|
// Write
|
||||||
for (int i = 0; i < 16; i += 1) {
|
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) {
|
if (ret != 0) {
|
||||||
return;
|
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] != src[i]) {
|
||||||
if (cache->buf[offset + i] != 0xff) {
|
if (cache->buf[offset + i] != 0xff) {
|
||||||
// Erase sector
|
// Erase sector
|
||||||
int ret = mp_spiflash_erase_sector(self, addr);
|
int ret = mp_spiflash_erase_block_internal(self, addr);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
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
|
// Write sector in pages of 256 bytes
|
||||||
for (size_t i = 0; i < 16; ++i) {
|
for (size_t i = 0; i < 16; ++i) {
|
||||||
if (dirty & (1 << 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) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ typedef struct _mp_spiflash_config_t {
|
||||||
const mp_qspi_proto_t *proto;
|
const mp_qspi_proto_t *proto;
|
||||||
} u_qspi;
|
} u_qspi;
|
||||||
} bus;
|
} bus;
|
||||||
mp_spiflash_cache_t *cache;
|
mp_spiflash_cache_t *cache; // can be NULL if cache functions not used
|
||||||
} mp_spiflash_config_t;
|
} mp_spiflash_config_t;
|
||||||
|
|
||||||
typedef struct _mp_spiflash_t {
|
typedef struct _mp_spiflash_t {
|
||||||
|
@ -69,6 +69,11 @@ typedef struct _mp_spiflash_t {
|
||||||
|
|
||||||
void mp_spiflash_init(mp_spiflash_t *self);
|
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)
|
// These functions use the cache (which must already be configured)
|
||||||
void mp_spiflash_cache_flush(mp_spiflash_t *self);
|
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);
|
void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest);
|
||||||
|
|
Ładowanie…
Reference in New Issue