summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/arm/beagle/pwm/README
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/arm/beagle/pwm/README')
-rw-r--r--c/src/lib/libbsp/arm/beagle/pwm/README197
1 files changed, 197 insertions, 0 deletions
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 0000000000..d41f5ca668
--- /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>
+