forked from mirrors/qmk_userspace
		
	V-USB: Add generic send_report() function (#22323)
		
	This commit is contained in:
		
					parent
					
						
							
								3a74fa5bf7
							
						
					
				
			
			
				commit
				
					
						cbf538aaaa
					
				
			
		
					 3 changed files with 53 additions and 92 deletions
				
			
		| 
						 | 
					@ -153,7 +153,6 @@ void protocol_task(void) {
 | 
				
			||||||
        if (usbConfiguration && usbInterruptIsReady()) {
 | 
					        if (usbConfiguration && usbInterruptIsReady()) {
 | 
				
			||||||
            keyboard_task();
 | 
					            keyboard_task();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        vusb_transfer_keyboard();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef RAW_ENABLE
 | 
					#ifdef RAW_ENABLE
 | 
				
			||||||
        usbPoll();
 | 
					        usbPoll();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -89,40 +89,51 @@ static uint8_t keyboard_led_state = 0;
 | 
				
			||||||
uint8_t        keyboard_idle      = 0;
 | 
					uint8_t        keyboard_idle      = 0;
 | 
				
			||||||
uint8_t        keyboard_protocol  = 1;
 | 
					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;
 | 
					static report_keyboard_t keyboard_report_sent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VUSB_TRANSFER_KEYBOARD_MAX_TRIES 10
 | 
					static void send_report_fragment(uint8_t endpoint, void *data, size_t size) {
 | 
				
			||||||
 | 
					    for (uint8_t retries = 5; retries > 0; retries--) {
 | 
				
			||||||
/* transfer keyboard report from buffer */
 | 
					        switch (endpoint) {
 | 
				
			||||||
void vusb_transfer_keyboard(void) {
 | 
					            case 1:
 | 
				
			||||||
    for (int i = 0; i < VUSB_TRANSFER_KEYBOARD_MAX_TRIES; i++) {
 | 
					                if (usbInterruptIsReady()) {
 | 
				
			||||||
        if (usbInterruptIsReady()) {
 | 
					                    usbSetInterrupt(data, size);
 | 
				
			||||||
            if (kbuf_head != kbuf_tail) {
 | 
					                    return;
 | 
				
			||||||
#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();
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                usbSetInterrupt((void *)(&(kbuf[kbuf_tail].keys[5])), 1);
 | 
					                break;
 | 
				
			||||||
#endif
 | 
					            case USB_CFG_EP3_NUMBER:
 | 
				
			||||||
                kbuf_tail = (kbuf_tail + 1) % KBUF_SIZE;
 | 
					                if (usbInterruptIsReady3()) {
 | 
				
			||||||
                if (debug_keyboard) {
 | 
					                    usbSetInterrupt3(data, size);
 | 
				
			||||||
                    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));
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					                break;
 | 
				
			||||||
            break;
 | 
					            case USB_CFG_EP4_NUMBER:
 | 
				
			||||||
 | 
					                if (usbInterruptIsReady4()) {
 | 
				
			||||||
 | 
					                    usbSetInterrupt4(data, size);
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        usbPoll();
 | 
					        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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,18 +152,7 @@ void raw_hid_send(uint8_t *data, uint8_t length) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    uint8_t *temp = data;
 | 
					    send_report(4, data, 32);
 | 
				
			||||||
    for (uint8_t i = 0; i < 4; i++) {
 | 
					 | 
				
			||||||
        while (!usbInterruptIsReady4()) {
 | 
					 | 
				
			||||||
            usbPoll();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        usbSetInterrupt4(temp, 8);
 | 
					 | 
				
			||||||
        temp += 8;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    while (!usbInterruptIsReady4()) {
 | 
					 | 
				
			||||||
        usbPoll();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    usbSetInterrupt4(0, 0);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
 | 
					__attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) {
 | 
				
			||||||
| 
						 | 
					@ -181,19 +181,6 @@ int8_t sendchar(uint8_t c) {
 | 
				
			||||||
    return 0;
 | 
					    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) {
 | 
					void console_task(void) {
 | 
				
			||||||
    if (!usbConfiguration) {
 | 
					    if (!usbConfiguration) {
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -210,16 +197,7 @@ void console_task(void) {
 | 
				
			||||||
        send_buf[send_buf_count++] = rbuf_dequeue();
 | 
					        send_buf[send_buf_count++] = rbuf_dequeue();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *temp = send_buf;
 | 
					    send_report(3, send_buf, CONSOLE_BUFFER_SIZE);
 | 
				
			||||||
    for (uint8_t i = 0; i < 4; i++) {
 | 
					 | 
				
			||||||
        if (!usbSendData3(temp, 8)) {
 | 
					 | 
				
			||||||
            break;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        temp += 8;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    usbSendData3(0, 0);
 | 
					 | 
				
			||||||
    usbPoll();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -243,17 +221,12 @@ static uint8_t keyboard_leds(void) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void send_keyboard(report_keyboard_t *report) {
 | 
					static void send_keyboard(report_keyboard_t *report) {
 | 
				
			||||||
    uint8_t next = (kbuf_head + 1) % KBUF_SIZE;
 | 
					    if (!keyboard_protocol) {
 | 
				
			||||||
    if (next != kbuf_tail) {
 | 
					        send_report(1, &report->mods, 8);
 | 
				
			||||||
        kbuf[kbuf_head] = *report;
 | 
					 | 
				
			||||||
        kbuf_head       = next;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } 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;
 | 
					    keyboard_report_sent = *report;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,50 +235,40 @@ static void send_nkro(report_nkro_t *report) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef KEYBOARD_SHARED_EP
 | 
					#ifndef KEYBOARD_SHARED_EP
 | 
				
			||||||
#    define usbInterruptIsReadyShared usbInterruptIsReady3
 | 
					#    define MOUSE_IN_EPNUM 3
 | 
				
			||||||
#    define usbSetInterruptShared usbSetInterrupt3
 | 
					#    define SHARED_IN_EPNUM 3
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#    define usbInterruptIsReadyShared usbInterruptIsReady
 | 
					#    define MOUSE_IN_EPNUM 1
 | 
				
			||||||
#    define usbSetInterruptShared usbSetInterrupt
 | 
					#    define SHARED_IN_EPNUM 1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void send_mouse(report_mouse_t *report) {
 | 
					static void send_mouse(report_mouse_t *report) {
 | 
				
			||||||
#ifdef MOUSE_ENABLE
 | 
					#ifdef MOUSE_ENABLE
 | 
				
			||||||
    if (usbInterruptIsReadyShared()) {
 | 
					    send_report(MOUSE_IN_EPNUM, report, sizeof(report_mouse_t));
 | 
				
			||||||
        usbSetInterruptShared((void *)report, sizeof(report_mouse_t));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void send_extra(report_extra_t *report) {
 | 
					static void send_extra(report_extra_t *report) {
 | 
				
			||||||
#ifdef EXTRAKEY_ENABLE
 | 
					#ifdef EXTRAKEY_ENABLE
 | 
				
			||||||
    if (usbInterruptIsReadyShared()) {
 | 
					    send_report(SHARED_IN_EPNUM, report, sizeof(report_extra_t));
 | 
				
			||||||
        usbSetInterruptShared((void *)report, sizeof(report_extra_t));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void send_joystick(report_joystick_t *report) {
 | 
					void send_joystick(report_joystick_t *report) {
 | 
				
			||||||
#ifdef JOYSTICK_ENABLE
 | 
					#ifdef JOYSTICK_ENABLE
 | 
				
			||||||
    if (usbInterruptIsReadyShared()) {
 | 
					    send_report(SHARED_IN_EPNUM, report, sizeof(report_joystick_t));
 | 
				
			||||||
        usbSetInterruptShared((void *)report, sizeof(report_joystick_t));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void send_digitizer(report_digitizer_t *report) {
 | 
					void send_digitizer(report_digitizer_t *report) {
 | 
				
			||||||
#ifdef DIGITIZER_ENABLE
 | 
					#ifdef DIGITIZER_ENABLE
 | 
				
			||||||
    if (usbInterruptIsReadyShared()) {
 | 
					    send_report(SHARED_IN_EPNUM, report, sizeof(report_digitizer_t));
 | 
				
			||||||
        usbSetInterruptShared((void *)report, sizeof(report_digitizer_t));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void send_programmable_button(report_programmable_button_t *report) {
 | 
					void send_programmable_button(report_programmable_button_t *report) {
 | 
				
			||||||
#ifdef PROGRAMMABLE_BUTTON_ENABLE
 | 
					#ifdef PROGRAMMABLE_BUTTON_ENABLE
 | 
				
			||||||
    if (usbInterruptIsReadyShared()) {
 | 
					    send_report(SHARED_IN_EPNUM, report, sizeof(report_programmable_button_t));
 | 
				
			||||||
        usbSetInterruptShared((void *)report, sizeof(report_programmable_button_t));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -121,4 +121,3 @@ typedef struct usbConfigurationDescriptor {
 | 
				
			||||||
extern bool vusb_suspended;
 | 
					extern bool vusb_suspended;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
host_driver_t *vusb_driver(void);
 | 
					host_driver_t *vusb_driver(void);
 | 
				
			||||||
void           vusb_transfer_keyboard(void);
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue