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: Incorrect ADC results when using different modes

Part Number: TMS320F28379D

Tool/software:

I am using ADC input channels A3, B2, B3, C3, D1 and D3 to measure DC voltages. And also using the same SOC number respectively. The ADC results are only fine when i  set Interrupt SOC trigger by INT1 . The results are not fine  when i use the hardware timer interrupt or software FORCE SOC by writing to that register.
The input voltage on the input channels are as follows
A3 - 1.541 V
B2 - 1.833 V
B3 - 1.905 V
C3 - 1.514 V
D1 - 1.880 V
D3 - 1.928 V
I am using it in 12bit single ended mode in late interrupt mode with a clock prescale value of 3 .
For my application, it is sufficient to measure the voltages for every 100ms. Hence i dont want to go with method 1 as it will trigger frequently. I want to use a hardware timer interrupt to trigger SOC much slowly.
Method 1 : The SOC 3 of all four ADC is set as source of interrupt 1 for the corresponding ADC. The Interrupt 1 flag will trigger the SOCs of all 6 channels.
   ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_SW_ONLY,
                     ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED); // A3 channel for I_AC_S

    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_SW_ONLY,
                 ADC_CH_ADCIN2, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_SW_ONLY,
                 ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);

    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_SW_ONLY,
                 ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED); //C3 channel for I_AC_P

    ADC_setupSOC(ADCD_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_SW_ONLY,
                 ADC_CH_ADCIN1, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);
    ADC_setupSOC(ADCD_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_SW_ONLY,  // D4 channel added
                 ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);


    ADC_setInterruptSOCTrigger(ADCA_BASE, ADC_SOC_NUMBER3,
                                  ADC_INT_SOC_TRIGGER_ADCINT1);

    ADC_setInterruptSOCTrigger(ADCB_BASE, ADC_SOC_NUMBER2,
                               ADC_INT_SOC_TRIGGER_ADCINT1;
    ADC_setInterruptSOCTrigger(ADCB_BASE, ADC_SOC_NUMBER3,
                               ADC_INT_SOC_TRIGGER_ADCINT1);

    ADC_setInterruptSOCTrigger(ADCC_BASE, ADC_SOC_NUMBER3,
                               ADC_INT_SOC_TRIGGER_ADCINT1);

    ADC_setInterruptSOCTrigger(ADCD_BASE, ADC_SOC_NUMBER1,
                               ADC_INT_SOC_TRIGGER_ADCINT1);
    ADC_setInterruptSOCTrigger(ADCD_BASE, ADC_SOC_NUMBER3,         // added for D4
                              ADC_INT_SOC_TRIGGER_ADCINT1);

    //
    // Disable Interrupt flags
    //
    ADC_disableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_disableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_disableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_disableInterrupt(ADCD_BASE, ADC_INT_NUMBER1);

    //
    // Enable continuous mode
    //
    ADC_enableContinuousMode(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_enableContinuousMode(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_enableContinuousMode(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_enableContinuousMode(ADCD_BASE, ADC_INT_NUMBER1);

    //
    // Configure interrupt triggers
    //
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);
    ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);
    ADC_setInterruptSource(ADCD_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);

    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCD_BASE, ADC_INT_NUMBER1);
Using the method 1 settings, I am getting the desired results as shown below.
Method 2: I set hardware  timer ( generates interrupt every 100ms ) to trigger SOC. This gives me incorrect results.
   ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER3,ADC_TRIGGER_CPU1_TINT0,
                     ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED); // A3 channel for I_AC_S

    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER2,ADC_TRIGGER_CPU1_TINT0,
                 ADC_CH_ADCIN2, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_CPU1_TINT0,
                 ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);

    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER3,ADC_TRIGGER_CPU1_TINT0,
                 ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED); //C3 channel for I_AC_P

    ADC_setupSOC(ADCD_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_CPU1_TINT0,
                 ADC_CH_ADCIN1, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);
    ADC_setupSOC(ADCD_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_CPU1_TINT0,  // D4 channel added
                 ADC_CH_ADCIN3, ADC_FW_ACQS_PERIOD_SINGLE_ENDED);


    ADC_setInterruptSOCTrigger(ADCA_BASE, ADC_SOC_NUMBER3,
                                   ADC_INT_SOC_TRIGGER_NONE);

    ADC_setInterruptSOCTrigger(ADCB_BASE, ADC_SOC_NUMBER2,
                               ADC_INT_SOC_TRIGGER_NONE);
    ADC_setInterruptSOCTrigger(ADCB_BASE, ADC_SOC_NUMBER3,
                               ADC_INT_SOC_TRIGGER_NONE);

    ADC_setInterruptSOCTrigger(ADCC_BASE, ADC_SOC_NUMBER3,
                               ADC_INT_SOC_TRIGGER_NONE);

    ADC_setInterruptSOCTrigger(ADCD_BASE, ADC_SOC_NUMBER1,
                               ADC_INT_SOC_TRIGGER_NONE);
    ADC_setInterruptSOCTrigger(ADCD_BASE, ADC_SOC_NUMBER3,         // added for D4
                               ADC_INT_SOC_TRIGGER_NONE);

    //
    // Disable Interrupt flags
    //
    ADC_disableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_disableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_disableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_disableInterrupt(ADCD_BASE, ADC_INT_NUMBER1);

    //
    // Enable continuous mode
    //
    ADC_enableContinuousMode(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_enableContinuousMode(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_enableContinuousMode(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_enableContinuousMode(ADCD_BASE, ADC_INT_NUMBER1);

    //
    // Configure interrupt triggers
    //
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);
    ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);
    ADC_setInterruptSource(ADCD_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER3);

    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_enableInterrupt(ADCD_BASE, ADC_INT_NUMBER1);
Using method 2 settings, i am getting incorrect results in B2,B3,D1,D3 channels. Kindly clarify.
  • Hi,

    For your method 2: 

    What is the value for your ADC_FW_ACQS_PERIOD_SINGLE_ENDED? Do your results change if you increase this value? 

    Also, could you try assigning a few different SOCs to convert for each channel? So for ADCA, you could setup SOC1, SOC2, SOC3 to all convert channel A3, all triggered by the timer. I'm curious if you see improved results for SOC3 if you have another conversion immediately preceding it. 

    Best Regards,

    Ben Collier