This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Code Composer Studio
Hi,
Im working with the ECAP as PWM signal. These are the details of my test:
My problems starts when I synchronize ECAP1 with ePWM1 trough the CTR_EQ_ZERO of the ePWM1 and the phase of ECAP1 is 0 or near 0. The interrupt of the eCAP nevers happends and therefore the shadow register of CAP4 is not written in CAP2 due CTR=PRD never happends!. If I dissable the synchronize both interrutptions enter without any problem and the duty values are properly written. Due to the application requierements I need the ePWM synchronized with the eCAP, there is any solution to ensure the PRD=CTR of the ECAP in order to load properly the values of CAP4? Or is possible to update CAP2 values at the synchronize moment? Because in the reference guide of the eCAP they said that CAP4 and CAP3 are loaded in CAP1 and CAP2 at PRD=CTR.
Here the code, used the same definitions that are used in the eCAP reference guide:
//============================================================================================================================== interrupt void APWM_ISR1() { _isr_counter++; // This counter is used only for debug mode if(_isr_counter>=150){_isr_counter=0;} GpioDataRegs.GPATOGGLE.bit.GPIO16=1; // Acknowledge this interrupt to receive more interrupts from group 4 PieCtrlRegs.PIEACK.all |= PIEACK_GROUP4; //Here the order is very important! First CTR_EQ_PRD then INT flag ECap1Regs.ECCLR.bit.CTR_EQ_PRD=1; //clear flag ECap1Regs.ECCLR.bit.INT=1; //clear flag } //============================================================================================================================== // ePWM interrupt interrupt void EPWM_SYNC_ISR() { ECap1Regs.CAP4= _newDuty_Value; //Uint32 variable (If its different than the start value when synch enable and phase = 0 do not update the value!) Why? ECap1Regs.CTRPHS= _newPhase_Value; //Uint32 variable /* My code for new Duty and Phase Values... Increase the duty from 0 to 1 and adapt to Uint32 values based on the PRD Change the phase value and adapt to Uint32 values based on the PRD, for ECAP1 always 0! */ // Acknowledge this interrupt to receive more interrupts from group 3 PieCtrlRegs.PIEACK.all |= PIEACK_GROUP3; // Clear EPWMxINT flag EPwm1Regs.ETCLR.bit.INT = 1; } //============================================================================================================================== // MAIN //============================================================================================================================== void main(void) { //Configuraton of DSP EALLOW; SysCtrlRegs.WDCR = 0x0068; // watchdog OFF SysCtrlRegs.PLLSTS.bit.DIVSEL = 2; // PLL SysCtrlRegs.PLLCR.bit.DIV = 10; // 30MHz * 10 / 2 = 150 MHz SysCtrlRegs.HISPCP.all = 0x0001; SysCtrlRegs.LOSPCP.all = 0x0002; SysCtrlRegs.PCLKCR0.all = 0x0000; SysCtrlRegs.PCLKCR1.all = 0x0000; SysCtrlRegs.PCLKCR3.all = 0x0000; //Enabling PWM & ECAP CLK SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // Enable CLK for EPWM1 SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM //Enabling GPIO CLK SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; //Enabling TMR0 CLK SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK=1; EDIS; //The GPIO clock must be enabled, EALLOW; //ENABLE COMMAND GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; // GPIOX = out EDIS; //Configure outputs for ePWM EALLOW; GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; GpioCtrlRegs.GPADIR.bit.GPIO1 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; GpioCtrlRegs.GPADIR.bit.GPIO4 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; GpioCtrlRegs.GPADIR.bit.GPIO5 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1; GpioCtrlRegs.GPADIR.bit.GPIO10 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1; GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // GPIOX = output EDIS; /CONFIGURE 1 PWM, FOR 50 uS PERIOD, //Time base EPwm1Regs.TBPRD=(TSW_us*75); //CLK frequency is 150 MHz, 6.67 ns. //Count type EPwm1Regs.TBPHS.half.TBPHS=0; // Set Phase register to zero EPwm1Regs.TBCTR=0; // clear TB counter EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Phase loading disabled EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //Base time EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; //Compare Shadowed mode EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //Use shadowed mode for CMPA EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; //Use shadowed mode for CMPB EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero //Counter Compare: initial values; EPwm1Regs.CMPA.half.CMPA=0; //Not PWM ratio at the start EPwm1Regs.CMPB=0; //Not PWM ratio at the start //Action Qualifier: Complementary mode EPwm1Regs.AQCTLB.bit.PRD = AQ_SET; //Set EPWMxB Transitions FROM 0 to 1 (AQ_SET) by CMPA CAD (CROSSING DOWN) EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; //Set EPWMxB Transitions FROM 1 to 0 (AQ_CLEAR) by CMPA CAU (CROSSING UP) //i.e. If CMPB increases, duty of EPWMA increases. //IF DEADBAND IS ENABLED AS COMPLEMENTARY ACTIVE HIGH, AQCTLA bits are OVERWRITTEN!!! EPwm1Regs.AQCTLA.bit.PRD = AQ_CLEAR; //Set EPWMxA Transitions FROM 1 to 0 (AQ_CLEAR) by CMPB CAD (CROSSING DOWN) EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; //Set EPWMxA Transitions FROM 0 to 1 (AQ_SET) by CMPB CAU (CROSSING UP) //i.e. If CMPB increases, duty of EPWMB decreases. //deadband EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module, rising of ePWMB is delayed, falling of ePWMA is delayed EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active HIC complementary //IF DEADBAND IS ENABLED AS COMPLEMENTARY ACTIVE HIGH, AQCTLB bits are OVERWRITTEN!!! EPwm1Regs.DBFED = dt_1; // FED = XX TBCLKs; 1 TBCLK=SYSCLKOUT = 6.67 ns; EPwm1Regs.DBRED = dt_1; // RED = XX TBCLKs; 299 ~ 2us //Configure outputs for aPWM EALLOW; // ECAP Clocks SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 1; // Enable CLK for ECAP1 SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 1; // Enable CLK for ECAP2 SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 1; // Enable CLK for ECAP3 SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 1; // Enable CLK for ECAP4 SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 1; // Enable CLK for ECAP5 SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 1; // Enable CLK for ECAP6 // ECAP pins as output GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 1; GpioCtrlRegs.GPADIR.bit.GPIO24 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 1; GpioCtrlRegs.GPADIR.bit.GPIO25 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 1; GpioCtrlRegs.GPADIR.bit.GPIO26 = 1; // GPIOX = output GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 1; GpioCtrlRegs.GPADIR.bit.GPIO27 = 1; // GPIOX = output GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 1; GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1; // GPIOX = output GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 1; GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // GPIOX = output EDIS; //Preset Values: GpioDataRegs.GPACLEAR.bit.GPIO16=1; // Define PWM duty EPwm1Regs.CMPB=(TSW_us*75)*duty1; EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; ECap1Regs.ECCTL2.bit.CAP_APWM = EC_APWM_MODE; // Enable APWM mode ECap1Regs.ECCTL2.bit.APWMPOL = EC_ACTV_LO; // Active Low ECap1Regs.ECCTL2.bit.SYNCI_EN = EC_ENABLE; // Synch: Master ePWM1 ECap1Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCIN; // Send Signal to ECAP2 ECap1Regs.ECCTL2.bit.TSCTRSTOP=EC_RUN; // RUN the clock ECap1Regs.CAP1 = 50*150; // Set Period of the signal. //Enable ECAP Interrupts DINT; //Dissable Interrupts ECap1Regs.ECEINT.all=0; //Dissable all interrupts ECap1Regs.ECCLR.all=1; //Clear all flags ECap1Regs.ECEINT.bit.CTR_EQ_PRD=1; //Enable CTR=CMP Interrupt EALLOW; *(&PieVectTable.ECAP1_INT) = APWM_ISR1; //Set the isr function IER |= M_INT4; PieCtrlRegs.PIEIER4.bit.INTx1 |= 1; EDIS; //Enable ePWM interrupts EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; // Select INT on Period event EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event // enable PWM interrupts EALLOW; *(&PieVectTable.EPWM1_INT + 0) = EPWM_SYNC_ISR; EDIS; // Enable CPU INT3 which is connected to EPWM1-6 INT: IER |= M_INT3; // PIE enable PieCtrlRegs.PIEIER3.all |= 1 << 0; //Preset APWM Values ECap1Regs.CAP1 =50*150; // Set Period value (150 no Preescaler) ECap1Regs.CAP2 =50*150*0.5; // Set Compare value (150 no Preescaler) ECap1Regs.CTRPHS = 0x0; // make phase zero //Enable Interrupts; // Enable the PIE PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enables PIE to drive a pulse into the CPU PieCtrlRegs.PIEACK.all = 0xFFFF; // Enable Interrupts at the CPU level EINT; // Enable Global realtime interrupt DBGM ERTM; //********************************************************************************* // Infinity Loop //********************************************************************************* while (1) { //**************************************************************** }//End Infinity Loop }//END MAIN
Hi Whitney,
I stop getting interrupts, but only the eCAP1 interrupt, ePWM1 PRD=CTR occurs every cycle properly. I'll try to clarify what i want to do:
There is any way to wait or check if the PRD=CTR ocurrs before update the phase or force an update of CAP2 at the sync? Or force the phase / sync_signal to update when CAP4 is loaded into CAP2? Or check if CAP2 have not been updated and therefore do not update the phase?
And why the CTR=ZERO of ePWM ocurrs before CTR=PRD of eCAP if both are set with the same period and same phase?
Miguel,