RK3568开发笔记-pwm调试

目录

前言

一、PWM驱动介绍

二、设备树DTS节点配置

三、PWM使用

四、PWM backlight

五、FAQ   

1、PWM 无法注册成功:

2、PWM 在 U-Boot 与 kernel 之间的衔接问题

3、PWM Regulator 时 PWM pin 脚上下拉配置问题

总结


前言

        PWM即脉冲宽度调制,是英文“Pulse Width ModulaTIon”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。PWM控制技术就是对脉冲的宽度进行调制的技术,即通过对一系列脉冲的宽度进行调制,来等效的获得所需要的波形(含形状和幅值)。PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。本文主要介绍RK3568平台PWM使用方法。

一、PWM驱动介绍

        驱动文件在SDK kernel目录下,驱动文件为drivers/pwm/pwm-rockchip.c 3.10 和 4.4 及以上版本内核下驱动文件名字是同一个,pwm-rockchip.c 只支持 Continuous mode,但是里 面的代码有些差别。4.4 及以上内核版本将 pwm_config()pwm_enable() pwm_disable() 包装pwm_apply_state() 函数里面,这样做的好处是可以一次改变几个 PWM 参数,3.10 内核的 PWM 驱动还 是原来的接口。

驱动接口说明如下所示:

1、头文件包含,该头文件包含PWM模块具体的函数接口

#include <linux/pwm.h>

2、PWM设备资源申请


struct pwm_device *pwm_request(int pwm_id, const char *label);

struct pwm_device * pwm1 = NULL;
pwm0 = pwm_request(1, “test-pwm”);

3、使用pwm_config 函数配置 PWM 的占空比

int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns);

pwm_config(pwm0, 500000, 1000000);

4、使用pwm_enable函数使能PWM函数

int pwm_enable(struct pwm_device *pwm);

pwm_enable(pwm0);

5、使用pwm_free函数释放所申请的 PWM

void pwm_free(struct pwm_device *pwm);

pwm_free(pwm0);

6、使用pwm_disable函数禁用 PWM

void pwm_disable(struct pwm_device *pwm);

pwm_disable(pwm0);

二、设备树DTS节点配置

        官方SDK对于RK3568各路PWM节点配置已经在基础设备树文件中已经详细定义,我们只需在我们的板级设备数配置文件中引用打开即可,如在板级配置文件中打开PWM7节点如下所示:

&pwm7 {
        status = "okay";
};

从调试过程来看,pwm容易被其他资源所占用,特别是背光等节点,本人使用的这块pwm就被backlight节点占用,需要在设备树文件关闭backlight节点,不然不能够使用该路PWM节点:


&backlight {
        status = "disabled";
};

&backlight1 {
        status = "disabled";
};

除此之外,我们可以设置pwm的一些其他参数,此处参考背光节点节点参数设置:

bl: backlight {
pwms = <&pwm 0 25000 PWM_POLARITY_INVERTED>;
pwm-names = "backlight";
};
参数 1 ,表示 index (per-chip index of the PWM to request) ,一般是 0 ,因为我们 Rockchip PWM 每个 chip 只有一个。
参数 2 ,表示 PWM 输出波形的时间周期,单位是 ns ;例如下面配置的 25000 就是表示想要得到的 PWM 输出周期是 40Khz
参数 3 ,表示极性,为可选参数;下面例子中的配置为负极性。

三、PWM使用

        本文主要介绍在终端通过命令方式控制pwm波输出。控制指令如下所示:以下是 pwmchip0 的例子,设置 pwm0 输出频率 100K,占空比 50%, 极性为正极性:

cd /sys/class/pwm/pwmchip0/

echo 0 > export

cd pwm0

echo 10000 > period

echo 5000 > duty_cycle

echo normal > polarity

echo 1 > enable
1、enable :写入 1 使能 pwm ,写入 0 关闭 pwm
2、polarity :有 normal inversed 两个参数选择,表示输出引脚电平翻转;
3、duty_cycle :在 normal 模式下,表示一个周期内高电平持续的时间(单位:纳秒),在 reversed 模 式下,表示一个周期中低电平持续的时间(单位:纳秒)
4、period :表示 pwm 波的周期 ( 单位:纳秒 )

四、PWM backlight

       背光使用 PWM 的连续模式较为频繁,以下是 DTS 文件中背光很常见的背光配置节点:

