aboutsummaryrefslogtreecommitdiff
path: root/keyboards/crkbd/rev1/legacy/split_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/crkbd/rev1/legacy/split_util.c')
-rw-r--r--keyboards/crkbd/rev1/legacy/split_util.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/keyboards/crkbd/rev1/legacy/split_util.c b/keyboards/crkbd/rev1/legacy/split_util.c
new file mode 100644
index 000000000..d0fee04ad
--- /dev/null
+++ b/keyboards/crkbd/rev1/legacy/split_util.c
@@ -0,0 +1,127 @@
1/*
2Copyright 2019 @foostan
3Copyright 2020 Drashna Jaelre <@drashna>
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include <avr/io.h>
20#include <avr/wdt.h>
21#include <avr/power.h>
22#include <avr/interrupt.h>
23#include <util/delay.h>
24#include <avr/eeprom.h>
25#include "split_util.h"
26#include "matrix.h"
27#include "keyboard.h"
28#include "wait.h"
29
30#ifdef EE_HANDS
31# include "eeconfig.h"
32#endif
33
34#ifdef USE_MATRIX_I2C
35# include "i2c_master.h"
36#else
37# include "split_scomm.h"
38#endif
39
40#ifndef SPLIT_USB_TIMEOUT
41# define SPLIT_USB_TIMEOUT 2000
42#endif
43
44#ifndef SPLIT_USB_TIMEOUT_POLL
45# define SPLIT_USB_TIMEOUT_POLL 10
46#endif
47
48volatile bool isLeftHand = true;
49
50bool waitForUsb(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 (UDADDR & _BV(ADDEN)) {
54 return true;
55 }
56 wait_ms(SPLIT_USB_TIMEOUT_POLL);
57 }
58
59 // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow
60 (USBCON &= ~(_BV(USBE) | _BV(OTGPADE)));
61
62 return false;
63}
64
65__attribute__((weak)) bool is_keyboard_left(void) {
66#if defined(SPLIT_HAND_PIN)
67 // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand
68 setPinInput(SPLIT_HAND_PIN);
69 return readPin(SPLIT_HAND_PIN);
70#elif defined(EE_HANDS)
71 return eeconfig_read_handedness();
72#elif defined(MASTER_RIGHT)
73 return !has_usb();
74#endif
75
76 return has_usb();
77}
78
79__attribute__((weak)) bool has_usb(void) {
80 static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN;
81
82 // only check once, as this is called often
83 if (usbstate == UNKNOWN) {
84#if defined(SPLIT_USB_DETECT)
85 usbstate = waitForUsb() ? MASTER : SLAVE;
86#elif defined(__AVR__)
87 USBCON |= (1 << OTGPADE); // enables VBUS pad
88 wait_us(5);
89
90 usbstate = (USBSTA & (1 << VBUS)) ? MASTER : SLAVE; // checks state of VBUS
91#else
92 usbstate = MASTER;
93#endif
94 }
95
96 return (usbstate == MASTER);
97}
98
99static void keyboard_master_setup(void) {
100
101#ifdef USE_MATRIX_I2C
102 i2c_init();
103#else
104 serial_master_init();
105#endif
106}
107
108static void keyboard_slave_setup(void) {
109
110#ifdef USE_MATRIX_I2C
111 i2c_slave_init(SLAVE_I2C_ADDRESS);
112#else
113 serial_slave_init();
114#endif
115}
116
117// this code runs before the usb and keyboard is initialized
118void split_keyboard_setup(void) {
119 isLeftHand = is_keyboard_left();
120
121 if (has_usb()) {
122 keyboard_master_setup();
123 } else {
124 keyboard_slave_setup();
125 }
126 sei();
127}