跳到主要内容

PWM 驱动调试指南

X5 有两类控制器:一类是标准 PWM,有 4 组,每组 2 路输出,共 8 个 PWM 输出,另一类是 LPWM,共两组,每组 4 路 PWM 输出,主要用于支持 Sensor 的同步曝光。

  • PWM 默认支持频率范围为 0.05Hz - 1MHz,占空比寄存器 RATIO 精度为 16bit,周期有效时间为 1us 到 20s,占空比有效时间为 10ns 到 20s;
  • LPWM 默认支持频率范围是 1Hz 到 1MHz,输出脉冲宽度范围为 1us~ 4ms;
  • LPWM 是为了 Sensor 同步设计的,不是一个通用的 PWM,单纯 PWM 功能建议使用 PWM。

驱动代码

代码路径

PWM 代码路径

drivers/pwm/pwm-hobot.c

LPWM 代码路径

kernel/drivers/media/platform/horizon/camsys/lpwm/

内核配置

/* arch/arm64/configs/hobot_x5_rdk_ubuntu_defconfig */
...
CONFIG_HOBOT_LPWM=m
...
CONFIG_PWM_DROBOT=y
...

DTS 节点配置

X5 PWM 及 LPWM 控制器设备树定义位于 SDK 包的 kernel 文件夹下的 arch/arm64/boot/dts/hobot/x5.dtsi 文件内。

备注

x5.dtsi 中的节点主要声明 SoC 共有特性,和具体电路板无关,一般情况下不用修改。

当需要使能特定 PWM 端口输出的时候,可以到对应的板级文件修改,这里以 x5-rdk-v1p0.dts 为例,使能 lpwm1_0, lpwm1_1, pwm0_0, pwm0_1, pwm1_0, pwm1_1, pwm2_0, pwm2_1, pwm3_0, pwm3_1。

&lpwm1 {
status = "okay";
pinctrl-names = "default";
/** for display backlight **/
pinctrl-0 = <&pinctrl_lpwm1_0 &pinctrl_lpwm1_1>;
};

&pwm0 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm0_0 &pinctrl_pwm0_1>;
};

&pwm1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm1_0 &pinctrl_pwm1_1>;
};

&pwm2 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm2_0 &pinctrl_pwm2_1>;
};

&pwm3 {
/* LSIO_PWM_OUT6 and LSIO_PWM_OUT7 */
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pwm3_0 &pinctrl_pwm3_1>;
};

DTS 中 pwm 和 pwmchip 对应关系查询方法

尽管 pwm 和 lpwm 都属于 pwmchip,但 PWM/LPWM 下含的设备数量不一致,所以无法通过 aliases 固定序号,因此在板端操作 pwm 时,需要 cat pwmchip 下的 device/uevent,查看 pwm 地址是否与目标 pwm 地址是否一致。以 pwm0 为例,在板端使用以下命令查看 pwmchip 的 uevent

root@ubuntu:~# cat /sys/class/pwm/pwmchip0/device/uevent
DRIVER=drobot-pwm
OF_NAME=pwm
OF_FULLNAME=/soc/a55_apb0/pwm@34140000
OF_COMPATIBLE_0=d-robotics,pwm
OF_COMPATIBLE_N=1
OF_ALIAS_0=pwm0
MODALIAS=of:NpwmT(null)Cd-robotics,pwm

40pin 中 pwm 对应关系表

40pin 引脚序号pwm 引脚序号pwmchip 序号srpi-config 中 pwm 序号该引脚在设备树中的配置标签该引脚默认功能
29 脚pwm0pwm0pwm0pinctrl_pwm0_0SPI2_SCLK
31 脚pwm1pwm0pwm0pinctrl_pwm0_1SPI2_SSN
37 脚pwm2pwm1pwm1pinctrl_pwm1_0SPI2_MISO
18 脚pwm3pwm1pwm1pinctrl_pwm1_1SPI2_MOSI
28 脚pwm4pwm2pwm2pinctrl_pwm2_0SCL0
27 脚pwm5pwm2pwm2pinctrl_pwm2_1SDA0
32 脚pwm6pwm3pwm3pinctrl_pwm3_0SCL1
33 脚pwm7pwm3pwm3pinctrl_pwm3_1SDA1

除了上述手动查表的方法来确认对应关系以外,我们还可以直接通过 hb_gpioinfo | grep pwm 命令,直接查询到已经使用了的 pwm 相关引脚。其中 403、404、356 等等是该引脚的 gpio 编号,和 40pin 的序号不是一个概念。

root@ubuntu:~# hb_gpioinfo  | grep pwm
line 24: unnamed input LSIO_SPI3_SCLK 403 pinctrl_lpwm1_0
line 25: unnamed input LSIO_SPI3_SSN 404 pinctrl_lpwm1_1
line 9: unnamed input LSIO_I2C1_SCL 356 pinctrl_pwm3_0
line 10: unnamed input LSIO_I2C1_SDA 357 pinctrl_pwm3_1
root@ubuntu:~#

测试

用户可以参考以下命令进行 pwm 功能测试,并进行信号测量,验证 pwm 工作是否正常。具体测量的硬件引脚请用户参考使用的具体硬件提供的说明。 以下命令以验证 PWM0 ch0 为例。

cd /sys/class/pwm/pwmchip0/
echo 0 > export
cd pwm0

# 配置周期为100us
echo 100000 > period
# 配置占空比为 50% = 100us * 0.5 = 50us
echo 50000 > duty_cycle
# 使能PWM输出
echo 1 > enable

#以下是进行寄存器读取
echo "Regs of PWM 3:"
echo "PWM_EN `devmem 0x34170000 32`"
echo "PWM_INT_CTRL `devmem 0x34170004 32`"
echo "PWM0_CTRL `devmem 0x34170008 32`"
echo "PWM0_CLK `devmem 0x34170010 32`"
echo "PWM0_PERIOD `devmem 0x34170020 32`"
echo "PWM0_STATUS `devmem 0x34170028 32`"
echo "PWM1_CTRL `devmem 0x34170030 32`"
echo "PWM1_CLK `devmem 0x34170034 32`"
echo "PWM1_PERIOD `devmem 0x34170040 32`"
echo "PWM1_STATUS `devmem 0x34170048 32`"