forked from espressif/esp-idf
fix(driver_spi): make slave_hd isr can place in flash to save iram
This commit is contained in:
@ -5,7 +5,6 @@ if(${target} STREQUAL "linux")
|
||||
endif()
|
||||
|
||||
set(srcs "")
|
||||
|
||||
set(public_include "include")
|
||||
|
||||
if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
@ -13,17 +12,21 @@ if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
"src/gpspi/spi_common.c"
|
||||
"src/gpspi/spi_master.c"
|
||||
"src/gpspi/spi_slave.c"
|
||||
"src/gpspi/spi_dma.c"
|
||||
)
|
||||
|
||||
if(NOT CONFIG_SOC_GDMA_SUPPORTED)
|
||||
list(APPEND srcs "src/gpspi/spi_dma.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2)
|
||||
list(APPEND srcs "src/gpspi/spi_slave_hd.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${public_include}
|
||||
REQUIRES esp_pm
|
||||
PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio esp_ringbuf
|
||||
LDFRAGMENTS "linker.lf"
|
||||
)
|
||||
idf_component_register(
|
||||
SRCS ${srcs}
|
||||
INCLUDE_DIRS ${public_include}
|
||||
REQUIRES esp_pm
|
||||
PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio
|
||||
LDFRAGMENTS "linker.lf"
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -274,13 +274,6 @@ void spicommon_dmaworkaround_transfer_active(int dmachan);
|
||||
/*******************************************************************************
|
||||
* Bus attributes
|
||||
******************************************************************************/
|
||||
/**
|
||||
* @brief Set bus lock for the main bus, called by startup code.
|
||||
*
|
||||
* @param lock The lock to be used by the main SPI bus.
|
||||
*/
|
||||
void spi_bus_main_set_lock(spi_bus_lock_handle_t lock);
|
||||
|
||||
/**
|
||||
* @brief Get the attributes of a specified SPI bus.
|
||||
*
|
||||
|
@ -1,14 +1,3 @@
|
||||
[mapping:gpspi_driver]
|
||||
archive: libesp_driver_spi.a
|
||||
entries:
|
||||
# SOC_GDMA_SUPPORTED is undeclared if GDMA not support, so use `SOC_GDMA_SUPPORTED != y` instead
|
||||
if SOC_GDMA_SUPPORTED != y && (SPI_MASTER_ISR_IN_IRAM = y || SPI_SLAVE_ISR_IN_IRAM = y):
|
||||
spi_dma: spi_dma_reset (noflash)
|
||||
spi_dma: spi_dma_start (noflash)
|
||||
|
||||
if SOC_SPI_SUPPORT_SLAVE_HD_VER2 = y:
|
||||
spi_dma: spi_dma_get_eof_desc (noflash)
|
||||
|
||||
[mapping:gpspi_hal]
|
||||
archive: libhal.a
|
||||
entries:
|
||||
|
@ -29,16 +29,20 @@
|
||||
#include "soc/dport_reg.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPI_MASTER_ISR_IN_IRAM || CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define SPI_COMMON_ISR_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define SPI_COMMON_ISR_ATTR
|
||||
#endif
|
||||
|
||||
static const char *SPI_TAG = "spi";
|
||||
|
||||
#define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, SPI_TAG, str)
|
||||
|
||||
#define SPI_CHECK_PIN(pin_num, pin_name, check_output) if (check_output) { \
|
||||
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(pin_num), pin_name" not valid", ESP_ERR_INVALID_ARG); \
|
||||
} else { \
|
||||
SPI_CHECK(GPIO_IS_VALID_GPIO(pin_num), pin_name" not valid", ESP_ERR_INVALID_ARG); \
|
||||
}
|
||||
|
||||
#define SPI_MAIN_BUS_DEFAULT() { \
|
||||
.host_id = 0, \
|
||||
.bus_attr = { \
|
||||
@ -66,7 +70,7 @@ static spicommon_bus_context_t* bus_ctx[SOC_SPI_PERIPH_NUM] = {&s_mainbus};
|
||||
static __attribute__((constructor)) void spi_bus_lock_init_main_bus(void)
|
||||
{
|
||||
/* Initialize bus context about the main SPI bus lock, called during chip startup. */
|
||||
spi_bus_main_set_lock(g_main_spi_bus_lock);
|
||||
bus_ctx[0]->bus_attr.lock = g_main_spi_bus_lock;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -303,7 +307,7 @@ esp_err_t spicommon_dma_desc_alloc(spi_dma_ctx_t *dma_ctx, int cfg_max_sz, int *
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void IRAM_ATTR spicommon_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, int len, bool is_rx)
|
||||
void SPI_COMMON_ISR_ATTR spicommon_dma_desc_setup_link(spi_dma_desc_t *dmadesc, const void *data, int len, bool is_rx)
|
||||
{
|
||||
dmadesc = ADDR_DMA_2_CPU(dmadesc);
|
||||
int n = 0;
|
||||
@ -767,11 +771,6 @@ bool spicommon_bus_using_iomux(spi_host_device_t host)
|
||||
return true;
|
||||
}
|
||||
|
||||
void spi_bus_main_set_lock(spi_bus_lock_handle_t lock)
|
||||
{
|
||||
bus_ctx[0]->bus_attr.lock = lock;
|
||||
}
|
||||
|
||||
spi_bus_lock_handle_t spi_bus_lock_get_by_id(spi_host_device_t host_id)
|
||||
{
|
||||
return bus_ctx[host_id]->bus_attr.lock;
|
||||
@ -1019,7 +1018,7 @@ static void *dmaworkaround_cb_arg;
|
||||
static portMUX_TYPE dmaworkaround_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
static int dmaworkaround_waiting_for_chan = 0;
|
||||
|
||||
bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg)
|
||||
bool SPI_COMMON_ISR_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg)
|
||||
{
|
||||
|
||||
int otherchan = (dmachan == 1) ? 2 : 1;
|
||||
@ -1042,12 +1041,12 @@ bool IRAM_ATTR spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress(void)
|
||||
bool SPI_COMMON_ISR_ATTR spicommon_dmaworkaround_reset_in_progress(void)
|
||||
{
|
||||
return (dmaworkaround_waiting_for_chan != 0);
|
||||
}
|
||||
|
||||
void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
void SPI_COMMON_ISR_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
{
|
||||
portENTER_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
dmaworkaround_channels_busy[dmachan - 1] = 0;
|
||||
@ -1064,7 +1063,7 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||
portEXIT_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
}
|
||||
|
||||
void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
|
||||
void SPI_COMMON_ISR_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
|
||||
{
|
||||
portENTER_CRITICAL_ISR(&dmaworkaround_mux);
|
||||
dmaworkaround_channels_busy[dmachan - 1] = 1;
|
||||
|
@ -1,13 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_private/spi_dma.h"
|
||||
#include "hal/spi_ll.h"
|
||||
|
||||
#if !SOC_GDMA_SUPPORTED
|
||||
#if CONFIG_SPI_MASTER_ISR_IN_IRAM || CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define SPI_DMA_ISR_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define SPI_DMA_ISR_ATTR
|
||||
#endif
|
||||
|
||||
void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bool desc_burst)
|
||||
{
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
@ -35,7 +41,7 @@ void spi_dma_append(spi_dma_chan_handle_t chan_handle)
|
||||
|
||||
/************************************* IRAM CONTEXT **************************************/
|
||||
|
||||
uint32_t spi_dma_get_eof_desc(spi_dma_chan_handle_t chan_handle)
|
||||
uint32_t SPI_DMA_ISR_ATTR spi_dma_get_eof_desc(spi_dma_chan_handle_t chan_handle)
|
||||
{
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
@ -45,7 +51,7 @@ uint32_t spi_dma_get_eof_desc(spi_dma_chan_handle_t chan_handle)
|
||||
}
|
||||
#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
|
||||
void spi_dma_reset(spi_dma_chan_handle_t chan_handle)
|
||||
void SPI_DMA_ISR_ATTR spi_dma_reset(spi_dma_chan_handle_t chan_handle)
|
||||
{
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
@ -56,7 +62,7 @@ void spi_dma_reset(spi_dma_chan_handle_t chan_handle)
|
||||
}
|
||||
}
|
||||
|
||||
void spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr)
|
||||
void SPI_DMA_ISR_ATTR spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr)
|
||||
{
|
||||
spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id);
|
||||
|
||||
@ -66,4 +72,3 @@ void spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr)
|
||||
spi_dma_ll_rx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -12,7 +12,6 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/ringbuf.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "esp_private/spi_common_internal.h"
|
||||
@ -24,6 +23,12 @@
|
||||
#include "esp_cache.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define SPI_SLAVE_ISR_ATTR IRAM_ATTR
|
||||
#else
|
||||
#define SPI_SLAVE_ISR_ATTR
|
||||
#endif
|
||||
|
||||
#if (SOC_SPI_PERIPH_NUM == 2)
|
||||
#define VALID_HOST(x) ((x) == SPI2_HOST)
|
||||
#elif (SOC_SPI_PERIPH_NUM == 3)
|
||||
@ -106,6 +111,9 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
|
||||
#elif SOC_GDMA_SUPPORTED
|
||||
SPIHD_CHECK(config->dma_chan == SPI_DMA_CH_AUTO, "dma is required or invalid channel, only support SPI_DMA_CH_AUTO", ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
#ifndef CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
SPIHD_CHECK((bus_config->intr_flags & ESP_INTR_FLAG_IRAM) == 0, "ESP_INTR_FLAG_IRAM should be disabled when CONFIG_SPI_SLAVE_ISR_IN_IRAM is not set.", ESP_ERR_INVALID_ARG);
|
||||
#endif
|
||||
|
||||
spi_chan_claimed = spicommon_periph_claim(host_id, "slave_hd");
|
||||
SPIHD_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
|
||||
@ -241,12 +249,12 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
|
||||
|
||||
//Alloc intr
|
||||
if (!host->append_mode) {
|
||||
ret = esp_intr_alloc(spicommon_irqsource_for_host(host_id), 0, s_spi_slave_hd_segment_isr,
|
||||
ret = esp_intr_alloc(spicommon_irqsource_for_host(host_id), bus_config->intr_flags, s_spi_slave_hd_segment_isr,
|
||||
(void *)host, &host->intr);
|
||||
if (ret != ESP_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), 0, s_spi_slave_hd_segment_isr,
|
||||
ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), bus_config->intr_flags, s_spi_slave_hd_segment_isr,
|
||||
(void *)host, &host->intr_dma);
|
||||
if (ret != ESP_OK) {
|
||||
goto cleanup;
|
||||
@ -262,7 +270,7 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
|
||||
gdma_register_rx_event_callbacks(host->dma_ctx->rx_dma_chan, &txrx_cbs, host);
|
||||
#else
|
||||
//On ESP32S2, `cmd7` and `cmd8` are designed as all `spi_dma` events, so use `dma_src` only
|
||||
ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), 0, s_spi_slave_hd_append_legacy_isr,
|
||||
ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), bus_config->intr_flags, s_spi_slave_hd_append_legacy_isr,
|
||||
(void *)host, &host->intr_dma);
|
||||
if (ret != ESP_OK) {
|
||||
goto cleanup;
|
||||
@ -405,7 +413,7 @@ static void rx_invoke(spi_slave_hd_slot_t *host)
|
||||
portEXIT_CRITICAL(&host->int_spinlock);
|
||||
}
|
||||
|
||||
static inline IRAM_ATTR BaseType_t intr_check_clear_callback(spi_slave_hd_slot_t *host, spi_event_t ev, slave_cb_t cb)
|
||||
static inline SPI_SLAVE_ISR_ATTR BaseType_t intr_check_clear_callback(spi_slave_hd_slot_t *host, spi_event_t ev, slave_cb_t cb)
|
||||
{
|
||||
BaseType_t cb_awoken = pdFALSE;
|
||||
if (spi_slave_hd_hal_check_clear_event(&host->hal, ev) && cb) {
|
||||
@ -414,7 +422,7 @@ static inline IRAM_ATTR BaseType_t intr_check_clear_callback(spi_slave_hd_slot_t
|
||||
}
|
||||
return cb_awoken;
|
||||
}
|
||||
static IRAM_ATTR void s_spi_slave_hd_segment_isr(void *arg)
|
||||
static SPI_SLAVE_ISR_ATTR void s_spi_slave_hd_segment_isr(void *arg)
|
||||
{
|
||||
spi_slave_hd_slot_t *host = (spi_slave_hd_slot_t *)arg;
|
||||
spi_slave_hd_callback_config_t *callback = &host->callback;
|
||||
@ -536,7 +544,7 @@ static IRAM_ATTR void s_spi_slave_hd_segment_isr(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg)
|
||||
static SPI_SLAVE_ISR_ATTR void spi_slave_hd_append_tx_isr(void *arg)
|
||||
{
|
||||
spi_slave_hd_slot_t *host = (spi_slave_hd_slot_t*)arg;
|
||||
spi_slave_hd_callback_config_t *callback = &host->callback;
|
||||
@ -579,7 +587,7 @@ static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
static SPI_SLAVE_ISR_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
{
|
||||
spi_slave_hd_slot_t *host = (spi_slave_hd_slot_t*)arg;
|
||||
spi_slave_hd_callback_config_t *callback = &host->callback;
|
||||
@ -631,7 +639,7 @@ static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
}
|
||||
|
||||
#if SOC_GDMA_SUPPORTED
|
||||
static IRAM_ATTR bool s_spi_slave_hd_append_gdma_isr(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
|
||||
static SPI_SLAVE_ISR_ATTR bool s_spi_slave_hd_append_gdma_isr(gdma_channel_handle_t dma_chan, gdma_event_data_t *event_data, void *user_data)
|
||||
{
|
||||
assert(event_data);
|
||||
spi_slave_hd_slot_t *host = (spi_slave_hd_slot_t*)user_data;
|
||||
@ -646,7 +654,7 @@ static IRAM_ATTR bool s_spi_slave_hd_append_gdma_isr(gdma_channel_handle_t dma_c
|
||||
}
|
||||
|
||||
#else
|
||||
static IRAM_ATTR void s_spi_slave_hd_append_legacy_isr(void *arg)
|
||||
static SPI_SLAVE_ISR_ATTR void s_spi_slave_hd_append_legacy_isr(void *arg)
|
||||
{
|
||||
spi_slave_hd_slot_t *host = (spi_slave_hd_slot_t *)arg;
|
||||
spi_slave_hd_hal_context_t *hal = &host->hal;
|
||||
|
@ -121,7 +121,7 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
|
||||
|
||||
// Test All clock source
|
||||
#define TEST_CLK_BYTE_LEN 10000
|
||||
#define TEST_TRANS_TIME_BIAS_RATIO (float)2.0/100 // think 2% transfer time bias as acceptable
|
||||
#define TEST_TRANS_TIME_BIAS_RATIO (float)5.0/100 // think 5% transfer time bias as acceptable
|
||||
TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]")
|
||||
{
|
||||
int64_t start = 0, end = 0;
|
||||
@ -1380,8 +1380,8 @@ TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test",
|
||||
/********************************************************************************
|
||||
* Test SPI transaction interval
|
||||
********************************************************************************/
|
||||
//Disabled since the check in portENTER_CRITICAL in esp_intr_enable/disable increase the delay
|
||||
#ifndef CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
|
||||
//Disabled since place code in flash increase the delay
|
||||
#if CONFIG_SPI_MASTER_ISR_IN_IRAM
|
||||
|
||||
#define RECORD_TIME_PREPARE() uint32_t __t1, __t2
|
||||
#define RECORD_TIME_START() do {__t1 = esp_cpu_get_cycle_count();}while(0)
|
||||
|
@ -10,7 +10,6 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
'config',
|
||||
[
|
||||
'release',
|
||||
'freertos_compliance',
|
||||
'freertos_flash',
|
||||
],
|
||||
indirect=True,
|
||||
@ -47,18 +46,8 @@ def test_master_esp_flash(case_tester) -> None: # type: ignore
|
||||
@pytest.mark.parametrize(
|
||||
'count, config',
|
||||
[
|
||||
(
|
||||
2,
|
||||
'release',
|
||||
),
|
||||
(
|
||||
2,
|
||||
'freertos_compliance',
|
||||
),
|
||||
(
|
||||
2,
|
||||
'freertos_flash',
|
||||
),
|
||||
(2, 'release'),
|
||||
(2, 'freertos_flash'),
|
||||
(2, 'iram_safe'),
|
||||
],
|
||||
indirect=True,
|
||||
|
@ -1,3 +0,0 @@
|
||||
CONFIG_PM_ENABLE=y
|
||||
CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE=y
|
@ -1 +1,3 @@
|
||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
|
||||
CONFIG_SPI_SLAVE_ISR_IN_IRAM=n
|
||||
|
Reference in New Issue
Block a user