summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2025-03-19 15:47:35 +1100
committerDamien George <damien@micropython.org>2025-03-25 12:58:43 +1100
commitc61e85910879d5db120d00f7790ed36f4dcda44d (patch)
tree1235e998114ab7f3e9ada871a20c8d26a2d565e2
parent274c8c419c97bdb54fa14de37a38b08dcefd1493 (diff)
drivers: Add MP_QSPI_IOCTL_MEMORY_MODIFIED to indicate flash changed.
Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--drivers/bus/qspi.h3
-rw-r--r--drivers/bus/softqspi.c3
-rw-r--r--drivers/memory/spiflash.c21
-rw-r--r--drivers/memory/spiflash.h2
-rw-r--r--ports/stm32/octospi.c3
-rw-r--r--ports/stm32/qspi.c2
6 files changed, 27 insertions, 7 deletions
diff --git a/drivers/bus/qspi.h b/drivers/bus/qspi.h
index 009f55b15..7ba2e7509 100644
--- a/drivers/bus/qspi.h
+++ b/drivers/bus/qspi.h
@@ -37,10 +37,11 @@ enum {
MP_QSPI_IOCTL_DEINIT,
MP_QSPI_IOCTL_BUS_ACQUIRE,
MP_QSPI_IOCTL_BUS_RELEASE,
+ MP_QSPI_IOCTL_MEMORY_MODIFIED,
};
typedef struct _mp_qspi_proto_t {
- int (*ioctl)(void *self, uint32_t cmd);
+ int (*ioctl)(void *self, uint32_t cmd, uintptr_t arg);
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);
int (*read_cmd)(void *self, uint8_t cmd, size_t len, uint32_t *dest);
diff --git a/drivers/bus/softqspi.c b/drivers/bus/softqspi.c
index 65a504a73..5cfc4db5e 100644
--- a/drivers/bus/softqspi.c
+++ b/drivers/bus/softqspi.c
@@ -56,8 +56,9 @@ static void nibble_write(mp_soft_qspi_obj_t *self, uint8_t v) {
mp_hal_pin_write(self->io3, (v >> 3) & 1);
}
-static int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd) {
+static int mp_soft_qspi_ioctl(void *self_in, uint32_t cmd, uintptr_t arg) {
mp_soft_qspi_obj_t *self = (mp_soft_qspi_obj_t*)self_in;
+ (void)arg;
switch (cmd) {
case MP_QSPI_IOCTL_INIT:
diff --git a/drivers/memory/spiflash.c b/drivers/memory/spiflash.c
index 773334e16..09ab7157b 100644
--- a/drivers/memory/spiflash.c
+++ b/drivers/memory/spiflash.c
@@ -61,14 +61,22 @@
static void mp_spiflash_acquire_bus(mp_spiflash_t *self) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
- c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_ACQUIRE);
+ c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_ACQUIRE, 0);
}
}
static void mp_spiflash_release_bus(mp_spiflash_t *self) {
const mp_spiflash_config_t *c = self->config;
if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
- c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_RELEASE);
+ c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_BUS_RELEASE, 0);
+ }
+}
+
+static void mp_spiflash_notify_modified(mp_spiflash_t *self, uint32_t addr, uint32_t len) {
+ const mp_spiflash_config_t *c = self->config;
+ if (c->bus_kind == MP_SPIFLASH_BUS_QSPI) {
+ uintptr_t arg[2] = { addr, len };
+ c->bus.u_qspi.proto->ioctl(c->bus.u_qspi.data, MP_QSPI_IOCTL_MEMORY_MODIFIED, (uintptr_t)&arg[0]);
}
}
@@ -174,7 +182,7 @@ void mp_spiflash_init(mp_spiflash_t *self) {
mp_hal_pin_output(self->config->bus.u_spi.cs);
self->config->bus.u_spi.proto->ioctl(self->config->bus.u_spi.data, MP_SPI_IOCTL_INIT);
} else {
- self->config->bus.u_qspi.proto->ioctl(self->config->bus.u_qspi.data, MP_QSPI_IOCTL_INIT);
+ self->config->bus.u_qspi.proto->ioctl(self->config->bus.u_qspi.data, MP_QSPI_IOCTL_INIT, 0);
}
mp_spiflash_acquire_bus(self);
@@ -285,6 +293,7 @@ static int mp_spiflash_write_page(mp_spiflash_t *self, uint32_t addr, size_t len
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_notify_modified(self, addr, SECTOR_SIZE);
mp_spiflash_release_bus(self);
return ret;
}
@@ -300,6 +309,8 @@ int mp_spiflash_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *de
}
int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src) {
+ uint32_t orig_addr = addr;
+ uint32_t orig_len = len;
mp_spiflash_acquire_bus(self);
int ret = 0;
uint32_t offset = addr & (PAGE_SIZE - 1);
@@ -317,12 +328,16 @@ int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint
src += rest;
offset = 0;
}
+ mp_spiflash_notify_modified(self, orig_addr, orig_len);
mp_spiflash_release_bus(self);
return ret;
}
/******************************************************************************/
// Interface functions that use the cache
+//
+// These functions do not call mp_spiflash_notify_modified(), so shouldn't be
+// used for memory-mapped flash (for example).
#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
diff --git a/drivers/memory/spiflash.h b/drivers/memory/spiflash.h
index 5ccf7d44c..edd7d4933 100644
--- a/drivers/memory/spiflash.h
+++ b/drivers/memory/spiflash.h
@@ -81,6 +81,8 @@ int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint
#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
// These functions use the cache (which must already be configured)
+// Note: don't use these functions in combination with memory-mapped
+// flash, because MP_QSPI_IOCTL_MEMORY_MODIFIED is not called.
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);
diff --git a/ports/stm32/octospi.c b/ports/stm32/octospi.c
index 407f48566..345c4a237 100644
--- a/ports/stm32/octospi.c
+++ b/ports/stm32/octospi.c
@@ -105,8 +105,9 @@ void octospi_init(void) {
OCTOSPI1->CR |= OCTOSPI_CR_EN;
}
-static int octospi_ioctl(void *self_in, uint32_t cmd) {
+static int octospi_ioctl(void *self_in, uint32_t cmd, uintptr_t arg) {
(void)self_in;
+ (void)arg;
switch (cmd) {
case MP_QSPI_IOCTL_INIT:
octospi_init();
diff --git a/ports/stm32/qspi.c b/ports/stm32/qspi.c
index 34359a1cc..1d3239b0d 100644
--- a/ports/stm32/qspi.c
+++ b/ports/stm32/qspi.c
@@ -170,7 +170,7 @@ void qspi_memory_map(void) {
qspi_mpu_enable_mapped();
}
-static int qspi_ioctl(void *self_in, uint32_t cmd) {
+static int qspi_ioctl(void *self_in, uint32_t cmd, uintptr_t arg) {
(void)self_in;
switch (cmd) {
case MP_QSPI_IOCTL_INIT: