drivers/memory/spiflash: Add MICROPY_HW_SPIFLASH_ENABLE_CACHE option.
This only needs to be enabled if a board uses FAT FS on external SPI flash. When disabled (and using external SPI flash) 4k of RAM can be saved. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
061cb1a73a
commit
e43a74a4db
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) : \
|
||||
|
|
|
@ -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) : \
|
||||
|
|
|
@ -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) : \
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue