Alright, I felt like looking at the tmk code to figure out a way to do brightness control on the backlight.
For now I sacrificed the separation of switch and pcb backlight I had previously, but with some changes to the core code it can be done. It would just need another set of backlight functions or incompatible changes to the existing one and its eeprom storage. For now this just touches the keyboard specific backlight configuration.
The PB6 and PB7 pins can be PWM controlled with a timer, and luckily there is a small example of static brightness setting in orphaned phantom code:
orphan/phantom/matrix.c.
So I basically just take that, kill the PWM at brightness zero and scale the brightness levels. The tmk core can set and save 128 brightness levels, but I end up scaling just 8 steps to useful values in the 8 bit range.
You could probably get a brightness hook into the main loop and do some fancy backlight cycling in a similar way.
backlilght.c
Code: Select all
void backlight_init_ports()
{
/*
* The backlight LED pins PB6 and PB7 can be
* controlled through the output compare values in
* OCR1C and OCR1B.
* Counter1 is set to Fast PWM 8-bit mode with
* a prescaler divisor of 256. (WGM10, WGM12, and CS12 bits
* set in the control registers A/B)
*
* f_clk 16000000
* f = --------- = ----------- =~ 244Hz
* N*(1+TOP) 256*(1+255)
*
* The comparision port is set to low once the counter matches
* our compare value (COM1x1 bit set in control register).
* Setting the compare register (OCR1x) to BOTTOM (=0)
* results in a narrow spike for each TOP+1 cycle.
* So the comparison output is deactivated to reach
* zero output.
*/
// Timer/Counter1 Control Registers
TCCR1A |= (1<<WGM10);
TCCR1B |= (1<<WGM12) | (1<<CS12);
// Enable output pins
DDRB |= 0b11100000; // PB7 (switch), PB6 (pcb), PB5 (caps)
// PB6 and 7 are only used by output compare
PORTB &= ~0b11000000;
}
void backlight_set(uint8_t level)
{
if (level == 0) {
// Disable comparison
TCCR1A &= ~((1<<COM1C1) | (1<<COM1B1));
} else {
// Enable comparison
TCCR1A |= (1<<COM1B1) | (1<<COM1C1);
uint8_t scaled = level * level * BACKLIGHT_SCALE - 1;
OCR1B = scaled; // Output compare register 1B (PB7 - switch)
OCR1C = scaled; // Output compare register 1C (PB6 - pcb)
}
}
(commits:
https://github.com/kekstee/tmk_keyboard ... 8b849b20e7
https://github.com/kekstee/tmk_keyboard ... 7782d56c46)
// edit
Just duplicated the tmk backlight stuff and named it backlightb, so now I can control switch and PCB backlight independently on my NerD60. It's on
a different branch for now - there are probably more elegant ways to extend backlight scaling to different sets of LEDs.