Page 1 of 1

maximum CH_FREQUENCY? software PWM generation

Posted: Sun Aug 25, 2013 3:17 am
by russian
I am playing with software PWM generation just to check how precisely can I schedule things. My algorithm is

Code: Select all

float period = (myfloat)CH_FREQUENCY) / 200;

start = chTimeNow();
while (TRUE) {
 for (int phaseIndex = 0; phaseIndex < state->phaseCount; phaseIndex++) {
  systime_t timeToSwitch = (systime_t) ((iteration + state->switchTimes[phaseIndex]) * period);
  chThdSleepUntil(start + timeToSwitch);
  int value = state->waves.pinStates[phaseIndex];
  setPinValue(outputPin, value);
 }
 iteration++;
}


Unless there is a better algorithm, this approach is as precise as big CH_FREQUENCY could be. With 168MHz stm32f4 I see that everything works with CH_FREQUENCY=200K but the board hangs with CH_FREQUENCY=500K (That's in Debug configuration with most of CH_DBG settings set to TRUE)
Looking at a logic analyzer I see that my 50% duty 200Hz software pulses are 2.49ms, 2.5ms or 2.51ms wide. All hardware PWM pulses are 2.5000x wide.

So, I guess my question is how much would things change with 3.0 tickless kernel and when is that happening? :) Unless there is a better algorithm or a way to get a higher CH_FREQUENCY

Re: maximum CH_FREQUENCY? software PWM generation

Posted: Sun Aug 25, 2013 7:21 am
by Giovanni
The problem is that doing that in SW you must expect some significant jitter when working with a resolution of just 2uS. The tickless kernel could improve the performance but you would still have jitter caused by critical zones and other ISRs.

You may make a better SW PWM by using a periodic timer generating a fast interrupt (priority 0), the fast handler cannot interact directly with the kernel but that would not be required, you may a global variable for the duty cycle (write it from threads, read it from the ISR, no synchronization needed because 32 bits accesses are atomic).

The fast interrupt would guarantee a very low jitter and if you optimize the handler you can even go for higher resolutions.

Giovanni

Re: maximum CH_FREQUENCY? software PWM generation

Posted: Sun Aug 25, 2013 8:16 pm
by russian
I've got better results with CH_FAST_IRQ_HANDLER, thank you for this hint! Things look right with a 2MHz timer / 2 tick period.

BTW what is the proper way to enable CH_FAST_IRQ_HANDLER (say for a timer in my case) and still enjoy the HAL driver to enable & configure everything? My hacky way was to simply comment 'CH_IRQ_HANDLER(STM32_TIM3_HANDLER)' declaration in pwm_lld.c but this does not look exactly right.

Re: maximum CH_FREQUENCY? software PWM generation

Posted: Sun Aug 25, 2013 8:26 pm
by Giovanni
Hi,

You can use just the NVIC functions for fast interrupts. You should not try to use the existing drivers, better operate at register level.

I will see if there are ways to bypass this problem in the 3.0 HAL.

Giovanni