mirror of
https://github.com/qmk/qmk_firmware.git
synced 2026-10-01 14:29:08 +02:00
Merge remote-tracking branch 'origin/develop' into xap
This commit is contained in:
@@ -157,7 +157,6 @@ void protocol_task(void) {
|
||||
if (usbConfiguration && usbInterruptIsReady()) {
|
||||
keyboard_task();
|
||||
}
|
||||
vusb_transfer_keyboard();
|
||||
|
||||
#ifdef RAW_ENABLE
|
||||
usbPoll();
|
||||
|
||||
+99
-106
@@ -98,40 +98,51 @@ static uint8_t keyboard_led_state = 0;
|
||||
uint8_t keyboard_idle = 0;
|
||||
uint8_t keyboard_protocol = 1;
|
||||
|
||||
/* Keyboard report send buffer */
|
||||
#define KBUF_SIZE 16
|
||||
static report_keyboard_t kbuf[KBUF_SIZE];
|
||||
static uint8_t kbuf_head = 0;
|
||||
static uint8_t kbuf_tail = 0;
|
||||
|
||||
static report_keyboard_t keyboard_report_sent;
|
||||
|
||||
#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10
|
||||
|
||||
/* transfer keyboard report from buffer */
|
||||
void vusb_transfer_keyboard(void) {
|
||||
for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) {
|
||||
if (usbInterruptIsReady()) {
|
||||
if (kbuf_head != kbuf_tail) {
|
||||
#ifndef KEYBOARD_SHARED_EP
|
||||
usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t));
|
||||
#else
|
||||
// Ugly hack! :(
|
||||
usbSetInterrupt((void *)&kbuf[kbuf_tail], sizeof(report_keyboard_t) - 1);
|
||||
while (!usbInterruptIsReady()) {
|
||||
usbPoll();
|
||||
static void send_report_fragment(uint8_t endpoint, void *data, size_t size) {
|
||||
for (uint8_t retries = 5; retries > 0; retries--) {
|
||||
switch (endpoint) {
|
||||
case 1:
|
||||
if (usbInterruptIsReady()) {
|
||||
usbSetInterrupt(data, size);
|
||||
return;
|
||||
}
|
||||
usbSetInterrupt((void *)(&(kbuf[kbuf_tail].keys[5])), 1);
|
||||
#endif
|
||||
kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
|
||||
if (debug_keyboard) {
|
||||
dprintf("V-USB: kbuf[%d->%d](%02X)\n", kbuf_tail, kbuf_head, (kbuf_head < kbuf_tail) ? (KBUF_SIZE - kbuf_tail + kbuf_head) : (kbuf_head - kbuf_tail));
|
||||
break;
|
||||
case USB_CFG_EP3_NUMBER:
|
||||
if (usbInterruptIsReady3()) {
|
||||
usbSetInterrupt3(data, size);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case USB_CFG_EP4_NUMBER:
|
||||
if (usbInterruptIsReady4()) {
|
||||
usbSetInterrupt4(data, size);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
usbPoll();
|
||||
wait_ms(1);
|
||||
wait_ms(5);
|
||||
}
|
||||
}
|
||||
|
||||
static void send_report(uint8_t endpoint, void *report, size_t size) {
|
||||
uint8_t *temp = (uint8_t *)report;
|
||||
|
||||
// Send as many full packets as possible
|
||||
for (uint8_t i = 0; i < size / 8; i++) {
|
||||
send_report_fragment(endpoint, temp, 8);
|
||||
temp += 8;
|
||||
}
|
||||
|
||||
// Send any data left over
|
||||
uint8_t remainder = size % 8;
|
||||
if (remainder) {
|
||||
send_report_fragment(endpoint, temp, remainder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,18 +161,7 @@ void raw_hid_send(uint8_t *data, uint8_t length) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *temp = data;
|
||||
for (uint8_t i = 0; i < (RAW_BUFFER_SIZE / RAW_EPSIZE); i++) {
|
||||
while (!usbInterruptIsReady4()) {
|
||||
usbPoll();
|
||||
}
|
||||
usbSetInterrupt4(temp, 8);
|
||||
temp += 8;
|
||||
}
|
||||
while (!usbInterruptIsReady4()) {
|
||||
usbPoll();
|
||||
}
|
||||
usbSetInterrupt4(0, 0);
|
||||
send_report(4, data, RAW_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
|
||||
@@ -195,18 +195,7 @@ void xap_send_base(uint8_t *data, uint8_t length) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *temp = data;
|
||||
for (uint8_t i = 0; i < (XAP_BUFFER_SIZE / XAP_EPSIZE); i++) {
|
||||
while (!usbInterruptIsReady4()) {
|
||||
usbPoll();
|
||||
}
|
||||
usbSetInterrupt4(temp, 8);
|
||||
temp += 8;
|
||||
}
|
||||
while (!usbInterruptIsReady4()) {
|
||||
usbPoll();
|
||||
}
|
||||
usbSetInterrupt4(0, 0);
|
||||
send_report(4, data, XAP_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void xap_send(xap_token_t token, xap_response_flags_t response_flags, const void *data, size_t length) {
|
||||
@@ -269,19 +258,6 @@ int8_t sendchar(uint8_t c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool usbSendData3(char *data, uint8_t len) {
|
||||
uint8_t retries = 5;
|
||||
while (!usbInterruptIsReady3()) {
|
||||
if (!(retries--)) {
|
||||
return false;
|
||||
}
|
||||
usbPoll();
|
||||
}
|
||||
|
||||
usbSetInterrupt3((unsigned char *)data, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
void console_task(void) {
|
||||
if (!usbConfiguration) {
|
||||
return;
|
||||
@@ -298,16 +274,7 @@ void console_task(void) {
|
||||
send_buf[send_buf_count++] = rbuf_dequeue();
|
||||
}
|
||||
|
||||
char *temp = send_buf;
|
||||
for (uint8_t i = 0; i < 4; i++) {
|
||||
if (!usbSendData3(temp, 8)) {
|
||||
break;
|
||||
}
|
||||
temp += 8;
|
||||
}
|
||||
|
||||
usbSendData3(0, 0);
|
||||
usbPoll();
|
||||
send_report(3, send_buf, CONSOLE_BUFFER_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -331,69 +298,56 @@ static uint8_t keyboard_leds(void) {
|
||||
}
|
||||
|
||||
static void send_keyboard(report_keyboard_t *report) {
|
||||
uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
|
||||
if (next != kbuf_tail) {
|
||||
kbuf[kbuf_head] = *report;
|
||||
kbuf_head = next;
|
||||
if (!keyboard_protocol) {
|
||||
send_report(1, &report->mods, 8);
|
||||
} else {
|
||||
dprint("kbuf: full\n");
|
||||
send_report(1, report, sizeof(report_keyboard_t));
|
||||
}
|
||||
|
||||
// NOTE: send key strokes of Macro
|
||||
usbPoll();
|
||||
vusb_transfer_keyboard();
|
||||
keyboard_report_sent = *report;
|
||||
}
|
||||
|
||||
static void send_nkro(report_nkro_t *report) {
|
||||
// TODO: Implement NKRO
|
||||
}
|
||||
|
||||
#ifndef KEYBOARD_SHARED_EP
|
||||
# define usbInterruptIsReadyShared usbInterruptIsReady3
|
||||
# define usbSetInterruptShared usbSetInterrupt3
|
||||
# define MOUSE_IN_EPNUM 3
|
||||
# define SHARED_IN_EPNUM 3
|
||||
#else
|
||||
# define usbInterruptIsReadyShared usbInterruptIsReady
|
||||
# define usbSetInterruptShared usbSetInterrupt
|
||||
# define MOUSE_IN_EPNUM 1
|
||||
# define SHARED_IN_EPNUM 1
|
||||
#endif
|
||||
|
||||
static void send_nkro(report_nkro_t *report) {
|
||||
#ifdef NKRO_ENABLE
|
||||
send_report(3, report, sizeof(report_nkro_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void send_mouse(report_mouse_t *report) {
|
||||
#ifdef MOUSE_ENABLE
|
||||
if (usbInterruptIsReadyShared()) {
|
||||
usbSetInterruptShared((void *)report, sizeof(report_mouse_t));
|
||||
}
|
||||
send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void send_extra(report_extra_t *report) {
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
if (usbInterruptIsReadyShared()) {
|
||||
usbSetInterruptShared((void *)report, sizeof(report_extra_t));
|
||||
}
|
||||
send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
void send_joystick(report_joystick_t *report) {
|
||||
#ifdef JOYSTICK_ENABLE
|
||||
if (usbInterruptIsReadyShared()) {
|
||||
usbSetInterruptShared((void *)report, sizeof(report_joystick_t));
|
||||
}
|
||||
send_report(SHARED_IN_EPNUM, report, sizeof(report_joystick_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
void send_digitizer(report_digitizer_t *report) {
|
||||
#ifdef DIGITIZER_ENABLE
|
||||
if (usbInterruptIsReadyShared()) {
|
||||
usbSetInterruptShared((void *)report, sizeof(report_digitizer_t));
|
||||
}
|
||||
send_report(SHARED_IN_EPNUM, report, sizeof(report_digitizer_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
void send_programmable_button(report_programmable_button_t *report) {
|
||||
#ifdef PROGRAMMABLE_BUTTON_ENABLE
|
||||
if (usbInterruptIsReadyShared()) {
|
||||
usbSetInterruptShared((void *)report, sizeof(report_programmable_button_t));
|
||||
}
|
||||
send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -576,6 +530,45 @@ const PROGMEM uchar shared_hid_report[] = {
|
||||
# define SHARED_REPORT_STARTED
|
||||
#endif
|
||||
|
||||
#ifdef NKRO_ENABLE
|
||||
// NKRO report descriptor
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x06, // Usage (Keyboard)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, REPORT_ID_NKRO, // Report ID
|
||||
// Modifiers (8 bits)
|
||||
0x05, 0x07, // Usage Page (Keyboard/Keypad)
|
||||
0x19, 0xE0, // Usage Minimum (Keyboard Left Control)
|
||||
0x29, 0xE7, // Usage Maximum (Keyboard Right GUI)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, 0x08, // Report Count (8)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||
// Keycodes
|
||||
0x05, 0x07, // Usage Page (Keyboard/Keypad)
|
||||
0x19, 0x00, // Usage Minimum (0)
|
||||
0x29, NKRO_REPORT_BITS * 8 - 1, // Usage Maximum
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, NKRO_REPORT_BITS * 8, // Report Count
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||
|
||||
// Status LEDs (5 bits)
|
||||
0x05, 0x08, // Usage Page (LED)
|
||||
0x19, 0x01, // Usage Minimum (Num Lock)
|
||||
0x29, 0x05, // Usage Maximum (Kana)
|
||||
0x95, 0x05, // Report Count (5)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x91, 0x02, // Output (Data, Variable, Absolute)
|
||||
// LED padding (3 bits)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x03, // Report Size (3)
|
||||
0x91, 0x03, // Output (Constant)
|
||||
0xC0, // End Collection
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_ENABLE
|
||||
// Mouse report descriptor
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
|
||||
@@ -128,4 +128,3 @@ typedef struct usbConfigurationDescriptor {
|
||||
extern bool vusb_suspended;
|
||||
|
||||
host_driver_t *vusb_driver(void);
|
||||
void vusb_transfer_keyboard(void);
|
||||
|
||||
Reference in New Issue
Block a user