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.

RTOS/CC1310: Accuracy of timer on idle mode (cc1310)

Part Number: CC1310

Tool/software: TI-RTOS

I want to set PWM pulse width in timer interrupt (TIMERA, 125us,need high Accuracy). For power saving,CPU enter idle mode . In my application, every 120 times(15ms),CPU will run 2ms(active mode,not enter idle). So when entering or exiting active programm, the timer will be slow or quick.  If it's quick, i can use CPUdelay() . If it's slow,  I stop the timer,and start another timer TIMERB.
 In interrupt TIMERB,I restart TIMERA
 The simple programmer (not including  2ms function) is following
 

 
int main(void)
{
   
   
    /* Call board init functions */
    Board_initGeneral();
 
    ledPinHandle = PIN_open(&ledPinState, pinTable);
    if(!ledPinHandle)
    {
        System_abort("Error initializing board LED pins\n");
    }
   
     Timer_init();
 
    /* Start BIOS */
    BIOS_start();
    return (0);
}
void Timer_init(void)
{
   /* Switches the peripheral power domain on */
  Power_setDependency(PowerCC26XX_PERIPH_GPT2);
  /* Prevents the controller from going to standby */
  Power_setConstraint(PowerCC26XX_SB_DISALLOW);
  // register ISR and enable hardware interrupt for timer
  Hwi_Params params;
  Hwi_Params_init(&params);
  params.enableInt = TRUE;
  params.priority = 1;
  Hwi_construct(&timerHwi, INT_GPT2A, &interruptTimerA, &params, NULL);
 Hwi_construct(&timerHwi, INT_GPT2B, &interruptTimerB, &params, NULL);
 
  /* Configure the timer hardware */
  TimerDisable(GPT2_BASE, TIMER_A);
  TimerDisable(GPT2_BASE, TIMER_B);
  TimerConfigure(GPT2_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC | TIMER_CFG_B_ONE_SHOT);//TIMER_CFG_B_ONE_SHOT
  TimerPrescaleSet(GPT2_BASE, TIMER_A, 9); // 
 TimerPrescaleSet(GPT2_BASE, TIMER_B, 9);
 
  TimerLoadSet(GPT2_BASE, TIMER_A, 600); // 
 TimerLoadSet(GPT2_BASE, TIMER_B, 450);
 
  TimerIntClear(GPT2_BASE, TIMER_TIMA_TIMEOUT);
  TimerIntEnable(GPT2_BASE, TIMER_TIMA_TIMEOUT);
  TimerEnable(GPT2_BASE, TIMER_A);
 
  TimerIntClear(GPT2_BASE, TIMER_TIMB_TIMEOUT);
  TimerIntEnable(GPT2_BASE, TIMER_TIMB_TIMEOUT);
//  TimerEnable(GPT2_BASE, TIMER_B);
  while(1)
  {
    PIN_setOutputValue(ledPinHandle, LED_IDLE,0);
    HWREG(PRCM_BASE +PRCM_O_PDCTL1VIMS)  &= ~PRCM_PDCTL1VIMS_ON;
     PRCMCacheRetentionEnable();
     PRCMPowerDomainOff(PRCM_DOMAIN_CPU);
     SysCtrlAonSync();
     PRCMDeepSleep();
     PIN_setOutputValue(ledPinHandle, LED_IDLE,1);
  }
 
}
void interruptTimerA(UArg arg0)
{
  uint32_t status = TimerIntStatus(GPT2_BASE, true);
 if (TIMER_TIMA_TIMEOUT & status) {
    TimerIntClear(GPT2_BASE, TIMER_TIMA_TIMEOUT);
  }
 
  PIN_setOutputValue(ledPinHandle, LED_INTA,1);
 
  PIN_setOutputValue(ledPinHandle, LED_SET,!PIN_getOutputValue(LED_SET));
//  HWREG(GPT0_BASE + TBMATCHR)= duty0[index_out*NUM_MIC_SAMPLES_PACKET+ipwm];
// HWREG(GPT0_BASE + TAMATCHR)= duty1[index_out*NUM_MIC_SAMPLES_PACKET+ipwm];
  
  
  if(IdleT++>=120)
  {
     
     IdleT=0;
     TimerEnable(GPT2_BASE, TIMER_B);
     
    TimerDisable(GPT2_BASE, TIMER_A);
    
     PIN_setOutputValue(ledPinHandle, LED_INTB,1);
     
  }
 
  PIN_setOutputValue(ledPinHandle, LED_INTA,0); 
}
void interruptTimerB(UArg arg0)
{
  uint32_t status = TimerIntStatus(GPT2_BASE, true);
 if (TIMER_TIMB_TIMEOUT & status) {
    TimerIntClear(GPT2_BASE, TIMER_TIMB_TIMEOUT);
  }
  PIN_setOutputValue(ledPinHandle, LED_INTB,0);
  
  CPUdelay(158); //adjust the time of seting pwm
  PIN_setOutputValue(ledPinHandle, LED_SET,!PIN_getOutputValue(LED_SET));
//  HWREG(GPT0_BASE + TBMATCHR)= duty0[index_out*NUM_MIC_SAMPLES_PACKET+ipwm];
// HWREG(GPT0_BASE + TAMATCHR)= duty1[index_out*NUM_MIC_SAMPLES_PACKET+ipwm];
  
   CPUdelay(11);
   TimerEnable(GPT2_BASE, TIMER_A);
}
The correct timing sequence is
Line1:  LED_INTA 
Line2:  LED_INTB (when starting TIMRB ,set  high  ,and when entering interrupt TIMERB , becomes low)
Line3:  LED_EXT (when seting PWM , LED_EXT switch)
But 
the first time after powering on ,the  timing sequence is
 there are 40us delay before start TIMERB (what does it do) ,and  TIMERB enters interrupt later. So the time of setting PWM is not correct
