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.

Piccolo ADC simultaneos sampling mode - problems

Other Parts Discussed in Thread: TMS320F28027, CONTROLSUITE

Hi Piccolo friends, 

Then I work with a Piccolo ( TMS320F28027/26 ) good processor  ( cheap and fast ), I'm a doctor degree student and I'm using this chip to build a power quality analyser. In my application I need to acquire all ad converters simultaneos. 

I want to use a dual sample hold and this mode acquire the channels:

A1 - B1  (A)

A2 -B2  ( B)

A3 - B3 (C)

A4 - B4  (D)

A6- B6 (E)

A7 - B7  (F)

A0 (G)

then I want to work with simultaneos sampling mode. 

My converter sequence need to be: 

A -> B -> C ->D -> E -> F -> G ->A

And my trigger will be a timer 0 configured to generate a interrupt the each   520.833 microseconds. 

I generated a below code : 

void adc_init()
{

EALLOW;
AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // use internal band gap reference
AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // power up band gap
AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // power up reference
AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // power up rest of ADC
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // enable ADC output
asm(" RPT#100 || NOP"); // wait 100 cycles
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; // create int pulses 1 cycle prior to output latch
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC6CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)
AdcRegs.ADCSOC7CTL.bit.ACQPS = 6; // set S/H window to 6 clk cycles (117ns)

//EOC = end of conversion event, SOC = start of conversion event
AdcRegs.INTSEL1N2.bit.INT1SEL = 0;
AdcRegs.INTSEL1N2.bit.INT2SEL = 1;
AdcRegs.INTSEL3N4.bit.INT3SEL = 0;
AdcRegs.INTSEL3N4.bit.INT4SEL = 1;
AdcRegs.INTSEL5N6.bit.INT5SEL = 0;
AdcRegs.INTSEL5N6.bit.INT6SEL = 1;
AdcRegs.INTSEL7N8.bit.INT7SEL = 0;
AdcRegs.INTSEL7N8.bit.INT8SEL = 1;
AdcRegs.INTSEL9N10.bit.INT9SEL = 0;
AdcRegs.INTSEL9N10.bit.INT10SEL = 1;



AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN2=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN4=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN6=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN8=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN10=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN12=1;
AdcRegs.ADCSAMPLEMODE.bit.SIMULEN14=1;


AdcRegs.INTSEL1N2.bit.INT1CONT = 1; // set ADCInterrupt 1 to auto clr (continuous conversion)
AdcRegs.INTSEL1N2.bit.INT1E = 1; // enable ADCInterrupt1; 0=none, 1=ADCInt1, 2=ADCInt2


AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC0CTL.bit.CHSEL= 0; // convert ADC-A0 (CH0) when SOC0 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC1CTL.bit.CHSEL= 1; // convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC2 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC2CTL.bit.CHSEL= 2; // convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC3 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC2CTL.bit.CHSEL= 3; //convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC4 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC2CTL.bit.CHSEL=4; // convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC5 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC2CTL.bit.CHSEL= 5; // convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC6 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC2CTL.bit.CHSEL= 6; // convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCINTSOCSEL1.bit.SOC7 = 1; // ADCInterrupt1 causes SOC0
AdcRegs.ADCSOC2CTL.bit.CHSEL= 7; // convert ADC-A0 (CH0) when SOC1 is received

AdcRegs.ADCSOCFRC1.all = 0x0001; // kick start ADC by causing an ADCInterrupt1 event

}

Anyone can help me to fix this code, because my acquisition didn't work well, I believe that I configured something wrong.  I guess that my seguencer is wrong. 

Thanks for all attentions and best regards to all. 

Please anyone has a example with simutaneos aquisition for I check my code?

  • I think you need to delay after everything is configured, but before you start sampling.  Notice that in the controlSUITE ADC examples, the function DELAY_US(ADC_usDELAY) is called after the ADC is powered up.  This is because we spec. an ADC settling time of ~1ms in the data sheet (section 6.11.11.2).  If you don't allow the ADC voltages to settle, then you may get garbage conversion results.      

  • Hi David, thanks for you attention. About this delay I used already in my codes. I have three projects that use ADC converter of  Piccolo and this work perfectly well. But in this new project I will work  with all channel with simultaneos aquisition.

    Normally I used 3 channel with individual sampling, now I need to use pair, because I will measure voltage and current and execute a power analyser algorithm. 

    After some analysis I concluded that my round-robin SOC0  isn't work, I concluded this because my waveform is wrong . 

    I my project I need that timer0 start adc converters automatically, and when ADC converter finish to converter all channels, ADC machine generate a interrupt for me, and this mode I can start to run my algorithm. 

    Thanlks for you attention 

  • Are you trying to repeatedly run through the sequencer for some amount of times after the
    timer generates the interrupt?  I think that is what will happen now, because all SOCs 
    start from ADCINT1 and EOC0 will keep generating more ADCINT1 because of the line:
    AdcRegs.INTSEL1N2.bit.INT1SEL = 0; //EOC0 generates ADCINT1 
    If you just want to sample all the channels once each time the timer interrupts and get 
    an interrupt for processing at the end, then set all the SOC trigger selects to
    ADCSOCxCTL.TRIGSEL = 1; //SOC x set by timer 0 interrupt
    And also set EOC7 to generate some interrupt that you can do processing in:
    AdcRegs.INTSELxNy.bit.INTySEL = 7; //set EOC7 to generate interrupt y
    If you use this strategy, be aware of the first sample issue in the errata.  Also, once again,
     I must stress that the above quoted code will NOT be guaranteed to work correctly because 
    there is not a 1ms delay before the line
    AdcRegs.ADCSOCFRC1.all = 0x0001
    which starts sampling without allowing the ADC to settle after powerup.