2022-08-04 06:45 PM
I am using Segger Embedded Studio 6.32 to develop a project for the STM32L062K8U6. While there are some start-up files created by the SES project wizard, I am not using any pre-built libraries and developing all my own code based on information from the "RM0376 Reference manual Ultra-low-power STM32L0x2 advanced Arm®-based 32-bit MCUs" and related docs.
I am having a problem with a hard fault occurring every time I enable one of the timers. I have code to run a 500us timer delay that I have tested with timers 2, 6, 21, and 22 with the same result in each case. The main loop toggles an IO pin every time the overflow flag is set. Watching the output on the o'scope I can see that I am getting a correct 500us period, but no matter what timer is used, after 48 seconds of operation I end up in the default hard fault exception handler. I am at a loss to explain this behavior and have not had this issue with timers on other ST Cortex M0 chips.
Internet searches on this topic turn up a lot of threads that suggest that the problem may lie with the processor calling an ISR that doesn't exist. However, if that applies in my case it raises a lot of questions:
* Interrupts are not enabled globally, so why would the code attempt to vector to an ISR, and even then, why a hard fault instead of the default ISR created by the project wizard?
* If it's a timer based ISR, why does the code continue to operate with no errors for 48 seconds instead of doing the hard fault immediately after the first 500us?
* Problem happens if the UIE bit for the timer is set or not.
* Problem happens if WDT is enabled or not, and a WDT timer reset would be expected to restart the code rather than hard fault.
For an example state when I'm in the hard fault handler using TIM2 :
CR1 = 0x00000001
CR2 = 0x00000000
DIER = 0x00000001
DMAR = 0x00000001
SR = 0x0000001F
Any thoughts would be appreciated.
Solved! Go to Solution.
2022-08-27 05:19 PM
Thank you to all who commented. As expected the issue turned out not to be related to the timer per se. I have the processor running at the max speed of 32MHz, which requires the LATENCY bit in FLASH_ACR to be set to 1, not the default value of zero. Although I did have a line of code in my configuration function that took care of this step, it wasn't correctly setting the bit, so when I took care of this issue everything finally started working correctly. It's still a matter of curiosity as to what the timer does that relates to this (maybe the auto-reload write to the count register gets out-of-sync?), since the issue doesn't present if I just have code that toggles the state of the IO pin w/o using the timer.
2022-08-25 02:22 PM
Still no luck with trying to debug this issue, but I did notice that the reset happens at faster intervals if I increase the speed at which the timer rolls over. Which still makes it confusing, if it's directly related to the timer why doesn't the issue happen at every roll-over?
2022-08-25 03:06 PM
Debug the Hard Fault as if it weren't related to the timer..
2022-08-26 12:56 PM
What ^^^^ he said.
Plus, you have the "update" interrupt enabled in DIER. If you haven't set the ARR, it defaults to 0xffff (or 0xffffffff for 32-bit timers). So you will get that interrupt whenever the timer reaches max count (i.e. rolls over). Do you have the timer IRQ enabled in the NVIC? And do you have the interrupt vector for the timer interrupt set to a real address (i.e.not zero)?
2022-08-27 05:19 PM
Thank you to all who commented. As expected the issue turned out not to be related to the timer per se. I have the processor running at the max speed of 32MHz, which requires the LATENCY bit in FLASH_ACR to be set to 1, not the default value of zero. Although I did have a line of code in my configuration function that took care of this step, it wasn't correctly setting the bit, so when I took care of this issue everything finally started working correctly. It's still a matter of curiosity as to what the timer does that relates to this (maybe the auto-reload write to the count register gets out-of-sync?), since the issue doesn't present if I just have code that toggles the state of the IO pin w/o using the timer.