Qmk_firmware: Hardware PWM on PD0

Created on 22 May 2019  Â·  11Comments  Â·  Source: qmk/qmk_firmware

Hi, I've flashed my keyboard (XD87) with the latest firmware, but I get random flashing of the backlight (even on full brightness), I assume that some USB processing is interrupting the soft PWM.

But confusingly the keyboard uses PD0 for the backlight on an atmega32u4, which as far as I can tell supports hardware PWM, is there away of QMK actually using this instead of falling back to soft PWM, which is a bit flaky ?

cheers!

bug core discussion help wanted question

Most helpful comment

I found the underlying cause of this issue — the problem is that the software PWM emulation code changes the state of the backlight control pin (D0 for XD87) from interrupt handlers, while the matrix scanning code changes the state of row pins, and some of row pins are from the same port D as the backlight pin. The matrix scanning code was updating the PORTD register in a way that was not safe against interrupt handlers which attempted to modify the same register, therefore some updates done by those interrupt handlers were overwritten by that unsafe read-modify-write code.

Disabling interrupts around the problematic operations (PR #9575) fixes this particular problem; the only remaining issue is that a running RGB underglow animation still causes backlight flicker, but this is a completely different problem which should appear on all keyboards which use software PWM for backlight and the bitbang WS2812 driver.

All 11 comments

The ATmega32U4 datasheet says of PD0:

This pin can be used to generate a PWM signal from the Timer 0 module.

However, I'm pretty sure Timer0 is used internally by QMK.

Soft PWM still uses a hardware timer as of recently - you should be seeing a message like this when compiling:

#pragma message "Using hardware timer 1 with software PWM"

Ah I see.
Yep I got that message, but somethings still glitching it.
I guess that that mode is still not perfect.

Have you tried using another USB cable?

I have experienced similar problems with the hardware PWM when using a thick cable with an aviator connector.

My theory is that something about the cable causes the VCC to drop lower than the controller can handle, and that the PWM feature is more sensitive to this.

I doubt it, as it was stable on the native firmware

@al3ph have you had a chance to test the PR referenced? With the suggested settings by fauxpark?

I'm confirming this issue. I'm also seeing the backlight blinking.

I compiled XD87 with the changes from #5983 (I looked in quantum.c and found the fix).

#ifdef BACKLIGHT_BREATHING
  if(is_breathing()) {
    breathing_task();
  }
#endif

I'm seeing the pragma message Using hardware time 1 with software PWM when compiling.

I'm coming from the TMK firmware which didn't have that problem (didn't change anything beside the firmware).

My knowledge won't get me far in debugging this though, at least without any help.

(also, related but unrelated, is the RGB underglow supposed to work? Doesn't look like it is on my end. I'm using RGB_TOG, RGB_VAI, RGB_MOD but nothing happens)

@LouWii could you try adding #define BACKLIGHT_ON_STATE 1 to your config.h? The default is 0, which is assuming a P-channel MOSFET where the LEDs are turned on by a low signal from the PWM pin (most backlight circuits use N-channel).

As for the RGB - resetting the EEPROM should work, otherwise perhaps it hasn't been set up - it's not enabled in rules.mk by default, and the config.h settings are commented out.

@fauxpark With #define BACKLIGHT_ON_STATE 1, the LEDs aren't blinking anymore at max brightness. However, the commands are reversed (bright+ decreases the brightness, and vice versa). Minimum brightness has the LEDs just a tiny bit lit up (not fully off) and they flash at almost full brightness randomly. When between max and min brightness, they flash like they do without #define BACKLIGHT_ON_STATE 1.

I'm going to look at the RGB config. EEPROM reset didn't work, but that's not surprising if RGB is not configured at all.

Those are exactly the same symptoms I got.

I've setup the RGB configuration for underglow and everything works fine. Submitted a PR for it: https://github.com/qmk/qmk_firmware/pull/6635

Still not sure what to do about the backlight though. Would the TMK firmware version help? I found it there: https://github.com/kairyu/tmk_keyboard_custom/pull/11/commits/bfcda567f6237462312fb5ac8b052f3ccedc6442

I found the underlying cause of this issue — the problem is that the software PWM emulation code changes the state of the backlight control pin (D0 for XD87) from interrupt handlers, while the matrix scanning code changes the state of row pins, and some of row pins are from the same port D as the backlight pin. The matrix scanning code was updating the PORTD register in a way that was not safe against interrupt handlers which attempted to modify the same register, therefore some updates done by those interrupt handlers were overwritten by that unsafe read-modify-write code.

Disabling interrupts around the problematic operations (PR #9575) fixes this particular problem; the only remaining issue is that a running RGB underglow animation still causes backlight flicker, but this is a completely different problem which should appear on all keyboards which use software PWM for backlight and the bitbang WS2812 driver.

Was this page helpful?
0 / 5 - 0 ratings