CM4_PWM使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 05/31/2024

    1. 概述

    PWM (Pulse Width Modulation) 模块用于产生脉宽波形,可通过改变频率和占空比来改变输出的电流、电压进而实现控制电机转速、液晶屏调光等功能。


    2. 功能描述

    • 支持PWM的channel数量为4个

    • channel 0~3支持的OSCCLK(Hz)为:12M;

    • 频率的工作范围是(OSCCLK/2)到(OSCCLK/2^34) ,例如OSCCLK = 12MHz,则范围是(0.0007Hz~6MHz);

    • 支持double buffer来防止产生错误波形,即波形会等待当前波形完全生成之后更新;


    3. 相关概念说明

    3.1. 频率和占空比

    • 频率(frequency)

      每秒钟信号从高电平到低电平再回到高电平的次数。

    • 占空比(duty cycle)

      高电平持续时间和低电平持续时间之间的比例。

    • 举例说明

      假设PWM的OSCCLK频率为12M,那么可设置的频率范围为:0.0007Hz~6MHz;

      设定PWM0和PWM1为频率120Hz,占空比25%的波形,且PWM1相对于PWM0有180°的相位偏移,那么各参数配置如下:

      period duty shift
      PWM0 120Hz 25% 0%
      PWM1 120Hz 75% 50%

      产生的波形如下图:

    3.2. 普通精度模式

    rtos config中不开启Support high precision calculation,则使用普通精度模式,该模式下配置PWM的period的单位为Hz,duty cycle的单位为百分比。

    假设要设置PWM0频率为10000HZ,占空比为50%,则:

    period = 10000

    duty cycle = 50

    3.3. 高精度模式

    rtos config中开启Support high precision calculation选项时,则使用高精度模式,该模式下配置PWM的period和duty_cycle均使用纳秒为单位,所以要先计算周期和占空比的值。

    假设要设置PWM0频率为10000.5HZ,占空比为49.5%,则:

    period = 10^9 ÷ 10000.5 = 99995

    duty cycle = 99995 * 49.5% = 49498

    由此可见,高精度模式的优势在于参数设定支持到小数。

    4. CM4用法介绍

    4.1 DRIVER PATH

    sc/driver/sysdriver/pwm/drv/pub/drv_pwm.h
    sc/driver/sysdriver/pwm/drv/src/drv_pwm.c
    sc/driver/sysdriver/pwm/drv/src/drv_pwm_test.c
    sc/driver/sysdriver/pwm/hal/chipname/src/hal_pwm.c
    sc/driver/sysdriver/pwm/hal/chipname/inc/hal_pwm.h
    sc/driver/sysdriver/pwm/hal/chipname/inc/hal_pwm_cfg.h
    

    4.2. CONFIG配置

    config文件位于mak/options_chipname_cm4_isw.mak

    # Feature_Name = [DRV] PWM driver support
    # Description = PWM driver support
    # Option_Selection = TRUE, FALSE
    CONFIG_PWM_SUPPORT = TRUE       //使能PWM驱动
    CONFIG_SSTAR_PWM_EXTEND = TRUE  //TRUE:高精度模式,FALSE:低精度模式
    

    4.3 SYSDESC配置

    chipname_xxx.sys文件是用于描述外设硬件属性的文件,外设节点中包含的属性值可用于外设的配置,类似Linux的设备树,该文件位于sc/driver/sysdriver/sysdesc/hal/chipname/pub:

    <pm_pwm0>
      [reg_u32_u16] 0x40003400 0x37;
      [status_u8] 1;
    
    <pm_pwm1>
      [reg_u32_u16] 0x40003440 0x37;
      [status_u8] 1;
    
    <pm_pwm2>
      [reg_u32_u16] 0x40003480 0x37;
      [status_u8] 1;
    
    <pm_pwm3>
      [reg_u32_u16] 0x400034C0 0x37;
      [status_u8] 1;
    

    pwm驱动中支持配置的属性如下表:

    属性 描述 设定值 备注
    reg_u32_u16 指定pwm bank地址 参考上文 禁止修改
    status_u8 选择是否使能驱动 1:enable;0:disable 可根据需要修改

    4.4 PADMUX配置

    CONFIG配置:CONFIG_PADMUX_SUPPORT=TRUE

    如果chipname_xxx.sys文件配置了属性<padmux>,那么PADMUX的设定直接在此配置:

    <padmux>
        [schematic_u32_u32_u32]
                  PAD_PM_PWM0   PINMUX_FOR_PM_PWM0_MODE_1    MDRV_PUSE_PWM0,
                  PAD_PM_PWM1   PINMUX_FOR_PM_PWM1_MODE_1    MDRV_PUSE_PWM1,
                  PAD_PM_PWM2   PINMUX_FOR_PM_PWM2_MODE_1    MDRV_PUSE_PWM2,
                  PAD_PM_PWM3   PINMUX_FOR_PM_PWM3_MODE_1    MDRV_PUSE_PWM3;
        [status_u8] 1;
    

    否则通过使能PADMUX驱动,在chipname-xxx-padmux.c文件配置引脚复用功能,该文件位于sc/driver/sysdriver/padmux/hal/chipname/src,只需要在对应的schematic属性添加如下内容中设定:

    pad_info_t schematic[] =
    {
          {PAD_PM_PWM0   PINMUX_FOR_PM_PWM0_MODE_1    MDRV_PUSE_PWM0},
          {PAD_PM_PWM1   PINMUX_FOR_PM_PWM1_MODE_1    MDRV_PUSE_PWM1},
          {PAD_PM_PWM2   PINMUX_FOR_PM_PWM2_MODE_1    MDRV_PUSE_PWM2},
          {PAD_PM_PWM3   PINMUX_FOR_PM_PWM3_MODE_1    MDRV_PUSE_PWM3},
    };
    

    第一列为引脚索引号,可以在sc/drivers/sysdriver/gpio/hal/chipname/pub/gpio.h中查询;

    第二列为模式定义,可以在sc/drivers/sysdriver/gpio/hal/chipname/pub/padmux.h中查询;

    第三列为引脚及搭配模式的索引名称,可以在sc/drivers/sysdriver/padmux/drv/pub/drv_puse.h中查询;

    各PWM硬件组padmux罗列

    PWM CHANNEL register addr padmod PAD PIN_NAME
    PWM0 bank 3fH offset 51H bit[2:0] 1 PAD_PM_PWM0 PM_PWM0
    2 PAD_PM_GPIO0 PM_GPIO0
    4 PAD_PM_PSPI0_DI PM_PSPI0_DI
    5 PAD_PM_GPIO12 PM_GPIO12
    PWM1 bank 3fH offset 51H bit[6:4] 1 PAD_PM_PWM1 PM_PWM1
    2 PAD_PM_GPIO1 PM_GPIO1
    3 PAD_PM_PSPI0_DO PM_PSPI0_DO
    4 PAD_PM_GPIO11 PM_GPIO11
    PWM2 bank 3fH offset 51H bit[10:8] 1 PAD_PM_PWM2 PM_PWM2
    2 PAD_PM_PSPI0_CZ PM_PSPI0_CZ
    3 PAD_PM_GPIO9 PM_GPIO9
    4 PAD_PM_I2C_CLK PM_I2C_CLK
    PWM3 bank 3fH offset 51H bit[14:12] 1 PAD_PM_PWM3 PM_PWM2
    2 PAD_PM_I2C_SDA PM_I2C_SDA
    3 PAD_PM_GPIO10 PM_GPIO10
    4 PAD_PM_PSPI0_CK PM_PSPI0_CK

    4.5 API说明

    头文件位于sc/driver/sysdriver/pwm/drv/pub/drv_pwm.h

    struct pwm_ch_cfg
    {
        u64 duty;     //设定占空比,实际占空比=duty-shift
        u64 shift;    //设定起始相位
        u64 period;   //设定周期
        u32 polarity; //极性设置:0-正常,1-极性取反
        u32 channel;  //指定channel
    };
    
    extern int drv_pwm_set_period(u32 channel, u64 period, u8 sync);
    extern int drv_pwm_set_duty(u32 channel, u64 duty, u8 sync);
    extern int drv_pwm_set_shift(u32 channel, u64 shift, u8 sync);
    extern int drv_pwm_set_polarity(u32 channel, u64 polar, u8 sync);
    extern int drv_pwm_channel_config(struct pwm_ch_cfg *pwm_ch);
    extern int drv_pwm_channel_enable(u32 channel, u8 enable);
    

    4.5.1. drv_pwm_set_period

    • 目的

      设置pwm周期。

    • 语法

      int drv_pwm_set_period(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和周期信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.2. drv_pwm_set_duty

    • 目的

      设置pwm占空比。

    • 语法

      int drv_pwm_set_duty(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和占空比信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.3. drv_pwm_set_shift

    • 目的

      设置pwm相位偏移。

    • 语法

      int drv_pwm_set_shift(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和相位偏移信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.4. drv_pwm_set_polarity

    • 目的

      设置pwm极性。

    • 语法

      int drv_pwm_set_polarity(struct pwm_ch_cfg *pwm_ch, u8 sync);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道和极性信息
      sync 1表示配置在此次接口调用后生效,0表示此次接口调用后不生效,生效需要调用drv_pwm_update_enable接口
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.5. drv_pwm_channel_config

    • 目的

      设置pwm配置。

    • 语法

      int drv_pwm_channel_config(struct pwm_ch_cfg *pwm_ch);
      
    • 参数

      参数名称 描述
      pwm_ch 用于配置pwm的通道、周期、占空比、相位偏移和极性信息
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.5.6. drv_pwm_channel_enable

    • 目的

      使能pwm配置。

    • 语法

      int drv_pwm_channel_enable(u32 channel, u8 enable);
      
    • 参数

      参数名称 描述
      channel 用于配置pwm的通道信息
      enable 1表示使能,0表示失能
    • 返回值

      结果 描述
      成功 返回0
      失败 返回负数

    4.6 DEMO

    demo源码位于sc/driver/sysdriver/pwm/drv/src/drv_pwm_test.c


    5. DEBUG方法

    5.1 PWM device不存在

    • 检查chipname.sys PWM节点的status是否为1

    • 检查config是否配置,详见4.2. CONFIG配置

    5.2 配置后PWM无波形产生

    Step1:首先确认测量的引脚是否正确:打开对应的原理图确认即可,如果没有错误的话,则进行下一步。

    Step2:确认对应的PWM mode是否生效,引脚复用失败主要有两个原因:

    原因一:该引脚没有设置为PWM mode,设置方法详见4.4 PADMUX配置

    原因二:有优先级比PWM mode更高级别的padmux mode被开启

    Step3:检查pwm相关参数是否设置成功