diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index ffbedd203d..95eaa60a7a 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -135,7 +135,6 @@ We have two bits to control the interrupt: #include "freertos/semphr.h" #include "freertos/xtensa_api.h" #include "freertos/task.h" -#include "freertos/ringbuf.h" #include "soc/soc.h" #include "soc/soc_memory_layout.h" #include "soc/dport_reg.h" @@ -709,7 +708,7 @@ static SPI_MASTER_ISR_ATTR esp_err_t device_acquire_bus_internal(spi_device_t *h /* This function check for whether the ISR is done, if not, block until semaphore given. */ -static inline esp_err_t device_wait_for_isr_idle(spi_device_t *handle, TickType_t wait) +static inline SPI_MASTER_ISR_ATTR esp_err_t device_wait_for_isr_idle(spi_device_t *handle, TickType_t wait) { //quickly skip if the isr is already free if (!handle->host->isr_free) { @@ -767,7 +766,7 @@ static SPI_MASTER_ISR_ATTR void device_release_bus_internal(spi_host_t *host) } } -static inline bool device_is_polling(spi_device_t *handle) +static inline SPI_MASTER_ISR_ATTR bool device_is_polling(spi_device_t *handle) { return atomic_load(&handle->host->acquire_cs) == handle->id && handle->host->polling; } @@ -1088,7 +1087,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) if (do_yield) portYIELD_FROM_ISR(); } -static esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t *trans_desc) +static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t *trans_desc) { SPI_CHECK(handle!=NULL, "invalid dev handle", ESP_ERR_INVALID_ARG); spi_host_t *host = handle->host; @@ -1112,7 +1111,7 @@ static esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t return ESP_OK; } -static SPI_MASTER_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf) +static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf) { spi_transaction_t *trans_desc = trans_buf->trans; if ((void *)trans_buf->buffer_to_send != &trans_desc->tx_data[0] && @@ -1131,7 +1130,7 @@ static SPI_MASTER_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf) } } -static SPI_MASTER_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_desc, spi_trans_priv_t* new_desc, bool isdma) +static SPI_MASTER_ISR_ATTR esp_err_t setup_priv_desc(spi_transaction_t *trans_desc, spi_trans_priv_t* new_desc, bool isdma) { *new_desc = (spi_trans_priv_t) { .trans = trans_desc, }; diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index 970bc69108..5d3026dc65 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -29,7 +29,6 @@ #include "freertos/semphr.h" #include "freertos/xtensa_api.h" #include "freertos/task.h" -#include "freertos/ringbuf.h" #include "soc/soc.h" #include "soc/soc_memory_layout.h" #include "soc/dport_reg.h" diff --git a/components/driver/test/test_spi_master.c b/components/driver/test/test_spi_master.c index b431a22142..dc8ea63d34 100644 --- a/components/driver/test/test_spi_master.c +++ b/components/driver/test/test_spi_master.c @@ -507,7 +507,6 @@ TEST_CASE("SPI Master no response when switch from host1 (HSPI) to host2 (VSPI)" TEST_ASSERT(spi_bus_free(host) == ESP_OK); } -IRAM_ATTR static uint32_t data_iram[80]; DRAM_ATTR static uint32_t data_dram[80]={0}; //force to place in code area. static const uint8_t data_drom[320+3] = { @@ -544,13 +543,24 @@ TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]") #ifdef CONFIG_SPIRAM_SUPPORT //test psram if enabled ESP_LOGI(TAG, "testing PSRAM..."); - uint32_t* data_malloc = (uint32_t*)heap_caps_calloc(1, 324, MALLOC_CAP_SPIRAM); + uint32_t* data_malloc = (uint32_t*)heap_caps_malloc(324, MALLOC_CAP_SPIRAM); + TEST_ASSERT(esp_ptr_external_ram(data_malloc)); #else - uint32_t* data_malloc = (uint32_t*)heap_caps_calloc(1, 324, MALLOC_CAP_DMA); + uint32_t* data_malloc = (uint32_t*)heap_caps_malloc(324, MALLOC_CAP_DMA); + TEST_ASSERT(esp_ptr_in_dram(data_malloc)); #endif - TEST_ASSERT(data_malloc != NULL); + //refer to soc_memory_layout.c + uint32_t* data_iram = (uint32_t*)heap_caps_malloc(324, MALLOC_CAP_EXEC); + TEST_ASSERT(data_iram != NULL); + + ESP_LOGI(TAG, "iram: %p, dram: %p", data_iram, data_dram); + ESP_LOGI(TAG, "drom: %p, malloc: %p", data_drom, data_malloc); + TEST_ASSERT(esp_ptr_in_dram(data_dram)); + TEST_ASSERT(esp_ptr_in_iram(data_iram)); + TEST_ASSERT(esp_ptr_in_drom(data_drom)); + srand(52); for (int i = 0; i < 320/4; i++) { data_iram[i] = rand(); @@ -577,8 +587,6 @@ TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]") static spi_transaction_t trans[TEST_REGION_SIZE]; int x; - ESP_LOGI(TAG, "iram: %p, dram: %p", data_iram, data_dram); - ESP_LOGI(TAG, "drom: %p, malloc: %p", data_drom, data_malloc); memset(trans, 0, sizeof(trans)); @@ -619,6 +627,7 @@ TEST_CASE("SPI Master DMA test, TX and RX in different regions", "[spi]") TEST_ASSERT(spi_bus_remove_device(spi) == ESP_OK); TEST_ASSERT(spi_bus_free(HSPI_HOST) == ESP_OK); free(data_malloc); + free(data_iram); } //this part tests 3 DMA issues in master mode, full-duplex in IDF2.1 @@ -1350,9 +1359,26 @@ static void sorted_array_insert(uint32_t* array, int* size, uint32_t item) #define TEST_TIMES 11 -TEST_CASE("spi_speed","[spi]") +static IRAM_ATTR void spi_transmit_measure(spi_device_handle_t spi, spi_transaction_t* trans, uint32_t* t_flight) { RECORD_TIME_PREPARE(); + spi_device_transmit(spi, trans); // prime the flash cache + RECORD_TIME_START(); + spi_device_transmit(spi, trans); + RECORD_TIME_END(t_flight); +} + +static IRAM_ATTR void spi_transmit_polling_measure(spi_device_handle_t spi, spi_transaction_t* trans, uint32_t* t_flight) +{ + RECORD_TIME_PREPARE(); + spi_device_polling_transmit(spi, trans); // prime the flash cache + RECORD_TIME_START(); + spi_device_polling_transmit(spi, trans); + RECORD_TIME_END(t_flight); +} + +TEST_CASE("spi_speed","[spi]") +{ uint32_t t_flight; //to get rid of the influence of randomly interrupts, we measured the performance by median value uint32_t t_flight_sorted[TEST_TIMES]; @@ -1372,16 +1398,13 @@ TEST_CASE("spi_speed","[spi]") //record flight time by isr, with DMA t_flight_num = 0; for (int i = 0; i < TEST_TIMES; i++) { - spi_device_transmit(spi, &trans); // prime the flash cache - RECORD_TIME_START(); - spi_device_transmit(spi, &trans); - RECORD_TIME_END(&t_flight); + spi_transmit_measure(spi, &trans, &t_flight); sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight); } - TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); for (int i = 0; i < TEST_TIMES; i++) { ESP_LOGI(TAG, "%d", t_flight_sorted[i]); } + TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_NO_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); //acquire the bus to send polling transactions faster ret = spi_device_acquire_bus(spi, portMAX_DELAY); @@ -1390,16 +1413,13 @@ TEST_CASE("spi_speed","[spi]") //record flight time by polling and with DMA t_flight_num = 0; for (int i = 0; i < TEST_TIMES; i++) { - spi_device_polling_transmit(spi, &trans); // prime the flash cache - RECORD_TIME_START(); - spi_device_polling_transmit(spi, &trans); - RECORD_TIME_END(&t_flight); + spi_transmit_polling_measure(spi, &trans, &t_flight); sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight); } - TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); for (int i = 0; i < TEST_TIMES; i++) { ESP_LOGI(TAG, "%d", t_flight_sorted[i]); } + TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); //release the bus spi_device_release_bus(spi); @@ -1410,16 +1430,13 @@ TEST_CASE("spi_speed","[spi]") //record flight time by isr, without DMA t_flight_num = 0; for (int i = 0; i < TEST_TIMES; i++) { - spi_device_transmit(spi, &trans); // prime the flash cache - RECORD_TIME_START(); - spi_device_transmit(spi, &trans); - RECORD_TIME_END(&t_flight); + spi_transmit_measure(spi, &trans, &t_flight); sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight); } - TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); for (int i = 0; i < TEST_TIMES; i++) { ESP_LOGI(TAG, "%d", t_flight_sorted[i]); } + TEST_PERFORMANCE_LESS_THAN( SPI_PER_TRANS_NO_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); //acquire the bus to send polling transactions faster ret = spi_device_acquire_bus(spi, portMAX_DELAY); @@ -1427,16 +1444,13 @@ TEST_CASE("spi_speed","[spi]") //record flight time by polling, without DMA t_flight_num = 0; for (int i = 0; i < TEST_TIMES; i++) { - spi_device_polling_transmit(spi, &trans); // prime the flash cache - RECORD_TIME_START(); - spi_device_polling_transmit(spi, &trans); - RECORD_TIME_END(&t_flight); + spi_transmit_polling_measure(spi, &trans, &t_flight); sorted_array_insert(t_flight_sorted, &t_flight_num, t_flight); } - TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); for (int i = 0; i < TEST_TIMES; i++) { ESP_LOGI(TAG, "%d", t_flight_sorted[i]); } + TEST_PERFORMANCE_LESS_THAN(SPI_PER_TRANS_POLLING_NO_DMA, "%d us", t_flight_sorted[(TEST_TIMES+1)/2]); //release the bus spi_device_release_bus(spi); diff --git a/components/soc/esp32/include/soc/soc.h b/components/soc/esp32/include/soc/soc.h index ff90df5420..15b77a3637 100644 --- a/components/soc/esp32/include/soc/soc.h +++ b/components/soc/esp32/include/soc/soc.h @@ -59,16 +59,18 @@ #define APP_CPU_NUM (1) /* Overall memory map */ -#define SOC_IROM_LOW 0x400D0000 -#define SOC_IROM_HIGH 0x40400000 -#define SOC_DROM_LOW 0x3F400000 -#define SOC_DROM_HIGH 0x3F800000 -#define SOC_RTC_IRAM_LOW 0x400C0000 -#define SOC_RTC_IRAM_HIGH 0x400C2000 -#define SOC_RTC_DATA_LOW 0x50000000 -#define SOC_RTC_DATA_HIGH 0x50002000 -#define SOC_EXTRAM_DATA_LOW 0x3F800000 -#define SOC_EXTRAM_DATA_HIGH 0x3FC00000 +#define SOC_IROM_LOW 0x400D0000 +#define SOC_IROM_HIGH 0x40400000 +#define SOC_DROM_LOW 0x3F400000 +#define SOC_DROM_HIGH 0x3F800000 +#define SOC_DRAM_LOW 0x3FAE0000 +#define SOC_DRAM_HIGH 0x40000000 +#define SOC_RTC_IRAM_LOW 0x400C0000 +#define SOC_RTC_IRAM_HIGH 0x400C2000 +#define SOC_RTC_DATA_LOW 0x50000000 +#define SOC_RTC_DATA_HIGH 0x50002000 +#define SOC_EXTRAM_DATA_LOW 0x3F800000 +#define SOC_EXTRAM_DATA_HIGH 0x3FC00000 #define DR_REG_DPORT_BASE 0x3ff00000 @@ -130,7 +132,7 @@ //Registers Operation {{ #define ETS_UNCACHED_ADDR(addr) (addr) -#define ETS_CACHED_ADDR(addr) (addr) +#define ETS_CACHED_ADDR(addr) (addr) #ifndef __ASSEMBLER__ #define BIT(nr) (1UL << (nr)) diff --git a/components/soc/include/soc/soc_memory_layout.h b/components/soc/include/soc/soc_memory_layout.h index b1e8d6eb98..8c96404832 100644 --- a/components/soc/include/soc/soc_memory_layout.h +++ b/components/soc/include/soc/soc_memory_layout.h @@ -173,3 +173,15 @@ inline static bool IRAM_ATTR esp_ptr_internal(const void *p) { inline static bool IRAM_ATTR esp_ptr_external_ram(const void *p) { return ((intptr_t)p >= SOC_EXTRAM_DATA_LOW && (intptr_t)p < SOC_EXTRAM_DATA_HIGH); } + +inline static bool IRAM_ATTR esp_ptr_in_iram(const void *p) { + return ((intptr_t)p >= SOC_IRAM_LOW && (intptr_t)p < SOC_IRAM_HIGH); +} + +inline static bool IRAM_ATTR esp_ptr_in_drom(const void *p) { + return ((intptr_t)p >= SOC_DROM_LOW && (intptr_t)p < SOC_DROM_HIGH); +} + +inline static bool IRAM_ATTR esp_ptr_in_dram(const void *p) { + return ((intptr_t)p >= SOC_DRAM_LOW && (intptr_t)p < SOC_DRAM_HIGH); +}