]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - quantum/split_common/split_util.c
Small fix to allow board to override split keyboard master check
[qmk_firmware.git] / quantum / split_common / split_util.c
index 13b09d5b815a774d936e1cf4d82d650507969b8b..d7ed6989f63f6c356e5b7cebd2748064d6293d5f 100644 (file)
-#include <avr/io.h>
-#include <avr/wdt.h>
-#include <avr/power.h>
-#include <avr/interrupt.h>
-#include <util/delay.h>
-#include <avr/eeprom.h>
 #include "split_util.h"
 #include "matrix.h"
 #include "keyboard.h"
 #include "config.h"
 #include "timer.h"
-#include "split_flags.h"
+#include "transport.h"
+#include "quantum.h"
 
-#ifdef RGBLIGHT_ENABLE
-#   include "rgblight.h"
-#endif
-#ifdef BACKLIGHT_ENABLE
-#   include "backlight.h"
+#ifdef EE_HANDS
+#   include "tmk_core/common/eeprom.h"
+#   include "eeconfig.h"
 #endif
 
-#ifdef SPLIT_HAND_PIN
-#   include "pincontrol.h"
-#endif
-
-#if defined(USE_I2C) || defined(EH)
-#  include "i2c.h"
-#else
-#  include "serial.h"
+#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
+#include "rgblight.h"
 #endif
 
 volatile bool isLeftHand = true;
 
-volatile uint8_t setTries = 0;
-
-static void setup_handedness(void) {
-  #ifdef SPLIT_HAND_PIN
+__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
-    pinMode(SPLIT_HAND_PIN, PinDirectionInput);
-    isLeftHand = digitalRead(SPLIT_HAND_PIN);
-  #else
-    #ifdef EE_HANDS
-      isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
-    #else
-      // I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
-      #if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
-        isLeftHand = !has_usb();
-      #else
-        isLeftHand = has_usb();
-      #endif
-    #endif
+    setPinInput(SPLIT_HAND_PIN);
+    return readPin(SPLIT_HAND_PIN);
+  #elif defined(EE_HANDS)
+    return eeprom_read_byte(EECONFIG_HANDEDNESS);
+  #elif defined(MASTER_RIGHT)
+    return !is_keyboard_master();
   #endif
+
+  return is_keyboard_master();
 }
 
-static void keyboard_master_setup(void) {
-#if defined(USE_I2C) || defined(EH)
-  i2c_master_init();
-  #ifdef SSD1306OLED
-    matrix_master_OLED_init ();
-  #endif
-#else
-  serial_master_init();
-#endif
+__attribute__((weak))
+bool is_keyboard_master(void)
+{
+#ifdef __AVR__
+  static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
 
-    // For master the Backlight info needs to be sent on startup
-    // Otherwise the salve won't start with the proper info until an update
-    BACKLIT_DIRTY = true;
-}
+  // only check once, as this is called often
+  if (usbstate == UNKNOWN)
+  {
+    USBCON |= (1 << OTGPADE);  // enables VBUS pad
+    wait_us(5);
 
-static void keyboard_slave_setup(void) {
-  timer_init();
-#if defined(USE_I2C) || defined(EH)
-    i2c_slave_init(SLAVE_I2C_ADDRESS);
+    usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE;  // checks state of VBUS
+  }
+
+  return (usbstate == MASTER);
 #else
-    serial_slave_init();
+  return true;
 #endif
 }
 
-bool has_usb(void) {
-   USBCON |= (1 << OTGPADE); //enables VBUS pad
-   _delay_us(5);
-   return (USBSTA & (1<<VBUS));  //checks state of VBUS
-}
-
-void split_keyboard_setup(void) {
-   setup_handedness();
-
-   if (has_usb()) {
-      keyboard_master_setup();
-   } else {
-      keyboard_slave_setup();
-   }
-   sei();
+static void keyboard_master_setup(void) {
+#if defined(USE_I2C) || defined(EH)
+  #ifdef SSD1306OLED
+    matrix_master_OLED_init ();
+  #endif
+#endif
+  transport_master_init();
 }
 
-void keyboard_slave_loop(void) {
-   matrix_init();
-   
-   //Init RGB
-   #ifdef RGBLIGHT_ENABLE
-      rgblight_init();
-   #endif
-
-   while (1) {
-    // Matrix Slave Scan
-    matrix_slave_scan();
-    
-    // Read Backlight Info
-    #ifdef BACKLIGHT_ENABLE
-        if (BACKLIT_DIRTY) {
-            #ifdef USE_I2C
-                backlight_set(i2c_slave_buffer[I2C_BACKLIT_START]);
-            #else // USE_SERIAL
-                backlight_set(serial_master_buffer[SERIAL_BACKLIT_START]);
-            #endif
-            BACKLIT_DIRTY = false;
-        }
-    #endif
-    // Read RGB Info
-    #ifdef RGBLIGHT_ENABLE
-        #ifdef USE_I2C
-            if (RGB_DIRTY) {
-                // Disable interupts (RGB data is big)
-                cli();
-                // Create new DWORD for RGB data
-                uint32_t dword; 
-                
-                // Fill the new DWORD with the data that was sent over
-                uint8_t *dword_dat = (uint8_t *)(&dword);
-                for (int i = 0; i < 4; i++) {
-                    dword_dat[i] = i2c_slave_buffer[I2C_RGB_START+i];
-                }
-                
-                // Update the RGB now with the new data and set RGB_DIRTY to false
-                rgblight_update_dword(dword);
-                RGB_DIRTY = false;
-                // Re-enable interupts now that RGB is set
-                sei();
-            }
-        #else // USE_SERIAL
-            // Add serial implementation for RGB here
-        #endif
-    #endif
-   }
+static void keyboard_slave_setup(void)
+{
+  transport_slave_init();
 }
 
 // this code runs before the usb and keyboard is initialized
-void matrix_setup(void) {
-    split_keyboard_setup();
+void matrix_setup(void)
+{
+  isLeftHand = is_keyboard_left();
+
+#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT)
+  uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT;
+  if (isLeftHand) {
+    rgblight_set_clipping_range(0, num_rgb_leds_split[0]);
+  }
+  else {
+    rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]);
+  }
+#endif
 
-    if (!has_usb()) {
-        //rgblight_init();
-        keyboard_slave_loop();
-    }
+  if (is_keyboard_master())
+  {
+    keyboard_master_setup();
+  }
+  else
+  {
+    keyboard_slave_setup();
+  }
 }