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.

TMS320F28027: Problem reading ADC on Piccolo, results look bogus

Part Number: TMS320F28027

We're using the Piccolo Launchpad to read a digitized light level coming from a photodiode.  The output from the photodiode is amplified by a PGA.  We used similar hardware on an earlier project so I'm fairly confident that this hardware should be working okay.

Using the driver model, I'm having the PWM module trigger a conversion on A1 using channel 14.  The ADC interrupt happens okay.  In the ISR, I read the value output from ADC_ResultNumber_1, store it in a local variable, and notify a loop in my main() function that displays the value at non-interrupt time.  The output value, however, is incorrect (never 0, but always far too low).

Here is the relevant code.  Can anyone see anything that might be incorrect here?

void adc_init()
{
    CLK_enableAdcClock(myClk);
    ADC_enableBandGap(myAdc);
    ADC_enableRefBuffers(myAdc);
    ADC_powerUp(myAdc);
    ADC_enable(myAdc);
    ADC_setVoltRefSrc(myAdc, ADC_VoltageRefSrc_Int);
    PIE_enableAdcInt(myPie, ADC_IntNumber_1);
    CPU_enableInt(myCpu, CPU_IntNumber_10);
    CPU_enableGlobalInts(myCpu);
    CPU_enableDebugInt(myCpu);

    // Configure ADC
    ADC_setIntPulseGenMode(myAdc, ADC_IntPulseGenMode_Prior);                       // ADCINT1 trips after AdcResults latches
    ADC_enableInt(myAdc, ADC_IntNumber_1);                                          // Enable ADCINT1 interrupt
    ADC_setIntMode(myAdc, ADC_IntNumber_1, ADC_IntMode_ClearFlag);                  // Disable ADCINT1 continuous mode
    ADC_setIntSrc(myAdc, ADC_IntNumber_1, ADC_IntSrc_EOC1);                         // EOC1 trigger causes ADCINT1 interrupt to occur
    ADC_setSocChanNumber(myAdc, ADC_SocNumber_1, ADC_SocChanNumber_B6);             // SOC1 channel select = ADCINB6
    ADC_setSocTrigSrc(myAdc, ADC_SocNumber_1, ADC_SocTrigSrc_EPWM1_ADCSOCA);        // SOC1 start trigger = EPWM1A
    ADC_setSocSampleWindow(myAdc, ADC_SocNumber_1, ADC_SocSampleWindow_7_cycles);   // SOC1 sample/hold = 7 ADC clock cycles (6 ACQPS plus 1)
}

interrupt void adc_isr(void)
{
    digitized_sample = ADC_readResult(myAdc, ADC_ResultNumber_1);
    sample_ready = 1;  // Notify main() loop for display
    ADC_clearIntFlag(myAdc, ADC_IntNumber_1);
    PIE_clearInt(myPie, PIE_GroupNumber_10);
    return;
}

  • Mike,

    Can you confirm that you want to convert ADC channel A1?  The code snippet that you posted is configured to convert ADC channel B6:

    ADC_setSocChanNumber(myAdc, ADC_SocNumber_1, ADC_SocChanNumber_B6);             // SOC1 channel select = ADCINB6

    -Tommy

  • Sorry, typo. It is using ADCINB6. But I found the problem. The PGA device is configured using SPI. I'm using an external /CS (GPIO 6) to notify the part that the configuration data is coming using a GPIO. It turns out that this GPIO by default has pull-ups enabled, and this was somehow confusing the SPI. Once I disabled the pull-up on that GPIO, the code worked fine.
  • Thanks for reporting back the root cause. We appreciate the closure.