From a0dfc386410b3a397e8643b269e352a8930b5f53 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 2 Mar 2018 23:11:47 +1100 Subject: [PATCH] stm32/spibdev: Update to work with new spiflash driver. --- ports/stm32/spibdev.c | 49 ++++++++++++++++++++++++++++++++----------- ports/stm32/storage.c | 2 ++ ports/stm32/storage.h | 2 ++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/ports/stm32/spibdev.c b/ports/stm32/spibdev.c index 5e5123867d..e70507b7ba 100644 --- a/ports/stm32/spibdev.c +++ b/ports/stm32/spibdev.c @@ -25,6 +25,8 @@ */ #include "py/obj.h" +#include "systick.h" +#include "led.h" #include "storage.h" #if defined(MICROPY_HW_SPIFLASH_SIZE_BITS) @@ -32,6 +34,8 @@ #include "drivers/memory/spiflash.h" #include "genhdr/pins.h" +static uint32_t flash_tick_counter_last_write; + STATIC const mp_machine_soft_spi_obj_t spiflash_spi_bus = { .base = {&mp_machine_soft_spi_type}, .delay_half = MICROPY_PY_MACHINE_SPI_MIN_DELAY, @@ -42,22 +46,42 @@ STATIC const mp_machine_soft_spi_obj_t spiflash_spi_bus = { .miso = &MICROPY_HW_SPIFLASH_MISO, }; -STATIC const mp_spiflash_t spiflash = { - .cs = &MICROPY_HW_SPIFLASH_CS, - .spi = (mp_obj_base_t*)&spiflash_spi_bus.base, +STATIC const mp_spiflash_config_t spiflash_config = { + .bus_kind = MP_SPIFLASH_BUS_SPI, + .bus.u_spi.cs = &MICROPY_HW_SPIFLASH_CS, + .bus.u_spi.data = (void*)&spiflash_spi_bus, + .bus.u_spi.proto = &mp_machine_soft_spi_p, }; +STATIC mp_spiflash_t spiflash; + void spi_bdev_init(void) { - mp_spiflash_init((mp_spiflash_t*)&spiflash); + spiflash.config = &spiflash_config; + mp_spiflash_init(&spiflash); + flash_tick_counter_last_write = 0; +} + +void spi_bdev_irq_handler(void) { + if ((spiflash.flags & 1) && sys_tick_has_passed(flash_tick_counter_last_write, 1000)) { + mp_spiflash_flush(&spiflash); + led_state(PYB_LED_RED, 0); // indicate a clean cache with LED off + } +} + +void spi_bdev_flush(void) { + if (spiflash.flags & 1) { + // we must disable USB irqs to prevent MSC contention with SPI flash + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + mp_spiflash_flush(&spiflash); + led_state(PYB_LED_RED, 0); // indicate a clean cache with LED off + restore_irq_pri(basepri); + } } bool spi_bdev_readblock(uint8_t *dest, uint32_t block) { // we must disable USB irqs to prevent MSC contention with SPI flash uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); - - mp_spiflash_read((mp_spiflash_t*)&spiflash, - block * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, dest); - + mp_spiflash_read(&spiflash, block * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, dest); restore_irq_pri(basepri); return true; @@ -66,10 +90,11 @@ bool spi_bdev_readblock(uint8_t *dest, uint32_t block) { bool spi_bdev_writeblock(const uint8_t *src, uint32_t block) { // we must disable USB irqs to prevent MSC contention with SPI flash uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); - - int ret = mp_spiflash_write((mp_spiflash_t*)&spiflash, - block * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, src); - + int ret = mp_spiflash_write(&spiflash, block * FLASH_BLOCK_SIZE, FLASH_BLOCK_SIZE, src); + if (spiflash.flags & 1) { + led_state(PYB_LED_RED, 1); // indicate a dirty cache with LED on + flash_tick_counter_last_write = HAL_GetTick(); + } restore_irq_pri(basepri); return ret == 0; diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c index 5eab4c7022..0607aeb88c 100644 --- a/ports/stm32/storage.c +++ b/ports/stm32/storage.c @@ -39,6 +39,8 @@ // Use external SPI flash as the storage medium #define BDEV_NUM_BLOCKS (MICROPY_HW_SPIFLASH_SIZE_BITS / 8 / FLASH_BLOCK_SIZE) #define BDEV_INIT spi_bdev_init +#define BDEV_IRQ_HANDLER spi_bdev_irq_handler +#define BDEV_FLUSH spi_bdev_flush #define BDEV_READBLOCK spi_bdev_readblock #define BDEV_WRITEBLOCK spi_bdev_writeblock diff --git a/ports/stm32/storage.h b/ports/stm32/storage.h index 37cacc1a68..2497633896 100644 --- a/ports/stm32/storage.h +++ b/ports/stm32/storage.h @@ -51,6 +51,8 @@ bool flash_bdev_readblock(uint8_t *dest, uint32_t block); bool flash_bdev_writeblock(const uint8_t *src, uint32_t block); void spi_bdev_init(void); +void spi_bdev_irq_handler(void); +void spi_bdev_flush(void); bool spi_bdev_readblock(uint8_t *dest, uint32_t block); bool spi_bdev_writeblock(const uint8_t *src, uint32_t block);