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.

CC2652R: How to get a timer interrupt that cannot be preempted by the BIOS (systick)?

Part Number: CC2652R
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

I have to generate a waveform over 6 digital outputs and one DAC. I have set a timer interrupt that handle the 7 signals and reprogram the timer for the next cycle. I got a pulse of 25us every 4ms on the DO and the DAC. This is what I need. However sometimes I got a glitch that makes the 25us pulse to last 300ms. I suspect the TI-RTOS system timer to preempt my interrupt for too long, making the timer's compare value passed and the timer running a complete cycle before firing the interrupt again. So, the quick question is: is it possible to get a timer interrupt that is not preemptible by anything including the TI-RTOS?  I started from the "Simple GATT profile" example and I am using SysConfig tool.

  • Hello Remi,

    I hope you are doing well which CCS version and SDK version are you using?

    Thanks,
    Alex F

  • Hi Alex,

    CCS Version: 12.8.1.00005 on Linux

    simplelink_cc13xx_cc26xx_sdk_7_41_00_17

    Thank you

    Rémi

  • Hello Remi,

    Sorry for the delay, 

    is it possible to get a timer interrupt that is not preemptible by anything including the TI-RTOS?

    -We may be able to the HWI module here, reference the following thread, https://e2e.ti.com/f/1/t/741555/

    Thanks,
    Alex F

  • Hi Alex,

    Thanks for your answer. I tried what is suggested in the thread. To make it compile I had to include <ti/devices/cc13x2_cc26x2/driverlib/systick.h>. But when it runs, it spin to this place in the Error.c:

        if (Error_policy_D == Error_SPIN) {
            for(;;) {
            }
        }

    I will post snippets of my code:

    In main.c:

      SimplePeripheral_createTask();
      MyCommApp_createTask();
      Start_waveform_timer();

      /* enable interrupts and start SYS/BIOS */
      BIOS_start();

      return 0;
    }

    In waveform.c:

    void TimerCallbackFunction(){
        waveCallback();
    }

    void Start_waveform_timer(){
        /*
        Timer_Params_init(&tParams);
        tParams.periodUnits = Timer_PERIOD_US;
        tParams.period = 1000;
        tParams.timerMode  = Timer_CONTINUOUS_CALLBACK;
        tParams.timerCallback = TimerCallbackFunction;

        tHandle = Timer_open(CONFIG_TIMER_0, &tParams);
        Timer_start(tHandle);
        */
        SysTickDisable();
        SysTickPeriodSet(48000); // 1mS interrupt timing
        SysTickIntRegister(TimerCallbackFunction);
        SysTickIntEnable();
        SysTickEnable();
        IntMasterEnable();

        DAC_init();
        DAC_Params dacParams = DAC_defaultParams;
        dacHandle = DAC_open(CONFIG_DAC_0, &dacParams);
        DAC_enable(dacHandle);
    }

    As you can see in Start_waveform_timer(), the code from the thread is active. You can also see commented, the code I made that was running fine except the glitch.

    Is it possible that the thread is outdated regarding the TI-RTOS7? I suspect the RTOS to make use of the Systick to preempt the tasks, that would explain why messing up with the Systick results in an error.

  • Hello Remi Demers,

    It is possible that the update to TI-RTOS7 changed some things that affected the systick. Just a question, but did you try wrapping a semaphore around the part of code you want to protect?

    Thanks,
    Alex F

  • Hi Alex,

    I was not using a semaphore. I read the section about the semaphore and I think it is not applicable since I do not exchange any information between tasks. The code making the waveform executes outside any task, it is only in the interrupt service routine.

    Reading about the semaphores I found that the RTOS sometimes suspend the interrupts. This may be the main cause of the problem. I changed my code to remove the reprogramming of the timer inside the ISR and changed the shortest pulse to 50 us. I still have glitches but now the 50us is sometimes extended to 1 ms instead of 300 ms.

    I wonder if it is possible to rely on the RTOS to call my waveform function every 50 us?

    This is the function called by the interrupt:

    void TimerCallbackFunction(){
        //waveCallback();
        static uint8_t cycle = 0;
        static uint16_t dacBase = 0xFF00;
        static int8_t rate = 1;
        static int16_t dacRate = -10;
        if(cycle<1)
            rate = 1;
        if(cycle>19)
            rate = -1;
        cycle += rate;

        if(dacBase<1)
            dacRate = 10;
        if(dacBase>0xFF00)
            dacRate = -10;
        dacBase += dacRate;

        if(cycle==0){
            // Pulse on the DAC
            ((uint32_t*)(0x400C9044))[0] = 255;

            // Set digital pulse
            ((uint32_t*)(0x400220A0))[0] = 0b00000000000000000000000000000000;
            ((uint32_t*)(0x40022090))[0] = 0b00000000000000000000000010000000;
        }
        else
        {
            // Baseline on the DAC
            ((uint32_t*)(0x400C9044))[0] = dacBase>>8;

            // Clear digital pulse
            ((uint32_t*)(0x400220A0))[0] = 0b00000000000000000000000010000000;
            ((uint32_t*)(0x40022090))[0] = 0b00000000000000000000000000000000;
        }
    }

    Thanks

  • Hello Remi,

    I wonder if it is possible to rely on the RTOS to call my waveform function every 50 us?

    Having a task, or interrupt configured to go off every 50 usec should be possible here, did you change around the priority of the task/interrupt already? 

    Thanks,
    Alex F

  • Hi Alex,

    Yes, using SysConfig, I have set the timer interrupt priority to 1. I would choose 0, but it is not available in SysConfig, only 1 to 7. When the priority is higher the glitch still happens but less frequently. In my end application, no glitch is acceptable.

    Thanks

  • Hi Alex,

    I found this in the TI-RTOS Basics documentation:

    • Hardware Interrupts (Hwi): Hwi run to completion. They don’t block on anything. They can get preempted by a higher priority Hwi. All Hwi share the same stack (system stack).

      Hwi can be written in ‘C’. They are managed by the TI-RTOS7 scheduler with an exception: zero-latency interrupts. Applications can designate that any interrupt be a “zero-latency” interrupt. This means the TI-RTOS7 scheduler does not interact with that interrupt. We call it a zero-latency interrupt because the TI-RTOS7 kernel adds zero latency to the execution of these interrupts. The downside to zero-latency interrupts is that they cannot call into the kernel scheduler APIs (e.g. Semphore_post(), etc.).

    Zero-latency interrupt is exactly what I need. I did not find how to do it yet. See the link to the document: https://dev.ti.com/tirex/explore/node?node=A__ATkPgRhVpDZIvTj00Xr4hQ__com.ti.SIMPLELINK_ACADEMY_CC13XX_CC26XX_SDK__AfkT0vQ__LATEST&placeholder=true

    Rémi