forked from espressif/esp-idf
Merge branch 'feature/rmt_clock_rc_fast_c6' into 'master'
rmt: support PLL clock on esp32c6 Closes IDF-6341 See merge request espressif/esp-idf!21602
This commit is contained in:
@@ -41,10 +41,6 @@ components/driver/test_apps/legacy_adc_driver:
|
|||||||
components/driver/test_apps/legacy_mcpwm_driver:
|
components/driver/test_apps/legacy_mcpwm_driver:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_MCPWM_SUPPORTED != 1
|
- if: SOC_MCPWM_SUPPORTED != 1
|
||||||
disable_test:
|
|
||||||
- if: IDF_TARGET == "esp32c6"
|
|
||||||
temporary: true
|
|
||||||
reason: target esp32c6 is not supported yet
|
|
||||||
|
|
||||||
components/driver/test_apps/legacy_pcnt_driver:
|
components/driver/test_apps/legacy_pcnt_driver:
|
||||||
disable:
|
disable:
|
||||||
@@ -61,10 +57,6 @@ components/driver/test_apps/legacy_rtc_temp_driver:
|
|||||||
components/driver/test_apps/mcpwm:
|
components/driver/test_apps/mcpwm:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_MCPWM_SUPPORTED != 1
|
- if: SOC_MCPWM_SUPPORTED != 1
|
||||||
disable_test:
|
|
||||||
- if: IDF_TARGET == "esp32c6"
|
|
||||||
temporary: true
|
|
||||||
reason: target esp32c6 is not supported yet
|
|
||||||
|
|
||||||
components/driver/test_apps/pulse_cnt:
|
components/driver/test_apps/pulse_cnt:
|
||||||
disable:
|
disable:
|
||||||
@@ -73,10 +65,6 @@ components/driver/test_apps/pulse_cnt:
|
|||||||
components/driver/test_apps/rmt:
|
components/driver/test_apps/rmt:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_RMT_SUPPORTED != 1
|
- if: SOC_RMT_SUPPORTED != 1
|
||||||
disable_test:
|
|
||||||
- if: IDF_TARGET == "esp32c6"
|
|
||||||
temporary: true
|
|
||||||
reason: target esp32c6 is not supported yet
|
|
||||||
|
|
||||||
components/driver/test_apps/rs485:
|
components/driver/test_apps/rs485:
|
||||||
disable_test:
|
disable_test:
|
||||||
|
@@ -133,8 +133,20 @@ esp_err_t rmt_select_periph_clock(rmt_channel_handle_t chan, rmt_clock_source_t
|
|||||||
ESP_RETURN_ON_ERROR(ret, TAG, "create APB_FREQ_MAX lock failed");
|
ESP_RETURN_ON_ERROR(ret, TAG, "create APB_FREQ_MAX lock failed");
|
||||||
ESP_LOGD(TAG, "install APB_FREQ_MAX lock for RMT channel (%d,%d)", group->group_id, channel_id);
|
ESP_LOGD(TAG, "install APB_FREQ_MAX lock for RMT channel (%d,%d)", group->group_id, channel_id);
|
||||||
#endif // CONFIG_PM_ENABLE
|
#endif // CONFIG_PM_ENABLE
|
||||||
#endif // SOC_RMT_SUPPORT_APB
|
|
||||||
break;
|
break;
|
||||||
|
#endif // SOC_RMT_SUPPORT_APB
|
||||||
|
#if SOC_RMT_SUPPORT_PLL_F80M
|
||||||
|
case RMT_CLK_SRC_PLL_F80M:
|
||||||
|
periph_src_clk_hz = 80000000;
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
|
sprintf(chan->pm_lock_name, "rmt_%d_%d", group->group_id, channel_id); // e.g. rmt_0_0
|
||||||
|
// ESP32C6 PLL_F80M is available even when SOC_ROOT_CLK switches from PLL to XTAL, so using NO_LIGHT_SLEEP lock here is sufficient
|
||||||
|
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");
|
||||||
|
ESP_LOGD(TAG, "install NO_LIGHT_SLEEP lock for RMT channel (%d,%d)", group->group_id, channel_id);
|
||||||
|
#endif // CONFIG_PM_ENABLE
|
||||||
|
break;
|
||||||
|
#endif // SOC_RMT_SUPPORT_PLL_F80M
|
||||||
#if SOC_RMT_SUPPORT_AHB
|
#if SOC_RMT_SUPPORT_AHB
|
||||||
case RMT_CLK_SRC_AHB:
|
case RMT_CLK_SRC_AHB:
|
||||||
// TODO: decide which kind of PM lock we should use for such clock
|
// TODO: decide which kind of PM lock we should use for such clock
|
||||||
|
@@ -7,6 +7,7 @@ from pytest_embedded import Dut
|
|||||||
|
|
||||||
@pytest.mark.esp32
|
@pytest.mark.esp32
|
||||||
@pytest.mark.esp32s3
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.esp32c6
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'config',
|
'config',
|
||||||
|
@@ -618,7 +618,7 @@ TEST_CASE("RMT Interrupt IRAM Safe", "[rmt]")
|
|||||||
.rmt_mode = RMT_MODE_TX,
|
.rmt_mode = RMT_MODE_TX,
|
||||||
};
|
};
|
||||||
TEST_ESP_OK(rmt_config(&tx));
|
TEST_ESP_OK(rmt_config(&tx));
|
||||||
TEST_ESP_OK(rmt_set_source_clk(tx.channel, RMT_BASECLK_APB));
|
TEST_ESP_OK(rmt_set_source_clk(tx.channel, RMT_BASECLK_DEFAULT));
|
||||||
// install interrupt with IRAM safe
|
// install interrupt with IRAM safe
|
||||||
TEST_ESP_OK(rmt_driver_install(tx.channel, 0, ESP_INTR_FLAG_IRAM));
|
TEST_ESP_OK(rmt_driver_install(tx.channel, 0, ESP_INTR_FLAG_IRAM));
|
||||||
|
|
||||||
|
@@ -111,13 +111,14 @@ TEST_CASE("mcpwm_capture_ext_gpio", "[mcpwm]")
|
|||||||
|
|
||||||
printf("simulate GPIO capture signal\r\n");
|
printf("simulate GPIO capture signal\r\n");
|
||||||
gpio_set_level(cap_gpio, 1);
|
gpio_set_level(cap_gpio, 1);
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
gpio_set_level(cap_gpio, 0);
|
gpio_set_level(cap_gpio, 0);
|
||||||
vTaskDelay(pdMS_TO_TICKS(100));
|
vTaskDelay(pdMS_TO_TICKS(10));
|
||||||
printf("capture value: Pos=%"PRIu32", Neg=%"PRIu32"\r\n", cap_value[0], cap_value[1]);
|
printf("capture value: Pos=%"PRIu32", Neg=%"PRIu32"\r\n", cap_value[0], cap_value[1]);
|
||||||
uint32_t clk_src_res;
|
uint32_t clk_src_res;
|
||||||
mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res);
|
TEST_ESP_OK(mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res));
|
||||||
TEST_ASSERT_UINT_WITHIN(100000, clk_src_res / 10, cap_value[1] - cap_value[0]);
|
clk_src_res /= 1000; // convert to kHz
|
||||||
|
TEST_ASSERT_UINT_WITHIN(1000, 10000, (cap_value[1] - cap_value[0]) * 1000 / clk_src_res);
|
||||||
|
|
||||||
printf("uninstall capture channel and timer\r\n");
|
printf("uninstall capture channel and timer\r\n");
|
||||||
TEST_ESP_OK(mcpwm_capture_channel_disable(pps_channel));
|
TEST_ESP_OK(mcpwm_capture_channel_disable(pps_channel));
|
||||||
@@ -184,8 +185,9 @@ TEST_CASE("mcpwm_capture_software_catch", "[mcpwm]")
|
|||||||
uint32_t delta = test_callback_data.cap_data[1] - test_callback_data.cap_data[0];
|
uint32_t delta = test_callback_data.cap_data[1] - test_callback_data.cap_data[0];
|
||||||
esp_rom_printf("duration=%u ticks\r\n", delta);
|
esp_rom_printf("duration=%u ticks\r\n", delta);
|
||||||
uint32_t clk_src_res;
|
uint32_t clk_src_res;
|
||||||
mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res);
|
TEST_ESP_OK(mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res));
|
||||||
TEST_ASSERT_UINT_WITHIN(80000, clk_src_res / 100, delta);
|
clk_src_res /= 1000; // convert to kHz
|
||||||
|
TEST_ASSERT_UINT_WITHIN(1000, 10000, delta * 1000 / clk_src_res);
|
||||||
|
|
||||||
printf("uninstall capture channel and timer\r\n");
|
printf("uninstall capture channel and timer\r\n");
|
||||||
TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel));
|
TEST_ESP_OK(mcpwm_capture_channel_disable(cap_channel));
|
||||||
|
@@ -79,9 +79,10 @@ TEST_CASE("mcpwm_capture_iram_safe", "[mcpwm]")
|
|||||||
unity_utils_run_cache_disable_stub(test_simulate_input_post_cache_disable, (void *)cap_gpio);
|
unity_utils_run_cache_disable_stub(test_simulate_input_post_cache_disable, (void *)cap_gpio);
|
||||||
|
|
||||||
printf("capture value: Pos=%"PRIu32", Neg=%"PRIu32"\r\n", cap_value[0], cap_value[1]);
|
printf("capture value: Pos=%"PRIu32", Neg=%"PRIu32"\r\n", cap_value[0], cap_value[1]);
|
||||||
// Capture timer is clocked from APB by default
|
uint32_t clk_src_res;
|
||||||
uint32_t clk_src_res = esp_clk_apb_freq();
|
TEST_ESP_OK(mcpwm_capture_timer_get_resolution(cap_timer, &clk_src_res));
|
||||||
TEST_ASSERT_UINT_WITHIN(2000, clk_src_res / 1000, cap_value[1] - cap_value[0]);
|
clk_src_res /= 1000; // convert to kHz
|
||||||
|
TEST_ASSERT_UINT_WITHIN(100, 1000, (cap_value[1] - cap_value[0]) * 1000 / clk_src_res);
|
||||||
|
|
||||||
printf("uninstall capture channel and timer\r\n");
|
printf("uninstall capture channel and timer\r\n");
|
||||||
TEST_ESP_OK(mcpwm_capture_channel_disable(pps_channel));
|
TEST_ESP_OK(mcpwm_capture_channel_disable(pps_channel));
|
||||||
|
@@ -7,6 +7,7 @@ from pytest_embedded import Dut
|
|||||||
|
|
||||||
@pytest.mark.esp32
|
@pytest.mark.esp32
|
||||||
@pytest.mark.esp32s3
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.esp32c6
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'config',
|
'config',
|
||||||
|
@@ -9,6 +9,7 @@ from pytest_embedded import Dut
|
|||||||
@pytest.mark.esp32s2
|
@pytest.mark.esp32s2
|
||||||
@pytest.mark.esp32s3
|
@pytest.mark.esp32s3
|
||||||
@pytest.mark.esp32c3
|
@pytest.mark.esp32c3
|
||||||
|
@pytest.mark.esp32c6
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'config',
|
'config',
|
||||||
|
@@ -95,9 +95,12 @@ static inline void rmt_ll_set_group_clock_src(rmt_dev_t *dev, uint32_t channel,
|
|||||||
PCR.rmt_sclk_conf.rmt_sclk_div_a = divider_numerator;
|
PCR.rmt_sclk_conf.rmt_sclk_div_a = divider_numerator;
|
||||||
PCR.rmt_sclk_conf.rmt_sclk_div_b = divider_denominator;
|
PCR.rmt_sclk_conf.rmt_sclk_div_b = divider_denominator;
|
||||||
switch (src) {
|
switch (src) {
|
||||||
case RMT_CLK_SRC_APB:
|
case RMT_CLK_SRC_PLL_F80M:
|
||||||
PCR.rmt_sclk_conf.rmt_sclk_sel = 1;
|
PCR.rmt_sclk_conf.rmt_sclk_sel = 1;
|
||||||
break;
|
break;
|
||||||
|
case RMT_CLK_SRC_RC_FAST:
|
||||||
|
PCR.rmt_sclk_conf.rmt_sclk_sel = 2;
|
||||||
|
break;
|
||||||
case RMT_CLK_SRC_XTAL:
|
case RMT_CLK_SRC_XTAL:
|
||||||
PCR.rmt_sclk_conf.rmt_sclk_sel = 3;
|
PCR.rmt_sclk_conf.rmt_sclk_sel = 3;
|
||||||
break;
|
break;
|
||||||
@@ -758,10 +761,13 @@ static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
|
|||||||
__attribute__((always_inline))
|
__attribute__((always_inline))
|
||||||
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
|
static inline rmt_clock_source_t rmt_ll_get_group_clock_src(rmt_dev_t *dev, uint32_t channel)
|
||||||
{
|
{
|
||||||
rmt_clock_source_t clk_src = RMT_CLK_SRC_APB;
|
rmt_clock_source_t clk_src = RMT_CLK_SRC_PLL_F80M;
|
||||||
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
|
switch (PCR.rmt_sclk_conf.rmt_sclk_sel) {
|
||||||
case 1:
|
case 1:
|
||||||
clk_src = RMT_CLK_SRC_APB;
|
clk_src = RMT_CLK_SRC_PLL_F80M;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
clk_src = RMT_CLK_SRC_RC_FAST;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
clk_src = RMT_CLK_SRC_XTAL;
|
clk_src = RMT_CLK_SRC_XTAL;
|
||||||
|
@@ -527,7 +527,11 @@ config SOC_RMT_SUPPORT_XTAL
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config SOC_RMT_SUPPORT_APB
|
config SOC_RMT_SUPPORT_PLL_F80M
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
|
config SOC_RMT_SUPPORT_RC_FAST
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
@@ -175,24 +175,25 @@ typedef enum {
|
|||||||
/**
|
/**
|
||||||
* @brief Array initializer for all supported clock sources of RMT
|
* @brief Array initializer for all supported clock sources of RMT
|
||||||
*/
|
*/
|
||||||
#define SOC_RMT_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_XTAL}
|
#define SOC_RMT_CLKS {SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_XTAL}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of RMT clock source
|
* @brief Type of RMT clock source
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RMT_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
|
RMT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
|
||||||
RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
RMT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
|
||||||
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default choice */
|
RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
|
||||||
|
RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default choice */
|
||||||
} soc_periph_rmt_clk_src_t;
|
} soc_periph_rmt_clk_src_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of RMT clock source, reserved for the legacy RMT driver
|
* @brief Type of RMT clock source, reserved for the legacy RMT driver
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RMT_BASECLK_APB = SOC_MOD_CLK_APB, /*!< RMT source clock is APB */
|
RMT_BASECLK_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock is PLL_F80M */
|
||||||
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
|
RMT_BASECLK_XTAL = SOC_MOD_CLK_XTAL, /*!< RMT source clock is XTAL */
|
||||||
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_APB, /*!< RMT source clock default choice is APB */
|
RMT_BASECLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< RMT source clock default choice is PLL_F80M */
|
||||||
} soc_periph_rmt_clk_src_legacy_t;
|
} soc_periph_rmt_clk_src_legacy_t;
|
||||||
|
|
||||||
//////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////
|
||||||
|
@@ -251,7 +251,8 @@
|
|||||||
#define SOC_RMT_SUPPORT_TX_SYNCHRO 1 /*!< Support coordinate a group of TX channels to start simultaneously */
|
#define SOC_RMT_SUPPORT_TX_SYNCHRO 1 /*!< Support coordinate a group of TX channels to start simultaneously */
|
||||||
#define SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY 1 /*!< TX carrier can be modulated to data phase only */
|
#define SOC_RMT_SUPPORT_TX_CARRIER_DATA_ONLY 1 /*!< TX carrier can be modulated to data phase only */
|
||||||
#define SOC_RMT_SUPPORT_XTAL 1 /*!< Support set XTAL clock as the RMT clock source */
|
#define SOC_RMT_SUPPORT_XTAL 1 /*!< Support set XTAL clock as the RMT clock source */
|
||||||
#define SOC_RMT_SUPPORT_APB 1 /*!< Support set APB as the RMT clock source */
|
#define SOC_RMT_SUPPORT_PLL_F80M 1 /*!< Support set PLL_F80M as the RMT clock source */
|
||||||
|
#define SOC_RMT_SUPPORT_RC_FAST 1 /*!< Support set RC_FAST as the RMT clock source */
|
||||||
|
|
||||||
/*-------------------------- MCPWM CAPS --------------------------------------*/
|
/*-------------------------- MCPWM CAPS --------------------------------------*/
|
||||||
#define SOC_MCPWM_GROUPS (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
|
#define SOC_MCPWM_GROUPS (1U) ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)
|
||||||
|
@@ -131,10 +131,6 @@ examples/peripherals/rmt/onewire_ds18b20:
|
|||||||
examples/peripherals/rmt/stepper_motor:
|
examples/peripherals/rmt/stepper_motor:
|
||||||
disable:
|
disable:
|
||||||
- if: SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP != 1
|
- if: SOC_RMT_SUPPORT_TX_LOOP_AUTO_STOP != 1
|
||||||
disable_test:
|
|
||||||
- if: IDF_TARGET == "esp32c6"
|
|
||||||
temporary: true
|
|
||||||
reason: target esp32c6 is not supported yet
|
|
||||||
|
|
||||||
examples/peripherals/sdio/host:
|
examples/peripherals/sdio/host:
|
||||||
enable:
|
enable:
|
||||||
|
@@ -12,8 +12,8 @@
|
|||||||
#include "stepper_motor_encoder.h"
|
#include "stepper_motor_encoder.h"
|
||||||
|
|
||||||
///////////////////////////////Change the following configurations according to your board//////////////////////////////
|
///////////////////////////////Change the following configurations according to your board//////////////////////////////
|
||||||
#define STEP_MOTOR_GPIO_EN 16
|
#define STEP_MOTOR_GPIO_EN 19
|
||||||
#define STEP_MOTOR_GPIO_DIR 17
|
#define STEP_MOTOR_GPIO_DIR 20
|
||||||
#define STEP_MOTOR_GPIO_STEP 18
|
#define STEP_MOTOR_GPIO_STEP 18
|
||||||
#define STEP_MOTOR_ENABLE_LEVEL 0 // DRV8825 is enabled on low level
|
#define STEP_MOTOR_ENABLE_LEVEL 0 // DRV8825 is enabled on low level
|
||||||
#define STEP_MOTOR_SPIN_DIR_CLOCKWISE 0
|
#define STEP_MOTOR_SPIN_DIR_CLOCKWISE 0
|
||||||
|
@@ -6,6 +6,7 @@ from pytest_embedded import Dut
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.esp32s3
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.esp32c6
|
||||||
@pytest.mark.generic
|
@pytest.mark.generic
|
||||||
def test_stepper_motor_example(dut: Dut) -> None:
|
def test_stepper_motor_example(dut: Dut) -> None:
|
||||||
dut.expect_exact('example: Initialize EN + DIR GPIO')
|
dut.expect_exact('example: Initialize EN + DIR GPIO')
|
||||||
|
Reference in New Issue
Block a user