Tool/software: Code Composer Studio
Hi,
I need to sample six channels in to two groups triggered with Epwm with a phase between them, but I can´t.
Something I must be doing wrong or I don't understand. If I group them altogether within the same trigger source everything works fine. This is the code that works OK
/******************************************************************************
* ADC Init
*******************************************************************************/
void InitAdcManager(void)
{
memset(&ControlAdc,0,sizeof(sControlAdc));
EALLOW;
PieVectTable.ADCINT2 = &adc_isr_grupo_2;
EDIS;
InitAdc();
AdcOffsetSelfCal();
// Enable CPU INT1 which is connected to ADCINT1:
IER |= M_INT1;
// Enable ADCINT2 in PIE
PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // Enable INT 1.2 in the PIE
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT2E = 1; //Enabled ADCINT2
AdcRegs.INTSEL1N2.bit.INT2CONT = 0; //Disable ADCINT2 Continuous mode
AdcRegs.INTSEL1N2.bit.INT2SEL = 5; //setup EOC5 to trigger ADCINT2 to fire
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // A0 NUEVA PLACA set SOC0 GRID.V 1
AdcRegs.ADCSOC1CTL.bit.CHSEL = 9; // B1 set SOC1 GRID.I 2
AdcRegs.ADCSOC2CTL.bit.CHSEL = 0xA; // B2 set SOC2 BUS.V 8
AdcRegs.ADCSOC3CTL.bit.CHSEL = 1; // A1 set SOC3 INVERTER.V 9
AdcRegs.ADCSOC4CTL.bit.CHSEL = 8; // B2 set SOC4 INVERTER.I a
AdcRegs.ADCSOC5CTL.bit.CHSEL = 2; // A2 set SOC5 I.INV 0
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC0 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC1 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC0CTL.bit.ACQPS = 8; //set SOC0 S/H Window to 9 ADC Clock Cycles, (8 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 8; //set SOC1 S/H Window to 9 ADC Clock Cycles, (8 ACQPS plus 1)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 8; //set SOC2 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 8; //set SOC3 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 8; //set SOC4 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC5CTL.bit.ACQPS = 8; //set SOC5 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
EDIS;
}
/******************************************************************************
* ADC Interrupt
*******************************************************************************/
__interrupt void adc_isr_grupo_2(void)
{
//GpioDataRegs.GPASET.bit.GPIO7 = 1;
EALLOW;
SysCtrlRegs.WDKEY = 0x00AA;
EDIS;
ControlAdc.Lectura.Canal_0 = AdcResult.ADCRESULT0;
ControlAdc.Lectura.Canal_1 = AdcResult.ADCRESULT1;
ControlAdc.Lectura.Canal_2 = AdcResult.ADCRESULT2;
ControlAdc.Lectura.Canal_3 = AdcResult.ADCRESULT3;
ControlAdc.Lectura.Canal_4 = AdcResult.ADCRESULT4;
ControlAdc.Lectura.Canal_5 = AdcResult.ADCRESULT5;
AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;
return;
}
// PWM Configuration
EPwm6Regs.TBCTR = 0;
EPwm6Regs.TBPRD = TIMER_PERIOD;
EPwm6Regs.CMPA.half.CMPA = TIMER_PERIOD / 4 ; // Uso Comparador A para disparar antes del 0 y centrar el muestro para la mínima potencia
EPwm6Regs.TBPHS.half.TBPHS = 0;
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW; // Sync down-stream module
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm6Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
// Configure the Start of Conversion for the ADC. ePWM5 is the trigger.
// At TBCNT1 = CMPA start to convert all the channel
EPwm6Regs.ETSEL.bit.SOCAEN = 1;
EPwm6Regs.ETSEL.bit.SOCASEL = ET_CTRD_CMPA; // Comparador A En Descendente
EPwm6Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate pulse on 1st event*/
But if I want to split them into two groups triggered with different EPWMs causing a delay between groups, the behavior of the interrupts of the ADC are erratic. I don´t know what is happening. What I see is that the interruption of the Adc´s are unstable in time. Is not interrupting always at the same time. What I am doing wrong?
The code is this
/******************************************************************************
* ADC Init
*******************************************************************************/
void InitAdcManager(void)
{
memset(&ControlAdc,0,sizeof(sControlAdc));
EALLOW;
PieVectTable.ADCINT1 = &adc_isr_grupo_1;
PieVectTable.ADCINT2 = &adc_isr_grupo_2;
EDIS;
InitAdc();
AdcOffsetSelfCal();
// Enable CPU INT1 which is connected to ADCINT1:
IER |= M_INT1;
// Enable ADCINT1 in PIE
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
// Enable ADCINT2 in PIE
PieCtrlRegs.PIEIER1.bit.INTx2 = 1; // Enable INT 1.2 in the PIE
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT1E = 1; //Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; //Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 2; //setup EOC2 to trigger ADCINT1 to fire
AdcRegs.INTSEL1N2.bit.INT2E = 1; //Enabled ADCINT2
AdcRegs.INTSEL1N2.bit.INT2CONT = 0; //Disable ADCINT2 Continuous mode
AdcRegs.INTSEL1N2.bit.INT2SEL = 5; //setup EOC5 to trigger ADCINT2 to fire
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; // A0 NUEVA PLACA set SOC0 GRID.V 1
AdcRegs.ADCSOC1CTL.bit.CHSEL = 9; // B1 set SOC1 GRID.I 2
AdcRegs.ADCSOC2CTL.bit.CHSEL = 0xA; // B2 set SOC2 BUS.V 8
AdcRegs.ADCSOC3CTL.bit.CHSEL = 1; // A1 set SOC3 INVERTER.V 9
AdcRegs.ADCSOC4CTL.bit.CHSEL = 8; // B2 set SOC4 INVERTER.I a
AdcRegs.ADCSOC5CTL.bit.CHSEL = 2; // A2 set SOC5 I.INV 0
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = ADCTRIG_EPWM5_SOCA; //set SOC0 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = ADCTRIG_EPWM5_SOCA; //set SOC1 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = ADCTRIG_EPWM5_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = ADCTRIG_EPWM6_SOCA; //set SOC2 start trigger on TINT0, due to round-robin SOC0 converts first then SOC1, then SOC2
AdcRegs.ADCSOC0CTL.bit.ACQPS = 8; //set SOC0 S/H Window to 9 ADC Clock Cycles, (8 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 8; //set SOC1 S/H Window to 9 ADC Clock Cycles, (8 ACQPS plus 1)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 8; //set SOC2 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 8; //set SOC3 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 8; //set SOC4 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC5CTL.bit.ACQPS = 8; //set SOC5 S/H Window to 9 ADC Clock Cycles, (6 ACQPS plus 1)
EDIS;
}
/******************************************************************************
* Interrupción ADC
*******************************************************************************/
__interrupt void adc_isr_grupo_1(void)
{
//GpioDataRegs.GPASET.bit.GPIO7 = 1;
EALLOW;
SysCtrlRegs.WDKEY = 0x00AA;
EDIS;
ControlAdc.Lectura.Canal_0 = AdcResult.ADCRESULT0;
ControlAdc.Lectura.Canal_1 = AdcResult.ADCRESULT1;
ControlAdc.Lectura.Canal_2 = AdcResult.ADCRESULT2;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;
return;
}
/******************************************************************************
* Interrupción ADC
*******************************************************************************/
__interrupt void adc_isr_grupo_2(void)
{
//GpioDataRegs.GPASET.bit.GPIO7 = 1;
EALLOW;
SysCtrlRegs.WDKEY = 0x00AA;
EDIS;
ControlAdc.Lectura.Canal_3 = AdcResult.ADCRESULT3;
ControlAdc.Lectura.Canal_4 = AdcResult.ADCRESULT4;
ControlAdc.Lectura.Canal_5 = AdcResult.ADCRESULT5;
AdcRegs.ADCINTFLGCLR.bit.ADCINT2 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
GpioDataRegs.GPACLEAR.bit.GPIO7 = 1;
return;
}
PWMs Configs
EPwm5Regs.TBCTR = 0;
EPwm5Regs.TBPRD = TIMER_PERIOD;
EPwm5Regs.CMPA.half.CMPA = TIMER_PERIOD - ( TOTAL_CONVERSION / 2 ) ; // Uso Comparador A para disparar antes del 0 y centrar el muestro para la mínima potencia
EPwm5Regs.TBPHS.half.TBPHS = 0;
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm5Regs.TBCTL.bit.PRDLD = TB_SHADOW; // Sync down-stream module
EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm5Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm5Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
EPwm5Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm5Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm5Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm5Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
// Configure the Start of Conversion for the ADC. ePWM5 is the trigger.
// At TBCNT1 = CMPA start to convert all the channel
EPwm5Regs.ETSEL.bit.SOCAEN = 1;
EPwm5Regs.ETSEL.bit.SOCASEL = ET_CTRU_CMPA; // Comparador A como Evento
EPwm5Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate pulse on 1st event*/
EPwm6Regs.TBCTR = 0;
EPwm6Regs.TBPRD = TIMER_PERIOD;
EPwm6Regs.CMPA.half.CMPA = TIMER_PERIOD / 4 ; // Uso Comparador A para disparar antes del 0 y centrar el muestro para la mínima potencia
EPwm6Regs.TBPHS.half.TBPHS = 0;
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW; // Sync down-stream module
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm6Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync "down-stream"
EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
// Configure the Start of Conversion for the ADC. ePWM5 is the trigger.
// At TBCNT1 = CMPA start to convert all the channel
EPwm6Regs.ETSEL.bit.SOCAEN = 1;
EPwm6Regs.ETSEL.bit.SOCASEL = ET_CTRD_CMPA; // Comparador A En Descendente
EPwm6Regs.ETPS.bit.SOCAPRD = ET_1ST; // Generate pulse on 1st event*/
Best Regards
Fernando Gatto
From Argentina