cancel
Showing results for 
Search instead for 
Did you mean: 

Why is a clear of the UIF for TIM after TIMinit necessary?

Benjamin Brammer
Senior II
Posted on June 01, 2017 at 16:23

Hi Guys,

iam using the NUCLEO-F446RE to check on some routines for a custom board I am developing.

right now I am using the TIM2 to implement a simple button debounce in software.

But what puzzles me is the fact, that after the TIM2 initialization via HAL (made by CubeMX) the UIF is set, which results in an immediate jump into the TIM2 ISR routine after i started the timer via HAL command. Why is that?

Off course I can solve the problem by clearing the UIF bit prior in starting the TIM2 and then everything works fine.

But I doubt that this is wanted, or am I missunderstanding here something?

Another thing that quite puzzles me, is when I want to step through the 

HAL_TIM_IRQHandler() routine in debug mode, it seems as if the STM32 doesn't jump into the correct if instructions. So for example the UIF is being checked but not stepped into the routine for clearing Also the register I/O view is not updated automatically, I allways have to update it manually to see if the bits are really cleared or not.

I tested my program without my manual clearing of the UIF bit which should be handled by the HAL_TIM_IRQHandler() function. But if I don't implement this, my program is not working. So the HAL_TIM_IRQHandler() is not working.

Anyone has an explanation for this?

best regards

Benjamin

#nucleo-f446re #irq #timer #hal #irq-handler
6 REPLIES 6
Posted on June 01, 2017 at 16:53

after the TIM2 initialization via HAL (made by CubeMX) the UIF is set

Look into that initialization routine.It's set deliberately through the respective bit in EGR. The reason is to force an update which in turn loads the freshly stored value from PSC into the prescaler counter; otherwise the first period would use the 'old' prescaler which might result in surprisingly different period time.

This is the price you pay for 'programming through clicking', resulting in using a routine which is designed to produce the expected behaviour for most 'typical' use cases; instead of programming like adults do, i.e. reading the manual and then writing into a couple of registers values according to your particular needs.

Another thing that quite puzzles me, is when I want to step through the 

HAL_TIM_IRQHandler() routine in debug mode, it seems as if the STM32 doesn't jump into the correct if instructions.

Most debuggers (the devices+programs) don't cope well with optimized code, especially preprocessor macros. It's up to the debugger (the human who debugs) to work out the understanding.

JW

Posted on June 01, 2017 at 18:18

Hey JW,

thanks for your answer.

I think that the Cube is agreat tool to ease the designers need to implement complex peripheral handling. Off course I don't just click and see what's happening but as most of my experience with microcontrollers comes from TI and the MSP43x-series I am used to have a good functioning driver lib API, which off course should be documented well. After all APIs shall ease my life so that I don't have to write every procedure and register access myself. Surely I want to rely on them in working properly or at least have a hint in the reference manual on what to watch out for. Sadly this seems not so much the case for the HAL library.

I have found the problem now myself. Inside the TIM2 ISR i use HAL_TIM_Base_Stop_IT(&htim2) to stop the timer and wait for a next button press. This routine has to be executed after i call 

HAL_TIM_IRQHandler() or else the flag will not be cleared. I think this might be because the interrupt is disabled.

 Anyway it works now.

This is the price you pay for 'programming through clicking', resulting in using a routine which is designed to produce the expected behaviour for most 'typical' use cases; instead of programming like adults do, i.e. reading the manual and then writing into a couple of registers values according to your particular needs.

Your 'adult' comparisson is quite insulting and arrogant I think. As if everybody who not programs a complex microcontroller architecture from the scratch with only register access is a little baby or not reading the manuals.

Like I stated out at the beginning of my post, I think APIs are here to ease the developer's life and help him focus on the implementation of complex algorithms rather then writing hundreds of lines of code to proper set up a peripheral.

And even you started at some time without any knowledge and would have been happy to have a forum like this where to learn from the experience and knowledge of others. So please get rid of this kind of arrogance.

Thanks
Posted on June 02, 2017 at 10:32

Inside the TIM2 ISR i use HAL_TIM_Base_Stop_IT(&htim2) to stop the timer and wait for a next button press.

