split_util.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #include "split_util.h"
  2. #include "matrix.h"
  3. #include "keyboard.h"
  4. #include "config.h"
  5. #include "timer.h"
  6. #include "transport.h"
  7. #include "quantum.h"
  8. #ifdef PROTOCOL_LUFA
  9. # include <LUFA/Drivers/USB/USB.h>
  10. #endif
  11. #ifdef PROTOCOL_VUSB
  12. # include "usbdrv.h"
  13. #endif
  14. #ifdef EE_HANDS
  15. # include "eeconfig.h"
  16. #endif
  17. #if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
  18. # include "rgblight.h"
  19. #endif
  20. #ifndef SPLIT_USB_TIMEOUT
  21. # define SPLIT_USB_TIMEOUT 2000
  22. #endif
  23. #ifndef SPLIT_USB_TIMEOUT_POLL
  24. # define SPLIT_USB_TIMEOUT_POLL 10
  25. #endif
  26. #ifdef PROTOCOL_CHIBIOS
  27. # define SPLIT_USB_DETECT // Force this on for now
  28. #endif
  29. volatile bool isLeftHand = true;
  30. #if defined(SPLIT_USB_DETECT)
  31. # if defined(PROTOCOL_LUFA)
  32. static inline bool usbHasActiveConnection(void) { return USB_Device_IsAddressSet(); }
  33. static inline void usbDisable(void) { USB_Disable(); }
  34. # elif defined(PROTOCOL_CHIBIOS)
  35. static inline bool usbHasActiveConnection(void) { usbGetDriverStateI(&USBD1) == USB_ACTIVE; }
  36. static inline void usbDisable(void) { usbStop(&USBD1); }
  37. # elif defined(PROTOCOL_VUSB)
  38. static inline bool usbHasActiveConnection(void) {
  39. usbPoll();
  40. return usbConfiguration;
  41. }
  42. static inline void usbDisable(void) { usbDeviceDisconnect(); }
  43. # else
  44. static inline bool usbHasActiveConnection(void) { return true; }
  45. static inline void usbDisable(void) {}
  46. # endif
  47. bool usbIsActive(void) {
  48. for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
  49. // This will return true if a USB connection has been established
  50. if (usbHasActiveConnection()) {
  51. return true;
  52. }
  53. wait_ms(SPLIT_USB_TIMEOUT_POLL);
  54. }
  55. // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
  56. usbDisable();
  57. return false;
  58. }
  59. #elif defined(PROTOCOL_LUFA)
  60. static inline bool usbIsActive(void) {
  61. USB_OTGPAD_On(); // enables VBUS pad
  62. wait_us(5);
  63. return USB_VBUS_GetStatus(); // checks state of VBUS
  64. }
  65. #else
  66. static inline bool usbIsActive(void) { return true; }
  67. #endif
  68. __attribute__((weak)) bool is_keyboard_left(void) {
  69. #if defined(SPLIT_HAND_PIN)
  70. // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
  71. setPinInput(SPLIT_HAND_PIN);
  72. return readPin(SPLIT_HAND_PIN);
  73. #elif defined(EE_HANDS)
  74. return eeconfig_read_handedness();
  75. #elif defined(MASTER_RIGHT)
  76. return !is_keyboard_master();
  77. #endif
  78. return is_keyboard_master();
  79. }
  80. __attribute__((weak)) bool is_keyboard_master(void) {
  81. static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
  82. // only check once, as this is called often
  83. if (usbstate == UNKNOWN) {
  84. usbstate = usbIsActive() ? MASTER : SLAVE;
  85. }
  86. return (usbstate == MASTER);
  87. }
  88. // this code runs before the keyboard is fully initialized
  89. void split_pre_init(void) {
  90. isLeftHand = is_keyboard_left();
  91. #if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
  92. uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
  93. if (isLeftHand) {
  94. rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
  95. } else {
  96. rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
  97. }
  98. #endif
  99. if (is_keyboard_master()) {
  100. #if defined(USE_I2C) && defined(SSD1306OLED)
  101. matrix_master_OLED_init();
  102. #endif
  103. transport_master_init();
  104. }
  105. }
  106. // this code runs after the keyboard is fully initialized
  107. // - avoids race condition during matrix_init_quantum where slave can start
  108. // receiving before the init process has completed
  109. void split_post_init(void) {
  110. if (!is_keyboard_master()) {
  111. transport_slave_init();
  112. }
  113. }