Commit 08bd7d1d authored by Jean-François Milants's avatar Jean-François Milants Committed by Damien George
Browse files

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.
parent a081b49d
......@@ -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
......
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