logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

djinn.c (7696B)


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