当前位置:   article > 正文

MTK平台-如何输出80KHZ频率的PWM信号_mtk smartpa调试

mtk smartpa调试

综述

传音项目的需求,因为smartpa在调试的时候,噪音很大,原因是i2s给的时钟信号不稳定,硬件工程师说能不能尝试用pwm信号当做时钟信号,因此就学习了一下pwm的一些知识,记录下来。

[PWM]AP PWM 使用配置参数说明

** AP端PWM使用配置参数说明**

** 1. 概述**

(1)目前平台AP端一般有7路PWM:PWM0/1/2/3/4/5/6。

        其中PWM1/2/3为pin脚,其余是复用其他GPIO口的某个mode

(2)AP端PWM有5种工作模式:OLD MODE/FIFO MODE/MEMORY MODE/RANDOM MODE/SEQ MODE.

  • 只有PWM0/1/2/6可以设置为old mode,其余之外mode的设置没有限制。
  • 实际中只有old mode 和FIFO mode最为常用。其中old mode可以在系统sleep时输出PWM信号。

(3)软件只需在应用driver里面调用如下接口,正确配置参数即可得到相应的PWM信号:pwm_set_spec_config(struct pwm_spec_config *conf)

图1

**2. old mode **

old mode PWM 本质是设定波形频率和占空比

(1)关键配置参数如下:

  • pwm_no:选择需要使用的PWM NUMBER
  • mode:PWM工作模式,此处应该设为PWM_MODE_OLD
  • clk_src:选择时钟源,PWM_CLK_OLD_MODE_BLOCK(52M)或者PWM_CLK_OLD_MODE_32K(32k)
  • clk_div:分频系数,CLK_DIV1, CLK_DIV2等
  • 结构体
    struct _PWM_OLDMODE_REGS { U16 IDLE_VALUE; //idle状态下的输出电平
    U16 GUARD_VALUE; //guard duration的输出电平
    U16 GDUARTION; //guard duration,即两次完整波形间隔时间
    U16 WAVE_NUM; //输出波形数目,为0则一直传输直到PWM_EN disabled
    U16 DATA_WIDTH; //波形周期宽度
    U16 THRESH; //高电平clk数目
    }PWM_MODE_OLD_REGS;

(2)old mode的输出波形如下:

其中,

输出频率为:clk_src/clk_div/DATA_WIDTH
占空比为:THRESH/DATA_WIDTH

图2

3. FIFO mode

FIFO mode下PWM波形是按照两个32位DATA的数值输出高低电平。

(1)关键参数

  • pwm_no:选择需要使用的PWM number, 取值为0~6;
  • mode:PWM工作模式,选择PWM_MODE_FIFO;
  • clk_src:PWM_CLK_NEW_MODE_BLOCK(即PWM_BLCK)或者PWM_CLK_NEW_MODE_BLOCK_DIV_BY_1625,需要注意的是PWM_BLCK和DDR频率有关,并非完全等于code中写的52M;
  • clk_div:分频系数
  • 结构体
    struct _PWM_MODE_FIFO_REGS {
    U32 IDLE_VALUE; //idle time输出电平
    U32 GUARD_VALUE; //guard duration输出电平
    U32 STOP_BITPOS_VALUE; //停止位,决定data中输出的bit位数,取值为0~63;
    U16 HDURATION; //高电平持续的base clk数目;
    U16 LDURATION; //低电平持续的base clk数目;
    U32 GDURATION; //两个完整波形间隔时间;
    U32 SEND_DATA0; //32位DATA0数值;
    U32 SEND_DATA1; //32为DATA1数值;
    U32 WAVE_NUM; //输出波形数目,若为0则持续输出;
    }PWM_MODE_FIFO_REGS;

(2)输出波形

FIFO MODE输出波形如下:

注意HDURATION、LDURATION只对DATA数据生效,GDURATION采用base clk

图3

若持续输出,则频率计算公式为:

freq = clk_src/clk_div/(DATA高电平数目*HDURATION + DATA低电平数目*LDURATION + GDURATION)

只有输出波形为规则方波的时候才会有占空比:

duty = (DATA高电平数目*HDURATION)/(DATA高电平数目*HDURATION + DATA低电平数目*LDURATION + GDURATION), 其中,GUARD_VALUE为1

实践

步骤一,配置dws文件

dws


这里使用GPIO10,设置默认模式为PWM_C,这里的C代表2,
PWM_A 对应的pwm_no=0
PWM_B 对应的pwm_no=1
PWM_C 对应的pwm_no=2
即:pwm_no:选择需要使用的PWM number, 取值为0~6
步骤二,编写代码
在你需要的地方加入以下设置,我这里加在lcm驱动里
kernel-3.18/drivers/misc/mediatek/lcm/KR070IG1T_6953_CPT/KR070IG1T_6953_CPT.c

 

  1. #include <mt-plat/mt_pwm.h>
  2. int my_set_pwm(int pwm_num)
  3. {
  4. struct pwm_spec_config pwm_setting;
  5. memset(&pwm_setting, 0, sizeof(struct pwm_spec_config));
  6. pwm_setting.pwm_no = pwm_num;
  7. pwm_setting.mode = PWM_MODE_OLD;
  8. printk("zcf my_set_pwm pwm_no=%d\n",pwm_num);
  9. //LEDS_DEBUG("led_set_pwm: mode=%d,pwm_no=%d\n", led->nled_mode,
  10. // pwm_num);
  11. /* We won't choose 32K to be the clock src of old mode
  12. because of system performance. */
  13. /* The setting here will be clock src = 26MHz,
  14. CLKSEL = 26M/1625 (i.e. 16K) */
  15. pwm_setting.clk_src = PWM_CLK_OLD_MODE_BLOCK; //pwm_setting.pmic_pad = 0;
  16. pwm_setting.PWM_MODE_OLD_REGS.THRESH = 66;
  17. pwm_setting.clk_div = CLK_DIV1;//CLK_DIV1 = 1
  18. pwm_setting.PWM_MODE_OLD_REGS.DATA_WIDTH = 133;
  19. pwm_setting.PWM_MODE_FIFO_REGS.IDLE_VALUE = 0;
  20. pwm_setting.PWM_MODE_FIFO_REGS.GUARD_VALUE = 0;
  21. pwm_setting.PWM_MODE_FIFO_REGS.GDURATION = 0;
  22. pwm_setting.PWM_MODE_FIFO_REGS.WAVE_NUM = 0;
  23. pwm_set_spec_config(&pwm_setting);
  24. return 0;
  25. }

注意
PWM_CLK_OLD_MODE_BLOCK=26KMHZ
输出频率为:clk_src/clk_div/DATA_WIDTH
26000/1/133=195MHZ
占空比为:THRESH/DATA_WIDTH
66/133=1/2

最后在probe函数中调用my_set_pwm(2)

  1. static int lcm_probe(struct device *dev)
  2. {
  3. //省略部分源码
  4. my_set_pwm(2);//2对应pwm_c
  5. }

酱紫就可以输出pwm信号了

 

pwm信号

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/75986
推荐阅读
相关标签
  

闽ICP备14008679号