summary refs log tree commit diff
path: root/keyboards/nullbitsco/common
diff options
context:
space:
mode:
authorJay Greco <jayv.greco@gmail.com>2021-10-10 18:37:33 -0700
committerGitHub <noreply@github.com>2021-10-10 18:37:33 -0700
commitc75bf9daf46897209338f7dc4b68f2efec074a65 (patch)
tree17c16997d48b1727a7eb6e67992b88efb1f4bd32 /keyboards/nullbitsco/common
parent5c034c43ab547b95847e7419b9a07e76f560dc16 (diff)
[Keyboard] nullbitsco keyboards: common file cleanup (#14358)
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