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.
This commit is contained in:
parent
a081b49d55
commit
08bd7d1d31
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue