[PATCH] beagle: pwm polishing

Ben Gras beng at shrike-systems.com
Sun Jul 17 13:59:36 UTC 2016


From: Punit Vara <punitvara at gmail.com>

	. added a README to pwm
	. added select_pwmss() to select pwmss-generic registers, as opposed
	  to PWM-specific registers
	. added pwmss_clock_en_status() and pwmss_tb_clock_check()
	. other API improvements
	. style improvements
---
 c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h | 113 ++++--
 c/src/lib/libbsp/arm/beagle/preinstall.am     |   4 +
 c/src/lib/libbsp/arm/beagle/pwm/README        | 197 +++++++++
 c/src/lib/libbsp/arm/beagle/pwm/pwm.c         | 563 ++++++++++++++------------
 4 files changed, 568 insertions(+), 309 deletions(-)
 create mode 100644 c/src/lib/libbsp/arm/beagle/pwm/README

diff --git a/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h b/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h
index ef016f0..cf5d6fe 100644
--- a/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h
+++ b/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h
@@ -3,11 +3,11 @@
  *
  * @ingroup arm_beagle
  *
- * @brief BeagleBone Black BSP definitions.
+ * @brief BeagleBone Black PWM support definitions.
  */
 
 /**
- * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
+ * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
  *
  * The license and distribution terms for this file may be
  * found in the file LICENSE in this distribution or at
@@ -31,43 +31,53 @@ extern "C" {
 #define BBB_CONTROL_CONF_GPMC_AD(n)   (0x800 + (n * 4))
 #define BBB_CONTROL_CONF_LCD_DATA(n)   (0x8a0 + (n * 4))
 
-#define BBB_PWMSS_COUNT       3
-#define BBB_PWMSS0  0
-#define BBB_PWMSS1  1  
-#define BBB_PWMSS2  2
-
-#define BBB_P8_13_2B  3
-#define BBB_P8_19_2A  4
-#define BBB_P8_45_2A  5
-#define BBB_P8_46_2B  6
-#define BBB_P8_34_1B  7
-#define BBB_P8_36_1A  8
-#define BBB_P9_14_1A  9
-#define BBB_P9_16_1B  10
-#define BBB_P9_21_0B  11
-#define BBB_P9_22_0A  12
-#define BBB_P9_29_0B  13
-#define BBB_P9_31_0A  14
-
-#define BBB_MUX0      0
-#define BBB_MUX1      1
-#define BBB_MUX2      2
-#define BBB_MUX3      3
-#define BBB_MUX4      4
-#define BBB_MUX5      5
-#define BBB_MUX6      6
-#define BBB_MUX7      7
-
-#define BBB_EPWM1     1
-#define BBB_EPWM2     2
-#define BBB_EPWM0     0
+/**
+ * @brief The set of possible PWM subsystem module
+ *
+ * Enumerated type to define various instance of pwm module.
+ */
+typedef enum{
+  BBB_PWMSS0 = 0,
+  BBB_PWMSS1,
+  BBB_PWMSS2,
+  BBB_PWMSS_COUNT
+}BBB_PWMSS;
+
+typedef enum{
+  BBB_P8_13_2B = 3,
+  BBB_P8_19_2A,
+  BBB_P8_45_2A,
+  BBB_P8_46_2B,
+  BBB_P8_34_1B,
+  BBB_P8_36_1A,
+  BBB_P9_14_1A,
+  BBB_P9_16_1B,
+  BBB_P9_21_0B,
+  BBB_P9_22_0A,
+  BBB_P9_29_0B,
+  BBB_P9_31_0A
+}bbb_pwm_pin_t;
+
+#define BBB_P8_13_MUX_PWM 4 
+#define BBB_P8_19_MUX_PWM 4
+#define BBB_P8_45_MUX_PWM 3
+#define BBB_P8_46_MUX_PWM 3
+#define BBB_P8_34_MUX_PWM 2
+#define BBB_P8_36_MUX_PWM 2
+#define BBB_P9_14_MUX_PWM 6
+#define BBB_P9_16_MUX_PWM 6
+#define BBB_P9_21_MUX_PWM 3
+#define BBB_P9_22_MUX_PWM 3
+#define BBB_P9_29_MUX_PWM 1
+#define BBB_P9_31_MUX_PWM 1
+#define BBB_PWM_FREQ_THRESHOLD 0.5f
 
 /**
  * @brief  BeagleBone Black PWM API.
  */
 
 /**
- * @brief This function intilize clock and pinmuxing for pwm sub system.
+ * @brief This function intilizes clock for pwm sub system.
  *
  * @param PWMSS_ID It is the instance number of EPWM of pwm sub system.
  * 
@@ -75,20 +85,20 @@ extern "C" {
  * @return false if not successful
  *
  **/
-bool beagle_pwm_init(uint32_t pwmss_id);
+bool beagle_pwm_init(BBB_PWMSS pwmss_id);
 
 /* PWMSS setting
  *      set pulse argument of epwm module
  *
  *      @param pwm_id    : EPWMSS number , 0~2
  *      @param pwm_freq : frequency to be generated
- *      @param dutyA    : Duty Cycle in ePWM A
- *      @param dutyB    : Duty Cycle in ePWM B
+ *      @param dutyA    : Duty Cycle(in percentage) in PWM channel A
+ *      @param dutyB    : Duty Cycle(in percentage) in PWM channel B
  *
  *      @return         : 1 for success
  *      @return         : 0 for failed
  *
- *      @example        :  PWMSS_Setting(0 , 50.0f , 50.0f , 25.0f);      // Generate 50HZ pwm in PWM0 ,
+ *      @example        :  beagle_pwm_configure(0 , 50.0f , 50.0f , 25.0f);      // Generate 50HZ pwm in PWM0 ,
  *                                                                              // duty cycle is 50% for ePWM0A , 25% for ePWM0B
  *
  *      @Note :
@@ -105,12 +115,12 @@ bool beagle_pwm_init(uint32_t pwmss_id);
  *              Divisor = CLKDIV * HSPCLKDIV
  *                      1 TBPRD : 10 ns (default)
  *                      65535 TBPRD : 655350 ns
- *                      65535 TBPRD : 655350 * Divisor ns  = X TBPRD : Cyclens
+ *                      65535 TBPRD : 655350 * Divisor ns  = X TBPRD : Cycle
  *
  *              accrooding to that , we must find a Divisor value , let X nearest 65535 .
- *              so , Divisor must  Nearest Cyclens/655350
+ *              so , Divisor must  Nearest Cycle/655350
  */
-int beagle_pwmss_setting(uint32_t pwm_id, float pwm_freq, float dutyA, float dutyB);
+int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b);
 
 /**
  * @brief   This API enables the particular PWM module.
@@ -121,10 +131,10 @@ int beagle_pwmss_setting(uint32_t pwm_id, float pwm_freq, float dutyA, float dut
  * @return  false if fail
  *
  **/
-bool beagle_ehrpwm_enable(uint32_t pwmid);
+bool beagle_pwm_enable(BBB_PWMSS pwmid);
 
 /**
- * @brief   This API disables the HR sub-module.
+ * @brief   This API disables the particular PWM module.
  *
  * @param   pwmid  It is the instance number of EPWM of pwm sub system.
  *
@@ -132,10 +142,10 @@ bool beagle_ehrpwm_enable(uint32_t pwmid);
  * @return  false if fail
  *
  **/
-bool beagle_ehrpwm_disable(uint32_t pwmid);
+bool beagle_pwm_disable(BBB_PWMSS pwmid);
 
 /**
- * @brief   This function Enables pinmuxing for PWM module.
+ * @brief   This function enables pinmuxing for PWM module.
  *
  * @param   pin_no  It is individual pin at which freuqency need to be generated.
  *                  It should be according to pwm sub system.
@@ -146,7 +156,20 @@ bool beagle_ehrpwm_disable(uint32_t pwmid);
  * @return  false if fail
  *
  **/
-bool beagle_epwm_pinmux_setup(uint32_t pin_no, uint32_t pwm_id);
+bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id);
+
+/**
+ * @brief   This function determines whether PWMSS-wide clocks enabled or not.
+ *
+ * @param   pwmss_id  It is the instance number of PWMSS which clocks need to be
+ *                    checked.
+ * 
+ * @return  true if successful
+ * @return  false if fail
+ *
+ **/
+bool beagle_pwmss_is_running(unsigned int pwmss_id);
+
 
 #ifdef __cplusplus
 }
diff --git a/c/src/lib/libbsp/arm/beagle/preinstall.am b/c/src/lib/libbsp/arm/beagle/preinstall.am
index 3701a2b..8a7ff8b 100644
--- a/c/src/lib/libbsp/arm/beagle/preinstall.am
+++ b/c/src/lib/libbsp/arm/beagle/preinstall.am
@@ -118,6 +118,10 @@ $(PROJECT_INCLUDE)/bsp/bbb-gpio.h: include/bbb-gpio.h $(PROJECT_INCLUDE)/bsp/$(d
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bbb-gpio.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bbb-gpio.h
 
+$(PROJECT_INCLUDE)/bsp/bbb-pwm.h: include/bbb-pwm.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
+	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/bbb-pwm.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/bbb-pwm.h
+
 $(PROJECT_INCLUDE)/libcpu/arm-cp15.h: ../../../libcpu/arm/shared/include/arm-cp15.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
 	$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
 PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/arm-cp15.h
diff --git a/c/src/lib/libbsp/arm/beagle/pwm/README b/c/src/lib/libbsp/arm/beagle/pwm/README
new file mode 100644
index 0000000..d41f5ca
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/pwm/README
@@ -0,0 +1,197 @@
+Pulse Width Modulation subsystem includes EPWM, ECAP , EQEP. There are
+different instances available for each one. For PWM there are three
+different individual EPWM module 0 , 1 and 2. So wherever pwmss word is
+used that affects whole PWM sub system such as EPWM, ECAP and EQEP. This code
+has only implementation Non high resolution PWM module. APIs for high
+resolution PWM has been yet to develop.
+
+For Each EPWM instance, has two PWM channels, e.g. EPWM0 has two channel
+EPWM0A and EPWM0B. If you configure two PWM outputs(e.g. EPWM0A , EPWM0B)
+in the same device, then they *must* be configured with the same frequency.
+Changing frequency on one channel (e.g EPWMxA) will automatically change
+frequency on another channel(e.g. EPWMxB). However, it is possible to set
+different pulse-width/duty cycle to different channel at a time. So always
+set the frequency first and then pulse-width/duty cycle.
+
+For more you can refer :
+http://www.ofitselfso.com/BBBCSIO/Source/PWMPortEnum.cs.html
+ 
+Pulse Width Modulation uses the system frequency of Beagle Bone Black.
+
+System frequency = SYSCLKOUT, that is, CPU clock. TBCLK = SYSCLKOUT(By Default)
+SYCLKOUT = 100 MHz
+
+Please visit following link to check why SYSCLKDIV = 100MHz:
+https://groups.google.com/forum/#!topic/beagleboard/Ed2J9Txe_E4
+(Refer Technical Reference Manual (TRM) Table 15-41 as well)
+
+To generate different frequencies with the help of PWM module , SYSCLKOUT
+need to be scaled down, which will act as TBCLK and TBCLK will be base clock
+for the pwm subsystem.
+
+TBCLK = SYSCLKOUT/(HSPCLKDIV * CLKDIV)
+
+                 |----------------| 
+                 |     clock      | 
+ SYSCLKOUT--->   |                |---> TBCLK 
+                 |   prescale     |
+                 |----------------|         
+                   ^           ^
+                   |           |
+ TBCTL[CLKDIV]-----            ------TBCTL[HSPCLKDIV]
+
+
+CLKDIV and HSPCLKDIV bits are part of the TBCTL register (Refer TRM).
+CLKDIV - These bits determine part of the time-base clock prescale value.
+Please use the following values of CLKDIV to scale down sysclk respectively.
+0h (R/W) = /1 
+1h (R/W) = /2
+2h (R/W) = /4
+3h (R/W) = /8
+4h (R/W) = /16
+5h (R/W) = /32
+6h (R/W) = /64
+7h (R/W) = /128
+
+These bits determine part of the time-base clock prescale value.
+Please use following value of HSPCLKDIV to scale down sysclk respectively
+0h (R/W) = /1
+1h (R/W) = /2
+2h (R/W) = /4
+3h (R/W) = /6
+4h (R/W) = /8
+5h (R/W) = /10
+6h (R/W) = /12
+7h (R/W) = /14
+
+For example, if you set CLKDIV = 3h and HSPCLKDIV= 2h Then
+SYSCLKOUT will be divided by (1/8)(1/4). It means SYSCLKOUT/32
+
+How to generate frequency ?
+
+freq = 1/Period
+
+TBPRD register is responsible to generate the frequency. These bits determine
+the period of the time-base counter.
+
+By default TBCLK = SYSCLKOUT = 100 MHz
+
+Here by default period is 1/100MHz = 10 nsec
+
+Following example shows value to be loaded into TBPRD
+ 
+e.g. TBPRD = 1 = 1 count
+  count x Period = 1 x 1ns = 1ns
+  freq = 1/Period = 1 / 1ns = 100 MHz
+
+For duty cycle CMPA and CMPB are the responsible registers.
+
+To generate single with 50% Duty cycle & 100MHz freq.
+ 
+ CMPA = count x Duty Cycle
+       = TBPRD x Duty Cycle
+       = 1 x 50/100
+       = 0.2
+
+The value in the active CMPA register is continuously compared to
+the time-base counter (TBCNT). When the values are equal, the
+counter-compare module generates a "time-base counter equal to
+counter compare A" event. This event is sent to the action-qualifier
+where it is qualified and converted it into one or more actions.
+These actions can be applied to either the EPWMxA or the
+EPWMxB output depending on the configuration of the AQCTLA and
+AQCTLB registers.
+ 
+List of pins for that can be used for different PWM instance :
+
+  ------------------------------------------------ 
+  |  EPWM2        | EPWM1         | EPWM0        |
+  ------------------------------------------------
+  |  BBB_P8_13_2B | BBB_P8_34_1B  | BBB_P9_21_0B |  
+  |  BBB_P8_19_2A | BBB_P8_36_1A  | BBB_P9_22_0A |
+  |  BBB_P8_45_2A | BBB_P9_14_1A  | BBB_P9_29_0B |
+  |  BBB_P8_46_2B | BBB_P9_16_1B  | BBB_P9_31_0A |
+  ------------------------------------------------
+BBB_P8_13_2B represents P8 Header , pin number 13 , 2nd PWM instance and B channel. 
+
+Following sample program can be used to generate 7 Hz frequency.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+#include <bsp.h>
+#include <bsp/gpio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <bsp/bbb-pwm.h>
+
+const char rtems_test_name[] = "Testing PWM driver";
+rtems_printer rtems_test_printer;
+
+static void inline delay_sec(int sec)
+{
+  rtems_task_wake_after(sec*rtems_clock_get_ticks_per_second());
+}  
+
+rtems_task Init(rtems_task_argument argument);
+
+rtems_task Init(
+	rtems_task_argument ignored
+)
+{
+  rtems_test_begin(); 
+  printf("Starting PWM Testing");
+  
+  /*Initialize GPIO pins in BBB*/
+  rtems_gpio_initialize();
+  
+  /* Set P9 Header , 21 Pin number , PWM B channel and 0 PWM instance to generate frequency*/ 
+  beagle_epwm_pinmux_setup(BBB_P9_21_0B,BBB_PWMSS0);
+  
+/** Initialize clock for PWM sub system
+  * Turn on time base clock for PWM o instance
+  */
+  beagle_pwm_init(BBB_PWMSS0);
+
+  float PWM_HZ = 7.0f ;           /* 7 Hz */
+  float duty_A = 20.0f ;          /* 20% Duty cycle for PWM 0_A output */
+  const float duty_B = 50.0f ;    /* 50% Duty cycle for PWM 0_B output*/
+  
+  /*Note: Always check whether pwmss clocks are enabled or not before configuring PWM*/
+  bool is_running = beagle_pwmss_is_running(BBB_PWMSS2);
+  
+  if(is_running) {
+  
+  /*To analyse the two different duty cycle Output should be observed at P8_45 and P8_46 pin number */
+  beagle_pwm_configure(BBB_PWMSS0, PWM_HZ ,duty_A , duty_B);
+  printf("PWM  enable for 10s ....\n");
+ 
+  /*Set Up counter and enable pwm module */
+  beagle_pwm_enable(BBB_PWMSS0);
+  delay_sec(10);
+  
+  /*freeze the counter and disable pwm module*/
+  beagle_epwm_disable(BBB_PWMSS0);
+  }
+}
+
+/* NOTICE: the clock driver is enabled */
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS            1
+#define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES    1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE 
+
+#define CONFIGURE_EXTRA_TASK_STACKS         (2 * RTEMS_MINIMUM_STACK_SIZE)
+
+#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
+
diff --git a/c/src/lib/libbsp/arm/beagle/pwm/pwm.c b/c/src/lib/libbsp/arm/beagle/pwm/pwm.c
index 3b9716e..0bc5d12 100644
--- a/c/src/lib/libbsp/arm/beagle/pwm/pwm.c
+++ b/c/src/lib/libbsp/arm/beagle/pwm/pwm.c
@@ -7,7 +7,7 @@
  */
 
 /**
- * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
+ * Copyright (c) 2016 Punit Vara <punitvara at gmail.com>
  *
  * The license and distribution terms for this file may be
  * found in the file LICENSE in this distribution or at
@@ -24,6 +24,7 @@
 #include <bsp/bbb-gpio.h>
 #include <bsp.h>
 #include <bsp/bbb-pwm.h>
+#include <bsp/beagleboneblack.h>
 
 /* Currently these definitions are for BeagleBone Black board only
  * Later on Beagle-xM board support can be added in this code.
@@ -32,102 +33,97 @@
 #if IS_AM335X
 
 /*
- * @brief This function select PWM module to be enabled
+ * @brief This function selects EPWM module to be enabled
  * 
  * @param pwm_id It is the instance number of EPWM of pwm sub system.
  * 
  * @return Base Address of respective pwm instant.
 */
-static uint32_t select_pwmss(uint32_t pwm_id)
+static uint32_t select_pwm(BBB_PWMSS pwm_id)
 {
-uint32_t baseAddr=0;
-   if (pwm_id == BBB_PWMSS0)
-   {
-   baseAddr = AM335X_EPWM_0_REGS;
-   return baseAddr;
-   }
-   else if (pwm_id == BBB_PWMSS1)
-   {
-   baseAddr = AM335X_EPWM_1_REGS;
-   return baseAddr;
-   } 
-   else if (pwm_id == BBB_PWMSS2)
-   {
-   baseAddr = AM335X_EPWM_2_REGS;
-   return baseAddr;
-   }
-   else 
-   {
-   printf("Invalid PWM Id\n");
-   return 0;   
-   }
+  uint32_t baseAddr=0;
+  
+  if (pwm_id == BBB_PWMSS0) {
+    baseAddr = AM335X_EPWM_0_REGS;
+  } else if (pwm_id == BBB_PWMSS1) {
+    baseAddr = AM335X_EPWM_1_REGS;
+  } else if (pwm_id == BBB_PWMSS2) {
+    baseAddr = AM335X_EPWM_2_REGS;
+  } else {
+    baseAddr = 0;
+  }
+  return baseAddr;	
 }
 
-bool beagle_epwm_pinmux_setup(uint32_t pin_no, uint32_t pwm_id)
+/*
+ * @brief This function selects PWM Sub system to be enabled
+ *  
+ * @param pwmss_id  The instance number of ePWMSS whose system clocks
+ *                  have to be configured.
+ * 
+ * @return Base Address of respective pwmss instant.
+*/
+static uint32_t select_pwmss(BBB_PWMSS pwmss_id)
 {
-  switch(pwm_id)  {
-   case BBB_PWMSS2:
-       switch(pin_no) { 
-           case BBB_P8_13_2B:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(BBB_MUX4);
-               break;
-           case BBB_P8_19_2A:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(BBB_MUX4);
-               break;
-           case BBB_P8_45_2A:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(BBB_MUX3);
-               break;
-           case BBB_P8_46_2B:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(BBB_MUX3);
-               break;
-           default :
-               printf("Invalid pin for module 2\n");
-               return false;
-       }
-       break;
-   case BBB_PWMSS1:
-       switch(pin_no) {
-           case BBB_P8_34_1B:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(BBB_MUX2);
-               break;
-           case BBB_P8_36_1A:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(BBB_MUX2);
-               break;
-           case BBB_P9_14_1A:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(2)) = BBB_MUXMODE(BBB_MUX6);
-               break;
-           case BBB_P9_16_1B:
-               REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(3)) = BBB_MUXMODE(BBB_MUX6);
-               break;
-           default :
-               printf("Invalid pin for module 1\n");
-               return false;
-       }   
-       break;
-   case BBB_PWMSS0:
-       switch(pin_no) {
-           case BBB_P9_21_0B:
-               REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(BBB_MUX3);
-               break;
-           case BBB_P9_22_0A:
-               REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(BBB_MUX3);
-               break;
-           case BBB_P9_29_0B:
-               REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(BBB_MUX1);
-               break;
-           case BBB_P9_31_0A:
-               REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(BBB_MUX1);
-               break;
-           default:
-               printf("Invalid pin for module 0\n");
-               return false;
-       }
-       break;
-   
-   default:
-       printf("Invalid PWM sub system\n");
-       return false;
+  uint32_t baseAddr=0;
+  
+  if (pwmss_id == BBB_PWMSS0) {
+    baseAddr = AM335X_PWMSS0_MMAP_ADDR;
+  } else if (pwmss_id == BBB_PWMSS1) {
+    baseAddr = AM335X_PWMSS1_MMAP_ADDR;
+  } else if (pwmss_id == BBB_PWMSS2) {
+    baseAddr = AM335X_PWMSS2_MMAP_ADDR;
+  } else {
+    baseAddr = 0;
+  }
+  return baseAddr;
 }
+
+bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
+{
+  bool is_valid = true;
+  
+  if(pwm_id == BBB_PWMSS0) {
+    if (pin_no == BBB_P9_21_0B) {
+      REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(BBB_P9_21_MUX_PWM);
+    } else if (pin_no == BBB_P9_22_0A) {
+      REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(BBB_P9_22_MUX_PWM);
+    } else if (pin_no == BBB_P9_29_0B) {
+      REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(BBB_P9_29_MUX_PWM);
+    } else if (pin_no == BBB_P9_31_0A) {
+      REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(BBB_P9_31_MUX_PWM);
+    } else { 
+      is_valid = false;
+    }
+    
+    } else if (pwm_id == BBB_PWMSS1) {
+      	if (pin_no == BBB_P8_34_1B) {
+      	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(BBB_P8_34_MUX_PWM);
+	} else if (pin_no == BBB_P8_36_1A) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(BBB_P8_36_MUX_PWM);
+	} else if (pin_no == BBB_P9_14_1A) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(2)) = BBB_MUXMODE(BBB_P9_14_MUX_PWM);
+	} else if (pin_no == BBB_P9_16_1B) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(3)) = BBB_MUXMODE(BBB_P9_16_MUX_PWM);
+	} else { 
+	  is_valid = false;
+        }
+   } else if (pwm_id == BBB_PWMSS2) {
+	if (pin_no == BBB_P8_13_2B) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(BBB_P8_13_MUX_PWM);
+	} else if (pin_no == BBB_P8_19_2A) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(BBB_P8_19_MUX_PWM);
+	} else if (pin_no == BBB_P8_45_2A) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(BBB_P8_45_MUX_PWM);
+	} else if (pin_no == BBB_P8_46_2B) {
+	  REG(AM335X_PADCONF_BASE + BBB_CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(BBB_P8_46_MUX_PWM);
+	} else {
+	  is_valid = false;
+        }
+  } else {
+	is_valid = false;
+  }
+  return is_valid;
 }
 
 /**
@@ -137,32 +133,26 @@ bool beagle_epwm_pinmux_setup(uint32_t pin_no, uint32_t pwm_id)
  * @param   instance  It is the instance number of EPWM of pwmsubsystem.
  *
  * @return  true if successful
+ *          false if unsuccessful
  **/
