当前位置:   article > 正文

mt6582 pwm_old mode与fifo mode是什么

old mode与fifo mode是什么
mt6582总共有7路PWM,6582 Android 4.4版本pwm程序为mediatek/kernel/drivers/pwm/mt_pwm.c,而lk部分的pwm程序为mediatek/platform/mt6582/lk/pwm.c,由于都是同一个平台的程序,所以这两个程序是相通的,我们只需要看一个就可以了。

pwm程序提供了两个主要的接口供外部调用,它们是pwm_set_easy_config()、pwm_set_spec_config(),那么这两个接口函数就分别对应两个结构体类型,是struct pwm_easy_config、struct pwm_spec_cofnig。这两个结构体类型定义如下:
  1. struct pwm_easy_config {
  2. U32 pwm_no;
  3. U32 duty;
  4. U32 clk_src;
  5. U32 clk_div;
  6. U16 duration;
  7. BOOL pmic_pad;
  8. };
  9. struct pwm_spec_config {
  10. U32 pwm_no;
  11. U32 mode;
  12. U32 clk_div;
  13. U32 clk_src;
  14. BOOL intr;
  15. BOOL pmic_pad;
  16. union {
  17. // for old mode
  18. struct _PWM_OLDMODE_REGS {
  19. U16 IDLE_VALUE;
  20. U16 GUARD_VALUE;
  21. U16 GDURATION;
  22. U16 WAVE_NUM;
  23. U16 DATA_WIDTH;
  24. U16 THRESH;
  25. }PWM_MODE_OLD_REGS;
  26. // for fifo mode
  27. struct _PWM_MODE_FIFO_REGS {
  28. U32 IDLE_VALUE;
  29. U32 GUARD_VALUE;
  30. U32 STOP_BITPOS_VALUE;
  31. U16 HDURATION;
  32. U16 LDURATION;
  33. U32 GDURATION;
  34. U32 SEND_DATA0;
  35. U32 SEND_DATA1;
  36. U32 WAVE_NUM;
  37. }PWM_MODE_FIFO_REGS;
  38. };
  39. };

在调用这两个接口函数之前,肯定是要先定义这两个结构体成员,并对其做初始化操作。那么这两个结构体应该怎样初始化呢,以便得到我们想要的波形,这便是本文的重点。

那么首先来看struct pwm_spec_config这个结构体。
pwm_no: pwm number,虽然mt6582有7路pwm,但是这里取值只能是PWM1~PWM5,也就是说只有5路pwm。
mode: pwm的模式,主要有两种模式old mode和fifo mode。
clk_div: 时钟分频,取值有CLK_DIV1、CLK_DIV2、CLK_DIV4、CLK_DIV8、CLK_DIV16、CLK_DIV32、CLK_DIV64、CLK_DIV128。
clk_src: 如果是old mode,那么取值只能是PWM_CLK_OLD_MODE_BLOCK、PWM_CLK_OLD_MODE_32K。如果是fifo mode,那么取值只能是PWM_CLK_NEW_MODE_BLOCK、PWM_CLK_NEW_MODE_DIV_BY_1625。
intr: 暂时不支持。
pmic_pad: 在6582平台上是无效的,设置成false(从代码里面看设不设置都没有关系,因为根本就没有使用该成员)。

接下来就要具体分析old mode和fifo mode了。

1. old mode
IDLE_VALUE: 取值有IDLE_FALSE和IDLE_TRUE,IDLE_VALUE主要是设置pwm波形输出完成之后,该gpio口输出电平高低状态,如果为false,则输出低电平,如果为true,则输出高电平。
GUARD_VALUE、GDURATION: 这里文档上面说的不是很明白,根据datasheet的意思呢GDURATION表示两个完整的pwm波形之间的时间间隔,如果为0,表示没有时间间隔,在old mode下,该值必须为0,而GUARD_VALUE为间隔时输出电平高低状态,应该同IDLE_VALUE一样,如果为false,表示输出低电平,如果为true表示输出高电平,在old mode下,忽略这两个成员就可以了。
WAVE_NUM: pwm波形次数,如果为0,只有在disable pwm时才会停止pwm波形输出。
DATA_WIDTH: 用于控制一次完整的波形输出时间,计算公式为(T = 1/(clk_src/clk_div) * (DATA_WIDTH+1)),例如clk_src选择为26MHz,clk_div选择1分频,DATA_WIDTH为99,则波形周期为T=1/(26/1) * (99+1)=3.85usec。
THRESH: 控制一次完整波形的高电平输出时间,即占空比,计算公式为(T = 1/(clk_src/clk_div) * (THRESH+1)),即如果要输出方波,那么这个值应该取值为(DATA_WIDTH+1)/2 - 1。

在old mode下,还有一点需要说明的是,clk_src如果为PWM_CLK_OLD_MODE_BLOCK,那么pwm的clock就是26MHz,如果是PWM_CLK_OLD_MODE_32K,那么实际clock应该是26MHz/1625=16KHz,不要理解错了。

2. fifo mode
fifo mode是非old mode,并且PWMx_CON的SRCSEL位应该置0,那么pwm才是fifo mode。
IDLE_VALUE: 同old mode类似。
GUARD_VALUE、GDURATION: 同上面类似。
HDURATION、LDURATION: 高低电平持续时间,计算公式为(T = 1/(clk_src/clk_div) * (VALUE+1)),例如clk_src选择为26MHz,clk_div选择1分频,HDURATION=1,那么高电平持续时间为T=1/(26/1) * (1+1)=77nsec,如果LDURATION=3,那么低电平持续时间为T=1/(26/1) * (3+1)=154nsec,需要注意的是高电平持续时间和低电平持续时间可以不同。
send_data0、send_data1: 两个32bit数据,共组成64bit数据,表示转换成二进制时,1代表高电平,0代表低电平。
STOP_BITPOS_VALUE: 在fifo mode下,实际传输的停止位,最大值为63(因为最多传输64bit),例如send_data0 = 0x0000ff11,send_data1 = 0xffffffff,如果STOP_BITPOS_VALUE=63,那么所有的bit都将被传输,波形如图所示。

如果STOP_BITPOS_VALUE=31,那么只有32bit数据被传输,也就是send_data1是被屏蔽了的,波形如图所示。
如果STOP_BITPOS_VALUE=15,那么只有16bit数据被传输,波形如图所示。
如果STOP_BITPOS_VALUE=7,那么只有8bit数据被传输,波形如图所示。
wave_num: 同上面类似。


struct pwm_spec_config这个结构看完了,那么再来看struct pwm_easy_config这个结构。
pwm_no: 同pwm_spec_config一样。
duty: pwm占空比,如果该值大于100,那么会被强制置成100。
duration: 在old mode下相当于DATA_WIDTH,即波形输出时间,计算公式为(T = (clk_src/clk_div) * duration)。
pmic_pad: 同pwm_spec_config一样。
clk_src: clk_src注意了,old mode和fifo mode取值是不一样的,pwm_set_easy_config函数就是根据这个取值来判断到底是old mode还是fifo mode的,取值同pwm_spec_config一样。
clk_div: 同pwm_spec_config一样。

需要注意的是在fifo mode下HDURATION和LDURATION值都为duration,即高电平和低电平持续时间是一样的。而duty值决定send_data0和send_data1,值越大,高电平持续时间也就越长。

通过上面可以看到,old mode就能完成大部分的需求了。

参考文档:mt6582 datasheet、PWM_Customer_Document_MT6752_MT6732.pdf

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

闽ICP备14008679号