From f4c17378b359d7b371e005aaac2dc8d86a88f8d8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 4 Dec 2015 11:39:21 +0000 Subject: [PATCH] stmhal: Protect SD card DMA transactions against USB MSC contention. Consider the following scenario: SD card is being read by pyboard; USB irq comes in for MSC read request; SD card needs to be read from within USB irq while SD read is already ongoing. Such contention needs to be avoided. This patch provides a simple solution, to raise the irq priority above that of the USB irq during SD DMA transfers. Pyboard and PC can now read from the SD card at the same time (well, reads are interleaved). --- stmhal/sdcard.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c index 6ca1e724d..2adbaf146 100644 --- a/stmhal/sdcard.c +++ b/stmhal/sdcard.c @@ -213,6 +213,9 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo HAL_SD_ErrorTypedef err = SD_OK; if (query_irq() == IRQ_STATE_ENABLED) { + // we must disable USB irqs to prevent MSC contention with SD card + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + dma_init(&sd_rx_dma, DMA_STREAM_SDIO_RX, &dma_init_struct_sdio, DMA_CHANNEL_SDIO_RX, DMA_PERIPH_TO_MEMORY, &sd_handle); sd_handle.hdmarx = &sd_rx_dma; @@ -225,6 +228,8 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo dma_deinit(sd_handle.hdmarx); sd_handle.hdmarx = NULL; + + restore_irq_pri(basepri); } else { err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks); } @@ -246,6 +251,9 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n HAL_SD_ErrorTypedef err = SD_OK; if (query_irq() == IRQ_STATE_ENABLED) { + // we must disable USB irqs to prevent MSC contention with SD card + uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS); + dma_init(&sd_tx_dma, DMA_STREAM_SDIO_TX, &dma_init_struct_sdio, DMA_CHANNEL_SDIO_TX, DMA_MEMORY_TO_PERIPH, &sd_handle); sd_handle.hdmatx = &sd_tx_dma; @@ -257,6 +265,8 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n } dma_deinit(sd_handle.hdmatx); sd_handle.hdmatx = NULL; + + restore_irq_pri(basepri); } else { err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks); }