The usual practice is to spend as little time in ISRs as possible, deferring any waiting or substantial processing to main().

----

at least have a hint in the reference manual on what to watch out for

I don't understand. You expect the reference manual to warn you about the peculiarities of a 'library'? Because in this case, forcing update through EGR is the choice of the 'library', not any necessary consequence of setting up the period-governing registers of the timer. And if you've actually seen the function in question, you've might have noticed the explanation *is* there:

  /* Generate an update event to reload the Prescaler

     and the repetition counter(only for TIM1 and TIM8) value immediately */

Your 'adult' comparisson is quite insulting and arrogant I think.

It's a general expression of frustration. Please don't take it personally - if you feel offended personally, I apologize.

Unfortunately, as your post shows it clearly too, it has become an accepted practice to click first and expect 'libraries' to take some imaginary burden off the shoulders of a novice. The fact is, that most peripherals in the mcu are set up using writes to a few, maybe up to a dozen of registers, and most of them are by default set so that they provide the most often used functionality without a need to touch them. 'Libraries' inevitably implement only a limited set of options, given the nearly infinite combination of options and possibilities, and they can't capture all their fine-level interactions. So, at the end of the day, most users who need more than the basics, resort to some esoteric combination of 'library' and low-level access after a period of confusion.

The 'libraries' may still be great for superficial use of the mcu's features, for those, who are absolutely sure they will never need to go beyond the limited set of use cases the 'library' captures. I am not such a user and I often strive to exploit full functionality of each and every transistor I have paid for, even if they costed only a few millicents apiece.

What is really needed instead of 'libraries' is an extensive set of concise examples with clearly written and up to the point documentation, both the firm foundation in manuals and the practical explanation in application notes.

Now my grief is, that ST spends much much less time and energy on proper documentation and proper application notes than they should, making it harder to everyone. The few existing practical examples are buried deep into the 'library', with almost no accompanying documentation except extensive and mostly unhelpful doxygen autovomits; and at times, it's quite hard to extract the essence of them.

So, from my point of view, the more users I convert to the True Way Of Using Mcus Is Thru Registers, the better for me.

🙂

Jan

Posted on June 02, 2017 at 15:56

Ok, I think I understand.

So what would you suggest, how I start to deepen my knowledge? For example on the MSP432 it was very complicated to program the DMA with pure register access on my own, so I used the DriverLib which off course eased my programming and spared me time.

Would you even say not to use the LL-driver? So I should program in CMSIS style and everything on my own?

I agree with you, that I would love to have a very clear example on how to properly set up an STM32. Like what c files are mandatory (startup, vector table etc..) and then have some basic examples on how to proper include peripherals in my program.

Greets

Posted on June 04, 2017 at 17:03

Benjamin,

So what would you suggest, how I start to deepen my knowledge?

I don't know. It's easier to rant than to teach, so I do just the former.

For example on the MSP432 it was very complicated to program the DMA with pure register access on my own, so I used the DriverLib which off course eased my programming and spared me time.

I don't think you can get anywhere

http://norvig.com/21-days.html

. I am old-fashioned, you see, and what I believe in is lots of reading and hard work.

Would you even say not to use the LL-driver?

My basic problem with 'libraries' is that they barely provide more than rename the registers; so whenever you want to go beyond the surface you need to understand both. Why to learn something twice?

I was told by ST that 'libraries' ease porting. I can't comment on that, I never needed to port an application or substantial portions of it. That said, those manufacturer-provided 'libraries' naturally want to lock you to that manufacturer's mcu - and even within that usually only one mcu family (e.g. you can't use Cube to program STM8, although this may change in time).

I agree with you, that I would love to have a very clear example on how to properly set up an STM32.

I can't say how much it fulfulls the 'very clear' and 'properly', but I have a few barebones STM32 examples on efton.sk/STM32 . They would probably fail my own criteria on 'clear', mainly on the documentation side; but hey, I have my bills to pay.

Jan

Posted on June 05, 2017 at 12:11

Hey Jan,

thanks for your respond! I will keep that in mind.

greets

Benjamin