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.

TMS320F280049: ADC timing appears much longer than expected?

Part Number: TMS320F280049


Champs,

I am asking this for our customer.

The customer is testing the ADC timings and we are confused about the results.

It seems the result is much longer than that on the doc.

1) First, the ADC timings showed on Table 5-47 of the datasheet (sprs945d) and on Table 13-8 of the TRM (sprui33b) have minor mismatch. The t(lat) column differs in one cycle in two tables. For example, t(lat) is 23 and 22 cycles at ADCCTL2 prescale =2 on two tables.  Would you please help check if this is a typo?

2) The customer's code is very simple and showed below.

And the result shows, it takes about 700 ns for an ADC latency (from SW SOC triggering to late ADC interrupt flag).

In theory, it should take 

t(sh) + t(lat)

10ns x 10 (ACQPS) + 10ns x 23 = 330 ns.

Even some more overhead cycles of the testing codes (like SW SOC force, GPIO set/clear), we are very confused why it takes up to 700 ns.

Would you please help us clarify why it takes much longer than ADC timing on the tables of the doc?

Wayne Huang

  • Hi Wayne,
    To answer your questions,
    1) First, the ADC timings showed on Table 5-47 of the datasheet (sprs945d) and on Table 13-8 of the TRM (sprui33b) have minor mismatch. The t(lat) column differs in one cycle in two tables. For example, t(lat) is 23 and 22 cycles at ADCCTL2 prescale =2 on two tables. Would you please help check if this is a typo?
    >> We shall check and get back to you.

    2) The customer's code is very simple and showed below.Even some more overhead cycles of the testing codes (like SW SOC force, GPIO set/clear), we are very confused why it takes up to 700 ns.
    Would you please help us clarify why it takes much longer than ADC timing on the tables of the doc?
    >> Following is the dis-assembly for the source code.

    GpioDataRegs.GPASET.bit.GPIO0 = 1;
    C$L10:
    00022a: 761F01FC MOVW DP, #0x1fc
    00022c: 1A020001 OR @0x2, #0x0001
    40 AdccRegs.ADCSOCFRC1.bit.SOC0 = 1;
    00022e: 761F01D4 MOVW DP, #0x1d4 ;
    000230: 1A0D0001 OR @0xd, #0x0001 ;
    41 while(AdccRegs.ADCINTFLG.bit.ADCINT1 == 0) {
    C$L11:
    000232: 4003 TBIT @0x3, #0x0 ;
    000233: 6CFF SB C$L11, NTC ;
    43 AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;
    000234: 1A040001 OR @0x4, #0x0001
    44 GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;
    000236: 761F01FC MOVW DP, #0x1fc
    000238: 1A040001 OR @0x4, #0x0001

    As can be seen,
    a. There are additional instructions for setting up the address.
    b. There is a TBIT and an SB instruction to poll the interrupt flag.
    * This check can take upto 12 cycles
    c. The reads from .ADCINTFLG register takes 2 additional cycles (Not a single cycle read)
    d. There is pipe-line delays for the write to GPIO to happen (to clear the flag).

    Overall these overheads could add up to ~25-26 cycles (Based on code analysis).

    Was there any other issue because of which, the customer was trying to measure the latency ?

    Regards,
    Srinivasa
  • Srinivasa,

    We are still not very clear how the above a) to d) comes out at 25-26 cycles.
    Eg, pipeline delay up to many cycles?

    Would you please elaborate it about how ~25-26 cycles are estimated?


    Also, did you use a similar way to test ADC latency (from SOC to ADC late interrupt flag) like what we do, or you used another way to verify it? If you used another way to verify it, would you please show us the idea and we will try to duplicate it.
    If so, would you please show us how you did?

    The customer wants to make sure all the timing needed in their control loop for digital power, because timing is critical in the control loop and their computational power budget is limited.


    Wayne Huang
  • Wayne,

    Firstly, I would like to confirm the that Tlat value of 23 is correct. We have taken an action to correct the documentation.

     

    Secondly, to measure latency between trigger and end of conversion of ADC, there are alternate methods which can be used which give a more accurate result. Using polling is not recommended if the latencies which are being measured are small. The data sheet numbers are from simulations and are very precise. One alternate method to measure this latency could be to use EPWM as a timer and using DMA to read the timer value and dump into a memory location before triggering the ADC and taking another reading of the timer through DMA when ADC generates and interrupt (ADC interrupt could trigger the DMA). Following is the code snippet for this method.

     // DMA Channel 1 configuration, DMA channel 1 is triggered from software, before triggering the ADC.

    // Enabling clock to DMA

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DMA);

    // Clear DMA configuration

    DMA_initController();

    // Set DMA emulation mode to free run

    DMA_setEmulationMode(DMA_EMULATION_FREE_RUN);

    start_addr = (uint16_t *) (EPWM1_BASE + EPWM_O_TBCTR);

    end_addr = (uint16_t *) (0xC000);

    DMA_configAddresses(

    DMA_CH1_BASE,

    end_addr,

    start_addr

    );

    DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_SOFTWARE,

    DMA_CFG_ONESHOT_DISABLE|

    DMA_CFG_CONTINUOUS_DISABLE|

    DMA_CFG_SIZE_32BIT

    );

    DMA_enableTrigger(DMA_CH1_BASE);

    DMA_configBurst(DMA_CH1_BASE, 1, 0, 0);

    DMA_configTransfer(DMA_CH1_BASE, 1, 0, 0);

    DMA_configWrap(DMA_CH1_BASE, 5, 0, 17, 0);

    DMA_startChannel(DMA_CH1_BASE);

    // DMA Channel 2 configuration, DMA channel 2 is triggered from ADCCINT1

    DMA_configAddresses(

    DMA_CH2_BASE,

    0xC002,

    start_addr

    );

    DMA_configMode(DMA_CH2_BASE, DMA_TRIGGER_ADCC1,

    DMA_CFG_ONESHOT_DISABLE|

    DMA_CFG_CONTINUOUS_DISABLE|

    DMA_CFG_SIZE_32BIT

    );

    DMA_enableTrigger(DMA_CH2_BASE);

    DMA_configBurst(DMA_CH2_BASE, 1, 0, 0);

    DMA_configWrap(DMA_CH2_BASE, 9, 0, 17, 0);

    DMA_startChannel(DMA_CH2_BASE);

    // ADC and EPWM configuration

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);

    EPWM_setClockPrescaler(EPWM1_BASE,0, 0);

    EPWM_setTimeBasePeriod(EPWM1_BASE,1000);

    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);

    EPWM_setEmulationMode(EPWM1_BASE, EPWM_EMULATION_FREE_RUN);

    EALLOW;

    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;

    EDIS;

    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCC);

    ADC_setInterruptSOCTrigger(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY);

    ADC_setPrescaler(ADCC_BASE, ADC_CLK_DIV_8_0);

    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);

    ADC_setInterruptPulseMode(ADCC_BASE, ADC_PULSE_END_OF_CONV);

    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);

    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 10);

     

    // Triggering DMA and ADC

    EALLOW;

    DmaRegs.CH1.CONTROL.bit.PERINTFRC = 1;

    EDIS;

    AdccRegs.ADCSOCFRC1.bit.SOC0 = 1;

     

    Once ADC is triggered, DMA channel1 dumps the timer value @0xC000  and DMA channel2 dumps the timer value at EOC. Following table captures the reading observed.

                                                                   

    ADC_CLK_DIV ACQPS + 1 T1= TBCNT @ EOC

    T2=TBCNT

    @trigger

    T2-T1(SYSCLK cycles)
    1 10 164 145 31
    2 10 16E 145 41
    3 10 178 145 51
    4 10 182 145 61
    5 10 18C 145 71
    6 10 196 145 81
    7 10 1A0 145 91
    8 10 1AA 145 101

    These readings will have additional delays ~7-8 cycles for the DMA to get triggered and read from EPWM1.

    Regards,

    Srinivasa

  • Srinivasa

    Thank you very much.

    Wayne
  • Wayne,
    Thanks, Hope the solution satisfied the customer.
    Regards,
    Srinivasa