-static bool pwmss_tbclk_enable(unsigned int instance)
+static bool pwmss_tbclk_enable(BBB_PWMSS instance)
 {
-uint32_t enable_bit;
-bool is_valid = true;
+  uint32_t enable_bit;
+  bool is_valid = true;
   
-  if (instance == BBB_PWMSS0)
-  {
-       enable_bit = AM335X_PWMSS_CTRL_PWMSS0_TBCLKEN;
-  }
-  else if (instance == BBB_PWMSS1)
-  {
+  if (instance == BBB_PWMSS0)  {
+    enable_bit = AM335X_PWMSS_CTRL_PWMSS0_TBCLKEN;
+  }  else if (instance == BBB_PWMSS1)  {
        enable_bit = AM335X_PWMSS_CTRL_PWMSS1_TBCLKEN;
-  }
-  else if (instance == BBB_PWMSS2)
-  {
+  }  else if (instance == BBB_PWMSS2)  {
        enable_bit = AM335X_PWMSS_CTRL_PWMSS2_TBCLKEN;
-  }
-  else
-  {
+  }  else  {
        is_valid = false;
   }
 
   if (is_valid)
   {
-       REG(AM335X_PADCONF_BASE + AM335X_PWMSS_CTRL) |= enable_bit;
+    REG(AM335X_PADCONF_BASE + AM335X_PWMSS_CTRL) |= enable_bit;
   }
 
   return is_valid;
@@ -173,18 +163,22 @@ bool is_valid = true;
  *
  * @param   pwm_id  It is the instance number of EPWM of pwm sub system.
  *
- * @return  None.
+ * @return  true if successful
+ *          false if unsuccessful 
  *
  **/
-static void epwm_clock_enable(uint32_t pwm_id)
-{  
-   if((pwm_id <3) && (pwm_id >=0)) {
-       uint32_t baseAddr;
-       baseAddr = select_pwmss(pwm_id);
-               REG(baseAddr - AM335X_EPWM_REGS + AM335X_PWMSS_CLKCONFIG) |= AM335X_PWMSS_CLK_EN_ACK;
-        } else {
-       printf("Invalid pwm_id\n");
-   }
+static bool pwm_clock_enable(BBB_PWMSS pwm_id)
+{
+  const bool id_is_valid = pwm_id < BBB_PWMSS_COUNT;	
+  bool status = true;
+  
+  if (id_is_valid) {
+    const uint32_t baseAddr = select_pwmss(pwm_id);
+    REG(baseAddr + AM335X_PWMSS_CLKCONFIG) |= AM335X_PWMSS_CLK_EN_ACK;
+  }  else  {
+       status = false;
+  }
+  return status;
 }
 
 /**
@@ -198,184 +192,230 @@ static void epwm_clock_enable(uint32_t pwm_id)
  * 'pwmss_id' can take one of the following values:
  * (0 <= pwmss_id <= 2)
  *
- * @return  None.
- *
+ * @return  True if successful
+ *          False if Unsuccessful 
  */
-static void module_clk_config(uint32_t pwmss_id)
+static bool pwmss_module_clk_config(BBB_PWMSS pwmss_id)
 {
-        if(pwmss_id == 0)
-        {
-                REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL) |=
-                        AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE;
-   
-    while(AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE !=
-              (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL) &
-               AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE));
-
-    while((AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC <<
-               AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT) !=
-              (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL) &
-               AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST));
-        }
-        else if(pwmss_id == 1)
-        {
-                REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL) |=
-                        AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE;
-   while(AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE !=
-              (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL) &
-               AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE));
+  bool is_valid = true;
+  
+  if(pwmss_id == BBB_PWMSS0) {
+    const uint32_t is_functional = AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC <<
+                         AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT;
+    const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS0_CLKCTRL;
+    const uint32_t idle_bits = AM335X_CM_PER_EPWMSS0_CLKCTRL_IDLEST;
+    const uint32_t is_enable = AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE;
+    const uint32_t module_mode = AM335X_CM_PER_EPWMSS0_CLKCTRL_MODULEMODE;
+    
+    REG(clkctrl) |= is_enable;
+    while((REG(clkctrl) & module_mode) != is_enable);
+    while((REG(clkctrl) & idle_bits) != is_functional);
+    }
+    else if(pwmss_id == BBB_PWMSS1) {
+    const uint32_t is_functional = AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC <<
+                         AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT;
+    const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL;
+    const uint32_t idle_bits = AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST;
+    const uint32_t is_enable = AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE;
+    const uint32_t module_mode = AM335X_CM_PER_EPWMSS1_CLKCTRL_MODULEMODE;
 
-        while((AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC <<
-               AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT) !=
-               (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS1_CLKCTRL) &
-               AM335X_CM_PER_EPWMSS1_CLKCTRL_IDLEST));
-        }
-        else if(pwmss_id == 2)
-        {
-                REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL) |=
-                        AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE;
-   while(AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE !=
-              (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL) &
-               AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE));
+    REG(clkctrl) |= is_enable;
+    while((REG(clkctrl) & module_mode) != is_enable);
+    while((REG(clkctrl) & idle_bits) != is_functional);
+    } else if(pwmss_id == BBB_PWMSS2) {
+    const uint32_t is_functional = AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_FUNC <<
+                         AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_SHIFT;
+    const uint32_t clkctrl = AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL;
+    const uint32_t idle_bits = AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST;
+    const uint32_t is_enable = AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE;
+    const uint32_t module_mode = AM335X_CM_PER_EPWMSS2_CLKCTRL_MODULEMODE;
 
-        while((AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_FUNC <<
-               AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST_SHIFT) !=
-               (REG(AM335X_CM_PER_ADDR + AM335X_CM_PER_EPWMSS2_CLKCTRL) &
-                AM335X_CM_PER_EPWMSS2_CLKCTRL_IDLEST));
-        }
-        else
-        {
-       printf("Please enter valid pwm Id \n");
-        }
+    REG(clkctrl) |= is_enable;
+    while((REG(clkctrl) & module_mode) != is_enable);
+    while((REG(clkctrl) & idle_bits) != is_functional);
+    } else 
+	is_valid = false;
+  return is_valid;
 }
 
