diff options
Diffstat (limited to 'keyboards/nullbitsco/common')
-rw-r--r-- | keyboards/nullbitsco/common/bitc_led.c | 37 | ||||
-rw-r--r-- | keyboards/nullbitsco/common/bitc_led.h | 29 | ||||
-rw-r--r-- | keyboards/nullbitsco/common/remote_kb.c | 178 | ||||
-rw-r--r-- | keyboards/nullbitsco/common/remote_kb.h | 52 |
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 |