作者信息
作者: 彭東林
QQ:405728433
平臺簡介
開發板:tiny4412ADK + S700 + 4GB Flash
要移植的內核版本:Linux-4.4.0 (支持device tree)
u-boot版本:友善之臂自帶的 U-Boot 2010.12 (為支持uImage啟動,做了少許改動)
busybox版本:busybox 1.25
交叉編譯工具鏈: arm-none-linux-gnueabi-gcc
(gcc version 4.8.3 20140320 (prerelease) (Sourcery CodeBench Lite 2014.05-29))
概述
Exynos4412一共可以輸出4路PWM(timer0、timer1、timer2、timer3產生的PWM有對應的輸出引腳,timer4沒有對應的引腳),但是在tiny4412上只有兩路PWM引出供片外外設使用,分別來自timer0和timer1,其中timer0輸出的PWM0用於控制底板上的有源蜂鳴器(TMB12A05),timer1產生的PWM1用於控制LCD的背光亮度。
核心板:
底板(有源蜂鳴器):
底板(LCD背光):
下麵我們以用PWM控制蜂鳴器為例學習一下PWM子系統和backlight子系統。
實驗一、用PWM控制板子上的蜂鳴器
對應的驅動文件:drivers/pwm/pwm-samsung.c
修改設備樹文件 arch/arm/boot/dts/exynos4412-tiny4412.dts
1: diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
2: index 585cab7..0425200 100644
3: --- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
4: +++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
5: @@ -123,6 +123,13 @@
6: cap-mmc-highspeed;
7: };
8:
9: +&pwm {
10: + pinctrl-0 = <&pwm0_out &pwm1_out>;
11: + pinctrl-names = "default";
12: + samsung,pwm-outputs = <0>, <1>;
13: + status = "okay";
14: +};
15: +
16: &serial_0 {
17: status = "okay";
18: };
其中 pinctrl-0後的參數是為了設置用到的gpio的復用功能,pwm0_out是在arch/arm/boot/dts/exynos4x12-pinctrl.dtsi中定義的:
1: pwm0_out: pwm0-out {
2: samsung,pins = "gpd0-0";
3: samsung,pin-function = <2>;
4: samsung,pin-pud = <0>;
5: samsung,pin-drv = <0>;
6: };
意思是將gpiod0_0引腳設置的功能復用設置為2,2是什麼意思呢?對於Samsung來說:
這裡的2表示設置為TOUT_0,即PWM0的脈衝輸出引腳。同理可以理解pwm1_out的意思。
samsung,pwm_outs後的參數表示只有PWM0和PWM1兩路可以供板級外設使用,解析過程可以參考驅動程式。
其中pwm是在 arch/arm/boot/dts/exynos4.dtsi
1: pwm: pwm@139D0000 {
2: compatible = "samsung,exynos4210-pwm";
3: reg = <0x139D0000 0x1000>;
4: interrupts = <0 37 0>, <0 38 0>, <0 39 0>, <0 40 0>, <0 41 0>;
5: clocks = <&clock CLK_PWM>;
6: clock-names = "timers";
7: #pwm-cells = <3>;
8: status = "disabled";
9: };
測試
重新編譯設備樹:
make dtbs
用新的設備樹鏡像啟動內核
[root@tiny4412 ]# cd /sys/class/pwm/
[root@tiny4412 pwm]# ls
pwmchip0
[root@tiny4412 pwm]# cd pwmchip0/
[root@tiny4412 pwmchip0]# ls
device export npwm power subsystem uevent unexport
在/sys/class/pwm中有註冊的pwmchip0,PWM0-3都對應這個pwmchip0,是調用pwmchip_add函數創建的。
[root@tiny4412 pwmchip0]# ls
device export npwm power subsystem uevent unexport
[root@tiny4412 pwmchip0]# cat npwm
5
[root@tiny4412 pwmchip0]# echo 0 > export
[root@tiny4412 pwmchip0]# ls
device npwm pwm0 uevent
export power subsystem unexport
[root@tiny4412 pwmchip0]# cd pwm0/
[root@tiny4412 pwm0]# ls
duty_cycle enable period polarity power uevent
npwm的意思是Exynos4412支持的pwm通道個數(在驅動里將這個值設置為了5,即將timer4也包含在內了)。蜂鳴器對應的的PWM0,所以我們向export中寫入0,然後就會在當前目錄下產生了一個名為pwm0的新目錄,其中是設置PWM0參數的配置文件。
在pwm0目錄下:
polarity:接受normal或inversed兩個參數,表示TOUT_0電平翻轉;在exynos4412的用戶手冊的第24節:
period:表示pwm波的周期(單位:納秒);
duty_cycle:在normal模式下,表示一個周期內高電平持續的時間(單位:納秒),所以duty_cycle <= period;在reversed模式下,表示一個周期中低電平持續的時間(單位:納秒);
enable:向其中寫入1表示啟動pwm,寫入0,表示關閉pwm;
更多詳情請參考內核文檔:Documentation/pwm.txt
下麵分享一個判斷tiny4412底板上的蜂鳴器是有源的還是無源的方法:
首先先關閉pwm,即向enable中寫入0;然後向polarity中寫入inversed,如果蜂鳴器開始響,那麼就是有源蜂鳴器,否則就是無源蜂鳴器。原理是:關閉了pwm後,在normal下,TOUT_0輸出低電平,在inversed模式下,TOUT_0輸出高電平。(從tiny4412的原理圖中看到,pwm輸出高電平時,三極體導通,蜂鳴器開始響,有源蜂鳴器的特點是,只要給它一個高電平,就響,而無源的特點是,必須給脈衝才響)
下麵實現一個頻率為1Hz, 占空比為1:9的例子:
[root@tiny4412 ]# cd /sys/class/pwm/pwmchip0/
[root@tiny4412 pwmchip0]# ls
device export npwm power subsystem uevent unexport
[root@tiny4412 pwmchip0]# echo 0 > export
[root@tiny4412 pwmchip0]# ls
device npwm pwm0 uevent
export power subsystem unexport
[root@tiny4412 pwmchip0]# cd pwm0/
[root@tiny4412 pwm0]# ls
duty_cycle enable period polarity power uevent
[root@tiny4412 pwm0]# echo normal > polarity
[root@tiny4412 pwm0]# echo 1000000000 > period
[root@tiny4412 pwm0]# echo 100000000 > duty_cycle
[root@tiny4412 pwm0]# echo 1 > enable
[root@tiny4412 pwm0]#
這裡:1秒 = 1 000 000 000 納秒
向unexport中寫入0,pwm0目錄會被自動刪除。
[root@tiny4412 pwmchip0]# ls
device npwm pwm0 uevent
export power subsystem unexport
[root@tiny4412 pwmchip0]# echo 0 > unexport
[root@tiny4412 pwmchip0]# ls
device export npwm power subsystem uevent unexport
未完待續。