summaryrefslogtreecommitdiff
path: root/keyboards/nullbitsco/common
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/nullbitsco/common')
-rw-r--r--keyboards/nullbitsco/common/bitc_led.c37
-rw-r--r--keyboards/nullbitsco/common/bitc_led.h29
-rw-r--r--keyboards/nullbitsco/common/remote_kb.c178
-rw-r--r--keyboards/nullbitsco/common/remote_kb.h52
4 files changed, 296 insertions, 0 deletions
diff --git a/keyboards/nullbitsco/common/bitc_led.c b/keyboards/nullbitsco/common/bitc_led.c
new file mode 100644
index 0000000000..64d7c7160a
--- /dev/null
+++ b/keyboards/nullbitsco/common/bitc_led.c
@@ -0,0 +1,37 @@
+/* Copyright 2021 Jay Greco
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "bitc_led.h"
+
+void set_bitc_LED(uint8_t mode) {
+ switch(mode) {
+ case LED_ON:
+ setPinOutput(PIN_LED);
+ writePin(PIN_LED, GPIO_STATE_HIGH);
+ break;
+
+ case LED_DIM:
+ setPinInput(PIN_LED);
+ break;
+
+ case LED_OFF:
+ setPinOutput(PIN_LED);
+ writePin(PIN_LED, GPIO_STATE_LOW);
+ break;
+
+ default:
+ break;
+ }
+} \ No newline at end of file
diff --git a/keyboards/nullbitsco/common/bitc_led.h b/keyboards/nullbitsco/common/bitc_led.h
new file mode 100644
index 0000000000..14cd4f15b7
--- /dev/null
+++ b/keyboards/nullbitsco/common/bitc_led.h
@@ -0,0 +1,29 @@
+/* Copyright 2021 Jay Greco
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "quantum.h"
+
+#define LED_ON 2
+#define LED_DIM 1
+#define LED_OFF 0
+
+#define GPIO_STATE_LOW 0
+#define GPIO_STATE_HIGH 1
+
+#define PIN_LED F0
+
+void set_bitc_LED(uint8_t mode); \ No newline at end of file
diff --git a/keyboards/nullbitsco/common/remote_kb.c b/keyboards/nullbitsco/common/remote_kb.c
new file mode 100644
index 0000000000..89cbf9a92a
--- /dev/null
+++ b/keyboards/nullbitsco/common/remote_kb.c
@@ -0,0 +1,178 @@
+/* Copyright 2021 Jay Greco
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+Remote keyboard is an experimental feature that allows for connecting another
+keyboard, macropad, numpad, or accessory without requiring an additional USB connection.
+The "remote keyboard" forwards its keystrokes using UART serial over TRRS. Dynamic VUSB
+detect allows the keyboard automatically switch to host or remote mode depending on
+which is connected to the USB port.
+
+Possible functionality includes the ability to send data from the host to the remote using
+a reverse link, allowing for LED sync, configuration, and more data sharing between devices.
+This will require a new communication protocol, as the current one is limited.
+*/
+
+#include "remote_kb.h"
+#include "uart.h"
+
+uint8_t
+ msg[UART_MSG_LEN],
+ msg_idx = 0;
+
+bool
+ is_host = true;
+
+// Private functions
+
+static bool vbus_detect(void) {
+ #if defined(__AVR_ATmega32U4__)
+ //returns true if VBUS is present, false otherwise.
+ USBCON |= (1 << OTGPADE); //enables VBUS pad
+ _delay_us(10);
+ return (USBSTA & (1<<VBUS)); //checks state of VBUS
+ #else
+ #error vbus_detect is not implemented for this architecure!
+ #endif
+}
+
+static uint8_t chksum8(const unsigned char *buf, size_t len) {
+ unsigned int sum;
+ for (sum = 0 ; len != 0 ; len--)
+ sum += *(buf++);
+ return (uint8_t)sum;
+}
+
+static void send_msg(uint16_t keycode, bool pressed) {
+ msg[IDX_PREAMBLE] = UART_PREAMBLE;
+ msg[IDX_KCLSB] = (keycode & 0xFF);
+ msg[IDX_KCMSB] = (keycode >> 8) & 0xFF;
+ msg[IDX_PRESSED] = pressed;
+ msg[IDX_CHECKSUM] = chksum8(msg, UART_MSG_LEN-1);
+
+ for (int i=0; i<UART_MSG_LEN; i++) {
+ uart_putchar(msg[i]);
+ }
+}
+
+static void print_message_buffer(void) {
+ for (int i=0; i<UART_MSG_LEN; i++) {
+ dprintf("msg[%u]: %u\n", i, msg[i]);
+ }
+}
+
+static void process_uart(void) {
+ uint8_t chksum = chksum8(msg, UART_MSG_LEN-1);
+ if (msg[IDX_PREAMBLE] != UART_PREAMBLE || msg[IDX_CHECKSUM] != chksum) {
+ dprintf("UART checksum mismatch!\n");
+ print_message_buffer();
+ dprintf("calc checksum: %u\n", chksum);
+ } else {
+ uint16_t keycode = (uint16_t)msg[IDX_KCLSB] | ((uint16_t)msg[IDX_KCMSB] << 8);
+ bool pressed = (bool)msg[IDX_PRESSED];
+ if (IS_RM_KC(keycode)) {
+ keyrecord_t record;
+ record.event.pressed = pressed;
+ if (pressed) dprintf("Remote macro: press [%u]\n", keycode);
+ else dprintf("Remote macro: release [%u]\n", keycode);
+ process_record_user(keycode, &record);
+ } else {
+ if (pressed) {
+ dprintf("Remote: press [%u]\n", keycode);
+ register_code(keycode);
+ } else {
+ dprintf("Remote: release [%u]\n", keycode);
+ unregister_code(keycode);
+ }
+ }
+ }
+}
+
+static void get_msg(void) {
+ while (uart_available()) {
+ msg[msg_idx] = uart_getchar();
+ dprintf("idx: %u, recv: %u\n", msg_idx, msg[msg_idx]);
+ if (msg_idx == 0 && (msg[msg_idx] != UART_PREAMBLE)) {
+ dprintf("Byte sync error!\n");
+ msg_idx = 0;
+ } else if (msg_idx == (UART_MSG_LEN-1)) {
+ process_uart();
+ msg_idx = 0;
+ } else {
+ msg_idx++;
+ }
+ }
+}
+
+static void handle_host_incoming(void) {
+ get_msg();
+}
+
+static void handle_host_outgoing(void) {
+ // for future reverse link use
+}
+
+static void handle_remote_incoming(void) {
+ // for future reverse link use
+}
+
+static void handle_remote_outgoing(uint16_t keycode, keyrecord_t *record) {
+ if (IS_HID_KC(keycode) || IS_RM_KC(keycode)) {
+ dprintf("Remote: send [%u]\n", keycode);
+ send_msg(keycode, record->event.pressed);
+ }
+}
+
+// Public functions
+
+void matrix_init_remote_kb(void) {
+ uart_init(SERIAL_UART_BAUD);
+ is_host = vbus_detect();
+}
+
+void process_record_remote_kb(uint16_t keycode, keyrecord_t *record) {
+ #if defined (KEYBOARD_HOST)
+ handle_host_outgoing();
+
+ #elif defined(KEYBOARD_REMOTE)
+ handle_remote_outgoing(keycode, record);
+
+ #else //auto check with VBUS
+ if (is_host) {
+ handle_host_outgoing();
+ }
+ else {
+ handle_remote_outgoing(keycode, record);
+ }
+ #endif
+}
+
+void matrix_scan_remote_kb(void) {
+ #if defined(KEYBOARD_HOST)
+ handle_host_incoming();
+
+ #elif defined (KEYBOARD_REMOTE)
+ handle_remote_incoming();
+
+ #else //auto check with VBUS
+ if (is_host) {
+ handle_host_incoming();
+ }
+ else {
+ handle_remote_incoming();
+ }
+ #endif
+}
diff --git a/keyboards/nullbitsco/common/remote_kb.h b/keyboards/nullbitsco/common/remote_kb.h
new file mode 100644
index 0000000000..6270e8f9f1
--- /dev/null
+++ b/keyboards/nullbitsco/common/remote_kb.h
@@ -0,0 +1,52 @@
+/* Copyright 2021 Jay Greco
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "quantum.h"
+
+#define SERIAL_UART_BAUD 153600 //low error rate for 32u4 @ 16MHz
+
+#define UART_PREAMBLE 0x69
+#define UART_MSG_LEN 5
+#define UART_NULL 0
+
+#define IDX_PREAMBLE 0
+#define IDX_KCLSB 1
+#define IDX_KCMSB 2
+#define IDX_PRESSED 3
+#define IDX_CHECKSUM 4
+
+#define IS_HID_KC(x) ((x > 0) && (x < 0xFF))
+#define IS_RM_KC(x) ((x >= RM_BASE) && (x <= 0xFFFF))
+
+#define RM_BASE 0xFFFF-16
+enum remote_macros {
+ RM_1 = RM_BASE,
+ RM_2, RM_3,
+ RM_4, RM_5,
+ RM_6, RM_7,
+ RM_8, RM_9,
+ RM_10, RM_11,
+ RM_12, RM_13,
+ RM_14, RM_15,
+};
+
+
+// Public functions
+void
+ matrix_init_remote_kb(void),
+ process_record_remote_kb(uint16_t keycode, keyrecord_t *record),
+ matrix_scan_remote_kb(void); \ No newline at end of file