Merge remote-tracking branch 'origin/develop' into xap

This commit is contained in:
QMK Bot 2024-10-18 07:57:41 +00:00
commit 595e339f57
20 changed files with 165 additions and 130 deletions

View File

@ -158,7 +158,7 @@ void solenoid_setup(void) {
#endif #endif
gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]); gpio_write_pin(solenoid_pads[i], !solenoid_active_state[i]);
gpio_set_pin_output(solenoid_pads[i]); gpio_set_pin_output(solenoid_pads[i]);
if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED)) { if ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED)) {
solenoid_fire(i); solenoid_fire(i);
} }
} }

View File

@ -8,6 +8,9 @@
"pid": "0xE88F", "pid": "0xE88F",
"device_version": "0.0.1" "device_version": "0.0.1"
}, },
"build": {
"lto": true
},
"features": { "features": {
"bootmagic": true, "bootmagic": true,
"command": false, "command": false,

View File

@ -8,6 +8,9 @@
"pid": "0x8C9C", "pid": "0x8C9C",
"device_version": "0.0.2" "device_version": "0.0.2"
}, },
"build": {
"lto": true
},
"features": { "features": {
"bootmagic": true, "bootmagic": true,
"encoder": true, "encoder": true,

View File

@ -30,7 +30,6 @@
"knight": true, "knight": true,
"rainbow_mood": true, "rainbow_mood": true,
"rainbow_swirl": true, "rainbow_swirl": true,
"rgb_test": true,
"snake": true, "snake": true,
"static_gradient": true, "static_gradient": true,
"twinkle": true "twinkle": true

View File

@ -51,8 +51,7 @@
"pixel_rain": true, "pixel_rain": true,
"pixel_flow": true, "pixel_flow": true,
"pixel_fractal": true, "pixel_fractal": true,
"typing_heatmap": true, "typing_heatmap": true
"digital_rain": true
}, },
"driver": "ws2812", "driver": "ws2812",
"max_brightness": 120, "max_brightness": 120,

View File

