cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L152 and short delay [Solved]

thoma
Associate II
Posted on November 01, 2011 at 12:36

Dear forum users,

I use the STM32L152 with a RTOS.

I need to wake up a task after a short delay (shorter than the time slot).

I think I will utilize a timer interrupt to release the mutex token in the delay routine.

This routine will also be protect using a second mutex to avoid re-entrance issue.

My question relates to the timer configuration to get the behavior description above.

Could someone help me to configure and to use the timer ?

Thank you in advance

Thoma

4 REPLIES 4
Posted on November 01, 2011 at 15:28

Please define ''short'' using international measurement units.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
thoma
Associate II
Posted on November 01, 2011 at 16:37

Hi clive1,

I would define ''short'' as between tens of clock pulses (~1µs) and the time slot of my RTOS (~1ms).

In the delay function, I will take the mutex and then I will start a timer (countdown) with the delay expressed in clock pulses.

When it reaches 0x00000000, it will raise an interrupt and I will give the mutex back.

Currently, I have no idea on how to configure the timer? And which timer can be use for this kind of operation?

Thank you.

Thoma

Posted on November 01, 2011 at 20:32

It's going to depend a lot on what resources you have to spare. You can pretty much use any timer.

I guess if I had TIM2 set up with a period of (10000 - 1), so that the update interrupt fell once every 1 ms, I could then use one of the 4 channels in compare mode to mark off events in the future. The timer would always be configured so you wouldn't need to set it up for each event.

For example, something like

 current = TIM_GetCounter(TIM2);

 TIM_SetCompare4(TIM2, current + 10); // 1us in the future

or

  TIM_SetCompare4(TIM2, 65535); // Off, park out of range

void TIM2_IRQHandler(void)

{

  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)

  {

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

    // 1ms event

  }

  else if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)

  {

    TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);

    TIM_SetCompare4(TIM2, 65535); // Out-of-scope

    // one-shot event

  }

}

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
thoma
Associate II
Posted on November 05, 2011 at 22:30

Hi clive1,

Many thanks for your suggestion.

Here is the final code:

initialization:

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    TIM_TimeBaseStructure.TIM_Period = 0x7FFF;

    TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 1000000) - 1;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active;

    TIM_OCInitStructure.TIM_Pulse = 0xFFFF; /* Out of scope */

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);

    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);

    TIM_ARRPreloadConfig(TIM3, DISABLE);

    TIM_Cmd(TIM3, ENABLE);

    TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);

interrupt code:

    if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)

    {

        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);

        TIM_SetCompare1(TIM3, 0xFFFF); /* Disable the interrupt by putting the compare value out of range */

        giveSemaphore();

    }

delay function:

 

   unsigned long current;

    lockFunction();

    current = TIM_GetCounter(TIM3);

    current += delay;

    current &= 0x7FFF;

    TIM_SetCompare1(TIM3, current);

    takeSemaphore();

    unlockFunction();

I chose a period of 32768 to simplify the computation of counter looping.

Thoma