概要
これの続き。
使ったボードは以下
公式の状況
2026年7月18日現在
今回はMCPWMを有効にする
パッチ
diff --git a/boards/espressif/esp32c5_devkitc/esp32c5_devkitc_hpcore-pinctrl.dtsi b/boards/espressif/esp32c5_devkitc/esp32c5_devkitc_hpcore-pinctrl.dtsi
index a6ed3c94a63..cc489972e82 100644
--- a/boards/espressif/esp32c5_devkitc/esp32c5_devkitc_hpcore-pinctrl.dtsi
+++ b/boards/espressif/esp32c5_devkitc/esp32c5_devkitc_hpcore-pinctrl.dtsi
@@ -51,4 +51,11 @@
<I2S_I_SD_GPIO8>;
};
};
+
+ mcpwm0_default: mcpwm0_default {
+ group1 {
+ pinmux = <MCPWM0_OUT0A_GPIO26>;
+ output-enable;
+ };
+ };
};
diff --git a/drivers/pwm/pwm_mc_esp32.c b/drivers/pwm/pwm_mc_esp32.c
index b9d9ef08032..02164181c0b 100644
--- a/drivers/pwm/pwm_mc_esp32.c
+++ b/drivers/pwm/pwm_mc_esp32.c
@@ -123,7 +123,7 @@ static void mcpwm_esp32_duty_set(const struct device *dev,
duty_mode = channel->inverted ? DUTY_MODE_ACTIVE_LOW : DUTY_MODE_ACTIVE_HIGH;
}
- uint32_t timer_clk_hz = data->mcpwm_clk_hz / config->prescale / channel->prescale;
+ uint32_t timer_clk_hz = data->mcpwm_clk_hz / (config->prescale + 1) / (channel->prescale + 1);
set_duty = (timer_clk_hz / channel->freq) * channel->duty / 100;
mcpwm_ll_operator_connect_timer(data->hal.dev, channel->operator_id, channel->timer_id);
@@ -183,11 +183,11 @@ static int mcpwm_esp32_timer_set(const struct device *dev,
__ASSERT_NO_MSG(channel->freq > 0);
- mcpwm_ll_timer_set_clock_prescale(data->hal.dev, channel->timer_id, channel->prescale);
+ mcpwm_ll_timer_set_clock_prescale(data->hal.dev, channel->timer_id, channel->prescale + 1);
mcpwm_ll_timer_set_count_mode(data->hal.dev, channel->timer_id, MCPWM_TIMER_COUNT_MODE_UP);
mcpwm_ll_timer_update_period_at_once(data->hal.dev, channel->timer_id);
- uint32_t timer_clk_hz = data->mcpwm_clk_hz / config->prescale / channel->prescale;
+ uint32_t timer_clk_hz = data->mcpwm_clk_hz / (config->prescale + 1) / (channel->prescale + 1);
mcpwm_ll_timer_set_peak(data->hal.dev, channel->timer_id, timer_clk_hz / channel->freq,
false);
@@ -360,7 +360,7 @@ static int mcpwm_esp32_enable_capture(const struct device *dev, uint32_t channel
return -EBUSY;
}
- mcpwm_ll_group_set_clock_prescale(config->index, config->prescale);
+ mcpwm_ll_group_set_clock_prescale(config->index, config->prescale + 1);
mcpwm_ll_group_enable_shadow_mode(data->hal.dev);
mcpwm_ll_group_flush_shadow(data->hal.dev);
@@ -516,7 +516,7 @@ int mcpwm_esp32_init(const struct device *dev)
channel_init(dev);
- mcpwm_ll_group_set_clock_prescale(config->index, config->prescale);
+ mcpwm_ll_group_set_clock_prescale(config->index, config->prescale + 1);
mcpwm_ll_group_enable_shadow_mode(data->hal.dev);
mcpwm_ll_group_flush_shadow(data->hal.dev);
diff --git a/samples/basic/servo_motor/boards/esp32c5_devkitc_hpcore.overlay b/samples/basic/servo_motor/boards/esp32c5_devkitc_hpcore.overlay
new file mode 100644
index 00000000000..b91511525d4
--- /dev/null
+++ b/samples/basic/servo_motor/boards/esp32c5_devkitc_hpcore.overlay
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: Apache-2.0 */
+/* Copyright 2026 Hayashi Takuma */
+
+#include <zephyr/dt-bindings/pwm/pwm.h>
+
+/ {
+ servo: servo {
+ compatible = "pwm-servo";
+ pwms = <&mcpwm0 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
+ min-pulse = <PWM_USEC(1450)>;
+ max-pulse = <PWM_USEC(2400)>;
+ };
+};
+
+&mcpwm0 {
+ pinctrl-0 = <&mcpwm0_default>;
+ pinctrl-names = "default";
+ prescale = <0>;
+ prescale-timer0 = <255>;
+ status = "okay";
+};
パッチの対応内容は以下の通り
-
ESP32-C5 DevKitCのピン設定追加
MCPWM0_OUT0A_GPIO26
GPIO26からPWMを出力する mcpwm0_default を追加 -
ESP32 MCPWMドライバ修正
TRMどおりにプリスケーラ値を +1 する修正
mcpwm_ll_group_set_clock_prescale()
mcpwm_ll_timer_set_clock_prescale()
クロック計算を修正しています。 -
servo_motor用overlay追加
GPIO26を潰さないように、mcpwm0もoverlayに定義する
ビルド
west build -p always -b esp32c5_devkitc/esp32c5/hpcore samples/basic/servo_motor/
west flash --esp-device /dev/ttyACM0
結果
ボードのGPIO26とGNDとオシロをつないで見る。
F = 50.00 Hz
T = 20.00 ms
で意図した波形が出ている。
コントリビュート
でIssueたててみた。

