Skip to content

Commit f4c1737

Browse files
committed
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).
1 parent 95c9cc8 commit f4c1737

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

stmhal/sdcard.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
213213
HAL_SD_ErrorTypedef err = SD_OK;
214214

215215
if (query_irq() == IRQ_STATE_ENABLED) {
216+
// we must disable USB irqs to prevent MSC contention with SD card
217+
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
218+
216219
dma_init(&sd_rx_dma, DMA_STREAM_SDIO_RX, &dma_init_struct_sdio,
217220
DMA_CHANNEL_SDIO_RX, DMA_PERIPH_TO_MEMORY, &sd_handle);
218221
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
225228

226229
dma_deinit(sd_handle.hdmarx);
227230
sd_handle.hdmarx = NULL;
231+
232+
restore_irq_pri(basepri);
228233
} else {
229234
err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
230235
}
@@ -246,6 +251,9 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
246251
HAL_SD_ErrorTypedef err = SD_OK;
247252

248253
if (query_irq() == IRQ_STATE_ENABLED) {
254+
// we must disable USB irqs to prevent MSC contention with SD card
255+
uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);
256+
249257
dma_init(&sd_tx_dma, DMA_STREAM_SDIO_TX, &dma_init_struct_sdio,
250258
DMA_CHANNEL_SDIO_TX, DMA_MEMORY_TO_PERIPH, &sd_handle);
251259
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
257265
}
258266
dma_deinit(sd_handle.hdmatx);
259267
sd_handle.hdmatx = NULL;
268+
269+
restore_irq_pri(basepri);
260270
} else {
261271
err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
262272
}

0 commit comments

Comments
 (0)