diff options
| author | Jean-François Milants <jf@codingfield.com> | 2016-11-23 22:16:14 +0100 |
|---|---|---|
| committer | Damien George <damien.p.george@gmail.com> | 2016-12-02 13:51:09 +1100 |
| commit | 08bd7d1d31a95331dad403adce8834c2d39ab3e8 (patch) | |
| tree | 132141f1b0fed8e706c8a183d9e1e1d0c5d60cb4 | |
| parent | a081b49d55ef409d612666d79a97e79259c8adba (diff) | |
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.
| -rw-r--r-- | stmhal/mphalport.h | 6 | ||||
| -rw-r--r-- | stmhal/sdcard.c | 8 |
2 files changed, 14 insertions, 0 deletions
diff --git a/stmhal/mphalport.h b/stmhal/mphalport.h index 5df053fa2..b55c9ccdc 100644 --- a/stmhal/mphalport.h +++ b/stmhal/mphalport.h @@ -6,10 +6,16 @@ // go in some MCU-specific header, but for now it lives here. #if defined(MCU_SERIES_F4) #define MP_HAL_UNIQUE_ID_ADDRESS (0x1fff7a10) +#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size) +#define MP_HAL_CLEAN_DCACHE(addr, size) #elif defined(MCU_SERIES_F7) #define MP_HAL_UNIQUE_ID_ADDRESS (0x1ff0f420) +#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))) +#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))) #elif defined(MCU_SERIES_L4) #define MP_HAL_UNIQUE_ID_ADDRESS (0x1fff7590) +#define MP_HAL_CLEANINVALIDATE_DCACHE(addr, size) +#define MP_HAL_CLEAN_DCACHE(addr, size) #else #error mphalport.h: Unrecognized MCU_SERIES #endif diff --git a/stmhal/sdcard.c b/stmhal/sdcard.c index a2aa4c84d..f7cf15343 100644 --- a/stmhal/sdcard.c +++ b/stmhal/sdcard.c @@ -30,6 +30,7 @@ #include "py/runtime.h" #include "lib/fatfs/ff.h" #include "extmod/fsusermount.h" +#include "mphalport.h" #include "sdcard.h" #include "pin.h" @@ -221,6 +222,10 @@ mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blo dma_init(&sd_rx_dma, &dma_SDIO_0_RX, &sd_handle); sd_handle.hdmarx = &sd_rx_dma; + // make sure cache is flushed and invalidated so when DMA updates the RAM + // from reading the peripheral the CPU then reads the new data + MP_HAL_CLEANINVALIDATE_DCACHE(dest, num_blocks * SDCARD_BLOCK_SIZE); + err = HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks); if (err == SD_OK) { // 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 dma_init(&sd_tx_dma, &dma_SDIO_0_TX, &sd_handle); sd_handle.hdmatx = &sd_tx_dma; + // make sure cache is flushed to RAM so the DMA can read the correct data + MP_HAL_CLEAN_DCACHE(src, num_blocks * SDCARD_BLOCK_SIZE); + err = HAL_SD_WriteBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks); if (err == SD_OK) { // wait for DMA transfer to finish, with a large timeout |
