Hi There,
In my software I would like to achieve sequential conversion of the signals going into the adc A module, such that:
When the EPWM6 CTR = 0, I start converting the signals on ADC A2, ADC A3, ADC A4, ADC A5, and when all the previous conversions are completed the last one will generate an interrupt.
I have used the code below, for the Epwm configuration:
EPwm6Regs.ETSEL.bit.SOCAEN = 1; EPwm6Regs.ETSEL.bit.SOCASEL = 1; // generate SOCA pulse when TBCTR =0 EPwm6Regs.ETPS.bit.SOCAPRD = 1;
and for the ADC configuration:
void ConfigureADC_A(void)
{
EALLOW;
//write configurations
AdcaRegs.ADCCTL2.bit.PRESCALE = 6; // set ADCCLK divider to INPUT CLOCK /4
AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
//Set pulse positions to late
AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
//power up the ADC
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
//delay for 1ms to allow ADC time to power up
DELAY_US(1000);
EDIS;
}
and configured each channel as:
void SetupADC_A()
{
Uint16 acqps;
//determine minimum acquisition window (in SYSCLKS) based on resolution (SYSCLK = 200MHz)
if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){
acqps = 19; //(19+1)/200MHz = 100ns. The min is 75ns
}
else { //resolution is 16-bit
acqps = 63; //320ns ((63+1)*(1/200MHz))
}
//Select the channels to convert and end of conversion flag
EALLOW;
AdcaRegs.ADCSOC2CTL.bit.CHSEL = 2;
AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample and hold window
AdcaRegs.ADCSOC2CTL.bit.TRIGSEL = 15; // 0Fh ADCTRIG15 - ePWM6, ADCSOCA
AdcaRegs.ADCSOC3CTL.bit.CHSEL = 3;
AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample and hold window
AdcaRegs.ADCSOC3CTL.bit.TRIGSEL = 15; //0Fh ADCTRIG15 - ePWM6, ADCSOCA
AdcaRegs.ADCSOC4CTL.bit.CHSEL = 4;
AdcaRegs.ADCSOC4CTL.bit.ACQPS = acqps; //sample and hold window
AdcaRegs.ADCSOC4CTL.bit.TRIGSEL = 15; //0Fh ADCTRIG15 - ePWM6, ADCSOCA
AdcaRegs.ADCSOC5CTL.bit.CHSEL = 5;
AdcaRegs.ADCSOC5CTL.bit.ACQPS = acqps; //sample and hold window
AdcaRegs.ADCSOC5CTL.bit.TRIGSEL = 15; // 0Fh ADCTRIG15 - ePWM6, ADCSOCA
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 5; // EOC5 is trigger for ADCINT1
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
}
Now in my "main.c" I have enable interrupt ADC A1:
//Map ISR functions EALLOW; PieVectTable.ADCA1_INT = &adca1_isr; EDIS; //Enable global Interrupts and higher priority real-time debug events: IER |= M_INT1; //Enable group 1 interrupts EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // Enable PIE interrupt (ref Table 2-2. PIE Channel Mapping, pag. 90) PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // enable adc_int_A_1 // interrupt ADC A1
and the interrupt looks as follow:
interrupt void adca1_isr(void) {
//********************************************
// Translate Adc measurements into double
//********************************************
AdcaResults2 = AdcaResultRegs.ADCRESULT2; //
AdcaResults3 = AdcaResultRegs.ADCRESULT3; //
AdcaResults4 = AdcaResultRegs.ADCRESULT4; //
AdcaResults5 = AdcaResultRegs.ADCRESULT5; //
i1_meas = (-0.004346) * ((double) (AdcaResults2)) + i1_meas_offset;
i2_meas = (-0.01622) * ((double) (AdcaResults3)) + i2_meas_offset;
v1_meas = (double)(AdcaResults4) * (- 0.03948) + v1_meas_offset;
v2_meas = (-0.08432) * ((double) (AdcaResults5)) + v2_meas_offset;
//...
//... PI controller code execution + PWM CMP update
//...
//********************************************
// Clearing the ADC interrupt
//********************************************
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
Is this the correct procedure to have the adc channels A2, A3, A4, A5 sampled in sequence? and is the interrupt "started" indeed after all the ADC conversion have been completed?
I am asking because I would like to be sure that inside the interrupt all the values sampled by the ADC are correct (and conversions are completed) in order to properly execute the control...
Your opinion would really help,
Thank you so much,
Leo