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.

Delay Program -28335

Other Parts Discussed in Thread: TMS320F28335, TMS320F2812, CONTROLSUITE

Dear all,

anybody can u give me  the delay calculation and sample code for tms320f28335

 

regards,

Malaiyappan.M

  • use 

    DELAY_US(time);

     

    with all header file.

     

    DSP2833x_EXAMPLES.H and all;

     

    Thanks

    malaiyappan

     

     

     

  • DSP2833x_usDelay.asm ,  The asm code for the delay is there in this file . you can ad this source in you file and

    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    add the above definition in your header . This a delay code which is availible in the examples code . 

    As Mr. Malaiyappan told the above #define is included in DSP2833x_Examples.h

     

  • Hi!

    Could you explain the use of

    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    how to calculate the time ?When the CPU_RATE is 10.000L or 16.667L.and so on!

  • The macro calls an assembly function called DSP28x_usDelay.   You specify the CPU_RATE and pass the macro the number of microseconds of delay you want.  The macro does the conversion for you.  This is from the source file for the delay function:

     

    ;// To use this function:
    ;//
    ;//  1 - update the CPU clock speed in the DSP2803x_Examples.h
    ;//    file. For example:
    ;//    #define CPU_RATE 16.667L // for a 60MHz CPU clock speed
    ;//
    ;//  2 - Call this function by using the DELAY_US(A) macro
    ;//    that is defined in the DSP2803x_Device.h file.  This macro
    ;//    will convert the number of microseconds specified
    ;//    into a loop count for use with this function. 
    ;//    This count will be based on the CPU frequency you specify.
    ;//
    ;//  3 - For the most accurate delay
    ;//    - Execute this function in 0 waitstate RAM. 
    ;//    - Disable interrupts before calling the function
    ;//      If you do not disable interrupts, then think of
    ;//      this as an "at least" delay function as the actual
    ;//      delay may be longer.

    Lori

  • Hello,  I'm looking at using the basis of this delay function, too.  When I look at the assember for this -

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

     

    I can see that the ACC register is decremented by one each time. Looking at the ACC register, it appears that it's only 32 bits wide. However, the possible 'loop' values could be bigger than this. Am I missing something?    Thanks,    Julian.

  • Julian Woloszczuk said:

    Hello,  I'm looking at using the basis of this delay function, too.  When I look at the assember for this -

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

     

    I can see that the ACC register is decremented by one each time. Looking at the ACC register, it appears that it's only 32 bits wide. However, the possible 'loop' values could be bigger than this. Am I missing something?    Thanks,    Julian.

    Yes.  The ACC is 32 bits - so if the value passed to the function to achieve the desired delay exceeds 32-bits, then more than one delay() will need to be called.   The MAX delay would depend on the CPU frequency.

    Regards

    Lori

     

  • I'm not sure that explains why the macro call casts values to 'long double', as below.

    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    Also, if I want to put the assembler 'inline', in a .cpp file, I have a few further questions -

    Do I have to put each assembler line in the 'asm statement', as below, or is there a better way?

     

     

    void

     

    DoDelay(Uint64 loop)

     

     

     

    {

     

    asm

    asm

     

    (" MOV AH, @PH");

     

    asm (" MOV AH, @PH");

     

     

    asm (" SUB ACC, #1");

     

     

    asm (" BF -1, GEQ");

     

     

    asm (" LRETR");

    }

    The only reference I can see in the documentation on this is section 6.9 of SPRU514 - the 'C' compiler guide - it only has one example! Is there a more detailed explanation elsewhere?

    Also, you can see from my assembler that I'm assuming my parameter from the 'C++' function is in the 'P' register(s). Is there a way I can reference my C++ parameter by name in the assembler language instructions?  Again, I'm struggling to find a document that covers this.      Looking forward to your help!   Julian.

     

  • Sorry about the formatting - don't know what happened there :-)

  • hopefully this is better....

     

    void

    DoDelay(Uint64 loop)

    {

     asm (" MOV AH, @PH");

    asm (" MOV AH, @PH");

    asm (" SUB ACC, #1");

    asm (" BF -1, GEQ");

    asm (" LRETR");

     }

  • Hi!

    How long do you want to wait? With a 32 bit counter (using 31 bit) you can wait up to 7 seconds on a 300 MHz Delphino. But you cannot do anything during waiting. Except some interrupt service routines, but the ISR execution time will make your waiting time longer. If you want to have an exact waiting time you will have to use a timer. I suggest to let CPU timer 0 simply count down and wait until the timer reaches the calculated end value:

    void Wait(unsigned long in us)
    { unsigned long int stop;
      asm(" clrc ovm");
      stop = CpuTimer0Regs.TIM.all-CLKS_PER_US*(unsigned long int)us; // CLKS_PER_US = number of ticks per micro second
      while((signed long int)(CpuTimer0Regs.TIM.all-stop)>0);
    }

    This waiting function works (nearly) exact. Independent of interrupts.

    For real long waiting times you will need a periodic timer interrupt incrementing a counter. Then you can implement your extra long delay in software. (a 1 ms periodic interrupt with a long long (64 bit) counter will give you millions of years).

    Hence, I do not recommend to use a delay loop for waiting. Perhaps in examples, but not in real applications where you need an exact waiting time.

    Regards,
    Edwin Krasser

  • Thanks for the info, Edwin.   I've given this a go, but my TMS320F2812 device's timer register is only 16 bits, so at 150 'ticks' per microsecond, this only gives me a max delay of 436 microseconds. Do you agree?  Yes, I will have to implement a 'proper' timer soon !

  • Just to clarify, on my CCS, I see the timer as a 16-bit value, and if I read the register into a 32-bit variable (see below), after I've reset the counter, I only see 0xFFFF. Am I missing something here?

     Uint32 cpuReg = CpuTimer0Regs.TIM.all;

  • Hi!

    The event manager counters are just 16 bit. You can use one for a 1 ms software counter. But if you want to get a universal wait function you should use the cpu timer 0. It is a 32 bit counter which counts down. And the 0xFFFF after resetting are ok cause it counts down. Just let your program run and stop it by JTAG some seconds later. Then you should see that the counter value has decremented. Here is the initialization I use for an endless 32 bit counter (counting clock cycles):

      CpuTimer0Regs.PRD.all=0xFFFFFFFF;
      CpuTimer0Regs.TPR.bit.TDDR=0;
      CpuTimer0Regs.TPRH.bit.TDDRH=0;
      CpuTimer0Regs.TCR.all=0x8020; // start timer, no interrupts

    With the waiting function (from my first post) you will get a maximum waiting time of 14.3 (=2^31/150E6) seconds at 150 MHz. Independent of ISR load.

    Regards,
    Edwin Krasser

  • Thanks for the info. I've put your settings into my routine (see below), but although a delay of 1,000us is OK, when I try a value of 10,000us, my while loop doesn't exit. Interestingly, when I stop the processor, I notice that the 'period' register is no longer 0xFFFFFFFF. You'll see I've simplified the routine so it assumes we're starting from 0xFFFFFFFF each time. Any ideas?   Thanks!

    CpuTimer0Regs.PRD.all=0xFFFFFFFF;

    CpuTimer0Regs.TPR.bit.TDDR=0;

    CpuTimer0Regs.TPRH.bit.TDDRH=0;

    CpuTimer0Regs.TCR.all=0x8020; // start timer, no interrupts

     Uint32 ticks_required = 150*number_of_microseconds;

    Uint32 stop_point = 0xFFFFFFFF-ticks_required;

    while (CpuTimer0Regs.TIM.all > stop_point);

    }

  • Hi!

    What's the variable type of number_of_microseconds? It must be long int or unsigned long int. Otherwise the 150*number_of_microseconds multiplication is a short int multiplication giving a wrong result. I tested it and I got ticks_required=4294959968 when using int as data type. With a long int data type it worked fine (just tested on a f28335).

    Regards,
    Edwin Krasser

  • It's a Uint32. My device is a 2812.

  • A bit more info.   Using a figure of 10,000 microseconds, the 'stop_point' ends up as  4293467295, or 0xFFE9 1C9F. With this value, the higher 16-bits are being considered.  Tests with lower delays end up with 'stop_point' figures that leave the higher 16-bits as 0xFFFF. This may be something to do with the problem.

  • I do not think that the 16-bit and 0xFFFF matter. You told that it worked with 1000 us wait time (150000 ticks, stop time will be 0xFFFD B60F). I do not know what else is running in your software, but the problem should derive from somewhere else (Watchdog? ISRs? Other functions accessing CPU timer 0? DSP-BIOS?).

    Regards,
    Edwin Krasser

  • Yes, you're right with the figures - my mistake!   I'll take a look and see what else might be mangling things.  Thanks for your help so far!

  • Dear all

    I add the following line in my code.

    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    When I want to build my project there is an error that "CPU_RATE" is undefined. However, the DSP2833x_Examples.h is included in my project and when I press Ctrl and click on "CPU_RATE", it directs me to to line "#define CPU_RATE    6.667L   // for a 150MHz CPU clock speed (SYSCLKOUT)" in file "DSP2833x_Examples.h" which means for me that "DSP2833x_Examples.h" is linked to my project. If I replace the "CPU_RATE" with "6.667L", there is not error. What is the problem?

    Second problem, as I said if I replace the "CPU_RATE" with "6.667L", my code doesn't have any error. But if I use "DELAY_US(1000000)" in my code, the delay is not working any more but if I use "DSP28x_usDelay(1000000)", delay works. 

    Can you please help me

    Arash

  • Hi Lori

    I add the following line in my code.

    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_RATE) - 9.0L) / 5.0L)

    When I want to build my project there is an error that "CPU_RATE" is undefined. However, theDSP2833x_Examples.h is included in my project and when I press Ctrl and click on "CPU_RATE", it directs me to to line "#define CPU_RATE    6.667L   // for a 150MHz CPU clock speed (SYSCLKOUT)" in file "DSP2833x_Examples.h" which means for me that "DSP2833x_Examples.h" is linked to my project. If I replace the "CPU_RATE" with "6.667L", there is not error. What is the problem?

    Second problem, as I said if I replace the "CPU_RATE" with "6.667L", my code doesn't have any error. But if I use "DELAY_US(1000000)" in my code, the delay is not working any more but if I use "DSP28x_usDelay(1000000)", delay works. 

    Can you please help me?

    Arash

  • Hi,

    as I already wrote in this thread: I strongly recommend not to use such delay loops because these loops do not have an exact wait time. It's better to use the 32 bit CPU timer (initialize it just after startup) und wait for a given number of ticks. That's exact, even if interrupts occur during waiting.

    Best regards,
    Edwin Krasser

  • The long & double depends on the valus that we are going to declare for CPU Frequency, delay calculation.
  • Malaiyappan,

    You can find all these items in controlSUITE.  I recommend downloading that at:

    http://www.ti.com/lsds/ti/microcontrollers-16-bit-32-bit/c2000-performance/real-time-control/tools-software.page#controlsuite

    If you install in the default location, you'll find the F28335 content at:

    C:\ti\controlSUITE\device_support\f2833x

    Regards,

    Richard