You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
6.3 KiB

  1. // Copyright 2018-2022 Nick Brassel (@tzarc)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <string.h>
  4. #include "quantum.h"
  5. #include <hal_pal.h>
  6. #include "djinn.h"
  7. #include "serial.h"
  8. #include "split_util.h"
  9. #include "qp.h"
  10. painter_device_t lcd;
  11. // clang-format off
  12. #ifdef SWAP_HANDS_ENABLE
  13. const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = {
  14. { { 6, 6 }, { 5, 6 }, { 4, 6 }, { 3, 6 }, { 2, 6 }, { 1, 6 }, { 0, 6 } },
  15. { { 6, 7 }, { 5, 7 }, { 4, 7 }, { 3, 7 }, { 2, 7 }, { 1, 7 }, { 0, 7 } },
  16. { { 6, 8 }, { 5, 8 }, { 4, 8 }, { 3, 8 }, { 2, 8 }, { 1, 8 }, { 0, 8 } },
  17. { { 6, 9 }, { 5, 9 }, { 4, 9 }, { 3, 9 }, { 2, 9 }, { 1, 9 }, { 0, 9 } },
  18. { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 10 }, { 5, 10 }, { 4, 10 }, { 3, 10 } },
  19. { { 0, 0 }, { 6, 11 }, { 5, 11 }, { 4, 11 }, { 3, 11 }, { 2, 11 }, { 1, 11 } },
  20. { { 6, 0 }, { 5, 0 }, { 4, 0 }, { 3, 0 }, { 2, 0 }, { 1, 0 }, { 0, 0 } },
  21. { { 6, 1 }, { 5, 1 }, { 4, 1 }, { 3, 1 }, { 2, 1 }, { 1, 1 }, { 0, 1 } },
  22. { { 6, 2 }, { 5, 2 }, { 4, 2 }, { 3, 2 }, { 2, 2 }, { 1, 2 }, { 0, 2 } },
  23. { { 6, 3 }, { 5, 3 }, { 4, 3 }, { 3, 3 }, { 2, 3 }, { 1, 3 }, { 0, 3 } },
  24. { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 6, 4 }, { 5, 4 }, { 4, 4 }, { 3, 4 } },
  25. { { 0, 0 }, { 6, 5 }, { 5, 5 }, { 4, 5 }, { 3, 5 }, { 2, 5 }, { 1, 5 } },
  26. };
  27. # ifdef ENCODER_MAP_ENABLE
  28. const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = { 1, 0 };
  29. # endif // ENCODER_MAP_ENABLE
  30. #endif // SWAP_HANDS_ENABLE
  31. // clang-format on
  32. void board_init(void) {
  33. usbpd_init();
  34. }
  35. //----------------------------------------------------------
  36. // Initialisation
  37. void keyboard_post_init_kb(void) {
  38. // Register keyboard state sync split transaction
  39. transaction_register_rpc(RPC_ID_SYNC_STATE_KB, kb_state_sync_slave);
  40. // Reset the initial shared data value between master and slave
  41. memset(&kb_state, 0, sizeof(kb_state));
  42. // Turn off increased current limits
  43. setPinOutput(RGB_CURR_1500mA_OK_PIN);
  44. writePinLow(RGB_CURR_1500mA_OK_PIN);
  45. setPinOutput(RGB_CURR_3000mA_OK_PIN);
  46. writePinLow(RGB_CURR_3000mA_OK_PIN);
  47. // Turn on the RGB
  48. setPinOutput(RGB_POWER_ENABLE_PIN);
  49. writePinHigh(RGB_POWER_ENABLE_PIN);
  50. #ifdef EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN
  51. setPinOutput(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN);
  52. writePinHigh(EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN);
  53. #endif // EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN
  54. // Turn on the LCD
  55. setPinOutput(LCD_POWER_ENABLE_PIN);
  56. writePinHigh(LCD_POWER_ENABLE_PIN);
  57. // Let the LCD get some power...
  58. wait_ms(150);
  59. // Initialise the LCD
  60. lcd = qp_ili9341_make_spi_device(320, 240, LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN, 4, 3);
  61. qp_init(lcd, QP_ROTATION_0);
  62. // Turn on the LCD and clear the display
  63. kb_state.lcd_power = 1;
  64. qp_power(lcd, true);
  65. qp_rect(lcd, 0, 0, 239, 319, HSV_BLACK, true);
  66. // Turn on the LCD backlight
  67. backlight_enable();
  68. backlight_level(BACKLIGHT_LEVELS);
  69. // Allow for user post-init
  70. keyboard_post_init_user();
  71. }
  72. //----------------------------------------------------------
  73. // RGB brightness scaling dependent on USBPD state
  74. #if defined(RGB_MATRIX_ENABLE)
  75. RGB rgb_matrix_hsv_to_rgb(HSV hsv) {
  76. float scale;
  77. switch (kb_state.current_setting) {
  78. default:
  79. case USBPD_500MA:
  80. scale = 0.35f;
  81. break;
  82. case USBPD_1500MA:
  83. scale = 0.75f;
  84. break;
  85. case USBPD_3000MA:
  86. scale = 1.0f;
  87. break;
  88. }
  89. hsv.v = (uint8_t)(hsv.v * scale);
  90. return hsv_to_rgb(hsv);
  91. }
  92. #endif
  93. //----------------------------------------------------------
  94. // UI Placeholder, implemented in themes
  95. __attribute__((weak)) void draw_ui_user(void) {}
  96. //----------------------------------------------------------
  97. // Housekeeping
  98. void housekeeping_task_kb(void) {
  99. // Update kb_state so we can send to slave
  100. kb_state_update();
  101. // Data sync from master to slave
  102. kb_state_sync();
  103. // Work out if we've changed our current limit, update the limiter circuit switches
  104. static uint8_t current_setting = USBPD_500MA;
  105. if (current_setting != kb_state.current_setting) {
  106. current_setting = kb_state.current_setting;
  107. switch (current_setting) {
  108. default:
  109. case USBPD_500MA:
  110. writePinLow(RGB_CURR_1500mA_OK_PIN);
  111. writePinLow(RGB_CURR_3000mA_OK_PIN);
  112. break;
  113. case USBPD_1500MA:
  114. writePinHigh(RGB_CURR_1500mA_OK_PIN);
  115. writePinLow(RGB_CURR_3000mA_OK_PIN);
  116. break;
  117. case USBPD_3000MA:
  118. writePinHigh(RGB_CURR_1500mA_OK_PIN);
  119. writePinHigh(RGB_CURR_3000mA_OK_PIN);
  120. break;
  121. }
  122. // If we've changed the current limit, toggle rgb off and on if it was on, to force a brightness update on all LEDs
  123. if (is_keyboard_master() && rgb_matrix_is_enabled()) {
  124. rgb_matrix_disable_noeeprom();
  125. rgb_matrix_enable_noeeprom();
  126. }
  127. }
  128. // Turn on/off the LCD
  129. static bool lcd_on = false;
  130. if (lcd_on != (bool)kb_state.lcd_power) {
  131. lcd_on = (bool)kb_state.lcd_power;
  132. qp_power(lcd, lcd_on);
  133. }
  134. // Enable/disable RGB
  135. if (lcd_on) {
  136. // Turn on RGB
  137. writePinHigh(RGB_POWER_ENABLE_PIN);
  138. // Modify the RGB state if different to the LCD state
  139. if (rgb_matrix_is_enabled() != lcd_on) {
  140. // Wait for a small amount of time to allow the RGB capacitors to charge, before enabling RGB output
  141. wait_ms(10);
  142. // Enable RGB
  143. rgb_matrix_enable_noeeprom();
  144. }
  145. } else {
  146. // Turn off RGB
  147. writePinLow(RGB_POWER_ENABLE_PIN);
  148. // Disable the PWM output for the RGB
  149. if (rgb_matrix_is_enabled() != lcd_on) {
  150. rgb_matrix_disable_noeeprom();
  151. }
  152. }
  153. // Match the backlight to the LCD state
  154. if (is_keyboard_master() && is_backlight_enabled() != lcd_on) {
  155. if (lcd_on)
  156. backlight_enable();
  157. else
  158. backlight_disable();
  159. }
  160. // Draw the UI
  161. if (kb_state.lcd_power) {
  162. draw_ui_user();
  163. }
  164. // Go into low-scan interrupt-based mode if we haven't had any matrix activity in the last 250 milliseconds
  165. if (last_input_activity_elapsed() > 250) {
  166. matrix_wait_for_interrupt();
  167. }
  168. }