Ignore:
Timestamp:
Jul 17, 2016, 1:40:30 PM (4 years ago)
Author:
Punit Vara <punitvara@…>
Branches:
master
Children:
8d785f7
Parents:
612297e8
git-author:
Punit Vara <punitvara@…> (07/17/16 13:40:30)
git-committer:
Ben Gras <beng@…> (07/17/16 14:48:18)
Message:

beagle: pwm polishing

. added a README to pwm
. added select_pwmss() to select pwmss-generic registers, as opposed

to PWM-specific registers

. added pwmss_clock_en_status(), beagle_pwmss_is_running() and pwmss_tb_clock_check()
. other API improvements
. style improvements

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/arm/beagle/pwm/pwm.c

    r612297e8 r55bde66  
    88
    99/**
    10  * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
     10 * Copyright (c) 2016 Punit Vara <punitvara@gmail.com>
    1111 *
    1212 * The license and distribution terms for this file may be
     
    2525#include <bsp.h>
    2626#include <bsp/bbb-pwm.h>
     27#include <bsp/beagleboneblack.h>
    2728
    2829/* Currently these definitions are for BeagleBone Black board only
     
    3334
    3435/*
    35  * @brief This function select PWM module to be enabled
     36 * @brief This function selects EPWM module to be enabled
    3637 *
    3738 * @param pwm_id It is the instance number of EPWM of pwm sub system.
     
    3940 * @return Base Address of respective pwm instant.
    4041*/
    41 static uint32_t select_pwmss(uint32_t pwm_id)
    42 {
    43 uint32_t baseAddr=0;
    44    if (pwm_id == BBB_PWMSS0)
    45    {
    46    baseAddr = AM335X_EPWM_0_REGS;
    47    return baseAddr;
    48    }
    49    else if (pwm_id == BBB_PWMSS1)
    50    {
    51    baseAddr = AM335X_EPWM_1_REGS;
    52    return baseAddr;
    53    }
    54    else if (pwm_id == BBB_PWMSS2)
    55    {
    56    baseAddr = AM335X_EPWM_2_REGS;
    57    return baseAddr;
    58    }
    59    else
    60    {
    61    printf("Invalid PWM Id\n");
    62    return 0;   
    63    }
    64 }
    65 
    66 bool beagle_epwm_pinmux_setup(uint32_t pin_no, uint32_t pwm_id)
    67 {
    68   switch(pwm_id)  {
    69    case BBB_PWMSS2:
    70        switch(pin_no) {
    71            case BBB_P8_13_2B:
    72                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(BBB_MUX4);
    73                break;
    74            case BBB_P8_19_2A:
    75                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(BBB_MUX4);
    76                break;
    77            case BBB_P8_45_2A:
    78                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(BBB_MUX3);
    79                break;
    80            case BBB_P8_46_2B:
    81                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(BBB_MUX3);
    82                break;
    83            default :
    84                printf("Invalid pin for module 2\n");
    85                return false;
    86        }
    87        break;
    88    case BBB_PWMSS1:
    89        switch(pin_no) {
    90            case BBB_P8_34_1B:
    91                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(BBB_MUX2);
    92                break;
    93            case BBB_P8_36_1A:
    94                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(BBB_MUX2);
    95                break;
    96            case BBB_P9_14_1A:
    97                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(2)) = BBB_MUXMODE(BBB_MUX6);
    98                break;
    99            case BBB_P9_16_1B:
    100                REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(3)) = BBB_MUXMODE(BBB_MUX6);
    101                break;
    102            default :
    103                printf("Invalid pin for module 1\n");
    104                return false;
    105        }   
    106        break;
    107    case BBB_PWMSS0:
    108        switch(pin_no) {
    109            case BBB_P9_21_0B:
    110                REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(BBB_MUX3);
    111                break;
    112            case BBB_P9_22_0A:
    113                REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(BBB_MUX3);
    114                break;
    115            case BBB_P9_29_0B:
    116                REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(BBB_MUX1);
    117                break;
    118            case BBB_P9_31_0A:
    119                REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(BBB_MUX1);
    120                break;
    121            default:
    122                printf("Invalid pin for module 0\n");
    123                return false;
    124        }
    125        break;
    126    
    127    default:
    128        printf("Invalid PWM sub system\n");
    129        return false;
    130 }
     42static uint32_t select_pwm(BBB_PWMSS pwm_id)
     43{
     44  uint32_t baseAddr=0;
     45 
     46  if (pwm_id == BBB_PWMSS0) {
     47    baseAddr = AM335X_EPWM_0_REGS;
     48  } else if (pwm_id == BBB_PWMSS1) {
     49    baseAddr = AM335X_EPWM_1_REGS;
     50  } else if (pwm_id == BBB_PWMSS2) {
     51    baseAddr = AM335X_EPWM_2_REGS;
     52  } else {
     53    baseAddr = 0;
     54  }
     55  return baseAddr;     
     56}
     57
     58/*
     59 * @brief This function selects PWM Sub system to be enabled
     60 * 
     61 * @param pwmss_id  The instance number of ePWMSS whose system clocks
     62 *                  have to be configured.
     63 *
     64 * @return Base Address of respective pwmss instant.
     65*/
     66static uint32_t select_pwmss(BBB_PWMSS pwmss_id)
     67{
     68  uint32_t baseAddr=0;
     69 
     70  if (pwmss_id == BBB_PWMSS0) {
     71    baseAddr = AM335X_PWMSS0_MMAP_ADDR;
     72  } else if (pwmss_id == BBB_PWMSS1) {
     73    baseAddr = AM335X_PWMSS1_MMAP_ADDR;
     74  } else if (pwmss_id == BBB_PWMSS2) {
     75    baseAddr = AM335X_PWMSS2_MMAP_ADDR;
     76  } else {
     77    baseAddr = 0;
     78  }
     79  return baseAddr;
     80}
     81
     82bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
     83{
     84  bool is_valid = true;
     85 
     86  if(pwm_id == BBB_PWMSS0) {
     87    if (pin_no == BBB_P9_21_0B) {
     88      REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(BBB_P9_21_MUX_PWM);
     89    } else if (pin_no == BBB_P9_22_0A) {
     90      REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(BBB_P9_22_MUX_PWM);
     91    } else if (pin_no == BBB_P9_29_0B) {
     92      REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(BBB_P9_29_MUX_PWM);
     93    } else if (pin_no == BBB_P9_31_0A) {
     94      REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(BBB_P9_31_MUX_PWM);
     95    } else {
     96      is_valid = false;
     97    }
     98   
     99    } else if (pwm_id == BBB_PWMSS1) {
     100        if (pin_no == BBB_P8_34_1B) {
     101          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(BBB_P8_34_MUX_PWM);
     102        } else if (pin_no == BBB_P8_36_1A) {
     103          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(BBB_P8_36_MUX_PWM);
     104        } else if (pin_no == BBB_P9_14_1A) {
     105          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(2)) = BBB_MUXMODE(BBB_P9_14_MUX_PWM);
     106        } else if (pin_no == BBB_P9_16_1B) {
     107          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(3)) = BBB_MUXMODE(BBB_P9_16_MUX_PWM);
     108        } else {
     109          is_valid = false;
     110        }
     111   } else if (pwm_id == BBB_PWMSS2) {
     112        if (pin_no == BBB_P8_13_2B) {
     113          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(BBB_P8_13_MUX_PWM);
     114        } else if (pin_no == BBB_P8_19_2A) {
     115          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(BBB_P8_19_MUX_PWM);
     116        } else if (pin_no == BBB_P8_45_2A) {
     117          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(BBB_P8_45_MUX_PWM);
     118        } else if (pin_no == BBB_P8_46_2B) {
     119          REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(BBB_P8_46_MUX_PWM);
     120        } else {
     121          is_valid = false;
     122        }
     123  } else {
     124        is_valid = false;
     125  }
     126  return is_valid;
    131127}
    132128
     
    138134 *
    139135 * @return  true if successful
     136 *          false if unsuccessful
    140137 **/
    141 static bool pwmss_tbclk_enable(unsigned int instance)
    142 {
    143 uint32_t enable_bit;
    144 bool is_valid = true;
    145  
    146   if (instance == BBB_PWMSS0)
    147   {
    148        enable_bit = AM335X_PWMSS_CTRL_PWMSS0_TBCLKEN;
    149   }
    150   else if (instance == BBB_PWMSS1)
    151   {
     138static bool pwmss_tbclk_enable(BBB_PWMSS instance)
     139{
     140  uint32_t enable_bit;
     141  bool is_valid = true;
     142 
     143  if (instance == BBB_PWMSS0)  {
     144    enable_bit = AM335X_PWMSS_CTRL_PWMSS0_TBCLKEN;
     145  }  else if (instance == BBB_PWMSS1)  {
    152146       enable_bit = AM335X_PWMSS_CTRL_PWMSS1_TBCLKEN;
    153   }
    154   else if (instance == BBB_PWMSS2)
    155   {
     147  }  else if (instance == BBB_PWMSS2)  {
    156148       enable_bit = AM335X_PWMSS_CTRL_PWMSS2_TBCLKEN;
    157   }
    158   else
    159   {
     149  }  else  {
    160150       is_valid = false;
    161151  }
     
    163153  if (is_valid)
    164154  {
    165        REG(AM335X_PADCONF_BASE + AM335X_PWMSS_CTRL) |= enable_bit;
     155    REG(AM335X_PADCONF_BASE + AM335X_PWMSS_CTRL) |= enable_bit;
    166156  }
    167157
     
    174164 * @param   pwm_id  It is the instance number of EPWM of pwm sub system.
    175165 *
    176  * @return  None.
     166 * @return  true if successful
     167 *          false if unsuccessful
    177168 *
    178169 **/
    179 static void epwm_clock_enable(uint32_t pwm_id)
    180 
    181    if((pwm_id <3) && (pwm_id >=0)) {
    182        uint32_t baseAddr;
    183        baseAddr = select_pwmss(pwm_id);
    184                REG(baseAddr - AM335X_EPWM_REGS + AM335X_PWMSS_CLKCONFIG) |= AM335X_PWMSS_CLK_EN_ACK;
    185         } else {
    186        printf("Invalid pwm_id\n");
    187    }
     170static bool pwm_clock_enable(BBB_PWMSS pwm_id)
     171{
     172  const bool id_is_valid = pwm_id < BBB_PWMSS_COUNT;   
     173  bool status = true;
     174 
     175  if (id_is_valid) {
     176    const uint32_t baseAddr = select_pwmss(pwm_id);
     177    REG(baseAddr + AM335X_PWMSS_CLKCONFIG) |= AM335X_PWMSS_CLK_EN_ACK;
     178  }  else  {
     179       status = false;
     180  }
     181  return status;
    188182}
    189183
     
    199193 * (0 <= pwmss_id <= 2)
    200194 *
    201  * @return  None.
    202  *
     195 * @return  True if successful
     196 *          False if Unsuccessful
    203197 */
    204 static void module_clk_config(uint32_t pwmss_id)
    205 {
    206         if(pwmss_id == 0)
    207         {
    208                 REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL) |=
    209                         AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE;
    210    
    211     while(AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE !=
    212               (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL) &
    213                AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE));
    214 
    215     while((AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC <<
    216                AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT) !=
    217               (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL) &
    218                AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST));
    219         }
    220         else if(pwmss_id == 1)
    221         {
    222                 REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL) |=
    223                         AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE;
    224    while(AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE !=
    225               (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL) &
    226                AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE));
    227 
    228         while((AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC <<
    229                AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT) !=
    230                (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL) &
    231                AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST));
    232         }
    233         else if(pwmss_id == 2)
    234         {
    235                 REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL) |=
    236                         AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE;
    237    while(AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE !=
    238               (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL) &
    239                AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE));
    240 
    241         while((AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_FUNC <<
    242                AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_SHIFT) !=
    243                (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL) &
    244                 AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST));
    245         }
    246         else
    247         {
    248        printf("Please enter valid pwm Id \n");
    249         }
    250 }
    251 
    252 bool beagle_pwm_init(uint32_t pwmss_id)
    253 {
     198static bool pwmss_module_clk_config(BBB_PWMSS pwmss_id)
     199{
     200  bool is_valid = true;
     201 
     202  if(pwmss_id == BBB_PWMSS0) {
     203    const uint32_t is_functional = AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC <<
     204                         AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT;
     205    const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL;
     206    const uint32_t idle_bits = AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST;
     207    const uint32_t is_enable = AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE;
     208    const uint32_t module_mode = AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE;
     209   
     210    REG(clkctrl) |= is_enable;
     211    while((REG(clkctrl) & module_mode) != is_enable);
     212    while((REG(clkctrl) & idle_bits) != is_functional);
     213    }
     214    else if(pwmss_id == BBB_PWMSS1) {
     215    const uint32_t is_functional = AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC <<
     216                         AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT;
     217    const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL;
     218    const uint32_t idle_bits = AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST;
     219    const uint32_t is_enable = AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE;
     220    const uint32_t module_mode = AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE;
     221
     222    REG(clkctrl) |= is_enable;
     223    while((REG(clkctrl) & module_mode) != is_enable);
     224    while((REG(clkctrl) & idle_bits) != is_functional);
     225    } else if(pwmss_id == BBB_PWMSS2) {
     226    const uint32_t is_functional = AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_FUNC <<
     227                         AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_SHIFT;
     228    const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL;
     229    const uint32_t idle_bits = AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST;
     230    const uint32_t is_enable = AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE;
     231    const uint32_t module_mode = AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE;
     232
     233    REG(clkctrl) |= is_enable;
     234    while((REG(clkctrl) & module_mode) != is_enable);
     235    while((REG(clkctrl) & idle_bits) != is_functional);
     236    } else
     237        is_valid = false;
     238  return is_valid;
     239}
     240
     241bool beagle_pwm_init(BBB_PWMSS pwmss_id)
     242{
     243  const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
    254244  bool status = true;
    255   if((pwmss_id <3) && (pwmss_id >=0))
    256   {
    257   module_clk_config(pwmss_id);
    258   epwm_clock_enable(pwmss_id);
    259   pwmss_tbclk_enable(pwmss_id);
    260   return status;
    261   }
    262   else {
    263    status =false;
    264   return status;
    265   }
    266 }
    267 
    268 int beagle_pwmss_setting(uint32_t pwm_id, float pwm_freq, float dutyA, float dutyB)
    269 
     245 
     246  if(id_is_valid) {
     247    pwmss_module_clk_config(pwmss_id);
     248    pwm_clock_enable(pwmss_id);
     249    pwmss_tbclk_enable(pwmss_id);
     250  } else {
     251      status =false;
     252  }
     253  return status;
     254}
     255
     256int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
     257{
    270258  uint32_t baseAddr;
    271259  int status = 1;
    272    
    273   if(pwm_freq <= 0.5) {
    274    status =0;
    275    return status;
    276   }
    277   if(dutyA < 0.0f || dutyA > 100.0f || dutyB < 0.0f || dutyB > 100.0f) {
    278    status = 0;
    279    return status;
    280   }
    281   dutyA /= 100.0f;
    282   dutyB /= 100.0f;
    283 
    284   /*Compute necessary TBPRD*/
    285   float Cyclens = 0.0f;
    286   float Divisor =0;
    287   int i,j;
     260  float cycle = 0.0f,divisor = 0;
     261  unsigned int i,j;
    288262  const float CLKDIV_div[] = {1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0};
    289263  const float HSPCLKDIV_div[] = {1.0, 2.0, 4.0, 6.0, 8.0, 10.0,12.0, 14.0};
    290   int NearCLKDIV =7;
    291   int NearHSPCLKDIV =7;
    292   int NearTBPRD =0;
    293 
     264  int NearCLKDIV =7,NearHSPCLKDIV =7,NearTBPRD =0;
     265 
     266  if (pwm_freq <= BBB_PWM_FREQ_THRESHOLD) {
     267    status =0;
     268  }
     269 
     270  if (duty_a < 0.0f || duty_a > 100.0f || duty_b < 0.0f || duty_b > 100.0f) {
     271    status = 0;
     272  }
     273  duty_a /= 100.0f;
     274  duty_b /= 100.0f;
     275 
    294276  /** 10^9 /Hz compute time per cycle (ns) */
    295   Cyclens = 1000000000.0f / pwm_freq;
     277  cycle = 1000000000.0f / pwm_freq;
    296278
    297279  /** am335x provide (128* 14) divider and per TBPRD means 10ns when divider
    298280    * and max TBPRD is 65535 so max cycle is 128 * 8 * 14 * 65535 * 10ns */
    299   Divisor = (Cyclens / 655350.0f);
    300    
    301   if(Divisor > (128 * 14)) {
    302    printf("Can't generate %f HZ",pwm_freq);
    303    return 0;
     281  divisor = (cycle / 655350.0f);
     282  if (divisor > (128 * 14)) {
     283    return 0;
    304284  }
    305285  else {
    306    for (i=0;i<8;i++) {
    307        for(j=0 ; j<8; j++) {
    308            if((CLKDIV_div[i] * HSPCLKDIV_div[j]) < (CLKDIV_div[NearCLKDIV]
    309                        * HSPCLKDIV_div[NearHSPCLKDIV]) && (CLKDIV_div[i] * HSPCLKDIV_div[j] > Divisor)) {
    310                NearCLKDIV = i;
    311                NearHSPCLKDIV = j;
    312            }
    313        }
    314    }
    315   baseAddr = select_pwmss(pwm_id);
     286    for (i=0;i<8;i++) {
     287      for(j=0 ; j<8; j++) {
     288        if((CLKDIV_div[i] * HSPCLKDIV_div[j]) < (CLKDIV_div[NearCLKDIV]
     289                            * HSPCLKDIV_div[NearHSPCLKDIV]) && (CLKDIV_div[i] * HSPCLKDIV_div[j] > divisor)) {
     290          NearCLKDIV = i;
     291          NearHSPCLKDIV = j;
     292         }
     293      }
     294    }
     295 
     296  baseAddr = select_pwm(pwm_id);
     297 
    316298  REG16(baseAddr + AM335X_EPWM_TBCTL) &= ~(AM335X_TBCTL_CLKDIV_MASK | AM335X_TBCTL_HSPCLKDIV_MASK);
    317            
    318   REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
    319   (~AM335X_EPWM_TBCTL_CLKDIV)) | ((NearCLKDIV
     299  const uint16_t clkdiv_clear = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
     300  (~AM335X_EPWM_TBCTL_CLKDIV));
     301  const uint16_t clkdiv_write = ((NearCLKDIV
    320302  << AM335X_EPWM_TBCTL_CLKDIV_SHIFT) & AM335X_EPWM_TBCTL_CLKDIV);
    321 
    322   REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
    323   (~AM335X_EPWM_TBCTL_HSPCLKDIV)) | ((NearHSPCLKDIV <<
     303  REG16(baseAddr + AM335X_EPWM_TBCTL) = clkdiv_clear | clkdiv_write;
     304  const uint16_t hspclkdiv_clear =  (REG16(baseAddr + AM335X_EPWM_TBCTL) &
     305  (~AM335X_EPWM_TBCTL_HSPCLKDIV));
     306  const uint16_t hspclkdiv_write = ((NearHSPCLKDIV <<
    324307  AM335X_EPWM_TBCTL_HSPCLKDIV_SHIFT) & AM335X_EPWM_TBCTL_HSPCLKDIV);
    325 
    326   NearTBPRD = (Cyclens / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV]));
    327        
    328   REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
    329   (~AM335X_EPWM_PRD_LOAD_SHADOW_MASK)) | (((bool)AM335X_EPWM_SHADOW_WRITE_DISABLE <<
     308  REG16(baseAddr + AM335X_EPWM_TBCTL) = hspclkdiv_clear | hspclkdiv_write;
     309  NearTBPRD = (cycle / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV]));
     310  const uint16_t shadow_mask =  (REG16(baseAddr + AM335X_EPWM_TBCTL) &
     311  (~AM335X_EPWM_PRD_LOAD_SHADOW_MASK));
     312  const uint16_t shadow_disable = (((bool)AM335X_EPWM_SHADOW_WRITE_DISABLE <<
    330313  AM335X_EPWM_TBCTL_PRDLD_SHIFT) & AM335X_EPWM_PRD_LOAD_SHADOW_MASK);
    331 
    332   REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
    333   (~AM335X_EPWM_COUNTER_MODE_MASK)) | (((unsigned int)AM335X_EPWM_COUNT_UP <<
     314  REG16(baseAddr + AM335X_EPWM_TBCTL) = shadow_mask | shadow_disable;
     315  const uint16_t counter_mask = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
     316  (~AM335X_EPWM_COUNTER_MODE_MASK));
     317  const uint16_t counter_shift = (((unsigned int)AM335X_EPWM_COUNT_UP <<
    334318  AM335X_TBCTL_CTRMODE_SHIFT) &  AM335X_EPWM_COUNTER_MODE_MASK);
    335 
     319  REG16(baseAddr + AM335X_EPWM_TBCTL) = counter_mask | counter_shift;
    336320  /*setting clock divider and freeze time base*/
    337   REG16(baseAddr + AM335X_EPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * dutyB);
    338   REG16(baseAddr + AM335X_EPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * dutyA);
     321  REG16(baseAddr + AM335X_EPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * duty_b);
     322  REG16(baseAddr + AM335X_EPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * duty_a);
    339323  REG16(baseAddr + AM335X_EPWM_TBPRD) = (unsigned short)NearTBPRD;
    340324  REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
     
    343327}
    344328
    345 bool beagle_ehrpwm_enable(uint32_t pwmid)
    346 {
     329bool beagle_pwm_enable(BBB_PWMSS pwmid)
     330{
     331  const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
    347332  bool status = true;
    348   uint32_t baseAddr;
    349   if((pwmid<3) && (pwmid >=0)) {
    350   baseAddr = select_pwmss(pwmid);
    351   REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XAHIGH | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
    352   REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLB_ZRO_XBHIGH | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
    353   REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
    354   REG16(baseAddr + AM335X_EPWM_TBCTL) |=  AM335X_TBCTL_FREERUN  | AM335X_TBCTL_CTRMODE_UP;
    355   return status;
    356   }
    357   else {
    358    status =false;
    359    return status;
    360   }
    361 }
    362 
    363 bool beagle_ehrpwm_disable(uint32_t pwmid)
    364 {
     333 
     334  if (id_is_valid)  {
     335    const uint32_t baseAddr = select_pwm(pwmid);
     336  /* Initially set EPWMxA o/p high , when increasing counter = CMPA toggle o/p of EPWMxA */
     337    REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XAHIGH | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
     338  /* Initially set EPWMxB o/p high , when increasing counter = CMPA toggle o/p of EPWMxB */ 
     339    REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLB_ZRO_XBHIGH | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
     340    REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
     341  /* Set counter mode : Up-count mode */
     342    REG16(baseAddr + AM335X_EPWM_TBCTL) |=  AM335X_TBCTL_FREERUN  | AM335X_TBCTL_CTRMODE_UP;
     343  }  else  {
     344       status =false;
     345  }
     346  return status;       
     347}
     348
     349bool beagle_pwm_disable(BBB_PWMSS pwmid)
     350{
     351  const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
    365352  bool status = true;
    366   uint32_t baseAddr;
    367   if((pwmid<3) && (pwmid >=0)) {
    368   baseAddr = select_pwmss(pwmid);
    369   REG16(baseAddr + AM335X_EPWM_TBCTL) = AM335X_EPWM_TBCTL_CTRMODE_STOPFREEZE;
    370   REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XALOW | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
    371   REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLA_ZRO_XBLOW | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
    372   REG16(baseAddr + AM335X_EPWM_TBCNT)  = 0;
    373   return status;
    374   }
    375   else {
    376    status = false;
    377    return status;
    378   }
     353 
     354  if (id_is_valid) {
     355    const uint32_t baseAddr = select_pwm(pwmid);
     356    REG16(baseAddr + AM335X_EPWM_TBCTL) = AM335X_EPWM_TBCTL_CTRMODE_STOPFREEZE;
     357    REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XALOW | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
     358    REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLA_ZRO_XBLOW | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
     359    REG16(baseAddr + AM335X_EPWM_TBCNT)  = 0;
     360  }  else  {
     361        status = false;
     362  }
     363  return status;
     364}
     365
     366/**
     367 * @brief   This functions determines whether time base clock is enabled for EPWMSS
     368 *
     369 * @param   pwmss_id  The instance number of ePWMSS whose time base clock need to
     370 *                    be checked
     371 *                   
     372 * @return  returns 4 for PWMSS_ID = 2
     373 *          returns 2 for PWMSS_ID = 1
     374 *          returns 1 for PWMSS_ID = 0
     375 **/
     376static int pwmss_tb_clock_check(unsigned int pwmss_id)
     377{
     378  unsigned int reg_value;
     379
     380  /*control module check*/
     381  reg_value = REG(AM335X_CONTROL_MODULE + AM335X_PWMSS_CTRL);
     382  return (reg_value & (1 << pwmss_id));
     383}
     384
     385/**
     386 * @brief   This functions determines whether clock for EPWMSS is enabled or not.
     387 *
     388 * @param   It is the Memory address of the PWMSS instance used.
     389 *
     390 * @return 
     391 *
     392 **/
     393static unsigned int pwmss_clock_en_status(unsigned int pwmid)
     394{
     395  unsigned int status;
     396  const uint32_t baseAddr = select_pwmss(pwmid);
     397 
     398  status = REG(baseAddr + AM335X_PWMSS_CLKSTATUS);
     399  status = status >> 8 & 0x1;
     400  return status;
     401}
     402
     403bool beagle_pwmss_is_running(unsigned int pwmss_id)
     404{
     405  const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
     406  bool status=true;
     407 
     408  if (id_is_valid) {
     409    status = pwmss_clock_en_status(pwmss_id);
     410    if(status){
     411    status = pwmss_tb_clock_check(pwmss_id);
     412    } else {
     413        status = false;
     414    } 
     415  } else {
     416  status = false;
     417  }
     418  return status;
    379419}
    380420
     
    388428 * Later on support can be added here.
    389429 */
    390 uint32_t select_pwmss(uint32_t pwm_id)
    391 {
    392 return -1;
    393 }
    394 bool pwmss_tbclk_enable(unsigned int instance)
     430bool beagle_pwm_init(BBB_PWMSS pwmss_id)
     431{
     432  return false;
     433}
     434bool beagle_pwm_disable(BBB_PWMSS pwmid)
     435{
     436  return false;
     437}
     438bool beagle_pwm_enable(BBB_PWMSS pwmid)
     439{
     440  return false;
     441}
     442int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
     443{
     444  return -1;
     445}
     446bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
     447{
     448  return false;
     449}
     450bool beagle_pwmss_is_running(unsigned int pwmss_id)
    395451{
    396452return false;
    397453}
    398 bool beagle_pwm_init(uint32_t pwmss_id)
    399 {
    400 return false;
    401 }
    402 bool beagle_ehrpwm_disable(uint32_t pwmid)
    403 {
    404 return false;
    405 }
    406 bool beagle_ehrpwm_enable(uint32_t pwmid)
    407 {
    408 return false;
    409 }
    410 int beagle_pwmss_setting(uint32_t pwm_id, float pwm_freq, float dutyA, float dutyB)
    411 {
    412 return -1;
    413 }
    414 bool beagle_epwm_pinmux_setup(uint32_t pin_no, uint32_t pwm_id)
    415 {
    416 return false;
    417 }
    418 
    419454#endif
Note: See TracChangeset for help on using the changeset viewer.