What's matter?
Another, cfg file is used the example of CC1310 launchpad. rfExamples.cfg, no change
 
  • Hi,

    Just what functionality are you after exactly, is there a reason you can't use the PWM functionality that exist in the timer hardware? In your setup, have you accounted for time it takes for the device to wakeup and resume operation?
  • Hi, M-W

    1.  For simplification, I have removed PWM functionality. So, it is not because the PWM timer.

    2. Ii  happens after 120 times interruption ,not the programmer beginning.

    Could you heip me to run the programmer after defining the several LEDs, and you can understand my question.

    Thanks

      

  • Is it related to the systick interrupt ?    

  • Hi,

    If you can put together a full example file using the empty project and share this with me I could check it out for you. You should also try to remove your "power saving" while loop and see if that helps you. I would recommend you to not bypass the power driver to go into standby as this could potentially impact the system later of using TI Drivers etc.

    It would still be good if you could clarify just how you expect the two PWM signals act and work in the end. I can understand the delay you are seeing when you do it as you do, I'm trying to understand the use-case to see if there another better approach for you. Typically, if you need a high resolution PWM signal, setting up a periodic timer to toggle a pin is not the best way to do it. You most likely get a better result by actually using the PWM functionality of the timer.

    @jun jun

    I don't think this has anything to do with the systick (or system timer interrupt, not to be confused with SysTick) interrupt in this case. It could however be related to how he are handling power saving by bypassing the Power driver. Idle -> active takes ~14us, add some additional overhead to this depending on state of the RTOS and you could easily get a few more us jitter.
  • Hi,M-W

    I have uploaded  the programmer. It runs on CC1310 LaunchPad. I wish you could find the problem which I asked in the first post.

    In my formal app, I bulid only one task and one hwi timer interruption.  The task is RF receive. After receiving ,pwm width will be set  in the timer ISR. If the task is always active, the programmer is ok. But if I add the idle function(PRCMDeepSleep() etc)in the task loop. (refering to swra486).  the ISR will be broken for 40us accidentally. So ,the time setting pwm is not correct.  I don't know what happen .

     

     

    rfPacketRx_CC1310_LAUNCHXL_TI_CC1310F128.rar

  • Hi,

    I'm not sure I can actually see the delay you are describing. Running your demo, this is the output I get at all time over several seconds:

    My question is, do INTA and INTB need to be connected like this? Currently there is a small "gap" in INTA when INTB is running, is this gap something you require or could you simply setup two separate PWM signals for this?

  • Hi M-W

    Did you observe the first times after powering on . Ii happens on off-line(not ccs debugging)

    I  set PWM on INTA and INTB, so, it is continous.

    Thanks

  •    What causes interruption of timer delay 40us ? M3 has only one timer HWI  .

      If M3 is active , Timer HWI is correct .

  • It do sound like you are simply experiencing the latency it takes for the device to go in and out of LP mode.
    When running with the debugger, the device never really goes into low-power mode as the debugger is attached, this is not the case when running without debugger.

    If you comment out your "custom power saving" code in teh while(1) loop, you should see the same timings with or without debugger.