diff --git a/class/audio/usbd_audio.c b/class/audio/usbd_audio.c index e48fd354..b2513cf0 100644 --- a/class/audio/usbd_audio.c +++ b/class/audio/usbd_audio.c @@ -17,7 +17,14 @@ int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, memcpy(&audio_control_info.mute, *data, *len); } else if (setup->wValueH == AUDIO_FU_CONTROL_VOLUME) { memcpy(&audio_control_info.vol_current, *data, *len); - USBD_LOG_DBG("vol:0x%x\r\n", audio_control_info.vol_current); + uint32_t vol; + if (audio_control_info.vol_current == 0) { + vol = 100; + } else { + vol = (audio_control_info.vol_current - 0xDB00 + 1) * 100 / (0xFFFF - 0xDB00); + } + usbd_audio_set_volume(vol); + USBD_LOG_WRN("vol:%d\r\n", vol); } } @@ -78,7 +85,9 @@ void audio_notify_handler(uint8_t event, void *arg) break; } } - +__weak void usbd_audio_set_volume(uint8_t vol) +{ +} void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf) { static usbd_class_t *last_class = NULL; diff --git a/class/audio/usbd_audio.h b/class/audio/usbd_audio.h index 6ce0dc87..35f3fe25 100644 --- a/class/audio/usbd_audio.h +++ b/class/audio/usbd_audio.h @@ -269,7 +269,7 @@ struct usbd_audio_control_info { void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf); void usbd_audio_set_interface_callback(uint8_t value); - +void usbd_audio_set_volume(uint8_t vol); #ifdef __cplusplus } #endif diff --git a/class/cdc/usbd_cdc.h b/class/cdc/usbd_cdc.h index a8913162..1441fd4c 100644 --- a/class/cdc/usbd_cdc.h +++ b/class/cdc/usbd_cdc.h @@ -295,71 +295,139 @@ struct cdc_ecm_descriptor { /*Length of template descriptor: 66 bytes*/ #define CDC_ACM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7) - +// clang-format off +#ifndef CONFIG_USB_HS #define CDC_ACM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \ /* Interface Associate */ \ - 0x08, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ - bFirstInterface, /* bFirstInterface */ \ - 0x02, /* bInterfaceCount */ \ - USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \ - CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \ - CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \ - 0x00, /* iFunction */ /* CDC Control Interface */ \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bFirstInterface, /* bInterfaceNumber */ \ - 0x00, /* bAlternateSetting */ \ - 0x01, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \ - CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \ - CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \ - str_idx, /* iInterface */ /* CDC Header */ \ - 0x05, /* bLength */ \ - CDC_CS_INTERFACE, /* bDescriptorType */ \ - CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \ - WBVAL(CDC_V1_10), /* bcdCDC */ /* CDC Call */ \ - 0x05, /* bLength */ \ - CDC_CS_INTERFACE, /* bDescriptorType */ \ - CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \ - bFirstInterface, /* bmCapabilities */ \ - (uint8_t)(bFirstInterface + 1), /* bDataInterface */ /* CDC ACM: support line request */ \ - 0x04, /* bLength */ \ - CDC_CS_INTERFACE, /* bDescriptorType */ \ - CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \ - 0x02, /* bmCapabilities */ /* CDC Union */ \ - 0x05, /* bLength */ \ - CDC_CS_INTERFACE, /* bDescriptorType */ \ - CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \ - bFirstInterface, /* bMasterInterface */ \ - (uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ /* Endpoint Notification */ \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - int_ep, /* bEndpointAddress */ \ - 0x03, /* bmAttributes */ \ - 0x40, 0x00, /* wMaxPacketSize */ \ - 0x01, /* bInterval */ /* CDC Data Interface */ \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ - 0x00, /* bAlternateSetting */ \ - 0x02, /* bNumEndpoints */ \ - CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ - 0x00, /* bInterfaceSubClass */ \ - 0x00, /* bInterfaceProtocol */ \ - 0x00, /* iInterface */ /* Endpoint Out */ \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - out_ep, /* bEndpointAddress */ \ - 0x02, /* bmAttributes */ \ - 0x40, 0x00, /* wMaxPacketSize */ \ - 0x01, /* bInterval */ /* Endpoint In */ \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - in_ep, /* bEndpointAddress */ \ - 0x02, /* bmAttributes */ \ - 0x40, 0x00, /* wMaxPacketSize */ \ - 0x01 /* bInterval */ + 0x08, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ + bFirstInterface, /* bFirstInterface */ \ + 0x02, /* bInterfaceCount */ \ + USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \ + CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \ + 0x00, /* iFunction */ /* CDC Control Interface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bFirstInterface, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x01, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \ + str_idx, /* iInterface */ /* CDC Header */ \ + 0x05, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \ + WBVAL(CDC_V1_10), /* bcdCDC */ /* CDC Call */ \ + 0x05, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \ + bFirstInterface, /* bmCapabilities */ \ + (uint8_t)(bFirstInterface + 1), /* bDataInterface */ /* CDC ACM: support line request */ \ + 0x04, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \ + 0x02, /* bmCapabilities */ /* CDC Union */ \ + 0x05, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \ + bFirstInterface, /* bMasterInterface */ \ + (uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ /* Endpoint Notification */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + int_ep, /* bEndpointAddress */ \ + 0x03, /* bmAttributes */ \ + 0x40, 0x00, /* wMaxPacketSize */ \ + 0x01, /* bInterval */ /* CDC Data Interface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x02, /* bNumEndpoints */ \ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ + 0x00, /* bInterfaceSubClass */ \ + 0x00, /* bInterfaceProtocol */ \ + 0x00, /* iInterface */ /* Endpoint Out */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + out_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x40, 0x00, /* wMaxPacketSize */ \ + 0x01, /* bInterval */ /* Endpoint In */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + in_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x40, 0x00, /* wMaxPacketSize */ \ + 0x01 /* bInterval */ +#else +#define CDC_ACM_DESCRIPTOR_INIT(bFirstInterface, int_ep, out_ep, in_ep, str_idx) \ + /* Interface Associate */ \ + 0x08, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ + bFirstInterface, /* bFirstInterface */ \ + 0x02, /* bInterfaceCount */ \ + USB_DEVICE_CLASS_CDC, /* bFunctionClass */ \ + CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bFunctionProtocol */ \ + 0x00, /* iFunction */ /* CDC Control Interface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bFirstInterface, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x01, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_CDC, /* bInterfaceClass */ \ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ \ + CDC_COMMON_PROTOCOL_AT_COMMANDS, /* bInterfaceProtocol */ \ + str_idx, /* iInterface */ /* CDC Header */ \ + 0x05, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_HEADER, /* bDescriptorSubtype */ \ + WBVAL(CDC_V1_10), /* bcdCDC */ /* CDC Call */ \ + 0x05, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_CALL_MANAGEMENT, /* bDescriptorSubtype */ \ + bFirstInterface, /* bmCapabilities */ \ + (uint8_t)(bFirstInterface + 1), /* bDataInterface */ /* CDC ACM: support line request */ \ + 0x04, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype */ \ + 0x02, /* bmCapabilities */ /* CDC Union */ \ + 0x05, /* bLength */ \ + CDC_CS_INTERFACE, /* bDescriptorType */ \ + CDC_FUNC_DESC_UNION, /* bDescriptorSubtype */ \ + bFirstInterface, /* bMasterInterface */ \ + (uint8_t)(bFirstInterface + 1), /* bSlaveInterface0 */ /* Endpoint Notification */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + int_ep, /* bEndpointAddress */ \ + 0x03, /* bmAttributes */ \ + 0x02, 0x00, /* wMaxPacketSize */ \ + 0x01, /* bInterval */ /* CDC Data Interface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + (uint8_t)(bFirstInterface + 1), /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x02, /* bNumEndpoints */ \ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ \ + 0x00, /* bInterfaceSubClass */ \ + 0x00, /* bInterfaceProtocol */ \ + 0x00, /* iInterface */ /* Endpoint Out */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + out_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x02, 0x00, /* wMaxPacketSize */ \ + 0x01, /* bInterval */ /* Endpoint In */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + in_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x02, 0x00, /* wMaxPacketSize */ \ + 0x01 /* bInterval */ +#endif +// clang-format on void usbd_cdc_add_acm_interface(usbd_class_t *class, usbd_interface_t *intf); diff --git a/class/hid/usbd_hid.c b/class/hid/usbd_hid.c index 503753e2..34f2faf5 100644 --- a/class/hid/usbd_hid.c +++ b/class/hid/usbd_hid.c @@ -30,11 +30,19 @@ struct usbd_hid_cfg_private { const uint8_t *hid_descriptor; const uint8_t *hid_report_descriptor; uint32_t hid_report_descriptor_len; - uint32_t protocol; - uint32_t idle_state; + uint8_t current_intf_num; uint8_t hid_state; uint8_t report; - uint8_t current_intf_num; + uint8_t idle_state; + uint8_t protocol; + + uint8_t (*get_report_callback)(uint8_t report_id, uint8_t report_type); + void (*set_report_callback)(uint8_t report_id, uint8_t report_type, uint8_t *report, uint8_t report_len); + uint8_t (*get_idle_callback)(uint8_t report_id); + void (*set_idle_callback)(uint8_t report_id, uint8_t duration); + void (*set_protocol_callback)(uint8_t protocol); + uint8_t (*get_protocol_callback)(void); + usb_slist_t list; } usbd_hid_cfg[4]; @@ -47,6 +55,7 @@ static void usbd_hid_reset(void) { struct usbd_hid_cfg_private *hid_intf = usb_slist_entry(i, struct usbd_hid_cfg_private, list); hid_intf->hid_state = HID_STATE_IDLE; + hid_intf->report = 0; hid_intf->idle_state = 0; hid_intf->protocol = 0; } @@ -131,24 +140,42 @@ int hid_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, ui switch (setup->bRequest) { case HID_REQUEST_GET_REPORT: + if (current_hid_intf->get_report_callback) + current_hid_intf->report = current_hid_intf->get_report_callback(setup->wValueL, setup->wValueH); /*report id ,report type*/ + *data = (uint8_t *)¤t_hid_intf->report; *len = 1; break; case HID_REQUEST_GET_IDLE: + if (current_hid_intf->get_idle_callback) + current_hid_intf->idle_state = current_hid_intf->get_idle_callback(setup->wValueL); + *data = (uint8_t *)¤t_hid_intf->idle_state; *len = 1; break; case HID_REQUEST_GET_PROTOCOL: + if (current_hid_intf->get_protocol_callback) + current_hid_intf->protocol = current_hid_intf->get_protocol_callback(); + *data = (uint8_t *)¤t_hid_intf->protocol; *len = 1; break; case HID_REQUEST_SET_REPORT: + if (current_hid_intf->set_report_callback) + current_hid_intf->set_report_callback(setup->wValueL, setup->wValueH, *data, *len); /*report id ,report type,report,report len*/ + current_hid_intf->report = **data; break; case HID_REQUEST_SET_IDLE: - current_hid_intf->idle_state = setup->wValueH; + if (current_hid_intf->set_idle_callback) + current_hid_intf->set_idle_callback(setup->wValueL, setup->wIndexH); /*report id ,duration*/ + + current_hid_intf->idle_state = setup->wIndexH; break; case HID_REQUEST_SET_PROTOCOL: + if (current_hid_intf->set_protocol_callback) + current_hid_intf->set_protocol_callback(setup->wValueL); /*protocol*/ + current_hid_intf->protocol = setup->wValueL; break; @@ -205,6 +232,38 @@ void usbd_hid_report_descriptor_register(uint8_t intf_num, const uint8_t *desc, } } } +// clang-format off +void usbd_hid_set_request_callback( uint8_t intf_num, + uint8_t (*get_report_callback)(uint8_t report_id, uint8_t report_type), + void (*set_report_callback)(uint8_t report_id, uint8_t report_type, uint8_t *report, uint8_t report_len), + uint8_t (*get_idle_callback)(uint8_t report_id), + void (*set_idle_callback)(uint8_t report_id, uint8_t duration), + void (*set_protocol_callback)(uint8_t protocol), + uint8_t (*get_protocol_callback)(void)) +// clang-format on +{ + usb_slist_t *i; + usb_slist_for_each(i, &usbd_hid_class_head) + { + struct usbd_hid_cfg_private *hid_intf = usb_slist_entry(i, struct usbd_hid_cfg_private, list); + + if (hid_intf->current_intf_num == intf_num) { + if (get_report_callback) + hid_intf->get_report_callback = get_report_callback; + if (set_report_callback) + hid_intf->set_report_callback = set_report_callback; + if (get_idle_callback) + hid_intf->get_idle_callback = get_idle_callback; + if (set_idle_callback) + hid_intf->set_idle_callback = set_idle_callback; + if (set_protocol_callback) + hid_intf->set_protocol_callback = set_protocol_callback; + if (get_protocol_callback) + hid_intf->get_protocol_callback = get_protocol_callback; + return; + } + } +} void usbd_hid_add_interface(usbd_class_t *class, usbd_interface_t *intf) { diff --git a/class/hid/usbd_hid.h b/class/hid/usbd_hid.h index 19ccb875..9319e7f2 100644 --- a/class/hid/usbd_hid.h +++ b/class/hid/usbd_hid.h @@ -12,6 +12,13 @@ extern "C" { #endif +/* HID Protocol Codes */ +#define HID_PROTOCOL_NONE 0x00 +#define HID_PROTOCOL_BOOT 0x00 +#define HID_PROTOCOL_KEYBOARD 0x01 +#define HID_PROTOCOL_REPORT 0x01 +#define HID_PROTOCOL_MOUSE 0x02 + /* HID Class Descriptor Types */ #define HID_DESCRIPTOR_TYPE_HID 0x21 #define HID_DESCRIPTOR_TYPE_HID_REPORT 0x22 @@ -25,6 +32,11 @@ extern "C" { #define HID_REQUEST_SET_IDLE 0x0A #define HID_REQUEST_SET_PROTOCOL 0x0B +/* HID Report Types */ +#define HID_REPORT_INPUT 0x01 +#define HID_REPORT_OUTPUT 0x02 +#define HID_REPORT_FEATURE 0x03 + /* HID Report Definitions */ struct usb_hid_class_subdescriptor { uint8_t bDescriptorType; @@ -122,10 +134,6 @@ struct usb_hid_descriptor { #define COLLECTION_PHYSICAL 0x00 #define COLLECTION_APPLICATION 0x01 -/* Protocols */ -#define HID_PROTOCOL_BOOT 0x00 -#define HID_PROTOCOL_REPORT 0x01 - /* Example HID report descriptors */ /** * @brief Simple HID mouse report descriptor for n button mouse. @@ -336,7 +344,15 @@ void usbd_hid_report_descriptor_register(uint8_t intf_num, const uint8_t *desc, void usbd_hid_add_interface(usbd_class_t *class, usbd_interface_t *intf); void usbd_hid_reset_state(void); void usbd_hid_send_report(uint8_t ep, uint8_t *data, uint8_t len); - +// clang-format off +void usbd_hid_set_request_callback( uint8_t intf_num, + uint8_t (*get_report_callback)(uint8_t report_id, uint8_t report_type), + void (*set_report_callback)(uint8_t report_id, uint8_t report_type, uint8_t *report, uint8_t report_len), + uint8_t (*get_idle_callback)(uint8_t report_id), + void (*set_idle_callback)(uint8_t report_id, uint8_t duration), + void (*set_protocol_callback)(uint8_t protocol), + uint8_t (*get_protocol_callback)(void)); +// clang-format on #ifdef __cplusplus } #endif diff --git a/class/msc/usbd_msc.c b/class/msc/usbd_msc.c index 55eefd3f..b43d1ba7 100644 --- a/class/msc/usbd_msc.c +++ b/class/msc/usbd_msc.c @@ -25,8 +25,11 @@ #include "usbd_msc.h" /* max USB packet size */ +#ifndef CONFIG_USB_HS #define MASS_STORAGE_BULK_EP_MPS 64 -#define MASS_STORAGE_BLOCK_SIZE 512 +#else +#define MASS_STORAGE_BULK_EP_MPS 512 +#endif #define MSD_OUT_EP_IDX 0 #define MSD_IN_EP_IDX 1 @@ -60,7 +63,7 @@ struct usbd_msc_cfg_private { uint32_t scsi_blk_addr; uint32_t scsi_blk_len; - uint8_t block_buffer[MASS_STORAGE_BLOCK_SIZE]; + uint8_t *block_buffer; } usbd_msc_cfg; @@ -76,6 +79,11 @@ static void usbd_msc_reset(void) usbd_msc_cfg.scsi_blk_len = 0U; usbd_msc_get_cap(0, &usbd_msc_cfg.scsi_blk_nbr, &usbd_msc_cfg.scsi_blk_size); usbd_msc_cfg.max_lun_count = 0; + + if (usbd_msc_cfg.block_buffer) { + free(usbd_msc_cfg.block_buffer); + } + usbd_msc_cfg.block_buffer = malloc(usbd_msc_cfg.scsi_blk_size * sizeof(uint8_t)); } /** @@ -138,7 +146,6 @@ static bool usbd_msc_datain_check(void) { if (!usbd_msc_cfg.cbw.DataLength) { USBD_LOG_WRN("Zero length in CBW"); - //SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR; usbd_msc_send_csw(); return false; @@ -164,7 +171,7 @@ static bool usbd_msc_send_to_host(uint8_t *buffer, uint16_t size) } if (usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, buffer, size, NULL)) { - USBD_LOG_ERR("USB write failed"); + USBD_LOG_ERR("USB write failed\r\n"); return false; } @@ -478,11 +485,10 @@ static bool usbd_msc_read_write_process(void) { /* Logical Block Address of First Block */ uint32_t lba; - uint32_t len = 0; + uint32_t blk_num = 0; if (!usbd_msc_cfg.cbw.DataLength) { USBD_LOG_WRN("Zero length in CBW\r\n"); - //SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB); usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR; usbd_msc_send_csw(); return false; @@ -498,22 +504,22 @@ static bool usbd_msc_read_write_process(void) case SCSI_READ10: case SCSI_WRITE10: case SCSI_VERIFY10: - len = GET_BE16(&usbd_msc_cfg.cbw.CB[7]); + blk_num = GET_BE16(&usbd_msc_cfg.cbw.CB[7]); break; case SCSI_READ12: case SCSI_WRITE12: - len = GET_BE32(&usbd_msc_cfg.cbw.CB[6]); + blk_num = GET_BE32(&usbd_msc_cfg.cbw.CB[6]); break; default: break; } - USBD_LOG_DBG("len (block) : 0x%x\r\n", len); - usbd_msc_cfg.scsi_blk_len = len * usbd_msc_cfg.scsi_blk_size; + USBD_LOG_DBG("num (block) : 0x%x\r\n", blk_num); + usbd_msc_cfg.scsi_blk_len = blk_num * usbd_msc_cfg.scsi_blk_size; - if ((lba + len) > usbd_msc_cfg.scsi_blk_nbr) { + if ((lba + blk_num) > usbd_msc_cfg.scsi_blk_nbr) { USBD_LOG_ERR("LBA out of range\r\n"); usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_FAILED; usbd_msc_send_csw(); diff --git a/class/msc/usbd_msc.h b/class/msc/usbd_msc.h index 1673ace4..1d198e79 100644 --- a/class/msc/usbd_msc.h +++ b/class/msc/usbd_msc.h @@ -64,30 +64,57 @@ struct CSW { /*Length of template descriptor: 23 bytes*/ #define MSC_DESCRIPTOR_LEN (9 + 7 + 7) - -#define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, str_idx) \ +// clang-format off +#ifndef SUPPORT_USB_HS +#define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep,str_idx) \ /* Interface */ \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bFirstInterface, /* bInterfaceNumber */ \ - 0x00, /* bAlternateSetting */ \ - 0x02, /* bNumEndpoints */ \ - USB_DEVICE_CLASS_MASS_STORAGE, /* bInterfaceClass */ \ - MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ \ - MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ \ - str_idx, /* iInterface */ /* Endpoint Out */ \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - out_ep, /* bEndpointAddress */ \ - 0x02, /* bmAttributes */ \ - 0x40, 0x00, /* wMaxPacketSize */ \ - 0x01, /* bInterval */ /* Endpoint In */ \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - in_ep, /* bEndpointAddress */ \ - 0x02, /* bmAttributes */ \ - 0x40, 0x00, /* wMaxPacketSize */ \ - 0x01 /* bInterval */ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bFirstInterface, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x02, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_MASS_STORAGE, /* bInterfaceClass */ \ + MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ \ + MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ \ + str_idx, /* iInterface */ /* Endpoint Out */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + out_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x40, 0x00, /* wMaxPacketSize */ \ + 0x01, /* bInterval */ /* Endpoint In */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + in_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x40, 0x00, /* wMaxPacketSize */ \ + 0x01 /* bInterval */ +#else +#define MSC_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep,str_idx) \ + /* Interface */ \ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bFirstInterface, /* bInterfaceNumber */ \ + 0x00, /* bAlternateSetting */ \ + 0x02, /* bNumEndpoints */ \ + USB_DEVICE_CLASS_MASS_STORAGE, /* bInterfaceClass */ \ + MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ \ + MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ \ + str_idx, /* iInterface */ /* Endpoint Out */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + out_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x02, 0x00, /* wMaxPacketSize */ \ + 0x01, /* bInterval */ /* Endpoint In */ \ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + in_ep, /* bEndpointAddress */ \ + 0x02, /* bmAttributes */ \ + 0x02, 0x00, /* wMaxPacketSize */ \ + 0x01 /* bInterval */ +#endif +// clang-format on void usbd_msc_class_init(uint8_t out_ep, uint8_t in_ep); void usbd_msc_get_cap(uint8_t lun, uint32_t *block_num, uint16_t *block_size); diff --git a/class/webusb/usbd_webusb.h b/class/webusb/usbd_webusb.h index 6274f496..d94d1702 100644 --- a/class/webusb/usbd_webusb.h +++ b/class/webusb/usbd_webusb.h @@ -19,19 +19,4 @@ #define WEBUSB_CONFIGURATION_SUBSET_HEADER_SIZE 4 #define WEBUSB_FUNCTION_SUBSET_HEADER_SIZE 3 -/* BOS Capability webusb */ -struct usb_bos_webusb_platform_capability_descriptor { - struct usb_bos_capability_descriptor webusb_platform; - uint16_t bcdVersion; - uint8_t bVendorCode; - uint8_t iLandingPage; -} __packed; - -struct webusb_url_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint8_t bScheme; - char URL[]; -} __packed; - #endif \ No newline at end of file diff --git a/class/winusb/usbd_winusb.h b/class/winusb/usbd_winusb.h index 5e76bac8..dc4a51dd 100644 --- a/class/winusb/usbd_winusb.h +++ b/class/winusb/usbd_winusb.h @@ -23,13 +23,4 @@ #define WINUSB_PROP_DATA_TYPE_REG_SZ 0x01 #define WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ 0x07 -/* WinUSB Microsoft OS 2.0 descriptor Platform Capability Descriptor */ -struct usb_bos_winusb_platform_capability_descriptor { - struct usb_bos_capability_descriptor winusb_platform; - uint32_t dwWindowsVersion; - uint16_t wMSOSDescriptorSetTotalLength; - uint8_t bMS_VendorCode; - uint8_t bAltEnumCode; -} __packed; - #endif \ No newline at end of file diff --git a/common/usb_def.h b/common/usb_def.h index 8a592c3a..57903f6b 100644 --- a/common/usb_def.h +++ b/common/usb_def.h @@ -351,8 +351,8 @@ struct usb_msosv1_comp_id_function_descriptor { uint8_t reserved2[6]; } __packed; -#define usb_msosv1_comp_id_property_create(x) \ - struct usb_msosv1_comp_id_property { \ +#define usb_msosv1_comp_id_create(x) \ + struct usb_msosv1_comp_id { \ struct usb_msosv1_compat_id_header_descriptor compat_id_header; \ struct usb_msosv1_comp_id_function_descriptor compat_id_function[x]; \ }; @@ -368,32 +368,23 @@ struct usb_msosv1_descriptor { }; /* MS OS 2.0 Header descriptor */ -struct usb_msosv2_property_header_descriptor { +struct usb_msosv2_header_descriptor { uint32_t dwLength; uint16_t bcdVersion; uint16_t wIndex; uint8_t bCount; } __packed; -/* WinUSB Microsoft OS 2.0 descriptor set header */ -struct winusb_header_descriptor { +/*Microsoft OS 2.0 set header descriptor*/ +struct usb_msosv2_set_header_descriptor { uint16_t wLength; uint16_t wDescriptorType; uint32_t dwWindowsVersion; uint16_t wDescriptorSetTotalLength; } __packed; -/* WinUSB Microsoft OS 2.0 subset function descriptor */ -struct winusb_subset_function_descriptor { - uint16_t wLength; - uint16_t wDescriptorType; - uint8_t bFirstInterface; - uint8_t bReserved; - uint16_t wSubsetLength; -} __packed; - -/* MS OS 2.0 Function Section */ -struct usb_msosv2_comp_id_function_descriptor { +/* Microsoft OS 2.0 compatibleID descriptor*/ +struct usb_msosv2_comp_id_descriptor { uint16_t wLength; uint16_t wDescriptorType; uint8_t compatibleID[8]; @@ -401,7 +392,7 @@ struct usb_msosv2_comp_id_function_descriptor { } __packed; /* MS OS 2.0 property descriptor */ -struct usb_msosv2_proerty_descriptor { +struct usb_msosv2_property_descriptor { uint16_t wLength; uint16_t wDescriptorType; uint32_t dwPropertyDataType; @@ -411,12 +402,22 @@ struct usb_msosv2_proerty_descriptor { const char *bPropertyData; }; +/* Microsoft OS 2.0 subset function descriptor */ +struct usb_msosv2_subset_function_descriptor { + uint16_t wLength; + uint16_t wDescriptorType; + uint8_t bFirstInterface; + uint8_t bReserved; + uint16_t wSubsetLength; +} __packed; + struct usb_msosv2_descriptor { uint8_t *compat_id; uint16_t compat_id_len; + uint8_t vendor_code; }; -/* BOS Descriptor */ +/* BOS header Descriptor */ struct usb_bos_header_descriptor { uint8_t bLength; uint8_t bDescriptorType; @@ -424,8 +425,8 @@ struct usb_bos_header_descriptor { uint8_t bNumDeviceCaps; } __packed; -/* BOS Capability Descriptor */ -struct usb_bos_capability_descriptor { +/* BOS Capability platform Descriptor */ +struct usb_bos_capability_platform_descriptor { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDevCapabilityType; @@ -433,20 +434,63 @@ struct usb_bos_capability_descriptor { uint8_t PlatformCapabilityUUID[16]; } __packed; -struct usb_bos_capability_lpm { +/* BOS Capability MS OS Descriptors version 2 */ +struct usb_bos_capability_msosv2_descriptor { + uint32_t dwWindowsVersion; + uint16_t wMSOSDescriptorSetTotalLength; + uint8_t bVendorCode; + uint8_t bAltEnumCode; +} __packed; + +/* BOS Capability webusb */ +struct usb_bos_capability_webusb_descriptor { + uint16_t bcdVersion; + uint8_t bVendorCode; + uint8_t iLandingPage; +} __packed; + +/* BOS Capability extension Descriptor*/ +struct usb_bos_capability_extension_descriptor { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDevCapabilityType; uint32_t bmAttributes; } __packed; +/* Microsoft OS 2.0 Platform Capability Descriptor +* See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/ +* microsoft-defined-usb-descriptors +* Adapted from the source: +* https://github.com/sowbug/weblight/blob/master/firmware/webusb.c +* (BSD-2) Thanks http://janaxelson.com/files/ms_os_20_descriptors.c +*/ +struct usb_bos_capability_platform_msosv2_descriptor { + struct usb_bos_capability_platform_descriptor platform_msos; + struct usb_bos_capability_msosv2_descriptor data_msosv2; +} __packed; + +/* WebUSB Platform Capability Descriptor: +* https://wicg.github.io/webusb/#webusb-platform-capability-descriptor +*/ +struct usb_bos_capability_platform_webusb_descriptor { + struct usb_bos_capability_platform_descriptor platform_webusb; + struct usb_bos_capability_webusb_descriptor data_webusb; +} __packed; + +struct usb_webusb_url_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bScheme; + char URL[]; +} __packed; + struct usb_bos_descriptor { - uint8_t *bos_id; - uint8_t bos_id_len; + uint8_t *string; + uint32_t string_len; }; /* USB Device Capability Descriptor */ -struct usb_device_capability__descriptor { +struct usb_device_capability_descriptor { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDevCapabilityType; @@ -457,66 +501,66 @@ struct usb_desc_header { uint8_t bLength; /**< descriptor length */ uint8_t bDescriptorType; /**< descriptor type */ }; - +// clang-format off #define USB_DEVICE_DESCRIPTOR_INIT(bcdUSB, bDeviceClass, bDeviceSubClass, bDeviceProtocol, idVendor, idProduct, bcdDevice, bNumConfigurations) \ - 0x12, /* bLength */ \ - USB_DESCRIPTOR_TYPE_DEVICE, /* bDescriptorType */ \ - WBVAL(bcdUSB), /* bcdUSB */ \ - bDeviceClass, /* bDeviceClass */ \ - bDeviceSubClass, /* bDeviceSubClass */ \ - bDeviceProtocol, /* bDeviceProtocol */ \ - 0x40, /* bMaxPacketSize */ \ - WBVAL(idVendor), /* idVendor */ \ - WBVAL(idProduct), /* idProduct */ \ - WBVAL(bcdDevice), /* bcdDevice */ \ - USB_STRING_MFC_INDEX, /* iManufacturer */ \ - USB_STRING_PRODUCT_INDEX, /* iProduct */ \ - USB_STRING_SERIAL_INDEX, /* iSerial */ \ - bNumConfigurations /* bNumConfigurations */ + 0x12, /* bLength */ \ + USB_DESCRIPTOR_TYPE_DEVICE, /* bDescriptorType */ \ + WBVAL(bcdUSB), /* bcdUSB */ \ + bDeviceClass, /* bDeviceClass */ \ + bDeviceSubClass, /* bDeviceSubClass */ \ + bDeviceProtocol, /* bDeviceProtocol */ \ + 0x40, /* bMaxPacketSize */ \ + WBVAL(idVendor), /* idVendor */ \ + WBVAL(idProduct), /* idProduct */ \ + WBVAL(bcdDevice), /* bcdDevice */ \ + USB_STRING_MFC_INDEX, /* iManufacturer */ \ + USB_STRING_PRODUCT_INDEX, /* iProduct */ \ + USB_STRING_SERIAL_INDEX, /* iSerial */ \ + bNumConfigurations /* bNumConfigurations */ #define USB_CONFIG_DESCRIPTOR_INIT(wTotalLength, bNumInterfaces, bConfigurationValue, bmAttributes, bMaxPower) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_CONFIGURATION, /* bDescriptorType */ \ - WBVAL(wTotalLength), /* wTotalLength */ \ - bNumInterfaces, /* bNumInterfaces */ \ - bConfigurationValue, /* bConfigurationValue */ \ - 0x00, /* iConfiguration */ \ - bmAttributes, /* bmAttributes */ \ - USB_CONFIG_POWER_MA(bMaxPower) /* bMaxPower */ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_CONFIGURATION, /* bDescriptorType */ \ + WBVAL(wTotalLength), /* wTotalLength */ \ + bNumInterfaces, /* bNumInterfaces */ \ + bConfigurationValue, /* bConfigurationValue */ \ + 0x00, /* iConfiguration */ \ + bmAttributes, /* bmAttributes */ \ + USB_CONFIG_POWER_MA(bMaxPower) /* bMaxPower */ #define USB_INTERFACE_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bNumEndpoints, \ bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol, iInterface) \ - 0x09, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ - bInterfaceNumber, /* bInterfaceNumber */ \ - bAlternateSetting, /* bAlternateSetting */ \ - bNumEndpoints, /* bNumEndpoints */ \ - bInterfaceClass, /* bInterfaceClass */ \ - bInterfaceSubClass, /* bInterfaceSubClass */ \ - bInterfaceProtocol, /* bInterfaceProtocol */ \ - iInterface /* iInterface */ + 0x09, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \ + bInterfaceNumber, /* bInterfaceNumber */ \ + bAlternateSetting, /* bAlternateSetting */ \ + bNumEndpoints, /* bNumEndpoints */ \ + bInterfaceClass, /* bInterfaceClass */ \ + bInterfaceSubClass, /* bInterfaceSubClass */ \ + bInterfaceProtocol, /* bInterfaceProtocol */ \ + iInterface /* iInterface */ #define USB_ENDPOINT_DESCRIPTOR_INIT(bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval) \ - 0x07, /* bLength */ \ - USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ - bEndpointAddress, /* bEndpointAddress */ \ - bmAttributes, /* bmAttributes */ \ - WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ - bInterval /* bInterval */ + 0x07, /* bLength */ \ + USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \ + bEndpointAddress, /* bEndpointAddress */ \ + bmAttributes, /* bmAttributes */ \ + WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \ + bInterval /* bInterval */ #define USB_IAD_INIT(bFirstInterface, bInterfaceCount, bFunctionClass, bFunctionSubClass, bFunctionProtocol) \ - 0x08, /* bLength */ \ - USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ - bFirstInterface, /* bFirstInterface */ \ - bInterfaceCount, /* bInterfaceCount */ \ - bFunctionClass, /* bFunctionClass */ \ - bFunctionSubClass, /* bFunctionSubClass */ \ - bFunctionProtocol, /* bFunctionProtocol */ \ - 0x00 /* iFunction */ - -#define USB_LANGID_INIT(id) \ - 0x04, /* bLength */ \ - USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \ - WBVAL(id) /* wLangID0 */ + 0x08, /* bLength */ \ + USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, /* bDescriptorType */ \ + bFirstInterface, /* bFirstInterface */ \ + bInterfaceCount, /* bInterfaceCount */ \ + bFunctionClass, /* bFunctionClass */ \ + bFunctionSubClass, /* bFunctionSubClass */ \ + bFunctionProtocol, /* bFunctionProtocol */ \ + 0x00 /* iFunction */ +#define USB_LANGID_INIT(id) \ + 0x04, /* bLength */ \ + USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */ \ + WBVAL(id) /* wLangID0 */ +// clang-format on #endif \ No newline at end of file diff --git a/common/usb_util.h b/common/usb_util.h index 83c59744..eebd3401 100644 --- a/common/usb_util.h +++ b/common/usb_util.h @@ -68,12 +68,21 @@ #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #endif +#ifndef BCD #define BCD(x) ((((x) / 10) << 4) | ((x) % 10)) +#endif -#define BIT(x) (1 << (x)) +#ifdef BIT +#undef BIT +#define BIT(n) (1UL << (n)) +#else +#define BIT(n) (1UL << (n)) +#endif +#ifndef ARRAY_SIZE #define ARRAY_SIZE(array) \ ((int)((sizeof(array) / sizeof((array)[0])))) +#endif #define USB_DESC_SECTION __attribute__((section("usb_desc"))) __used __aligned(1) diff --git a/core/usbd_core.c b/core/usbd_core.c index ffcb5202..ee4373d2 100644 --- a/core/usbd_core.c +++ b/core/usbd_core.c @@ -21,6 +21,7 @@ * */ #include "usbd_core.h" +#include "usbd_winusb.h" #define USBD_EP_CALLBACK_LIST_SEARCH 0 #define USBD_EP_CALLBACK_ARR_SEARCH 1 @@ -76,6 +77,7 @@ static struct usbd_core_cfg_priv { static usb_slist_t usbd_class_head = USB_SLIST_OBJECT_INIT(usbd_class_head); static struct usb_msosv1_descriptor *msosv1_desc; +static struct usb_msosv2_descriptor *msosv2_desc; static struct usb_bos_descriptor *bos_desc; /** @@ -259,25 +261,25 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l index = GET_DESC_INDEX(type_index); if ((type == USB_DESCRIPTOR_TYPE_STRING) && (index == USB_OSDESC_STRING_DESC_INDEX)) { - USBD_LOG("MS OS Descriptor string read\r\n"); + USBD_LOG("read MS OS 2.0 descriptor string\r\n"); if (!msosv1_desc) { return false; } *data = (uint8_t *)msosv1_desc->string; - *len = sizeof(struct usb_msosv1_string_descriptor); + *len = msosv1_desc->string_len; return true; } else if (type == USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE) { - USBD_LOG("BOS descriptor string read\r\n"); + USBD_LOG("read BOS descriptor string\r\n"); if (!bos_desc) { return false; } - *data = bos_desc->bos_id; - *len = bos_desc->bos_id_len; + *data = bos_desc->string; + *len = bos_desc->string_len; return true; } /* @@ -285,7 +287,11 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l * see USB Spec. Revision 2.0, 9.4.3 Get Descriptor */ else if ((type == USB_DESCRIPTOR_TYPE_INTERFACE) || (type == USB_DESCRIPTOR_TYPE_ENDPOINT) || +#ifndef CONFIG_USB_HS + (type > USB_DESCRIPTOR_TYPE_ENDPOINT)) { +#else (type > USB_DESCRIPTOR_TYPE_OTHER_SPEED)) { +#endif return false; } @@ -811,19 +817,33 @@ static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t * if (setup->bRequest == msosv1_desc->vendor_code) { switch (setup->wIndex) { case 0x04: - USBD_LOG("Handle Compat ID\r\n"); + USBD_LOG("get Compat ID\r\n"); *data = (uint8_t *)msosv1_desc->compat_id; *len = msosv1_desc->compat_id_len; return 0; case 0x05: - USBD_LOG("Handle Compat properties\r\n"); + USBD_LOG("get Compat id properties\r\n"); *data = (uint8_t *)msosv1_desc->comp_id_property; *len = msosv1_desc->comp_id_property_len; return 0; default: - break; + USBD_LOG("unknown vendor code\r\n"); + return -1; + } + } + } else if (msosv2_desc) { + if (setup->bRequest == msosv2_desc->vendor_code) { + switch (setup->wIndex) { + case WINUSB_REQUEST_GET_DESCRIPTOR_SET: + USBD_LOG("GET MS OS 2.0 Descriptor\r\n"); + *data = (uint8_t *)msosv2_desc->compat_id; + *len = msosv2_desc->compat_id_len; + return 0; + default: + USBD_LOG("unknown vendor code\r\n"); + return -1; } } } @@ -930,8 +950,12 @@ static void usbd_send_to_host(uint16_t len) if (usbd_core_cfg.zlp_flag == false) { chunk = usbd_core_cfg.ep0_data_buf_residue; - usbd_ep_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, - usbd_core_cfg.ep0_data_buf_residue, &chunk); + + if (usbd_ep_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue, &chunk) < 0) { + USBD_LOG_ERR("USB write data failed\r\n"); + return; + } + usbd_core_cfg.ep0_data_buf += chunk; usbd_core_cfg.ep0_data_buf_residue -= chunk; @@ -949,7 +973,10 @@ static void usbd_send_to_host(uint16_t len) } } else { usbd_core_cfg.zlp_flag = false; - usbd_ep_write(USB_CONTROL_IN_EP0, NULL, 0, NULL); + if (usbd_ep_write(USB_CONTROL_IN_EP0, NULL, 0, NULL) < 0) { + USBD_LOG_ERR("USB write zlp failed\r\n"); + return; + } } } @@ -1206,6 +1233,17 @@ void usbd_msosv1_desc_register(struct usb_msosv1_descriptor *desc) msosv1_desc = desc; } +/* Register MS OS Descriptors version 2 */ +void usbd_msosv2_desc_register(struct usb_msosv2_descriptor *desc) +{ + msosv2_desc = desc; +} + +void usbd_bos_desc_register(struct usb_bos_descriptor *desc) +{ + bos_desc = desc; +} + void usbd_class_register(usbd_class_t *class) { usb_slist_add_tail(&usbd_class_head, &class->list); diff --git a/core/usbd_core.h b/core/usbd_core.h index 5881106e..6884a76e 100644 --- a/core/usbd_core.h +++ b/core/usbd_core.h @@ -125,6 +125,8 @@ void usbd_event_notify_handler(uint8_t event, void *arg); void usbd_desc_register(const uint8_t *desc); void usbd_class_register(usbd_class_t *class); void usbd_msosv1_desc_register(struct usb_msosv1_descriptor *desc); +void usbd_msosv2_desc_register(struct usb_msosv2_descriptor *desc); +void usbd_bos_desc_register(struct usb_bos_descriptor *desc); void usbd_class_add_interface(usbd_class_t *class, usbd_interface_t *intf); void usbd_interface_add_endpoint(usbd_interface_t *intf, usbd_endpoint_t *ep); bool usb_device_is_configured(void);