summaryrefslogtreecommitdiffstatshomepage
path: root/stmhal
diff options
context:
space:
mode:
authorJean-François Milants <jf@codingfield.com>2016-11-23 22:16:14 +0100
committerDamien George <damien.p.george@gmail.com>2016-12-02 13:51:09 +1100
commit08bd7d1d31a95331dad403adce8834c2d39ab3e8 (patch)
tree132141f1b0fed8e706c8a183d9e1e1d0c5d60cb4 /stmhal
parenta081b49d55ef409d612666d79a97e79259c8adba (diff)
downloadmicropython-08bd7d1d31a95331dad403adce8834c2d39ab3e8.tar.gz
micropython-08bd7d1d31a95331dad403adce8834c2d39ab3e8.zip
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.
Diffstat (limited to 'stmhal')
-rw-r--r--stmhal/mphalport.h6
-rw-r--r--stmhal/sdcard.c8
2 files changed, 14 insertions, 0 deletions
diff --git a/stmhal/mphalport.h b/stmhal/mphalport.h
index 5df053fa20..b55c9ccdc4 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 a2aa4c84d8..f7cf153431 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