3434#include "block_device_ev3.h"
3535
3636#include <pbdrv/block_device.h>
37+ #include <pbdrv/cache.h>
3738#include <pbdrv/clock.h>
3839#include <pbdrv/compiler.h>
3940#include <pbdrv/gpio.h>
@@ -103,6 +104,10 @@ static struct {
103104 uint8_t spi_cmd_buf_tx [SPI_CMD_BUF_SZ ];
104105 // This is used to hold the replies to commands to the SPI peripheral.
105106 uint8_t spi_cmd_buf_rx [SPI_CMD_BUF_SZ ];
107+ // This stores the RX buffer address so that we clean the cache when DMA is complete
108+ uint32_t rx_user_buf_addr ;
109+ // This stores the RX buffer size;
110+ uint32_t rx_user_buf_sz ;
106111} spi_dev ;
107112
108113static uint32_t last_spi_dma_complete_time ;
@@ -114,6 +119,10 @@ static void spi_dma_complete(void) {
114119 }
115120 SPIIntDisable (SOC_SPI_0_REGS , SPI_DMA_REQUEST_ENA_INT );
116121 pbio_os_request_poll ();
122+ pbdrv_cache_prepare_after_dma (spi_dev .spi_cmd_buf_rx , SPI_CMD_BUF_SZ );
123+ if (spi_dev .rx_user_buf_addr && spi_dev .rx_user_buf_sz ) {
124+ pbdrv_cache_prepare_after_dma ((void * )spi_dev .rx_user_buf_addr , spi_dev .rx_user_buf_sz );
125+ }
117126 last_spi_dma_complete_time = pbdrv_clock_get_ms ();
118127}
119128
@@ -351,16 +360,21 @@ static pbio_error_t spi_begin_for_flash(
351360
352361 spi_dev .status = SPI_STATUS_WAIT_RX ;
353362
363+ // Prevent write to spi_dev.status from being reordered
364+ pbdrv_compiler_memory_barrier ();
365+
354366 uint32_t tx = spi0_last_dat1_for_flash (cmd [0 ]);
355367 SPIIntEnable (SOC_SPI_0_REGS , SPI_RECV_INT );
356368 HWREG (SOC_SPI_0_REGS + SPI_SPIDAT1 ) = tx ;
357369 } else {
358- memcpy (& spi_dev .spi_cmd_buf_tx , cmd , cmd_len );
370+ memcpy (PBDRV_UNCACHED_ADDR (spi_dev .spi_cmd_buf_tx ), cmd , cmd_len );
371+ spi_dev .rx_user_buf_addr = (uint32_t )user_data_rx ;
372+ spi_dev .rx_user_buf_sz = user_data_len ;
359373
360374 if (user_data_len == 0 ) {
361375 // Only a command, no user data
362376
363- spi_dev .tx_last_word = spi0_last_dat1_for_flash (cmd [cmd_len - 1 ]);
377+ PBDRV_UNCACHED ( spi_dev .tx_last_word ) = spi0_last_dat1_for_flash (cmd [cmd_len - 1 ]);
364378
365379 // TX everything except last byte
366380 ps .p .srcAddr = (unsigned int )(& spi_dev .spi_cmd_buf_tx );
@@ -418,7 +432,8 @@ static pbio_error_t spi_begin_for_flash(
418432 edma3_set_param (EDMA3_CHA_SPI0_TX , & ps );
419433
420434 if (user_data_tx ) {
421- spi_dev .tx_last_word = spi0_last_dat1_for_flash (user_data_tx [user_data_len - 1 ]);
435+ pbdrv_cache_prepare_before_dma (user_data_tx , user_data_len );
436+ PBDRV_UNCACHED (spi_dev .tx_last_word ) = spi0_last_dat1_for_flash (user_data_tx [user_data_len - 1 ]);
422437
423438 // TX all but the last byte
424439 ps .p .srcAddr = (unsigned int )(user_data_tx );
@@ -434,7 +449,7 @@ static pbio_error_t spi_begin_for_flash(
434449 ps .p .opt = EDMA3CC_OPT_TCINTEN | (EDMA3_CHA_SPI0_TX << EDMA3CC_OPT_TCC_SHIFT );
435450 edma3_set_param (127 , & ps );
436451 } else {
437- spi_dev .tx_last_word = spi0_last_dat1_for_flash (0 );
452+ PBDRV_UNCACHED ( spi_dev .tx_last_word ) = spi0_last_dat1_for_flash (0 );
438453
439454 // TX all but the last byte
440455 ps .p .srcAddr = (unsigned int )(& spi_dev .tx_dummy_byte );
@@ -487,7 +502,7 @@ static pbio_error_t spi_begin_for_flash(
487502
488503 spi_dev .status = SPI_STATUS_WAIT_TX | SPI_STATUS_WAIT_RX ;
489504
490- // TODO: eventually needs DMA cache management
505+ // Prevent write to spi_dev.status from being reordered
491506 pbdrv_compiler_memory_barrier ();
492507
493508 EDMA3EnableTransfer (SOC_EDMA30CC_0_REGS , EDMA3_CHA_SPI0_TX , EDMA3_TRIG_MODE_EVENT );
@@ -804,9 +819,14 @@ static pbio_error_t pbdrv_block_device_ev3_spi_begin_for_adc(const uint32_t *cmd
804819 ps .p .opt = EDMA3CC_OPT_TCINTEN | (EDMA3_CHA_SPI0_RX << EDMA3CC_OPT_TCC_SHIFT );
805820 edma3_set_param (EDMA3_CHA_SPI0_RX , & ps );
806821
822+ // We play dangerously and don't flush the cache for commands (since they're const)
823+ // but we do need to flush the cache for the data which is read.
824+ spi_dev .rx_user_buf_addr = (uint32_t )data ;
825+ spi_dev .rx_user_buf_sz = sizeof (uint16_t ) * len ;
826+
807827 spi_dev .status = SPI_STATUS_WAIT_TX | SPI_STATUS_WAIT_RX ;
808828
809- // TODO: eventually needs DMA cache management
829+ // Prevent write to spi_dev.status from being reordered
810830 pbdrv_compiler_memory_barrier ();
811831
812832 EDMA3EnableTransfer (SOC_EDMA30CC_0_REGS , EDMA3_CHA_SPI0_TX , EDMA3_TRIG_MODE_EVENT );
0 commit comments