backlight: backlight {
compatible = "pwm-backlight";
pwms = <&pwm0 0 25000 0>;
brightness-levels = <
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47
48 49 50 51 52 53 54 55
56 57 58 59 60 61 62 63
64 65 66 67 68 69 70 71
72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87
88 89 90 91 92 93 94 95
96 97 98 99 100 101 102 103
104 105 106 107 108 109 110 111
112 113 114 115 116 117 118 119
120 121 122 123 124 125 126 127
128 129 130 131 132 133 134 135
136 137 138 139 140 141 142 143
144 145 146 147 148 149 150 151
152 153 154 155 156 157 158 159
160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175
176 177 178 179 180 181 182 183
184 185 186 187 188 189 190 191
192 193 194 195 196 197 198 199
200 201 202 203 204 205 206 207
208 209 210 211 212 213 214 215
216 217 218 219 220 221 222 223
224 225 226 227 228 229 230 231
232 233 234 235 236 237 238 239
240 241 242 243 244 245 246 247
248 249 250 251 252 253 254 255>;
default-brightness-level = <200>;
enable-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>;
};
1、"pwms = <&pwm0 0 25000 0>" 上面 PWM 节点配置小节中有描述;
2、brightness-levels 数组,我们一般以值 255 为一个 scale ,所以一般的 brightness-levels 256 个元素 的数组。当 PWM 设置为正极性时,从 0~255 表示背光为正极,占空比从 0%~100% 变化, 255~0 位负极性,占空比从 100%~0% 变化;当 PWM 设置为负极性时,反之。
3、default-brightness-level 表示默认的背光,它存在于开机时候,如背光驱动初始化到安卓用户层设置 下来新的背光这段时间,表示为第 200 个元素的背光亮度。
4、enable-gpios 表示背光使能脚,这个根据电路原理图配置即可;有的硬件没有这个背光使能脚,那 么将这个配置删除,背光驱动通过配置 brightness-levels 数组的第 0 个元素将背光关闭
如何确定背光灭的 brightness-level 值,通过命令行调试背光亮度, echo xxx > sys/class/backlight/backlight/brightness。
PWM 设置为正极性时,可以通过 echo xxx > sys/class/backlight/backlight/brightness 到背光节点, xxx 的范围为 0~255 ,这时观察亮度变化,如 x 为背光亮度为 0 的点, y 为客户接受的背光最亮的点。这时重 新调整 brightness-level 表,就可以将数组第一个值改为 x ,最大值改为 y ,中间值需均匀变化,凑成 256 个 元素,且有一个元素值为 255 。当 PWM 为负极性时,则反之

五、FAQ   

1、PWM 无法注册成功:

dts 配置文件是否打开对应的 PWM。
该路PWM 是否被其他资源占用,可以根据报错的返回值去查看原因。

2、PWM U-Boot kernel 之间的衔接问题

 a、U-Boot 如果有用 PWM 调压功能,到了 kernel 阶段,此时 PWM 仍然是工作状态, 需要根据当前 PWM 的硬件状态,将 PWM clock count 调整与当前 PWM 状态一致。否则可能会出现 clock 架构发 现无人使用的 PWM clock ,将其关闭后,导致 PWM 无法工作,出现类似 PWM 调压电压不够导致 的死机问题等。以上的补丁已经修正,确保 PWM 驱动 : drivers/pwm/pwmrockchip.c ,更新到下面的 提交点:
1. kernel-4.4: commit e6f2796ef5b660a70102c02d6c15f65ff8701d76
2. kernel-3.10: commit 5a3d9257d5e379391eb02457ccd70f28a8fb188b
b、U-Boot kernel PWM 所用的时钟源的频率不同,也会导致中间出现切换 , 可能会导致 PWM 占空比 发生变化,出现类似 PWM 调压电压不够导致的死机问题等,所以要保持 U-Boot kernel 的时钟 源或时钟源的频率一致。确保 U-Boot GPLL 频率与 kernel 保持一致,因为 PWM 的时钟现在都 是挂在 GPLL 下面; U-Boot GPLL 频率通过 U-Boot 的开机打印 log 可以看到, kernel 的频率通过 查看 clock tree, cat /sys/kernel/debug/clock/clock_tree | grep gpll
c、U-Boot kernel 所配置的极性和周期不一致,也会导致中间出现切换,可能会导致 PWM 占空比发 生变化,出现类似 PWM 调压电压不够导致的死机问题等,所以要保持 U-Boot kernel 的极性和 周期一致

3、PWM Regulator PWM pin 脚上下拉配置问题

 
        由于在做 reboot 的时候,很多情况是不复位 GRF 里面的寄存器,而 PWM 控制器会发生复位,这就会在 reboot 起来后改变 PWM Regulator 的默认电压,所以要在 kernel 中配置 PWM pin 脚上下拉与默认的上下 拉一致,不能配置为 none 。该问题只针对 PWM 作为调压时才需要修改,作为其他功能可以不需要关注。
a、通过硬件原理图确认该 PWM pin 的默认上下拉。例如 RK3399 挖掘机板子 PWM2 作为调压功能, 在原理图上找到 PWM2 pin : GPIO1_C3/PWM2_d ,其中的 "d" 表示 down 为默认下拉;如果 是"u" 表示 up 默认上拉。
b、dtsi 中定义 PWM pull down pinctrl
pwm2_pin_pull_down: pwm2-pin-pull-down {
    rockchip,pins =
    <1 19 RK_FUNC_1 &pcfg_pull_down>;
};

c、 dts 中重新 PWM 覆盖 pinctrl:

&pwm2 {
    status = "okay";
    pinctrl-names = "active";
    pinctrl-0 = <&pwm2_pin_pull_down>;
};

总结

        以上为在RK3568平台上使用PWM功能的一些记录和总结,如果pwm功能不能正常使用,主要检查该路pwm是否被其他功能复用。        

猜你喜欢

转载自blog.csdn.net/qq_18376583/article/details/127929767
今日推荐