Commit f4c17378 authored by Damien George's avatar Damien George
Browse files

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).
parent 95c9cc81
...@@ -213,6 +213,9 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo ...@@ -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; HAL_SD_ErrorTypedef err = SD_OK;
if (query_irq() == IRQ_STATE_ENABLED) { 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_init(&sd_rx_dma, DMA_STREAM_SDIO_RX, &dma_init_struct_sdio,
DMA_CHANNEL_SDIO_RX, DMA_PERIPH_TO_MEMORY, &sd_handle); DMA_CHANNEL_SDIO_RX, DMA_PERIPH_TO_MEMORY, &sd_handle);
sd_handle.hdmarx = &sd_rx_dma; 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 ...@@ -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); dma_deinit(sd_handle.hdmarx);
sd_handle.hdmarx = NULL; sd_handle.hdmarx = NULL;
restore_irq_pri(basepri);
} else { } else {
err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks); 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 ...@@ -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; HAL_SD_ErrorTypedef err = SD_OK;
if (query_irq() == IRQ_STATE_ENABLED) { 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_init(&sd_tx_dma, DMA_STREAM_SDIO_TX, &dma_init_struct_sdio,
DMA_CHANNEL_SDIO_TX, DMA_MEMORY_TO_PERIPH, &sd_handle); DMA_CHANNEL_SDIO_TX, DMA_MEMORY_TO_PERIPH, &sd_handle);
sd_handle.hdmatx = &sd_tx_dma; 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 ...@@ -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); dma_deinit(sd_handle.hdmatx);
sd_handle.hdmatx = NULL; sd_handle.hdmatx = NULL;
restore_irq_pri(basepri);
} else { } else {
err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks); err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment