PWM使用参考

Version 1.0


1. 概述

本文描述透过提供的硬件PWM如何产生特定的波型。


2. Default PWM Pad

PWM 00 -> PAD_GPIO8

PWM 01 -> PAD_GPIO9

PWM 02 -> PAD_GPIO10

PWM 03 -> PAD_GPIO11

PWM 04 -> PAD_GPIO12

PWM 05 -> PAD_GPIO13

PWM 06 -> PAD_GPIO14

PWM 07 -> PAD_GPIO15

PWM 08 -> PAD_SD0_GPIO0

PWM 09 -> PAD_FUART_CTS


3. LINUX PWM控制


3.1. Console下控制PWM

  1. Motor hierarchy

    • Group 0

      PWM 0

      PWM 1

      PWM 2

      PWM 3

    • Group 1

      PWM 4

      PWM 5

      PWM 6

      PWM 7

    • Group 2

      PWM 8

      PWM 9

      PWM 10

  2. cd 马达控制路径

    cd /sys/devices/virtual/mstar/motor
    
  3. Set mode/period(frequency) / Begin/End / round number/enable/hold/stop

    • mode

      echo PWM_ID enable > group_mode
      

      ex :

      echo 0 1 > group_mode # 设定PWM0为马达模式
      
      echo 0 0 > group_mode # 取消PWM0为马达模式
      
    • period

      echo PWM_ID period > group_period
      

      In our driver implementation, xxxx indicates output frequency.

      ex:

      echo 0 2000 > group_period # PWM0 will generate 2kHz waveform
      
    • begin

      echo PWM_ID begin > group_begin
      

      ex:

      echo 0 10 > group_begin # PWM0 will generate duty_cycle starting
      from 10% of the period
      
    • end

      echo PWM_ID end > group_end
      

      ex:

      echo 0 25 > group_end # PWM0 will generate duty_cycle ending at 25%
      of the period
      
    • round

      echo GROUP_ID round > group_round
      

      ex:

      echo 0 10000 > group_round # Group 0 will generate 10000 period of
      waveform.
      
    • enable

      echo GROUP_ID enable > group_enable
      

      ex:

      echo 0 1 > group_enable # Group 0 start generating the waveform
      
      echo 0 0 > group_enable # Group 0 stop generating the waveform
      
    • hold

      echo GROUP_ID > group_hold
      

      ex:

      echo 0 > group_hold # Group 0 hold the last complete waveform
      
    • stop

      echo GROUP_ID > group_stop
      

      ex:

      echo 0 > group_stop # Group 0 immediately stop the waveform
      
    • duty_qe0

      echo QE0_EN > group_duty_qe0
      

      ex:

      echo 0 > group_duty_qe0 # QE0 enable/disable
      
    • hold_mode1

      echo MODE1_EN > group_hold_mode1
      

      ex:

      echo 1 > group_hold_mode1 # Mode1 enable
      

Mode 0 (keep pwm state)

在拉hold期间更改设定,且pwm值保持原始。

Mode 1 (pull low)

在拉hold期间更改设定,但pwm值数完最后一个period后会拉low。

Hold 0 会有interrupt, 这个interrupt是下了hold 0之后, 这个period结束,HW会发interrupt,然后driver在ISR里头填新的参数, 取消hold 0, 然后PWM就会产生新的参数的波型。

所以操作应如下:

红色代表是AP(用户) 的操作

蓝色代表是Driver的操作

绿色代表是HW 的行为

填参数 -> enable之后, 以下分成hold 0/1来解释

  1. Hold 0

    1. 下新的参数  (驱动先把新的参数放在内存中)-> 打开hold 0-> 一个period结束/保持最后波型 -> ( ISR ) 驱动从内存把参数回填 PWM/放开 hold 0 -> 产生新的波型
  2. Hold 1

    1. 打开Hold 1 -> 一个period结束/波形拉低 -> (AP确定period结束) 下新的参数 -> 放开Hold 1 -> 产生新的波形

3.2. Kernel driver控制PWM

#include \< linux/pwm.h>

#static struct pwm_device *mstar_pwm;

  • struct pwm_device *pwm_request(int pwm_id, const char *label)

    • pwm_request - request a PWM device
  • int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)

    • pwm_config - change a PWM device configuration
  • int pwm_enable(struct pwm_device *pwm, int duty_ns, int period_ns)

    • pwm_enable - start a PWM output toggling

sample:

  • enable PWM0(PAD_PWM0)
    static struct pwm_device *mstar_pwm;
        mstar_pwm = pwm_request(0, "MSTAR LCD");
    
        if (IS_ERR(mstar_pwm)) {
            printk("Start Unable to request PWM for LCD power!\n");
            return PTR_ERR(mstar_pwm);
        }
            pwm_config(mstar_pwm, 50, 1000);//duty=50, hz=1000
            pwm_enable(mstar_pwm);
    

4. UBOOT标准 PWM控制接口


4.1. PWM API

#include \< pwm.h>

  • int pwm_init(id, div, invert)

    - sets up the clock speed and whether or not it is inverted

  • int pwm_config(id, duty, period_ns)

    - sets up the duty and period

  • int pwm_enable(int pwm_id)

    - enables the PWM driver

  • int pwm_disable(int pwm_id)

    - disables the PWM driver

参数说明:

  • Id: 0:PWM0, 1:PWM1……7:PWM7

  • DIV: 设置范围0~65535

  • Invert: 设置范围0或1

  • Duty: 设置范围0~100

  • Period: 设置范围 2~262143 (在这边的Period指的是Hz)


4.2. PWM Reference Setting Table