Hi all,
I am playing with the Piccolo F28035 examples and try to understand the ADC timings.
I want to start sequential AD conversion for channels 0..5 on PWM timer equal to zero and get an interrupt when all channels are sampled.
I have set up the ADC and PWM so that the PWM timer is upcounting and triggering an SOC on A group on time-base counter equal to zero.
The ADC SOC start triggers are set up for start on ePWM1A (for several ADC channels, here 0..5).
I have setup EOC0..5 to trigger ADCINT1 to fire and measured the PWM counter when entering the interrupt for the different EOC trigger 0..5 settings.
I get the following timing values (measured via breakpoint on interrupt entry):
setup EOC0 to trigger ADCINT1 to fire: EPwm1Regs.TBCTR = 22
setup EOC1 to trigger ADCINT1 to fire: EPwm1Regs.TBCTR = 27
setup EOC2 to trigger ADCINT1 to fire: EPwm1Regs.TBCTR = 34
setup EOC3 to trigger ADCINT1 to fire: EPwm1Regs.TBCTR = 40
setup EOC4 to trigger ADCINT1 to fire: EPwm1Regs.TBCTR = 47
setup EOC5 to trigger ADCINT1 to fire: EPwm1Regs.TBCTR = 53
The first timer value is clear, EOC pulse after 22 cycles is like in the datasheet.
The following samples do not take 13 cycles as described in the datasheet, but only 5..7 cycles.
Where is my fault?
Here is my code:
// Enable ADCINT1 in PIE
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
IER |= M_INT1; // Enable CPU Interrupt 1
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
LoopCount = 0;
ConversionCount = 0;
// Configure ADC
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 = 0; //setup EOC0 to trigger ADCINT1 to fire
//AdcRegs.INTSEL1N2.bit.INT1SEL = 1; //setup EOC1 to trigger ADCINT1 to fire
//AdcRegs.INTSEL1N2.bit.INT1SEL = 2; //setup EOC2 to trigger ADCINT1 to fire
//AdcRegs.INTSEL1N2.bit.INT1SEL = 3; //setup EOC3 to trigger ADCINT1 to fire
AdcRegs.INTSEL1N2.bit.INT1SEL = 5; //setup EOC4 to trigger ADCINT1 to fire
AdcRegs.ADCSOC0CTL.bit.CHSEL = 4; //set SOC0 channel select to ADCINA4
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //set SOC0 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.CHSEL = 2; //set SOC1 channel select to ADCINA2
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 5; //set SOC1 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //set SOC1 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC2CTL.bit.CHSEL = 3; //set SOC2 channel select to ADCINA3
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 5; //set SOC2 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; //set SOC2 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC3CTL.bit.CHSEL = 5; //set SOC3 channel select to ADCINA5
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 5; //set SOC3 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; //set SOC3 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC4CTL.bit.CHSEL = 7; //set SOC4 channel select to ADCINA5
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 5; //set SOC4 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6; //set SOC4 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC5CTL.bit.CHSEL = 9; //set SOC5 channel select to ADCINA5
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 5; //set SOC5 start trigger on EPWM1A, due to round-robin SOC0 converts first then SOC1
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6; //set SOC5 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
EDIS;
// Assumes ePWM1 clock is already enabled in InitSysCtrl();
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
//EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from CPMA on upcount
EPwm1Regs.ETSEL.bit.SOCASEL = 1; // Enable event time-base counter equal to zero. (TBCTR = 0x0000)
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
EPwm1Regs.CMPA.half.CMPA = 0x0080; // Set compare A value
EPwm1Regs.TBPRD = 0xFFFF; // Set period for ePWM1
EPwm1Regs.TBCTL.bit.CTRMODE = 0; // count up and start
// Wait for ADC interrupt
for(;;)
{
LoopCount++;
}
}
interrupt void adc_isr(void)
{
Voltage1[ConversionCount] = AdcResult.ADCRESULT0; // <- here is the breakpoint and EPwm1Regs.TBCTR measured
Voltage2[ConversionCount] = AdcResult.ADCRESULT1;
Voltage3[ConversionCount] = AdcResult.ADCRESULT2;
// If 20 conversions have been logged, start over
if(ConversionCount >= 9)
{
ConversionCount = 0;
}
else ConversionCount++;
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
return;
}