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.

CC1310: usleep imprecise

Part Number: CC1310

Hello,

customer uses usleep function in their application but it is very imprecise.

set: 10us; measured 180-200us
set: 30us; measured 180-200us
set: 100us; measured 180-200us
set: 300us; measured 350-410us
set: 1000us; measured 1100us
set: 3000us; measured 3070-3200us

Other task are swithc blocked or terminated.

Why is this timing variating? Any hidden tasks?

Regards, Holger

  • Hi Holger, 

    In order to help you with this issue, I need more information. Please provide as much information as possible but at a minimum: 

    1. What kind of HW are they testing on? A custom board or a Launchpad?

    2. Which version of the SDK are they using?

    3. Which examples are they using? And what kind of modifications have they made? 

    4. How are they measuring the timing? 

    Thanks,
    Elin

  • Hello Elin,
    they test in customer application with custom board. They use SDK V3.10.00.11 and measure with oscilloscope.

    Regards, Holger

  • How do they measure with a scope? Are they measuring current, toggling of pins etc? Or in other words, how can we replicate this measurements here? 

  • may be we can propose to run an TI example on their HW. What example would you suggest?

    Regards, Holger

  • I found this thread that seems to be relevant to your question. e2e.ti.com/.../time-delay-with-task_sleep-api 

  • Hello,

    ok, that is a good explaination from that link:

    https://e2e.ti.com/support/legacy_forums/embedded/tirtos/f/ti-rtos-forum-read-only-archived/512040/time-delay-with-task_sleep-api

    But still customer need us precision. Can they use the code from that link? Would it work?

    Timer_Handle timer;
    Semaphore_Handle sem;
    
    void hwiFxn(UArg arg){ Semaphore_post(sem);}
    
    main() {
       Timer_Params timerParams;
       Timer_Params_init(&timerParams);
       uint16 time1, time2;
    
       timerParams.period = 1; // will this be 1 us??
       timer = Timer_create(Timer_ANY, hwiFxn, &timerParams, &eb);
       sem = Semaphore_create(0, NULL, &eb);
    
       BIOS_start();
    
       while(1) {
         time1 = Timer_getCount();
         Semaphore_pend(sem, BIOS_WAIT_FOREVER);
         time2 = Timer_getCount();
         System_printf("\nTime difference = %lu", (ULong) (time2-time1));
         System_flush();
       }
    }

    Or an other macro with assembler function or NOPs?

    Regards, Holger

  • I found a function which works very well in us resolution using the internal CYCCNT „Current PC Sampler Cycle Count“:

    void delay_us(volatile uint32_t micros) {

    volatile uint32_t start;

    //volatile uint32_t end1;

    //volatile uint32_t diff1;

    micros *= 48;

    start = HWREG(CPU_DWT_BASE + CPU_DWT_O_CYCCNT) - 48;

    /* Delay till end */

    while (((HWREG(CPU_DWT_BASE + CPU_DWT_O_CYCCNT)) - start) < micros);

    //end1 = HWREG(CPU_DWT_BASE + CPU_DWT_O_CYCCNT) - 48;

    //diff1 = end1 - start;

    //System_printf("\nTime = %lu", (uint32_t) diff1);

    }

    Regards, Holger

  • Hi Holger, 

    Thanks for sharing. 

    Did the code/function you shared solve your issue? 

    Thanks,
    Elin

  • Hello Elin,
    the problem with the CYCCNT is that it only works with debugger. W/o debugger it works only if DWT is active.

    Eg DWT activation:

      HWREG(CPU_SCS_BASE + CPU_SCS_O_DEMCR) = CPU_SCS_DEMCR_TRCENA;

      HWREG(CPU_DWT_BASE + CPU_DWT_O_CTRL) = CPU_DWT_CTRL_CYCCNTENA;

    Then it works but customer is not sure if this has other consequences like high power consumption.

    He likes to use Driverlib function void CPUdelay ( uint32_t ui32Count ):

    Provide a small non-zero delay using a simple loop counter.
    This function provides means for generating a constant length delay. It is written in assembly to keep the delay consistent across tool chains, avoiding the need to tune the delay based on the tool chain in use.
    Note:
    It is not recommended using this function for long delays.
    Notice that interrupts can affect the delay if not manually disabled in advance.
    The delay depends on where code resides and the path for code fetching:

    • Code in flash, cache enabled, prefetch enabled : 4 cycles per loop (Default)
    • Code in flash, cache enabled, prefetch disabled : 5 cycles per loop
    • Code in flash, cache disabled : 7 cycles per loop
    • Code in SRAM : 6 cycles per loop
    • Code in GPRAM : 3 cycles per loop

    Question: Is the Cache and Prefetch already activated in TI-RTOS?

    Regards, Holger

  • Hi Holger, 

    Please refer to the TI-RTOS User's Guide

    Thanks,
    Elin 

  • Hello Elin,
    sorry, I'm not that TI-RTOS expert. Does your answer mean that cache and prefetch are enabled per default in TI-RTOS? This info I couldn't in the Guide.

    Regards, Holger