summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/memory/spiflash.c4
-rw-r--r--drivers/memory/spiflash.h6
-rw-r--r--ports/stm32/boards/PYBD_SF2/mpconfigboard.h1
-rw-r--r--ports/stm32/boards/STM32F769DISC/mpconfigboard.h1
-rw-r--r--ports/stm32/boards/STM32L476DISC/mpconfigboard.h1
-rw-r--r--ports/stm32/mpconfigboard_common.h8
-rw-r--r--ports/stm32/spibdev.c6
7 files changed, 27 insertions, 0 deletions
diff --git a/drivers/memory/spiflash.c b/drivers/memory/spiflash.c
index e870d39f5..bb15bd625 100644
--- a/drivers/memory/spiflash.c
+++ b/drivers/memory/spiflash.c
@@ -287,6 +287,8 @@ int mp_spiflash_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint
/******************************************************************************/
// Interface functions that use the cache
+#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
+
void mp_spiflash_cached_read(mp_spiflash_t *self, uint32_t addr, size_t len, uint8_t *dest) {
if (len == 0) {
return;
@@ -509,3 +511,5 @@ int mp_spiflash_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, con
mp_spiflash_release_bus(self);
return 0;
}
+
+#endif // MICROPY_HW_SPIFLASH_ENABLE_CACHE
diff --git a/drivers/memory/spiflash.h b/drivers/memory/spiflash.h
index 96dfdeeab..c4162ff21 100644
--- a/drivers/memory/spiflash.h
+++ b/drivers/memory/spiflash.h
@@ -38,6 +38,7 @@ enum {
struct _mp_spiflash_t;
+#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
// A cache must be provided by the user in the config struct. The same cache
// struct can be shared by multiple SPI flash instances.
typedef struct _mp_spiflash_cache_t {
@@ -45,6 +46,7 @@ typedef struct _mp_spiflash_cache_t {
struct _mp_spiflash_t *user; // current user of buf, for shared use
uint32_t block; // current block stored in buf; 0xffffffff if invalid
} mp_spiflash_cache_t;
+#endif
typedef struct _mp_spiflash_config_t {
uint32_t bus_kind;
@@ -59,7 +61,9 @@ typedef struct _mp_spiflash_config_t {
const mp_qspi_proto_t *proto;
} u_qspi;
} bus;
+ #if MICROPY_HW_SPIFLASH_ENABLE_CACHE
mp_spiflash_cache_t *cache; // can be NULL if cache functions not used
+ #endif
} mp_spiflash_config_t;
typedef struct _mp_spiflash_t {
@@ -75,9 +79,11 @@ 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);
+#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_cached_write(mp_spiflash_t *self, uint32_t addr, size_t len, const uint8_t *src);
+#endif
#endif // MICROPY_INCLUDED_DRIVERS_MEMORY_SPIFLASH_H
diff --git a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h
index f6e130eb5..29164ac11 100644
--- a/ports/stm32/boards/PYBD_SF2/mpconfigboard.h
+++ b/ports/stm32/boards/PYBD_SF2/mpconfigboard.h
@@ -77,6 +77,7 @@ void board_sleep(int value);
// SPI flash #1, block device config
extern const struct _mp_spiflash_config_t spiflash_config;
extern struct _spi_bdev_t spi_bdev;
+#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1)
#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \
(op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \
(op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \
diff --git a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h
index e1fe93bb0..843b987ce 100644
--- a/ports/stm32/boards/STM32F769DISC/mpconfigboard.h
+++ b/ports/stm32/boards/STM32F769DISC/mpconfigboard.h
@@ -40,6 +40,7 @@ extern const struct _mp_spiflash_config_t spiflash_config;
extern struct _spi_bdev_t spi_bdev;
#if !USE_QSPI_XIP
#define MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE (0)
+#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1)
#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \
(op) == BDEV_IOCTL_NUM_BLOCKS ? ((1 << MICROPY_HW_QSPIFLASH_SIZE_BITS_LOG2) / 8 / FLASH_BLOCK_SIZE) : \
(op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \
diff --git a/ports/stm32/boards/STM32L476DISC/mpconfigboard.h b/ports/stm32/boards/STM32L476DISC/mpconfigboard.h
index 283118753..ad62f761e 100644
--- a/ports/stm32/boards/STM32L476DISC/mpconfigboard.h
+++ b/ports/stm32/boards/STM32L476DISC/mpconfigboard.h
@@ -22,6 +22,7 @@ void STM32L476DISC_board_early_init(void);
// block device config for SPI flash
extern const struct _mp_spiflash_config_t spiflash_config;
extern struct _spi_bdev_t spi_bdev;
+#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (1)
#define MICROPY_HW_BDEV_IOCTL(op, arg) ( \
(op) == BDEV_IOCTL_NUM_BLOCKS ? (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) : \
(op) == BDEV_IOCTL_INIT ? spi_bdev_ioctl(&spi_bdev, (op), (uint32_t)&spiflash_config) : \
diff --git a/ports/stm32/mpconfigboard_common.h b/ports/stm32/mpconfigboard_common.h
index 8890abc59..60fbc35fc 100644
--- a/ports/stm32/mpconfigboard_common.h
+++ b/ports/stm32/mpconfigboard_common.h
@@ -286,6 +286,14 @@
#define MICROPY_HW_BDEV_WRITEBLOCK flash_bdev_writeblock
#endif
+// Whether to enable caching for external SPI flash, to allow block writes that are
+// smaller than the native page-erase size of the SPI flash, eg when FAT FS is used.
+// Enabling this enables spi_bdev_readblocks() and spi_bdev_writeblocks() functions,
+// and requires a valid mp_spiflash_config_t.cache pointer.
+#ifndef MICROPY_HW_SPIFLASH_ENABLE_CACHE
+#define MICROPY_HW_SPIFLASH_ENABLE_CACHE (0)
+#endif
+
// Enable the storage sub-system if a block device is defined
#if defined(MICROPY_HW_BDEV_IOCTL)
#define MICROPY_HW_ENABLE_STORAGE (1)
diff --git a/ports/stm32/spibdev.c b/ports/stm32/spibdev.c
index 05c8819a7..5090b43b1 100644
--- a/ports/stm32/spibdev.c
+++ b/ports/stm32/spibdev.c
@@ -41,19 +41,23 @@ int32_t spi_bdev_ioctl(spi_bdev_t *bdev, uint32_t op, uint32_t arg) {
return 0;
case BDEV_IOCTL_IRQ_HANDLER:
+ #if MICROPY_HW_SPIFLASH_ENABLE_CACHE
if ((bdev->spiflash.flags & 1) && HAL_GetTick() - bdev->flash_tick_counter_last_write >= 1000) {
mp_spiflash_cache_flush(&bdev->spiflash);
led_state(PYB_LED_RED, 0); // indicate a clean cache with LED off
}
+ #endif
return 0;
case BDEV_IOCTL_SYNC:
+ #if MICROPY_HW_SPIFLASH_ENABLE_CACHE
if (bdev->spiflash.flags & 1) {
uint32_t basepri = raise_irq_pri(IRQ_PRI_FLASH); // prevent cache flushing and USB access
mp_spiflash_cache_flush(&bdev->spiflash);
led_state(PYB_LED_RED, 0); // indicate a clean cache with LED off
restore_irq_pri(basepri);
}
+ #endif
return 0;
case BDEV_IOCTL_BLOCK_ERASE: {
@@ -66,6 +70,7 @@ int32_t spi_bdev_ioctl(spi_bdev_t *bdev, uint32_t op, uint32_t arg) {
return -MP_EINVAL;
}
+#if MICROPY_HW_SPIFLASH_ENABLE_CACHE
int spi_bdev_readblocks(spi_bdev_t *bdev, uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
uint32_t basepri = raise_irq_pri(IRQ_PRI_FLASH); // prevent cache flushing and USB access
mp_spiflash_cached_read(&bdev->spiflash, block_num * FLASH_BLOCK_SIZE, num_blocks * FLASH_BLOCK_SIZE, dest);
@@ -85,6 +90,7 @@ int spi_bdev_writeblocks(spi_bdev_t *bdev, const uint8_t *src, uint32_t block_nu
return ret;
}
+#endif // MICROPY_HW_SPIFLASH_ENABLE_CACHE
int spi_bdev_readblocks_raw(spi_bdev_t *bdev, uint8_t *dest, uint32_t block_num, uint32_t block_offset, uint32_t num_bytes) {
uint32_t basepri = raise_irq_pri(IRQ_PRI_FLASH); // prevent cache flushing and USB access