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.

TMS320F28377S: Multiple SOC, channels, interrupts, and trigger source problem

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?