mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 10:40:47 +03:00
fix(driver_spi): fixes psram dma rx buffer memory barrier issue
This commit is contained in:
@@ -154,6 +154,14 @@ void spicommon_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, in
|
||||
*/
|
||||
esp_err_t spicommon_dma_setup_priv_buffer(spi_host_device_t host_id, uint32_t *buffer, uint32_t len, bool is_tx, bool psram_prefer, bool auto_malloc, uint32_t **ret_buffer);
|
||||
|
||||
/**
|
||||
* @brief Memory barrier for DMA RX buffer
|
||||
*
|
||||
* @param host_id SPI host ID
|
||||
* @param rx_buffer RX buffer
|
||||
*/
|
||||
void spicommon_dma_rx_mb(spi_host_device_t host_id, void *rx_buffer);
|
||||
|
||||
/**
|
||||
* @brief Free DMA for SPI
|
||||
*
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#include "soc/dport_reg.h"
|
||||
#endif
|
||||
#if CONFIG_SPIRAM
|
||||
#include "esp_private/esp_psram_mspi.h"
|
||||
#endif
|
||||
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
#define SPI_COMMON_PERI_CLOCK_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
@@ -438,6 +441,17 @@ esp_err_t SPI_COMMON_ISR_ATTR spicommon_dma_setup_priv_buffer(spi_host_device_t
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void SPI_COMMON_ISR_ATTR spicommon_dma_rx_mb(spi_host_device_t host_id, void *rx_buffer)
|
||||
{
|
||||
(void)host_id;
|
||||
#if SOC_PSRAM_DMA_CAPABLE && CONFIG_SPIRAM
|
||||
if (esp_ptr_external_ram(rx_buffer)) {
|
||||
// dma rx data to psram need memory barrier fix
|
||||
esp_psram_mspi_mb();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------------------------------------------------------free dma periph-------------------------------------------------------//
|
||||
esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id)
|
||||
{
|
||||
|
||||
@@ -1002,6 +1002,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
|
||||
//This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same
|
||||
spicommon_dmaworkaround_idle(dma_ctx->tx_dma_chan.chan_id);
|
||||
#endif //#if CONFIG_IDF_TARGET_ESP32
|
||||
spicommon_dma_rx_mb(host->id, host->cur_trans_buf.buffer_to_rcv);
|
||||
spi_trans_dma_error_check(host);
|
||||
}
|
||||
|
||||
@@ -1429,6 +1430,7 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_end(spi_device_handle_t handle,
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
spicommon_dma_rx_mb(host->id, host->cur_trans_buf.buffer_to_rcv);
|
||||
spi_trans_dma_error_check(host);
|
||||
uint32_t trans_flags = host->cur_trans_buf.trans->flags; // save the flags before bus_lock release
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -654,6 +654,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
// When DMA is enabled, the slave rx dma suffers from unexpected transactions. Forbid reading until transaction ready.
|
||||
if (use_dma) {
|
||||
freeze_cs(host);
|
||||
spicommon_dma_rx_mb(host->id, host->cur_trans.rx_buffer);
|
||||
spi_slave_trans_dma_error_check(host);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "esp_compiler.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_cache.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
@@ -19,9 +20,6 @@
|
||||
#include "esp_private/esp_cache_private.h"
|
||||
#include "driver/spi_slave_hd.h"
|
||||
#include "hal/spi_slave_hd_hal.h"
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#include "esp_cache.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define SPI_SLAVE_ISR_ATTR IRAM_ATTR
|
||||
@@ -476,6 +474,7 @@ static SPI_SLAVE_ISR_ATTR void s_spi_slave_hd_segment_isr(void *arg)
|
||||
host->tx_curr_trans.trans = NULL;
|
||||
}
|
||||
if (rx_done) {
|
||||
spicommon_dma_rx_mb(host->host_id, host->rx_curr_trans.aligned_buffer);
|
||||
spi_slave_hd_rx_dma_error_check(host, host->rx_curr_trans);
|
||||
bool ret_queue = true;
|
||||
host->rx_curr_trans.trans->trans_len = spi_slave_hd_hal_rxdma_seg_get_len(hal);
|
||||
@@ -617,6 +616,7 @@ static SPI_SLAVE_ISR_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
ret_priv_trans.trans->trans_len = trans_len;
|
||||
|
||||
bool ret_queue = true;
|
||||
spicommon_dma_rx_mb(host->host_id, ret_priv_trans.aligned_buffer);
|
||||
spi_slave_hd_rx_dma_error_check(host, ret_priv_trans);
|
||||
if (callback->cb_recv) {
|
||||
spi_slave_hd_event_t ev = {
|
||||
|
||||
Reference in New Issue
Block a user