Sfoglia il codice sorgente

rmt: support pll clock source on esp32c6

morris 3 anni fa
parent
commit
32cd193ddf

+ 0 - 4
components/driver/.build-test-rules.yml

@@ -73,10 +73,6 @@ components/driver/test_apps/pulse_cnt:
 components/driver/test_apps/rmt:
   disable:
     - 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:
   disable_test:

+ 12 - 0
components/driver/rmt/rmt_common.c

@@ -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_LOGD(TAG, "install APB_FREQ_MAX lock for RMT channel (%d,%d)", group->group_id, channel_id);
 #endif // CONFIG_PM_ENABLE
+        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
     case RMT_CLK_SRC_AHB:
         // TODO: decide which kind of PM lock we should use for such clock

+ 1 - 1
components/driver/test_apps/legacy_rmt_driver/main/test_legacy_rmt.c

@@ -618,7 +618,7 @@ TEST_CASE("RMT Interrupt IRAM Safe", "[rmt]")
         .rmt_mode = RMT_MODE_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
     TEST_ESP_OK(rmt_driver_install(tx.channel, 0, ESP_INTR_FLAG_IRAM));
 

+ 1 - 0
components/driver/test_apps/rmt/pytest_rmt.py

@@ -9,6 +9,7 @@ from pytest_embedded import Dut
 @pytest.mark.esp32s2
 @pytest.mark.esp32s3
 @pytest.mark.esp32c3
+@pytest.mark.esp32c6
 @pytest.mark.generic
 @pytest.mark.parametrize(
     'config',

+ 9 - 3
components/hal/esp32c6/include/hal/rmt_ll.h

@@ -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_b = divider_denominator;
     switch (src) {
-    case RMT_CLK_SRC_APB:
+    case RMT_CLK_SRC_PLL_F80M:
         PCR.rmt_sclk_conf.rmt_sclk_sel = 1;
         break;
+    case RMT_CLK_SRC_RC_FAST:
+        PCR.rmt_sclk_conf.rmt_sclk_sel = 2;
+        break;
     case RMT_CLK_SRC_XTAL:
         PCR.rmt_sclk_conf.rmt_sclk_sel = 3;
         break;
@@ -758,10 +761,13 @@ static inline bool rmt_ll_tx_is_loop_enabled(rmt_dev_t *dev, uint32_t channel)
 __attribute__((always_inline))
 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) {
     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;
     case 3:
         clk_src = RMT_CLK_SRC_XTAL;

+ 5 - 1
components/soc/esp32c6/include/soc/Kconfig.soc_caps.in

@@ -515,7 +515,11 @@ config SOC_RMT_SUPPORT_XTAL
     bool
     default y
 
-config SOC_RMT_SUPPORT_APB
+config SOC_RMT_SUPPORT_PLL_F80M
+    bool
+    default y
+
+config SOC_RMT_SUPPORT_RC_FAST
     bool
     default y
 

+ 8 - 7
components/soc/esp32c6/include/soc/clk_tree_defs.h

@@ -174,24 +174,25 @@ typedef enum {
 /**
  * @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
  */
 typedef enum {
-    RMT_CLK_SRC_APB = SOC_MOD_CLK_APB,         /*!< Select APB as the source clock */
-    RMT_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL,       /*!< Select XTAL as the source clock */
-    RMT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB,     /*!< Select APB as the default choice */
+    RMT_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
+    RMT_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST,   /*!< Select RC_FAST as the source clock */
+    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;
 
 /**
  * @brief Type of RMT clock source, reserved for the legacy RMT driver
  */
 typedef enum {
-    RMT_BASECLK_APB = SOC_MOD_CLK_APB,     /*!< RMT source clock is APB */
-    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_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_DEFAULT = SOC_MOD_CLK_PLL_F80M,  /*!< RMT source clock default choice is PLL_F80M */
 } soc_periph_rmt_clk_src_legacy_t;
 
 //////////////////////////////////////////////////Temp Sensor///////////////////////////////////////////////////////////

+ 2 - 1
components/soc/esp32c6/include/soc/soc_caps.h

@@ -252,7 +252,8 @@
 #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_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 --------------------------------------*/
 #define SOC_MCPWM_GROUPS                     (1U)   ///< 1 MCPWM groups on the chip (i.e., the number of independent MCPWM peripherals)

+ 0 - 4
examples/peripherals/.build-test-rules.yml

@@ -131,10 +131,6 @@ examples/peripherals/rmt/onewire_ds18b20:
 examples/peripherals/rmt/stepper_motor:
   disable:
     - 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:
   enable:

+ 2 - 2
examples/peripherals/rmt/stepper_motor/main/stepper_motor_example_main.c

@@ -12,8 +12,8 @@
 #include "stepper_motor_encoder.h"
 
 ///////////////////////////////Change the following configurations according to your board//////////////////////////////
-#define STEP_MOTOR_GPIO_EN       16
-#define STEP_MOTOR_GPIO_DIR      17
+#define STEP_MOTOR_GPIO_EN       19
+#define STEP_MOTOR_GPIO_DIR      20
 #define STEP_MOTOR_GPIO_STEP     18
 #define STEP_MOTOR_ENABLE_LEVEL  0 // DRV8825 is enabled on low level
 #define STEP_MOTOR_SPIN_DIR_CLOCKWISE 0

+ 1 - 0
examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py

@@ -6,6 +6,7 @@ from pytest_embedded import Dut
 
 
 @pytest.mark.esp32s3
+@pytest.mark.esp32c6
 @pytest.mark.generic
 def test_stepper_motor_example(dut: Dut) -> None:
     dut.expect_exact('example: Initialize EN + DIR GPIO')