add hid_raw feature to VUSB (#8380)
* rewrite usbhid feature on vusb * Apply suggestions from code review Co-Authored-By: Ryan <fauxpark@gmail.com> * fix typo * fix typo again * Update tmk_core/protocol/vusb/vusb.c Co-Authored-By: Ryan <fauxpark@gmail.com> * clean up defines Co-authored-by: Ryan <fauxpark@gmail.com>
This commit is contained in:
		
							parent
							
								
									b892a1429d
								
							
						
					
					
						commit
						89a675d57c
					
				
					 3 changed files with 174 additions and 1 deletions
				
			
		|  | @ -28,6 +28,14 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>. | |||
| #include "vusb.h" | ||||
| #include <util/delay.h> | ||||
| 
 | ||||
| #if defined(RAW_ENABLE) | ||||
| #    include "raw_hid.h" | ||||
| #endif | ||||
| 
 | ||||
| #if (defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)) && defined(RAW_ENABLE) | ||||
| #    error "Enabling Mousekeys/Extrakeys and Raw HID at the same time is not currently supported on V-USB." | ||||
| #endif | ||||
| 
 | ||||
| static uint8_t vusb_keyboard_leds = 0; | ||||
| static uint8_t vusb_idle_rate     = 0; | ||||
| 
 | ||||
|  | @ -71,6 +79,52 @@ void vusb_transfer_keyboard(void) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /*------------------------------------------------------------------*
 | ||||
|  * RAW HID | ||||
|  *------------------------------------------------------------------*/ | ||||
| #ifdef RAW_ENABLE | ||||
| #    define RAW_BUFFER_SIZE 32 | ||||
| #    define RAW_EPSIZE 8 | ||||
| 
 | ||||
| static uint8_t raw_output_buffer[RAW_BUFFER_SIZE]; | ||||
| static uint8_t raw_output_received_bytes = 0; | ||||
| 
 | ||||
| void raw_hid_send(uint8_t *data, uint8_t length) { | ||||
|     if (length != RAW_BUFFER_SIZE) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     uint8_t *temp = data; | ||||
|     for (uint8_t i = 0; i < 4; i++) { | ||||
|         while (!usbInterruptIsReady3()) { | ||||
|             usbPoll(); | ||||
|         } | ||||
|         usbSetInterrupt3(temp, 8); | ||||
|         temp += 8; | ||||
|     } | ||||
|     while (!usbInterruptIsReady3()) { | ||||
|         usbPoll(); | ||||
|     } | ||||
|     usbSetInterrupt3(0, 0); | ||||
|     usbPoll(); | ||||
|     _delay_ms(1); | ||||
| } | ||||
| 
 | ||||
| __attribute__((weak)) void raw_hid_receive(uint8_t *data, uint8_t length) { | ||||
|     // Users should #include "raw_hid.h" in their own code
 | ||||
|     // and implement this function there. Leave this as weak linkage
 | ||||
|     // so users can opt to not handle data coming in.
 | ||||
| } | ||||
| 
 | ||||
| void raw_hid_task(void) { | ||||
|     if (raw_output_received_bytes == RAW_BUFFER_SIZE) { | ||||
|         raw_hid_receive(raw_output_buffer, RAW_BUFFER_SIZE); | ||||
|         raw_output_received_bytes = 0; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| /*------------------------------------------------------------------*
 | ||||
|  * Host driver | ||||
|  *------------------------------------------------------------------*/ | ||||
|  | @ -206,6 +260,27 @@ uchar usbFunctionWrite(uchar *data, uchar len) { | |||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| void usbFunctionWriteOut(uchar *data, uchar len) { | ||||
| #ifdef RAW_ENABLE | ||||
|     // Data from host must be divided every 8bytes
 | ||||
|     if (len != 8) { | ||||
|         debug("RAW: invalid length"); | ||||
|         raw_output_received_bytes = 0; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (raw_output_received_bytes + len > RAW_BUFFER_SIZE) { | ||||
|         debug("RAW: buffer full"); | ||||
|         raw_output_received_bytes = 0; | ||||
|     } else { | ||||
|         for (uint8_t i = 0; i < 8; i++) { | ||||
|             raw_output_buffer[raw_output_received_bytes + i] = data[i]; | ||||
|         } | ||||
|         raw_output_received_bytes += len; | ||||
|     } | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /*------------------------------------------------------------------*
 | ||||
|  * Descriptors                                                      * | ||||
|  *------------------------------------------------------------------*/ | ||||
|  | @ -335,6 +410,29 @@ const PROGMEM uchar mouse_extra_hid_report[] = { | |||
| }; | ||||
| #endif | ||||
| 
 | ||||
| #if defined(RAW_ENABLE) | ||||
| const PROGMEM uchar raw_hid_report[] = { | ||||
|     0x06, 0x60, 0xFF,  // Usage Page (Vendor Defined)
 | ||||
|     0x09, 0x61,        // Usage (Vendor Defined)
 | ||||
|     0xA1, 0x01,        // Collection (Application)
 | ||||
|     // Data to host
 | ||||
|     0x09, 0x62,             //   Usage (Vendor Defined)
 | ||||
|     0x15, 0x00,             //   Logical Minimum (0)
 | ||||
|     0x26, 0xFF, 0x00,       //   Logical Maximum (255)
 | ||||
|     0x95, RAW_BUFFER_SIZE,  //   Report Count
 | ||||
|     0x75, 0x08,             //   Report Size (8)
 | ||||
|     0x81, 0x02,             //   Input (Data, Variable, Absolute)
 | ||||
|     // Data from host
 | ||||
|     0x09, 0x63,             //   Usage (Vendor Defined)
 | ||||
|     0x15, 0x00,             //   Logical Minimum (0)
 | ||||
|     0x26, 0xFF, 0x00,       //   Logical Maximum (255)
 | ||||
|     0x95, RAW_BUFFER_SIZE,  //   Report Count
 | ||||
|     0x75, 0x08,             //   Report Size (8)
 | ||||
|     0x91, 0x02,             //   Output (Data, Variable, Absolute)
 | ||||
|     0xC0,                   // End Collection
 | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| #ifndef SERIAL_NUMBER | ||||
| #    define SERIAL_NUMBER 0 | ||||
| #endif | ||||
|  | @ -416,7 +514,7 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = { | |||
|             .bDescriptorType = USBDESCR_CONFIG | ||||
|         }, | ||||
|         .wTotalLength        = sizeof(usbConfigurationDescriptor_t), | ||||
| #    if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) | ||||
| #    if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE) || defined(RAW_ENABLE) | ||||
|         .bNumInterfaces      = 2, | ||||
| #    else | ||||
|         .bNumInterfaces      = 1, | ||||
|  | @ -511,6 +609,53 @@ const PROGMEM usbConfigurationDescriptor_t usbConfigurationDescriptor = { | |||
|         .bInterval           = USB_POLLING_INTERVAL_MS | ||||
|     } | ||||
| #        endif | ||||
| #    elif defined(RAW_ENABLE) | ||||
|     .rawInterface = { | ||||
|         .header = { | ||||
|             .bLength         = sizeof(usbInterfaceDescriptor_t), | ||||
|             .bDescriptorType = USBDESCR_INTERFACE | ||||
|         }, | ||||
|         .bInterfaceNumber    = 1, | ||||
|         .bAlternateSetting   = 0x00, | ||||
|         .bNumEndpoints       = 2, | ||||
|         .bInterfaceClass     = 0x03, | ||||
|         .bInterfaceSubClass  = 0x00, | ||||
|         .bInterfaceProtocol  = 0x00, | ||||
|         .iInterface          = 0x00 | ||||
|     }, | ||||
|     .rawHID = { | ||||
|         .header = { | ||||
|             .bLength         = sizeof(usbHIDDescriptor_t), | ||||
|             .bDescriptorType = USBDESCR_HID | ||||
|         }, | ||||
|         .bcdHID              = 0x0101, | ||||
|         .bCountryCode        = 0x00, | ||||
|         .bNumDescriptors     = 2, | ||||
|         .bDescriptorType     = USBDESCR_HID_REPORT, | ||||
|         .wDescriptorLength   = sizeof(raw_hid_report) | ||||
|     }, | ||||
| #        if USB_CFG_HAVE_INTRIN_ENDPOINT3 | ||||
|     .rawINEndpoint = { | ||||
|         .header = { | ||||
|             .bLength         = sizeof(usbEndpointDescriptor_t), | ||||
|             .bDescriptorType = USBDESCR_ENDPOINT | ||||
|         }, | ||||
|         .bEndpointAddress    = (USBRQ_DIR_DEVICE_TO_HOST | USB_CFG_EP3_NUMBER), | ||||
|         .bmAttributes        = 0x03, | ||||
|         .wMaxPacketSize      = RAW_EPSIZE, | ||||
|         .bInterval           = USB_POLLING_INTERVAL_MS | ||||
|     }, | ||||
|     .rawOUTEndpoint = { | ||||
|         .header = { | ||||
|             .bLength         = sizeof(usbEndpointDescriptor_t), | ||||
|             .bDescriptorType = USBDESCR_ENDPOINT | ||||
|         }, | ||||
|         .bEndpointAddress    = (USBRQ_DIR_HOST_TO_DEVICE | USB_CFG_EP3_NUMBER), | ||||
|         .bmAttributes        = 0x03, | ||||
|         .wMaxPacketSize      = RAW_EPSIZE, | ||||
|         .bInterval           = USB_POLLING_INTERVAL_MS | ||||
|     } | ||||
| #        endif | ||||
| #    endif | ||||
| }; | ||||
| #endif | ||||
|  | @ -572,6 +717,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { | |||
|                     usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.mouseExtraHID; | ||||
|                     len       = sizeof(usbHIDDescriptor_t); | ||||
|                     break; | ||||
| #elif defined(RAW_ENABLE) | ||||
|                 case 1: | ||||
|                     usbMsgPtr = (unsigned char *)&usbConfigurationDescriptor.rawHID; | ||||
|                     len       = sizeof(usbHIDDescriptor_t); | ||||
|                     break; | ||||
| #endif | ||||
|             } | ||||
|             break; | ||||
|  | @ -587,6 +737,11 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) { | |||
|                     usbMsgPtr = (unsigned char *)mouse_extra_hid_report; | ||||
|                     len       = sizeof(mouse_extra_hid_report); | ||||
|                     break; | ||||
| #elif defined(RAW_ENABLE) | ||||
|                 case 1: | ||||
|                     usbMsgPtr = (unsigned char *)raw_hid_report; | ||||
|                     len       = sizeof(raw_hid_report); | ||||
|                     break; | ||||
| #endif | ||||
|             } | ||||
|             break; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Takuya Urakawa
						Takuya Urakawa