From fd5bfb2cd4eed2be4b429a19f8eee53be06e253a Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Fri, 24 Feb 2023 15:46:15 +0800 Subject: [PATCH 1/3] sdm: fixed wrong sdm struct sequence on esp32h2 --- .../soc/esp32c6/include/soc/gpio_ext_reg.h | 62 +++++++++---------- .../soc/esp32h2/include/soc/gpio_ext_reg.h | 32 +++++----- .../soc/esp32h2/include/soc/gpio_ext_struct.h | 2 +- components/soc/esp32h2/include/soc/reg_base.h | 1 + 4 files changed, 49 insertions(+), 48 deletions(-) diff --git a/components/soc/esp32c6/include/soc/gpio_ext_reg.h b/components/soc/esp32c6/include/soc/gpio_ext_reg.h index 7f6b4d6d01..6b7fb33f6f 100644 --- a/components/soc/esp32c6/include/soc/gpio_ext_reg.h +++ b/components/soc/esp32c6/include/soc/gpio_ext_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,58 +34,58 @@ extern "C" { * Duty Cycle Configure Register of SDM1 */ #define GPIO_SIGMADELTA1_REG (DR_REG_GPIO_EXT_BASE + 0x4) -/** GPIO_SD0_IN : R/W; bitpos: [7:0]; default: 0; +/** GPIO_SD1_IN : R/W; bitpos: [7:0]; default: 0; * This field is used to configure the duty cycle of sigma delta modulation output. */ -#define GPIO_SD0_IN 0x000000FFU -#define GPIO_SD0_IN_M (GPIO_SD0_IN_V << GPIO_SD0_IN_S) -#define GPIO_SD0_IN_V 0x000000FFU -#define GPIO_SD0_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +#define GPIO_SD1_IN 0x000000FFU +#define GPIO_SD1_IN_M (GPIO_SD1_IN_V << GPIO_SD1_IN_S) +#define GPIO_SD1_IN_V 0x000000FFU +#define GPIO_SD1_IN_S 0 +/** GPIO_SD1_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD1_PRESCALE 0x000000FFU +#define GPIO_SD1_PRESCALE_M (GPIO_SD1_PRESCALE_V << GPIO_SD1_PRESCALE_S) +#define GPIO_SD1_PRESCALE_V 0x000000FFU +#define GPIO_SD1_PRESCALE_S 8 /** GPIO_SIGMADELTA2_REG register * Duty Cycle Configure Register of SDM2 */ #define GPIO_SIGMADELTA2_REG (DR_REG_GPIO_EXT_BASE + 0x8) -/** GPIO_SD0_IN : R/W; bitpos: [7:0]; default: 0; +/** GPIO_SD2_IN : R/W; bitpos: [7:0]; default: 0; * This field is used to configure the duty cycle of sigma delta modulation output. */ -#define GPIO_SD0_IN 0x000000FFU -#define GPIO_SD0_IN_M (GPIO_SD0_IN_V << GPIO_SD0_IN_S) -#define GPIO_SD0_IN_V 0x000000FFU -#define GPIO_SD0_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +#define GPIO_SD2_IN 0x000000FFU +#define GPIO_SD2_IN_M (GPIO_SD2_IN_V << GPIO_SD2_IN_S) +#define GPIO_SD2_IN_V 0x000000FFU +#define GPIO_SD2_IN_S 0 +/** GPIO_SD2_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD2_PRESCALE 0x000000FFU +#define GPIO_SD2_PRESCALE_M (GPIO_SD2_PRESCALE_V << GPIO_SD2_PRESCALE_S) +#define GPIO_SD2_PRESCALE_V 0x000000FFU +#define GPIO_SD2_PRESCALE_S 8 /** GPIO_SIGMADELTA3_REG register * Duty Cycle Configure Register of SDM3 */ #define GPIO_SIGMADELTA3_REG (DR_REG_GPIO_EXT_BASE + 0xc) -/** GPIO_SD0_IN : R/W; bitpos: [7:0]; default: 0; +/** GPIO_SD3_IN : R/W; bitpos: [7:0]; default: 0; * This field is used to configure the duty cycle of sigma delta modulation output. */ -#define GPIO_SD0_IN 0x000000FFU -#define GPIO_SD0_IN_M (GPIO_SD0_IN_V << GPIO_SD0_IN_S) -#define GPIO_SD0_IN_V 0x000000FFU -#define GPIO_SD0_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +#define GPIO_SD3_IN 0x000000FFU +#define GPIO_SD3_IN_M (GPIO_SD3_IN_V << GPIO_SD3_IN_S) +#define GPIO_SD3_IN_V 0x000000FFU +#define GPIO_SD3_IN_S 0 +/** GPIO_SD3_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD3_PRESCALE 0x000000FFU +#define GPIO_SD3_PRESCALE_M (GPIO_SD3_PRESCALE_V << GPIO_SD3_PRESCALE_S) +#define GPIO_SD3_PRESCALE_V 0x000000FFU +#define GPIO_SD3_PRESCALE_S 8 /** GPIO_CLOCK_GATE_REG register * Clock Gating Configure Register diff --git a/components/soc/esp32h2/include/soc/gpio_ext_reg.h b/components/soc/esp32h2/include/soc/gpio_ext_reg.h index 22143537fc..eecc2edc20 100644 --- a/components/soc/esp32h2/include/soc/gpio_ext_reg.h +++ b/components/soc/esp32h2/include/soc/gpio_ext_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -41,13 +41,13 @@ extern "C" { #define GPIO_SD1_IN_M (GPIO_SD1_IN_V << GPIO_SD1_IN_S) #define GPIO_SD1_IN_V 0x000000FFU #define GPIO_SD1_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +/** GPIO_SD1_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD1_PRESCALE 0x000000FFU +#define GPIO_SD1_PRESCALE_M (GPIO_SD1_PRESCALE_V << GPIO_SD1_PRESCALE_S) +#define GPIO_SD1_PRESCALE_V 0x000000FFU +#define GPIO_SD1_PRESCALE_S 8 /** GPIO_SIGMADELTA2_REG register * Duty Cycle Configure Register of SDM2 @@ -60,13 +60,13 @@ extern "C" { #define GPIO_SD2_IN_M (GPIO_SD2_IN_V << GPIO_SD2_IN_S) #define GPIO_SD2_IN_V 0x000000FFU #define GPIO_SD2_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +/** GPIO_SD2_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD2_PRESCALE 0x000000FFU +#define GPIO_SD2_PRESCALE_M (GPIO_SD2_PRESCALE_V << GPIO_SD2_PRESCALE_S) +#define GPIO_SD2_PRESCALE_V 0x000000FFU +#define GPIO_SD2_PRESCALE_S 8 /** GPIO_SIGMADELTA3_REG register * Duty Cycle Configure Register of SDM3 @@ -79,13 +79,13 @@ extern "C" { #define GPIO_SD3_IN_M (GPIO_SD3_IN_V << GPIO_SD3_IN_S) #define GPIO_SD3_IN_V 0x000000FFU #define GPIO_SD3_IN_S 0 -/** GPIO_SD0_PRESCALE : R/W; bitpos: [15:8]; default: 255; +/** GPIO_SD3_PRESCALE : R/W; bitpos: [15:8]; default: 255; * This field is used to set a divider value to divide APB clock. */ -#define GPIO_SD0_PRESCALE 0x000000FFU -#define GPIO_SD0_PRESCALE_M (GPIO_SD0_PRESCALE_V << GPIO_SD0_PRESCALE_S) -#define GPIO_SD0_PRESCALE_V 0x000000FFU -#define GPIO_SD0_PRESCALE_S 8 +#define GPIO_SD3_PRESCALE 0x000000FFU +#define GPIO_SD3_PRESCALE_M (GPIO_SD3_PRESCALE_V << GPIO_SD3_PRESCALE_S) +#define GPIO_SD3_PRESCALE_V 0x000000FFU +#define GPIO_SD3_PRESCALE_S 8 /** GPIO_CLOCK_GATE_REG register * Clock Gating Configure Register diff --git a/components/soc/esp32h2/include/soc/gpio_ext_struct.h b/components/soc/esp32h2/include/soc/gpio_ext_struct.h index d0388d3ad0..10786e703c 100644 --- a/components/soc/esp32h2/include/soc/gpio_ext_struct.h +++ b/components/soc/esp32h2/include/soc/gpio_ext_struct.h @@ -275,8 +275,8 @@ typedef union { typedef struct gpio_sd_dev_t { volatile gpio_sigmadelta_chn_reg_t channel[4]; uint32_t reserved_010[4]; - volatile gpio_sigmadelta_misc_reg_t misc; volatile gpio_sigmadelta_clock_gate_reg_t clock_gate; + volatile gpio_sigmadelta_misc_reg_t misc; } gpio_sd_dev_t; typedef struct { diff --git a/components/soc/esp32h2/include/soc/reg_base.h b/components/soc/esp32h2/include/soc/reg_base.h index 550c3b5094..a902acdf2a 100644 --- a/components/soc/esp32h2/include/soc/reg_base.h +++ b/components/soc/esp32h2/include/soc/reg_base.h @@ -40,6 +40,7 @@ #define DR_REG_PAU_BASE 0x60093000 #define DR_REG_LPPERI_BASE 0x600B2800 #define DR_REG_GPIO_BASE 0x60091000 +#define DR_REG_GPIO_EXT_BASE 0x60091f00 #define DR_REG_MEM_ACS_MONITOR_BASE 0x60092000 #define DR_REG_REGDMA_BASE 0x60093000 #define DR_REG_HP_SYSTEM_BASE 0x60095000 From 754aa7d128a173f82ee18c635ad92305c7ee28b6 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Sun, 26 Feb 2023 19:33:25 +0800 Subject: [PATCH 2/3] sdm: adopt clock tree --- components/driver/sigma_delta/sdm.c | 56 ++++++++++------------------- 1 file changed, 19 insertions(+), 37 deletions(-) diff --git a/components/driver/sigma_delta/sdm.c b/components/driver/sigma_delta/sdm.c index 1eaa9bd5c1..e473afe4b0 100644 --- a/components/driver/sigma_delta/sdm.c +++ b/components/driver/sigma_delta/sdm.c @@ -19,6 +19,7 @@ #include "esp_log.h" #include "esp_check.h" #include "esp_pm.h" +#include "clk_tree.h" #include "driver/gpio.h" #include "driver/sdm.h" #include "hal/gpio_hal.h" @@ -209,46 +210,27 @@ esp_err_t sdm_new_channel(const sdm_config_t *config, sdm_channel_handle_t *ret_ ESP_GOTO_ON_FALSE(group->clk_src == 0 || group->clk_src == config->clk_src, ESP_ERR_INVALID_ARG, err, TAG, "clock source conflict"); uint32_t src_clk_hz = 0; - switch (config->clk_src) { -#if SOC_SDM_CLK_SUPPORT_APB - case SDM_CLK_SRC_APB: - src_clk_hz = esp_clk_apb_freq(); + ESP_GOTO_ON_ERROR(clk_tree_src_get_freq_hz((soc_module_clk_t)config->clk_src, + CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz), err, TAG, "get source clock frequency failed"); + #if CONFIG_PM_ENABLE - sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, chan->pm_lock_name, &chan->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create APB_FREQ_MAX lock failed"); -#endif - break; -#endif // SOC_SDM_CLK_SUPPORT_APB + esp_pm_lock_type_t pm_type = ESP_PM_NO_LIGHT_SLEEP; #if SOC_SDM_CLK_SUPPORT_XTAL - case SDM_CLK_SRC_XTAL: - src_clk_hz = esp_clk_xtal_freq(); - break; -#endif // SOC_SDM_CLK_SUPPORT_XTAL -#if SOC_SDM_CLK_SUPPORT_PLL_F80M - case SDM_CLK_SRC_PLL_F80M: - src_clk_hz = 80 * 1000 * 1000; -#if CONFIG_PM_ENABLE - sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 - ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, chan->pm_lock_name, &chan->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed"); -#endif // CONFIG_PM_ENABLE - break; -#endif // SOC_SDM_CLK_SUPPORT_PLL_F80M -#if SOC_SDM_CLK_SUPPORT_PLL_F48M - case SDM_CLK_SRC_PLL_F48M: - src_clk_hz = 48 * 1000 * 1000; -#if CONFIG_PM_ENABLE - sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 - ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, chan->pm_lock_name, &chan->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create NO_LIGHT_SLEEP lock failed"); -#endif // CONFIG_PM_ENABLE - break; -#endif // SOC_SDM_CLK_SUPPORT_PLL_F48M - default: - ESP_GOTO_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, err, TAG, "clock source %d is not support", config->clk_src); - break; + if (config->clk_src == SDM_CLK_SRC_XTAL) { + pm_type = -1; } +#endif // SOC_SDM_CLK_SUPPORT_XTAL +#if SOC_SDM_CLK_SUPPORT_APB + if (config->clk_src == SDM_CLK_SRC_APB) { + pm_type = ESP_PM_APB_FREQ_MAX; + } +#endif // SOC_SDM_CLK_SUPPORT_APB + if (pm_type >= 0) { + sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 + ret = esp_pm_lock_create(pm_type, 0, chan->pm_lock_name, &chan->pm_lock); + ESP_RETURN_ON_ERROR(ret, TAG, "create %s lock failed", chan->pm_lock_name); + } +#endif // CONFIG_PM_ENABLE group->clk_src = config->clk_src; // SDM clock comes from IO MUX, but IO MUX clock might be shared with other submodules as well From 40f1709a1f5b8136c2c805d8b4eed80b0e261903 Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Mon, 27 Feb 2023 11:59:58 +0800 Subject: [PATCH 3/3] Revert "i2s: guarantee safety of memcpy from being interrupted by uart logging" This reverts commit 646fd5e15abd23d5237e7aac237eb43be149b0b4. --- components/driver/i2s/i2s_common.c | 9 --------- components/driver/sigma_delta/sdm.c | 13 +++---------- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/components/driver/i2s/i2s_common.c b/components/driver/i2s/i2s_common.c index ce530ef236..c3dc28124f 100644 --- a/components/driver/i2s/i2s_common.c +++ b/components/driver/i2s/i2s_common.c @@ -1086,11 +1086,8 @@ esp_err_t i2s_channel_preload_data(i2s_chan_handle_t tx_handle, const void *src, if (bytes_can_load == 0) { break; } - /* Add spinlock in case memcpy be interrupted */ - portENTER_CRITICAL_SAFE(&g_i2s.spinlock); /* Load the data from the last loaded position */ memcpy((uint8_t *)(desc_ptr->buf + tx_handle->dma.rw_pos), data_ptr, bytes_can_load); - portEXIT_CRITICAL_SAFE(&g_i2s.spinlock); data_ptr += bytes_can_load; // Move forward the data pointer total_loaded_bytes += bytes_can_load; // Add to the total loaded bytes remain_bytes -= bytes_can_load; // Update the remaining bytes to be loaded @@ -1146,10 +1143,7 @@ esp_err_t i2s_channel_write(i2s_chan_handle_t handle, const void *src, size_t si if (bytes_can_write > size) { bytes_can_write = size; } - /* Add spinlock in case memcpy be interrupted */ - portENTER_CRITICAL_SAFE(&g_i2s.spinlock); memcpy(data_ptr, src_byte, bytes_can_write); - portEXIT_CRITICAL_SAFE(&g_i2s.spinlock); size -= bytes_can_write; src_byte += bytes_can_write; handle->dma.rw_pos += bytes_can_write; @@ -1191,10 +1185,7 @@ esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, si if (bytes_can_read > (int)size) { bytes_can_read = size; } - /* Add spinlock in case memcpy be interrupted */ - portENTER_CRITICAL_SAFE(&g_i2s.spinlock); memcpy(dest_byte, data_ptr, bytes_can_read); - portEXIT_CRITICAL_SAFE(&g_i2s.spinlock); size -= bytes_can_read; dest_byte += bytes_can_read; handle->dma.rw_pos += bytes_can_read; diff --git a/components/driver/sigma_delta/sdm.c b/components/driver/sigma_delta/sdm.c index e473afe4b0..41005295f2 100644 --- a/components/driver/sigma_delta/sdm.c +++ b/components/driver/sigma_delta/sdm.c @@ -215,21 +215,14 @@ esp_err_t sdm_new_channel(const sdm_config_t *config, sdm_channel_handle_t *ret_ #if CONFIG_PM_ENABLE esp_pm_lock_type_t pm_type = ESP_PM_NO_LIGHT_SLEEP; -#if SOC_SDM_CLK_SUPPORT_XTAL - if (config->clk_src == SDM_CLK_SRC_XTAL) { - pm_type = -1; - } -#endif // SOC_SDM_CLK_SUPPORT_XTAL #if SOC_SDM_CLK_SUPPORT_APB if (config->clk_src == SDM_CLK_SRC_APB) { pm_type = ESP_PM_APB_FREQ_MAX; } #endif // SOC_SDM_CLK_SUPPORT_APB - if (pm_type >= 0) { - sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 - ret = esp_pm_lock_create(pm_type, 0, chan->pm_lock_name, &chan->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create %s lock failed", chan->pm_lock_name); - } + sprintf(chan->pm_lock_name, "sdm_%d_%d", group->group_id, chan_id); // e.g. sdm_0_0 + ret = esp_pm_lock_create(pm_type, 0, chan->pm_lock_name, &chan->pm_lock); + ESP_GOTO_ON_ERROR(ret, err, TAG, "create %s lock failed", chan->pm_lock_name); #endif // CONFIG_PM_ENABLE group->clk_src = config->clk_src;