@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_layer.h" #include "action_layer.h"
#include "timer.h" #include "timer.h"
#include "keycode_config.h" #include "keycode_config.h"
#include "usb_device_state.h"
#include <string.h> #include <string.h>
extern keymap_config_t keymap_config; extern keymap_config_t keymap_config;
@ -318,7 +319,7 @@ void send_nkro_report(void) {
*/ */
void send_keyboard_report(void) { void send_keyboard_report(void) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
send_nkro_report(); send_nkro_report();
} else { } else {
send_6kro_report(); send_6kro_report();

View File

@ -32,6 +32,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "led.h" #include "led.h"
#include "command.h" #include "command.h"
#include "quantum.h" #include "quantum.h"
#include "usb_device_state.h"
#include "version.h" #include "version.h"
#ifdef BACKLIGHT_ENABLE #ifdef BACKLIGHT_ENABLE
@ -230,8 +231,8 @@ static void print_status(void) {
"timer_read32(): %08lX\n" "timer_read32(): %08lX\n"
, host_keyboard_leds() , host_keyboard_leds()
, keyboard_protocol , usb_device_state_get_protocol()
, keyboard_idle , usb_device_state_get_idle_rate()
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
, keymap_config.nkro , keymap_config.nkro
#endif #endif

View File

@ -36,7 +36,7 @@ extern uint8_t split_haptic_play;
haptic_config_t haptic_config; haptic_config_t haptic_config;
static void update_haptic_enable_gpios(void) { static void update_haptic_enable_gpios(void) {
if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
#if defined(HAPTIC_ENABLE_PIN) #if defined(HAPTIC_ENABLE_PIN)
HAPTIC_ENABLE_PIN_WRITE_ACTIVE(); HAPTIC_ENABLE_PIN_WRITE_ACTIVE();
#endif #endif

View File

@ -65,8 +65,8 @@ static volatile os_variant_t reported_os = OS_UNSURE;
static volatile bool first_report = true; static volatile bool first_report = true;
// to react on USB state changes // to react on USB state changes
static volatile enum usb_device_state current_usb_device_state = USB_DEVICE_STATE_NO_INIT; static volatile struct usb_device_state current_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT};
static volatile enum usb_device_state maxprev_usb_device_state = USB_DEVICE_STATE_NO_INIT; static volatile struct usb_device_state maxprev_usb_device_state = {.configure_state = USB_DEVICE_STATE_NO_INIT};
// the OS detection might be unstable for a while, "debounce" it // the OS detection might be unstable for a while, "debounce" it
static volatile bool debouncing = false; static volatile bool debouncing = false;
@ -88,7 +88,7 @@ void os_detection_task(void) {
return; return;
} }
#endif #endif
if (current_usb_device_state == USB_DEVICE_STATE_CONFIGURED) { if (current_usb_device_state.configure_state == USB_DEVICE_STATE_CONFIGURED) {
// debouncing goes for both the detected OS as well as the USB state // debouncing goes for both the detected OS as well as the USB state
if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) { if (debouncing && timer_elapsed_fast(last_time) >= OS_DETECTION_DEBOUNCE) {
debouncing = false; debouncing = false;
@ -163,19 +163,19 @@ os_variant_t detected_host_os(void) {
void erase_wlength_data(void) { void erase_wlength_data(void) {
memset(&setups_data, 0, sizeof(setups_data)); memset(&setups_data, 0, sizeof(setups_data));
detected_os = OS_UNSURE; detected_os = OS_UNSURE;
reported_os = OS_UNSURE; reported_os = OS_UNSURE;
current_usb_device_state = USB_DEVICE_STATE_NO_INIT; current_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT;
maxprev_usb_device_state = USB_DEVICE_STATE_NO_INIT; maxprev_usb_device_state.configure_state = USB_DEVICE_STATE_NO_INIT;
debouncing = false; debouncing = false;
last_time = 0; last_time = 0;
first_report = true; first_report = true;
} }
void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state) { void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state) {
// treat this like any other source of instability // treat this like any other source of instability
if (maxprev_usb_device_state < current_usb_device_state) { if (maxprev_usb_device_state.configure_state < current_usb_device_state.configure_state) {
maxprev_usb_device_state = current_usb_device_state; maxprev_usb_device_state.configure_state = current_usb_device_state.configure_state;
} }
current_usb_device_state = usb_device_state; current_usb_device_state = usb_device_state;
last_time = timer_read_fast(); last_time = timer_read_fast();

View File

@ -31,7 +31,7 @@ typedef enum {
void process_wlength(const uint16_t w_length); void process_wlength(const uint16_t w_length);
os_variant_t detected_host_os(void); os_variant_t detected_host_os(void);
void erase_wlength_data(void); void erase_wlength_data(void);
void os_detection_notify_usb_device_state_change(enum usb_device_state usb_device_state); void os_detection_notify_usb_device_state_change(struct usb_device_state usb_device_state);
void os_detection_task(void); void os_detection_task(void);

View File

@ -253,9 +253,11 @@ TEST_F(OsDetectionTest, TestDoNotReportIfUsbUnstable) {
EXPECT_EQ(detected_host_os(), OS_LINUX); EXPECT_EQ(detected_host_os(), OS_LINUX);
} }
static struct usb_device_state usb_device_state_configured = {.configure_state = USB_DEVICE_STATE_CONFIGURED};
TEST_F(OsDetectionTest, TestReportAfterDebounce) { TEST_F(OsDetectionTest, TestReportAfterDebounce) {
EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX);
os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task(); os_detection_task();
assert_not_reported(); assert_not_reported();
@ -291,7 +293,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounce) {
TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) { TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task(); os_detection_task();
assert_not_reported(); assert_not_reported();
@ -318,7 +320,7 @@ TEST_F(OsDetectionTest, TestReportAfterDebounceLongWait) {
TEST_F(OsDetectionTest, TestReportUnsure) { TEST_F(OsDetectionTest, TestReportUnsure) {
EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE); EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task(); os_detection_task();
assert_not_reported(); assert_not_reported();
@ -345,7 +347,7 @@ TEST_F(OsDetectionTest, TestReportUnsure) {
TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) { TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE); EXPECT_EQ(check_sequence({0x12, 0xFF}), OS_UNSURE);
os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); os_detection_notify_usb_device_state_change(usb_device_state_configured);
os_detection_task(); os_detection_task();
assert_not_reported(); assert_not_reported();
@ -356,7 +358,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
// at this stage, the final result has not been reached yet // at this stage, the final result has not been reached yet
EXPECT_EQ(check_sequence({0xFF}), OS_LINUX); EXPECT_EQ(check_sequence({0xFF}), OS_LINUX);
os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); os_detection_notify_usb_device_state_change(usb_device_state_configured);
advance_time(OS_DETECTION_DEBOUNCE - 1); advance_time(OS_DETECTION_DEBOUNCE - 1);
os_detection_task(); os_detection_task();
assert_not_reported(); assert_not_reported();
@ -365,7 +367,7 @@ TEST_F(OsDetectionTest, TestDoNotReportIntermediateResults) {
// the remainder is processed // the remainder is processed
EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); EXPECT_EQ(check_sequence({0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS);
os_detection_notify_usb_device_state_change(USB_DEVICE_STATE_CONFIGURED); os_detection_notify_usb_device_state_change(usb_device_state_configured);
advance_time(OS_DETECTION_DEBOUNCE - 1); advance_time(OS_DETECTION_DEBOUNCE - 1);
os_detection_task(); os_detection_task();
assert_not_reported(); assert_not_reported();

View File

@ -129,7 +129,7 @@ bool process_haptic(uint16_t keycode, keyrecord_t *record) {
} }
} }
if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state_get_configure_state() == USB_DEVICE_STATE_CONFIGURED))) {
if (record->event.pressed) { if (record->event.pressed) {
// keypress // keypress
if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) { if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) {

View File

@ -62,14 +62,13 @@
*/ */
/* declarations */ /* declarations */
uint8_t keyboard_leds(void); void send_keyboard(report_keyboard_t *report);
void send_keyboard(report_keyboard_t *report); void send_nkro(report_nkro_t *report);
void send_nkro(report_nkro_t *report); void send_mouse(report_mouse_t *report);
void send_mouse(report_mouse_t *report); void send_extra(report_extra_t *report);
void send_extra(report_extra_t *report);
/* host struct */ /* host struct */
host_driver_t chibios_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; host_driver_t chibios_driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra};
#ifdef VIRTSER_ENABLE #ifdef VIRTSER_ENABLE
void virtser_task(void); void virtser_task(void);

View File

@ -58,10 +58,6 @@ extern keymap_config_t keymap_config;
extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT]; extern usb_endpoint_in_t usb_endpoints_in[USB_ENDPOINT_IN_COUNT];
extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT]; extern usb_endpoint_out_t usb_endpoints_out[USB_ENDPOINT_OUT_COUNT];
uint8_t _Alignas(2) keyboard_idle = 0;
uint8_t _Alignas(2) keyboard_protocol = 1;
uint8_t keyboard_led_state = 0;
static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size); static bool __attribute__((__unused__)) send_report_buffered(usb_endpoint_in_lut_t endpoint, void *report, size_t size);
static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded); static void __attribute__((__unused__)) flush_report_buffered(usb_endpoint_in_lut_t endpoint, bool padded);
static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size); static bool __attribute__((__unused__)) receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t size);
@ -172,6 +168,7 @@ void usb_event_queue_task(void) {
break; break;
case USB_EVENT_RESET: case USB_EVENT_RESET:
usb_device_state_set_reset(); usb_device_state_set_reset();
usb_device_state_set_protocol(USB_PROTOCOL_REPORT);
break; break;
default: default:
// Nothing to do, we don't handle it. // Nothing to do, we don't handle it.
@ -254,10 +251,10 @@ static void set_led_transfer_cb(USBDriver *usbp) {
if (setup->wLength == 2) { if (setup->wLength == 2) {
uint8_t report_id = set_report_buf[0]; uint8_t report_id = set_report_buf[0];
if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) { if ((report_id == REPORT_ID_KEYBOARD) || (report_id == REPORT_ID_NKRO)) {
keyboard_led_state = set_report_buf[1]; usb_device_state_set_leds(set_report_buf[1]);
} }
} else { } else {
keyboard_led_state = set_report_buf[0]; usb_device_state_set_leds(set_report_buf[0]);
} }
} }
@ -273,7 +270,9 @@ static bool usb_requests_hook_cb(USBDriver *usbp) {
return usb_get_report_cb(usbp); return usb_get_report_cb(usbp);
case HID_REQ_GetProtocol: case HID_REQ_GetProtocol:
if (setup->wIndex == KEYBOARD_INTERFACE) { if (setup->wIndex == KEYBOARD_INTERFACE) {
usbSetupTransfer(usbp, &keyboard_protocol, sizeof(uint8_t), NULL); static uint8_t keyboard_protocol;
keyboard_protocol = usb_device_state_get_protocol();
usbSetupTransfer(usbp, &keyboard_protocol, sizeof(keyboard_protocol), NULL);
return true; return true;
} }
break; break;
@ -296,12 +295,12 @@ static bool usb_requests_hook_cb(USBDriver *usbp) {
break; break;
case HID_REQ_SetProtocol: case HID_REQ_SetProtocol:
if (setup->wIndex == KEYBOARD_INTERFACE) { if (setup->wIndex == KEYBOARD_INTERFACE) {
keyboard_protocol = setup->wValue.word; usb_device_state_set_protocol(setup->wValue.lbyte);
} }
usbSetupTransfer(usbp, NULL, 0, NULL); usbSetupTransfer(usbp, NULL, 0, NULL);
return true; return true;
case HID_REQ_SetIdle: case HID_REQ_SetIdle:
keyboard_idle = setup->wValue.hbyte; usb_device_state_set_idle_rate(setup->wValue.hbyte);
return usb_set_idle_cb(usbp); return usb_set_idle_cb(usbp);
} }
break; break;
@ -400,11 +399,6 @@ __attribute__((weak)) void restart_usb_driver(USBDriver *usbp) {
* --------------------------------------------------------- * ---------------------------------------------------------
*/ */
/* LED status */
uint8_t keyboard_leds(void) {
return keyboard_led_state;
}
/** /**
* @brief Send a report to the host, the report is enqueued into an output * @brief Send a report to the host, the report is enqueued into an output
* queue and send once the USB endpoint becomes empty. * queue and send once the USB endpoint becomes empty.
@ -462,7 +456,7 @@ static bool receive_report(usb_endpoint_out_lut_t endpoint, void *report, size_t
void send_keyboard(report_keyboard_t *report) { void send_keyboard(report_keyboard_t *report) {
/* If we're in Boot Protocol, don't send any report ID or other funky fields */ /* If we're in Boot Protocol, don't send any report ID or other funky fields */
if (!keyboard_protocol) { if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
send_report(USB_ENDPOINT_IN_KEYBOARD, &report->mods, 8); send_report(USB_ENDPOINT_IN_KEYBOARD, &report->mods, 8);
} else { } else {
send_report(USB_ENDPOINT_IN_KEYBOARD, report, KEYBOARD_REPORT_SIZE); send_report(USB_ENDPOINT_IN_KEYBOARD, report, KEYBOARD_REPORT_SIZE);

View File

@ -27,9 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern "C" { extern "C" {
#endif #endif
extern uint8_t keyboard_idle;
extern uint8_t keyboard_protocol;
/* host driver */ /* host driver */
void host_set_driver(host_driver_t *driver); void host_set_driver(host_driver_t *driver);
host_driver_t *host_get_driver(void); host_driver_t *host_get_driver(void);

View File

@ -76,20 +76,14 @@
# define USB_WAIT_FOR_ENUMERATION # define USB_WAIT_FOR_ENUMERATION
#endif #endif
uint8_t keyboard_idle = 0;
/* 0: Boot Protocol, 1: Report Protocol(default) */
uint8_t keyboard_protocol = 1;
static uint8_t keyboard_led_state = 0;
static report_keyboard_t keyboard_report_sent; static report_keyboard_t keyboard_report_sent;
/* Host driver */ /* Host driver */
static uint8_t keyboard_leds(void); static void send_keyboard(report_keyboard_t *report);
static void send_keyboard(report_keyboard_t *report); static void send_nkro(report_nkro_t *report);
static void send_nkro(report_nkro_t *report); static void send_mouse(report_mouse_t *report);
static void send_mouse(report_mouse_t *report); static void send_extra(report_extra_t *report);
static void send_extra(report_extra_t *report); host_driver_t lufa_driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra};
host_driver_t lufa_driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra};
void send_report(uint8_t endpoint, void *report, size_t size) { void send_report(uint8_t endpoint, void *report, size_t size) {
uint8_t timeout = 255; uint8_t timeout = 255;
@ -374,6 +368,7 @@ void EVENT_USB_Device_Disconnect(void) {
void EVENT_USB_Device_Reset(void) { void EVENT_USB_Device_Reset(void) {
print("[R]"); print("[R]");
usb_device_state_set_reset(); usb_device_state_set_reset();
usb_device_state_set_protocol(USB_PROTOCOL_REPORT);
} }
/** \brief Event USB Device Connect /** \brief Event USB Device Connect
@ -562,10 +557,10 @@ void EVENT_USB_Device_ControlRequest(void) {
uint8_t report_id = Endpoint_Read_8(); uint8_t report_id = Endpoint_Read_8();
if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) { if (report_id == REPORT_ID_KEYBOARD || report_id == REPORT_ID_NKRO) {
keyboard_led_state = Endpoint_Read_8(); usb_device_state_set_leds(Endpoint_Read_8());
} }
} else { } else {
keyboard_led_state = Endpoint_Read_8(); usb_device_state_set_leds(Endpoint_Read_8());
} }
Endpoint_ClearOUT(); Endpoint_ClearOUT();
@ -582,7 +577,7 @@ void EVENT_USB_Device_ControlRequest(void) {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady())) while (!(Endpoint_IsINReady()))
; ;
Endpoint_Write_8(keyboard_protocol); Endpoint_Write_8(usb_device_state_get_protocol());
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }
@ -595,7 +590,7 @@ void EVENT_USB_Device_ControlRequest(void) {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF); usb_device_state_set_protocol(USB_ControlRequest.wValue & 0xFF);
clear_keyboard(); clear_keyboard();
} }
} }
@ -606,7 +601,7 @@ void EVENT_USB_Device_ControlRequest(void) {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8); usb_device_state_set_idle_rate(USB_ControlRequest.wValue >> 8);
} }
break; break;
@ -615,7 +610,7 @@ void EVENT_USB_Device_ControlRequest(void) {
Endpoint_ClearSETUP(); Endpoint_ClearSETUP();
while (!(Endpoint_IsINReady())) while (!(Endpoint_IsINReady()))
; ;
Endpoint_Write_8(keyboard_idle); Endpoint_Write_8(usb_device_state_get_idle_rate());
Endpoint_ClearIN(); Endpoint_ClearIN();
Endpoint_ClearStatusStage(); Endpoint_ClearStatusStage();
} }
@ -631,13 +626,6 @@ void EVENT_USB_Device_ControlRequest(void) {
/******************************************************************************* /*******************************************************************************
* Host driver * Host driver
******************************************************************************/ ******************************************************************************/
/** \brief Keyboard LEDs
*
* FIXME: Needs doc
*/
static uint8_t keyboard_leds(void) {
return keyboard_led_state;
}
/** \brief Send Keyboard /** \brief Send Keyboard
* *
@ -645,7 +633,7 @@ static uint8_t keyboard_leds(void) {
*/ */
static void send_keyboard(report_keyboard_t *report) { static void send_keyboard(report_keyboard_t *report) {
/* If we're in Boot Protocol, don't send any report ID or other funky fields */ /* If we're in Boot Protocol, don't send any report ID or other funky fields */
if (!keyboard_protocol) { if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
send_report(KEYBOARD_IN_EPNUM, &report->mods, 8); send_report(KEYBOARD_IN_EPNUM, &report->mods, 8);
} else { } else {
send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE); send_report(KEYBOARD_IN_EPNUM, report, KEYBOARD_REPORT_SIZE);

View File

@ -19,6 +19,7 @@
#include "host.h" #include "host.h"
#include "keycode_config.h" #include "keycode_config.h"
#include "debug.h" #include "debug.h"
#include "usb_device_state.h"
#include "util.h" #include "util.h"
#include <string.h> #include <string.h>
@ -31,7 +32,7 @@ uint8_t has_anykey(void) {
uint8_t* p = keyboard_report->keys; uint8_t* p = keyboard_report->keys;
uint8_t lp = sizeof(keyboard_report->keys); uint8_t lp = sizeof(keyboard_report->keys);
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
p = nkro_report->bits; p = nkro_report->bits;
lp = sizeof(nkro_report->bits); lp = sizeof(nkro_report->bits);
} }
@ -48,7 +49,7 @@ uint8_t has_anykey(void) {
*/ */
uint8_t get_first_key(void) { uint8_t get_first_key(void) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
uint8_t i = 0; uint8_t i = 0;
for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++) for (; i < NKRO_REPORT_BITS && !nkro_report->bits[i]; i++)
; ;
@ -68,7 +69,7 @@ bool is_key_pressed(uint8_t key) {
return false; return false;
} }
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
if ((key >> 3) < NKRO_REPORT_BITS) { if ((key >> 3) < NKRO_REPORT_BITS) {
return nkro_report->bits[key >> 3] & 1 << (key & 7); return nkro_report->bits[key >> 3] & 1 << (key & 7);
} else { } else {
@ -150,7 +151,7 @@ void del_key_bit(report_nkro_t* nkro_report, uint8_t code) {
*/ */
void add_key_to_report(uint8_t key) { void add_key_to_report(uint8_t key) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
add_key_bit(nkro_report, key); add_key_bit(nkro_report, key);
return; return;
} }
@ -164,7 +165,7 @@ void add_key_to_report(uint8_t key) {
*/ */
void del_key_from_report(uint8_t key) { void del_key_from_report(uint8_t key) {
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
del_key_bit(nkro_report, key); del_key_bit(nkro_report, key);
return; return;
} }
@ -179,7 +180,7 @@ void del_key_from_report(uint8_t key) {
void clear_keys_from_report(void) { void clear_keys_from_report(void) {
// not clear mods // not clear mods
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) { if (usb_device_state_get_protocol() == USB_PROTOCOL_REPORT && keymap_config.nkro) {
memset(nkro_report->bits, 0, sizeof(nkro_report->bits)); memset(nkro_report->bits, 0, sizeof(nkro_report->bits));
return; return;
} }

View File

@ -24,15 +24,15 @@
# include "os_detection.h" # include "os_detection.h"
#endif #endif
enum usb_device_state usb_device_state = USB_DEVICE_STATE_NO_INIT; static struct usb_device_state usb_device_state = {.idle_rate = 0, .leds = 0, .protocol = USB_PROTOCOL_REPORT, .configure_state = USB_DEVICE_STATE_NO_INIT};
__attribute__((weak)) void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state) { __attribute__((weak)) void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state) {
notify_usb_device_state_change_user(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) {} __attribute__((weak)) void notify_usb_device_state_change_user(struct usb_device_state usb_device_state) {}
static void notify_usb_device_state_change(enum usb_device_state usb_device_state) { static void notify_usb_device_state_change(struct usb_device_state usb_device_state) {
#if defined(HAPTIC_ENABLE) && HAPTIC_OFF_IN_LOW_POWER #if defined(HAPTIC_ENABLE) && HAPTIC_OFF_IN_LOW_POWER
haptic_notify_usb_device_state_change(); haptic_notify_usb_device_state_change();
#endif #endif
@ -44,27 +44,58 @@ static void notify_usb_device_state_change(enum usb_device_state usb_device_stat
#endif #endif
} }
void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber) { void usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number) {
usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; usb_device_state.configure_state = is_configured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
notify_usb_device_state_change(usb_device_state); notify_usb_device_state_change(usb_device_state);
} }
void usb_device_state_set_suspend(bool isConfigured, uint8_t configurationNumber) { void usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number) {
usb_device_state = USB_DEVICE_STATE_SUSPEND; usb_device_state.configure_state = USB_DEVICE_STATE_SUSPEND;
notify_usb_device_state_change(usb_device_state); notify_usb_device_state_change(usb_device_state);
} }
void usb_device_state_set_resume(bool isConfigured, uint8_t configurationNumber) { void usb_device_state_set_resume(bool is_configured, uint8_t configuration_number) {
usb_device_state = isConfigured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT; usb_device_state.configure_state = is_configured ? USB_DEVICE_STATE_CONFIGURED : USB_DEVICE_STATE_INIT;
notify_usb_device_state_change(usb_device_state); notify_usb_device_state_change(usb_device_state);
} }
void usb_device_state_set_reset(void) { void usb_device_state_set_reset(void) {
usb_device_state = USB_DEVICE_STATE_INIT; usb_device_state.configure_state = USB_DEVICE_STATE_INIT;
notify_usb_device_state_change(usb_device_state); notify_usb_device_state_change(usb_device_state);
} }
void usb_device_state_init(void) { void usb_device_state_init(void) {
usb_device_state = USB_DEVICE_STATE_INIT; usb_device_state.configure_state = USB_DEVICE_STATE_INIT;
notify_usb_device_state_change(usb_device_state); notify_usb_device_state_change(usb_device_state);
} }
inline usb_configure_state_t usb_device_state_get_configure_state(void) {
return usb_device_state.configure_state;
}
void usb_device_state_set_protocol(usb_hid_protocol_t protocol) {
usb_device_state.protocol = protocol == USB_PROTOCOL_BOOT ? USB_PROTOCOL_BOOT : USB_PROTOCOL_REPORT;
notify_usb_device_state_change(usb_device_state);
}
inline usb_hid_protocol_t usb_device_state_get_protocol() {
return usb_device_state.protocol;
}
void usb_device_state_set_leds(uint8_t leds) {
usb_device_state.leds = leds;
notify_usb_device_state_change(usb_device_state);
}
inline uint8_t usb_device_state_get_leds(void) {
return usb_device_state.leds;
}
void usb_device_state_set_idle_rate(uint8_t idle_rate) {
usb_device_state.idle_rate = idle_rate;
notify_usb_device_state_change(usb_device_state);
}
inline uint8_t usb_device_state_get_idle_rate(void) {
return usb_device_state.idle_rate;
}

View File

@ -20,20 +20,41 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
void usb_device_state_set_configuration(bool isConfigured, uint8_t configurationNumber); typedef enum {
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_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_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_CONFIGURED = 2, // Can consume up to what is specified in configuration descriptor, typically 500mA
USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current USB_DEVICE_STATE_SUSPEND = 3 // Can consume only suspend current
} usb_configure_state_t;
typedef enum {
USB_PROTOCOL_BOOT = 0,
USB_PROTOCOL_REPORT = 1,
} usb_hid_protocol_t;
// note: we can't typedef this struct to usb_device_state_t because it would
// conflict with the previous definition in:
// lib/chibios-contrib/ext/nxp-middleware-usb/device/usb_device.h
struct usb_device_state {
uint8_t idle_rate;
uint8_t leds;
usb_hid_protocol_t protocol;
usb_configure_state_t configure_state;
}; };
extern enum usb_device_state usb_device_state; void usb_device_state_set_configuration(bool is_configured, uint8_t configuration_number);
void usb_device_state_set_suspend(bool is_configured, uint8_t configuration_number);
void usb_device_state_set_resume(bool is_configured, uint8_t configuration_number);
void usb_device_state_set_reset(void);
void usb_device_state_init(void);
usb_configure_state_t usb_device_state_get_configure_state(void);
void usb_device_state_set_protocol(usb_hid_protocol_t protocol);
usb_hid_protocol_t usb_device_state_get_protocol(void);
void usb_device_state_set_leds(uint8_t leds);
uint8_t usb_device_state_get_leds(void);
void usb_device_state_set_idle_rate(uint8_t idle_rate);
uint8_t usb_device_state_get_idle_rate(void);
void usb_device_state_reset_hid_state(void);
void notify_usb_device_state_change_kb(enum usb_device_state usb_device_state); void notify_usb_device_state_change_kb(struct usb_device_state usb_device_state);
void notify_usb_device_state_change_user(enum usb_device_state usb_device_state); void notify_usb_device_state_change_user(struct usb_device_state usb_device_state);

View File

@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h" #include "debug.h"
#include "wait.h" #include "wait.h"
#include "usb_descriptor_common.h" #include "usb_descriptor_common.h"
#include "usb_device_state.h"
#ifdef RAW_ENABLE #ifdef RAW_ENABLE
# include "raw_hid.h" # include "raw_hid.h"
@ -94,10 +95,6 @@ _Static_assert(TOTAL_INTERFACES <= MAX_INTERFACES, "There are not enough availab
# error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two. # error Mouse/Extra Keys share an endpoint with Console. Please disable one of the two.
#endif #endif
static uint8_t keyboard_led_state = 0;
uint8_t keyboard_idle = 0;
uint8_t keyboard_protocol = 1;
static report_keyboard_t keyboard_report_sent; static report_keyboard_t keyboard_report_sent;
static void send_report_fragment(uint8_t endpoint, void *data, size_t size) { static void send_report_fragment(uint8_t endpoint, void *data, size_t size) {
@ -295,24 +292,19 @@ void console_task(void) {
/*------------------------------------------------------------------* /*------------------------------------------------------------------*
* Host driver * Host driver
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
static uint8_t keyboard_leds(void); static void send_keyboard(report_keyboard_t *report);
static void send_keyboard(report_keyboard_t *report); static void send_nkro(report_nkro_t *report);
static void send_nkro(report_nkro_t *report); static void send_mouse(report_mouse_t *report);
static void send_mouse(report_mouse_t *report); static void send_extra(report_extra_t *report);
static void send_extra(report_extra_t *report);
static host_driver_t driver = {keyboard_leds, send_keyboard, send_nkro, send_mouse, send_extra}; static host_driver_t driver = {.keyboard_leds = usb_device_state_get_leds, .send_keyboard = send_keyboard, .send_nkro = send_nkro, .send_mouse = send_mouse, .send_extra = send_extra};
host_driver_t *vusb_driver(void) { host_driver_t *vusb_driver(void) {
return &driver; return &driver;
} }
static uint8_t keyboard_leds(void) {
return keyboard_led_state;
}
static void send_keyboard(report_keyboard_t *report) { static void send_keyboard(report_keyboard_t *report) {
if (!keyboard_protocol) { if (usb_device_state_get_protocol() == USB_PROTOCOL_BOOT) {
send_report(1, &report->mods, 8); send_report(1, &report->mods, 8);
} else { } else {
send_report(1, report, sizeof(report_keyboard_t)); send_report(1, report, sizeof(report_keyboard_t));
@ -387,11 +379,15 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
break; break;
case USBRQ_HID_GET_IDLE: case USBRQ_HID_GET_IDLE:
dprint("GET_IDLE:"); dprint("GET_IDLE:");
usbMsgPtr = (usbMsgPtr_t)&keyboard_idle; static uint8_t keyboard_idle;
keyboard_idle = usb_device_state_get_idle_rate();
usbMsgPtr = (usbMsgPtr_t)&keyboard_idle;
return 1; return 1;
case USBRQ_HID_GET_PROTOCOL: case USBRQ_HID_GET_PROTOCOL:
dprint("GET_PROTOCOL:"); dprint("GET_PROTOCOL:");
usbMsgPtr = (usbMsgPtr_t)&keyboard_protocol; static uint8_t keyboard_protocol;
keyboard_protocol = usb_device_state_get_protocol();
usbMsgPtr = (usbMsgPtr_t)&keyboard_protocol;
return 1; return 1;
case USBRQ_HID_SET_REPORT: case USBRQ_HID_SET_REPORT:
dprint("SET_REPORT:"); dprint("SET_REPORT:");
@ -403,13 +399,13 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) {
} }
return USB_NO_MSG; // to get data in usbFunctionWrite return USB_NO_MSG; // to get data in usbFunctionWrite
case USBRQ_HID_SET_IDLE: case USBRQ_HID_SET_IDLE:
keyboard_idle = (rq->wValue.word & 0xFF00) >> 8; usb_device_state_set_idle_rate(rq->wValue.word >> 8);
dprintf("SET_IDLE: %02X", keyboard_idle); dprintf("SET_IDLE: %02X", usb_device_state_get_idle_rate());
break; break;
case USBRQ_HID_SET_PROTOCOL: case USBRQ_HID_SET_PROTOCOL:
if (rq->wIndex.word == KEYBOARD_INTERFACE) { if (rq->wIndex.word == KEYBOARD_INTERFACE) {
keyboard_protocol = rq->wValue.word & 0xFF; usb_device_state_set_protocol(rq->wValue.word & 0xFF);
dprintf("SET_PROTOCOL: %02X", keyboard_protocol); dprintf("SET_PROTOCOL: %02X", usb_device_state_get_protocol());
} }
break; break;
default: default:
@ -430,9 +426,9 @@ uchar usbFunctionWrite(uchar *data, uchar len) {
} }
switch (last_req.kind) { switch (last_req.kind) {
case SET_LED: case SET_LED:
dprintf("SET_LED: %02X\n", data[0]); usb_device_state_set_leds(data[0]);
keyboard_led_state = data[0]; dprintf("SET_LED: %02X\n", usb_device_state_get_leds());
last_req.len = 0; last_req.len = 0;
return 1; return 1;
break; break;
case NONE: case NONE: