summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/stm32/flashbdev.c7
-rw-r--r--ports/stm32/irq.h11
-rw-r--r--ports/stm32/spibdev.c9
-rw-r--r--ports/stm32/storage.c3
4 files changed, 15 insertions, 15 deletions
diff --git a/ports/stm32/flashbdev.c b/ports/stm32/flashbdev.c
index 2b633cf16..395662c8b 100644
--- a/ports/stm32/flashbdev.c
+++ b/ports/stm32/flashbdev.c
@@ -143,14 +143,17 @@ int32_t flash_bdev_ioctl(uint32_t op, uint32_t arg) {
flash_bdev_irq_handler();
return 0;
- case BDEV_IOCTL_SYNC:
+ case BDEV_IOCTL_SYNC: {
+ uint32_t basepri = raise_irq_pri(IRQ_PRI_FLASH); // prevent cache flushing and USB access
if (flash_flags & FLASH_FLAG_DIRTY) {
flash_flags |= FLASH_FLAG_FORCE_WRITE;
while (flash_flags & FLASH_FLAG_DIRTY) {
- NVIC->STIR = FLASH_IRQn;
+ flash_bdev_irq_handler();
}
}
+ restore_irq_pri(basepri);
return 0;
+ }
}
return -MP_EINVAL;
}
diff --git a/ports/stm32/irq.h b/ports/stm32/irq.h
index 3fe20867f..9919013f8 100644
--- a/ports/stm32/irq.h
+++ b/ports/stm32/irq.h
@@ -106,9 +106,9 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_irq_stats_obj);
//#def IRQ_PRI_SYSTICK 0
#define IRQ_PRI_UART 1
-#define IRQ_PRI_FLASH 1
#define IRQ_PRI_SDIO 1
#define IRQ_PRI_DMA 1
+#define IRQ_PRI_FLASH 2
#define IRQ_PRI_OTG_FS 2
#define IRQ_PRI_OTG_HS 2
#define IRQ_PRI_TIM5 2
@@ -126,10 +126,6 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_irq_stats_obj);
// get dropped. The handling for each character only consumes about 0.5 usec
#define IRQ_PRI_UART NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0)
-// Flash IRQ must be higher priority than interrupts of all those components
-// that rely on the flash storage.
-#define IRQ_PRI_FLASH NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 2, 0)
-
// SDIO must be higher priority than DMA for SDIO DMA transfers to work.
#define IRQ_PRI_SDIO NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 4, 0)
@@ -137,6 +133,11 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_irq_stats_obj);
// into the sdcard driver which waits for the DMA to complete.
#define IRQ_PRI_DMA NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 5, 0)
+// Flash IRQ (used for flushing storage cache) must be at the same priority as
+// the USB IRQs, so that the IRQ priority can be raised to this level to disable
+// both the USB and cache flushing, when storage transfers are in progress.
+#define IRQ_PRI_FLASH NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
+
#define IRQ_PRI_OTG_FS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
#define IRQ_PRI_OTG_HS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
#define IRQ_PRI_TIM5 NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
diff --git a/ports/stm32/spibdev.c b/ports/stm32/spibdev.c
index 368e63966..9b5a10b40 100644
--- a/ports/stm32/spibdev.c
+++ b/ports/stm32/spibdev.c
@@ -49,8 +49,7 @@ int32_t spi_bdev_ioctl(spi_bdev_t *bdev, uint32_t op, uint32_t arg) {
case BDEV_IOCTL_SYNC:
if (bdev->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);
+ 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);
@@ -61,8 +60,7 @@ int32_t spi_bdev_ioctl(spi_bdev_t *bdev, uint32_t op, uint32_t arg) {
}
int spi_bdev_readblocks(spi_bdev_t *bdev, uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
- // we must disable USB irqs to prevent MSC contention with SPI flash
- uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
+ 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);
restore_irq_pri(basepri);
@@ -70,8 +68,7 @@ int spi_bdev_readblocks(spi_bdev_t *bdev, uint8_t *dest, uint32_t block_num, uin
}
int spi_bdev_writeblocks(spi_bdev_t *bdev, const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
- // we must disable USB irqs to prevent MSC contention with SPI flash
- uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
+ uint32_t basepri = raise_irq_pri(IRQ_PRI_FLASH); // prevent cache flushing and USB access
int ret = mp_spiflash_cached_write(&bdev->spiflash, block_num * FLASH_BLOCK_SIZE, num_blocks * FLASH_BLOCK_SIZE, src);
if (bdev->spiflash.flags & 1) {
led_state(PYB_LED_RED, 1); // indicate a dirty cache with LED on
diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c
index b0b607def..7724ae0f4 100644
--- a/ports/stm32/storage.c
+++ b/ports/stm32/storage.c
@@ -55,8 +55,7 @@ void storage_init(void) {
#endif
// Enable the flash IRQ, which is used to also call our storage IRQ handler
- // It needs to go at a higher priority than all those components that rely on
- // the flash storage (eg higher than USB MSC).
+ // It must go at the same priority as USB (see comment in irq.h).
NVIC_SetPriority(FLASH_IRQn, IRQ_PRI_FLASH);
HAL_NVIC_EnableIRQ(FLASH_IRQn);
}