/* * The MIT License (MIT) * * Copyright (c) 2015 by Sergey Fetisov * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* * version: 1.0 demo (7.02.2015) */ #include "usbd_core.h" #include "usbd_desc.h" #include "usbd_conf.h" #include "usbd_rndis_core.h" #include "common_config.h" #define USB_DEVICE_DESCRIPTOR_TYPE 0x01 #define USB_STRING_DESCRIPTOR_TYPE 0x03 #define USB_SIZ_STRING_LANGID 4 #define USB_SIZ_DEVICE_DESC 0x12 usbd_desc_t *get_device_descriptor(void); usbd_desc_t *get_device_qualifier(void); usbd_desc_t *get_device_configuration(void); usbd_desc_t *get_device_other_speed(void); usbd_desc_t *get_device_lang_id(void); usbd_desc_t *get_device_manufacturer_string(void); usbd_desc_t *get_device_product_string(void); usbd_desc_t *get_device_serial_string(void); usbd_desc_t *get_device_config_string(void); usbd_desc_t *get_device_interface_string(void); uint16_t usbd_unicode_convert(uint8_t *string, uint8_t *unicode_buf); static void usbd_int_to_unicode (uint32_t value , uint8_t *pbuf , uint8_t len); extern usbd_core_type usb_core_dev; extern uint8_t usbd_cdc_CfgDesc[]; usbd_desc_handler USR_desc = { get_device_descriptor, get_device_qualifier, get_device_configuration, get_device_other_speed, get_device_lang_id, get_device_manufacturer_string, get_device_product_string, get_device_serial_string, get_device_interface_string, get_device_config_string, }; #if defined ( __ICCARM__ ) /* iar compiler */ #pragma data_alignment=4 #endif uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ]; #if defined ( __ICCARM__ ) /* iar compiler */ #pragma data_alignment=4 #endif ALIGNED_HEAD uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] ALIGNED_TAIL = { 18, // bLength = 18 bytes. USB_DEVICE_DESCRIPTOR_TYPE, // bDescriptorType = DEVICE 0x00, 0x02, // bcdUSB = 1.1 0x10,0x01 2.0 0x00,0x02 0xE0, // bDeviceClass = Communication Device Class 0x00, // bDeviceSubClass = Unused at this time. 0x00, // bDeviceProtocol = Unused at this time. 0x40, // bMaxPacketSize0 = EP0 buffer size.. LBYTE(USBD_VID), HBYTE(USBD_VID), // Vendor ID LBYTE(USBD_PID), HBYTE(USBD_PID), // Product ID 0xFF, 0xFF, // bcdDevice USB_MFC_STRING, USB_PRODUCT_STRING, USB_SERIAL_STRING, 1 }; #if defined ( __ICCARM__ ) /* iar compiler */ #pragma data_alignment=4 #endif /* USB Standard Device Descriptor */ ALIGNED_HEAD uint8_t USBD_DeviceQualifierDesc[USB_DEVICE_QUALIFIER_DESC_LEN] ALIGNED_TAIL = { USB_DEVICE_QUALIFIER_DESC_LEN, USB_DESCIPTOR_TYPE_DEVICE_QUALIFIER, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, }; #if defined ( __ICCARM__ ) /* iar compiler */ #pragma data_alignment=4 #endif /* USB Standard Device Descriptor */ ALIGNED_HEAD uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] ALIGNED_TAIL = { USB_SIZ_STRING_LANGID, USB_DESCIPTOR_TYPE_STRING, LBYTE(USBD_LANGID_STRING), HBYTE(USBD_LANGID_STRING), }; /* device descriptor */ usbd_desc_t device_descriptor = { USB_DEVICE_DESC_LEN, USBD_DeviceDesc }; /* device qualifier */ usbd_desc_t device_qualifier = { USB_DEVICE_QUALIFIER_DESC_LEN, USBD_DeviceQualifierDesc }; /* langid descriptor */ usbd_desc_t langid_descriptor = { USB_SIZ_STRING_LANGID, USBD_LangIDDesc }; usbd_desc_t vp_desc; /** * @brief standard usb unicode convert * @param string: source string * @param unicode_buf: unicode buffer * @retval length */ uint16_t usbd_unicode_convert(uint8_t *string, uint8_t *unicode_buf) { uint16_t str_len = 0, id_pos = 2; uint8_t *tmp_str = string; while(*tmp_str != '\0') { str_len ++; unicode_buf[id_pos ++] = *tmp_str ++; unicode_buf[id_pos ++] = 0x00; } str_len = str_len * 2 + 2; unicode_buf[0] = str_len; unicode_buf[1] = USB_DESCIPTOR_TYPE_STRING; return str_len; } /** * @brief usb int convert to unicode * @param value: int value * @param pbus: unicode buffer * @param len: length * @retval none */ static void usbd_int_to_unicode (uint32_t value , uint8_t *pbuf , uint8_t len) { uint8_t idx = 0; for( idx = 0 ; idx < len ; idx ++) { if( ((value >> 28)) < 0xA ) { pbuf[ 2 * idx] = (value >> 28) + '0'; } else { pbuf[2 * idx] = (value >> 28) + 'A' - 10; } value = value << 4; pbuf[2 * idx + 1] = 0; } } /** * @brief get device descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_descriptor(void) { DBG printf("DeviceDescriptor\r\n"); return &device_descriptor; } usbd_desc_t *get_device_qualifier(void) { DBG printf("DeviceQulifier\r\n"); return &device_qualifier; } usbd_desc_t *get_device_configuration(void) { vp_desc.descriptor = usbd_rndis_get_cfg(0, &vp_desc.length); return &vp_desc; } usbd_desc_t *get_device_other_speed(void) { return NULL; } /** * @brief get lang id descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_lang_id(void) { DBG printf("LangIDStrDescriptor\r\n"); return &langid_descriptor; } /** * @brief get product descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_product_string(void) { DBG printf("ProductStrDescriptor\r\n"); static usbd_desc_t device_product_string_disc; device_product_string_disc.length = usbd_unicode_convert((uint8_t *)USBD_PRODUCT_FS_STRING, USBD_StrDesc); device_product_string_disc.descriptor = USBD_StrDesc; return &device_product_string_disc; } /** * @brief get manufacturer descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_manufacturer_string(void) { DBG printf("ManufacturerStrDescriptor\r\n"); static usbd_desc_t device_manufacturer_string_disc; device_manufacturer_string_disc.length = usbd_unicode_convert((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc); device_manufacturer_string_disc.descriptor = USBD_StrDesc; return &device_manufacturer_string_disc; } /** * @brief get serial descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_serial_string(void) { DBG printf("SerialStrDescriptor\r\n"); static usbd_desc_t device_serial_string_disc; device_serial_string_disc.length = usbd_unicode_convert((uint8_t *)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc); device_serial_string_disc.descriptor = USBD_StrDesc; return &device_serial_string_disc; } /** * @brief get device config descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_config_string(void) { DBG printf("ConfigStrDescriptor\r\n"); static usbd_desc_t device_config_string_disc; device_config_string_disc.length = usbd_unicode_convert((uint8_t *)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc); device_config_string_disc.descriptor = USBD_StrDesc; return &device_config_string_disc; } /** * @brief get interface descriptor * @param none * @retval usbd_desc */ usbd_desc_t *get_device_interface_string(void) { DBG printf("InterfaceStrDescriptor\r\n"); static usbd_desc_t device_interface_string_disc; device_interface_string_disc.length = usbd_unicode_convert((uint8_t *)USBD_INTERFACE_FS_STRING, USBD_StrDesc); device_interface_string_disc.descriptor = USBD_StrDesc; return &device_interface_string_disc; }