From 1b747867bd03695ee22c6d2593c2615ef9a3eb91 Mon Sep 17 00:00:00 2001 From: Matus Fabo Date: Mon, 25 Jul 2022 04:21:02 +0200 Subject: [PATCH] spi: implement yield for spi2 and spi3 add: yield functions for spi2 and spi3 add: spi23 start and end functions change: function names with spi1 that were not specific to spi1 change: chip data for spi2 and spi3 increased for timestamps change: merge spi_app_func_arg_t into app_func_arg_t change: moved os_func_data allocation before host check --- components/spi_flash/spi_flash_os_func_app.c | 113 +++++++++---------- 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/components/spi_flash/spi_flash_os_func_app.c b/components/spi_flash/spi_flash_os_func_app.c index 5dd958f9d9..dcea41619b 100644 --- a/components/spi_flash/spi_flash_os_func_app.c +++ b/components/spi_flash/spi_flash_os_func_app.c @@ -32,10 +32,6 @@ static const char TAG[] = "spi_flash"; * into the IRAM,and their data should be put into the DRAM. */ -typedef struct { - spi_bus_lock_dev_handle_t dev_lock; -} app_func_arg_t; - /* * Time yield algorithm: * Every time spi_flash_os_check_yield() is called: @@ -48,16 +44,16 @@ typedef struct { * counter mentioned in #2, but still be counted into the time mentioned in #2. */ typedef struct { - app_func_arg_t common_arg; //shared args, must be the first item + spi_bus_lock_dev_handle_t dev_lock; bool no_protect; //to decide whether to check protected region (for the main chip) or not. uint32_t acquired_since_us; // Time since last explicit yield() uint32_t released_since_us; // Time since last end() (implicit yield) -} spi1_app_func_arg_t; +} app_func_arg_t; -static inline void on_spi1_released(spi1_app_func_arg_t* ctx); -static inline void on_spi1_acquired(spi1_app_func_arg_t* ctx); -static inline void on_spi1_yielded(spi1_app_func_arg_t* ctx); -static inline bool on_spi1_check_yield(spi1_app_func_arg_t* ctx); +static inline void on_spi_released(app_func_arg_t* ctx); +static inline void on_spi_acquired(app_func_arg_t* ctx); +static inline void on_spi_yielded(app_func_arg_t* ctx); +static inline bool on_spi_check_yield(app_func_arg_t* ctx); IRAM_ATTR static void cache_enable(void* arg) { @@ -91,6 +87,18 @@ static IRAM_ATTR esp_err_t spi_end(void *arg) return spi_bus_lock_acquire_end(((app_func_arg_t *)arg)->dev_lock); } +static IRAM_ATTR esp_err_t spi23_start(void *arg){ + esp_err_t ret = spi_start(arg); + on_spi_acquired((app_func_arg_t*)arg); + return ret; +} + +static IRAM_ATTR esp_err_t spi23_end(void *arg){ + esp_err_t ret = spi_end(arg); + on_spi_released((app_func_arg_t*)arg); + return ret; +} + static IRAM_ATTR esp_err_t spi1_start(void *arg) { #if CONFIG_SPI_FLASH_SHARE_SPI1_BUS @@ -99,7 +107,7 @@ static IRAM_ATTR esp_err_t spi1_start(void *arg) #else //directly disable the cache and interrupts when lock is not used cache_disable(NULL); - on_spi1_acquired((spi1_app_func_arg_t*)arg); + on_spi_acquired((app_func_arg_t*)arg); return ESP_OK; #endif } @@ -112,17 +120,17 @@ static IRAM_ATTR esp_err_t spi1_end(void *arg) #else cache_enable(NULL); #endif - on_spi1_released((spi1_app_func_arg_t*)arg); + on_spi_released((app_func_arg_t*)arg); return ret; } -static IRAM_ATTR esp_err_t spi1_flash_os_check_yield(void *arg, uint32_t chip_status, uint32_t* out_request) +static IRAM_ATTR esp_err_t spi_flash_os_check_yield(void *arg, uint32_t chip_status, uint32_t* out_request) { assert (chip_status == 0); //TODO: support suspend esp_err_t ret = ESP_ERR_TIMEOUT; //Nothing happened uint32_t request = 0; - if (on_spi1_check_yield((spi1_app_func_arg_t *)arg)) { + if (on_spi_check_yield((app_func_arg_t *)arg)) { request = SPI_FLASH_YIELD_REQ_YIELD; ret = ESP_OK; } @@ -132,7 +140,7 @@ static IRAM_ATTR esp_err_t spi1_flash_os_check_yield(void *arg, uint32_t chip_st return ret; } -static IRAM_ATTR esp_err_t spi1_flash_os_yield(void *arg, uint32_t* out_status) +static IRAM_ATTR esp_err_t spi_flash_os_yield(void *arg, uint32_t* out_status) { if (likely(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)) { #ifdef CONFIG_SPI_FLASH_ERASE_YIELD_TICKS @@ -141,7 +149,7 @@ static IRAM_ATTR esp_err_t spi1_flash_os_yield(void *arg, uint32_t* out_status) vTaskDelay(1); #endif } - on_spi1_yielded((spi1_app_func_arg_t*)arg); + on_spi_yielded((app_func_arg_t*)arg); return ESP_OK; } @@ -179,7 +187,7 @@ static IRAM_ATTR void release_buffer_malloc(void* arg, void *temp_buf) static IRAM_ATTR esp_err_t main_flash_region_protected(void* arg, size_t start_addr, size_t size) { - if (((spi1_app_func_arg_t*)arg)->no_protect || esp_partition_main_flash_region_safe(start_addr, size)) { + if (((app_func_arg_t*)arg)->no_protect || esp_partition_main_flash_region_safe(start_addr, size)) { //ESP_OK = 0, also means protected==0 return ESP_OK; } else { @@ -194,7 +202,7 @@ static IRAM_ATTR void main_flash_op_status(uint32_t op_status) spi_flash_set_erasing_flag(is_erasing); } -static DRAM_ATTR spi1_app_func_arg_t main_flash_arg = {}; +static DRAM_ATTR app_func_arg_t main_flash_arg = {}; //for SPI1, we have to disable the cache and interrupts before using the SPI bus static const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functions = { @@ -204,8 +212,8 @@ static const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functi .delay_us = delay_us, .get_temp_buffer = get_buffer_malloc, .release_temp_buffer = release_buffer_malloc, - .check_yield = spi1_flash_os_check_yield, - .yield = spi1_flash_os_yield, + .check_yield = spi_flash_os_check_yield, + .yield = spi_flash_os_yield, #if CONFIG_SPI_FLASH_BROWNOUT_RESET .set_flash_op_status = main_flash_op_status, #else @@ -214,14 +222,14 @@ static const DRAM_ATTR esp_flash_os_functions_t esp_flash_spi1_default_os_functi }; static const esp_flash_os_functions_t esp_flash_spi23_default_os_functions = { - .start = spi_start, - .end = spi_end, + .start = spi23_start, + .end = spi23_end, .delay_us = delay_us, .get_temp_buffer = get_buffer_malloc, .release_temp_buffer = release_buffer_malloc, .region_protected = NULL, - .check_yield = NULL, - .yield = NULL, + .check_yield = spi_flash_os_check_yield, + .yield = spi_flash_os_yield, .set_flash_op_status = NULL, }; @@ -243,22 +251,16 @@ esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id, spi_bus_lo return ESP_ERR_INVALID_ARG; } - switch (host_id) - { + chip->os_func_data = heap_caps_malloc(sizeof(app_func_arg_t), + MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); + if (chip->os_func_data == NULL) { + return ESP_ERR_NO_MEM; + } + + switch (host_id) { case SPI1_HOST: //SPI1 chip->os_func = &esp_flash_spi1_default_os_functions; - chip->os_func_data = heap_caps_malloc(sizeof(spi1_app_func_arg_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - if (chip->os_func_data == NULL) { - return ESP_ERR_NO_MEM; - } - *(spi1_app_func_arg_t*) chip->os_func_data = (spi1_app_func_arg_t) { - .common_arg = { - .dev_lock = dev_handle, - }, - .no_protect = true, - }; break; case SPI2_HOST: #if SOC_SPI_PERIPH_NUM > 2 @@ -266,18 +268,17 @@ esp_err_t esp_flash_init_os_functions(esp_flash_t *chip, int host_id, spi_bus_lo #endif //SPI2, SPI3 chip->os_func = &esp_flash_spi23_default_os_functions; - chip->os_func_data = heap_caps_malloc(sizeof(app_func_arg_t), - MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - if (chip->os_func_data == NULL) { - return ESP_ERR_NO_MEM; - } - *(app_func_arg_t*) chip->os_func_data = (app_func_arg_t) { - .dev_lock = dev_handle, - }; break; - default: return ESP_ERR_INVALID_ARG; + default: + return ESP_ERR_INVALID_ARG; + break; } + *(app_func_arg_t*) chip->os_func_data = (app_func_arg_t) { + .dev_lock = dev_handle, + .no_protect = true, // This is OK because this code path isn't used for the main flash chip which requires `no_protect = false` + }; + return ESP_OK; } @@ -314,10 +315,8 @@ esp_err_t esp_flash_init_main_bus_lock(void) esp_err_t esp_flash_app_enable_os_functions(esp_flash_t* chip) { - main_flash_arg = (spi1_app_func_arg_t) { - .common_arg = { - .dev_lock = g_spi_lock_main_flash_dev, //for SPI1, - }, + main_flash_arg = (app_func_arg_t) { + .dev_lock = g_spi_lock_main_flash_dev, .no_protect = false, }; chip->os_func = &esp_flash_spi1_default_os_functions; @@ -331,11 +330,11 @@ esp_err_t esp_flash_app_enable_os_functions(esp_flash_t* chip) // Valid task execution interval: continuous time with the cache enabled, which is longer than // CONFIG_SPI_FLASH_ERASE_YIELD_TICKS. Yield time shorter than CONFIG_SPI_FLASH_ERASE_YIELD_TICKS is // not treated as valid interval. -static inline IRAM_ATTR bool on_spi1_check_yield(spi1_app_func_arg_t* ctx) +static inline IRAM_ATTR bool on_spi_check_yield(app_func_arg_t* ctx) { #ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE uint32_t time = esp_system_get_time(); - // We handle the reset here instead of in `on_spi1_acquired()`, when acquire() and release() is + // We handle the reset here instead of in `on_spi_acquired()`, when acquire() and release() is // larger than CONFIG_SPI_FLASH_ERASE_YIELD_TICKS, to save one `esp_system_get_time()` call if ((time - ctx->released_since_us) >= CONFIG_SPI_FLASH_ERASE_YIELD_TICKS * portTICK_PERIOD_MS * 1000) { // Reset the acquired time as if the yield has just happened. @@ -346,22 +345,22 @@ static inline IRAM_ATTR bool on_spi1_check_yield(spi1_app_func_arg_t* ctx) #endif return false; } -static inline IRAM_ATTR void on_spi1_released(spi1_app_func_arg_t* ctx) +static inline IRAM_ATTR void on_spi_released(app_func_arg_t* ctx) { #ifdef CONFIG_SPI_FLASH_YIELD_DURING_ERASE ctx->released_since_us = esp_system_get_time(); #endif } -static inline IRAM_ATTR void on_spi1_acquired(spi1_app_func_arg_t* ctx) +static inline IRAM_ATTR void on_spi_acquired(app_func_arg_t* ctx) { - // Ideally, when the time after `on_spi1_released()` before this function is called is larger + // Ideally, when the time after `on_spi_released()` before this function is called is larger // than CONFIG_SPI_FLASH_ERASE_YIELD_TICKS, the acquired time should be reset. We assume the - // time after `on_spi1_check_yield()` before this function is so short that we can do the reset + // time after `on_spi_check_yield()` before this function is so short that we can do the reset // in that function instead. } -static inline IRAM_ATTR void on_spi1_yielded(spi1_app_func_arg_t* ctx) +static inline IRAM_ATTR void on_spi_yielded(app_func_arg_t* ctx) { uint32_t time = esp_system_get_time(); ctx->acquired_since_us = time;