* 4: about 26kbps
* 5: about 20kbps
+* `#define SPLIT_USB_DETECT`
+ * Detect (with timeout) USB connection when delegating master/slave
+ * Default behavior for ARM
+ * Required for AVR Teensy
+
+* `#define SPLIT_USB_TIMEOUT 2500`
+ * Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`
+
# The `rules.mk` File
This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features.
?> This setting implies that `RGBLIGHT_SPLIT` is enabled, and will forcibly enable it, if it's not.
+```c
+#define SPLIT_USB_DETECT
+```
+This option changes the startup behavior to detect an active USB connection when delegating master/slave. If this operation times out, then the half is assume to be a slave. This is the default behavior for ARM, and required for AVR Teensy boards (due to hardware limitations).
+
+?> This setting will stop the ability to demo using battery packs.
+
+```c
+#define SPLIT_USB_TIMEOUT 2500
+```
+This sets the maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`.
+
## Additional Resources
Nicinabox has a [very nice and detailed guide](https://github.com/nicinabox/lets-split-guide) for the Let's Split keyboard, that covers most everything you need to know, including troubleshooting information.
# include "rgblight.h"
#endif
+#ifndef SPLIT_USB_TIMEOUT
+# define SPLIT_USB_TIMEOUT 2500
+#endif
+
volatile bool isLeftHand = true;
+bool waitForUsb(void) {
+ for (uint8_t i = 0; i < (SPLIT_USB_TIMEOUT / 100); i++) {
+ // This will return true of a USB connection has been established
+#if defined(__AVR__)
+ if (UDADDR & _BV(ADDEN)) {
+#else
+ if (usbGetDriverStateI(&USBD1) == USB_ACTIVE) {
+#endif
+ return true;
+ }
+ wait_ms(100);
+ }
+ return false;
+}
+
__attribute__((weak)) bool is_keyboard_left(void) {
#if defined(SPLIT_HAND_PIN)
// Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
}
__attribute__((weak)) bool is_keyboard_master(void) {
-#ifdef __AVR__
static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
// only check once, as this is called often
if (usbstate == UNKNOWN) {
+#if defined(SPLIT_USB_DETECT) || defined(PROTOCOL_CHIBIOS)
+ usbstate = waitForUsb() ? MASTER : SLAVE;
+#elif defined(__AVR__)
USBCON |= (1 << OTGPADE); // enables VBUS pad
wait_us(5);
usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS
+#else
+ usbstate = MASTER;
+#endif
}
return (usbstate == MASTER);
-#else
- return true;
-#endif
}
static void keyboard_master_setup(void) {
static void keyboard_slave_setup(void) { transport_slave_init(); }
-// this code runs before the usb and keyboard is initialized
-void matrix_setup(void) {
+// this code runs before the keyboard is fully initialized
+void keyboard_split_setup(void) {
isLeftHand = is_keyboard_left();
#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)