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.

TMS320F28335: DELAY_US() cycle counts not as described in DSP28x_usDelay()'s source file?

Guru 20075 points

Part Number: TMS320F28335

Hello,

I am coming up with a DELAY_US() cycle count that is different than what is described in the DSP28x_usDelay() function's source file.

Could someone please verify my analysis shown below.

Stephen

The comments in  DSP28x_usDelay function file say the following:

;There is a 9/10 cycle overhead and each loop
;takes five cycles. The LoopCount is given by
;the following formula:
; DELAY_CPU_CYCLES = 9 + 5*LoopCount
; LoopCount = (DELAY_CPU_CYCLES - 9) / 5
; The macro DELAY_US(A) performs this calculation for you

I counted 3 (3 mov instructions) +4 (LCR) + 4 (LRETR) = 11 cycles of overhead (see assembly for main()  and DSP28x_usDelay() below) .  Is that correct?

Also, if the computed delay loop count passed to  DSP28x_usDelay() is n, I found that the the number of loop interations  in DSP28x_usDelay() is n+1.  Is that correct?

For example, if n=4 (i.e. 0.210us for 150MHz 28335), the total cycle count will be 11+(n+1)*5 = 11+25 = 36 cycles, which is equivalent to 36*6.667ns = 0.240us.  Is that correct?

C CODE:

/*
 * main.c
 */
#define CPU_RATE 6.667L
extern void DSP28x_usDelay(long int delayTime);
#define COMPUTED_LOOP_COUNT(A)  (long int)(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)
#define DELAY_US(A)  DSP28x_usDelay((long int)(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L))

volatile long int a = 0;
int main(void)
{
	
    a = COMPUTED_LOOP_COUNT(0.210);
    DELAY_US(0.210);
	return 0;
}

main() assembly code:

        main():
009101:   0204        MOVB         ACC, #4
009102:   761F0300    MOVW         DP, #0x300
009104:   1E0A        MOVL         @0xa, ACC
14          DELAY_US(0.210);
009105:   76400050    LCR          $../DSP2833x_usDelay.asm:62:75$
15      	return 0;
009107:   9A00        MOVB         AL, #0x0
16      }
009108:   0006        LRETR        

DSP28x_usDelay Assembly Code:

62              SUB    ACC,#1
        $../DSP2833x_usDelay.asm:62:75$(), DSP28x_usDelay:
000050:   1901        SUBB         ACC, #1
63              BF     _DSP28x_usDelay,GEQ    ;; Loop if ACC >= 0
000051:   56C3FFFF    BF           -1, GEQ
64              LRETR 



  • Would it be best for the compiler group to answer this question?
  • I understand now the overhead discrepancy between the code comment and my assembly was caused by the additional DP, #0x300 command.

    Could someone please verify the loop time is 5*(n+1) cylcles, where n is the number passed to the DSP28x_usDelay function.

    Stephen

  • Steven,

    As you show, the delay loop consists of a subtraction (SUB) and a branch conditional (BF). The branch is 4 cycles and the SUB is 1 cycle. So each time through the loop is 5 cycles.

    _DSP28x_usDelay:
            SUB    ACC,#1
            BF     _DSP28x_usDelay,GEQ    ;; Loop if ACC >= 0
            LRETR 
    

    Does that answer your question?


    Regards
    Lori

  • I just wanted someone else to verify that the number of times the the loop is n+1, where n is the value passed in ACC.
  • Steven,

    Apologies for the formatting above.  I agree with you.  To really tune the function or test it, one method would be to toggle an I/O before and after it.   Then the duration can be measured on a scope.

    ACC = 3
            SUB    ACC,#1                  –> ACC = 2
            BF     _DSP28x_usDelay,GEQ    ;; Loop if ACC >= 0 - true
    
            SUB    ACC,#1                  -> ACC = 1
            BF     _DSP28x_usDelay,GEQ    ;; Loop if ACC >= 0 - true
    
            SUB    ACC,#1                  -> ACC = 0
            BF     _DSP28x_usDelay,GEQ    ;; Loop if ACC >= 0 - true
    
            SUB    ACC,#1                  -> ACC = -1
            BF     _DSP28x_usDelay,GEQ    ;; Loop if ACC >= 0 – false
    
    	LRETR