2020-05-25 12:19 PM
I have a custom board design using a STM32F407. Timer6 is running in interrupt mode with a 42 usec period. I also have Timer7 running in interrupt mode with a 3 second period (upcount mode).
Each time the Timer6 interrupt runs I reset the Timer7 TIM7_CNT register with this code:
HAL_TIM_Base_Stop_IT(&htim7);
TIM7->CNT = 0; // reset Timer7 count register
HAL_TIM_Base_Start_IT(&htim7);
I tried to reset TIM7_CNT without stopping and restarting the timer but it doesn't work that way. Is there a way the count register can be reset without stopping and restarting the timer? I have worked with other processors that allow you to change the timer count registers on the fly.
The 407 is running at 168 MHz. Looking at the family reference manual the start and stop operations appear to only take one clock cycle. So there is no real delay caused by starting and stopping the timer. I am just curious if the count reset can be done with one instruction.
There is an asynchronous process that is triggered by external hardware. It may run 50 times a day or it may run 0 times per day. When the process starts, it starts Timer6 and Timer7. As long as the process continues to run, Timer7 is constantly reset. When the process stops and doesn't restart within 3 seconds, Timer7 times out and the interrupt fires. Timer6, Timer7, and other hardware is then shutdown.
2020-05-25 01:21 PM
> I tried to reset TIM7_CNT without stopping and restarting the timer but it doesn't work that way.
I don't know what exactly did you do, but writing to TIM7->CNT on the fly does work.
There are also other ways to clear a timer's register, e.g. by setting TIMx_EGR.UG, but that has other effects, different from directly setting TIMx_CNT.
46us interrupt period may be excessive even with 168MHz system clock. There may be ways to achieve your goal entirely in hardware, not with TIM6/TIM7 though.
JW
PS. STM323DF4?
2020-05-25 01:29 PM
Dunno about the M4, but the F730 reference manual explicitly says yes. I know because i was wondering about the same thing, so i did some careful reading of the rm.
2020-05-26 11:00 AM
Jan, based on what you said, I ran some additional tests. I was triggering the test by using the push button on the Discovery board. I commented that code out and just ran the 2 timers. You are correct, I do not have to stop and start the timer. TIM7_CNT can be reset on the fly.
Based on my first timer tests on the Dicovery board, I had put the stop and start functions in my actual application code. After I saw it worked in the new timer test code on the Discovery board, I commented the stop and start functions out on my custom board. The count register reset works there also so all is good.
The 42 usec interrupt is set in stone. I am processing a signal 24,000 times per second and the timer is being used as a trigger for that process.
Rich, your comment reinforced what Jan was saying. If it works on the F730 it should work on the F407.
2020-05-26 02:08 PM
> Looking at the family reference manual the start and stop operations appear to only take one clock cycle.
It takes one bus cycle to write the register. TIM6 and TIM7 are on the slower APB1 bus, so it takes two system core cycles, two more cycles for loading a value in a CPU register and storing it to a memory mapped hardware register, and up to 6 cycles flash latency. Assuming that the base address of TIM7 is already loaded into a register.
> So there is no real delay caused by starting and stopping the timer.
The real delay is rather caused by the HAL functions, which can take a couple of milliseconds to set a few registers.
24 kHz interrupt frequency (one interrupt every 7000 cycles) is IMO noticeable but fine as long as you don't do lengthy calculations in the interrupt handler. But a single HAL function call can easily burn 500 cycles, so try sticking the register interface if you want to do something useful in the time between interrupts.
2020-05-26 06:48 PM
Peter,
Thanks for the calculations. I looked at several timing diagrams but couldn't figure out how to put all the timings together.
The only thing I do in the interrupt routine is trigger an ADC measurement, read the value, and send it via UDP to another remote 407 board using the MX_LWIP_Process() function. I am actually processing audio and sending it to the remote end. I have monitored the remote audio for several 10 minute test sessions and there are no dropouts. So I guess timer manipulation isn't causing any noticeable delay. I use a 32K buffer on the remote end and trigger the DAC at the same 24 kHz rate that the sending end uses. I wait for the buffer to get half full before processing the audio. That solves any data arrival timing discrepancies.
I have thought about moving all of the code to direct register access. The only thing I would not be able to move would be the LwIP and STM32 Ethernet code. I would still need to use CubeMX to generate that code as it is quite complex. Everything else I can do with direct register read and write operations. I would do that as a learning exercise as I have only been seriously working with STM32 parts for about 6 months. I have played with them several times over the last 3 or 4 years and finally decided to make a serious effort to learn how all the peripherals work. This project was an exercise to see if I could make it work.