2022-06-02 03:16 PM
I'm using STM32CubeMX and HAL functions.
I've gotten interrupt capture working for Timer 3 Channel 3. However, my input frequency is low and the 16-bit capture value is overflowing multiple times. I've solved this many times in the past with a different manufacturer microcontroller, so I know what to do. I'm trying to capture an interrupt for when Timer 3 itself overflow, so that I can count those overflows and thus logically extend the 16-bit capture value.
HOWEVER, I can't seem to catch the overflow interrupt (Period Elapsed). I do find that there's pretty much ZERO comprehensive doc for how all the HAL functions work. So I find myself poking around at many examples, and looking inside HAL code, trying to figure out what to do. It's just not working.
Please note that my main function has a definition of HAL_TIM_PeriodElapsedCallback() that was put there by the Cube and includes an "if(htim->Instance == TIM1) HAL_IncTick();". So I tried adding an "if(htim->Instance == TIM3) CallMyIncrement();" but CallMyIncrement() seems to never be called.
I have an early call to HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_3) to configure the input capture, just because an example did this. I also have NVIC Settings TIM3 global interrupt enabled in the Cube. I've had those since the beginning, and the input capture has worked since the beginning. But not the overflow (period elapsed) interrupt. I tried adding a call to HAL_TIM_Base_Init(&htim3); and HAL_TIM_Base_Start(&htim3); but that doesn't help.
CAN I IN FACT GET TWO TYPES OF INTERRUPTS out of Timer 3? I need both the input capture interrupt and the overflow (period elapsed) interrupt.
Another thing, the Cube for TIM3 has a config for "Clock Source" that is currently "Disable". No clue what that does. I could joke about how does this timer work if it has a clock source. Changing this to Internal, without perhaps doing some other magic, didn't help my overflow interrupts either.
Help!!!! Thanks very much.
2022-06-04 09:58 AM
Thanks, @Community member . I see the 16-bit thing in AN4013 Table 2 (page 7).
Now what I need and haven't been able to find is a simple register map with simple bit definitions. I need this, for example, so that I can inspect the right control register and confirm in the debugger after-the-fact that the correct bits are set. Working in this direction is nearly impossible using the source code and #define values, because there's too much inter-referencing of the #define values. It makes me have to run a compiler in my head all the time
2022-06-04 10:05 AM
((accidental sent above)) ...It makes me have to run a pre-compiler in my head all the time to figure out which bit position a cascade of #define references. This is definitely error-prone and NOT the right way to do it!
So what I mean my a simple register map is something like this:
And then for simple bit definitions I mean something like this:
2022-06-04 10:11 AM
,,,For example, my TIM3 has 0x4000,0400 and it's too unreliable to try and confirm which bits are set. Also, that's just the "TIM3" #define. I think there are more registers to be found, and I don't know their exact names yet. The map/defs I'm looking for should help that. The App Note has too many shortcuts and abbreviations to easily make certain. For example, AN4013 page 13 says "Select the active input by setting the CCxS bits in CCMRx register." There's not a "CCMR3" register #define name exactly, per se. So it's short hand for some longer name I haven't found yet. (Yes, I'll also search examples for non-HAL, but there ought to be some explicit stinking doc somewhere, if I can find it!)
Thanks. Had to "vent" a little about the doc. Still need the doc, though...
2022-06-04 11:00 AM
It might be a good idea to have a look at the Reference Manual for your uC. Surprise: you will find the detailed description of timer functionality and registers there. ;)
2022-06-04 01:12 PM
You should have started at the product folder for your STM32 on ST's web. It's ugly, but the info is there. As gbm said above, one of the canonical documents is the Reference Manual, in your case RM0008, that describes the registers.
Some general writeup about documentation here.
JW
2022-06-04 01:17 PM
> There's not a "CCMR3" register
The "x" does not necessarily mean "channel number", it's a generic placeholder. And TIMx_CCMRx is a confusing exception: timers have generally up to 4 capture-compare channels (some have 6 but that's exception), and there are two TIMx_CCMR registers, TIMx_CCMR1 for CH1 and CH2, and TIMx_CCMR2 for CH3 and CH4.
JW
2022-06-05 01:45 AM
In the debugger's peripheral view pane, there is a magic PLUS sign, which, once clicked, expands the register view into nicely labeled bits and bit fields, so no, you don't have to have register content decoder in your head.
2022-06-05 08:21 AM
My recommendation - show your code for us to look at. If it is proprietary, extract just the related Timer code.
[Edit] - show your original HAL code.
Cheers, Hal
2022-06-06 07:23 AM
***NOW WORKING***
@gbm that "debugger's peripheral view pane" sounds fantastic. Which debugger? Which IDE? I researched in the beginning and advise suggested using the Atollic TrueSTUDIO as the IDE. I know there's one from ST as well. So, to which are you referring? If Atollic, then might you clarify how to find this pane? I've searched through Atollic while running and can't find it. I find "Registers"/"General Registers", but that's a small subset. I find "SFR", which I assume is "Special Function Registers". That's empty and I can' figure out how to populate it with anything. Note: This question remains!
@gbm Yes, I have been RTFM, LOL, but there are far too many M's to find what I need. I've been unable to find any manuall with a detailed description of the timer functionality and registers, as you describe. I find plenty of examples; they all use HAL; I'm doing everything in the examples already; only one even mentions timer overflow counting, and I'm doing that, and HAL_TIM_PeriodElapsedCallback() is being called for TIM1, but not for the TIM3 I'm using.
@Community member thanks for the product folder link. Doh! I'm been searching for the manuals (the "FM") via Google and Digikey. There's so much that it escaped my attention to try ST's own home page for the processor. Even at that page, there's a lot of stuff and it's hard to figure out which is needed. Thanks for quoting RM0008. YAY! THERE'S THE REGISTER DEFINITIONS I WAS LOOKING FOR! (BTW, the ST home page still had too much doc for me to know that the "Reference Manual" was what I needed. So thanks again for naming it RM0008. It could hav been a "Programming Manual" or "User Manual" or "App Note" that had these register definitions.)
...In RM0008, I find TIM3 timer and, even before right now, I had realized 0x4000,0400 is a memory address, not a content. It's the base address. But I don't yet know what follows the base address for additional TIM3 control registers. Searching...
...In RM0008, I find page 423 section 15.4.19 TIMx register map. I see TIMx_???? such as TIMx_DIER. I recognize these names line up with debugging watch expression for htim3->Instance details. So I'm getting closer.
... ... I THINK I WANT TO FIND THE ENABLE BIT FOR TIM3 OVERFLOW EVENTUALLY GOING TO HAL_TIM_PeriodElapsedCallback(). In debugging, this callback was happening for TIM1 due to RTC, so I know the callback is hooked up. But it was never happening for TIM3.
... ... Now I just need to figure out if and which of these many bits enables interrupt on counter overflow or reset. I see a bit "CC3IE". That might be "Capture Channel 3 Interrupt Enable". That's in TIMx_DIER. Dunno yet what "DIER" means! Table of contents -- TIM2 to TIM5 -- DIER is "DMA/Interrupt Enable Register" -- checking page 409... Bingo. I see CC3IE is "Capture/Compare Interrupt Enable". I see "UIE" is Update interrupt enable. Maybe "Update" is the word I seek, for when the timer gets updated with a new value in order to run the count again. So UIE bit 0 of DIER. (FYI, RM0008 Figure 55 somewhat defines the term "update" and it occurs on counter "overflow". I'm used to the word "overflow". This is indeed what I'm looking for.)
... ... ... While debugging, inside my response to rising edge capture interrupt, I see that htim3->Instance->DIER = 8. That's an even number, so the UIE bit 0 is ***not*** set. That is consistent with the fact that I'm not getting overflow aka update aka periodelasped events. My I be so bold as to change the 8 to a 9 right here in the debugger, while the program is already running? Why yes. BAM!!!!!!!!!!!!!!!!! Very next debug stop was my overlow counter function, now called for the first time. So I just proved my problem is that htim3->Instance->DIER[UIE] bit is not being set anywhere.
... ... ... It's been under 10 minutes since I first started looking at RM0008 and now I know where I'm going!
... ... ... I found where DIER's CC3IE bit is beging set, at call to __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3) in function HAL_TIM_IC_Start_IT(). That makes sense. I saw and suspected that before, but couldn't connect to "DIER" or "CC3IE" because of nested #defines. (LOL, the comment above it helps: "Enable the TIM Capture/Compare 1 interrupt". But there's no mention anywhere of overflow or update or periodelapsed...)
... ... ... ... Ah, but the definition of __HAL_TIM_ENABLE_IT is enlighening. It simply assigns the second parameter bit to DIER. So I could call that function with a second parameter bit for UIE. (Source stm32f1xx_hal_tim.h)
... ... ... ... Found it. No input capture examples anywhere said I needed to call HAL_TIM_Base_Start_IT(). I had called HAL_TIM_Base_Start() as a shot in the dark, but didn't connect two and two together to realize there must exist a HAL_TIM_Base_Start_IT() function. I added HAL_TIM_Base_Start_IT(&htim3) and voila, I started getting overflow interrupts.
... ... ... It took under an hour all told to finish getting proper race-condition adjusted frequencies, including timer 3 overflows ("updates"), timing from when I opened RM0008. I just couldn't find RM0008. Thanks to all.
@raptorhal2 I was going to send select code, but now that's no longer necessary.
2022-06-07 12:24 AM
With some small extra effort you can get rid of Cube/HAL altogether. Its interrupt mux/demux model is super inefficient.
JW