This patch adds required definitions, registers definitions and testsuit to test pwm driver for beagle bone black. --- c/src/lib/libbsp/arm/beagle/Makefile.am | 3 + c/src/lib/libbsp/arm/beagle/pwm/bbb-pwm.c | 345 ++++++++++++++++++++++++++ c/src/lib/libbsp/shared/include/gpio.h | 11 + c/src/lib/libcpu/arm/shared/include/am335x.h | 349 ++++++++++++++++++++++++++- testsuites/samples/Makefile.am | 2 +- testsuites/samples/configure.ac | 1 + testsuites/samples/pwm/Makefile.am | 19 ++ testsuites/samples/pwm/init.c | 70 ++++++ testsuites/samples/pwm/pwm.doc | 9 + testsuites/samples/pwm/pwm.scn | 3 + 10 files changed, 810 insertions(+), 2 deletions(-) create mode 100644 c/src/lib/libbsp/arm/beagle/pwm/bbb-pwm.c create mode 100644 testsuites/samples/pwm/Makefile.am create mode 100644 testsuites/samples/pwm/init.c create mode 100644 testsuites/samples/pwm/pwm.doc create mode 100644 testsuites/samples/pwm/pwm.scn
diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am index 20d3092..68bdbd4 100644 --- a/c/src/lib/libbsp/arm/beagle/Makefile.am +++ b/c/src/lib/libbsp/arm/beagle/Makefile.am @@ -117,6 +117,9 @@ libbsp_a_SOURCES += misc/i2c.c # GPIO libbsp_a_SOURCES += gpio/bbb-gpio.c +#pwm +libbsp_a_SOURCES += pwm/bbb-pwm.c + #RTC libbsp_a_SOURCES += rtc.c libbsp_a_SOURCES += ../../shared/tod.c diff --git a/c/src/lib/libbsp/arm/beagle/pwm/bbb-pwm.c b/c/src/lib/libbsp/arm/beagle/pwm/bbb-pwm.c new file mode 100644 index 0000000..a2f1107 --- /dev/null +++ b/c/src/lib/libbsp/arm/beagle/pwm/bbb-pwm.c @@ -0,0 +1,345 @@ +/* This file is based on following licence + * Copyright (c) 2015, Shabaz, VegetableAvenger + * Copyright (c) 2016, Punit Vara + * Added clock functions and improved pwm_enable function + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of BBBIOlib nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include<libcpu/am335x.h> +#include<stdio.h> +#include<bsp/gpio.h> +#include<bsp/bbb-gpio.h> +#include<bsp.h> + +#define BASE_CLOCK 100000000 +/** + * @brief This function intilize clock and pinmuxing for pwm sub system. + * + * @param PWMSS_ID It is the instance number of EPWM of pwm sub system. + **/ +void pwm_init(unsigned int baseAddr, unsigned int PWMSS_ID) +{ + module_clk_config(PWMSS_ID); + EPWMPinMuxSetup(); + EPWM_clock_enable(baseAddr); + pwmss_tbclk_enable(PWMSS_ID); + +} + + +/** + * \brief This function Enables TBCLK(Time Base Clock) for specific + * EPWM instance of pwmsubsystem. + * + * \param instance It is the instance number of EPWM of pwmsubsystem. + * + **/ +void pwmss_tbclk_enable(unsigned int instance) +{ + switch(instance) + { + + case 0: + REG(AM335X_PADCONF_BASE + CONTROL_PWMSS_CTRL) |= + BBBIO_PWMSS_CTRL_PWMSS0_TBCLKEN; + break; + + case 1: + REG(AM335X_PADCONF_BASE + CONTROL_PWMSS_CTRL) |= + BBBIO_PWMSS_CTRL_PWMSS1_TBCLKEN; + break; + + case 2: + REG(AM335X_PADCONF_BASE + CONTROL_PWMSS_CTRL) |= + BBBIO_PWMSS_CTRL_PWMSS2_TBCLKEN; + break; + + default: + break; + } +} + +/** + * \brief This function Enables pinmuxing for PWM module. + * + * + * \param instance It is the instance number of EPWM of pwmsubsystem. + * + **/ + + + +void EPWMPinMuxSetup(void) +{ + REG(AM335X_PADCONF_BASE + CONTROL_CONF_GPMC_AD(9)) = BBB_MUXMODE(4); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_GPMC_AD(8)) = BBB_MUXMODE(4); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_LCD_DATA(0)) = BBB_MUXMODE(3); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_LCD_DATA(1)) = BBB_MUXMODE(3); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_LCD_DATA(11)) = BBB_MUXMODE(2); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_LCD_DATA(10)) = BBB_MUXMODE(2); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_GPMC_AD(2)) = BBB_MUXMODE(6); + + REG(AM335X_PADCONF_BASE + CONTROL_CONF_GPMC_AD(3)) = BBB_MUXMODE(6); + + REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_D0) = BBB_MUXMODE(3); + + REG(AM335X_PADCONF_BASE + AM335X_CONF_SPI0_SCLK) = BBB_MUXMODE(3); + + REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_FSX) = BBB_MUXMODE(1); + + REG(AM335X_PADCONF_BASE + AM335X_CONF_MCASP0_ACLKX) = BBB_MUXMODE(1); +} + + + + +/** + * \brief This functions enables clock for EHRPWM module in PWMSS subsystem. + * + * \param baseAdd It is the Memory address of the PWMSS instance used. + * + * \return None. + * + **/ + +void EPWM_clock_enable(unsigned int baseAdd) +{ + REG(baseAdd + PWMSS_CLKCONFIG) |= PWMSS_CLK_EN_ACK; +} + + +/** + * \brief This function configures the L3 and L4_PER system clocks. + * It also configures the system clocks for the specified ePWMSS + * instance. + * + * \param instanceNum The instance number of ePWMSS whose system clocks + * have to be configured. + * + * 'instanceNum' can take one of the following values: + * (0 <= instanceNum <= 2) + * + * \return None. + * + */ +void module_clk_config(unsigned int instanceNum) +{ + if(0 == instanceNum) + { + REG(BBBIO_CM_PER_ADDR + CM_PER_EPWMSS0_CLKCTRL) |= + CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE; + + + } + else if(1 == instanceNum) + { + REG(BBBIO_CM_PER_ADDR + CM_PER_EPWMSS1_CLKCTRL) |= + CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE; + + } + else if(2 == instanceNum) + { + REG(BBBIO_CM_PER_ADDR + CM_PER_EPWMSS2_CLKCTRL) |= + CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE; + + } + else + { + + } +} + + +/** + * \brief This API enables the particular PWM module. + * + * \param baseAddr Base Address of the PWM Module Registers. + * + * \return None + * + **/ +void ehrPWM_Enable(unsigned int baseAddr) +{ + REG16(baseAddr + EHRPWM_AQCTLA) = 0x2 | (0x3 << 4); + REG16(baseAddr + EHRPWM_AQCTLB) = 0x2 | (0x3 << 8); + REG16(baseAddr + EHRPWM_TBCNT) = 0; + REG16(baseAddr + EHRPWM_TBCTL) |= TBCTL_FREERUN | TBCTL_CTRMODE_UP; +} + +/** + * \brief This API disables the HR sub-module. + * + * \param baseAddr Base Address of the PWM Module Registers. + * + * \return None + * + **/ + +void ehrPWM_Disable(unsigned int baseAddr) +{ + + REG16(baseAddr + EHRPWM_TBCTL) = 0x3; + REG16(baseAddr + EHRPWM_AQCTLA) = 0x1 | ( 0x3 << 4 ); + REG16(baseAddr + EHRPWM_AQCTLB) = 0x1 | ( 0x3 << 8 ); + REG16(baseAddr + EHRPWM_TBCNT) = 0; +} + +/* PWMSS setting + * set pulse argument of epwm module + * + * @param PWMID : EPWMSS number , 0~2 + * @param HZ : pulse HZ + * @param dutyA : Duty Cycle in ePWM A + * @param dutyB : Duty Cycle in ePWM B + * + * @return : 1 for success , 0 for failed + * + * @example : PWMSS_Setting(0 , 50.0f , 50.0f , 25.0f); // Generate 50HZ pwm in PWM0 , + * // duty cycle is 50% for ePWM0A , 25% for ePWM0B + * + * @Note : + * find an number nearst 65535 for TBPRD , to improve duty precision, + * + * Using big TBPRD can increase the range of CMPA and CMPB , + * and it means we can get better precision on duty cycle. + * + * EX : 20.25% duty cycle + * on TBPRD = 62500 , CMPA = 12656.25 ( .25 rejection) , real duty : 20.2496% (12656 /62500) + * on TBPRD = 6250 , CMPA = 1265.625 ( .625 rejection), real duty : 20.24% (1265 6250) + * on TBPRD = 500 , CMPA = 101.25 ( .25 rejection) , real duty : 20.2% (101/500) + * + * Divisor = CLKDIV * HSPCLKDIV + * 1 TBPRD : 10 ns (default) + * 65535 TBPRD : 655350 ns + * 65535 TBPRD : 655350 * Divisor ns = X TBPRD : Cyclens + * + * accrooding to that , we must find a Divisor value , let X nearest 65535 . + * so , Divisor must Nearest Cyclens/655350 + */ + +int PWMSS_Setting(unsigned int baseAddr, float HZ, float dutyA, float dutyB) +{ + unsigned int z,p,y; + int param_error =1; + if(HZ < 0) + param_error =0; + if(dutyA < 0.0f || dutyA > 100.0f || dutyB < 0.0f || dutyB > 100.0f) + param_error = 0; + if(param_error == 0) { + printf("ERROR in parameter \n"); + } + dutyA /= 100.0f; + dutyB /= 100.0f; + + /*Compute necessary TBPRD*/ + float Cyclens = 0.0f; + float Divisor =0; + 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; + + Cyclens = 1000000000.0f / HZ; /** 10^9 /Hz compute time per cycle (ns) + */ + Divisor = (Cyclens / 655350.0f); /** 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 + */ + if(Divisor > (128 * 14)) { + printf("Can't generate %f HZ",HZ); + 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; + } + } + } + printf("BBBIO CLKDIV = %d and HSPCLKDIV = %d\n",NearCLKDIV,NearHSPCLKDIV); + + REG16(baseAddr + EHRPWM_TBCTL) &= ~(TBCTL_CLKDIV_MASK | TBCTL_HSPCLKDIV_MASK); + + REG16(baseAddr + EHRPWM_TBCTL) = (REG16(baseAddr + EHRPWM_TBCTL) & + (~EHRPWM_TBCTL_CLKDIV)) | ((NearCLKDIV << TBCTL_CLKDIV_SHIFT) & EHRPWM_TBCTL_CLKDIV); + + REG16(baseAddr + EHRPWM_TBCTL) = (REG16(baseAddr + EHRPWM_TBCTL) & + (~EHRPWM_TBCTL_HSPCLKDIV)) | ((NearHSPCLKDIV << + TBCTL_HSPCLKDIV_SHIFT) & EHRPWM_TBCTL_HSPCLKDIV); + + NearTBPRD = (Cyclens / (10.0 * CLKDIV_div[NearCLKDIV] * HSPCLKDIV_div[NearHSPCLKDIV])); + + REG16(baseAddr + EHRPWM_TBCTL) = (REG16(baseAddr + EHRPWM_TBCTL) & + (~EHRPWM_PRD_LOAD_SHADOW_MASK)) | (((bool)EHRPWM_SHADOW_WRITE_DISABLE << + EHRPWM_TBCTL_PRDLD_SHIFT) & EHRPWM_PRD_LOAD_SHADOW_MASK); + + REG16(baseAddr + EHRPWM_TBCTL) = (REG16(baseAddr + EHRPWM_TBCTL) & + (~EHRPWM_COUNTER_MODE_MASK)) | (((unsigned int)EHRPWM_COUNT_UP << + EHRPWM_TBCTL_CTRMODE_SHIFT) & EHRPWM_COUNTER_MODE_MASK); + + printf("writing TBPRD = %x \n",NearTBPRD); + /*setting clock divider and freeze time base*/ + // configure_tbclk(baseAddr, HZ); + REG16(baseAddr + EHRPWM_CMPB) = (unsigned short)((float)(NearTBPRD) * dutyB); + z = REG16(baseAddr + EHRPWM_CMPB); + printk("read CMPB = %x\t",z); + REG16(baseAddr + EHRPWM_CMPA) = (unsigned short)((float)(NearTBPRD) * dutyA); + p = REG16(baseAddr + EHRPWM_CMPA); + printk("read CMPA = %x\n",p); + REG16(baseAddr + EHRPWM_TBPRD) = (unsigned short)NearTBPRD; + y = REG16(baseAddr + EHRPWM_TBPRD); + printk("TBPRD read = %x \n",y); + REG16(baseAddr + EHRPWM_TBCNT) = 0; + printf("\nfinished setting \n"); + } + return 1; +} + +int PWMSS_TB_clock_check(unsigned int PWMSS_ID) +{ + unsigned int reg_value,value; + + /*control module check*/ + reg_value = REG(BBBIO_CONTROL_MODULE + BBBIO_PWMSS_CTRL); + + value = reg_value & (1 << PWMSS_ID); + printf("\n PWMSS_CTRL = %d and reg_value = %d \n",value,reg_value); + return (reg_value & (1 << PWMSS_ID)); +} diff --git a/c/src/lib/libbsp/shared/include/gpio.h b/c/src/lib/libbsp/shared/include/gpio.h index 7d8f67b..2a89f1d 100644 --- a/c/src/lib/libbsp/shared/include/gpio.h +++ b/c/src/lib/libbsp/shared/include/gpio.h @@ -947,6 +947,17 @@ extern rtems_status_code rtems_gpio_bsp_disable_interrupt( /** @} */ +extern void pwmss_tbclk_enable(unsigned int instance); +extern void EPWM_clock_enable(unsigned int baseAdd); +extern void module_clk_config(unsigned int instanceNum); +extern void EPWMPinMuxSetup(void); +extern int PWMSS_Setting(unsigned int baseAddr, float HZ, float dutyA, float dutyB); +extern void ehrPWM_Disable(unsigned int baseAddr); +extern void ehrPWM_Enable(unsigned int baseAddr); +extern int PWMSS_TB_clock_check(unsigned int PWMSS_ID); +extern void pwm_init(unsigned int baseAddr, unsigned int PWMSS_ID); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/c/src/lib/libcpu/arm/shared/include/am335x.h b/c/src/lib/libcpu/arm/shared/include/am335x.h index 2009cef..b89a188 100644 --- a/c/src/lib/libcpu/arm/shared/include/am335x.h +++ b/c/src/lib/libcpu/arm/shared/include/am335x.h @@ -467,4 +467,351 @@ #define AM335X_CONF_EXT_WAKEUP 0xA00 #define AM335X_CONF_RTC_KALDO_ENN 0xA04 #define AM335X_CONF_USB0_DRVVBUS 0xA1C -#define AM335X_CONF_USB1_DRVVBUS 0xA34 \ No newline at end of file +#define AM335X_CONF_USB1_DRVVBUS 0xA34 + +/* Added by punit vara + + PWMSS register definitions */ + +#define PWMSS_CLOCK_CONFIG 0x08 + +#define PWMSS_CLOCK_STATUS 0x0C + +#define PWMSS_ECAP_CLK_EN_ACK_SHIFT 0x00 + +#define PWMSS_ECAP_CLK_STOP_ACK_SHIFT 0x01 + +#define PWMSS_EHRPWM_CLK_EN_ACK_SHIFT 0x08 + +#define PWMSS_EHRPWM_CLK_STOP_ACK_SHIFT 0x09 + +#define PWMSS_ECAP_CLK_EN_ACK 0x01 + +#define PWMSS_ECAP_CLK_STOP_ACK 0x02 + +#define PWMSS_EHRPWM_CLK_EN_ACK 0x100 + +#define PWMSS_EHRPWM_CLK_STOP_ACK 0x200 + +/** @brief Base addresses of PWMSS memory mapped registers. */ + +#define SOC_PWMSS0_REGS (0x48300000) +#define SOC_PWMSS1_REGS (0x48302000) +#define SOC_PWMSS2_REGS (0x48304000) + +#define SOC_ECAP_REGS (0x00000100) +#define SOC_EQEP_REGS (0x00000180) +#define SOC_EPWM_REGS (0x00000200) +#define SOC_ECAP_0_REGS (SOC_PWMSS0_REGS + SOC_ECAP_REGS) +#define SOC_ECAP_1_REGS (SOC_PWMSS1_REGS + SOC_ECAP_REGS) +#define SOC_ECAP_2_REGS (SOC_PWMSS2_REGS + SOC_ECAP_REGS) + +#define SOC_EQEP_0_REGS (SOC_PWMSS0_REGS + SOC_EQEP_REGS) +#define SOC_EQEP_1_REGS (SOC_PWMSS1_REGS + SOC_EQEP_REGS) +#define SOC_EQEP_2_REGS (SOC_PWMSS2_REGS + SOC_EQEP_REGS) + +#define SOC_EPWM_0_REGS (SOC_PWMSS0_REGS + SOC_EPWM_REGS) +#define SOC_EPWM_1_REGS (SOC_PWMSS1_REGS + SOC_EPWM_REGS) +#define SOC_EPWM_2_REGS (SOC_PWMSS2_REGS + SOC_EPWM_REGS) + +#define CONTROL_PWMSS_CTRL (0x664) +#define CONTROL_PWMSS_CTRL_PWMSS0_TBCLKEN (0x00000001u) +#define CONTROL_PWMSS_CTRL_PWMMS1_TBCLKEN (0x00000002u) +#define CONTROL_PWMSS_CTRL_PWMSS2_TBCLKEN (0x00000004u) +#define SOC_PRCM_REGS (0x44E00000) +#define CM_PER_EPWMSS0_CLKCTRL (0xd4) +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE (0x2u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC (0x0u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT (0x00000010u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST (0x00030000u) +#define CM_PER_EPWMSS1_CLKCTRL (0xcc) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE (0x2u) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE (0x00000003u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC (0x0u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT (0x00000010u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST (0x00030000u) + +/* TBCTL */ + +#define EHRPWM_TBCTL_FREE_SOFT (0xC000u) +#define EHRPWM_TBCTL_FREE_SOFT_SHIFT (0x000Eu) + +#define EHRPWM_TBCTL_PHSDIR (0x2000u) +#define EHRPWM_TBCTL_PHSDIR_SHIFT (0x000Du) +#define EHRPWM_TBCTL_CLKDIV (0x1C00u) +#define EHRPWM_TBCTL_CLKDIV_SHIFT (0x000Au) +#define EHRPWM_TBCTL_CLKDIV_DIVBY1 (0x0000u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY2 (0x0001u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY4 (0x0002u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY8 (0x0003u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY16 (0x0004u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY32 (0x0005u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY64 (0x0006u) +#define EHRPWM_TBCTL_CLKDIV_DIVBY128 (0x0007u) +#define EHRPWM_TBCTL_HSPCLKDIV (0x0380u) +#define EHRPWM_TBCTL_HSPCLKDIV_SHIFT (0x0007u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY1 (0x0000u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY2 (0x0001u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY4 (0x0002u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY6 (0x0003u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY8 (0x0004u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY10 (0x0005u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY12 (0x0006u) +#define EHRPWM_TBCTL_HSPCLKDIV_DIVBY14 (0x0007u) +#define EHRPWM_TBCTL_SWFSYNC (0x0040u) +#define EHRPWM_TBCTL_SWFSYNC_SHIFT (0x0006u) +#define EHRPWM_TBCTL_SYNCOSEL (0x0030u) +#define EHRPWM_TBCTL_SYNCOSEL_SHIFT (0x0004u) +#define EHRPWM_TBCTL_SYNCOSEL_EPWMXSYNCI (0x0000u) +#define EHRPWM_TBCTL_SYNCOSEL_TBCTRZERO (0x0001u) +#define EHRPWM_TBCTL_SYNCOSEL_TBCTRCMPB (0x0002u) +#define EHRPWM_TBCTL_SYNCOSEL_DISABLE (0x0003u) +#define EHRPWM_TBCTL_PRDLD (0x0008u) +#define EHRPWM_TBCTL_PRDLD_SHIFT (0x0003u) +#define EHRPWM_TBCTL_PHSEN (0x0004u) +#define EHRPWM_TBCTL_PHSEN_SHIFT (0x0002u) +#define EHRPWM_TBCTL_CTRMODE (0x0003u) +#define EHRPWM_TBCTL_CTRMODE_SHIFT (0x0000u) +#define EHRPWM_TBCTL_CTRMODE_UP (0x0000u) +#define EHRPWM_TBCTL_CTRMODE_DOWN (0x0001u) +#define EHRPWM_TBCTL_CTRMODE_UPDOWN (0x0002u) +#define EHRPWM_TBCTL_CTRMODE_STOPFREEZE (0x0003u) + +/* TBPRD */ + +#define EHRPWM_TBPRD_TBPRD (0xFFFFu) +#define EHRPWM_TBPRD_TBPRD_SHIFT (0x0000u) + + +/* CMPA */ + +#define EHRPWM_CMPA_CMPA (0xFFFFu) +#define EHRPWM_CMPA_CMPA_SHIFT (0x0000u) + + +/* CMPB */ + +#define EHRPWM_CMPB_CMPB (0xFFFFu) +#define EHRPWM_CMPB_CMPB_SHIFT (0x0000u) + +/* REVID */ + +#define EHRPWM_REVID_REV (0xFFFFFFFFu) +#define EHRPWM_REVID_REV_SHIFT (0x00000000u) + +#define EHRPWM_TBCTL (0x0) +#define EHRPWM_TBSTS (0x2) +#define EHRPWM_TBPHSHR (0x4) +#define EHRPWM_TBPHS (0x6) +#define EHRPWM_TBCTR (0x8) +#define EHRPWM_TBPRD (0xA) +#define EHRPWM_CMPCTL (0xE) +#define EHRPWM_CMPAHR (0x10) +#define EHRPWM_CMPA (0x12) +#define EHRPWM_CMPB (0x14) +#define EHRPWM_AQCTLA (0x16) +#define EHRPWM_AQCTLB (0x18) +#define EHRPWM_AQSFRC (0x1A) +#define EHRPWM_AQCSFRC (0x1C) +#define EHRPWM_DBCTL (0x1E) +#define EHRPWM_DBRED (0x20) +#define EHRPWM_DBFED (0x22) +#define EHRPWM_TZSEL (0x24) +#define EHRPWM_TZCTL (0x28) +#define EHRPWM_TZEINT (0x2A) +#define EHRPWM_TZFLG (0x2C) +#define EHRPWM_TZCLR (0x2E) +#define EHRPWM_TZFRC (0x30) +#define EHRPWM_ETSEL (0x32) +#define EHRPWM_ETPS (0x34) +#define EHRPWM_ETFLG (0x36) +#define EHRPWM_ETCLR (0x38) +#define EHRPWM_ETFRC (0x3A) +#define EHRPWM_PCCTL (0x3C) +#define EHRPWM_HRCNFG (0x1040) + + +/* TB Period load */ +#define EHRPWM_PRD_LOAD_SHADOW_MASK EHRPWM_TBCTL_PRDLD + +/* Counter mode */ +#define EHRPWM_COUNTER_MODE_MASK EHRPWM_TBCTL_CTRMODE +#define EHRPWM_COUNT_UP (EHRPWM_TBCTL_CTRMODE_UP << \ + EHRPWM_TBCTL_CTRMODE_SHIFT) +#define EHRPWM_COUNT_DOWN (EHRPWM_TBCTL_CTRMODE_DOWN << \ + EHRPWM_TBCTL_CTRMODE_SHIFT) +#define EHRPWM_COUNT_UP_DOWN (EHRPWM_TBCTL_CTRMODE_UPDOWN << \ + EHRPWM_TBCTL_CTRMODE_SHIFT) +#define EHRPWM_COUNT_STOP (EHRPWM_TBCTL_CTRMODE_STOPFREEZE << \ + EHRPWM_TBCTL_CTRMODE_SHIFT) +/* Synchronization */ +#define EHRPWM_SYNC_ENABLE EHRPWM_TBCTL_PHSEN +//#define EHRPWM_SW_FORCED_SYNC 0x1 + +#define EHRPWM_SYNCOUT_MASK EHRPWM_TBCTL_SYNCOSEL +#define EHRPWM_SYNCOUT_SYNCIN (EHRPWM_TBCTL_SYNCOSEL_EPWMXSYNCI << \ + EHRPWM_TBCTL_SYNCOSEL_SHIFT) +#define EHRPWM_SYNCOUT_COUNTER_EQUAL_ZERO (EHRPWM_TBCTL_SYNCOSEL_TBCTRZERO << \ + EHRPWM_TBCTL_SYNCOSEL_SHIFT) +#define EHRPWM_SYNCOUT_COUNTER_EQUAL_COMPAREB (EHRPWM_TBCTL_SYNCOSEL_TBCTRCMPB << \ + EHRPWM_TBCTL_SYNCOSEL_SHIFT) +#define EHRPWM_SYNCOUT_DISABLE (EHRPWM_TBCTL_SYNCOSEL_DISABLE << \ + EHRPWM_TBCTL_SYNCOSEL_SHIFT) +/* Shadow */ +#define EHRPWM_SHADOW_WRITE_ENABLE 0x0 +#define EHRPWM_SHADOW_WRITE_DISABLE 0x1 + +/* Time base clock */ +#define EHRPWM_TBCTL_CLKDIV_1 (0x0001u) +#define EHRPWM_TBCTL_CLKDIV_2 (0x0002u) +#define EHRPWM_TBCTL_CLKDIV_4 (0x0004u) +#define EHRPWM_TBCTL_CLKDIV_8 (0x0008u) +#define EHRPWM_TBCTL_CLKDIV_16 (0x0010u) +#define EHRPWM_TBCTL_CLKDIV_32 (0x0020u) +#define EHRPWM_TBCTL_CLKDIV_64 (0x0040u) +#define EHRPWM_TBCTL_CLKDIV_128 (0x0080u) + +#define EHRPWM_TBCTL_HSPCLKDIV_1 (0x0001u) +#define EHRPWM_TBCTL_HSPCLKDIV_2 (0x0002u) +#define EHRPWM_TBCTL_HSPCLKDIV_4 (0x0004u) +#define EHRPWM_TBCTL_HSPCLKDIV_6 (0x0006u) +#define EHRPWM_TBCTL_HSPCLKDIV_8 (0x0008u) +#define EHRPWM_TBCTL_HSPCLKDIV_10 (0x000Au) +#define EHRPWM_TBCTL_HSPCLKDIV_12 (0x000Cu) +#define EHRPWM_TBCTL_HSPCLKDIV_14 (0x000Eu) + +/* Count direction after sync */ +#define EHRPWM_COUNT_DOWN_AFTER_SYNC 0x0 +#define EHRPWM_COUNT_UP_AFTER_SYNC 0x1 +/* Counter Compare */ +#define EHRPWM_SHADOW_A_EMPTY (0x0 << EHRPWM_CMPCTL_SHDWAFULL_SHIFT) +#define EHRPWM_SHADOW_A_FULL (EHRPWM_CMPCTL_SHDWAFULL) +#define EHRPWM_SHADOW_B_EMPTY (0x0 << EHRPWM_CMPCTL_SHDWBFULL_SHIFT) +#define EHRPWM_SHADOW_B_FULL (EHRPWM_CMPCTL_SHDWBFULL) + +#define EHRPWM_CMPCTL_NOT_OVERWR_SH_FL 0x0 +#define EHRPWM_CMPCTL_OVERWR_SH_FL 0x1 + +/* Compare register load */ +#define EHRPWM_COMPB_LOAD_MASK EHRPWM_CMPCTL_LOADBMODE +#define EHRPWM_COMPB_LOAD_COUNT_EQUAL_ZERO (EHRPWM_CMPCTL_LOADBMODE_TBCTRZERO << \ + EHRPWM_CMPCTL_LOADBMODE_SHIFT) +#define EHRPWM_COMPB_LOAD_COUNT_EQUAL_PERIOD (EHRPWM_CMPCTL_LOADBMODE_TBCTRPRD << \ + EHRPWM_CMPCTL_LOADBMODE_SHIFT) +#define EHRPWM_COMPB_LOAD_COUNT_EQUAL_ZERO_OR_PERIOD \ + (EHRPWM_CMPCTL_LOADBMODE_ZEROORPRD << \ + EHRPWM_CMPCTL_LOADBMODE_SHIFT) +#define EHRPWM_COMPB_NO_LOAD (EHRPWM_CMPCTL_LOADBMODE_FREEZE << \ + EHRPWM_CMPCTL_LOADBMODE_SHIFT) + + +#define EHRPWM_COMPA_LOAD_MASK EHRPWM_CMPCTL_LOADAMODE +#define EHRPWM_COMPA_LOAD_COUNT_EQUAL_ZERO (EHRPWM_CMPCTL_LOADAMODE_TBCTRZERO << \ + EHRPWM_CMPCTL_LOADAMODE_SHIFT) +#define EHRPWM_COMPA_LOAD_COUNT_EQUAL_PERIOD (EHRPWM_CMPCTL_LOADAMODE_TBCTRPRD << \ + EHRPWM_CMPCTL_LOADAMODE_SHIFT) +#define EHRPWM_COMPA_LOAD_COUNT_EQUAL_ZERO_OR_PERIOD \ + (EHRPWM_CMPCTL_LOADAMODE_ZEROORPRD << \ + EHRPWM_CMPCTL_LOADAMODE_SHIFT) +#define EHRPWM_COMPA_NO_LOAD (EHRPWM_CMPCTL_LOADAMODE_FREEZE << \ + EHRPWM_CMPCTL_LOADAMODE_SHIFT) + +#define CM_PER_EPWMSS1_CLKCTRL (0xcc) +#define CM_PER_EPWMSS0_CLKCTRL (0xd4) +#define CM_PER_EPWMSS2_CLKCTRL (0xd8) + +/* EPWMSS1_CLKCTRL */ +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST (0x00030000u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_SHIFT (0x00000010u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_DISABLE (0x3u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_FUNC (0x0u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_IDLE (0x2u) +#define CM_PER_EPWMSS1_CLKCTRL_IDLEST_TRANS (0x1u) + +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE (0x00000003u) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_SHIFT (0x00000000u) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_DISABLED (0x0u) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_ENABLE (0x2u) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_RESERVED (0x3u) +#define CM_PER_EPWMSS1_CLKCTRL_MODULEMODE_RESERVED_1 (0x1u) + +/* EPWMSS0_CLKCTRL */ +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST (0x00030000u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_SHIFT (0x00000010u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_DISABLED (0x3u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_FUNC (0x0u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_IDLE (0x2u) +#define CM_PER_EPWMSS0_CLKCTRL_IDLEST_TRANS (0x1u) + +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE (0x00000003u) +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_SHIFT (0x00000000u) +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_DISABLE (0x0u) +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_ENABLE (0x2u) +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_RESERVED (0x3u) +#define CM_PER_EPWMSS0_CLKCTRL_MODULEMODE_RESERVED_1 (0x1u) + +/* EPWMSS2_CLKCTRL */ +#define CM_PER_EPWMSS2_CLKCTRL_IDLEST (0x00030000u) +#define CM_PER_EPWMSS2_CLKCTRL_IDLEST_SHIFT (0x00000010u) +#define CM_PER_EPWMSS2_CLKCTRL_IDLEST_DISABLE (0x3u) +#define CM_PER_EPWMSS2_CLKCTRL_IDLEST_FUNC (0x0u) +#define CM_PER_EPWMSS2_CLKCTRL_IDLEST_IDLE (0x2u) +#define CM_PER_EPWMSS2_CLKCTRL_IDLEST_TRANS (0x1u) + +#define CM_PER_EPWMSS2_CLKCTRL_MODULEMODE (0x00000003u) +#define CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_SHIFT (0x00000000u) +#define CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_DISABLED (0x0u) +#define CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_ENABLE (0x2u) +#define CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_RESERVED (0x3u) +#define CM_PER_EPWMSS2_CLKCTRL_MODULEMODE_RESERVED_1 (0x1u) + +#define CONTROL_CONF_GPMC_AD(n) (0x800 + (n * 4)) +#define CONTROL_CONF_LCD_DATA(n) (0x8a0 + (n * 4)) +#define EHRPWM_TBCNT 0x8 + +#define BBBIO_CONTROL_MODULE 0x44e10000 +#define BBBIO_PWMSS_CTRL 0x664 +#define BBBIO_CM_PER_ADDR 0x44e00000 +#define BBBIO_CM_PER_EPWMSS1_CLKCTRL 0xcc +#define BBBIO_CM_PER_EPWMSS0_CLKCTRL 0xd4 +#define BBBIO_CM_PER_EPWMSS2_CLKCTRL 0xd8 + +#define PWMSS0_MMAP_ADDR 0x48300000 +#define PWMSS1_MMAP_ADDR 0x48302000 +#define PWMSS2_MMAP_ADDR 0x48304000 + +#define BBBIO_PWMSS_CTRL_PWMSS0_TBCLKEN (0x00000001u) +#define BBBIO_PWMSS_CTRL_PWMSS1_TBCLKEN (0x00000002u) +#define BBBIO_PWMSS_CTRL_PWMSS2_TBCLKEN (0x00000004u) + +#define PWMSS_CLKCONFIG 0x8 +#define PWMSS_CLK_EN_ACK 0x100 + +#define TBCTL_CLKDIV (0x1C00u) +#define TBCTL_CLKDIV_SHIFT (0x000Au) +#define TBCTL_CLKDIV_DIVBY1 (0x0000u) +#define TBCTL_CLKDIV_DIVBY2 (0x0001u) +#define TBCTL_CLKDIV_DIVBY4 (0x0002u) +#define TBCTL_CLKDIV_DIVBY8 (0x0003u) +#define TBCTL_CLKDIV_DIVBY16 (0x0004u) +#define TBCTL_CLKDIV_DIVBY32 (0x0005u) +#define TBCTL_CLKDIV_DIVBY64 (0x0006u) +#define TBCTL_CLKDIV_DIVBY128 (0x0007u) +#define TBCTL_HSPCLKDIV (0x0380u) +#define TBCTL_HSPCLKDIV_SHIFT (0x0007u) +#define TBCTL_HSPCLKDIV_DIVBY1 (0x0000u) +#define TBCTL_HSPCLKDIV_DIVBY2 (0x0001u) +#define TBCTL_HSPCLKDIV_DIVBY4 (0x0002u) +#define TBCTL_HSPCLKDIV_DIVBY6 (0x0003u) +#define TBCTL_HSPCLKDIV_DIVBY8 (0x0004u) +#define TBCTL_HSPCLKDIV_DIVBY10 (0x0005u) +#define TBCTL_HSPCLKDIV_DIVBY12 (0x0006u) +#define TBCTL_HSPCLKDIV_DIVBY14 (0x0007u) + + +#define TBCTL_CLKDIV(x) ((x) << 10) +#define TBCTL_CLKDIV_MASK (3 << 10) +#define TBCTL_HSPCLKDIV(x) ((x) << 7) +#define TBCTL_HSPCLKDIV_MASK (3 << 7) +#define TBCTL_FREERUN (2 << 14) +#define TBCTL_CTRMODE_UP (0 << 0) diff --git a/testsuites/samples/Makefile.am b/testsuites/samples/Makefile.am index 374617b..70ebe57 100644 --- a/testsuites/samples/Makefile.am +++ b/testsuites/samples/Makefile.am @@ -1,6 +1,6 @@ ACLOCAL_AMFLAGS = -I ../aclocal -_SUBDIRS = hello capture ticker base_sp unlimited minimum fileio +_SUBDIRS = hello capture ticker base_sp unlimited minimum fileio pwm if MPTESTS ## base_mp is a sample multiprocessing test diff --git a/testsuites/samples/configure.ac b/testsuites/samples/configure.ac index 91a3661..72a64a0 100644 --- a/testsuites/samples/configure.ac +++ b/testsuites/samples/configure.ac @@ -62,6 +62,7 @@ AC_CHECK_SIZEOF([time_t]) AC_CONFIG_FILES([Makefile base_sp/Makefile hello/Makefile +pwm/Makefile loopback/Makefile minimum/Makefile fileio/Makefile diff --git a/testsuites/samples/pwm/Makefile.am b/testsuites/samples/pwm/Makefile.am new file mode 100644 index 0000000..85d0fc1 --- /dev/null +++ b/testsuites/samples/pwm/Makefile.am @@ -0,0 +1,19 @@ +rtems_tests_PROGRAMS = pwm +pwm_SOURCES = init.c + +dist_rtems_tests_DATA = pwm.scn +dist_rtems_tests_DATA += pwm.doc + +include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg +include $(top_srcdir)/../automake/compile.am +include $(top_srcdir)/../automake/leaf.am + + +LINK_OBJS = $(pwm_OBJECTS) +LINK_LIBS = $(pwm_LDLIBS) + +hello$(EXEEXT): $(pwm_OBJECTS) $(pwm_DEPENDENCIES) + @rm -f pwm$(EXEEXT) + $(make-exe) + +include $(top_srcdir)/../automake/local.am diff --git a/testsuites/samples/pwm/init.c b/testsuites/samples/pwm/init.c new file mode 100644 index 0000000..0814720 --- /dev/null +++ b/testsuites/samples/pwm/init.c @@ -0,0 +1,70 @@ +#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> + +const char rtems_test_name[] = "Punit PWM test GSOC 2016"; +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"); + +/* Initialization PWM API*/ +rtems_gpio_initialize(); +pwm_init(PWMSS2_MMAP_ADDR, 2); +PWMSS_TB_clock_check(2); + + + float PWM_HZ = 1.0f ; + float duty_A = 50.0f ; /* 50% Duty cycle for PWM 2_A output */ + const float duty_B = 50.0f ; /* 50% Duty cycle for PWM 2_B output*/ + + + for(PWM_HZ=1; PWM_HZ <=100000000; PWM_HZ= PWM_HZ*3) + { + printf("\n Generating frequency : %f\n",PWM_HZ); + PWMSS_Setting(SOC_EPWM_2_REGS, PWM_HZ ,duty_A , duty_B); + printf("PWM enable for 10s ....\n"); + ehrPWM_Enable(SOC_EPWM_2_REGS); + delay_sec(10); + + ehrPWM_Disable(SOC_EPWM_2_REGS); + } + printf("close\n"); + +} + +/* 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/testsuites/samples/pwm/pwm.doc b/testsuites/samples/pwm/pwm.doc new file mode 100644 index 0000000..9812864 --- /dev/null +++ b/testsuites/samples/pwm/pwm.doc @@ -0,0 +1,9 @@ +# COPYRIGHT (c) 1989-1999. +# On-Line Applications Research Corporation (OAR). +# +# The license and distribution terms for this file may be +# found in the file LICENSE in this distribution or at +# http://www.rtems.org/license/LICENSE. +# + + diff --git a/testsuites/samples/pwm/pwm.scn b/testsuites/samples/pwm/pwm.scn new file mode 100644 index 0000000..057ab6e --- /dev/null +++ b/testsuites/samples/pwm/pwm.scn @@ -0,0 +1,3 @@ +*** GPIO TEST *** +Gpio Testing +*** END OF GPIO TEST *** -- 2.7.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel