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.

Question about ADC Sample Code

There is a line of assembly code in the "adc_seqmode_test" sample included in the C281x header files. Its the sample that samples the ADC continuously. The other sample that triggers a SOC via the event manager doesn't have this line.

asm(" RPT #11 || NOP");

Can anyone explain what that line does? There is no clear explanation of this?

Thanks

  • Hi Henry,

     

    It is an TI compiler way of inserting assembly code within C source. This one exectutes repeats NOP (No OPeration) 12-times (11+1). I assume it is for delay purposes only.

    Beware, inserting anything else than NOP or ESTOP0 can have unpredictable consequences.

    Regards, Mitja

  • What is the purpose of this delay for ADC sampling?

    The rest of the code is:

            while (AdcRegs.ADCST.bit.INT_SEQ1== 0) {}
            asm(" RPT #11 || NOP");
            AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
            SampleTable[i] =((AdcRegs.ADCRESULT0>>4) );

    I assumed the while loop to wait for the interrupt signaling a completed sequence is enough indicationg. Is is still necessary to wait the delay before retrieving results?

  • This is a workaround for a C281x specific ADC errata.  The errata reads(pg 18):

     

     

     

     

    The ADC result status flags INT_SEQ1 and INT_SEQ2 bit fields (bits 0 and 1

    respectively) in the ADC_ST_FLG register indicate the availability of new ADC results

    after conversions and initiation of the ADC interrupts.

    The update of the ADC result register requires one extra ADC cycle to complete after the

    status flags INT_SEQ1 and INT_SEQ2 bit(s) are set. The result of reading the result register

    prior to this extra cycle will result in old data being read (reset value/previous conversion

    result).

    If auto-sequencers are enabled with a non-zero value in the MAXCONV register, the last

    result register update takes an additional ADC cycle from the time the INT_SEQ1 or

    INT_SEQ2 flag is set.

    Workaround

     

     

    : Delay the read of the ADC result register(s) by at least one ADC clock period. This delay can

    be implemented by using software delay loops.

    If the ADC result register(s) are read using the ADC interrupt, rather than polling, the wait

    period introduced by the ISR (interrupt service routine) could minimize the delay needed in

    software. This ISR branching delay is generally greater than 8 SYSCLKOUT cycles.

    The ratio of the ADC clock (ADCCLK) to the CPU clock (SYSCLKOUT) determines the size of

    the software delay. For example, if ADCCLK = 10 MHz the software delay should be at least

    100 ns.

    Timing example to estimate the software delay:

    1) Get the HSPCLK prescaler value − HISPCP

    2) Get the ADCCLK prescaler value − ADCCLKPS

    3) Get the CPS (ADCCTRL1[7]) value − CPS

    4) Software wait-period in CPU cycles (SYSCLKOUT) before the ADC result register read

    is defined as:

    Software wait = (HISPCP *2) * (ADCCLKPS * 2) * (CPS +1) cycles

    If HISPCP or ADCCLKPS is 0, then the respective terms should be (HISPCP +1)

    or (ADCCLKPS+1)

  • Thanks Mathew, that clears it up.

    Does that delay also apply for setting of the SEQx_BSY or EOS_BUFx bits?

    ie. Can I use:

    while (AdcRegs.ADCST.bit.SEQ1_BSY == 1);

    or

    while (AdcRegs.ADCST.bit.EOS_BUF1 == 0);

    instead of:

    while (AdcRegs.ADCST.bit.INT_SEQ1 == 0);