Skip to content

Commit 08bd7d1

Browse files
JF002dpgeorge
authored andcommitted
stmhal/sdcard: Clean/invalidate cache before DMA transfers with SD card.
Add 2 macros in mphalport.h that clean and invalidate data caches only on STM32F7 MCUs. They are needed to ensure the cache coherency before/after DMA transferts. * MP_HAL_CLEANINVALIDATE_DCACHE cleans and invalidate the data cache. It must be called before starting a DMA transfer from the peripheral to the RAM memory. * MP_HAL_CLEAN_DCACHE cleans the data cache. It must be called before starting a DMA transfert from the RAM memory to the peripheral. These macros are called in sdcard.c, before reading from and writing to the SDCard, when DMA is used.
1 parent a081b49 commit 08bd7d1

2 files changed

Lines changed: 14 additions & 0 deletions

File tree

stmhal/mphalport.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66
// go in some MCU-specific header, but for now it lives here.
77
#if defined(MCU_SERIES_F4)
88
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1fff7a10)
9+
#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size)
10+
#define MP_HAL_CLEAN_DCACHE(addr, size)
911
#elif defined(MCU_SERIES_F7)
1012
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1ff0f420)
13+
#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size) (SCB_CleanInvalidateDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
14+
#define MP_HAL_CLEAN_DCACHE(addr, size) (SCB_CleanDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
1115
#elif defined(MCU_SERIES_L4)
1216
#define MP_HAL_UNIQUE_ID_ADDRESS (0x1fff7590)
17+
#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size)
18+
#define MP_HAL_CLEAN_DCACHE(addr, size)
1319
#else
1420
#error mphalport.h: Unrecognized MCU_SERIES
1521
#endif

stmhal/sdcard.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "py/runtime.h"
3131
#include "lib/fatfs/ff.h"
3232
#include "extmod/fsusermount.h"
33+
#include "mphalport.h"
3334

3435
#include "sdcard.h"
3536
#include "pin.h"
@@ -221,6 +222,10 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo
221222
dma_init(&sd_rx_dma, &dma_SDIO_0_RX, &sd_handle);
222223
sd_handle.hdmarx = &sd_rx_dma;
223224

225+
// make sure cache is flushed and invalidated so when DMA updates the RAM
226+
// from reading the peripheral the CPU then reads the new data
227+
MP_HAL_CLEANINVALIDATE_DCACHE(dest, num_blocks * SDCARD_BLOCK_SIZE);
228+
224229
err = HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
225230
if (err == SD_OK) {
226231
// wait for DMA transfer to finish, with a large timeout
@@ -277,6 +282,9 @@ mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t n
277282
dma_init(&sd_tx_dma, &dma_SDIO_0_TX, &sd_handle);
278283
sd_handle.hdmatx = &sd_tx_dma;
279284

285+
// make sure cache is flushed to RAM so the DMA can read the correct data
286+
MP_HAL_CLEAN_DCACHE(src, num_blocks * SDCARD_BLOCK_SIZE);
287+
280288
err = HAL_SD_WriteBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
281289
if (err == SD_OK) {
282290
// wait for DMA transfer to finish, with a large timeout

0 commit comments

Comments
 (0)