Part Number: TMS320F28377S
Hello TI community,
Currently I am able to get convert two different ADC pins/channels with SOC0 using EPwm1 generating SOCA on each period. I am able to fill two separate arrays, one array per channel (A2 and B2), using an interrupt based on end of conversions on SOCA. I am currently trying to implement a third ADC channel with it's own trigger source and interrupt routine. I am trying to use EPwm3 as the SOCA trigger source and the SOC1 module. After trying to debug, I gave up and bit and commented out some things. I am able to get EPwm3 to generate SOCA for pin ADCINB0 when I have the following code (using SOC0).
EALLOW;
PieVectTable.ADCB1_INT = &generic_isr_2;
EDIS;
config_ADC(ADC[ADC_ADCB], ADC_ADCB);
config_EPwm_SOCA(ePWM[3]);
setup_ADC_SOC0(0, ADC[ADC_ADCB], 9);
setup_ADC_INT_TRIG(ADC[ADC_ADCB], 0);
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx2 = 1;
EINT;
ERTM;
//--Interrupts--//
interrupt void generic_isr_2(void)
{
adc_sample_buffer[bufferIndex] = AdcbResultRegs.ADCRESULT0; // test buffer to hold the dc value of the battery
bufferIndex++;
if(ADC_BUF_LEN <= bufferIndex)
{
bufferIndex = 0;
bufferFull = 1;
}
AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//--Functions--//
// config_ADC - Write ADC configurations and power up the ADC
void config_ADC(volatile struct ADC_REGS *ADC, Uint16 adc)
{
EALLOW;
//write configurations
(*ADC).ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 maximum speed of ADCCLK is 50 Mhz = 200 MHz/4
AdcSetMode(adc, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);
//Set pulse positions to late
(*ADC).ADCCTL1.bit.INTPULSEPOS = 1;
//power up the ADC
(*ADC).ADCCTL1.bit.ADCPWDNZ = 1;
//delay for 1ms to allow ADC time to power up
DELAY_US(1000);
EDIS;
}
// config_EPwm_SOCA to generate event on SOCA
void config_EPwm_SOCA(volatile struct EPWM_REGS *ePWM)
{
EALLOW;
// the counter clk, TBCLK, is calculated by the following: "TBCLK = EPWMCLK / (HSPCLKDIV * CLKDIV)"
// EPWMCLK should be equal to SYSCLK/2 which is 100 MHz
(*ePWM).TBCTL.bit.CLKDIV = 0; // configures the divider to /1
(*ePWM).TBCTL.bit.HSPCLKDIV = 0; // configures the high speed divider to /1
// Assumes ePWM clock is already enabled
(*ePWM).ETSEL.bit.SOCAEN = 0; // Disable SOC on A group
(*ePWM).ETSEL.bit.SOCASEL = 4; // Select SOC on up-count
(*ePWM).ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
//EPwm1Regs.CMPA.bit.CMPA = 195; // Generate event on CMPA value // not necessary
(*ePWM).TBPRD = 194; // TBPRD = EPWM Period value - 1
(*ePWM).TBCTL.bit.CTRMODE = TB_FREEZE; // freeze counter
EDIS;
}
void setup_ADC_SOC0(Uint16 adc_channel, volatile struct ADC_REGS *ADC, Uint16 trigger)
{
Uint16 acqps;
//determine minimum acquisition window (in SYSCLKS) based on resolution
if(ADC_RESOLUTION_12BIT == (*ADC).ADCCTL2.bit.RESOLUTION)
{
acqps = 14; //75ns
}
else //resolution is 16-bit
{
acqps = 63; //320ns
}
EALLOW;
(*ADC).ADCSOC0CTL.bit.CHSEL = adc_channel; //SOCx will convert selected adc_channel of chosen ADC
(*ADC).ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
(*ADC).ADCSOC0CTL.bit.TRIGSEL = trigger;//5; //trigger
EDIS;
}
void setup_ADC_INT_TRIG(volatile struct ADC_REGS *ADC, Uint16 end_of_conversion)
{
EALLOW;
(*ADC).ADCINTSEL1N2.bit.INT1SEL = end_of_conversion; // EOCx will set INT1 flag of chosen ADC
(*ADC).ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
(*ADC).ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
EDIS;
}
When I change the SOC0 to be SOC1, it stops working - does anyone have an idea of how to fix this or is my understanding of what SOC0 and SOC1 differences incorrect?