Phase matching timer interrupt sequence with LEDC PWM
Posted: Mon Feb 17, 2020 5:48 am
Hi all,
I am using an ESP32-PICO SoC to drive a display. I am programming it in Arduino framework using PlatformIO for Visual Studio Code. I have managed to set up a bit banging routine to drive my display. The bit bang is very lean and runs inside of a timer interrupt. I've programmed the interrupt to use hardware timer 0.
Now, I also want to dim my display using the LEDC function which seems perfect for my application. My display driver chips are essentially shift registers (clock, data, latch) inputs, and they also have a "blanking" pin which will turn the active outputs off when low, or on when high. They are intended to be driven with PWM, and varying the duty cycle high or low will dim the display accordingly.
I've set up my LEDC function to also use hardware timer 0.
...where ledChannel is set to 0. As defined in the espressif ledc library file esp32-hal-ledc.c:
* LEDC Chan to Group/Channel/Timer Mapping
** ledc: 0 => Group: 0, Channel: 0, Timer: 0
So why is it that when both my interrupt routine and the PWM are running at the same frequency and set to hardware timer 0, that the output signals are out of phase? This is causing visible jitter in my display, as the PWM signal goes high when the shift registers are clocking in new data. If I could control the phase of the PWM with respect to the interrupt, I would be able to make sure the PWM high does not overlap when the display is updating.
I appreciate any insight. Thank you.
I am using an ESP32-PICO SoC to drive a display. I am programming it in Arduino framework using PlatformIO for Visual Studio Code. I have managed to set up a bit banging routine to drive my display. The bit bang is very lean and runs inside of a timer interrupt. I've programmed the interrupt to use hardware timer 0.
Code: Select all
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 250, true); //250 microseconds = 4khz
timerAlarmEnable(timer);
I've set up my LEDC function to also use hardware timer 0.
Code: Select all
ledcSetup(ledChannel, freq, resolution);
ledcAttachPin(PWM, ledChannel);
* LEDC Chan to Group/Channel/Timer Mapping
** ledc: 0 => Group: 0, Channel: 0, Timer: 0
So why is it that when both my interrupt routine and the PWM are running at the same frequency and set to hardware timer 0, that the output signals are out of phase? This is causing visible jitter in my display, as the PWM signal goes high when the shift registers are clocking in new data. If I could control the phase of the PWM with respect to the interrupt, I would be able to make sure the PWM high does not overlap when the display is updating.
I appreciate any insight. Thank you.