backlight_software.c (1365B)
1 #include "backlight.h" 2 #include "backlight_driver_common.h" 3 #include "util.h" 4 5 #ifdef BACKLIGHT_BREATHING 6 # error "Backlight breathing is not available for software PWM. Please disable." 7 #endif 8 9 static uint16_t s_duty_pattern = 0; 10 11 // clang-format off 12 13 /** \brief PWM duty patterns 14 * 15 * We scale the current backlight level to an index within this array. This allows 16 * backlight_task to focus on just switching LEDs on/off, and we can predict the duty pattern 17 */ 18 static const uint16_t backlight_duty_table[] = { 19 0b0000000000000000, 20 0b1000000000000000, 21 0b1000000010000000, 22 0b1000001000010000, 23 0b1000100010001000, 24 0b1001001001001000, 25 0b1010101010101010, 26 0b1110111011101110, 27 0b1111111111111111, 28 }; 29 #define backlight_duty_table_size ARRAY_SIZE(backlight_duty_table) 30 31 // clang-format on 32 33 static uint8_t scale_backlight(uint8_t v) { 34 return v * (backlight_duty_table_size - 1) / BACKLIGHT_LEVELS; 35 } 36 37 void backlight_init_ports(void) { 38 backlight_pins_init(); 39 } 40 41 void backlight_set(uint8_t level) { 42 s_duty_pattern = backlight_duty_table[scale_backlight(level)]; 43 } 44 45 void backlight_task(void) { 46 static uint8_t backlight_tick = 0; 47 48 if (s_duty_pattern & ((uint16_t)1 << backlight_tick)) { 49 backlight_pins_on(); 50 } else { 51 backlight_pins_off(); 52 } 53 backlight_tick = (backlight_tick + 1) % 16; 54 }