/ examples / usb_device / usb_device.c
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  }