drivers: Add MP_QSPI_IOCTL_MEMORY_MODIFIED to indicate flash changed.

Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
Damien George
2025-03-19 15:47:35 +11:00
parent 274c8c419c
commit c61e859108
6 changed files with 27 additions and 7 deletions

View File

@@ -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);

View File

@@ -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:

View File

@@ -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

View File

@@ -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);

View File

@@ -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();

View File

@@ -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: