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.

How to improve ADC speed of TMS320F2812?

Hi,

I am using F2812 to control a DCDC converter and trying to make it work at 100KHz switching frequency. I need to sample three analog voltage by T1 periode interupt and convert digital value. It turns out that ADC needs more time than T1 periode. Furthermore, I probably need to sample multiple times of single analog value to eliminate error. How could I improve the speed of ADC?

He, Siyu

  • Can you be more specific about how long you have to sample the 3 voltages?  You should have more than enough time to sample 3 voltages if using minimum sample window in 1/100KHz; each conversion should take in the range of 80ns (25MHz ADC clock) to 160ns(12.5MHz ADC clock).  

  • Thank you for your reply,.

    I set sample window equals 1 ADCCLK which runs at 2.5MHz. I was thinking this frequency is high enough. How do I calculate ADC time required? and What are other factors that affect ADC time costing?

    He, Siyu

  • To determine timings, see figure 6-41 in the datasheet: http://www.ti.com/lit/ds/symlink/tms320f2812.pdf

    From this you will see that ADC clock rate greatly influences conversion time.  You can run the ADC with full spec's up to 18.75 MHz (and I recommend that you do run at this maximum speed).  

  • I set ADCTRL1.bit.CPS=0,ADCTRL3.bit.ADCCLKPS=2 and ADCTRL1.bit.ACQ_PS=1. In this way, the ADC clock is at 18.75MHz and sample frequency is at 9.375MHz.

    Am I right? And I tried to use converted values to do calculaiton(multiply and plus), the calculation process takes long time, How do I reduce this cost?

    Thank you

    He, Siyu

  • Assuming HSPCLK is SYSCLK/2 (default) and the device is running at 150MHz, this should give you 18.75MHz ADC clock.  To get 9.375 MSPS, I think you want ACQ_PS to be 0 and not 1 though; the sample window is (ACQ_PS)+1 ADC clocks.

    Multiply and accumulate should be possible in a single cycle, although there may be some overhead moving things around in memory.  I would recommend you look at the disassembly window to see what kind of instructions the compiler actually generated.

  • Thanks for reminding me the setting of ACQ_PS. As I set the F2812 as you mentioned above, I used source-single step to measure time cost of each sentence. The code below is what I measured based on reading profile clock<cpu cycle>

    IL=(AdcRegs.RESULT0 >>4)*ADCslope;//cost 173 CPU cycles
    IL=IL+(AdcRegs.RESULT1 >>4)*ADCslope;//cost 105 CPU cycles
    IL=IL*0.5;//cost 112 CPU cycles
    vin=(AdcRegs.RESULT2 >>4)*ADCinVol;//173 CPU cycles
    vout=(AdcRegs.RESULT3 >>4)*ADCoutVol;//173 cpu cycles

    I am not familiar with ASM and had difficult time to match C and ASM. Would you help me with this?

    He, Siyu

  • What are the data-types of these variables?  Floating point or integer?  

    Either way, the number of cycles seems way too high.  If you search around the forum/wiki you should be able to find some instructions on code profiling.  I think using something like a CPU timer or ePWM timebase should give you a better idea of the cycle cost of your code.

  • The data-type are float point.

    Yes, I also used timer 1 to calculate time cost, the T1CLK=HSPCLK/2=37.5MHz. The corresponding T1CNT is shown below

     IL=(AdcRegs.RESULT0 >>4)*ADCslope;//cost 43 T1 counts
     IL=IL+(AdcRegs.RESULT1 >>4)*ADCslope;//cost 26 T1 counts
     IL=IL*0.5;//cost 29 T1 counts
     vin=(AdcRegs.RESULT2 >>4)*ADCinVol;//42 T1 counts
     vout=(AdcRegs.RESULT3 >>4)*ADCoutVol;//42 T1 counts

    He, Siyu

  • Hi Devin,

    I think I made some progress with replacing a complex operation by 2 or more simple instruction. The new test result is shown below:

        IL=((AdcRegs.RESULT0 >>4)+(AdcRegs.RESULT1 >>4));//cost 17 T1CINT 65 CPU cycle
        IL=IL*ADCslope;//cost 14 T1CINT 55 CPU cycle
        vin=(AdcRegs.RESULT2 >>4);//7 T1CINT 23 CPU cycle
        vin=vin*ADCinVol;//9 T1CNT 34 CPU cycle
        vout=((AdcRegs.RESULT3 >>4));//4 T1CNT 23 CPU cycle
        vout=vout*ADCoutVol;//8 T1CNT 34 CPU cycle

    The process above is costing much less time now, but I noticed that a single shift instruction costs about 23 CPU cycles. Is it reasonable?

    He, Siyu

  • Siyu,

    Seems like a good optimization.  

    23 cycles is definitely not reasonable.  I wonder if your profiling has some overhead.  Maybe try profiling a chunk of code with the same statement repeated, say 10 times (then divide the time by 10):

    //start timer

    vin=(AdcRegs.RESULT2 >>4);//7 T1CINT 23 CPU cycle

    vin=(AdcRegs.RESULT2 >>4);//7 T1CINT 23 CPU cycle

    ...

    vin=(AdcRegs.RESULT2 >>4);//7 T1CINT 23 CPU cycle

    //stop timer

    or profile your entire chunk of code at once to see if the total time adds up to the sum of the individual statements

  • Devin,

    I tried to run both vin=(AdcRegs.RESULT2 >>4) 10 times and from IL=((AdcRegs.RESULT0 >>4)+(AdcRegs.RESULT1 >>4)) to vout=vout*ADCoutVol in one time, the previous time cost is about 254 cpu cycles equivalent to 25 cpu cycle per time, and the last test is equal to the sum of individual time cost.

    All the data used is defined as float in main and defines as extern float in Globlavariable.h. I wondering that if I define some data as contant, would this help?If so, in which section of code should I define them as const, I tried before main but it fails. All the test I did is based on loading program to internal RAM and connected throgh JTAG, would this affect the speed?

  • Devin,

    I just had a new post focus on computation speed here http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/278230.aspx

    If you have more thought about my problem, please let me know.

    He, Siyu