-bool beagle_pwm_init(uint32_t pwmss_id)
+bool beagle_pwm_init(BBB_PWMSS pwmss_id)
 {
+  const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
   bool status = true;
-  if((pwmss_id <3) && (pwmss_id >=0)) 
-  {
-  module_clk_config(pwmss_id);
-  epwm_clock_enable(pwmss_id); 
-  pwmss_tbclk_enable(pwmss_id);
-  return status;
+  
+  if(id_is_valid) {
+    pwmss_module_clk_config(pwmss_id);
+    pwm_clock_enable(pwmss_id);	
+    pwmss_tbclk_enable(pwmss_id);
+  } else {
+      status =false;
   }
-  else {
-   status =false;
   return status;
-  }
 }
 
-int beagle_pwmss_setting(uint32_t pwm_id, float pwm_freq, float dutyA, float dutyB)
-{  
+int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
+{
   uint32_t baseAddr;
   int status = 1;
-   
-  if(pwm_freq <= 0.5) {
-   status =0;
-   return status;
-  }
-  if(dutyA < 0.0f || dutyA > 100.0f || dutyB < 0.0f || dutyB > 100.0f) {
-   status = 0;
-   return status;
-  }
-  dutyA /= 100.0f;
-  dutyB /= 100.0f;
-
-  /*Compute necessary TBPRD*/
-  float Cyclens = 0.0f;
-  float Divisor =0;
-  int i,j;
+  float cycle = 0.0f,divisor = 0;
+  unsigned int i,j;
   const float CLKDIV_div[] = {1.0,2.0,4.0,8.0,16.0,32.0,64.0,128.0};
   const float HSPCLKDIV_div[] = {1.0, 2.0, 4.0, 6.0, 8.0, 10.0,12.0, 14.0};
-  int NearCLKDIV =7;
-  int NearHSPCLKDIV =7;
-  int NearTBPRD =0;
-
+  int NearCLKDIV =7,NearHSPCLKDIV =7,NearTBPRD =0;
+ 
+  if (pwm_freq <= BBB_PWM_FREQ_THRESHOLD) {
+    status =0;
+  }
+  
+  if (duty_a < 0.0f || duty_a > 100.0f || duty_b < 0.0f || duty_b > 100.0f) {
+    status = 0;
+  }
+  duty_a /= 100.0f;
+  duty_b /= 100.0f;
+  
   /** 10^9 /Hz compute time per cycle (ns) */
-  Cyclens = 1000000000.0f / pwm_freq;
+  cycle = 1000000000.0f / pwm_freq;
 
   /** am335x provide (128* 14) divider and per TBPRD means 10ns when divider 
     * and max TBPRD is 65535 so max cycle is 128 * 8 * 14 * 65535 * 10ns */
-  Divisor = (Cyclens / 655350.0f);
-   
-  if(Divisor > (128 * 14)) {
-   printf("Can't generate %f HZ",pwm_freq);
-   return 0;
+  divisor = (cycle / 655350.0f);
+  if (divisor > (128 * 14)) {
+    return 0;
   }
   else {
-   for (i=0;i<8;i++) {
-       for(j=0 ; j<8; j++) {
-           if((CLKDIV_div[i] * HSPCLKDIV_div[j]) < (CLKDIV_div[NearCLKDIV] 
-                       * HSPCLKDIV_div[NearHSPCLKDIV]) && (CLKDIV_div[i] * HSPCLKDIV_div[j] > Divisor)) {
-               NearCLKDIV = i;
-               NearHSPCLKDIV = j;
-           }
-       }
-   }
-  baseAddr = select_pwmss(pwm_id); 
+    for (i=0;i<8;i++) {
+      for(j=0 ; j<8; j++) {
+        if((CLKDIV_div[i] * HSPCLKDIV_div[j]) < (CLKDIV_div[NearCLKDIV]
+                            * HSPCLKDIV_div[NearHSPCLKDIV]) && (CLKDIV_div[i] * HSPCLKDIV_div[j] > divisor)) {
+          NearCLKDIV = i;
+          NearHSPCLKDIV = j;
+         }
+      }
+    }
+  
+  baseAddr = select_pwm(pwm_id);
+  
   REG16(baseAddr + AM335X_EPWM_TBCTL) &= ~(AM335X_TBCTL_CLKDIV_MASK | AM335X_TBCTL_HSPCLKDIV_MASK);
-           
-  REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
-  (~AM335X_EPWM_TBCTL_CLKDIV)) | ((NearCLKDIV 
+  const uint16_t clkdiv_clear = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
+  (~AM335X_EPWM_TBCTL_CLKDIV));
+  const uint16_t clkdiv_write = ((NearCLKDIV
   << AM335X_EPWM_TBCTL_CLKDIV_SHIFT) & AM335X_EPWM_TBCTL_CLKDIV);
-
-  REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
-  (~AM335X_EPWM_TBCTL_HSPCLKDIV)) | ((NearHSPCLKDIV << 
+  REG16(baseAddr + AM335X_EPWM_TBCTL) = clkdiv_clear | clkdiv_write;
+  const uint16_t hspclkdiv_clear =  (REG16(baseAddr + AM335X_EPWM_TBCTL) &
+  (~AM335X_EPWM_TBCTL_HSPCLKDIV));
+  const uint16_t hspclkdiv_write = ((NearHSPCLKDIV <<
   AM335X_EPWM_TBCTL_HSPCLKDIV_SHIFT) & AM335X_EPWM_TBCTL_HSPCLKDIV);
-
-  NearTBPRD = (Cyclens / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV]));
-       
-  REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
-  (~AM335X_EPWM_PRD_LOAD_SHADOW_MASK)) | (((bool)AM335X_EPWM_SHADOW_WRITE_DISABLE <<
+  REG16(baseAddr + AM335X_EPWM_TBCTL) = hspclkdiv_clear | hspclkdiv_write;
+  NearTBPRD = (cycle / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV]));
+  const uint16_t shadow_mask =  (REG16(baseAddr + AM335X_EPWM_TBCTL) &
+  (~AM335X_EPWM_PRD_LOAD_SHADOW_MASK));
+  const uint16_t shadow_disable =  (((bool)AM335X_EPWM_SHADOW_WRITE_DISABLE <<
   AM335X_EPWM_TBCTL_PRDLD_SHIFT) & AM335X_EPWM_PRD_LOAD_SHADOW_MASK);
-
-  REG16(baseAddr + AM335X_EPWM_TBCTL) = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
-  (~AM335X_EPWM_COUNTER_MODE_MASK)) | (((unsigned int)AM335X_EPWM_COUNT_UP <<
+  REG16(baseAddr + AM335X_EPWM_TBCTL) = shadow_mask | shadow_disable;
+  const uint16_t counter_mask = (REG16(baseAddr + AM335X_EPWM_TBCTL) &
+  (~AM335X_EPWM_COUNTER_MODE_MASK));
+  const uint16_t counter_shift = (((unsigned int)AM335X_EPWM_COUNT_UP <<
   AM335X_TBCTL_CTRMODE_SHIFT) &  AM335X_EPWM_COUNTER_MODE_MASK);
-
+  REG16(baseAddr + AM335X_EPWM_TBCTL) = counter_mask | counter_shift;
   /*setting clock divider and freeze time base*/
-  REG16(baseAddr + AM335X_EPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * dutyB);
-  REG16(baseAddr + AM335X_EPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * dutyA);
+  REG16(baseAddr + AM335X_EPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * duty_b);
+  REG16(baseAddr + AM335X_EPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * duty_a);
   REG16(baseAddr + AM335X_EPWM_TBPRD) = (unsigned short)NearTBPRD;
   REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
   }
   return status;
 }
 
-bool beagle_ehrpwm_enable(uint32_t pwmid)
+bool beagle_pwm_enable(BBB_PWMSS pwmid)
 {
+  const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
   bool status = true;
-  uint32_t baseAddr;
-  if((pwmid<3) && (pwmid >=0)) {
-  baseAddr = select_pwmss(pwmid);
-  REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XAHIGH | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
-  REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLB_ZRO_XBHIGH | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
-  REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
-  REG16(baseAddr + AM335X_EPWM_TBCTL) |=  AM335X_TBCTL_FREERUN  | AM335X_TBCTL_CTRMODE_UP;
-  return status;
-  }
-  else {
-   status =false;
-   return status;
+  
+  if (id_is_valid)  {
+    const uint32_t baseAddr = select_pwm(pwmid);
+  /* Initially set EPWMxA o/p high , when increasing counter = CMPA toggle o/p of EPWMxA */
+    REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XAHIGH | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
+  /* Initially set EPWMxB o/p high , when increasing counter = CMPA toggle o/p of EPWMxB */  
+    REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLB_ZRO_XBHIGH | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
+    REG16(baseAddr + AM335X_EPWM_TBCNT) = 0;
+  /* Set counter mode : Up-count mode */
+    REG16(baseAddr + AM335X_EPWM_TBCTL) |=  AM335X_TBCTL_FREERUN  | AM335X_TBCTL_CTRMODE_UP;
+  }  else  {
+       status =false;
   }
+  return status;	
 }
 
-bool beagle_ehrpwm_disable(uint32_t pwmid)
+bool beagle_pwm_disable(BBB_PWMSS pwmid)
 {
+  const bool id_is_valid = pwmid < BBB_PWMSS_COUNT;
   bool status = true;
-  uint32_t baseAddr;
-  if((pwmid<3) && (pwmid >=0)) {
-  baseAddr = select_pwmss(pwmid);
-  REG16(baseAddr + AM335X_EPWM_TBCTL) = AM335X_EPWM_TBCTL_CTRMODE_STOPFREEZE;
-  REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XALOW | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
-  REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLA_ZRO_XBLOW | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
-  REG16(baseAddr + AM335X_EPWM_TBCNT)  = 0;
-  return status;
+  
+  if (id_is_valid) {
+    const uint32_t baseAddr = select_pwm(pwmid);
+    REG16(baseAddr + AM335X_EPWM_TBCTL) = AM335X_EPWM_TBCTL_CTRMODE_STOPFREEZE;
+    REG16(baseAddr + AM335X_EPWM_AQCTLA) = AM335X_EPWM_AQCTLA_ZRO_XALOW | (AM335X_EPWM_AQCTLA_CAU_EPWMXATOGGLE << AM335X_EPWM_AQCTLA_CAU_SHIFT);
+    REG16(baseAddr + AM335X_EPWM_AQCTLB) = AM335X_EPWM_AQCTLA_ZRO_XBLOW | (AM335X_EPWM_AQCTLB_CBU_EPWMXBTOGGLE << AM335X_EPWM_AQCTLB_CBU_SHIFT);
+    REG16(baseAddr + AM335X_EPWM_TBCNT)  = 0;
+  }  else  {
+ 	status = false;
   }
-  else {
-   status = false;
-   return status;
+  return status;
+}
+
+/**
+ * @brief   This functions determines whether time base clock is enabled for EPWMSS
+ *
+ * @param   pwmss_id  The instance number of ePWMSS whose time base clock need to
+ *                    be checked
+ *                    
+ * @return  returns 4 for PWMSS_ID = 2
+ *          returns 2 for PWMSS_ID = 1
+ *          returns 1 for PWMSS_ID = 0
+ **/ 
+static int pwmss_tb_clock_check(unsigned int pwmss_id)
+{
+  unsigned int reg_value;
+
+  /*control module check*/
+  reg_value = REG(AM335X_CONTROL_MODULE + AM335X_PWMSS_CTRL);
+  return (reg_value & (1 << pwmss_id));
+}
+
+/**
+ * @brief   This functions determines whether clock for EPWMSS is enabled or not.
+ *
+ * @param   It is the Memory address of the PWMSS instance used.
+ *
+ * @return  
+ *
+ **/
+static unsigned int pwmss_clock_en_status(unsigned int pwmid)
+{
+  unsigned int status;
+  const uint32_t baseAddr = select_pwmss(pwmid);
+  
+  status = REG(baseAddr + AM335X_PWMSS_CLKSTATUS);
+  status = status >> 8 & 0x1;
+  return status;
+}
+
+bool beagle_pwmss_is_running(unsigned int pwmss_id)
+{
+  const bool id_is_valid = pwmss_id < BBB_PWMSS_COUNT;
+  bool status=true;
+  
+  if (id_is_valid) {
+    status = pwmss_clock_en_status(pwmss_id);
+    if(status){
+    status = pwmss_tb_clock_check(pwmss_id);
+    } else {
+        status = false;
+    }  
+  } else {
+  status = false;
   }
+  return status;
 }
 
 #endif
@@ -387,33 +427,28 @@ bool beagle_ehrpwm_disable(uint32_t pwmid)
  * GPIO API and to make the build successful.
  * Later on support can be added here.
  */
-uint32_t select_pwmss(uint32_t pwm_id)
+bool beagle_pwm_init(BBB_PWMSS pwmss_id)
 {
-return -1;
+  return false;
 }
-bool pwmss_tbclk_enable(unsigned int instance)
+bool beagle_pwm_disable(BBB_PWMSS pwmid)
 {
-return false;
+  return false;
 }
-bool beagle_pwm_init(uint32_t pwmss_id)
+bool beagle_pwm_enable(BBB_PWMSS pwmid)
 {
-return false;
+  return false;
 }
-bool beagle_ehrpwm_disable(uint32_t pwmid)
+int beagle_pwm_configure(BBB_PWMSS pwm_id, float pwm_freq, float duty_a, float duty_b)
 {
-return false;
+  return -1;
 }
-bool beagle_ehrpwm_enable(uint32_t pwmid)
+bool beagle_pwm_pinmux_setup(bbb_pwm_pin_t pin_no, BBB_PWMSS pwm_id)
 {
-return false;
+  return false;
 }
-int beagle_pwmss_setting(uint32_t pwm_id, float pwm_freq, float dutyA, float dutyB)
-{
-return -1;
-}
-bool beagle_epwm_pinmux_setup(uint32_t pin_no, uint32_t pwm_id)
+bool beagle_pwmss_is_running(unsigned int pwmss_id)
 {
 return false;
 }
-
 #endif
-- 
2.7.4



More information about the devel mailing list