Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


You are viewing a reply to pwm with one shot timer  

pwm with one shot timer

start_of_pulse      Pulsefinishedcallback   Periodelapsedcallback and start of next pulse

|-----------------------|                                   |-----------------------------|
|                             |----------------/ /---- -- --|                                    |------------
calculate|               |update                        |effekt
              |


If doing the updates of CCRs when Periodelapsedcallback arrives the next pulse is already started isn’t it so?
If this is the case, the updates gets in effekt not until the over next pulse starts, because the calculation
of their lengths starts at Periodelapsedcallback.
Or is the next pulse started not until Periodelapsedcallback has terminated? I don’t think so, the hardware is going on.

So I update any CCR in the corresponding Pulsefinishedcallback.

But even then the updates gets in effekt not until the next pulse starts.

The pulses are repaeted with period 5ms. Minimum lenght of pulse is 1ms.

The calculation for the lengths last about 500us started right after Periodelapsedcallback.
Can I update the CCRs shadows for the current pulses while they are not jet finished? I don’t think so,

So, when the calculation is done, it lasts 4.5 ms until it gets in effekt. While inbetween
there are more recent values which could be a more recent foundation for a calculation of the
length of the pulses.

My idea now is to start the pulses by software right after the calculation is done and start
the next calculation right after the period has elapsed. The Period of the timer must be set
to 4.5 ms then to keep the overall period.

Maybe have a look at https://github.com/nichtgedacht/mini-sysQuestion

Regards,
Dieter

France

Hi Dieter,

If what you want is that each pulse length be calculated using the most recent data available, why not compute these about 1ms before the next pulse start? This can be done simply using output comare in another channel of the same timer. Then you will have 500µs for calculating the next pulse length and update the pulse length comparator value and you should have finished 500µs before the next update event (at the end of the period, just before the next pulse starts) having thus enough margin to be sure you will be OK.

However I’m afraid you may have to look at HAL timer code as I’m not sure there is standard APIs to do that. Perhaps a simple call to HAL_TIM_OC_Start_IT with another channel of the same timer will be enough, after having set the corresponding CCxR register to 4/5 of the timer period... (the same register you set to set the pulse length); then HAL_TIM_OC_DelayElapsedCallback should be called about 1ms before the next pulse start, so you had plenty of time to calculate its length...

However, while looking at the code, although the IRQ handler knows what channel has generated the interrupt, it does not pass this information to th eDelayElapsed callback (it even calls both the pulse terminated callback and the delay elapsed callback, as PWM is based on output compare...), so you must (in both callbacks) check if the channel that generate the IRQ is the one you are interested in, by
if(__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) !=RESET)


It’s a pity that, while there is 4 independent channels in a timer, the HAL layer does not support using more than 1 channel at the same time... We thus have to trick it to obtain what we need.

Bernard (Ac6)


France

Hi Dieter,

I’ve looked a bit more on the HAL way to do what I’ve sketched above.

I’ve missed at least two things:

  1. You should do a call to HAL_TIM_OC_ConfigChannel for th eoutput compare channel in your initialization routine
  2. In th einterrupt callbacks, you could know which channel is generating th einterrupt by looking at the htim->Channel field


Of course the initialzation part can be simplified a lot if you use CubeMX...

Bernard (Ac6)