STM32/STM8 Timers - should I "wait" before updating ARR after UEV? - Page 1
Forum section: electronics / general

author: Saimoun
author_rank: Frequent Contributor
timestamp: February 11, 2021, 01:48:00 pm
content: HiShort version: should there be time (cycles) between generating an update event by setting the UG bit in TIMx_EGR and updating ARR/CCR preload registers?Long version:I am using one timer on an STM8, which is automatically enabled (triggered) by another timer.I made sure that:The timer is not enabled and will not be started before the setup (lines below)Setting the UG bit will not call the interrupt (URS set in in TIMx_CR)Both ARR and CCR are pre-loaded (ARPE set in TIMx_CR and OC1PE set in TIMx_CCMR)Then I do:set ARR and CRR values into their preload registergenerate a UEV (UG bit in TIMx_EGR) to load the values into the shadow registersThen change again (right away) the values of the preload registers so that the shadows are automatically updated on the next UEVThen - later - the timer is startedI get very strange result - if I add a nop() or pretty much any instruction anywhere in the whole code as long as it is "before" (i.e. lower address) the first line below, then the code works fine. My guess is that is just "lucky" and it should not work.... ?So my guess is that I need to wait at least one cycle after the UEV before updating the preload registers again - but I could not find any info about that in the manuals.Here is my code, uncommenting or not the nop():Code:TIM3->CCR1L = 2; // these values will be taken into account right away (see below)TIM3->ARRL = 9;TIM3->EGR |= TIM_EGR_UG; // generate and UEV to load the CCR and ARR values right above//nop();TIM3->CCR1L = 4; // these values will be taken into account on the next UEVTIM3->ARRL = 11;When the nop() is not there, then the output acts like if the first ARR was 7 and not 9, the rest all works fine. Very strange, it is like it "did not have the time" and missed one bit? haI already checked with the Debugger and it shows all the values are fine - but I can only check the preload registers and not the shadow registers.Thank you!Simon

author: Saimoun
author_rank: Frequent Contributor
timestamp: February 11, 2021, 04:45:31 pm
content: I did a bit more investigation regarding the strange behavior without the nop after the UG bit setting.It seems it only has an issue when the bit setting (TIM3->EGR |= TIM_EGR_UG) isexactlyat the beginning of a 32 bit word, i.e. an adress divisible by 4.For example if that instruction is at 0xfb64 in the memory space, then I can add or remove any multiple of 4 bytes before and the problem persists. If I add or remove 1, 2 or 3 bytes, then the problem is gone.Kinda very nerdy at this point, but I guess it is something to do with the fact that the STM8 has a 32 bit wide pre-fetching buffer... If anybody has the courage to help me understand, I think the answer is in chapter 5 (Pipeline execution) of this manual:https://www.st.com/resource/en/programming_manual/cd00161709-stm8-cpu-programming-manual-stmicroelectronics.pdf

author: Saimoun
author_rank: Frequent Contributor
timestamp: February 11, 2021, 06:41:01 pm
content: Just FYI I also tried the same test (adding 1, 2, 3 or 4 bytes before the bit of code shown) but this time with the nop() after the UG bit setting.With the nop() it works all the time, regardless of its position in the memory space.