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.

TMS320F28379D: config ADC to perform sequential SOC conversions ons SW trigger

Part Number: TMS320F28379D
Hello there,
I´m a bit confused About how to configure the ADC to do Serial conversions on a few SOC´s.
The Controller has 3 ADC´s 1 to 3. On each ADC I want  SOC 0 to 3 to perform a sequential conversion and SOC3 of ADC_A to throw an Interrupt when done.
Until 2 weeks ago everything worked fine but now I observe faulty behavior and I´m doubting if I have done the a correct configuration.
1st Thing I don´t understand is the difference of ADCIN1/2 and the "four flexible PIE Interrupts"  (see spruhm8f / Reference Manual -> 10.1.1 Features)
I think ADCIN1/2 do NOT mean an Interrupt to the CPU but only for ADC internal Purpose?
2nd Thing in spruhm8f / Reference Manual -> 10.1.4.2 Trigger Operation  it is said, "This is useful for creating continuous conversions." I think it means
continous conversions of the same SOC? Or does it mean one SOC can trigger another one? How would one configure that?
3thrd my solution Regading my Goal to create a sequential conversion of SOC 0 to 3, I make use of the round Robin scheeme explained in
spruhm8f / Reference Manual -> 10.1.6 ADC Conversion Priority. The way I understand this is it is good, if I set SOC 3 to throw an Interrupt when done
and trigger the SOC´s all together.
Plus I´m not sure what is best practice to check, if the ADC is busy. I´ve see, there are busy flags, but I´m not 100% sure how to use them properly.
See below the Adc_Trigger and Init ans ISR.
best regards,
Moe
In ISR I do
  AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
  PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;// Acknowledge this interrupt to receive more interrupts from group 1
void StartCon(void)
{
 EALLOW;
 AdccRegs.ADCSOCFRC1.all = 15 ;
 AdcbRegs.ADCSOCFRC1.all = 15 ;
 AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 3; //end of SOC3 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
 AdcaRegs.ADCSOCFRC1.all = 15 ;
 EDIS;
}
InitAdc() 
 {
   // TODO Auto-generated constructor stub
      EALLOW;
      //
      //write configurations
      //
      AdcaRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
      AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
      AdcbRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
      AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
      AdccRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4
      AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
      //
      //Set pulse positions to late
      //
      AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
      AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;
      AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;
      //
      //power up the ADC
      //
      AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
      AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;
      AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;
      //
      //delay for 1ms to allow ADC time to power up
      //
      DELAY_US(1000);
      EDIS;
      Uint16 acqps;
       //
       //determine minimum acquisition window (in SYSCLKS) based on resolution
       //
       if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION)
       {
           acqps = 14; //75ns
       }
       else //resolution is 16-bit
       {
           acqps = 63; //320ns
       }
       //
       //Select the channels to convert and end of conversion flag
       //
       EALLOW;
       AdccRegs.ADCSOC0CTL.bit.CHSEL = 2;  //SOC0 will convert pin A0
       AdccRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
       AdccRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
       AdcaRegs.ADCSOC0CTL.bit.CHSEL = 14;  //SOC0 will convert pin A1
       AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
       AdcaRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
       AdccRegs.ADCSOC1CTL.bit.CHSEL = 5;  //SOC0 will convert pin A2
       AdccRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
       AdccRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
       AdccRegs.ADCSOC2CTL.bit.CHSEL = 4;  //SOC0 will convert pin A3
       AdccRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
       AdccRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
       AdcaRegs.ADCSOC1CTL.bit.CHSEL = 4;  //SOC0 will convert pin A4
       AdcaRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
       AdcaRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
       AdcbRegs.ADCSOC0CTL.bit.CHSEL = 5;  //SOC0 will convert pin A0
       AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
       AdcbRegs.ADCINTSOCSEL1.bit.SOC0 = 0;
  ///////////////////////////////////////////////////////////////////////////////////////////////
      AdcbRegs.ADCSOC1CTL.bit.CHSEL = 2;  //SOC0 will convert pin A0
   AdcbRegs.ADCSOC1CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
   AdcbRegs.ADCINTSOCSEL1.bit.SOC1 = 0;
   AdccRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC0 will convert pin A1
   AdccRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
   AdccRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
   AdcaRegs.ADCSOC2CTL.bit.CHSEL = 3;  //SOC0 will convert pin A2
   AdcaRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
   AdcaRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
   AdcbRegs.ADCSOC2CTL.bit.CHSEL = 4;  //SOC0 will convert pin A3
   AdcbRegs.ADCSOC2CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
   AdcbRegs.ADCINTSOCSEL1.bit.SOC2 = 0;
   AdcbRegs.ADCSOC3CTL.bit.CHSEL = 3;  //SOC0 will convert pin A4
   AdcbRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
   AdcbRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
   AdcaRegs.ADCSOC3CTL.bit.CHSEL = 5;  //SOC0 will convert pin A0
   AdcaRegs.ADCSOC3CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
   AdcaRegs.ADCINTSOCSEL1.bit.SOC3 = 0;
   ///////////////////////////////////////////////////////////////////////////////////////////////
   //AdcaRegs.ADCINTSEL1N2.bit.INT1CONT = 1; // make it unnesessarry to set back IntFlag by Code
   AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared/**/

   /*
    * The application uses ADC´s a, b and c. together with thier SOC´s. Since all SOC´s are
    * serving the same amount channels and are all triggered at the same time,
    * it is sufficient to activate only one ADC interrupt.
    */
       IER |= M_INT1;
       PieCtrlRegs.PIEIER1.bit.INTx1 = 1;// Enable TINT0 in the PIE: Group 1 interrupt 7
       PieVectTable.ADCA1_INT = &adcAint;
       EDIS;
  }
  • Hi '1161,

    I think you are on the right track; you want one trigger to set SOC0 through SOC3 on all the ADCs. At the end, only one ADC needs to generate an ISR.

    The ADCINT flag has multiple uses:
    -Can be checked directly by SW to see if results are done
    -Can be allowed to propagate through to PIE to interrupt the CPU
    -Can be looped back as a trigger to make ADC convert continuously

    This 3rd case is enabled by 'ADCINTSOCSEL1', which doesn't sound like something you want. Have a read through the TRM about these registers.

    After a cursory look though your code, you might also want to investigate:
    AdcaRegs.ADCCTL2.bit.PRESCALE = 4; //set ADCCLK divider to /4

    The comment doesn't align with the setting. 4 does not result in /4 ; check the register descriptions.