backlight_software.c 1.3 KB

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