From fe13b2ed50f4f61c160afd6bef6a8e0571d2a821 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 3 Mar 2022 15:34:32 +0800 Subject: [PATCH 1/4] lcd: add rgb isr iram safe callback test --- components/esp_lcd/include/esp_lcd_panel_rgb.h | 2 +- components/esp_lcd/src/esp_lcd_panel_io_spi.c | 2 +- components/esp_lcd/src/esp_lcd_rgb_panel.c | 2 +- .../esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c | 13 ++++++++++++- docs/en/migration-guides/peripherals.rst | 7 ------- examples/peripherals/lcd/rgb_panel/README.md | 2 +- .../lcd/rgb_panel/main/rgb_lcd_example_main.c | 1 + 7 files changed, 17 insertions(+), 12 deletions(-) diff --git a/components/esp_lcd/include/esp_lcd_panel_rgb.h b/components/esp_lcd/include/esp_lcd_panel_rgb.h index 836fc343de..0f654939ef 100644 --- a/components/esp_lcd/include/esp_lcd_panel_rgb.h +++ b/components/esp_lcd/include/esp_lcd_panel_rgb.h @@ -64,7 +64,7 @@ typedef struct { unsigned int hsync_idle_low: 1; /*!< The hsync signal is low in IDLE state */ unsigned int vsync_idle_low: 1; /*!< The vsync signal is low in IDLE state */ unsigned int de_idle_high: 1; /*!< The de signal is high in IDLE state */ - unsigned int pclk_active_pos: 1; /*!< Whether the display data is clocked out on the rising edge of PCLK */ + unsigned int pclk_active_neg: 1; /*!< Whether the display data is clocked out on the falling edge of PCLK */ unsigned int pclk_idle_high: 1; /*!< The PCLK stays at high level in IDLE phase */ } flags; } esp_lcd_rgb_timing_t; diff --git a/components/esp_lcd/src/esp_lcd_panel_io_spi.c b/components/esp_lcd/src/esp_lcd_panel_io_spi.c index 0d8a4a7e0f..9ce2a3000d 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_spi.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_spi.c @@ -254,7 +254,7 @@ static esp_err_t panel_io_spi_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons ESP_GOTO_ON_ERROR(ret, err, TAG, "spi transmit (polling) command failed"); // split to chunks if required: - // the SPI bus has a maximum transaction size determined by SPI_USR_MOSI_DBITLEN's bit width + // the SPI bus has a maximum transaction size determined by SPI_LL_DATA_MAX_BIT_LEN do { size_t chunk_size = color_size; diff --git a/components/esp_lcd/src/esp_lcd_rgb_panel.c b/components/esp_lcd/src/esp_lcd_rgb_panel.c index b93218bfdf..8ad8efc7be 100644 --- a/components/esp_lcd/src/esp_lcd_rgb_panel.c +++ b/components/esp_lcd/src/esp_lcd_rgb_panel.c @@ -266,7 +266,7 @@ static esp_err_t rgb_panel_init(esp_lcd_panel_t *panel) rgb_panel->timings.pclk_hz = rgb_panel->resolution_hz / pclk_prescale; // pixel clock phase and polarity lcd_ll_set_clock_idle_level(rgb_panel->hal.dev, rgb_panel->timings.flags.pclk_idle_high); - lcd_ll_set_pixel_clock_edge(rgb_panel->hal.dev, !rgb_panel->timings.flags.pclk_active_pos); + lcd_ll_set_pixel_clock_edge(rgb_panel->hal.dev, rgb_panel->timings.flags.pclk_active_neg); // enable RGB mode and set data width lcd_ll_enable_rgb_mode(rgb_panel->hal.dev, true); lcd_ll_set_data_width(rgb_panel->hal.dev, rgb_panel->data_width); diff --git a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c index 272897f4cc..0e35ad3cbd 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c +++ b/components/esp_lcd/test_apps/rgb_lcd/main/test_rgb_panel.c @@ -134,13 +134,22 @@ TEST_CASE("lcd_rgb_panel_one_shot_mode", "[lcd]") } #if CONFIG_LCD_RGB_ISR_IRAM_SAFE +TEST_LCD_CALLBACK_ATTR static bool test_rgb_panel_count_in_callback(esp_lcd_panel_handle_t panel, esp_lcd_rgb_panel_event_data_t *edata, void *user_ctx) +{ + uint32_t *count = (uint32_t *)user_ctx; + *count = *count + 1; + return false; +} + TEST_CASE("lcd_rgb_panel_with_nvs_read_write", "[lcd]") { uint8_t *img = malloc(TEST_IMG_SIZE); TEST_ASSERT_NOT_NULL(img); + uint32_t callback_calls = 0; + printf("initialize RGB panel with stream mode\r\n"); - esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(true, NULL, NULL); + esp_lcd_panel_handle_t panel_handle = test_rgb_panel_initialization(true, test_rgb_panel_count_in_callback, &callback_calls); printf("flush one clock block to the LCD\r\n"); uint8_t color_byte = esp_random() & 0xFF; int x_start = esp_random() % (TEST_LCD_H_RES - 100); @@ -176,6 +185,8 @@ TEST_CASE("lcd_rgb_panel_with_nvs_read_write", "[lcd]") nvs_close(my_handle); TEST_ESP_OK(nvs_flash_deinit()); + TEST_ASSERT(callback_calls > 50); + printf("delete RGB panel\r\n"); TEST_ESP_OK(esp_lcd_panel_del(panel_handle)); free(img); diff --git a/docs/en/migration-guides/peripherals.rst b/docs/en/migration-guides/peripherals.rst index 553c85a4e2..24c6e44caa 100644 --- a/docs/en/migration-guides/peripherals.rst +++ b/docs/en/migration-guides/peripherals.rst @@ -116,10 +116,3 @@ I2C - ``rmt_set_intr_enable_mask`` and ``rmt_clr_intr_enable_mask`` are removed, as the interrupt is handled by the driver, user doesn't need to take care of it. - ``rmt_set_pin`` is removed, as ``rmt_set_gpio`` can do the same thing. - ``rmt_memory_rw_rst`` is removed, user can use ``rmt_tx_memory_reset`` and ``rmt_rx_memory_reset`` for TX and RX channel respectively. - -.. only:: SOC_LCD_RGB_SUPPORTED - - RGB LCD Driver - -------------- - - - The `pclk_active_neg` in the RGB timing configuration structure :cpp:type:`esp_lcd_rgb_timing_t` has been changed into `pclk_active_pos`. This was made to change the default PCLK sample moment to **falling** edge. From user side, you don't need to explicitly assign `pclk_active_neg = true` anymore. diff --git a/examples/peripherals/lcd/rgb_panel/README.md b/examples/peripherals/lcd/rgb_panel/README.md index 8998e56ec1..6169166eef 100644 --- a/examples/peripherals/lcd/rgb_panel/README.md +++ b/examples/peripherals/lcd/rgb_panel/README.md @@ -83,6 +83,6 @@ I (741) example: Display LVGL Scatter Chart * The frame buffer of RGB panel is located in ESP side (unlike other controller based LCDs, where the frame buffer is located in external chip). As the frame buffer usually consumes much RAM (depends on the LCD resolution and color depth), we recommend to put the frame buffer into PSRAM (like what we do in this example). However, putting frame buffer in PSRAM will limit the PCLK to around 12MHz (due to the bandwidth of PSRAM). * LCD screen drift * Slow down the PCLK frequency - * Adjust other timing parameters like PCLK clock edge (by `pclk_active_pos`), sync porches like HBP (by `hsync_back_porch`) according to your LCD spec + * Adjust other timing parameters like PCLK clock edge (by `pclk_active_neg`), sync porches like HBP (by `hsync_back_porch`) according to your LCD spec For any technical queries, please open an [issue] (https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. \ No newline at end of file diff --git a/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c b/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c index e6915a3091..db9585ca51 100644 --- a/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c +++ b/examples/peripherals/lcd/rgb_panel/main/rgb_lcd_example_main.c @@ -124,6 +124,7 @@ void app_main(void) .vsync_back_porch = 8, .vsync_front_porch = 4, .vsync_pulse_width = 1, + .flags.pclk_active_neg = true, }, .flags.fb_in_psram = 1, // allocate frame buffer in PSRAM }; From 31f9915603d2918ff2d6673d012377454db9585a Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 21 Mar 2022 10:57:58 +0800 Subject: [PATCH 2/4] driver: move deprecated drivers into single folder --- components/driver/CMakeLists.txt | 8 +++++--- components/driver/{ => deprecated}/pcnt_legacy.c | 0 .../driver/{ => deprecated}/rtc_temperature_legacy.c | 0 components/driver/{ => deprecated}/timer_legacy.c | 0 4 files changed, 5 insertions(+), 3 deletions(-) rename components/driver/{ => deprecated}/pcnt_legacy.c (100%) rename components/driver/{ => deprecated}/rtc_temperature_legacy.c (100%) rename components/driver/{ => deprecated}/timer_legacy.c (100%) diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 2003bcbfde..676831fe98 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -3,7 +3,6 @@ idf_build_get_property(target IDF_TARGET) set(srcs "gpio.c" "gptimer.c" - "timer_legacy.c" "i2c.c" "ledc.c" "legacy_new_driver_coexist.c" @@ -19,6 +18,9 @@ set(srcs "spi_bus_lock.c" "uart.c") +# deprecated source files +list(APPEND srcs "deprecated/timer_legacy.c") + set(includes "include" "deprecated") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${target}/include") list(APPEND includes "${target}/include") @@ -51,7 +53,7 @@ if(CONFIG_SOC_RMT_SUPPORTED) endif() if(CONFIG_SOC_PCNT_SUPPORTED) - list(APPEND srcs "pcnt_legacy.c" "pulse_cnt.c") + list(APPEND srcs "pulse_cnt.c" "deprecated/pcnt_legacy.c") endif() if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) @@ -64,7 +66,7 @@ endif() if(CONFIG_SOC_TEMP_SENSOR_SUPPORTED) list(APPEND srcs "temperature_sensor.c" - "rtc_temperature_legacy.c") + "deprecated/rtc_temperature_legacy.c") endif() if(CONFIG_SOC_TWAI_SUPPORTED) diff --git a/components/driver/pcnt_legacy.c b/components/driver/deprecated/pcnt_legacy.c similarity index 100% rename from components/driver/pcnt_legacy.c rename to components/driver/deprecated/pcnt_legacy.c diff --git a/components/driver/rtc_temperature_legacy.c b/components/driver/deprecated/rtc_temperature_legacy.c similarity index 100% rename from components/driver/rtc_temperature_legacy.c rename to components/driver/deprecated/rtc_temperature_legacy.c diff --git a/components/driver/timer_legacy.c b/components/driver/deprecated/timer_legacy.c similarity index 100% rename from components/driver/timer_legacy.c rename to components/driver/deprecated/timer_legacy.c From 38090a0248ed59639b8288363125aa47c90f09c3 Mon Sep 17 00:00:00 2001 From: songruo Date: Mon, 21 Mar 2022 21:25:21 +0800 Subject: [PATCH 3/4] gpio: fix GPIO_IS_VALID_(OUTPUT_)GPIO macro ... which has the potential of doing bit shift by a negative amount --- components/driver/gpio.c | 2 +- components/driver/include/driver/gpio.h | 6 ++++-- components/driver/ledc.c | 2 +- components/driver/spi_common.c | 6 ++++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/components/driver/gpio.c b/components/driver/gpio.c index 9b3dbae6e9..0abbbeb5e0 100644 --- a/components/driver/gpio.c +++ b/components/driver/gpio.c @@ -392,7 +392,7 @@ esp_err_t gpio_config(const gpio_config_t *pGPIOConfig) esp_err_t gpio_reset_pin(gpio_num_t gpio_num) { - assert(gpio_num >= 0 && GPIO_IS_VALID_GPIO(gpio_num)); + assert(GPIO_IS_VALID_GPIO(gpio_num)); gpio_config_t cfg = { .pin_bit_mask = BIT64(gpio_num), .mode = GPIO_MODE_DISABLE, diff --git a/components/driver/include/driver/gpio.h b/components/driver/include/driver/gpio.h index b03c89e5c5..f71f47aa0c 100644 --- a/components/driver/include/driver/gpio.h +++ b/components/driver/include/driver/gpio.h @@ -24,9 +24,11 @@ extern "C" { #define GPIO_PIN_COUNT (SOC_GPIO_PIN_COUNT) /// Check whether it is a valid GPIO number -#define GPIO_IS_VALID_GPIO(gpio_num) (((1ULL << (gpio_num)) & SOC_GPIO_VALID_GPIO_MASK) != 0) +#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num >= 0) && \ + (((1ULL << (gpio_num)) & SOC_GPIO_VALID_GPIO_MASK) != 0)) /// Check whether it can be a valid GPIO number of output mode -#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) (((1ULL << (gpio_num)) & SOC_GPIO_VALID_OUTPUT_GPIO_MASK) != 0) +#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((gpio_num >= 0) && \ + (((1ULL << (gpio_num)) & SOC_GPIO_VALID_OUTPUT_GPIO_MASK) != 0)) typedef intr_handle_t gpio_isr_handle_t; diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 6bec8b05e7..7ca4ff9569 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -597,7 +597,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf) { LEDC_ARG_CHECK(ledc_conf, "ledc_conf"); uint32_t speed_mode = ledc_conf->speed_mode; - uint32_t gpio_num = ledc_conf->gpio_num; + int gpio_num = ledc_conf->gpio_num; uint32_t ledc_channel = ledc_conf->channel; uint32_t timer_select = ledc_conf->timer_sel; uint32_t intr_type = ledc_conf->intr_type; diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index c81f8d173e..000b1379a5 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -690,7 +690,9 @@ esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg) }; for (int i = 0; i < sizeof(pin_array)/sizeof(int); i ++) { const int io = pin_array[i]; - if (io >= 0 && GPIO_IS_VALID_GPIO(io)) gpio_reset_pin(io); + if (GPIO_IS_VALID_GPIO(io)) { + gpio_reset_pin(io); + } } return ESP_OK; } @@ -717,7 +719,7 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, void spicommon_cs_free_io(int cs_gpio_num) { - assert(cs_gpio_num>=0 && GPIO_IS_VALID_GPIO(cs_gpio_num)); + assert(GPIO_IS_VALID_GPIO(cs_gpio_num)); gpio_reset_pin(cs_gpio_num); } From de662b987e5d4d8b3d6bf258bdddc6db6012663c Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 14 Mar 2022 22:49:18 +0800 Subject: [PATCH 4/4] driver: fix issue found by coverity scan --- .../bootloader_support/src/esp_image_format.c | 2 +- components/driver/gptimer.c | 2 +- components/driver/i2s.c | 4 +- components/driver/rmt.c | 37 ++++++------------- components/driver/spi_master.c | 5 ++- components/driver/spi_slave.c | 3 ++ 6 files changed, 23 insertions(+), 30 deletions(-) diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index 73c5810df4..979750f5af 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -789,7 +789,7 @@ static esp_err_t process_checksum(bootloader_sha256_handle_t sha_handle, uint32_ length = length - unpadded_length; // Verify checksum - WORD_ALIGNED_ATTR uint8_t buf[16]; + WORD_ALIGNED_ATTR uint8_t buf[16] = {0}; if (!skip_check_checksum || sha_handle != NULL) { CHECK_ERR(bootloader_flash_read(data->start_addr + unpadded_length, buf, length, true)); } diff --git a/components/driver/gptimer.c b/components/driver/gptimer.c index 0c51207eb2..6044d8523a 100644 --- a/components/driver/gptimer.c +++ b/components/driver/gptimer.c @@ -428,7 +428,7 @@ static esp_err_t gptimer_select_periph_clock(gptimer_t *timer, gptimer_clock_sou timer_ll_set_clock_prescale(timer->hal.dev, timer_id, prescale); timer->resolution_hz = counter_src_hz / prescale; // this is the real resolution if (timer->resolution_hz != resolution_hz) { - ESP_LOGW(TAG, "resolution lost, expect %ul, real %ul", resolution_hz, timer->resolution_hz); + ESP_LOGW(TAG, "resolution lost, expect %u, real %u", resolution_hz, timer->resolution_hz); } return ret; } diff --git a/components/driver/i2s.c b/components/driver/i2s.c index 5eafedf65b..7730f2b69a 100644 --- a/components/driver/i2s.c +++ b/components/driver/i2s.c @@ -1210,12 +1210,12 @@ static void i2s_mode_identify(i2s_port_t i2s_num, const i2s_config_t *i2s_config static esp_err_t i2s_config_transfer(i2s_port_t i2s_num, const i2s_config_t *i2s_config) { /* Convert legacy configuration into general part of slot and clock configuration */ - i2s_slot_config_t slot_cfg; + i2s_slot_config_t slot_cfg = {}; slot_cfg.mode = p_i2s[i2s_num]->mode; slot_cfg.data_bit_width = i2s_config->bits_per_sample; slot_cfg.slot_bit_width = (int)i2s_config->bits_per_chan < (int)i2s_config->bits_per_sample ? i2s_config->bits_per_sample : i2s_config->bits_per_chan; - i2s_clk_config_t clk_cfg; + i2s_clk_config_t clk_cfg = {}; clk_cfg.sample_rate_hz = i2s_config->sample_rate; clk_cfg.mclk_multiple = i2s_config->mclk_multiple == 0 ? I2S_MCLK_MULTIPLE_256 : i2s_config->mclk_multiple; clk_cfg.clk_src = I2S_CLK_D2CLK; diff --git a/components/driver/rmt.c b/components/driver/rmt.c index 086c56ead0..397845ac8f 100644 --- a/components/driver/rmt.c +++ b/components/driver/rmt.c @@ -589,7 +589,7 @@ static esp_err_t rmt_internal_config(rmt_dev_t *dev, const rmt_config_t *rmt_par uint32_t rmt_source_clk_hz; ESP_RETURN_ON_FALSE(rmt_is_channel_number_valid(channel, mode), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); - ESP_RETURN_ON_FALSE(mem_cnt + channel <= 8 && mem_cnt > 0, ESP_ERR_INVALID_ARG, TAG, RMT_MEM_CNT_ERROR_STR); + ESP_RETURN_ON_FALSE(mem_cnt + channel <= SOC_RMT_CHANNELS_PER_GROUP && mem_cnt > 0, ESP_ERR_INVALID_ARG, TAG, RMT_MEM_CNT_ERROR_STR); ESP_RETURN_ON_FALSE(clk_div > 0, ESP_ERR_INVALID_ARG, TAG, RMT_CLK_DIV_ERROR_STR); if (mode == RMT_MODE_TX) { @@ -726,7 +726,6 @@ esp_err_t rmt_fill_tx_items(rmt_channel_t channel, const rmt_item32_t *item, uin ESP_RETURN_ON_FALSE(item, ESP_ERR_INVALID_ARG, TAG, RMT_ADDR_ERROR_STR); ESP_RETURN_ON_FALSE(item_num > 0, ESP_ERR_INVALID_ARG, TAG, RMT_DRIVER_LENGTH_ERROR_STR); - /*Each block has 64 x 32 bits of data*/ uint8_t mem_cnt = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel); ESP_RETURN_ON_FALSE(mem_cnt * RMT_MEM_ITEM_NUM >= item_num, ESP_ERR_INVALID_ARG, TAG, RMT_WR_MEM_OVF_ERROR_STR); rmt_fill_memory(channel, item, item_num, mem_offset); @@ -746,22 +745,6 @@ esp_err_t rmt_isr_deregister(rmt_isr_handle_t handle) return esp_intr_free(handle); } -static int IRAM_ATTR rmt_rx_get_mem_len_in_isr(rmt_channel_t channel) -{ - int block_num = rmt_ll_rx_get_mem_blocks(rmt_contex.hal.regs, channel); - int item_block_len = block_num * RMT_MEM_ITEM_NUM; - volatile rmt_item32_t *data = (rmt_item32_t *)RMTMEM.chan[RMT_ENCODE_RX_CHANNEL(channel)].data32; - int idx; - for (idx = 0; idx < item_block_len; idx++) { - if (data[idx].duration0 == 0) { - return idx; - } else if (data[idx].duration1 == 0) { - return idx + 1; - } - } - return idx; -} - static void IRAM_ATTR rmt_driver_isr_default(void *arg) { uint32_t status = 0; @@ -849,7 +832,7 @@ static void IRAM_ATTR rmt_driver_isr_default(void *arg) rmt_obj_t *p_rmt = p_rmt_obj[RMT_ENCODE_RX_CHANNEL(channel)]; if (p_rmt) { rmt_ll_rx_enable(rmt_contex.hal.regs, channel, false); - int item_len = rmt_rx_get_mem_len_in_isr(channel); + int item_len = rmt_ll_rx_get_memory_writer_offset(rmt_contex.hal.regs, channel); rmt_ll_rx_set_mem_owner(rmt_contex.hal.regs, channel, RMT_LL_MEM_OWNER_SW); if (p_rmt->rx_buf) { addr = (rmt_item32_t *)RMTMEM.chan[RMT_ENCODE_RX_CHANNEL(channel)].data32; @@ -1135,6 +1118,8 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, i ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR); ESP_RETURN_ON_FALSE(rmt_item, ESP_FAIL, TAG, RMT_ADDR_ERROR_STR); ESP_RETURN_ON_FALSE(item_num > 0, ESP_ERR_INVALID_ARG, TAG, RMT_DRIVER_LENGTH_ERROR_STR); + uint32_t mem_blocks = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel); + ESP_RETURN_ON_FALSE(mem_blocks + channel <= SOC_RMT_CHANNELS_PER_GROUP, ESP_ERR_INVALID_STATE, TAG, RMT_MEM_CNT_ERROR_STR); #if CONFIG_SPIRAM_USE_MALLOC if (p_rmt_obj[channel]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) { if (!esp_ptr_internal(rmt_item)) { @@ -1144,9 +1129,8 @@ esp_err_t rmt_write_items(rmt_channel_t channel, const rmt_item32_t *rmt_item, i } #endif rmt_obj_t *p_rmt = p_rmt_obj[channel]; - int block_num = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel); - int item_block_len = block_num * RMT_MEM_ITEM_NUM; - int item_sub_len = block_num * RMT_MEM_ITEM_NUM / 2; + int item_block_len = mem_blocks * RMT_MEM_ITEM_NUM; + int item_sub_len = mem_blocks * RMT_MEM_ITEM_NUM / 2; int len_rem = item_num; xSemaphoreTake(p_rmt->tx_sem, portMAX_DELAY); // fill the memory block first @@ -1222,8 +1206,9 @@ esp_err_t rmt_translator_init(rmt_channel_t channel, sample_to_rmt_t fn) ESP_RETURN_ON_FALSE(fn, ESP_ERR_INVALID_ARG, TAG, RMT_TRANSLATOR_NULL_STR); ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR); - const uint32_t block_size = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel) * - RMT_MEM_ITEM_NUM * sizeof(rmt_item32_t); + uint32_t mem_blocks = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel); + ESP_RETURN_ON_FALSE(mem_blocks + channel <= SOC_RMT_CHANNELS_PER_GROUP, ESP_ERR_INVALID_STATE, TAG, RMT_MEM_CNT_ERROR_STR); + const uint32_t block_size = mem_blocks * RMT_MEM_ITEM_NUM * sizeof(rmt_item32_t); if (p_rmt_obj[channel]->tx_buf == NULL) { #if !CONFIG_SPIRAM_USE_MALLOC p_rmt_obj[channel]->tx_buf = (rmt_item32_t *)malloc(block_size); @@ -1273,6 +1258,8 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src ESP_RETURN_ON_FALSE(RMT_IS_TX_CHANNEL(channel), ESP_ERR_INVALID_ARG, TAG, RMT_CHANNEL_ERROR_STR); ESP_RETURN_ON_FALSE(p_rmt_obj[channel], ESP_FAIL, TAG, RMT_DRIVER_ERROR_STR); ESP_RETURN_ON_FALSE(p_rmt_obj[channel]->sample_to_rmt, ESP_FAIL, TAG, RMT_TRANSLATOR_UNINIT_STR); + uint32_t mem_blocks = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel); + ESP_RETURN_ON_FALSE(mem_blocks + channel <= SOC_RMT_CHANNELS_PER_GROUP, ESP_ERR_INVALID_STATE, TAG, RMT_MEM_CNT_ERROR_STR); #if CONFIG_SPIRAM_USE_MALLOC if (p_rmt_obj[channel]->intr_alloc_flags & ESP_INTR_FLAG_IRAM) { if (!esp_ptr_internal(src)) { @@ -1283,7 +1270,7 @@ esp_err_t rmt_write_sample(rmt_channel_t channel, const uint8_t *src, size_t src #endif size_t translated_size = 0; rmt_obj_t *p_rmt = p_rmt_obj[channel]; - const uint32_t item_block_len = rmt_ll_tx_get_mem_blocks(rmt_contex.hal.regs, channel) * RMT_MEM_ITEM_NUM; + const uint32_t item_block_len = mem_blocks * RMT_MEM_ITEM_NUM; const uint32_t item_sub_len = item_block_len / 2; xSemaphoreTake(p_rmt->tx_sem, portMAX_DELAY); p_rmt->sample_to_rmt((void *)src, p_rmt->tx_buf, src_size, item_block_len, &translated_size, &p_rmt->tx_len_rem); diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 505d7a4989..ab37526860 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -649,6 +649,8 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) // We stay in the ISR to deal with those transactions of desired device, otherwise nothing will be done, check whether we need to resume some other tasks, or just quit the ISR resume_task = spi_bus_lock_bg_check_dev_acq(lock, &desired_dev); } + // sanity check + assert(desired_dev); if (!resume_task) { bool dev_has_req = spi_bus_lock_bg_check_dev_req(desired_dev); @@ -733,7 +735,8 @@ static SPI_MASTER_ISR_ATTR void uninstall_priv_desc(spi_trans_priv_t* trans_buf) free((void *)trans_buf->buffer_to_send); //force free, ignore const } // copy data from temporary DMA-capable buffer back to IRAM buffer and free the temporary one. - if ((void *)trans_buf->buffer_to_rcv != &trans_desc->rx_data[0] && + if (trans_buf->buffer_to_rcv && + (void *)trans_buf->buffer_to_rcv != &trans_desc->rx_data[0] && trans_buf->buffer_to_rcv != trans_desc->rx_buffer) { // NOLINT(clang-analyzer-unix.Malloc) if (trans_desc->flags & SPI_TRANS_USE_RXDATA) { memcpy((uint8_t *) & trans_desc->rx_data[0], trans_buf->buffer_to_rcv, (trans_desc->rxlength + 7) / 8); diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index aa4f88bf1f..ca7409a72d 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -370,6 +370,9 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //Grab next transaction r = xQueueReceiveFromISR(host->trans_queue, &trans, &do_yield); if (r) { + // sanity check + assert(trans); + //enable the interrupt again if there is packet to send esp_intr_enable(host->intr);