split_util.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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) {
  34. USB_Disable();
  35. USB_DeviceState = DEVICE_STATE_Unattached;
  36. }
  37. # elif defined(PROTOCOL_CHIBIOS)
  38. static inline bool usbHasActiveConnection(void) { return usbGetDriverStateI(&USBD1) == USB_ACTIVE; }
  39. static inline void usbDisable(void) { usbStop(&USBD1); }
  40. # elif defined(PROTOCOL_VUSB)
  41. static inline bool usbHasActiveConnection(void) {
  42. usbPoll();
  43. return usbConfiguration;
  44. }
  45. static inline void usbDisable(void) { usbDeviceDisconnect(); }
  46. # else
  47. static inline bool usbHasActiveConnection(void) { return true; }
  48. static inline void usbDisable(void) {}
  49. # endif
  50. bool usbIsActive(void) {
  51. for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) {
  52. // This will return true if a USB connection has been established
  53. if (usbHasActiveConnection()) {
  54. return true;
  55. }
  56. wait_ms(SPLIT_USB_TIMEOUT_POLL);
  57. }
  58. // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
  59. usbDisable();
  60. return false;
  61. }
  62. #elif defined(PROTOCOL_LUFA)
  63. static inline bool usbIsActive(void) {
  64. USB_OTGPAD_On(); // enables VBUS pad
  65. wait_us(5);
  66. return USB_VBUS_GetStatus(); // checks state of VBUS
  67. }
  68. #else
  69. static inline bool usbIsActive(void) { return true; }
  70. #endif
  71. __attribute__((weak)) bool is_keyboard_left(void) {
  72. #if defined(SPLIT_HAND_PIN)
  73. // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
  74. setPinInput(SPLIT_HAND_PIN);
  75. return readPin(SPLIT_HAND_PIN);
  76. #elif defined(EE_HANDS)
  77. return eeconfig_read_handedness();
  78. #elif defined(MASTER_RIGHT)
  79. return !is_keyboard_master();
  80. #endif
  81. return is_keyboard_master();
  82. }
  83. __attribute__((weak)) bool is_keyboard_master(void) {
  84. static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
  85. // only check once, as this is called often
  86. if (usbstate == UNKNOWN) {
  87. usbstate = usbIsActive() ? MASTER : SLAVE;
  88. }
  89. return (usbstate == MASTER);
  90. }
  91. // this code runs before the keyboard is fully initialized
  92. void split_pre_init(void) {
  93. isLeftHand = is_keyboard_left();
  94. #if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
  95. uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
  96. if (isLeftHand) {
  97. rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
  98. } else {
  99. rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
  100. }
  101. #endif
  102. if (is_keyboard_master()) {
  103. #if defined(USE_I2C) && defined(SSD1306OLED)
  104. matrix_master_OLED_init();
  105. #endif
  106. transport_master_init();
  107. }
  108. }
  109. // this code runs after the keyboard is fully initialized
  110. // - avoids race condition during matrix_init_quantum where slave can start
  111. // receiving before the init process has completed
  112. void split_post_init(void) {
  113. if (!is_keyboard_master()) {
  114. transport_slave_init();
  115. }
  116. }