赞
踩
- struct pwm_easy_config {
- U32 pwm_no;
- U32 duty;
- U32 clk_src;
- U32 clk_div;
- U16 duration;
- BOOL pmic_pad;
- };
-
- struct pwm_spec_config {
- U32 pwm_no;
- U32 mode;
- U32 clk_div;
- U32 clk_src;
- BOOL intr;
- BOOL pmic_pad;
-
- union {
- // for old mode
- struct _PWM_OLDMODE_REGS {
- U16 IDLE_VALUE;
- U16 GUARD_VALUE;
- U16 GDURATION;
- U16 WAVE_NUM;
- U16 DATA_WIDTH;
- U16 THRESH;
- }PWM_MODE_OLD_REGS;
-
- // for fifo mode
- struct _PWM_MODE_FIFO_REGS {
- U32 IDLE_VALUE;
- U32 GUARD_VALUE;
- U32 STOP_BITPOS_VALUE;
- U16 HDURATION;
- U16 LDURATION;
- U32 GDURATION;
- U32 SEND_DATA0;
- U32 SEND_DATA1;
- U32 WAVE_NUM;
- }PWM_MODE_FIFO_REGS;
- };
- };
在调用这两个接口函数之前,肯定是要先定义这两个结构体成员,并对其做初始化操作。那么这两个结构体应该怎样初始化呢,以便得到我们想要的波形,这便是本文的重点。
那么首先来看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
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。