usb_device.c
1 2 3 #include <stdio.h> 4 #include <string.h> 5 6 #include "hardware/clocks.h" 7 #include "pico/stdlib.h" 8 #include "pico/multicore.h" 9 #include "pico/bootrom.h" 10 11 #include "pio_usb.h" 12 13 // Use tinyUSB header to define USB descriptors 14 #include "device/usbd.h" 15 #include "class/hid/hid_device.h" 16 17 static usb_device_t *usb_device = NULL; 18 19 tusb_desc_device_t const desc_device = {.bLength = sizeof(tusb_desc_device_t), 20 .bDescriptorType = TUSB_DESC_DEVICE, 21 .bcdUSB = 0x0110, 22 .bDeviceClass = 0x00, 23 .bDeviceSubClass = 0x00, 24 .bDeviceProtocol = 0x00, 25 .bMaxPacketSize0 = 64, 26 27 .idVendor = 0xCafe, 28 .idProduct = 0, 29 .bcdDevice = 0x0100, 30 31 .iManufacturer = 0x01, 32 .iProduct = 0x02, 33 .iSerialNumber = 0x03, 34 35 .bNumConfigurations = 0x01}; 36 37 enum { 38 ITF_NUM_KEYBOARD, 39 ITF_NUM_MOUSE, 40 ITF_NUM_TOTAL, 41 }; 42 43 enum { 44 EPNUM_KEYBOARD = 0x81, 45 EPNUM_MOUSE = 0x82, 46 }; 47 48 49 uint8_t const desc_hid_keyboard_report[] = 50 { 51 TUD_HID_REPORT_DESC_KEYBOARD() 52 }; 53 54 uint8_t const desc_hid_mouse_report[] = 55 { 56 TUD_HID_REPORT_DESC_MOUSE() 57 }; 58 59 const uint8_t *report_desc[] = {desc_hid_keyboard_report, 60 desc_hid_mouse_report}; 61 62 #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + 2*TUD_HID_DESC_LEN) 63 uint8_t const desc_configuration[] = { 64 TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 65 TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), 66 TUD_HID_DESCRIPTOR(ITF_NUM_KEYBOARD, 0, HID_ITF_PROTOCOL_KEYBOARD, 67 sizeof(desc_hid_keyboard_report), EPNUM_KEYBOARD, 68 CFG_TUD_HID_EP_BUFSIZE, 10), 69 TUD_HID_DESCRIPTOR(ITF_NUM_MOUSE, 0, HID_ITF_PROTOCOL_MOUSE, 70 sizeof(desc_hid_mouse_report), EPNUM_MOUSE, 71 CFG_TUD_HID_EP_BUFSIZE, 10), 72 }; 73 74 static_assert(sizeof(desc_device) == 18, "device desc size error"); 75 76 const char *string_descriptors_base[] = { 77 [0] = (const char[]){0x09, 0x04}, 78 [1] = "Pico PIO USB", 79 [2] = "Pico PIO USB Device", 80 [3] = "123456", 81 }; 82 static string_descriptor_t str_desc[4]; 83 84 static void init_string_desc(void) { 85 for (int idx = 0; idx < 4; idx++) { 86 uint8_t len = 0; 87 uint16_t *wchar_str = (uint16_t *)&str_desc[idx]; 88 if (idx == 0) { 89 wchar_str[1] = string_descriptors_base[0][0] | 90 ((uint16_t)string_descriptors_base[0][1] << 8); 91 len = 1; 92 } else if (idx <= 3) { 93 len = strnlen(string_descriptors_base[idx], 31); 94 for (int i = 0; i < len; i++) { 95 wchar_str[i + 1] = string_descriptors_base[idx][i]; 96 } 97 98 } else { 99 len = 0; 100 } 101 102 wchar_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2); 103 } 104 } 105 106 static usb_descriptor_buffers_t desc = { 107 .device = (uint8_t *)&desc_device, 108 .config = desc_configuration, 109 .hid_report = report_desc, 110 .string = str_desc 111 }; 112 113 114 void core1_main() { 115 sleep_ms(10); 116 117 static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; 118 init_string_desc(); 119 usb_device = pio_usb_device_init(&config, &desc); 120 121 while (true) { 122 pio_usb_device_task(); 123 } 124 } 125 126 int main() { 127 // default 125MHz is not appropreate. Sysclock should be multiple of 12MHz. 128 set_sys_clock_khz(120000, true); 129 130 stdio_init_all(); 131 printf("hello!"); 132 133 sleep_ms(10); 134 135 multicore_reset_core1(); 136 // all USB task run in core1 137 multicore_launch_core1(core1_main); 138 139 // move mouse pointer every 0.5s 140 while (true) { 141 if (usb_device != NULL) { 142 hid_mouse_report_t mouse_report = {0}; 143 mouse_report.x = 1; 144 endpoint_t *ep = pio_usb_get_endpoint(usb_device, 2); 145 pio_usb_set_out_data(ep, (uint8_t *)&mouse_report, sizeof(mouse_report)); 146 } 147 sleep_ms(500); 148 } 149 }