PWM(Pulse Width Modulation)
是脉冲宽度调制的缩写,在嵌入式系统中非常常见。它提供了一种脉冲周期波形的方法,一般用于控制马达、LED
、背光灯等。
本文介绍RK3399 PWM
控制器驱动和调试方法。
一、PWM驱动
1、PWM控制器
RK3399 PWM
控制器框图如下:
RK3399 PWM
控制器特性如下:
1)、4个内置PWM
通道。
2)、可配置为捕获模式(输入)。
3)、可配置为连续模式或单次模式(输出)。
4)、在通道为非激活状态时,处于低功耗模式。
2、PWM配置
RK3399 PWM
配置文件:
1)arch/arm64/boot/dts/rockchip/rk3399.dtsi
PWM
属性配置如下:
pwm0: pwm@ff420000 { compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm"; reg = <0x0 0xff420000 0x0 0x10>; ## PWM0寄存器基地址和映射大小 #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm0_pin>; ## PWM0引脚配置 clocks = <&pmucru PCLK_RKPWM_PMU>; ## PWM0时钟源 clock-names = "pwm"; ## PWM0时钟名称 status = "disabled"; }; ... pwm2: pwm@ff420020 { compatible = "rockchip,rk3399-pwm", "rockchip,rk3288-pwm"; reg = <0x0 0xff420020 0x0 0x10>; #pwm-cells = <3>; pinctrl-names = "active"; pinctrl-0 = <&pwm2_pin>; clocks = <&pmucru PCLK_RKPWM_PMU>; clock-names = "pwm"; status = "disabled"; };
PWM
引脚配置如下:
pwm0 { pwm0_pin: pwm0-pin { rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_none>; ## 将GPIO4_C2引脚配置为PWM0功能 }; pwm0_pin_pull_down: pwm0-pin-pull-down { rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_down>; }; ... }; pwm2 { pwm2_pin: pwm2-pin { rockchip,pins = <1 19 RK_FUNC_1 &pcfg_pull_none>; ## 将GPIO1_C3引脚配置为PWM2功能 }; pwm2_pin_pull_down: pwm2-pin-pull-down { rockchip,pins = <1 19 RK_FUNC_1 &pcfg_pull_down>; }; };
2)arch/arm64/boot/dts/rockchip/rockpi-4-linux.dtsi
使能PWM
配置如下:
&pwm0 { status = "okay"; ## 使能pwm0 }; vdd_log: vdd-log { compatible = "pwm-regulator"; pwms = <&pwm2 0 25000 1>; regulator-name = "vdd_log"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <1400000>; regulator-always-on; regulator-boot-on; /* for rockchip boot on */ rockchip,pwm_id= <2>; rockchip,pwm_voltage = <900000>; vin-supply = <&vcc_sys>; }; &pwm2 { status = "okay"; ## 使能pwm2 };
其中:
1)、pwms = <&pwm2 0 25000 1>;
&pwm2
:表示选择pwm2
通道;
0:PWM
的设备号;
25000:PWM
的周期为40KHZ
,即:1000000000/25000ns
,25000单位是ns
。
1:反转极性(PWM_POLARITY_INVERTED
);0:正常极性(PWM_POLARITY_NORMAL
)。
2)、PWM0
只打开使能,未被其他模块使用,在系统启动后,可通过sysfs
配置pwmchip0
的相关属性。
3)、PWM2
已经分配给其它模块,在系统启动后,无法通过sysfs
配置pwmchip2
的相关属性。硬上会提示write error: Device or resource busy
。
3、PWM驱动
RK3399 PWM
驱动文件:drivers/pwm/pwm-rockchip.c
,主要关注:
static const struct pwm_ops rockchip_pwm_ops = { .get_state = rockchip_pwm_get_state, .apply = rockchip_pwm_apply, .owner = THIS_MODULE, };
RK3399 PWM
通道配置调用流程如下:
rockchip_pwm_apply()-> rockchip_pwm_config() rockchip_pwm_enable() rockchip_pwm_get_state()
二、PWM调试
下面基于RockPI 4A
单板调试,该单板运行的是Debian
系统。
在系统启动时,会加载hw_intfc.conf
文件,该文件里配置了PWM/UART
等通信接口的使能。如果不打开,即使在rockpi-4-linux.dtsi
里配置PWM status=okay
,在系统启动后,也看不到pwm0/pwm1
通道。
Retrieving file: /hw_intfc.conf reading /hw_intfc.conf 1718 bytes read in 4 ms (418.9 KiB/s) dtoverlay number: 0, name:/overlays/console-on-ttyS2.dtbo dtoverlay number: 1, name:/overlays/spi1-flash.dtbo hw_conf.valid = 1 hw_conf.pwm0 = 1 ## 使能pwm0通道 hw_conf.pwm1 = 1 ## 使能pwm1通道 hw_conf.uart2 = 0 ## 关闭使能UART2接口 hw_conf.uart4 = 0 hw_conf.spi1 = 1 hw_conf.spi2 = 0 hw_conf.i2c2 = 0 hw_conf.i2c6 = 0 hw_conf.i2c7 = 0 hw_conf.dts_overlay_count = 2 hw_conf.dts_overlay[0] = /overlays/console-on-ttyS2.dtbo hw_conf.dts_overlay[1] = /overlays/spi1-flash.dtbo
PWM
通道调试命令如下:
0、查看PWM设备
目前每个PWM
控制器下只有1路PWM
设备,方法如下:
root@linaro-alip:/sys/kernel/debug# cat pwm platform/ff420020.pwm, 1 PWM device pwm-0 (vdd-log ): requested enabled period: 24997 ns duty: 0 ns polarity: inverse platform/ff420000.pwm, 1 PWM device pwm-0 ((null) ): period: 0 ns duty: 0 ns polarity: inverse
1、查看PWM总线设备
root@xiaotianbsp:~# cd /sys/class/pwm/ root@xiaotianbsp:/sys/class/pwm# ls pwmchip0 pwmchip1 pwmchip2
2、导出PWM
在配置pwmchip0
前,需要将pwmchip0
中的pwm0
导出,方法如下:
root@xiaotianbsp:/sys/class/pwm# cd pwmchip0 root@xiaotianbsp:/sys/class/pwm/pwmchip0# ls device export npwm power subsystem uevent unexport root@xiaotianbsp:/sys/class/pwm/pwmchip0# echo 0 > export ## 此时导出pwm0 root@xiaotianbsp:/sys/class/pwm/pwmchip0# ls device export npwm power pwm0 subsystem uevent unexport
3、配置PWM周期
PWM
周期的单位是ns
,通过配置period
实现,方法如下:
root@xiaotianbsp:/sys/class/pwm/pwmchip0# cd pwm0/ root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# ls capture duty_cycle enable period polarity power uevent ## 周期1KHZ root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# echo 1000000 > period [ 116.102019] ---- rockchip_pwm_apply [ 116.102348] ---- rockchip_pwm_config [ 116.102929] ---- rockchip_pwm_get_state
4、配置PWM占空比
duty_cycle
是一个周期中on
的时间,单位是ns
,方法如下:
## 占空比50%,即duty_cycle/period root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# echo 500000 > duty_cycle [ 148.418151] ---- rockchip_pwm_apply [ 148.418472] ---- rockchip_pwm_config [ 148.418993] ---- rockchip_pwm_get_state
5、配置PWM极性
PWM
极性包括:正常(normal
)和反转(inversed
),通过配置polarity
实现,方法如下:
root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# cat polarity inversed root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# echo normal > polarity [ 193.456890] ---- rockchip_pwm_apply [ 193.457211] ---- rockchip_pwm_config [ 193.457541] ---- rockchip_pwm_get_state
6、打开/关闭PWM
配置完成后,可以打开PWM
,此时可以用示波器测量到输出的PWM
波形,方法如下:
## 打开PWM root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# echo 1 > enable [ 202.627679] ---- rockchip_pwm_apply [ 202.628009] ---- rockchip_pwm_config [ 202.628341] ---- rockchip_pwm_enable [ 202.628668] ---- rockchip_pwm_get_state ## 关闭PWM root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# echo 0 > enable [ 211.909522] ---- rockchip_pwm_apply [ 211.909851] ---- rockchip_pwm_config [ 211.910183] ---- rockchip_pwm_enable [ 211.910510] ---- rockchip_pwm_get_state
7、删除导出PWM
PWM
使用完成后,可以将导出的PWM
删除,方法如下:
root@xiaotianbsp:/sys/class/pwm/pwmchip0/pwm0# cd .. root@xiaotianbsp:/sys/class/pwm/pwmchip0# ls device export npwm power pwm0 subsystem uevent unexport root@xiaotianbsp:/sys/class/pwm/pwmchip0# echo 0 > unexport ## 此时没有pwm0 root@xiaotianbsp:/sys/class/pwm/pwmchip0# ls device export npwm power subsystem uevent unexport
8、测试已使用PWM
PWM2
已经被使用,此时通过sysfs
访问,会提示Device or resource busy
,操作如下:
root@xiaotianbsp:/sys/class/pwm# cd pwmchip2 root@xiaotianbsp:/sys/class/pwm/pwmchip2# ls device export npwm power subsystem uevent unexport root@xiaotianbsp:/sys/class/pwm/pwmchip2# echo 0 > export -bash: echo: write error: Device or resource busy
注:转载请注明作者。