Why does this include your non-BBBIOlib changes to two header files?
On Wed, Jun 22, 2016 at 2:56 AM, Punit Vara <punitv...@gmail.com> wrote: > This patch perform following things: > - adds original BBBIO PWM code as it is. > - not added to Makefile otherwise it will break build > - adds required registers > - adds declarations to BSP_HEADERS > > This code is added from > > https://github.com/VegetableAvenger/BBBIOlib/blob/master/BBBio_lib/BBBiolib_PWMSS.c > --- > c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h | 46 +++ > c/src/lib/libbsp/arm/beagle/pwm/pwm.c | 407 > ++++++++++++++++++++++++++ > c/src/lib/libcpu/arm/shared/include/am335x.h | 11 +- > 3 files changed, 463 insertions(+), 1 deletion(-) > create mode 100644 c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h > create mode 100644 c/src/lib/libbsp/arm/beagle/pwm/pwm.c > > diff --git a/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h > b/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h > new file mode 100644 > index 0000000..bd70385 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/beagle/include/bbb-pwm.h > @@ -0,0 +1,46 @@ > +/** > + * @file > + * > + * @ingroup arm_beagle > + * > + * @brief BeagleBone Black BSP definitions. > + */ > + > +/** > + * Copyright (c) 2016 Punit Vara <punitv...@gmail.com> > + * > + * 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. > + */ > + > +#ifndef LIBBSP_ARM_BEAGLE_BBB_PWM_H > +#define LIBBSP_ARM_BEAGLE_BBB_PWM_H > + > +#ifdef __cplusplus > +extern "C" { > +#endif /* __cplusplus */ > + > +/** > + * @brief BeagleBone Black PWM functions. > + */ > +#define BBBIO_PWMSS_COUNT 3 > +#define BBBIO_PWMSS0 0 > +#define BBBIO_PWMSS1 1 > +#define BBBIO_PWMSS2 2 > + > +/** > + * @brief BeagleBone Black PWM API. > + */ > +int BBBIO_PWMSS_Setting(unsigned int PWMID , float HZ ,float dutyA ,float > dutyB); > +int BBBIO_PWM_Init(); > +void BBBIO_PWM_Release(); > +int BBBIO_PWMSS_Status(unsigned int PWMID); > +void BBBIO_ehrPWM_Enable(unsigned int PWMSS_ID); > +void BBBIO_ehrPWM_Disable(unsigned int PWMSS_ID); > + > +#ifdef __cplusplus > +} > +#endif /* __cplusplus */ > + > +#endif /* LIBBSP_ARM_BEAGLE_BBB_PWM_H */ > diff --git a/c/src/lib/libbsp/arm/beagle/pwm/pwm.c > b/c/src/lib/libbsp/arm/beagle/pwm/pwm.c > new file mode 100644 > index 0000000..f65ff89 > --- /dev/null > +++ b/c/src/lib/libbsp/arm/beagle/pwm/pwm.c > @@ -0,0 +1,407 @@ > +#include <stdio.h> > +#include <stdlib.h> > +#include <sys/mman.h> > +#include <sys/stat.h> > +#include <fcntl.h> > +#include <errno.h> > +#include <time.h> > +#include "BBBiolib.h" > +/*-----------------------------------------------------------------------------------------------*/ > +/* > + * PWMSS Registers > + * > + * @Source : AM335x Technical Reference Manual ,page 1991 > + * Table 15-5. PWMSS REGISTERS > + * > +*/ > + > +#define PWMSS0_MMAP_ADDR 0x48300000 > +#define PWMSS1_MMAP_ADDR 0x48302000 > +#define PWMSS2_MMAP_ADDR 0x48304000 > +#define PWMSS_MMAP_LEN 0x1000 > + > +#define PWMSS_IDVER 0x0 > +#define PWMSS_SYSCONFIG 0x4 > +#define PWMSS_CLKCONFIG 0x8 > +#define PWMSS_CLKSTATUS 0xC > + > +/* EPWM Registers > + * > + * @Source : AM335x Technical Reference Manual ,page 2084 > + * Table 15-58. EPWM REGISTERS > + * > +*/ > +#define EPWM_TBCTL 0x0 > +#define EPWM_TBSTS 0x2 > +#define EPWM_TBPHSHR 0x4 > +#define EPWM_TBPHS 0x6 > +#define EPWM_TBCNT 0x8 > +#define EPWM_TBPRD 0xA > +#define EPWM_CMPCTL 0xE > +#define EPWM_CMPAHR 0x10 > +#define EPWM_CMPA 0x12 > +#define EPWM_CMPB 0x14 > +#define EPWM_AQCTLA 0x16 > +#define EPWM_AQCTLB 0x18 > +#define EPWM_AQSFRC 0x1A > +#define EPWM_AQCSFRC 0x1C > +#define EPWM_DBCTL 0x1E > +#define EPWM_DBRED 0x20 > +#define EPWM_DBFED 0x22 > +/*-----------------------------------------------------------------------------------------------*/ > +extern int memh; > +extern volatile unsigned int *CM_ptr; /*c ontrol module */ > +volatile unsigned int *cm_per_addr; > + > + > +const unsigned int PWMSS_AddressOffset[]={PWMSS0_MMAP_ADDR, > + PWMSS1_MMAP_ADDR, > + PWMSS2_MMAP_ADDR}; > +volatile unsigned int *pwmss_ptr[3] ={NULL, NULL, NULL} ; > +volatile unsigned int *epwm_ptr[3] ={NULL, NULL, NULL} ; > +volatile unsigned int *ecap_ptr[3] ={NULL, NULL, NULL} ; > +volatile unsigned int *eqep_ptr[3] ={NULL, NULL, NULL} ; > + > +#define TBCTL_CTRMODE_UP 0x0 > +#define TBCTL_CTRMODE_DOWN 0x1 > +#define TBCTL_CTRMODE_UPDOWN 0x2 > +#define TBCTL_CTRMODE_FREEZE 0x3 > +/* > ----------------------------------------------------------------------------------------------- > */ > +/* PWMSS Timebase clock check > + * check the timenase clock enable or not > + * > + * @param PWMSS_ID : PWM sumsystem ID (BBBIO_PWMSS0 ,BBBIO_PWMSS1, > BBBIO_PWMSS2) > + * > + * @return : 0 for disable timebase clock , 1 for enable for timebase > clock > + */ > +static int PWMSS_TB_clock_check(unsigned int PWMSS_ID) > +{ > + volatile unsigned int* reg; > + unsigned int reg_value ; > + > + /* Control module check */ > + reg =(void *)CM_ptr + BBBIO_PWMSS_CTRL; > + reg_value = *reg ; > + > + return (reg_value & (1 << PWMSS_ID)) ; > +} > + > +/* > ----------------------------------------------------------------------------------------------- > */ > +/* PWM subsystem system control > + * enable or disable module clock > + * > + * @param PWMSS_ID : PWM sumsystem ID (BBBIO_PWMSS0 ,BBBIO_PWMSS1, > BBBIO_PWMSS2). > + * @param enable : 0 for disable , else for enable . > + * > + * @return : 1 for success , 0 for error > + */ > +static int PWMSS_module_ctrl(unsigned int PWMSS_ID, int enable) > +{ > + volatile unsigned int *reg = NULL; > + unsigned int module_set[] = {BBBIO_PWMSS0, BBBIO_PWMSS1, > BBBIO_PWMSS2}; > + unsigned int module_clk_set[] = {BBBIO_CM_PER_EPWMSS0_CLKCTRL, > BBBIO_CM_PER_EPWMSS1_CLKCTRL, BBBIO_CM_PER_EPWMSS2_CLKCTRL}; > + int ret = 1; > + > + reg = (void*)cm_per_addr + module_clk_set[PWMSS_ID]; > + if(enable) { > + if(PWMSS_TB_clock_check(module_set[PWMSS_ID])) { > + /* Enable module clock */ > + *reg = 0x2; /* Module enable and fully functional > */ > + return ret; > + } > +#ifdef BBBIO_LIB_DBG > + else { > + printf("PWMSS_module_ctrl : PWMSS-%d timebase clock > disable in Control Module\n", PWMSS_ID); > + } > +#endif > + ret = 0 ; > + } > + *reg = 0x3 << 16; /* Module is disabled and cannot be accessed > */ > + return ret; > +} > + > +/* > ----------------------------------------------------------------------------------------------- > */ > +/* PWM init > + * iolib_init will run this function automatically > + * > + * @return : 1 for success , 0 for failed > + */ > + > +int BBBIO_PWM_Init() > +{ > + int i = 0; > + > + if (memh == 0) { > +#ifdef BBBIO_LIB_DBG > + printf("BBBIO_PWM_Init: memory not mapped?\n"); > +#endif > + return 0; > + } > + > + /* Create Memory map */ > + for (i = 0 ; i < 3 ; i ++) { > + pwmss_ptr[i] = mmap(0, PWMSS_MMAP_LEN, PROT_READ | > PROT_WRITE, MAP_SHARED, memh, PWMSS_AddressOffset[i]); > + if(pwmss_ptr[i] == MAP_FAILED) { > +#ifdef BBBIO_LIB_DBG > + printf("BBBIO_PWM_Init: PWMSS %d mmap failure!\n", i); > +#endif > + goto INIT_ERROR ; > + } > + ecap_ptr[i] = (void *)pwmss_ptr[i] + 0x100 ; > + eqep_ptr[i] = (void *)pwmss_ptr[i] + 0x180 ; > + epwm_ptr[i] = (void *)pwmss_ptr[i] + 0x200 ; > + > + if(!PWMSS_module_ctrl(i, 1)) { > +#ifdef BBBIO_LIB_DBG > + printf("BBBIO_PWM_Init: PWMSS %d clock failure!\n", > i); > +#endif > + goto INIT_ERROR ; > + } > + } > + return 1; > + > +INIT_ERROR : > + BBBIO_PWM_Release(); > + return 0; > +} > + > +/* > ----------------------------------------------------------------------------------------------- > */ > +void BBBIO_PWM_Release() > +{ > + int i = 0; > + for(i = 0 ; i < 3 ; i ++) { > + if(pwmss_ptr[i] != NULL) { > + munmap((void *)pwmss_ptr[i], PWMSS_MMAP_LEN); > + pwmss_ptr[i] = NULL; > + ecap_ptr[i] = NULL; > + eqep_ptr[i] = NULL; > + epwm_ptr[i] = NULL; > + } > + } > +} > + > +/* > ----------------------------------------------------------------------------------------------- > */ > +/* PWMSS status (no effect now) > + * set pluse rgument of epwm module > + * > + * @param PWMID : EPWMSS number , 0~3 > + * > + * @return : 1 for success , 0 for failed > + */ > +int BBBIO_PWMSS_Status(unsigned int PWMID) > +{ > + int param_error = 1; > + volatile unsigned int* reg; > + unsigned int reg_value ; > + > + if (memh == 0) > + param_error = 0; > + > + if (PWMID > 2) /* if input is not EPWMSS 0~ WPEMSS 2 */ > + param_error = 0; > + > + if (param_error == 0) { > +#ifdef BBBIO_LIB_DBG > + printf("BBBIO_PWM_Status: parameter error!\n"); > +#endif > + return 0; > + } > + > + reg =(void *)CM_ptr + BBBIO_PWMSS_CTRL; > + > + reg_value = *reg >> PWMID & 0x01 ; > + if(reg_value == 0) { > + printf("PWMSS [%d] Timebase clock Disable , Control Module > [pwmss_ctrl register]\n", PWMID); > + } > + else { > + reg=(void *)pwmss_ptr[PWMID] + PWMSS_CLKSTATUS; > + reg_value = *reg ; > + > + printf("PWMSS [%d] :\tCLKSTOP_ACK %d , CLK_EN_ACK %d , > CLKSTOP_ACK %d , CLK_EN_ACK %d , CLKSTOP_ACK %d , CLK_EN_ACK %d\n", > + PWMID , > + reg_value >>9 & 0x1 , > + reg_value >>8 & 0x1 , > + reg_value >>5 & 0x1 , > + reg_value >>4 & 0x1 , > + reg_value >>1 & 0x1 , > + reg_value >>0 & 0x1 ); > + } > + return 1 ; > +} > +/* > ----------------------------------------------------------------------------------------------- > */ > +/* PWMSS setting > + * set pluse rgument of epwm module > + * > + * @param PWMID : EPWMSS number , 0~2 > + * @param HZ : pluse HZ > + * @param dutyA : Duty Cycle in ePWM A > + * @param dutyB : Duty Cycle in ePWM B > + * > + * @return : 1 for success , 0 for failed > + * > + * @example : BBBIO_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 BBBIO_PWMSS_Setting(unsigned int PWMID , float HZ ,float dutyA ,float > dutyB) > +{ > + int param_error = 1; > + volatile unsigned short* reg16 ; > + if (memh == 0) > + param_error = 0; > + if (PWMID > 2) // if input is not EPWMSS 0~ WPEMSS 2 > + param_error = 0; > + 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) { > +#ifdef BBBIO_LIB_DBG > + printf("BBBIO_PWMSS_Setting: parameter error!\n"); > +#endif > + return 0; > + } > + > + dutyA /= 100.0f ; > + dutyB /= 100.0f ; > + > + /* compute neccessary 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 , comput time per cycle > (ns) */ > + > + > + Divisor = (Cyclens / 655350.0f) ; /* am335x provide (128*14) > divider , and per TBPRD means 10 ns when divider /1 , > + * and max TBPRD is 65535 , > so , the max cycle is 128*14* 65535 *10ns > + */ > +#ifdef BBBIO_LIB_DBG > + printf("Cyclens %f , Divisor %f\n", Cyclens, Divisor); > +#endif > + > + if(Divisor > (128 * 14)) { > +#ifdef BBBIO_LIB_DBG > + printf("BBBIO_PWMSS_Setting : Can't generate %f HZ \n", HZ); > +#endif > + return 0; > + } > + else { > + /* using Exhaustive Attack metho */ > + 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 ; > + } > + } > + } > +#ifdef BBBIO_LIB_DBG > + printf("nearest CLKDIV %f , HSPCLKDIV %f\n" > ,CLKDIV_div[NearCLKDIV] ,HSPCLKDIV_div[NearHSPCLKDIV]); > +#endif > + NearTBPRD = (Cyclens / (10.0 *CLKDIV_div[NearCLKDIV] > *HSPCLKDIV_div[NearHSPCLKDIV])) ; > + > +#ifdef BBBIO_LIB_DBG > + printf("nearest TBPRD %d, %f %f\n ",NearTBPRD,NearTBPRD * > dutyA, NearTBPRD * dutyB); > +#endif > + > + /* setting clock diver and freeze time base */ > + reg16=(void*)epwm_ptr[PWMID] +EPWM_TBCTL; > + *reg16 = TBCTL_CTRMODE_FREEZE | (NearCLKDIV << 10) | > (NearHSPCLKDIV << 7); > + > + /* setting duty A and duty B */ > + reg16=(void*)epwm_ptr[PWMID] +EPWM_CMPB; > + *reg16 =(unsigned short)((float)NearTBPRD * dutyB); > + > + reg16=(void*)epwm_ptr[PWMID] +EPWM_CMPA; > + *reg16 =(unsigned short)((float)NearTBPRD * dutyA); > + > + reg16=(void*)epwm_ptr[PWMID] +EPWM_TBPRD; > + *reg16 =(unsigned short)NearTBPRD; > + > + /* reset time base counter */ > + reg16 = (void *)epwm_ptr[PWMID] + EPWM_TBCNT; > + *reg16 = 0; > + } > + return 1; > +} > +/* > ----------------------------------------------------------------------------------------------- > */ > +/* Enable/Disable ehrPWM module > + * @param PWMID : PWMSS number , 0~2 > + * > + * @return : void > + * > + * @example : BBBIO_PWMSS_Enable(0) ;// Enable PWMSS 0 > + */ > + > +void BBBIO_ehrPWM_Enable(unsigned int PWMSS_ID) > +{ > + volatile unsigned short *reg16 ; > + > + reg16=(void*)epwm_ptr[PWMSS_ID] +EPWM_AQCTLA; > + *reg16 = 0x2 | ( 0x3 << 4) ; > + > + reg16=(void*)epwm_ptr[PWMSS_ID] +EPWM_AQCTLB; > + *reg16 = 0x2 | ( 0x3 << 8) ; > + > + reg16 = (void *)epwm_ptr[PWMSS_ID] + EPWM_TBCNT; > + *reg16 = 0; > + > + reg16=(void *)epwm_ptr[PWMSS_ID] + EPWM_TBCTL; > + *reg16 &= ~0x3; > +} > + > +void BBBIO_ehrPWM_Disable(unsigned int PWMSS_ID) > +{ > + volatile unsigned short *reg16 ; > + reg16=(void *)epwm_ptr[PWMSS_ID] + EPWM_TBCTL; > + *reg16 |= 0x3; > + > + reg16=(void*)epwm_ptr[PWMSS_ID] +EPWM_AQCTLA; > + *reg16 = 0x1 | ( 0x3 << 4) ; > + > + reg16=(void*)epwm_ptr[PWMSS_ID] +EPWM_AQCTLB; > + *reg16 = 0x1 | ( 0x3 << 8) ; > + > + reg16 = (void *)epwm_ptr[PWMSS_ID] + EPWM_TBCNT; > + *reg16 = 0; > +} > +//-------------------------------------------------------- > + > + > + > + > + > + > + > + > + > + > + > + > diff --git a/c/src/lib/libcpu/arm/shared/include/am335x.h > b/c/src/lib/libcpu/arm/shared/include/am335x.h > index 2009cef..2ba5a98 100644 > --- a/c/src/lib/libcpu/arm/shared/include/am335x.h > +++ b/c/src/lib/libcpu/arm/shared/include/am335x.h > @@ -467,4 +467,13 @@ > #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 > + > +/* Registers for PWM Subsystem */ > +#define BBBIO_PWMSS_CTRL (0x664) > +#define BBBIO_CM_PER_EPWMSS0_CLKCTRL (0xD4) > +#define BBBIO_CM_PER_EPWMSS1_CLKCTRL (0xCC) > +#define BBBIO_CM_PER_EPWMSS2_CLKCTRL (0xD8) > +#define BBBIO_CONTROL_MODULE (0x44e10000) > +#define BBBIO_CM_PER_ADDR (0x44e00000) > +#define PWMSS_CLKSTATUS (0xC) > -- > 2.7.1 > _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel