From dcfffa7b67a072f7d9e37bd8c0029c53b61aeb0f Mon Sep 17 00:00:00 2001
From: Joel Challis
Date: Thu, 28 Oct 2021 22:31:59 +0100
Subject: Relocate protocol files within tmk_core/common/ (#14972)
* Relocate non platform files within tmk_core/common/
* clang---
common_features.mk | 2 +-
quantum/keyboard.c | 3 +
quantum/raw_hid.h | 5 +
quantum/sync_timer.c | 58 +++++++
quantum/sync_timer.h | 54 ++++++
quantum/usb_device_state.c | 51 ------
quantum/usb_device_state.h | 39 -----
quantum/virtser.h | 9 +
tmk_core/common.mk | 4 -
tmk_core/common/host.c | 138 ---------------
tmk_core/common/host.h | 58 -------
tmk_core/common/host_driver.h | 35 ----
tmk_core/common/raw_hid.h | 5 -
tmk_core/common/report.c | 280 ------------------------------
tmk_core/common/report.h | 325 -----------------------------------
tmk_core/common/sync_timer.c | 58 -------
tmk_core/common/sync_timer.h | 54 ------
tmk_core/common/usb_util.c | 29 ----
tmk_core/common/usb_util.h | 22 ---
tmk_core/common/virtser.h | 7 -
tmk_core/protocol.mk | 6 +
tmk_core/protocol/host.c | 138 +++++++++++++++
tmk_core/protocol/host.h | 58 +++++++
tmk_core/protocol/host_driver.h | 35 ++++
tmk_core/protocol/report.c | 280 ++++++++++++++++++++++++++++++
tmk_core/protocol/report.h | 325 +++++++++++++++++++++++++++++++++++
tmk_core/protocol/usb_device_state.c | 51 ++++++
tmk_core/protocol/usb_device_state.h | 39 +++++
tmk_core/protocol/usb_util.c | 29 ++++
tmk_core/protocol/usb_util.h | 22 +++
30 files changed, 1113 insertions(+), 1106 deletions(-)
create mode 100644 quantum/raw_hid.h
create mode 100644 quantum/sync_timer.c
create mode 100644 quantum/sync_timer.h
delete mode 100644 quantum/usb_device_state.c
delete mode 100644 quantum/usb_device_state.h
create mode 100644 quantum/virtser.h
delete mode 100644 tmk_core/common/host.c
delete mode 100644 tmk_core/common/host.h
delete mode 100644 tmk_core/common/host_driver.h
delete mode 100644 tmk_core/common/raw_hid.h
delete mode 100644 tmk_core/common/report.c
delete mode 100644 tmk_core/common/report.h
delete mode 100644 tmk_core/common/sync_timer.c
delete mode 100644 tmk_core/common/sync_timer.h
delete mode 100644 tmk_core/common/usb_util.c
delete mode 100644 tmk_core/common/usb_util.h
delete mode 100644 tmk_core/common/virtser.h
create mode 100644 tmk_core/protocol/host.c
create mode 100644 tmk_core/protocol/host.h
create mode 100644 tmk_core/protocol/host_driver.h
create mode 100644 tmk_core/protocol/report.c
create mode 100644 tmk_core/protocol/report.h
create mode 100644 tmk_core/protocol/usb_device_state.c
create mode 100644 tmk_core/protocol/usb_device_state.h
create mode 100644 tmk_core/protocol/usb_util.c
create mode 100644 tmk_core/protocol/usb_util.h
diff --git a/common_features.mk b/common_features.mk
index af538b696f..1d7e955cdf 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -27,7 +27,7 @@ QUANTUM_SRC += \
$(QUANTUM_DIR)/keyboard.c \
$(QUANTUM_DIR)/keymap_common.c \
$(QUANTUM_DIR)/keycode_config.c \
- $(QUANTUM_DIR)/usb_device_state.c \
+ $(QUANTUM_DIR)/sync_timer.c \
$(QUANTUM_DIR)/logging/debug.c \
$(QUANTUM_DIR)/logging/sendchar.c \
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index 030fec2d3e..806e4ef7e8 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -94,6 +94,9 @@ along with this program. If not, see .
#ifdef DIGITIZER_ENABLE
# include "digitizer.h"
#endif
+#ifdef VIRTSER_ENABLE
+# include "virtser.h"
+#endif
static uint32_t last_input_modification_time = 0;
uint32_t last_input_activity_time(void) { return last_input_modification_time; }
diff --git a/quantum/raw_hid.h b/quantum/raw_hid.h
new file mode 100644
index 0000000000..6d60ab2bff
--- /dev/null
+++ b/quantum/raw_hid.h
@@ -0,0 +1,5 @@
+#pragma once
+
+void raw_hid_receive(uint8_t *data, uint8_t length);
+
+void raw_hid_send(uint8_t *data, uint8_t length);
diff --git a/quantum/sync_timer.c b/quantum/sync_timer.c
new file mode 100644
index 0000000000..de24b463b6
--- /dev/null
+++ b/quantum/sync_timer.c
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 2020 Ryan Caltabiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+If you happen to meet one of the copyright holders in a bar you are obligated
+to buy them one pint of beer.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "sync_timer.h"
+#include "keyboard.h"
+
+#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
+volatile int32_t sync_timer_ms;
+
+void sync_timer_init(void) { sync_timer_ms = 0; }
+
+void sync_timer_update(uint32_t time) {
+ if (is_keyboard_master()) return;
+ sync_timer_ms = time - timer_read32();
+}
+
+uint16_t sync_timer_read(void) {
+ if (is_keyboard_master()) return timer_read();
+ return sync_timer_read32();
+}
+
+uint32_t sync_timer_read32(void) {
+ if (is_keyboard_master()) return timer_read32();
+ return sync_timer_ms + timer_read32();
+}
+
+uint16_t sync_timer_elapsed(uint16_t last) {
+ if (is_keyboard_master()) return timer_elapsed(last);
+ return TIMER_DIFF_16(sync_timer_read(), last);
+}
+
+uint32_t sync_timer_elapsed32(uint32_t last) {
+ if (is_keyboard_master()) return timer_elapsed32(last);
+ return TIMER_DIFF_32(sync_timer_read32(), last);
+}
+#endif
diff --git a/quantum/sync_timer.h b/quantum/sync_timer.h
new file mode 100644
index 0000000000..9ddef45bb2
--- /dev/null
+++ b/quantum/sync_timer.h
@@ -0,0 +1,54 @@
+/*
+Copyright (C) 2020 Ryan Caltabiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+If you happen to meet one of the copyright holders in a bar you are obligated
+to buy them one pint of beer.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#pragma once
+
+#include
+#include "timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
+void sync_timer_init(void);
+void sync_timer_update(uint32_t time);
+uint16_t sync_timer_read(void);
+uint32_t sync_timer_read32(void);
+uint16_t sync_timer_elapsed(uint16_t last);
+uint32_t sync_timer_elapsed32(uint32_t last);
+#else
+# define sync_timer_init()
+# define sync_timer_clear()
+# define sync_timer_update(t)
+# define sync_timer_read() timer_read()
+# define sync_timer_read32() timer_read32()
+# define sync_timer_elapsed(t) timer_elapsed(t)
+# define sync_timer_elapsed32(t) timer_elapsed32(t)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/quantum/usb_device_state.c b/quantum/usb_device_state.c
deleted file mode 100644
index 5ccd309ec2..0000000000
--- a/quantum/usb_device_state.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2021 Andrei Purdea
- *
- * 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 .
- */
-
-#include "usb_device_state.h"
-
-enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT;
-
-__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { notify_usb_device_state_change_user(usb_device_state); }
-
-__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {}
-
-static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { notify_usb_device_state_change_kb(usb_device_state); }
-
-void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) {
- usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
- notify_usb_device_state_change(usb_device_state);
-}
-
-void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) {
- usb_device_state = USB_DEVICE_STATE_SUSPEND;
- notify_usb_device_state_change(usb_device_state);
-}
-
-void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) {
- usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
- notify_usb_device_state_change(usb_device_state);
-}
-
-void usb_device_state_set_reset(void) {
- usb_device_state = USB_DEVICE_STATE_INIT;
- notify_usb_device_state_change(usb_device_state);
-}
-
-void usb_device_state_init(void) {
- usb_device_state = USB_DEVICE_STATE_INIT;
- notify_usb_device_state_change(usb_device_state);
-}
diff --git a/quantum/usb_device_state.h b/quantum/usb_device_state.h
deleted file mode 100644
index c229311d46..0000000000
--- a/quantum/usb_device_state.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2021 Andrei Purdea
- *
- * 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 .
- */
-
-#pragma once
-
-#include
-#include
-
-void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber);
-void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber);
-void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber);
-void usb_device_state_set_reset(void);
-void usb_device_state_init(void);
-
-enum usb_device_state {
- USB_DEVICE_STATE_NO_INIT = 0, // We're in this state before calling usb_device_state_init()
- USB_DEVICE_STATE_INIT = 1, // Can consume up to 100mA
- USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
- USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current
-};
-
-extern enum usb_device_state usb_device_state;
-
-void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state);
-void notify_usb_device_state_change_user(enum usb_device_state usb_device_state);
diff --git a/quantum/virtser.h b/quantum/virtser.h
new file mode 100644
index 0000000000..df7e87984c
--- /dev/null
+++ b/quantum/virtser.h
@@ -0,0 +1,9 @@
+#pragma once
+
+void virtser_init(void);
+
+/* Define this function in your code to process incoming bytes */
+void virtser_recv(const uint8_t ch);
+
+/* Call this to send a character over the Virtual Serial Device */
+void virtser_send(const uint8_t byte);
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index ce335f0d3c..8fa1a31e80 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -2,10 +2,6 @@ COMMON_DIR = common
PLATFORM_COMMON_DIR = $(COMMON_DIR)/$(PLATFORM_KEY)
TMK_COMMON_SRC += \
- $(COMMON_DIR)/host.c \
- $(COMMON_DIR)/report.c \
- $(COMMON_DIR)/sync_timer.c \
- $(COMMON_DIR)/usb_util.c \
$(PLATFORM_COMMON_DIR)/platform.c \
$(PLATFORM_COMMON_DIR)/suspend.c \
$(PLATFORM_COMMON_DIR)/timer.c \
diff --git a/tmk_core/common/host.c b/tmk_core/common/host.c
deleted file mode 100644
index 56d4bb0847..0000000000
--- a/tmk_core/common/host.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
-Copyright 2011,2012 Jun Wako
-
-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 .
-*/
-
-#include
-//#include
-#include "keyboard.h"
-#include "keycode.h"
-#include "host.h"
-#include "util.h"
-#include "debug.h"
-#include "digitizer.h"
-
-#ifdef NKRO_ENABLE
-# include "keycode_config.h"
-extern keymap_config_t keymap_config;
-#endif
-
-static host_driver_t *driver;
-static uint16_t last_system_report = 0;
-static uint16_t last_consumer_report = 0;
-static uint32_t last_programmable_button_report = 0;
-
-void host_set_driver(host_driver_t *d) { driver = d; }
-
-host_driver_t *host_get_driver(void) { return driver; }
-
-#ifdef SPLIT_KEYBOARD
-uint8_t split_led_state = 0;
-void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; }
-#endif
-
-uint8_t host_keyboard_leds(void) {
-#ifdef SPLIT_KEYBOARD
- if (!is_keyboard_master()) return split_led_state;
-#endif
- if (!driver) return 0;
- return (*driver->keyboard_leds)();
-}
-
-led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); }
-
-/* send report */
-void host_keyboard_send(report_keyboard_t *report) {
- if (!driver) return;
-#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
- if (keyboard_protocol && keymap_config.nkro) {
- /* The callers of this function assume that report->mods is where mods go in.
- * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
- */
- report->nkro.mods = report->mods;
- report->nkro.report_id = REPORT_ID_NKRO;
- } else
-#endif
- {
-#ifdef KEYBOARD_SHARED_EP
- report->report_id = REPORT_ID_KEYBOARD;
-#endif
- }
- (*driver->send_keyboard)(report);
-
- if (debug_keyboard) {
- dprint("keyboard_report: ");
- for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
- dprintf("%02X ", report->raw[i]);
- }
- dprint("\n");
- }
-}
-
-void host_mouse_send(report_mouse_t *report) {
- if (!driver) return;
-#ifdef MOUSE_SHARED_EP
- report->report_id = REPORT_ID_MOUSE;
-#endif
- (*driver->send_mouse)(report);
-}
-
-void host_system_send(uint16_t report) {
- if (report == last_system_report) return;
- last_system_report = report;
-
- if (!driver) return;
- (*driver->send_system)(report);
-}
-
-void host_consumer_send(uint16_t report) {
- if (report == last_consumer_report) return;
- last_consumer_report = report;
-
- if (!driver) return;
- (*driver->send_consumer)(report);
-}
-
-void host_digitizer_send(digitizer_t *digitizer) {
- if (!driver) return;
-
- report_digitizer_t report = {
-#ifdef DIGITIZER_SHARED_EP
- .report_id = REPORT_ID_DIGITIZER,
-#endif
- .tip = digitizer->tipswitch & 0x1,
- .inrange = digitizer->inrange & 0x1,
- .x = (uint16_t)(digitizer->x * 0x7FFF),
- .y = (uint16_t)(digitizer->y * 0x7FFF),
- };
-
- send_digitizer(&report);
-}
-
-__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
-
-void host_programmable_button_send(uint32_t report) {
- if (report == last_programmable_button_report) return;
- last_programmable_button_report = report;
-
- if (!driver) return;
- (*driver->send_programmable_button)(report);
-}
-
-uint16_t host_last_system_report(void) { return last_system_report; }
-
-uint16_t host_last_consumer_report(void) { return last_consumer_report; }
-
-uint32_t host_last_programmable_button_report(void) { return last_programmable_button_report; }
diff --git a/tmk_core/common/host.h b/tmk_core/common/host.h
deleted file mode 100644
index 6b15f0d0c1..0000000000
--- a/tmk_core/common/host.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Copyright 2011 Jun Wako
-
-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 .
-*/
-
-#pragma once
-
-#include
-#include
-#include "report.h"
-#include "host_driver.h"
-#include "led.h"
-
-#define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name)))
-#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name)))
-
-#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name)
-#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern uint8_t keyboard_idle;
-extern uint8_t keyboard_protocol;
-
-/* host driver */
-void host_set_driver(host_driver_t *driver);
-host_driver_t *host_get_driver(void);
-
-/* host driver interface */
-uint8_t host_keyboard_leds(void);
-led_t host_keyboard_led_state(void);
-void host_keyboard_send(report_keyboard_t *report);
-void host_mouse_send(report_mouse_t *report);
-void host_system_send(uint16_t data);
-void host_consumer_send(uint16_t data);
-void host_programmable_button_send(uint32_t data);
-
-uint16_t host_last_system_report(void);
-uint16_t host_last_consumer_report(void);
-uint32_t host_last_programmable_button_report(void);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tmk_core/common/host_driver.h b/tmk_core/common/host_driver.h
deleted file mode 100644
index affd0dcb34..0000000000
--- a/tmk_core/common/host_driver.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-Copyright 2011 Jun Wako
-
-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 .
-*/
-
-#pragma once
-
-#include
-#include "report.h"
-#ifdef MIDI_ENABLE
-# include "midi.h"
-#endif
-
-typedef struct {
- uint8_t (*keyboard_leds)(void);
- void (*send_keyboard)(report_keyboard_t *);
- void (*send_mouse)(report_mouse_t *);
- void (*send_system)(uint16_t);
- void (*send_consumer)(uint16_t);
- void (*send_programmable_button)(uint32_t);
-} host_driver_t;
-
-void send_digitizer(report_digitizer_t *report);
\ No newline at end of file
diff --git a/tmk_core/common/raw_hid.h b/tmk_core/common/raw_hid.h
deleted file mode 100644
index 6d60ab2bff..0000000000
--- a/tmk_core/common/raw_hid.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#pragma once
-
-void raw_hid_receive(uint8_t *data, uint8_t length);
-
-void raw_hid_send(uint8_t *data, uint8_t length);
diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c
deleted file mode 100644
index 2a7fc006c4..0000000000
--- a/tmk_core/common/report.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* Copyright 2017 Fred Sundvik
- *
- * 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 .
- */
-
-#include "report.h"
-#include "host.h"
-#include "keycode_config.h"
-#include "debug.h"
-#include "util.h"
-#include
-
-#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
-# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
-# define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
-# define RO_INC(a) RO_ADD(a, 1)
-# define RO_DEC(a) RO_SUB(a, 1)
-static int8_t cb_head = 0;
-static int8_t cb_tail = 0;
-static int8_t cb_count = 0;
-#endif
-
-/** \brief has_anykey
- *
- * FIXME: Needs doc
- */
-uint8_t has_anykey(report_keyboard_t* keyboard_report) {
- uint8_t cnt = 0;
- uint8_t* p = keyboard_report->keys;
- uint8_t lp = sizeof(keyboard_report->keys);
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- p = keyboard_report->nkro.bits;
- lp = sizeof(keyboard_report->nkro.bits);
- }
-#endif
- while (lp--) {
- if (*p++) cnt++;
- }
- return cnt;
-}
-
-/** \brief get_first_key
- *
- * FIXME: Needs doc
- */
-uint8_t get_first_key(report_keyboard_t* keyboard_report) {
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- uint8_t i = 0;
- for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
- ;
- return i << 3 | biton(keyboard_report->nkro.bits[i]);
- }
-#endif
-#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
- uint8_t i = cb_head;
- do {
- if (keyboard_report->keys[i] != 0) {
- break;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- return keyboard_report->keys[i];
-#else
- return keyboard_report->keys[0];
-#endif
-}
-
-/** \brief Checks if a key is pressed in the report
- *
- * Returns true if the keyboard_report reports that the key is pressed, otherwise false
- * Note: The function doesn't support modifers currently, and it returns false for KC_NO
- */
-bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) {
- if (key == KC_NO) {
- return false;
- }
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- if ((key >> 3) < KEYBOARD_REPORT_BITS) {
- return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7);
- } else {
- return false;
- }
- }
-#endif
- for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == key) {
- return true;
- }
- }
- return false;
-}
-
-/** \brief add key byte
- *
- * FIXME: Needs doc
- */
-void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
-#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
- int8_t i = cb_head;
- int8_t empty = -1;
- if (cb_count) {
- do {
- if (keyboard_report->keys[i] == code) {
- return;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- if (i == cb_tail) {
- if (cb_tail == cb_head) {
- // buffer is full
- if (empty == -1) {
- // pop head when has no empty space
- cb_head = RO_INC(cb_head);
- cb_count--;
- } else {
- // left shift when has empty space
- uint8_t offset = 1;
- i = RO_INC(empty);
- do {
- if (keyboard_report->keys[i] != 0) {
- keyboard_report->keys[empty] = keyboard_report->keys[i];
- keyboard_report->keys[i] = 0;
- empty = RO_INC(empty);
- } else {
- offset++;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- cb_tail = RO_SUB(cb_tail, offset);
- }
- }
- }
- }
- // add to tail
- keyboard_report->keys[cb_tail] = code;
- cb_tail = RO_INC(cb_tail);
- cb_count++;
-#else
- int8_t i = 0;
- int8_t empty = -1;
- for (; i < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- break;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- }
- if (i == KEYBOARD_REPORT_KEYS) {
- if (empty != -1) {
- keyboard_report->keys[empty] = code;
- }
- }
-#endif
-}
-
-/** \brief del key byte
- *
- * FIXME: Needs doc
- */
-void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
-#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
- uint8_t i = cb_head;
- if (cb_count) {
- do {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- cb_count--;
- if (cb_count == 0) {
- // reset head and tail
- cb_tail = cb_head = 0;
- }
- if (i == RO_DEC(cb_tail)) {
- // left shift when next to tail
- do {
- cb_tail = RO_DEC(cb_tail);
- if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
- break;
- }
- } while (cb_tail != cb_head);
- }
- break;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- }
-#else
- for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- }
- }
-#endif
-}
-
-#ifdef NKRO_ENABLE
-/** \brief add key bit
- *
- * FIXME: Needs doc
- */
-void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
- if ((code >> 3) < KEYBOARD_REPORT_BITS) {
- keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7);
- } else {
- dprintf("add_key_bit: can't add: %02X\n", code);
- }
-}
-
-/** \brief del key bit
- *
- * FIXME: Needs doc
- */
-void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
- if ((code >> 3) < KEYBOARD_REPORT_BITS) {
- keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7));
- } else {
- dprintf("del_key_bit: can't del: %02X\n", code);
- }
-}
-#endif
-
-/** \brief add key to report
- *
- * FIXME: Needs doc
- */
-void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- add_key_bit(keyboard_report, key);
- return;
- }
-#endif
- add_key_byte(keyboard_report, key);
-}
-
-/** \brief del key from report
- *
- * FIXME: Needs doc
- */
-void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- del_key_bit(keyboard_report, key);
- return;
- }
-#endif
- del_key_byte(keyboard_report, key);
-}
-
-/** \brief clear key from report
- *
- * FIXME: Needs doc
- */
-void clear_keys_from_report(report_keyboard_t* keyboard_report) {
- // not clear mods
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
- return;
- }
-#endif
- memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
-}
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
deleted file mode 100644
index 1adc892f3b..0000000000
--- a/tmk_core/common/report.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
-Copyright 2011,2012 Jun Wako
-
-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 .
-*/
-
-#pragma once
-
-#include
-#include
-#include "keycode.h"
-
-// clang-format off
-
-/* HID report IDs */
-enum hid_report_ids {
- REPORT_ID_KEYBOARD = 1,
- REPORT_ID_MOUSE,
- REPORT_ID_SYSTEM,
- REPORT_ID_CONSUMER,
- REPORT_ID_PROGRAMMABLE_BUTTON,
- REPORT_ID_NKRO,
- REPORT_ID_JOYSTICK,
- REPORT_ID_DIGITIZER
-};
-
-/* Mouse buttons */
-#define MOUSE_BTN_MASK(n) (1 << (n))
-enum mouse_buttons {
- MOUSE_BTN1 = MOUSE_BTN_MASK(0),
- MOUSE_BTN2 = MOUSE_BTN_MASK(1),
- MOUSE_BTN3 = MOUSE_BTN_MASK(2),
- MOUSE_BTN4 = MOUSE_BTN_MASK(3),
- MOUSE_BTN5 = MOUSE_BTN_MASK(4),
- MOUSE_BTN6 = MOUSE_BTN_MASK(5),
- MOUSE_BTN7 = MOUSE_BTN_MASK(6),
- MOUSE_BTN8 = MOUSE_BTN_MASK(7)
-};
-
-/* Consumer Page (0x0C)
- *
- * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75
- */
-enum consumer_usages {
- // 15.5 Display Controls
- SNAPSHOT = 0x065,
- BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf
- BRIGHTNESS_DOWN = 0x070,
- // 15.7 Transport Controls
- TRANSPORT_RECORD = 0x0B2,
- TRANSPORT_FAST_FORWARD = 0x0B3,
- TRANSPORT_REWIND = 0x0B4,
- TRANSPORT_NEXT_TRACK = 0x0B5,
- TRANSPORT_PREV_TRACK = 0x0B6,
- TRANSPORT_STOP = 0x0B7,
- TRANSPORT_EJECT = 0x0B8,
- TRANSPORT_RANDOM_PLAY = 0x0B9,
- TRANSPORT_STOP_EJECT = 0x0CC,
- TRANSPORT_PLAY_PAUSE = 0x0CD,
- // 15.9.1 Audio Controls - Volume
- AUDIO_MUTE = 0x0E2,
- AUDIO_VOL_UP = 0x0E9,
- AUDIO_VOL_DOWN = 0x0EA,
- // 15.15 Application Launch Buttons
- AL_CC_CONFIG = 0x183,
- AL_EMAIL = 0x18A,
- AL_CALCULATOR = 0x192,
- AL_LOCAL_BROWSER = 0x194,
- AL_LOCK = 0x19E,
- AL_CONTROL_PANEL = 0x19F,
- AL_ASSISTANT = 0x1CB,
- AL_KEYBOARD_LAYOUT = 0x1AE,
- // 15.16 Generic GUI Application Controls
- AC_NEW = 0x201,
- AC_OPEN = 0x202,
- AC_CLOSE = 0x203,
- AC_EXIT = 0x204,
- AC_MAXIMIZE = 0x205,
- AC_MINIMIZE = 0x206,
- AC_SAVE = 0x207,
- AC_PRINT = 0x208,
- AC_PROPERTIES = 0x209,
- AC_UNDO = 0x21A,
- AC_COPY = 0x21B,
- AC_CUT = 0x21C,
- AC_PASTE = 0x21D,
- AC_SELECT_ALL = 0x21E,
- AC_FIND = 0x21F,
- AC_SEARCH = 0x221,
- AC_HOME = 0x223,
- AC_BACK = 0x224,
- AC_FORWARD = 0x225,
- AC_STOP = 0x226,
- AC_REFRESH = 0x227,
- AC_BOOKMARKS = 0x22A
-};
-
-/* Generic Desktop Page (0x01)
- *
- * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26
- */
-enum desktop_usages {
- // 4.5.1 System Controls - Power Controls
- SYSTEM_POWER_DOWN = 0x81,
- SYSTEM_SLEEP = 0x82,
- SYSTEM_WAKE_UP = 0x83,
- SYSTEM_RESTART = 0x8F,
- // 4.10 System Display Controls
- SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5
-};
-
-// clang-format on
-
-#define NKRO_SHARED_EP
-/* key report size(NKRO or boot mode) */
-#if defined(NKRO_ENABLE)
-# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
-# include "protocol/usb_descriptor.h"
-# define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
-# elif defined(PROTOCOL_ARM_ATSAM)
-# include "protocol/arm_atsam/usb/udi_device_epsize.h"
-# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
-# undef NKRO_SHARED_EP
-# undef MOUSE_SHARED_EP
-# else
-# error "NKRO not supported with this protocol"
-# endif
-#endif
-
-#ifdef KEYBOARD_SHARED_EP
-# define KEYBOARD_REPORT_SIZE 9
-#else
-# define KEYBOARD_REPORT_SIZE 8
-#endif
-
-#define KEYBOARD_REPORT_KEYS 6
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys.
- *
- * byte |0 |1 |2 |3 |4 |5 |6 |7
- * -----+--------+--------+--------+--------+--------+--------+--------+--------
- * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5]
- *
- * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode.
- *
- * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15
- * -----+--------+--------+--------+--------+--------+--------+--------+-------- +--------
- * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14]
- *
- * mods retains state of 8 modifiers.
- *
- * bit |0 |1 |2 |3 |4 |5 |6 |7
- * -----+--------+--------+--------+--------+--------+--------+--------+--------
- * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui
- *
- */
-typedef union {
- uint8_t raw[KEYBOARD_REPORT_SIZE];
- struct {
-#ifdef KEYBOARD_SHARED_EP
- uint8_t report_id;
-#endif
- uint8_t mods;
- uint8_t reserved;
- uint8_t keys[KEYBOARD_REPORT_KEYS];
- };
-#ifdef NKRO_ENABLE
- struct nkro_report {
-# ifdef NKRO_SHARED_EP
- uint8_t report_id;
-# endif
- uint8_t mods;
- uint8_t bits[KEYBOARD_REPORT_BITS];
- } nkro;
-#endif
-} __attribute__((packed)) report_keyboard_t;
-
-typedef struct {
- uint8_t report_id;
- uint16_t usage;
-} __attribute__((packed)) report_extra_t;
-
-typedef struct {
- uint8_t report_id;
- uint32_t usage;
-} __attribute__((packed)) report_programmable_button_t;
-
-typedef struct {
-#ifdef MOUSE_SHARED_EP
- uint8_t report_id;
-#endif
- uint8_t buttons;
- int8_t x;
- int8_t y;
- int8_t v;
- int8_t h;
-} __attribute__((packed)) report_mouse_t;
-
-typedef struct {
-#ifdef DIGITIZER_SHARED_EP
- uint8_t report_id;
-#endif
- uint8_t tip : 1;
- uint8_t inrange : 1;
- uint8_t pad2 : 6;
- uint16_t x;
- uint16_t y;
-} __attribute__((packed)) report_digitizer_t;
-
-typedef struct {
-#if JOYSTICK_AXES_COUNT > 0
-# if JOYSTICK_AXES_RESOLUTION > 8
- int16_t axes[JOYSTICK_AXES_COUNT];
-# else
- int8_t axes[JOYSTICK_AXES_COUNT];
-# endif
-#endif
-
-#if JOYSTICK_BUTTON_COUNT > 0
- uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
-#endif
-} __attribute__((packed)) joystick_report_t;
-
-/* keycode to system usage */
-static inline uint16_t KEYCODE2SYSTEM(uint8_t key) {
- switch (key) {
- case KC_SYSTEM_POWER:
- return SYSTEM_POWER_DOWN;
- case KC_SYSTEM_SLEEP:
- return SYSTEM_SLEEP;
- case KC_SYSTEM_WAKE:
- return SYSTEM_WAKE_UP;
- default:
- return 0;
- }
-}
-
-/* keycode to consumer usage */
-static inline uint16_t KEYCODE2CONSUMER(uint8_t key) {
- switch (key) {
- case KC_AUDIO_MUTE:
- return AUDIO_MUTE;
- case KC_AUDIO_VOL_UP:
- return AUDIO_VOL_UP;
- case KC_AUDIO_VOL_DOWN:
- return AUDIO_VOL_DOWN;
- case KC_MEDIA_NEXT_TRACK:
- return TRANSPORT_NEXT_TRACK;
- case KC_MEDIA_PREV_TRACK:
- return TRANSPORT_PREV_TRACK;
- case KC_MEDIA_FAST_FORWARD:
- return TRANSPORT_FAST_FORWARD;
- case KC_MEDIA_REWIND:
- return TRANSPORT_REWIND;
- case KC_MEDIA_STOP:
- return TRANSPORT_STOP;
- case KC_MEDIA_EJECT:
- return TRANSPORT_STOP_EJECT;
- case KC_MEDIA_PLAY_PAUSE:
- return TRANSPORT_PLAY_PAUSE;
- case KC_MEDIA_SELECT:
- return AL_CC_CONFIG;
- case KC_MAIL:
- return AL_EMAIL;
- case KC_CALCULATOR:
- return AL_CALCULATOR;
- case KC_MY_COMPUTER:
- return AL_LOCAL_BROWSER;
- case KC_WWW_SEARCH:
- return AC_SEARCH;
- case KC_WWW_HOME:
- return AC_HOME;
- case KC_WWW_BACK:
- return AC_BACK;
- case KC_WWW_FORWARD:
- return AC_FORWARD;
- case KC_WWW_STOP:
- return AC_STOP;
- case KC_WWW_REFRESH:
- return AC_REFRESH;
- case KC_BRIGHTNESS_UP:
- return BRIGHTNESS_UP;
- case KC_BRIGHTNESS_DOWN:
- return BRIGHTNESS_DOWN;
- case KC_WWW_FAVORITES:
- return AC_BOOKMARKS;
- default:
- return 0;
- }
-}
-
-uint8_t has_anykey(report_keyboard_t* keyboard_report);
-uint8_t get_first_key(report_keyboard_t* keyboard_report);
-bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key);
-
-void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
-void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
-#ifdef NKRO_ENABLE
-void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
-void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
-#endif
-
-void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key);
-void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
-void clear_keys_from_report(report_keyboard_t* keyboard_report);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tmk_core/common/sync_timer.c b/tmk_core/common/sync_timer.c
deleted file mode 100644
index de24b463b6..0000000000
--- a/tmk_core/common/sync_timer.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-Copyright (C) 2020 Ryan Caltabiano
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-If you happen to meet one of the copyright holders in a bar you are obligated
-to buy them one pint of beer.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#include "sync_timer.h"
-#include "keyboard.h"
-
-#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
-volatile int32_t sync_timer_ms;
-
-void sync_timer_init(void) { sync_timer_ms = 0; }
-
-void sync_timer_update(uint32_t time) {
- if (is_keyboard_master()) return;
- sync_timer_ms = time - timer_read32();
-}
-
-uint16_t sync_timer_read(void) {
- if (is_keyboard_master()) return timer_read();
- return sync_timer_read32();
-}
-
-uint32_t sync_timer_read32(void) {
- if (is_keyboard_master()) return timer_read32();
- return sync_timer_ms + timer_read32();
-}
-
-uint16_t sync_timer_elapsed(uint16_t last) {
- if (is_keyboard_master()) return timer_elapsed(last);
- return TIMER_DIFF_16(sync_timer_read(), last);
-}
-
-uint32_t sync_timer_elapsed32(uint32_t last) {
- if (is_keyboard_master()) return timer_elapsed32(last);
- return TIMER_DIFF_32(sync_timer_read32(), last);
-}
-#endif
diff --git a/tmk_core/common/sync_timer.h b/tmk_core/common/sync_timer.h
deleted file mode 100644
index 9ddef45bb2..0000000000
--- a/tmk_core/common/sync_timer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-Copyright (C) 2020 Ryan Caltabiano
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-If you happen to meet one of the copyright holders in a bar you are obligated
-to buy them one pint of beer.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-#pragma once
-
-#include
-#include "timer.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER)
-void sync_timer_init(void);
-void sync_timer_update(uint32_t time);
-uint16_t sync_timer_read(void);
-uint32_t sync_timer_read32(void);
-uint16_t sync_timer_elapsed(uint16_t last);
-uint32_t sync_timer_elapsed32(uint32_t last);
-#else
-# define sync_timer_init()
-# define sync_timer_clear()
-# define sync_timer_update(t)
-# define sync_timer_read() timer_read()
-# define sync_timer_read32() timer_read32()
-# define sync_timer_elapsed(t) timer_elapsed(t)
-# define sync_timer_elapsed32(t) timer_elapsed32(t)
-#endif
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/tmk_core/common/usb_util.c b/tmk_core/common/usb_util.c
deleted file mode 100644
index dd1deeaa11..0000000000
--- a/tmk_core/common/usb_util.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Copyright 2021 QMK
- *
- * 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 3 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 .
- */
-#include "quantum.h"
-#include "usb_util.h"
-
-__attribute__((weak)) void usb_disconnect(void) {}
-__attribute__((weak)) bool usb_connected_state(void) { return true; }
-__attribute__((weak)) bool usb_vbus_state(void) {
-#ifdef USB_VBUS_PIN
- setPinInput(USB_VBUS_PIN);
- wait_us(5);
- return readPin(USB_VBUS_PIN);
-#else
- return true;
-#endif
-}
diff --git a/tmk_core/common/usb_util.h b/tmk_core/common/usb_util.h
deleted file mode 100644
index 13db9fbfbd..0000000000
--- a/tmk_core/common/usb_util.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2021 QMK
- *
- * 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 3 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 .
- */
-#pragma once
-
-#include
-
-void usb_disconnect(void);
-bool usb_connected_state(void);
-bool usb_vbus_state(void);
diff --git a/tmk_core/common/virtser.h b/tmk_core/common/virtser.h
deleted file mode 100644
index a0645f9e03..0000000000
--- a/tmk_core/common/virtser.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#pragma once
-
-/* Define this function in your code to process incoming bytes */
-void virtser_recv(const uint8_t ch);
-
-/* Call this to send a character over the Virtual Serial Device */
-void virtser_send(const uint8_t byte);
diff --git a/tmk_core/protocol.mk b/tmk_core/protocol.mk
index d4ad50db6a..359ddbfef1 100644
--- a/tmk_core/protocol.mk
+++ b/tmk_core/protocol.mk
@@ -1,5 +1,11 @@
PROTOCOL_DIR = protocol
+TMK_COMMON_SRC += \
+ $(PROTOCOL_DIR)/host.c \
+ $(PROTOCOL_DIR)/report.c \
+ $(PROTOCOL_DIR)/usb_device_state.c \
+ $(PROTOCOL_DIR)/usb_util.c \
+
ifeq ($(strip $(USB_HID_ENABLE)), yes)
include $(TMK_DIR)/protocol/usb_hid.mk
endif
diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c
new file mode 100644
index 0000000000..56d4bb0847
--- /dev/null
+++ b/tmk_core/protocol/host.c
@@ -0,0 +1,138 @@
+/*
+Copyright 2011,2012 Jun Wako
+
+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 .
+*/
+
+#include
+//#include
+#include "keyboard.h"
+#include "keycode.h"
+#include "host.h"
+#include "util.h"
+#include "debug.h"
+#include "digitizer.h"
+
+#ifdef NKRO_ENABLE
+# include "keycode_config.h"
+extern keymap_config_t keymap_config;
+#endif
+
+static host_driver_t *driver;
+static uint16_t last_system_report = 0;
+static uint16_t last_consumer_report = 0;
+static uint32_t last_programmable_button_report = 0;
+
+void host_set_driver(host_driver_t *d) { driver = d; }
+
+host_driver_t *host_get_driver(void) { return driver; }
+
+#ifdef SPLIT_KEYBOARD
+uint8_t split_led_state = 0;
+void set_split_host_keyboard_leds(uint8_t led_state) { split_led_state = led_state; }
+#endif
+
+uint8_t host_keyboard_leds(void) {
+#ifdef SPLIT_KEYBOARD
+ if (!is_keyboard_master()) return split_led_state;
+#endif
+ if (!driver) return 0;
+ return (*driver->keyboard_leds)();
+}
+
+led_t host_keyboard_led_state(void) { return (led_t)host_keyboard_leds(); }
+
+/* send report */
+void host_keyboard_send(report_keyboard_t *report) {
+ if (!driver) return;
+#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
+ if (keyboard_protocol && keymap_config.nkro) {
+ /* The callers of this function assume that report->mods is where mods go in.
+ * But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
+ */
+ report->nkro.mods = report->mods;
+ report->nkro.report_id = REPORT_ID_NKRO;
+ } else
+#endif
+ {
+#ifdef KEYBOARD_SHARED_EP
+ report->report_id = REPORT_ID_KEYBOARD;
+#endif
+ }
+ (*driver->send_keyboard)(report);
+
+ if (debug_keyboard) {
+ dprint("keyboard_report: ");
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
+ dprintf("%02X ", report->raw[i]);
+ }
+ dprint("\n");
+ }
+}
+
+void host_mouse_send(report_mouse_t *report) {
+ if (!driver) return;
+#ifdef MOUSE_SHARED_EP
+ report->report_id = REPORT_ID_MOUSE;
+#endif
+ (*driver->send_mouse)(report);
+}
+
+void host_system_send(uint16_t report) {
+ if (report == last_system_report) return;
+ last_system_report = report;
+
+ if (!driver) return;
+ (*driver->send_system)(report);
+}
+
+void host_consumer_send(uint16_t report) {
+ if (report == last_consumer_report) return;
+ last_consumer_report = report;
+
+ if (!driver) return;
+ (*driver->send_consumer)(report);
+}
+
+void host_digitizer_send(digitizer_t *digitizer) {
+ if (!driver) return;
+
+ report_digitizer_t report = {
+#ifdef DIGITIZER_SHARED_EP
+ .report_id = REPORT_ID_DIGITIZER,
+#endif
+ .tip = digitizer->tipswitch & 0x1,
+ .inrange = digitizer->inrange & 0x1,
+ .x = (uint16_t)(digitizer->x * 0x7FFF),
+ .y = (uint16_t)(digitizer->y * 0x7FFF),
+ };
+
+ send_digitizer(&report);
+}
+
+__attribute__((weak)) void send_digitizer(report_digitizer_t *report) {}
+
+void host_programmable_button_send(uint32_t report) {
+ if (report == last_programmable_button_report) return;
+ last_programmable_button_report = report;
+
+ if (!driver) return;
+ (*driver->send_programmable_button)(report);
+}
+
+uint16_t host_last_system_report(void) { return last_system_report; }
+
+uint16_t host_last_consumer_report(void) { return last_consumer_report; }
+
+uint32_t host_last_programmable_button_report(void) { return last_programmable_button_report; }
diff --git a/tmk_core/protocol/host.h b/tmk_core/protocol/host.h
new file mode 100644
index 0000000000..6b15f0d0c1
--- /dev/null
+++ b/tmk_core/protocol/host.h
@@ -0,0 +1,58 @@
+/*
+Copyright 2011 Jun Wako
+
+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 .
+*/
+
+#pragma once
+
+#include
+#include
+#include "report.h"
+#include "host_driver.h"
+#include "led.h"
+
+#define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name)))
+#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name)))
+
+#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name)
+#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint8_t keyboard_idle;
+extern uint8_t keyboard_protocol;
+
+/* host driver */
+void host_set_driver(host_driver_t *driver);
+host_driver_t *host_get_driver(void);
+
+/* host driver interface */
+uint8_t host_keyboard_leds(void);
+led_t host_keyboard_led_state(void);
+void host_keyboard_send(report_keyboard_t *report);
+void host_mouse_send(report_mouse_t *report);
+void host_system_send(uint16_t data);
+void host_consumer_send(uint16_t data);
+void host_programmable_button_send(uint32_t data);
+
+uint16_t host_last_system_report(void);
+uint16_t host_last_consumer_report(void);
+uint32_t host_last_programmable_button_report(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tmk_core/protocol/host_driver.h b/tmk_core/protocol/host_driver.h
new file mode 100644
index 0000000000..affd0dcb34
--- /dev/null
+++ b/tmk_core/protocol/host_driver.h
@@ -0,0 +1,35 @@
+/*
+Copyright 2011 Jun Wako
+
+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 .
+*/
+
+#pragma once
+
+#include
+#include "report.h"
+#ifdef MIDI_ENABLE
+# include "midi.h"
+#endif
+
+typedef struct {
+ uint8_t (*keyboard_leds)(void);
+ void (*send_keyboard)(report_keyboard_t *);
+ void (*send_mouse)(report_mouse_t *);
+ void (*send_system)(uint16_t);
+ void (*send_consumer)(uint16_t);
+ void (*send_programmable_button)(uint32_t);
+} host_driver_t;
+
+void send_digitizer(report_digitizer_t *report);
\ No newline at end of file
diff --git a/tmk_core/protocol/report.c b/tmk_core/protocol/report.c
new file mode 100644
index 0000000000..854b59ae48
--- /dev/null
+++ b/tmk_core/protocol/report.c
@@ -0,0 +1,280 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 .
+ */
+
+#include "report.h"
+#include "host.h"
+#include "keycode_config.h"
+#include "debug.h"
+#include "util.h"
+#include
+
+#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
+# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
+# define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
+# define RO_INC(a) RO_ADD(a, 1)
+# define RO_DEC(a) RO_SUB(a, 1)
+static int8_t cb_head = 0;
+static int8_t cb_tail = 0;
+static int8_t cb_count = 0;
+#endif
+
+/** \brief has_anykey
+ *
+ * FIXME: Needs doc
+ */
+uint8_t has_anykey(report_keyboard_t* keyboard_report) {
+ uint8_t cnt = 0;
+ uint8_t* p = keyboard_report->keys;
+ uint8_t lp = sizeof(keyboard_report->keys);
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ p = keyboard_report->nkro.bits;
+ lp = sizeof(keyboard_report->nkro.bits);
+ }
+#endif
+ while (lp--) {
+ if (*p++) cnt++;
+ }
+ return cnt;
+}
+
+/** \brief get_first_key
+ *
+ * FIXME: Needs doc
+ */
+uint8_t get_first_key(report_keyboard_t* keyboard_report) {
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ uint8_t i = 0;
+ for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+ ;
+ return i << 3 | biton(keyboard_report->nkro.bits[i]);
+ }
+#endif
+#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
+ uint8_t i = cb_head;
+ do {
+ if (keyboard_report->keys[i] != 0) {
+ break;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ return keyboard_report->keys[i];
+#else
+ return keyboard_report->keys[0];
+#endif
+}
+
+/** \brief Checks if a key is pressed in the report
+ *
+ * Returns true if the keyboard_report reports that the key is pressed, otherwise false
+ * Note: The function doesn't support modifers currently, and it returns false for KC_NO
+ */
+bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key) {
+ if (key == KC_NO) {
+ return false;
+ }
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ if ((key >> 3) < KEYBOARD_REPORT_BITS) {
+ return keyboard_report->nkro.bits[key >> 3] & 1 << (key & 7);
+ } else {
+ return false;
+ }
+ }
+#endif
+ for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == key) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/** \brief add key byte
+ *
+ * FIXME: Needs doc
+ */
+void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
+#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
+ int8_t i = cb_head;
+ int8_t empty = -1;
+ if (cb_count) {
+ do {
+ if (keyboard_report->keys[i] == code) {
+ return;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ if (i == cb_tail) {
+ if (cb_tail == cb_head) {
+ // buffer is full
+ if (empty == -1) {
+ // pop head when has no empty space
+ cb_head = RO_INC(cb_head);
+ cb_count--;
+ } else {
+ // left shift when has empty space
+ uint8_t offset = 1;
+ i = RO_INC(empty);
+ do {
+ if (keyboard_report->keys[i] != 0) {
+ keyboard_report->keys[empty] = keyboard_report->keys[i];
+ keyboard_report->keys[i] = 0;
+ empty = RO_INC(empty);
+ } else {
+ offset++;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ cb_tail = RO_SUB(cb_tail, offset);
+ }
+ }
+ }
+ }
+ // add to tail
+ keyboard_report->keys[cb_tail] = code;
+ cb_tail = RO_INC(cb_tail);
+ cb_count++;
+#else
+ int8_t i = 0;
+ int8_t empty = -1;
+ for (; i < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ break;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ }
+ if (i == KEYBOARD_REPORT_KEYS) {
+ if (empty != -1) {
+ keyboard_report->keys[empty] = code;
+ }
+ }
+#endif
+}
+
+/** \brief del key byte
+ *
+ * FIXME: Needs doc
+ */
+void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
+#ifdef RING_BUFFERED_6KRO_REPORT_ENABLE
+ uint8_t i = cb_head;
+ if (cb_count) {
+ do {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ cb_count--;
+ if (cb_count == 0) {
+ // reset head and tail
+ cb_tail = cb_head = 0;
+ }
+ if (i == RO_DEC(cb_tail)) {
+ // left shift when next to tail
+ do {
+ cb_tail = RO_DEC(cb_tail);
+ if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
+ break;
+ }
+ } while (cb_tail != cb_head);
+ }
+ break;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ }
+#else
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ }
+ }
+#endif
+}
+
+#ifdef NKRO_ENABLE
+/** \brief add key bit
+ *
+ * FIXME: Needs doc
+ */
+void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
+ if ((code >> 3) < KEYBOARD_REPORT_BITS) {
+ keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7);
+ } else {
+ dprintf("add_key_bit: can't add: %02X\n", code);
+ }
+}
+
+/** \brief del key bit
+ *
+ * FIXME: Needs doc
+ */
+void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
+ if ((code >> 3) < KEYBOARD_REPORT_BITS) {
+ keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7));
+ } else {
+ dprintf("del_key_bit: can't del: %02X\n", code);
+ }
+}
+#endif
+
+/** \brief add key to report
+ *
+ * FIXME: Needs doc
+ */
+void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ add_key_bit(keyboard_report, key);
+ return;
+ }
+#endif
+ add_key_byte(keyboard_report, key);
+}
+
+/** \brief del key from report
+ *
+ * FIXME: Needs doc
+ */
+void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ del_key_bit(keyboard_report, key);
+ return;
+ }
+#endif
+ del_key_byte(keyboard_report, key);
+}
+
+/** \brief clear key from report
+ *
+ * FIXME: Needs doc
+ */
+void clear_keys_from_report(report_keyboard_t* keyboard_report) {
+ // not clear mods
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ memset(keyboard_report->nkro.bits, 0, sizeof(keyboard_report->nkro.bits));
+ return;
+ }
+#endif
+ memset(keyboard_report->keys, 0, sizeof(keyboard_report->keys));
+}
diff --git a/tmk_core/protocol/report.h b/tmk_core/protocol/report.h
new file mode 100644
index 0000000000..1adc892f3b
--- /dev/null
+++ b/tmk_core/protocol/report.h
@@ -0,0 +1,325 @@
+/*
+Copyright 2011,2012 Jun Wako
+
+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 .
+*/
+
+#pragma once
+
+#include
+#include
+#include "keycode.h"
+
+// clang-format off
+
+/* HID report IDs */
+enum hid_report_ids {
+ REPORT_ID_KEYBOARD = 1,
+ REPORT_ID_MOUSE,
+ REPORT_ID_SYSTEM,
+ REPORT_ID_CONSUMER,
+ REPORT_ID_PROGRAMMABLE_BUTTON,
+ REPORT_ID_NKRO,
+ REPORT_ID_JOYSTICK,
+ REPORT_ID_DIGITIZER
+};
+
+/* Mouse buttons */
+#define MOUSE_BTN_MASK(n) (1 << (n))
+enum mouse_buttons {
+ MOUSE_BTN1 = MOUSE_BTN_MASK(0),
+ MOUSE_BTN2 = MOUSE_BTN_MASK(1),
+ MOUSE_BTN3 = MOUSE_BTN_MASK(2),
+ MOUSE_BTN4 = MOUSE_BTN_MASK(3),
+ MOUSE_BTN5 = MOUSE_BTN_MASK(4),
+ MOUSE_BTN6 = MOUSE_BTN_MASK(5),
+ MOUSE_BTN7 = MOUSE_BTN_MASK(6),
+ MOUSE_BTN8 = MOUSE_BTN_MASK(7)
+};
+
+/* Consumer Page (0x0C)
+ *
+ * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=75
+ */
+enum consumer_usages {
+ // 15.5 Display Controls
+ SNAPSHOT = 0x065,
+ BRIGHTNESS_UP = 0x06F, // https://www.usb.org/sites/default/files/hutrr41_0.pdf
+ BRIGHTNESS_DOWN = 0x070,
+ // 15.7 Transport Controls
+ TRANSPORT_RECORD = 0x0B2,
+ TRANSPORT_FAST_FORWARD = 0x0B3,
+ TRANSPORT_REWIND = 0x0B4,
+ TRANSPORT_NEXT_TRACK = 0x0B5,
+ TRANSPORT_PREV_TRACK = 0x0B6,
+ TRANSPORT_STOP = 0x0B7,
+ TRANSPORT_EJECT = 0x0B8,
+ TRANSPORT_RANDOM_PLAY = 0x0B9,
+ TRANSPORT_STOP_EJECT = 0x0CC,
+ TRANSPORT_PLAY_PAUSE = 0x0CD,
+ // 15.9.1 Audio Controls - Volume
+ AUDIO_MUTE = 0x0E2,
+ AUDIO_VOL_UP = 0x0E9,
+ AUDIO_VOL_DOWN = 0x0EA,
+ // 15.15 Application Launch Buttons
+ AL_CC_CONFIG = 0x183,
+ AL_EMAIL = 0x18A,
+ AL_CALCULATOR = 0x192,
+ AL_LOCAL_BROWSER = 0x194,
+ AL_LOCK = 0x19E,
+ AL_CONTROL_PANEL = 0x19F,
+ AL_ASSISTANT = 0x1CB,
+ AL_KEYBOARD_LAYOUT = 0x1AE,
+ // 15.16 Generic GUI Application Controls
+ AC_NEW = 0x201,
+ AC_OPEN = 0x202,
+ AC_CLOSE = 0x203,
+ AC_EXIT = 0x204,
+ AC_MAXIMIZE = 0x205,
+ AC_MINIMIZE = 0x206,
+ AC_SAVE = 0x207,
+ AC_PRINT = 0x208,
+ AC_PROPERTIES = 0x209,
+ AC_UNDO = 0x21A,
+ AC_COPY = 0x21B,
+ AC_CUT = 0x21C,
+ AC_PASTE = 0x21D,
+ AC_SELECT_ALL = 0x21E,
+ AC_FIND = 0x21F,
+ AC_SEARCH = 0x221,
+ AC_HOME = 0x223,
+ AC_BACK = 0x224,
+ AC_FORWARD = 0x225,
+ AC_STOP = 0x226,
+ AC_REFRESH = 0x227,
+ AC_BOOKMARKS = 0x22A
+};
+
+/* Generic Desktop Page (0x01)
+ *
+ * See https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf#page=26
+ */
+enum desktop_usages {
+ // 4.5.1 System Controls - Power Controls
+ SYSTEM_POWER_DOWN = 0x81,
+ SYSTEM_SLEEP = 0x82,
+ SYSTEM_WAKE_UP = 0x83,
+ SYSTEM_RESTART = 0x8F,
+ // 4.10 System Display Controls
+ SYSTEM_DISPLAY_TOGGLE_INT_EXT = 0xB5
+};
+
+// clang-format on
+
+#define NKRO_SHARED_EP
+/* key report size(NKRO or boot mode) */
+#if defined(NKRO_ENABLE)
+# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
+# include "protocol/usb_descriptor.h"
+# define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
+# elif defined(PROTOCOL_ARM_ATSAM)
+# include "protocol/arm_atsam/usb/udi_device_epsize.h"
+# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
+# undef NKRO_SHARED_EP
+# undef MOUSE_SHARED_EP
+# else
+# error "NKRO not supported with this protocol"
+# endif
+#endif
+
+#ifdef KEYBOARD_SHARED_EP
+# define KEYBOARD_REPORT_SIZE 9
+#else
+# define KEYBOARD_REPORT_SIZE 8
+#endif
+
+#define KEYBOARD_REPORT_KEYS 6
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * keyboard report is 8-byte array retains state of 8 modifiers and 6 keys.
+ *
+ * byte |0 |1 |2 |3 |4 |5 |6 |7
+ * -----+--------+--------+--------+--------+--------+--------+--------+--------
+ * desc |mods |reserved|keys[0] |keys[1] |keys[2] |keys[3] |keys[4] |keys[5]
+ *
+ * It is exended to 16 bytes to retain 120keys+8mods when NKRO mode.
+ *
+ * byte |0 |1 |2 |3 |4 |5 |6 |7 ... |15
+ * -----+--------+--------+--------+--------+--------+--------+--------+-------- +--------
+ * desc |mods |bits[0] |bits[1] |bits[2] |bits[3] |bits[4] |bits[5] |bits[6] ... |bit[14]
+ *
+ * mods retains state of 8 modifiers.
+ *
+ * bit |0 |1 |2 |3 |4 |5 |6 |7
+ * -----+--------+--------+--------+--------+--------+--------+--------+--------
+ * desc |Lcontrol|Lshift |Lalt |Lgui |Rcontrol|Rshift |Ralt |Rgui
+ *
+ */
+typedef union {
+ uint8_t raw[KEYBOARD_REPORT_SIZE];
+ struct {
+#ifdef KEYBOARD_SHARED_EP
+ uint8_t report_id;
+#endif
+ uint8_t mods;
+ uint8_t reserved;
+ uint8_t keys[KEYBOARD_REPORT_KEYS];
+ };
+#ifdef NKRO_ENABLE
+ struct nkro_report {
+# ifdef NKRO_SHARED_EP
+ uint8_t report_id;
+# endif
+ uint8_t mods;
+ uint8_t bits[KEYBOARD_REPORT_BITS];
+ } nkro;
+#endif
+} __attribute__((packed)) report_keyboard_t;
+
+typedef struct {
+ uint8_t report_id;
+ uint16_t usage;
+} __attribute__((packed)) report_extra_t;
+
+typedef struct {
+ uint8_t report_id;
+ uint32_t usage;
+} __attribute__((packed)) report_programmable_button_t;
+
+typedef struct {
+#ifdef MOUSE_SHARED_EP
+ uint8_t report_id;
+#endif
+ uint8_t buttons;
+ int8_t x;
+ int8_t y;
+ int8_t v;
+ int8_t h;
+} __attribute__((packed)) report_mouse_t;
+
+typedef struct {
+#ifdef DIGITIZER_SHARED_EP
+ uint8_t report_id;
+#endif
+ uint8_t tip : 1;
+ uint8_t inrange : 1;
+ uint8_t pad2 : 6;
+ uint16_t x;
+ uint16_t y;
+} __attribute__((packed)) report_digitizer_t;
+
+typedef struct {
+#if JOYSTICK_AXES_COUNT > 0
+# if JOYSTICK_AXES_RESOLUTION > 8
+ int16_t axes[JOYSTICK_AXES_COUNT];
+# else
+ int8_t axes[JOYSTICK_AXES_COUNT];
+# endif
+#endif
+
+#if JOYSTICK_BUTTON_COUNT > 0
+ uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1];
+#endif
+} __attribute__((packed)) joystick_report_t;
+
+/* keycode to system usage */
+static inline uint16_t KEYCODE2SYSTEM(uint8_t key) {
+ switch (key) {
+ case KC_SYSTEM_POWER:
+ return SYSTEM_POWER_DOWN;
+ case KC_SYSTEM_SLEEP:
+ return SYSTEM_SLEEP;
+ case KC_SYSTEM_WAKE:
+ return SYSTEM_WAKE_UP;
+ default:
+ return 0;
+ }
+}
+
+/* keycode to consumer usage */
+static inline uint16_t KEYCODE2CONSUMER(uint8_t key) {
+ switch (key) {
+ case KC_AUDIO_MUTE:
+ return AUDIO_MUTE;
+ case KC_AUDIO_VOL_UP:
+ return AUDIO_VOL_UP;
+ case KC_AUDIO_VOL_DOWN:
+ return AUDIO_VOL_DOWN;
+ case KC_MEDIA_NEXT_TRACK:
+ return TRANSPORT_NEXT_TRACK;
+ case KC_MEDIA_PREV_TRACK:
+ return TRANSPORT_PREV_TRACK;
+ case KC_MEDIA_FAST_FORWARD:
+ return TRANSPORT_FAST_FORWARD;
+ case KC_MEDIA_REWIND:
+ return TRANSPORT_REWIND;
+ case KC_MEDIA_STOP:
+ return TRANSPORT_STOP;
+ case KC_MEDIA_EJECT:
+ return TRANSPORT_STOP_EJECT;
+ case KC_MEDIA_PLAY_PAUSE:
+ return TRANSPORT_PLAY_PAUSE;
+ case KC_MEDIA_SELECT:
+ return AL_CC_CONFIG;
+ case KC_MAIL:
+ return AL_EMAIL;
+ case KC_CALCULATOR:
+ return AL_CALCULATOR;
+ case KC_MY_COMPUTER:
+ return AL_LOCAL_BROWSER;
+ case KC_WWW_SEARCH:
+ return AC_SEARCH;
+ case KC_WWW_HOME:
+ return AC_HOME;
+ case KC_WWW_BACK:
+ return AC_BACK;
+ case KC_WWW_FORWARD:
+ return AC_FORWARD;
+ case KC_WWW_STOP:
+ return AC_STOP;
+ case KC_WWW_REFRESH:
+ return AC_REFRESH;
+ case KC_BRIGHTNESS_UP:
+ return BRIGHTNESS_UP;
+ case KC_BRIGHTNESS_DOWN:
+ return BRIGHTNESS_DOWN;
+ case KC_WWW_FAVORITES:
+ return AC_BOOKMARKS;
+ default:
+ return 0;
+ }
+}
+
+uint8_t has_anykey(report_keyboard_t* keyboard_report);
+uint8_t get_first_key(report_keyboard_t* keyboard_report);
+bool is_key_pressed(report_keyboard_t* keyboard_report, uint8_t key);
+
+void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
+void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
+#ifdef NKRO_ENABLE
+void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+#endif
+
+void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key);
+void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
+void clear_keys_from_report(report_keyboard_t* keyboard_report);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tmk_core/protocol/usb_device_state.c b/tmk_core/protocol/usb_device_state.c
new file mode 100644
index 0000000000..5ccd309ec2
--- /dev/null
+++ b/tmk_core/protocol/usb_device_state.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2021 Andrei Purdea
+ *
+ * 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 .
+ */
+
+#include "usb_device_state.h"
+
+enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT;
+
+__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { notify_usb_device_state_change_user(usb_device_state); }
+
+__attribute__((weak)) void notify_usb_device_state_change_user(enum usb_device_state usb_device_state) {}
+
+static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { notify_usb_device_state_change_kb(usb_device_state); }
+
+void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) {
+ usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
+ notify_usb_device_state_change(usb_device_state);
+}
+
+void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) {
+ usb_device_state = USB_DEVICE_STATE_SUSPEND;
+ notify_usb_device_state_change(usb_device_state);
+}
+
+void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) {
+ usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
+ notify_usb_device_state_change(usb_device_state);
+}
+
+void usb_device_state_set_reset(void) {
+ usb_device_state = USB_DEVICE_STATE_INIT;
+ notify_usb_device_state_change(usb_device_state);
+}
+
+void usb_device_state_init(void) {
+ usb_device_state = USB_DEVICE_STATE_INIT;
+ notify_usb_device_state_change(usb_device_state);
+}
diff --git a/tmk_core/protocol/usb_device_state.h b/tmk_core/protocol/usb_device_state.h
new file mode 100644
index 0000000000..c229311d46
--- /dev/null
+++ b/tmk_core/protocol/usb_device_state.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 Andrei Purdea
+ *
+ * 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 .
+ */
+
+#pragma once
+
+#include
+#include
+
+void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber);
+void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber);
+void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber);
+void usb_device_state_set_reset(void);
+void usb_device_state_init(void);
+
+enum usb_device_state {
+ USB_DEVICE_STATE_NO_INIT = 0, // We're in this state before calling usb_device_state_init()
+ USB_DEVICE_STATE_INIT = 1, // Can consume up to 100mA
+ USB_DEVICE_STATE_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
+ USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current
+};
+
+extern enum usb_device_state usb_device_state;
+
+void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state);
+void notify_usb_device_state_change_user(enum usb_device_state usb_device_state);
diff --git a/tmk_core/protocol/usb_util.c b/tmk_core/protocol/usb_util.c
new file mode 100644
index 0000000000..dd1deeaa11
--- /dev/null
+++ b/tmk_core/protocol/usb_util.c
@@ -0,0 +1,29 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 .
+ */
+#include "quantum.h"
+#include "usb_util.h"
+
+__attribute__((weak)) void usb_disconnect(void) {}
+__attribute__((weak)) bool usb_connected_state(void) { return true; }
+__attribute__((weak)) bool usb_vbus_state(void) {
+#ifdef USB_VBUS_PIN
+ setPinInput(USB_VBUS_PIN);
+ wait_us(5);
+ return readPin(USB_VBUS_PIN);
+#else
+ return true;
+#endif
+}
diff --git a/tmk_core/protocol/usb_util.h b/tmk_core/protocol/usb_util.h
new file mode 100644
index 0000000000..13db9fbfbd
--- /dev/null
+++ b/tmk_core/protocol/usb_util.h
@@ -0,0 +1,22 @@
+/* Copyright 2021 QMK
+ *
+ * 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 3 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 .
+ */
+#pragma once
+
+#include
+
+void usb_disconnect(void);
+bool usb_connected_state(void);
+bool usb_vbus_state(void);
--
cgit v1.2.3