Conversation
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
| * Change Logs: | ||
| * Date Author Notes | ||
| * 2025-12-02 Car12(1085582540@qq.com) first version | ||
|
|
| * Change Logs: | ||
| * Date Author Notes | ||
| * 2025-12-02 Car12(1085582540@qq.com) first version | ||
|
|
There was a problem hiding this comment.
Pull request overview
This PR introduces a PWM driver for N32 BSPs and wires it into multiple N32 board Kconfigs and build scripts so PWM can be enabled per-board/per-timer.
Changes:
- Add
drv_pwm.cimplementing RT-Thread PWM device ops for N32 timers/channels. - Add PWM-related Kconfig options to multiple N32 board BSPs (TIM1/2/3 + pin/remap/channel selection).
- Update SConscripts to compile the new PWM driver and ensure timer peripheral sources are included when PWM is enabled.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 23 comments.
Show a summary per file
| File | Description |
|---|---|
| bsp/n32/n32gxx_lxx/n32wb45xl-evb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) for this board |
| bsp/n32/n32gxx_lxx/n32l43xrl-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, per-channel pin choices) |
| bsp/n32/n32gxx_lxx/n32l43xml-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, per-channel pin choices) |
| bsp/n32/n32gxx_lxx/n32l436-evb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, per-channel pin choices) |
| bsp/n32/n32gxx_lxx/n32l40xcl-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, per-channel pin choices) |
| bsp/n32/n32gxx_lxx/n32g4frml-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) |
| bsp/n32/n32gxx_lxx/n32g45xvl-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) |
| bsp/n32/n32gxx_lxx/n32g45xrl-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) |
| bsp/n32/n32gxx_lxx/n32g45xml-stb/board/Kconfig | Adds PWM Kconfig options (TIM1 remap/channels) |
| bsp/n32/n32gxx_lxx/n32g45xcl-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) |
| bsp/n32/n32gxx_lxx/n32g457qel-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) |
| bsp/n32/n32gxx_lxx/n32g43xcl-stb/board/Kconfig | Adds PWM Kconfig options (TIM1/2/3, remap, channels) |
| bsp/n32/n32gxx_lxx/libraries/n32_drivers/drv_pwm.c | New N32 PWM driver implementation and device registration |
| bsp/n32/n32gxx_lxx/libraries/n32_drivers/SConscript | Builds drv_pwm.c when BSP_USING_PWM is enabled |
| bsp/n32/n32gxx_lxx/libraries/N32WB452_Firmware_Library/SConscript | Adds timer peripheral source when PWM is enabled |
| bsp/n32/n32gxx_lxx/libraries/N32L43x_Firmware_Library/SConscript | Adds timer peripheral source when PWM is enabled |
| bsp/n32/n32gxx_lxx/libraries/N32L40x_Firmware_Library/SConscript | Adds timer peripheral source when PWM is enabled |
| bsp/n32/n32gxx_lxx/libraries/N32G4FR_Firmware_Library/SConscript | Adds timer peripheral source when PWM is enabled |
| bsp/n32/n32gxx_lxx/libraries/N32G45x_Firmware_Library/SConscript | Adds timer peripheral source when PWM is enabled |
| bsp/n32/n32gxx_lxx/libraries/N32G43x_Firmware_Library/SConscript | Adds timer peripheral source when PWM is enabled |
| endchoice | ||
| endif | ||
| config BSP_USING_TIM2_PWM_CH4 | ||
| bool "Enable TIM2 channel3 AF2 PB11" |
There was a problem hiding this comment.
[documentation/文档]: TIM2 CH4 prompt text references the wrong channel
English: config BSP_USING_TIM2_PWM_CH4 is described as "Enable TIM2 channel3 AF2 PB11". This is misleading (channel number doesn't match CH4). Please fix the prompt string so it correctly reflects CH4 and its pin/AF.
中文:config BSP_USING_TIM2_PWM_CH4 的提示文本是“Enable TIM2 channel3 AF2 PB11”,与 CH4 不一致,容易误导。建议修正提示字符串,使其正确描述 CH4 对应的通道/引脚/复用。
| bool "Enable TIM2 channel3 AF2 PB11" | |
| bool "Enable TIM2 channel4 AF2 PB11" |
| endchoice | ||
| endif | ||
| config BSP_USING_TIM2_PWM_CH4 | ||
| bool "Enable TIM2 channel3 AF2 PB11" |
There was a problem hiding this comment.
[documentation/文档]: TIM2 CH4 prompt text references the wrong channel
English: config BSP_USING_TIM2_PWM_CH4 is described as "Enable TIM2 channel3 AF2 PB11". This is misleading for CH4. Please fix the prompt string so it correctly reflects CH4 and its pin/AF.
中文:config BSP_USING_TIM2_PWM_CH4 的提示文本写成了“Enable TIM2 channel3 AF2 PB11”,与 CH4 不一致,容易误导。建议修正提示字符串,使其正确描述 CH4 对应的通道/引脚/复用。
| bool "Enable TIM2 channel3 AF2 PB11" | |
| bool "Enable TIM2 channel4 AF2 PB11" |
| endchoice | ||
| endif | ||
| config BSP_USING_TIM2_PWM_CH4 | ||
| bool "Enable TIM2 channel3 AF2 PB11" |
There was a problem hiding this comment.
[documentation/文档]: TIM2 CH4 prompt text references the wrong channel
English: config BSP_USING_TIM2_PWM_CH4 is described as "Enable TIM2 channel3 AF2 PB11". This is misleading for CH4. Please fix the prompt string so it correctly reflects CH4 and its pin/AF.
中文:config BSP_USING_TIM2_PWM_CH4 的提示文本写成了“Enable TIM2 channel3 AF2 PB11”,与 CH4 不一致,容易误导。建议修正提示字符串,使其正确描述 CH4 对应的通道/引脚/复用。
| bool "Enable TIM2 channel3 AF2 PB11" | |
| bool "Enable TIM2 channel4 PB11 AF2" |
| tim_clock = tim_clock_get(tim); | ||
|
|
||
| tim_clock /= 1000000UL; | ||
| /*caculate period*/ | ||
| period = (TIM_GetAutoReload(tim) + 1) * (TIM_GetPrescaler(tim) + 1) * 1000UL / tim_clock; | ||
| pulse = (rt_uint64_t)configuration->pulse * (TIM_GetAutoReload(tim) + 1) / period; | ||
|
|
||
| if (pulse < MIN_PULSE) | ||
| { | ||
| pulse = MIN_PULSE; | ||
| } | ||
| /*To determine user input, output high level is required*/ | ||
| else if (pulse >= period) | ||
| { | ||
| pulse = period + 1; |
There was a problem hiding this comment.
[bug/缺陷]: Unit mismatch in drv_pwm_set_pulse makes 100% duty handling wrong
English: period is computed in nanoseconds, but pulse is computed in timer ticks. The comparison pulse >= period (and then pulse = period + 1) mixes units, so the clamp logic is incorrect and can set an out-of-range compare value. Use consistent units (e.g., compare configuration->pulse >= configuration->period, or compare pulse >= (ARR+1) in ticks).
中文:period 计算结果是纳秒(ns),而 pulse 计算结果是计数器 tick。pulse >= period(以及 pulse = period + 1)混用了单位,导致占空比边界判断/钳位逻辑错误,并可能写入越界的比较值。需要统一单位(例如比较 configuration->pulse >= configuration->period,或在 tick 单位下比较 pulse >= (ARR+1))。
| tim_clock = tim_clock_get(tim); | |
| tim_clock /= 1000000UL; | |
| /*caculate period*/ | |
| period = (TIM_GetAutoReload(tim) + 1) * (TIM_GetPrescaler(tim) + 1) * 1000UL / tim_clock; | |
| pulse = (rt_uint64_t)configuration->pulse * (TIM_GetAutoReload(tim) + 1) / period; | |
| if (pulse < MIN_PULSE) | |
| { | |
| pulse = MIN_PULSE; | |
| } | |
| /*To determine user input, output high level is required*/ | |
| else if (pulse >= period) | |
| { | |
| pulse = period + 1; | |
| rt_uint32_t auto_reload = TIM_GetAutoReload(tim) + 1; | |
| tim_clock = tim_clock_get(tim); | |
| tim_clock /= 1000000UL; | |
| /*caculate period*/ | |
| period = auto_reload * (TIM_GetPrescaler(tim) + 1) * 1000UL / tim_clock; | |
| pulse = (rt_uint64_t)configuration->pulse * auto_reload / period; | |
| /* To determine user input, output high level is required */ | |
| if (configuration->pulse >= period) | |
| { | |
| /* 100% or above duty: keep output high over the whole period */ | |
| pulse = auto_reload; | |
| } | |
| else if (pulse < MIN_PULSE) | |
| { | |
| pulse = MIN_PULSE; |
| menuconfig BSP_USING_TIM1_PWM | ||
| bool "Enable TIM1 output PWM" | ||
| default n | ||
| # --------------selcet remap----------------- |
There was a problem hiding this comment.
[spelling/拼写]: Typo in comment selcet
English: The comment says selcet remap; please correct to select remap.
中文:注释中 selcet remap 存在拼写错误,建议更正为 select remap。
| # --------------selcet remap----------------- | |
| # --------------select remap----------------- |
| // .tim = TIM2, | ||
| // .name = "pwm2", |
There was a problem hiding this comment.
[bug/缺陷]: TIM2 PWM object is missing required fields
English: In the #ifdef BSP_USING_TIM2_PWM initializer, .tim = TIM2 and .name = "pwm2" are commented out. This leaves device->tim as NULL/0 for that entry, causing n32_time_rcc_config(device->tim) to assert/fail and breaking PWM registration/initialization when TIM2 PWM is enabled.
中文:在 #ifdef BSP_USING_TIM2_PWM 的对象初始化中,.tim = TIM2 和 .name = "pwm2" 被注释掉了,导致该对象的 device->tim 为空/0。启用 TIM2 PWM 时会在 n32_time_rcc_config(device->tim) 处断言失败,PWM 初始化/注册会直接出错。
| // .tim = TIM2, | |
| // .name = "pwm2", | |
| .tim = TIM2, | |
| .name = "pwm2", |
| if ((GPIOA == gpio_grp && GPIO_PIN_15) || | ||
| (GPIOB == gpio_grp && GPIO_PIN_3) || | ||
| (GPIOB == gpio_grp && GPIO_PIN_4)) |
There was a problem hiding this comment.
[bug/缺陷]: JTAG/SWD remap condition ignores pin and always triggers for GPIOA/GPIOB
English: The condition uses (GPIOA == gpio_grp && GPIO_PIN_15) etc. Since GPIO_PIN_15/3/4 are non-zero constants, the && expression does not check the pin argument at all. This will remap JTAG->SWD whenever gpio_grp matches, potentially disabling JTAG unexpectedly. Compare against the pin parameter (e.g., pin == GPIO_PIN_15 or pin & GPIO_PIN_15).
中文:条件写成了 (GPIOA == gpio_grp && GPIO_PIN_15) 等,由于 GPIO_PIN_15/3/4 是非零常量,该判断并没有使用 pin 参数,导致只要 gpio_grp 匹配就会执行 JTAG->SWD 重映射,可能意外关闭 JTAG。应当用 pin 参数进行比较(如 pin == GPIO_PIN_15 或 pin & GPIO_PIN_15)。
| if ((GPIOA == gpio_grp && GPIO_PIN_15) || | |
| (GPIOB == gpio_grp && GPIO_PIN_3) || | |
| (GPIOB == gpio_grp && GPIO_PIN_4)) | |
| if ((GPIOA == gpio_grp && (pin & GPIO_PIN_15)) || | |
| (GPIOB == gpio_grp && (pin & GPIO_PIN_3)) || | |
| (GPIOB == gpio_grp && (pin & GPIO_PIN_4))) |
| uint16_t tim_ch; | ||
| switch (channel) | ||
| { | ||
| case 0: | ||
| tim_ch = TIM_CH_1; | ||
| break; | ||
| case 1: | ||
| tim_ch = TIM_CH_2; | ||
| break; | ||
| case 2: | ||
| tim_ch = TIM_CH_3; | ||
| break; | ||
| case 3: | ||
| tim_ch = TIM_CH_4; | ||
|
|
||
| default: | ||
| break; | ||
| } | ||
|
|
||
| TIM_EnableCapCmpCh(time, tim_ch, enable ? TIM_CAP_CMP_ENABLE : TIM_CAP_CMP_DISABLE); | ||
|
|
There was a problem hiding this comment.
[bug/缺陷]: Invalid channel values can use an uninitialized tim_ch
English: If channel is not 0..3, the switch falls into default without assigning tim_ch, but TIM_EnableCapCmpCh() is still called. Return -RT_EINVAL (or assert) on invalid channels to avoid unpredictable behavior.
中文:当 channel 不在 0..3 时,switch 进入 default 且没有给 tim_ch 赋值,但仍然调用了 TIM_EnableCapCmpCh(),会导致不可预期行为。建议对非法 channel 直接返回 -RT_EINVAL(或断言)。
| if GetDepend(['RT_USING_CLOCK_TIME']): | ||
| src += ['n32wb452_std_periph_driver/src/n32wb452_tim.c'] | ||
|
|
||
| if GetDepend(['RT_USING_PWM']): | ||
| src += ['n32wb452_std_periph_driver/src/n32wb452_tim.c'] | ||
|
|
There was a problem hiding this comment.
[bug/缺陷]: Duplicate source inclusion of n32wb452_tim.c
English: n32wb452_tim.c is added under both RT_USING_CLOCK_TIME and RT_USING_PWM. If both are enabled, the same C file will be compiled twice, typically causing duplicate object/duplicate symbol build failures. Add the file only once (e.g., gate it behind a combined condition or de-duplicate the src list).
中文:n32wb452_tim.c 同时在 RT_USING_CLOCK_TIME 和 RT_USING_PWM 条件下被加入 src。如果两者同时使能,同一源文件会被编译两次,通常会导致重复目标文件/重复符号的构建失败。应保证该文件只被加入一次(例如使用合并条件或对 src 去重)。
| if GetDepend(['RT_USING_CLOCK_TIME']): | ||
| src += ['n32g43x_std_periph_driver/src/n32g43x_tim.c'] | ||
|
|
||
| if GetDepend(['RT_USING_PWM']): | ||
| src += ['n32g43x_std_periph_driver/src/n32g43x_tim.c'] | ||
|
|
There was a problem hiding this comment.
[bug/缺陷]: Duplicate source inclusion of n32g43x_tim.c
English: n32g43x_tim.c is appended in both the RT_USING_CLOCK_TIME and RT_USING_PWM conditions. When both are enabled, the same source may be compiled twice and break the build with duplicate symbols. Ensure it is included only once.
中文:n32g43x_tim.c 同时在 RT_USING_CLOCK_TIME 与 RT_USING_PWM 条件下加入;两者同时开启时可能导致重复编译并引发重复符号的构建失败。请确保只加入一次。
| if GetDepend(['RT_USING_CLOCK_TIME']): | |
| src += ['n32g43x_std_periph_driver/src/n32g43x_tim.c'] | |
| if GetDepend(['RT_USING_PWM']): | |
| src += ['n32g43x_std_periph_driver/src/n32g43x_tim.c'] | |
| if GetDepend(['RT_USING_CLOCK_TIME']) or GetDepend(['RT_USING_PWM']): | |
| src += ['n32g43x_std_periph_driver/src/n32g43x_tim.c'] |
拉取/合并请求描述:(PR description)
[
add bsp driver
1.add n32xxx pwm driver
Test
N32
Test OK on 2 dev boards; KConfig modified for all official dev boards:
bsp\32\32l40xcl-stb: Tested OK
bsp\32\32g457qel-stb: Tested OK
Other boards: KConfig updated, compiled without errors/warnings (no physical board test yet)
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up