[style] format files by clang-format

This commit is contained in:
jzlv 2021-06-20 12:25:46 +08:00
parent 47ce9f871c
commit d427e7fdda
1131 changed files with 7338846 additions and 422042 deletions

View file

@ -1,8 +1,7 @@
#include "usbd_core.h"
#include "usbd_audio.h"
struct usbd_audio_control_info audio_control_info = {0xdb00,0x0000,0x0100,0xf600,0};
struct usbd_audio_control_info audio_control_info = { 0xdb00, 0x0000, 0x0100, 0xf600, 0 };
int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
{
@ -10,87 +9,88 @@ int audio_class_request_handler(struct usb_setup_packet *setup, uint8_t **data,
"bRequest 0x%02x, bmRequestType 0x%02x len %d",
setup->bRequest, setup->bmRequestType, *len);
switch (setup->bRequest)
{
switch (setup->bRequest) {
case AUDIO_REQUEST_SET_CUR:
if(setup->wValueL == 0x01)
{
if(setup->wValueH == AUDIO_FU_CONTROL_MUTE)
{
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);
if (setup->wValueL == 0x01) {
if (setup->wValueH == AUDIO_FU_CONTROL_MUTE) {
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);
}
}
break;
case AUDIO_REQUEST_GET_CUR:
if(setup->wValueH == AUDIO_FU_CONTROL_MUTE)
{
*data = (uint8_t*)&audio_control_info.mute;
if (setup->wValueH == AUDIO_FU_CONTROL_MUTE) {
*data = (uint8_t *)&audio_control_info.mute;
*len = 1;
}
else if(setup->wValueH == AUDIO_FU_CONTROL_VOLUME)
{
*data = (uint8_t*)&audio_control_info.vol_current;
} else if (setup->wValueH == AUDIO_FU_CONTROL_VOLUME) {
*data = (uint8_t *)&audio_control_info.vol_current;
*len = 2;
}
break;
case AUDIO_REQUEST_SET_RES:
break;
break;
case AUDIO_REQUEST_GET_MIN:
*data = (uint8_t*)&audio_control_info.vol_min;
*data = (uint8_t *)&audio_control_info.vol_min;
*len = 2;
break;
case AUDIO_REQUEST_GET_MAX:
*data = (uint8_t*)&audio_control_info.vol_max;
*data = (uint8_t *)&audio_control_info.vol_max;
*len = 2;
break;
case AUDIO_REQUEST_GET_RES:
*data = (uint8_t*)&audio_control_info.vol_res;
*data = (uint8_t *)&audio_control_info.vol_res;
*len = 2;
break;
default:
USBD_LOG_ERR("Unhandled request 0x%02x", setup->bRequest);
break;
}
return 0;
}
void audio_notify_handler(uint8_t event, void* arg)
void audio_notify_handler(uint8_t event, void *arg)
{
switch (event)
{
case USB_EVENT_RESET:
switch (event) {
case USB_EVENT_RESET:
break;
case USB_EVENT_SOF:
break;
case USB_EVENT_SET_INTERFACE:
usbd_audio_set_interface_callback(((uint8_t*)arg)[3]);
break;
default:
break;
}
break;
case USB_EVENT_SOF:
break;
case USB_EVENT_SET_INTERFACE:
usbd_audio_set_interface_callback(((uint8_t *)arg)[3]);
break;
default:
break;
}
}
void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf)
{
static usbd_class_t *last_class = NULL;
static usbd_class_t *last_class = NULL;
if(last_class != class)
{
last_class = class;
usbd_class_register(class);
}
if (last_class != class) {
last_class = class;
usbd_class_register(class);
}
intf->class_handler = audio_class_request_handler;
intf->custom_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = audio_notify_handler;
usbd_class_add_interface(class,intf);
intf->class_handler = audio_class_request_handler;
intf->custom_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = audio_notify_handler;
usbd_class_add_interface(class, intf);
}

View file

@ -20,152 +20,148 @@ extern "C" {
/** Audio Interface Subclass Codes
* Refer to Table A-2 from audio10.pdf
*/
#define AUDIO_SUBCLASS_UNDEFINED 0x00
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
#define AUDIO_SUBCLASS_MIDISTREAMING 0x03
#define AUDIO_SUBCLASS_UNDEFINED 0x00
#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01
#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02
#define AUDIO_SUBCLASS_MIDISTREAMING 0x03
#define AUDIO_PROTOCOL_UNDEFINED 0x00U
#define AUDIO_PROTOCOL_UNDEFINED 0x00U
#define AUDIO_ENDPOINT_GENERAL 0x01U
#define AUDIO_ENDPOINT_GENERAL 0x01U
/** Audio Class-Specific Control Interface Descriptor Subtypes
* Refer to Table A-5 from audio10.pdf
*/
#define AUDIO_CONTROL_UNDEFINED 0x01U
#define AUDIO_CONTROL_HEADER 0x01U
#define AUDIO_CONTROL_INPUT_TERMINAL 0x02U
#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03U
#define AUDIO_CONTROL_MIXER_UNIT 0x04U
#define AUDIO_CONTROL_SELECTOR_UNIT 0x05U
#define AUDIO_CONTROL_FEATURE_UNIT 0x06U
#define AUDIO_CONTROL_PROCESSING_UNIT 0x07U
#define AUDIO_CONTROL_EXTENSION_UNIT 0x08U
#define AUDIO_CONTROL_UNDEFINED 0x01U
#define AUDIO_CONTROL_HEADER 0x01U
#define AUDIO_CONTROL_INPUT_TERMINAL 0x02U
#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03U
#define AUDIO_CONTROL_MIXER_UNIT 0x04U
#define AUDIO_CONTROL_SELECTOR_UNIT 0x05U
#define AUDIO_CONTROL_FEATURE_UNIT 0x06U
#define AUDIO_CONTROL_PROCESSING_UNIT 0x07U
#define AUDIO_CONTROL_EXTENSION_UNIT 0x08U
/** Audio Class-Specific AS Interface Descriptor Subtypes
* Refer to Table A-6 from audio10.pdf
*/
#define AUDIO_STREAMING_UNDEFINED 0x00U
#define AUDIO_STREAMING_GENERAL 0x01U
#define AUDIO_STREAMING_FORMAT_TYPE 0x02U
#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03U
#define AUDIO_STREAMING_UNDEFINED 0x00U
#define AUDIO_STREAMING_GENERAL 0x01U
#define AUDIO_STREAMING_FORMAT_TYPE 0x02U
#define AUDIO_STREAMING_FORMAT_SPECIFIC 0x03U
/** Audio Class-Specific Request Codes
* Refer to Table A-9 from audio10.pdf
*/
#define AUDIO_REQUEST_UNDEFINED 0x00
#define AUDIO_REQUEST_SET_CUR 0x01
#define AUDIO_REQUEST_GET_CUR 0x81
#define AUDIO_REQUEST_SET_MIN 0x02
#define AUDIO_REQUEST_GET_MIN 0x82
#define AUDIO_REQUEST_SET_MAX 0x03
#define AUDIO_REQUEST_GET_MAX 0x83
#define AUDIO_REQUEST_SET_RES 0x04
#define AUDIO_REQUEST_GET_RES 0x84
#define AUDIO_REQUEST_SET_MEM 0x05
#define AUDIO_REQUEST_GET_MEM 0x85
#define AUDIO_REQUEST_GET_STAT 0xFF
#define AUDIO_REQUEST_UNDEFINED 0x00
#define AUDIO_REQUEST_SET_CUR 0x01
#define AUDIO_REQUEST_GET_CUR 0x81
#define AUDIO_REQUEST_SET_MIN 0x02
#define AUDIO_REQUEST_GET_MIN 0x82
#define AUDIO_REQUEST_SET_MAX 0x03
#define AUDIO_REQUEST_GET_MAX 0x83
#define AUDIO_REQUEST_SET_RES 0x04
#define AUDIO_REQUEST_GET_RES 0x84
#define AUDIO_REQUEST_SET_MEM 0x05
#define AUDIO_REQUEST_GET_MEM 0x85
#define AUDIO_REQUEST_GET_STAT 0xFF
/* Feature Unit Control Bits */
#define AUDIO_CONTROL_MUTE 0x0001
#define AUDIO_CONTROL_VOLUME 0x0002
#define AUDIO_CONTROL_BASS 0x0004
#define AUDIO_CONTROL_MID 0x0008
#define AUDIO_CONTROL_TREBLE 0x0010
#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040
#define AUDIO_CONTROL_DEALY 0x0080
#define AUDIO_CONTROL_BASS_BOOST 0x0100
#define AUDIO_CONTROL_LOUDNESS 0x0200
#define AUDIO_CONTROL_MUTE 0x0001
#define AUDIO_CONTROL_VOLUME 0x0002
#define AUDIO_CONTROL_BASS 0x0004
#define AUDIO_CONTROL_MID 0x0008
#define AUDIO_CONTROL_TREBLE 0x0010
#define AUDIO_CONTROL_GRAPHIC_EQUALIZER 0x0020
#define AUDIO_CONTROL_AUTOMATIC_GAIN 0x0040
#define AUDIO_CONTROL_DEALY 0x0080
#define AUDIO_CONTROL_BASS_BOOST 0x0100
#define AUDIO_CONTROL_LOUDNESS 0x0200
/** Feature Unit Control Selectors
* Refer to Table A-11 from audio10.pdf
*/
#define AUDIO_FU_CONTROL_MUTE 0x01
#define AUDIO_FU_CONTROL_VOLUME 0x02
#define AUDIO_FU_CONTROL_BASS 0x03
#define AUDIO_FU_CONTROL_MID 0x04
#define AUDIO_FU_CONTROL_TREBLE 0x05
#define AUDIO_FU_CONTROL_GRAPHIC_EQUALIZER 0x06
#define AUDIO_FU_CONTROL_AUTOMATIC_GAIN 0x07
#define AUDIO_FU_CONTROL_DELAY 0x08
#define AUDIO_FU_CONTROL_BASS_BOOST 0x09
#define AUDIO_FU_CONTROL_LOUDNESS 0x0A
#define AUDIO_FU_CONTROL_MUTE 0x01
#define AUDIO_FU_CONTROL_VOLUME 0x02
#define AUDIO_FU_CONTROL_BASS 0x03
#define AUDIO_FU_CONTROL_MID 0x04
#define AUDIO_FU_CONTROL_TREBLE 0x05
#define AUDIO_FU_CONTROL_GRAPHIC_EQUALIZER 0x06
#define AUDIO_FU_CONTROL_AUTOMATIC_GAIN 0x07
#define AUDIO_FU_CONTROL_DELAY 0x08
#define AUDIO_FU_CONTROL_BASS_BOOST 0x09
#define AUDIO_FU_CONTROL_LOUDNESS 0x0A
/* Audio Descriptor Types */
#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20
#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21
#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22
#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25
#define AUDIO_UNDEFINED_DESCRIPTOR_TYPE 0x20
#define AUDIO_DEVICE_DESCRIPTOR_TYPE 0x21
#define AUDIO_CONFIGURATION_DESCRIPTOR_TYPE 0x22
#define AUDIO_STRING_DESCRIPTOR_TYPE 0x23
#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24
#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25
/* Audio Data Format Type I Codes */
#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000
#define AUDIO_FORMAT_PCM 0x0001
#define AUDIO_FORMAT_PCM8 0x0002
#define AUDIO_FORMAT_IEEE_FLOAT 0x0003
#define AUDIO_FORMAT_ALAW 0x0004
#define AUDIO_FORMAT_MULAW 0x0005
#define AUDIO_FORMAT_TYPE_I_UNDEFINED 0x0000
#define AUDIO_FORMAT_PCM 0x0001
#define AUDIO_FORMAT_PCM8 0x0002
#define AUDIO_FORMAT_IEEE_FLOAT 0x0003
#define AUDIO_FORMAT_ALAW 0x0004
#define AUDIO_FORMAT_MULAW 0x0005
/* Predefined Audio Channel Configuration Bits */
#define AUDIO_CHANNEL_M 0x0000 /* Mono */
#define AUDIO_CHANNEL_L 0x0001 /* Left Front */
#define AUDIO_CHANNEL_R 0x0002 /* Right Front */
#define AUDIO_CHANNEL_C 0x0004 /* Center Front */
#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */
#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */
#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */
#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */
#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */
#define AUDIO_CHANNEL_S 0x0100 /* Surround */
#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */
#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */
#define AUDIO_CHANNEL_T 0x0800 /* Top */
#define AUDIO_FORMAT_TYPE_I 0x01
#define AUDIO_FORMAT_TYPE_II 0x02
#define AUDIO_FORMAT_TYPE_III 0x03
#define AUDIO_CHANNEL_M 0x0000 /* Mono */
#define AUDIO_CHANNEL_L 0x0001 /* Left Front */
#define AUDIO_CHANNEL_R 0x0002 /* Right Front */
#define AUDIO_CHANNEL_C 0x0004 /* Center Front */
#define AUDIO_CHANNEL_LFE 0x0008 /* Low Freq. Enhance. */
#define AUDIO_CHANNEL_LS 0x0010 /* Left Surround */
#define AUDIO_CHANNEL_RS 0x0020 /* Right Surround */
#define AUDIO_CHANNEL_LC 0x0040 /* Left of Center */
#define AUDIO_CHANNEL_RC 0x0080 /* Right of Center */
#define AUDIO_CHANNEL_S 0x0100 /* Surround */
#define AUDIO_CHANNEL_SL 0x0200 /* Side Left */
#define AUDIO_CHANNEL_SR 0x0400 /* Side Right */
#define AUDIO_CHANNEL_T 0x0800 /* Top */
#define AUDIO_FORMAT_TYPE_I 0x01
#define AUDIO_FORMAT_TYPE_II 0x02
#define AUDIO_FORMAT_TYPE_III 0x03
/** USB Terminal Types
* Refer to Table 2-1 - Table 2-4 from termt10.pdf
*/
enum usb_audio_terminal_types {
/* USB Terminal Types */
USB_AUDIO_USB_UNDEFINED = 0x0100,
USB_AUDIO_USB_STREAMING = 0x0101,
USB_AUDIO_USB_VENDOR_SPEC = 0x01FF,
/* USB Terminal Types */
USB_AUDIO_USB_UNDEFINED = 0x0100,
USB_AUDIO_USB_STREAMING = 0x0101,
USB_AUDIO_USB_VENDOR_SPEC = 0x01FF,
/* Input Terminal Types */
USB_AUDIO_IN_UNDEFINED = 0x0200,
USB_AUDIO_IN_MICROPHONE = 0x0201,
USB_AUDIO_IN_DESKTOP_MIC = 0x0202,
USB_AUDIO_IN_PERSONAL_MIC = 0x0203,
USB_AUDIO_IN_OM_DIR_MIC = 0x0204,
USB_AUDIO_IN_MIC_ARRAY = 0x0205,
USB_AUDIO_IN_PROC_MIC_ARRAY = 0x0205,
/* Input Terminal Types */
USB_AUDIO_IN_UNDEFINED = 0x0200,
USB_AUDIO_IN_MICROPHONE = 0x0201,
USB_AUDIO_IN_DESKTOP_MIC = 0x0202,
USB_AUDIO_IN_PERSONAL_MIC = 0x0203,
USB_AUDIO_IN_OM_DIR_MIC = 0x0204,
USB_AUDIO_IN_MIC_ARRAY = 0x0205,
USB_AUDIO_IN_PROC_MIC_ARRAY = 0x0205,
/* Output Terminal Types */
USB_AUDIO_OUT_UNDEFINED = 0x0300,
USB_AUDIO_OUT_SPEAKER = 0x0301,
USB_AUDIO_OUT_HEADPHONES = 0x0302,
USB_AUDIO_OUT_HEAD_AUDIO = 0x0303,
USB_AUDIO_OUT_DESKTOP_SPEAKER = 0x0304,
USB_AUDIO_OUT_ROOM_SPEAKER = 0x0305,
USB_AUDIO_OUT_COMM_SPEAKER = 0x0306,
USB_AUDIO_OUT_LOW_FREQ_SPEAKER = 0x0307,
/* Output Terminal Types */
USB_AUDIO_OUT_UNDEFINED = 0x0300,
USB_AUDIO_OUT_SPEAKER = 0x0301,
USB_AUDIO_OUT_HEADPHONES = 0x0302,
USB_AUDIO_OUT_HEAD_AUDIO = 0x0303,
USB_AUDIO_OUT_DESKTOP_SPEAKER = 0x0304,
USB_AUDIO_OUT_ROOM_SPEAKER = 0x0305,
USB_AUDIO_OUT_COMM_SPEAKER = 0x0306,
USB_AUDIO_OUT_LOW_FREQ_SPEAKER = 0x0307,
/* Bi-directional Terminal Types */
USB_AUDIO_IO_UNDEFINED = 0x0400,
USB_AUDIO_IO_HANDSET = 0x0401,
USB_AUDIO_IO_HEADSET = 0x0402,
USB_AUDIO_IO_SPEAKERPHONE_ECHO_NONE = 0x0403,
USB_AUDIO_IO_SPEAKERPHONE_ECHO_SUP = 0x0404,
USB_AUDIO_IO_SPEAKERPHONE_ECHO_CAN = 0x0405,
/* Bi-directional Terminal Types */
USB_AUDIO_IO_UNDEFINED = 0x0400,
USB_AUDIO_IO_HANDSET = 0x0401,
USB_AUDIO_IO_HEADSET = 0x0402,
USB_AUDIO_IO_SPEAKERPHONE_ECHO_NONE = 0x0403,
USB_AUDIO_IO_SPEAKERPHONE_ECHO_SUP = 0x0404,
USB_AUDIO_IO_SPEAKERPHONE_ECHO_CAN = 0x0405,
};
/**
@ -175,26 +171,26 @@ enum usb_audio_terminal_types {
* .bLength.
*/
struct cs_ac_if_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bcdADC;
uint16_t wTotalLength;
uint8_t bInCollection;
uint8_t baInterfaceNr[2];
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint16_t bcdADC;
uint16_t wTotalLength;
uint8_t bInCollection;
uint8_t baInterfaceNr[2];
} __packed;
struct input_terminal_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bNrChannels;
uint16_t wChannelConfig;
uint8_t iChannelNames;
uint8_t iTerminal;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bNrChannels;
uint16_t wChannelConfig;
uint8_t iChannelNames;
uint8_t iTerminal;
} __packed;
/**
@ -202,80 +198,80 @@ struct input_terminal_descriptor {
* This structure is just a helper not a common type.
*/
struct feature_unit_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;
uint16_t bmaControls[1];
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bUnitID;
uint8_t bSourceID;
uint8_t bControlSize;
uint16_t bmaControls[1];
} __packed;
struct output_terminal_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bSourceID;
uint8_t iTerminal;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalID;
uint16_t wTerminalType;
uint8_t bAssocTerminal;
uint8_t bSourceID;
uint8_t iTerminal;
} __packed;
struct as_cs_interface_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalLink;
uint8_t bDelay;
uint16_t wFormatTag;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bTerminalLink;
uint8_t bDelay;
uint16_t wFormatTag;
} __packed;
struct format_type_i_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bFormatType;
uint8_t bNrChannels;
uint8_t bSubframeSize;
uint8_t bBitResolution;
uint8_t bSamFreqType;
uint8_t tSamFreq[3];
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bFormatType;
uint8_t bNrChannels;
uint8_t bSubframeSize;
uint8_t bBitResolution;
uint8_t bSamFreqType;
uint8_t tSamFreq[3];
} __packed;
struct std_as_ad_endpoint_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
uint8_t bRefresh;
uint8_t bSynchAddress;
} __packed;
struct cs_as_ad_ep_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmAttributes;
uint8_t bLockDelayUnits;
uint16_t wLockDelay;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bmAttributes;
uint8_t bLockDelayUnits;
uint16_t wLockDelay;
} __packed;
struct usbd_audio_control_info
{
uint16_t vol_min;
uint16_t vol_max;
uint16_t vol_res;
uint16_t vol_current;
uint8_t mute;
struct usbd_audio_control_info {
uint16_t vol_min;
uint16_t vol_max;
uint16_t vol_res;
uint16_t vol_current;
uint8_t mute;
};
void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf);
void usbd_audio_set_interface_callback(uint8_t value);
#ifdef __cplusplus
}
#endif
void usbd_audio_add_interface(usbd_class_t *class, usbd_interface_t *intf);
void usbd_audio_set_interface_callback(uint8_t value);
#endif /* _USB_AUDIO_H_ */

View file

@ -1,58 +1,57 @@
/**
* @file usbd_cdc.c
* @brief
*
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
const char *stop_name[] = {"1", "1.5", "2"};
const char *parity_name[] = {"N","O","E","M","S"};
const char *stop_name[] = { "1", "1.5", "2" };
const char *parity_name[] = { "N", "O", "E", "M", "S" };
/* Device data structure */
struct cdc_acm_cfg_private {
/* CDC ACM line coding properties. LE order */
struct cdc_line_coding line_coding;
/* CDC ACM line state bitmap, DTE side */
uint8_t line_state;
/* CDC ACM serial state bitmap, DCE side */
uint8_t serial_state;
/* CDC ACM notification sent status */
uint8_t notification_sent;
/* CDC ACM configured flag */
bool configured;
/* CDC ACM suspended flag */
bool suspended;
uint32_t uart_first_init_flag;
/* CDC ACM line coding properties. LE order */
struct cdc_line_coding line_coding;
/* CDC ACM line state bitmap, DTE side */
uint8_t line_state;
/* CDC ACM serial state bitmap, DCE side */
uint8_t serial_state;
/* CDC ACM notification sent status */
uint8_t notification_sent;
/* CDC ACM configured flag */
bool configured;
/* CDC ACM suspended flag */
bool suspended;
uint32_t uart_first_init_flag;
} usbd_cdc_acm_cfg;
static void usbd_cdc_acm_reset(void)
{
usbd_cdc_acm_cfg.line_coding.dwDTERate = 2000000;
usbd_cdc_acm_cfg.line_coding.bDataBits = 8;
usbd_cdc_acm_cfg.line_coding.bParityType = 0;
usbd_cdc_acm_cfg.line_coding.bCharFormat = 0;
usbd_cdc_acm_cfg.configured = false;
usbd_cdc_acm_cfg.uart_first_init_flag = 0;
usbd_cdc_acm_cfg.line_coding.dwDTERate = 2000000;
usbd_cdc_acm_cfg.line_coding.bDataBits = 8;
usbd_cdc_acm_cfg.line_coding.bParityType = 0;
usbd_cdc_acm_cfg.line_coding.bCharFormat = 0;
usbd_cdc_acm_cfg.configured = false;
usbd_cdc_acm_cfg.uart_first_init_flag = 0;
}
/**
@ -64,113 +63,106 @@ static void usbd_cdc_acm_reset(void)
*
* @return 0 on success, negative errno code on fail.
*/
static int cdc_acm_class_request_handler(struct usb_setup_packet *pSetup,uint8_t **data,uint32_t *len)
static int cdc_acm_class_request_handler(struct usb_setup_packet *pSetup, uint8_t **data, uint32_t *len)
{
switch (pSetup->bRequest)
{
case CDC_REQUEST_SET_LINE_CODING:
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
if(usbd_cdc_acm_cfg.uart_first_init_flag == 0)
{
usbd_cdc_acm_cfg.uart_first_init_flag = 1;
return 0;
}
memcpy(&usbd_cdc_acm_cfg.line_coding,*data, sizeof(usbd_cdc_acm_cfg.line_coding));
USBD_LOG_DBG("CDC_SET_LINE_CODING <%d %d %s %s>\r\n",
usbd_cdc_acm_cfg.line_coding.dwDTERate,
usbd_cdc_acm_cfg.line_coding.bDataBits,
parity_name[usbd_cdc_acm_cfg.line_coding.bParityType],
stop_name[usbd_cdc_acm_cfg.line_coding.bCharFormat]
);
usbd_cdc_acm_set_line_coding(usbd_cdc_acm_cfg.line_coding.dwDTERate,usbd_cdc_acm_cfg.line_coding.bDataBits,\
usbd_cdc_acm_cfg.line_coding.bParityType,usbd_cdc_acm_cfg.line_coding.bCharFormat);
break;
switch (pSetup->bRequest) {
case CDC_REQUEST_SET_LINE_CODING:
case CDC_REQUEST_SET_CONTROL_LINE_STATE:
usbd_cdc_acm_cfg.line_state = (uint8_t)pSetup->wValue;
bool dtr = (pSetup->wValue & 0x01);
bool rts = (pSetup->wValue & 0x02);
USBD_LOG_DBG("DTR 0x%x,RTS 0x%x\r\n",
dtr,rts);
usbd_cdc_acm_set_dtr(dtr);
usbd_cdc_acm_set_rts(rts);
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
if (usbd_cdc_acm_cfg.uart_first_init_flag == 0) {
usbd_cdc_acm_cfg.uart_first_init_flag = 1;
return 0;
}
case CDC_REQUEST_GET_LINE_CODING:
*data = (uint8_t *)(&usbd_cdc_acm_cfg.line_coding);
*len = sizeof(usbd_cdc_acm_cfg.line_coding);
USBD_LOG_DBG("CDC_GET_LINE_CODING %d %d %d %d\r\n",
usbd_cdc_acm_cfg.line_coding.dwDTERate,
usbd_cdc_acm_cfg.line_coding.bCharFormat,
usbd_cdc_acm_cfg.line_coding.bParityType,
usbd_cdc_acm_cfg.line_coding.bDataBits);
break;
memcpy(&usbd_cdc_acm_cfg.line_coding, *data, sizeof(usbd_cdc_acm_cfg.line_coding));
USBD_LOG_DBG("CDC_SET_LINE_CODING <%d %d %s %s>\r\n",
usbd_cdc_acm_cfg.line_coding.dwDTERate,
usbd_cdc_acm_cfg.line_coding.bDataBits,
parity_name[usbd_cdc_acm_cfg.line_coding.bParityType],
stop_name[usbd_cdc_acm_cfg.line_coding.bCharFormat]);
usbd_cdc_acm_set_line_coding(usbd_cdc_acm_cfg.line_coding.dwDTERate, usbd_cdc_acm_cfg.line_coding.bDataBits,
usbd_cdc_acm_cfg.line_coding.bParityType, usbd_cdc_acm_cfg.line_coding.bCharFormat);
break;
default:
USBD_LOG_DBG("CDC ACM request 0x%x, value 0x%x\r\n",
pSetup->bRequest, pSetup->wValue);
return -1;
}
case CDC_REQUEST_SET_CONTROL_LINE_STATE:
usbd_cdc_acm_cfg.line_state = (uint8_t)pSetup->wValue;
bool dtr = (pSetup->wValue & 0x01);
bool rts = (pSetup->wValue & 0x02);
USBD_LOG_DBG("DTR 0x%x,RTS 0x%x\r\n",
dtr, rts);
usbd_cdc_acm_set_dtr(dtr);
usbd_cdc_acm_set_rts(rts);
break;
return 0;
case CDC_REQUEST_GET_LINE_CODING:
*data = (uint8_t *)(&usbd_cdc_acm_cfg.line_coding);
*len = sizeof(usbd_cdc_acm_cfg.line_coding);
USBD_LOG_DBG("CDC_GET_LINE_CODING %d %d %d %d\r\n",
usbd_cdc_acm_cfg.line_coding.dwDTERate,
usbd_cdc_acm_cfg.line_coding.bCharFormat,
usbd_cdc_acm_cfg.line_coding.bParityType,
usbd_cdc_acm_cfg.line_coding.bDataBits);
break;
default:
USBD_LOG_DBG("CDC ACM request 0x%x, value 0x%x\r\n",
pSetup->bRequest, pSetup->wValue);
return -1;
}
return 0;
}
static void cdc_notify_handler(uint8_t event, void* arg)
static void cdc_notify_handler(uint8_t event, void *arg)
{
switch (event)
{
case USB_EVENT_RESET:
usbd_cdc_acm_reset();
break;
default:
break;
}
switch (event) {
case USB_EVENT_RESET:
usbd_cdc_acm_reset();
break;
default:
break;
}
}
__weak void usbd_cdc_acm_set_line_coding(uint32_t baudrate,uint8_t databits,uint8_t parity,uint8_t stopbits)
__weak void usbd_cdc_acm_set_line_coding(uint32_t baudrate, uint8_t databits, uint8_t parity, uint8_t stopbits)
{
}
__weak void usbd_cdc_acm_set_dtr(bool dtr)
{
}
__weak void usbd_cdc_acm_set_rts(bool rts)
{
}
void usbd_cdc_add_acm_interface(usbd_class_t *class, usbd_interface_t *intf)
{
static usbd_class_t *last_class = NULL;
static usbd_class_t *last_class = NULL;
if(last_class != class)
{
last_class = class;
usbd_class_register(class);
}
if (last_class != class) {
last_class = class;
usbd_class_register(class);
}
intf->class_handler = cdc_acm_class_request_handler;
intf->custom_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = cdc_notify_handler;
usbd_class_add_interface(class,intf);
intf->class_handler = cdc_acm_class_request_handler;
intf->custom_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = cdc_notify_handler;
usbd_class_add_interface(class, intf);
}

View file

@ -12,197 +12,199 @@
#ifndef _USBD_CDC_H
#define _USBD_CDC_H
#ifdef __cplusplus
extern "C" {
#endif
/*------------------------------------------------------------------------------
* Definitions based on usbcdc11.pdf (www.usb.org)
*----------------------------------------------------------------------------*/
/* Communication device class specification version 1.10 */
#define CDC_V1_10 0x0110U
#define CDC_V1_10 0x0110U
// Communication device class specification version 1.2
#define CDC_V1_2_0 0x0120U
#define CDC_V1_2_0 0x0120U
/* Communication interface class code */
/* (usbcdc11.pdf, 4.2, Table 15) */
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02U
#define CDC_COMMUNICATION_INTERFACE_CLASS 0x02U
/* Communication interface class subclass codes */
/* (usbcdc11.pdf, 4.3, Table 16) */
#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01U
#define CDC_ABSTRACT_CONTROL_MODEL 0x02U
#define CDC_TELEPHONE_CONTROL_MODEL 0x03U
#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04U
#define CDC_CAPI_CONTROL_MODEL 0x05U
#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06U
#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07U
#define CDC_WIRELESS_HANDSET_CONTROL_MODEL 0x08U
#define CDC_DEVICE_MANAGEMENT 0x09U
#define CDC_MOBILE_DIRECT_LINE_MODEL 0x0AU
#define CDC_OBEX 0x0BU
#define CDC_ETHERNET_EMULATION_MODEL 0x0CU
#define CDC_NETWORK_CONTROL_MODEL 0x0DU
#define CDC_DIRECT_LINE_CONTROL_MODEL 0x01U
#define CDC_ABSTRACT_CONTROL_MODEL 0x02U
#define CDC_TELEPHONE_CONTROL_MODEL 0x03U
#define CDC_MULTI_CHANNEL_CONTROL_MODEL 0x04U
#define CDC_CAPI_CONTROL_MODEL 0x05U
#define CDC_ETHERNET_NETWORKING_CONTROL_MODEL 0x06U
#define CDC_ATM_NETWORKING_CONTROL_MODEL 0x07U
#define CDC_WIRELESS_HANDSET_CONTROL_MODEL 0x08U
#define CDC_DEVICE_MANAGEMENT 0x09U
#define CDC_MOBILE_DIRECT_LINE_MODEL 0x0AU
#define CDC_OBEX 0x0BU
#define CDC_ETHERNET_EMULATION_MODEL 0x0CU
#define CDC_NETWORK_CONTROL_MODEL 0x0DU
/* Communication interface class control protocol codes */
/* (usbcdc11.pdf, 4.4, Table 17) */
#define CDC_COMMON_PROTOCOL_NONE 0x00U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS 0x01U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101 0x02U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO 0x03U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_GSM_707 0x04U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_3GPP_27007 0x05U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_CDMA 0x06U
#define CDC_COMMON_PROTOCOL_ETHERNET_EMULATION_MODEL 0x07U
#define CDC_COMMON_PROTOCOL_NONE 0x00U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS 0x01U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101 0x02U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_PCCA_101_AND_ANNEXO 0x03U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_GSM_707 0x04U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_3GPP_27007 0x05U
#define CDC_COMMON_PROTOCOL_AT_COMMANDS_CDMA 0x06U
#define CDC_COMMON_PROTOCOL_ETHERNET_EMULATION_MODEL 0x07U
// NCM Communication Interface Protocol Codes
// (usbncm10.pdf, 4.2, Table 4-2)
#define CDC_NCM_PROTOCOL_NONE 0x00U
#define CDC_NCM_PROTOCOL_OEM 0xFEU
#define CDC_NCM_PROTOCOL_NONE 0x00U
#define CDC_NCM_PROTOCOL_OEM 0xFEU
/* Data interface class code */
/* (usbcdc11.pdf, 4.5, Table 18) */
#define CDC_DATA_INTERFACE_CLASS 0x0A
#define CDC_DATA_INTERFACE_CLASS 0x0A
/* Data interface class protocol codes */
/* (usbcdc11.pdf, 4.7, Table 19) */
#define CDC_DATA_PROTOCOL_ISDN_BRI 0x30
#define CDC_DATA_PROTOCOL_HDLC 0x31
#define CDC_DATA_PROTOCOL_TRANSPARENT 0x32
#define CDC_DATA_PROTOCOL_Q921_MANAGEMENT 0x50
#define CDC_DATA_PROTOCOL_Q921_DATA_LINK 0x51
#define CDC_DATA_PROTOCOL_Q921_MULTIPLEXOR 0x52
#define CDC_DATA_PROTOCOL_V42 0x90
#define CDC_DATA_PROTOCOL_EURO_ISDN 0x91
#define CDC_DATA_PROTOCOL_V24_RATE_ADAPTATION 0x92
#define CDC_DATA_PROTOCOL_CAPI 0x93
#define CDC_DATA_PROTOCOL_HOST_BASED_DRIVER 0xFD
#define CDC_DATA_PROTOCOL_DESCRIBED_IN_PUFD 0xFE
#define CDC_DATA_PROTOCOL_ISDN_BRI 0x30
#define CDC_DATA_PROTOCOL_HDLC 0x31
#define CDC_DATA_PROTOCOL_TRANSPARENT 0x32
#define CDC_DATA_PROTOCOL_Q921_MANAGEMENT 0x50
#define CDC_DATA_PROTOCOL_Q921_DATA_LINK 0x51
#define CDC_DATA_PROTOCOL_Q921_MULTIPLEXOR 0x52
#define CDC_DATA_PROTOCOL_V42 0x90
#define CDC_DATA_PROTOCOL_EURO_ISDN 0x91
#define CDC_DATA_PROTOCOL_V24_RATE_ADAPTATION 0x92
#define CDC_DATA_PROTOCOL_CAPI 0x93
#define CDC_DATA_PROTOCOL_HOST_BASED_DRIVER 0xFD
#define CDC_DATA_PROTOCOL_DESCRIBED_IN_PUFD 0xFE
/* Type values for bDescriptorType field of functional descriptors */
/* (usbcdc11.pdf, 5.2.3, Table 24) */
#define CDC_CS_INTERFACE 0x24
#define CDC_CS_ENDPOINT 0x25
#define CDC_CS_INTERFACE 0x24
#define CDC_CS_ENDPOINT 0x25
/* Type values for bDescriptorSubtype field of functional descriptors */
/* (usbcdc11.pdf, 5.2.3, Table 25) */
#define CDC_FUNC_DESC_HEADER 0x00
#define CDC_FUNC_DESC_CALL_MANAGEMENT 0x01
#define CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT 0x02
#define CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT 0x03
#define CDC_FUNC_DESC_TELEPHONE_RINGER 0x04
#define CDC_FUNC_DESC_REPORTING_CAPABILITIES 0x05
#define CDC_FUNC_DESC_UNION 0x06
#define CDC_FUNC_DESC_COUNTRY_SELECTION 0x07
#define CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES 0x08
#define CDC_FUNC_DESC_USB_TERMINAL 0x09
#define CDC_FUNC_DESC_NETWORK_CHANNEL 0x0A
#define CDC_FUNC_DESC_PROTOCOL_UNIT 0x0B
#define CDC_FUNC_DESC_EXTENSION_UNIT 0x0C
#define CDC_FUNC_DESC_MULTI_CHANNEL_MANAGEMENT 0x0D
#define CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT 0x0E
#define CDC_FUNC_DESC_ETHERNET_NETWORKING 0x0F
#define CDC_FUNC_DESC_ATM_NETWORKING 0x10
#define CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL 0x11
#define CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL 0x12
#define CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL 0x13
#define CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL 0x14
#define CDC_FUNC_DESC_OBEX 0x15
#define CDC_FUNC_DESC_COMMAND_SET 0x16
#define CDC_FUNC_DESC_COMMAND_SET_DETAIL 0x17
#define CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL 0x18
#define CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER 0x19
#define CDC_FUNC_DESC_HEADER 0x00
#define CDC_FUNC_DESC_CALL_MANAGEMENT 0x01
#define CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT 0x02
#define CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT 0x03
#define CDC_FUNC_DESC_TELEPHONE_RINGER 0x04
#define CDC_FUNC_DESC_REPORTING_CAPABILITIES 0x05
#define CDC_FUNC_DESC_UNION 0x06
#define CDC_FUNC_DESC_COUNTRY_SELECTION 0x07
#define CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES 0x08
#define CDC_FUNC_DESC_USB_TERMINAL 0x09
#define CDC_FUNC_DESC_NETWORK_CHANNEL 0x0A
#define CDC_FUNC_DESC_PROTOCOL_UNIT 0x0B
#define CDC_FUNC_DESC_EXTENSION_UNIT 0x0C
#define CDC_FUNC_DESC_MULTI_CHANNEL_MANAGEMENT 0x0D
#define CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT 0x0E
#define CDC_FUNC_DESC_ETHERNET_NETWORKING 0x0F
#define CDC_FUNC_DESC_ATM_NETWORKING 0x10
#define CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL 0x11
#define CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL 0x12
#define CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL 0x13
#define CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL 0x14
#define CDC_FUNC_DESC_OBEX 0x15
#define CDC_FUNC_DESC_COMMAND_SET 0x16
#define CDC_FUNC_DESC_COMMAND_SET_DETAIL 0x17
#define CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL 0x18
#define CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER 0x19
/* CDC class-specific request codes */
/* (usbcdc11.pdf, 6.2, Table 46) */
/* see Table 45 for info about the specific requests. */
#define CDC_REQUEST_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_REQUEST_GET_ENCAPSULATED_RESPONSE 0x01
#define CDC_REQUEST_SET_COMM_FEATURE 0x02
#define CDC_REQUEST_GET_COMM_FEATURE 0x03
#define CDC_REQUEST_CLEAR_COMM_FEATURE 0x04
#define CDC_REQUEST_SET_AUX_LINE_STATE 0x10
#define CDC_REQUEST_SET_HOOK_STATE 0x11
#define CDC_REQUEST_PULSE_SETUP 0x12
#define CDC_REQUEST_SEND_PULSE 0x13
#define CDC_REQUEST_SET_PULSE_TIME 0x14
#define CDC_REQUEST_RING_AUX_JACK 0x15
#define CDC_REQUEST_SET_LINE_CODING 0x20
#define CDC_REQUEST_GET_LINE_CODING 0x21
#define CDC_REQUEST_SET_CONTROL_LINE_STATE 0x22
#define CDC_REQUEST_SEND_BREAK 0x23
#define CDC_REQUEST_SET_RINGER_PARMS 0x30
#define CDC_REQUEST_GET_RINGER_PARMS 0x31
#define CDC_REQUEST_SET_OPERATION_PARMS 0x32
#define CDC_REQUEST_GET_OPERATION_PARMS 0x33
#define CDC_REQUEST_SET_LINE_PARMS 0x34
#define CDC_REQUEST_GET_LINE_PARMS 0x35
#define CDC_REQUEST_DIAL_DIGITS 0x36
#define CDC_REQUEST_SET_UNIT_PARAMETER 0x37
#define CDC_REQUEST_GET_UNIT_PARAMETER 0x38
#define CDC_REQUEST_CLEAR_UNIT_PARAMETER 0x39
#define CDC_REQUEST_GET_PROFILE 0x3A
#define CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS 0x40
#define CDC_REQUEST_SET_ETHERNET_PMP_FILTER 0x41
#define CDC_REQUEST_GET_ETHERNET_PMP_FILTER 0x42
#define CDC_REQUEST_SET_ETHERNET_PACKET_FILTER 0x43
#define CDC_REQUEST_GET_ETHERNET_STATISTIC 0x44
#define CDC_REQUEST_SET_ATM_DATA_FORMAT 0x50
#define CDC_REQUEST_GET_ATM_DEVICE_STATISTICS 0x51
#define CDC_REQUEST_SET_ATM_DEFAULT_VC 0x52
#define CDC_REQUEST_GET_ATM_VC_STATISTICS 0x53
#define CDC_REQUEST_SEND_ENCAPSULATED_COMMAND 0x00
#define CDC_REQUEST_GET_ENCAPSULATED_RESPONSE 0x01
#define CDC_REQUEST_SET_COMM_FEATURE 0x02
#define CDC_REQUEST_GET_COMM_FEATURE 0x03
#define CDC_REQUEST_CLEAR_COMM_FEATURE 0x04
#define CDC_REQUEST_SET_AUX_LINE_STATE 0x10
#define CDC_REQUEST_SET_HOOK_STATE 0x11
#define CDC_REQUEST_PULSE_SETUP 0x12
#define CDC_REQUEST_SEND_PULSE 0x13
#define CDC_REQUEST_SET_PULSE_TIME 0x14
#define CDC_REQUEST_RING_AUX_JACK 0x15
#define CDC_REQUEST_SET_LINE_CODING 0x20
#define CDC_REQUEST_GET_LINE_CODING 0x21
#define CDC_REQUEST_SET_CONTROL_LINE_STATE 0x22
#define CDC_REQUEST_SEND_BREAK 0x23
#define CDC_REQUEST_SET_RINGER_PARMS 0x30
#define CDC_REQUEST_GET_RINGER_PARMS 0x31
#define CDC_REQUEST_SET_OPERATION_PARMS 0x32
#define CDC_REQUEST_GET_OPERATION_PARMS 0x33
#define CDC_REQUEST_SET_LINE_PARMS 0x34
#define CDC_REQUEST_GET_LINE_PARMS 0x35
#define CDC_REQUEST_DIAL_DIGITS 0x36
#define CDC_REQUEST_SET_UNIT_PARAMETER 0x37
#define CDC_REQUEST_GET_UNIT_PARAMETER 0x38
#define CDC_REQUEST_CLEAR_UNIT_PARAMETER 0x39
#define CDC_REQUEST_GET_PROFILE 0x3A
#define CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS 0x40
#define CDC_REQUEST_SET_ETHERNET_PMP_FILTER 0x41
#define CDC_REQUEST_GET_ETHERNET_PMP_FILTER 0x42
#define CDC_REQUEST_SET_ETHERNET_PACKET_FILTER 0x43
#define CDC_REQUEST_GET_ETHERNET_STATISTIC 0x44
#define CDC_REQUEST_SET_ATM_DATA_FORMAT 0x50
#define CDC_REQUEST_GET_ATM_DEVICE_STATISTICS 0x51
#define CDC_REQUEST_SET_ATM_DEFAULT_VC 0x52
#define CDC_REQUEST_GET_ATM_VC_STATISTICS 0x53
/* Communication feature selector codes */
/* (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) */
#define CDC_ABSTRACT_STATE 0x01
#define CDC_COUNTRY_SETTING 0x02
#define CDC_ABSTRACT_STATE 0x01
#define CDC_COUNTRY_SETTING 0x02
/** Control Signal Bitmap Values for SetControlLineState */
#define SET_CONTROL_LINE_STATE_RTS 0x02
#define SET_CONTROL_LINE_STATE_DTR 0x01
#define SET_CONTROL_LINE_STATE_RTS 0x02
#define SET_CONTROL_LINE_STATE_DTR 0x01
/* Feature Status returned for ABSTRACT_STATE Selector */
/* (usbcdc11.pdf, 6.2.3, Table 48) */
#define CDC_IDLE_SETTING (1 << 0)
#define CDC_DATA_MULTPLEXED_STATE (1 << 1)
#define CDC_IDLE_SETTING (1 << 0)
#define CDC_DATA_MULTPLEXED_STATE (1 << 1)
/* Control signal bitmap values for the SetControlLineState request */
/* (usbcdc11.pdf, 6.2.14, Table 51) */
#define CDC_DTE_PRESENT (1 << 0)
#define CDC_ACTIVATE_CARRIER (1 << 1)
#define CDC_DTE_PRESENT (1 << 0)
#define CDC_ACTIVATE_CARRIER (1 << 1)
/* CDC class-specific notification codes */
/* (usbcdc11.pdf, 6.3, Table 68) */
/* see Table 67 for Info about class-specific notifications */
#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00
#define CDC_RESPONSE_AVAILABLE 0x01
#define CDC_AUX_JACK_HOOK_STATE 0x08
#define CDC_RING_DETECT 0x09
#define CDC_NOTIFICATION_SERIAL_STATE 0x20
#define CDC_CALL_STATE_CHANGE 0x28
#define CDC_LINE_STATE_CHANGE 0x29
#define CDC_CONNECTION_SPEED_CHANGE 0x2A
#define CDC_NOTIFICATION_NETWORK_CONNECTION 0x00
#define CDC_RESPONSE_AVAILABLE 0x01
#define CDC_AUX_JACK_HOOK_STATE 0x08
#define CDC_RING_DETECT 0x09
#define CDC_NOTIFICATION_SERIAL_STATE 0x20
#define CDC_CALL_STATE_CHANGE 0x28
#define CDC_LINE_STATE_CHANGE 0x29
#define CDC_CONNECTION_SPEED_CHANGE 0x2A
/* UART state bitmap values (Serial state notification). */
/* (usbcdc11.pdf, 6.3.5, Table 69) */
#define CDC_SERIAL_STATE_OVERRUN (1 << 6) /* receive data overrun error has occurred */
#define CDC_SERIAL_STATE_OVERRUN_Pos ( 6)
#define CDC_SERIAL_STATE_OVERRUN_Msk (1 << CDC_SERIAL_STATE_OVERRUN_Pos)
#define CDC_SERIAL_STATE_PARITY (1 << 5) /* parity error has occurred */
#define CDC_SERIAL_STATE_PARITY_Pos ( 5)
#define CDC_SERIAL_STATE_PARITY_Msk (1 << CDC_SERIAL_STATE_PARITY_Pos)
#define CDC_SERIAL_STATE_FRAMING (1 << 4) /* framing error has occurred */
#define CDC_SERIAL_STATE_FRAMING_Pos ( 4)
#define CDC_SERIAL_STATE_FRAMING_Msk (1 << CDC_SERIAL_STATE_FRAMING_Pos)
#define CDC_SERIAL_STATE_RING (1 << 3) /* state of ring signal detection */
#define CDC_SERIAL_STATE_RING_Pos ( 3)
#define CDC_SERIAL_STATE_RING_Msk (1 << CDC_SERIAL_STATE_RING_Pos)
#define CDC_SERIAL_STATE_BREAK (1 << 2) /* state of break detection */
#define CDC_SERIAL_STATE_BREAK_Pos ( 2)
#define CDC_SERIAL_STATE_BREAK_Msk (1 << CDC_SERIAL_STATE_BREAK_Pos)
#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) /* state of transmission carrier */
#define CDC_SERIAL_STATE_TX_CARRIER_Pos ( 1)
#define CDC_SERIAL_STATE_TX_CARRIER_Msk (1 << CDC_SERIAL_STATE_TX_CARRIER_Pos)
#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) /* state of receiver carrier */
#define CDC_SERIAL_STATE_RX_CARRIER_Pos ( 0)
#define CDC_SERIAL_STATE_RX_CARRIER_Msk (1 << CDC_SERIAL_STATE_RX_CARRIER_Pos)
#define CDC_SERIAL_STATE_OVERRUN (1 << 6) /* receive data overrun error has occurred */
#define CDC_SERIAL_STATE_OVERRUN_Pos (6)
#define CDC_SERIAL_STATE_OVERRUN_Msk (1 << CDC_SERIAL_STATE_OVERRUN_Pos)
#define CDC_SERIAL_STATE_PARITY (1 << 5) /* parity error has occurred */
#define CDC_SERIAL_STATE_PARITY_Pos (5)
#define CDC_SERIAL_STATE_PARITY_Msk (1 << CDC_SERIAL_STATE_PARITY_Pos)
#define CDC_SERIAL_STATE_FRAMING (1 << 4) /* framing error has occurred */
#define CDC_SERIAL_STATE_FRAMING_Pos (4)
#define CDC_SERIAL_STATE_FRAMING_Msk (1 << CDC_SERIAL_STATE_FRAMING_Pos)
#define CDC_SERIAL_STATE_RING (1 << 3) /* state of ring signal detection */
#define CDC_SERIAL_STATE_RING_Pos (3)
#define CDC_SERIAL_STATE_RING_Msk (1 << CDC_SERIAL_STATE_RING_Pos)
#define CDC_SERIAL_STATE_BREAK (1 << 2) /* state of break detection */
#define CDC_SERIAL_STATE_BREAK_Pos (2)
#define CDC_SERIAL_STATE_BREAK_Msk (1 << CDC_SERIAL_STATE_BREAK_Pos)
#define CDC_SERIAL_STATE_TX_CARRIER (1 << 1) /* state of transmission carrier */
#define CDC_SERIAL_STATE_TX_CARRIER_Pos (1)
#define CDC_SERIAL_STATE_TX_CARRIER_Msk (1 << CDC_SERIAL_STATE_TX_CARRIER_Pos)
#define CDC_SERIAL_STATE_RX_CARRIER (1 << 0) /* state of receiver carrier */
#define CDC_SERIAL_STATE_RX_CARRIER_Pos (0)
#define CDC_SERIAL_STATE_RX_CARRIER_Msk (1 << CDC_SERIAL_STATE_RX_CARRIER_Pos)
/*------------------------------------------------------------------------------
* Structures based on usbcdc11.pdf (www.usb.org)
@ -212,165 +214,161 @@
/* (usbcdc11.pdf, 5.2.3.1) */
/* This header must precede any list of class-specific descriptors. */
struct cdc_header_descriptor {
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* Header functional descriptor subtype */
uint16_t bcdCDC; /* USB CDC specification release version */
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* Header functional descriptor subtype */
uint16_t bcdCDC; /* USB CDC specification release version */
} __packed;
/* Call management functional descriptor */
/* (usbcdc11.pdf, 5.2.3.2) */
/* Describes the processing of calls for the communication class interface. */
struct cdc_call_management_descriptor {
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* call management functional descriptor subtype */
uint8_t bmCapabilities; /* capabilities that this configuration supports */
uint8_t bDataInterface; /* interface number of the data class interface used for call management (optional) */
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* call management functional descriptor subtype */
uint8_t bmCapabilities; /* capabilities that this configuration supports */
uint8_t bDataInterface; /* interface number of the data class interface used for call management (optional) */
} __packed;
/* Abstract control management functional descriptor */
/* (usbcdc11.pdf, 5.2.3.3) */
/* Describes the command supported by the communication interface class with the Abstract Control Model subclass code. */
struct cdc_abstract_control_management_descriptor{
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* abstract control management functional descriptor subtype */
uint8_t bmCapabilities; /* capabilities supported by this configuration */
struct cdc_abstract_control_management_descriptor {
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* abstract control management functional descriptor subtype */
uint8_t bmCapabilities; /* capabilities supported by this configuration */
} __packed;
/* Union functional descriptors */
/* (usbcdc11.pdf, 5.2.3.8) */
/* Describes the relationship between a group of interfaces that can be considered to form a functional unit. */
struct cdc_union_descriptor{
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* union functional descriptor subtype */
uint8_t bMasterInterface; /* interface number designated as master */
struct cdc_union_descriptor {
uint8_t bFunctionLength; /* size of this descriptor in bytes */
uint8_t bDescriptorType; /* CS_INTERFACE descriptor type */
uint8_t bDescriptorSubtype; /* union functional descriptor subtype */
uint8_t bMasterInterface; /* interface number designated as master */
} __packed;
/* Union functional descriptors with one slave interface */
/* (usbcdc11.pdf, 5.2.3.8) */
struct cdc_union_1slave_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bControlInterface;
uint8_t bSubordinateInterface0;
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t bControlInterface;
uint8_t bSubordinateInterface0;
} __packed;
/* Line coding structure for GET_LINE_CODING / SET_LINE_CODING class requests*/
/* Format of the data returned when a GetLineCoding request is received */
/* (usbcdc11.pdf, 6.2.13) */
struct cdc_line_coding {
uint32_t dwDTERate; /* Data terminal rate in bits per second */
uint8_t bCharFormat; /* Number of stop bits */
uint8_t bParityType; /* Parity bit type */
uint8_t bDataBits; /* Number of data bits */
uint32_t dwDTERate; /* Data terminal rate in bits per second */
uint8_t bCharFormat; /* Number of stop bits */
uint8_t bParityType; /* Parity bit type */
uint8_t bDataBits; /* Number of data bits */
} __packed;
/** Data structure for the notification about SerialState */
struct cdc_acm_notification {
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t data;
uint8_t bmRequestType;
uint8_t bNotificationType;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
uint16_t data;
} __packed;
/** Ethernet Networking Functional Descriptor */
struct cdc_ecm_descriptor {
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t iMACAddress;
uint32_t bmEthernetStatistics;
uint16_t wMaxSegmentSize;
uint16_t wNumberMCFilters;
uint8_t bNumberPowerFilters;
uint8_t bFunctionLength;
uint8_t bDescriptorType;
uint8_t bDescriptorSubtype;
uint8_t iMACAddress;
uint32_t bmEthernetStatistics;
uint16_t wMaxSegmentSize;
uint16_t wNumberMCFilters;
uint8_t bNumberPowerFilters;
} __packed;
/*Length of template descriptor: 66 bytes*/
#define CDC_ACM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7)
#define CDC_ACM_DESCRIPTOR_LEN (8 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7)
#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 */
#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 */
void usbd_cdc_add_acm_interface(usbd_class_t *class, usbd_interface_t *intf);
void usbd_cdc_acm_set_line_coding(uint32_t baudrate, uint8_t databits, uint8_t parity, uint8_t stopbits);
void usbd_cdc_acm_set_dtr(bool dtr);
void usbd_cdc_acm_set_rts(bool rts);
#ifdef __cplusplus
}
#endif
#endif /* USB_CDC_H_ */

View file

@ -1,24 +1,24 @@
/**
* @file usbd_hid.c
* @brief
*
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#include "usbd_core.h"
#include "usbd_hid.h"
@ -26,21 +26,30 @@
#define HID_STATE_IDLE 0
#define HID_STATE_BUSY 1
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 hid_state;
} usbd_hid_cfg;
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 hid_state;
uint8_t report;
uint8_t current_intf_num;
usb_slist_t list;
} usbd_hid_cfg[4];
static usb_slist_t usbd_hid_class_head = USB_SLIST_OBJECT_INIT(usbd_hid_class_head);
static void usbd_hid_reset(void)
{
usbd_hid_cfg.idle_state = 0;
usbd_hid_cfg.protocol = 2;
usbd_hid_cfg.hid_state = HID_STATE_IDLE;
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);
hid_intf->hid_state = HID_STATE_IDLE;
hid_intf->idle_state = 0;
hid_intf->protocol = 0;
}
}
int hid_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
@ -50,31 +59,48 @@ int hid_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, u
setup->bmRequestType, setup->bRequest, *len);
if (REQTYPE_GET_DIR(setup->bmRequestType) == USB_REQUEST_DEVICE_TO_HOST &&
setup->bRequest == USB_REQUEST_GET_DESCRIPTOR)
{
setup->bRequest == USB_REQUEST_GET_DESCRIPTOR) {
uint8_t value = (uint8_t)(setup->wValue >> 8);
//uint8_t iface_num = (uint8_t)setup->wIndex;
uint8_t intf_num = (uint8_t)setup->wIndex;
switch (value)
struct usbd_hid_cfg_private *current_hid_intf = NULL;
usb_slist_t *i;
usb_slist_for_each(i, &usbd_hid_class_head)
{
case HID_DESCRIPTOR_TYPE_HID:
USBD_LOG("get HID Descriptor\r\n");
*data = (uint8_t*)usbd_hid_cfg.hid_descriptor;
*len = usbd_hid_cfg.hid_descriptor[0];
break;
case HID_DESCRIPTOR_TYPE_HID_REPORT:
USBD_LOG("get Report Descriptor\r\n");
*data = (uint8_t*)usbd_hid_cfg.hid_report_descriptor;
*len = usbd_hid_cfg.hid_report_descriptor_len;
break;
case HID_DESCRIPTOR_TYPE_HID_PHYSICAL:
USBD_LOG_DBG("get PHYSICAL Descriptor\r\n");
struct usbd_hid_cfg_private *hid_intf = usb_slist_entry(i, struct usbd_hid_cfg_private, list);
break;
default:
if (hid_intf->current_intf_num == intf_num) {
current_hid_intf = hid_intf;
break;
}
}
if (current_hid_intf == NULL) {
return -2;
}
switch (value) {
case HID_DESCRIPTOR_TYPE_HID:
USBD_LOG("get HID Descriptor\r\n");
*data = (uint8_t *)current_hid_intf->hid_descriptor;
*len = current_hid_intf->hid_descriptor[0];
break;
case HID_DESCRIPTOR_TYPE_HID_REPORT:
USBD_LOG("get Report Descriptor\r\n");
*data = (uint8_t *)current_hid_intf->hid_report_descriptor;
*len = current_hid_intf->hid_report_descriptor_len;
break;
case HID_DESCRIPTOR_TYPE_HID_PHYSICAL:
USBD_LOG_DBG("get PHYSICAL Descriptor\r\n");
break;
default:
return -2;
}
return 0;
}
@ -84,83 +110,118 @@ int hid_custom_request_handler(struct usb_setup_packet *setup, uint8_t **data, u
int hid_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
{
USBD_LOG("Class request:"
"bmRequestType 0x%02x bRequest 0x%02x, len %d\r\n",
setup->bmRequestType,setup->bRequest, *len);
"bmRequestType 0x%02x bRequest 0x%02x, len %d\r\n",
setup->bmRequestType, setup->bRequest, *len);
switch (setup->bRequest)
struct usbd_hid_cfg_private *current_hid_intf = NULL;
usb_slist_t *i;
usb_slist_for_each(i, &usbd_hid_class_head)
{
case HID_REQUEST_GET_IDLE:
*data = (uint8_t*)&usbd_hid_cfg.idle_state;
*len = 1;
break;
case HID_REQUEST_GET_PROTOCOL:
*data = (uint8_t*)&usbd_hid_cfg.protocol;
*len = 1;
break;
case HID_REQUEST_SET_IDLE:
usbd_hid_cfg.idle_state = setup->wValueH;
break;
case HID_REQUEST_SET_PROTOCOL:
usbd_hid_cfg.protocol = setup->wValueL;
break;
default:
USBD_LOG_ERR("Unhandled request 0x%02x\r\n", setup->bRequest);
break;
struct usbd_hid_cfg_private *hid_intf = usb_slist_entry(i, struct usbd_hid_cfg_private, list);
uint8_t intf_num = (uint8_t)setup->wIndex;
if (hid_intf->current_intf_num == intf_num) {
current_hid_intf = hid_intf;
break;
}
}
if (current_hid_intf == NULL) {
return -2;
}
switch (setup->bRequest) {
case HID_REQUEST_GET_REPORT:
*data = (uint8_t *)&current_hid_intf->report;
*len = 1;
break;
case HID_REQUEST_GET_IDLE:
*data = (uint8_t *)&current_hid_intf->idle_state;
*len = 1;
break;
case HID_REQUEST_GET_PROTOCOL:
*data = (uint8_t *)&current_hid_intf->protocol;
*len = 1;
break;
case HID_REQUEST_SET_REPORT:
current_hid_intf->report = **data;
break;
case HID_REQUEST_SET_IDLE:
current_hid_intf->idle_state = setup->wValueH;
break;
case HID_REQUEST_SET_PROTOCOL:
current_hid_intf->protocol = setup->wValueL;
break;
default:
USBD_LOG_ERR("Unhandled request 0x%02x\r\n", setup->bRequest);
break;
}
return 0;
}
static void hid_notify_handler(uint8_t event, void* arg)
static void hid_notify_handler(uint8_t event, void *arg)
{
switch (event)
{
case USB_EVENT_RESET:
usbd_hid_reset();
break;
default:
break;
}
switch (event) {
case USB_EVENT_RESET:
usbd_hid_reset();
break;
default:
break;
}
}
void usbd_hid_reset_state(void)
{
usbd_hid_cfg.hid_state = HID_STATE_IDLE;
// usbd_hid_cfg.hid_state = HID_STATE_IDLE;
}
void usbd_hid_send_report(uint8_t ep, uint8_t* data, uint8_t len)
void usbd_hid_send_report(uint8_t ep, uint8_t *data, uint8_t len)
{
if(usbd_hid_cfg.hid_state == HID_STATE_IDLE)
// if(usbd_hid_cfg.hid_state == HID_STATE_IDLE)
// {
// usbd_hid_cfg.hid_state = HID_STATE_BUSY;
// usbd_ep_write(ep, data, len, NULL);
// }
}
void usbd_hid_descriptor_register(uint8_t intf_num, const uint8_t *desc)
{
// usbd_hid_cfg.hid_descriptor = desc;
}
void usbd_hid_report_descriptor_register(uint8_t intf_num, const uint8_t *desc, uint32_t desc_len)
{
usb_slist_t *i;
usb_slist_for_each(i, &usbd_hid_class_head)
{
usbd_hid_cfg.hid_state = HID_STATE_BUSY;
usbd_ep_write(ep,data,len,NULL);
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) {
hid_intf->hid_report_descriptor = desc;
hid_intf->hid_report_descriptor_len = desc_len;
return;
}
}
}
void usbd_hid_descriptor_register(const uint8_t* desc)
{
usbd_hid_cfg.hid_descriptor = desc;
}
void usbd_hid_report_descriptor_register(const uint8_t* desc, uint32_t desc_len)
{
usbd_hid_cfg.hid_report_descriptor = desc;
usbd_hid_cfg.hid_report_descriptor_len = desc_len;
}
void usbd_hid_add_interface(usbd_class_t *class, usbd_interface_t *intf)
{
static usbd_class_t *last_class = NULL;
static usbd_class_t *last_class = NULL;
static uint8_t hid_num = 0;
if (last_class != class) {
last_class = class;
usbd_class_register(class);
}
if(last_class != class)
{
last_class = class;
usbd_class_register(class);
}
intf->class_handler = hid_class_request_handler;
intf->custom_handler = hid_custom_request_handler;
intf->vendor_handler = NULL;
intf->notify_handler = hid_notify_handler;
usbd_class_add_interface(class, intf);
intf->class_handler = hid_class_request_handler;
intf->custom_handler = hid_custom_request_handler;
intf->vendor_handler = NULL;
intf->notify_handler = hid_notify_handler;
usbd_class_add_interface(class,intf);
usbd_hid_cfg[hid_num].current_intf_num = intf->intf_num;
usb_slist_add_tail(&usbd_hid_class_head, &usbd_hid_cfg[hid_num].list);
hid_num++;
}

View file

@ -13,389 +13,332 @@ extern "C" {
#endif
/* HID Class Descriptor Types */
#define HID_DESCRIPTOR_TYPE_HID 0x21
#define HID_DESCRIPTOR_TYPE_HID_REPORT 0x22
#define HID_DESCRIPTOR_TYPE_HID_PHYSICAL 0x23
#define HID_DESCRIPTOR_TYPE_HID 0x21
#define HID_DESCRIPTOR_TYPE_HID_REPORT 0x22
#define HID_DESCRIPTOR_TYPE_HID_PHYSICAL 0x23
/* HID Class Specific Requests */
#define HID_REQUEST_GET_REPORT 0x01
#define HID_REQUEST_GET_IDLE 0x02
#define HID_REQUEST_GET_PROTOCOL 0x03
#define HID_REQUEST_SET_REPORT 0x09
#define HID_REQUEST_SET_IDLE 0x0A
#define HID_REQUEST_SET_PROTOCOL 0x0B
#define HID_REQUEST_GET_REPORT 0x01
#define HID_REQUEST_GET_IDLE 0x02
#define HID_REQUEST_GET_PROTOCOL 0x03
#define HID_REQUEST_SET_REPORT 0x09
#define HID_REQUEST_SET_IDLE 0x0A
#define HID_REQUEST_SET_PROTOCOL 0x0B
/* HID Report Definitions */
struct usb_hid_class_subdescriptor {
uint8_t bDescriptorType;
uint16_t wDescriptorLength;
uint8_t bDescriptorType;
uint16_t wDescriptorLength;
} __packed;
struct usb_hid_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdHID;
uint8_t bCountryCode;
uint8_t bNumDescriptors;
/*
* Specification says at least one Class Descriptor needs to
* be present (Report Descriptor).
*/
struct usb_hid_class_subdescriptor subdesc[1];
/*
* Specification says at least one Class Descriptor needs to
* be present (Report Descriptor).
*/
struct usb_hid_class_subdescriptor subdesc[1];
} __packed;
/* HID Items types */
#define ITEM_MAIN 0x0
#define ITEM_GLOBAL 0x1
#define ITEM_LOCAL 0x2
#define ITEM_MAIN 0x0
#define ITEM_GLOBAL 0x1
#define ITEM_LOCAL 0x2
/* HID Main Items tags */
#define ITEM_TAG_INPUT 0x8
#define ITEM_TAG_OUTPUT 0x9
#define ITEM_TAG_COLLECTION 0xA
#define ITEM_TAG_COLLECTION_END 0xC
#define ITEM_TAG_INPUT 0x8
#define ITEM_TAG_OUTPUT 0x9
#define ITEM_TAG_COLLECTION 0xA
#define ITEM_TAG_COLLECTION_END 0xC
/* HID Global Items tags */
#define ITEM_TAG_USAGE_PAGE 0x0
#define ITEM_TAG_LOGICAL_MIN 0x1
#define ITEM_TAG_LOGICAL_MAX 0x2
#define ITEM_TAG_REPORT_SIZE 0x7
#define ITEM_TAG_REPORT_ID 0x8
#define ITEM_TAG_REPORT_COUNT 0x9
#define ITEM_TAG_USAGE_PAGE 0x0
#define ITEM_TAG_LOGICAL_MIN 0x1
#define ITEM_TAG_LOGICAL_MAX 0x2
#define ITEM_TAG_REPORT_SIZE 0x7
#define ITEM_TAG_REPORT_ID 0x8
#define ITEM_TAG_REPORT_COUNT 0x9
/* HID Local Items tags */
#define ITEM_TAG_USAGE 0x0
#define ITEM_TAG_USAGE_MIN 0x1
#define ITEM_TAG_USAGE_MAX 0x2
#define ITEM_TAG_USAGE 0x0
#define ITEM_TAG_USAGE_MIN 0x1
#define ITEM_TAG_USAGE_MAX 0x2
#define HID_ITEM(bTag, bType, bSize) (((bTag & 0xF) << 4) | \
((bType & 0x3) << 2) | (bSize & 0x3))
#define HID_ITEM(bTag, bType, bSize) (((bTag & 0xF) << 4) | \
((bType & 0x3) << 2) | (bSize & 0x3))
#define HID_MAIN_ITEM(bTag, bSize) HID_ITEM(bTag, ITEM_MAIN, bSize)
#define HID_GLOBAL_ITEM(bTag, bSize) HID_ITEM(bTag, ITEM_GLOBAL, bSize)
#define HID_LOCAL_ITEM(bTag, bSize) HID_ITEM(bTag, ITEM_LOCAL, bSize)
#define HID_MAIN_ITEM(bTag, bSize) HID_ITEM(bTag, ITEM_MAIN, bSize)
#define HID_GLOBAL_ITEM(bTag, bSize) HID_ITEM(bTag, ITEM_GLOBAL, bSize)
#define HID_LOCAL_ITEM(bTag, bSize) HID_ITEM(bTag, ITEM_LOCAL, bSize)
#define HID_MI_COLLECTION HID_MAIN_ITEM(ITEM_TAG_COLLECTION, 1)
#define HID_MI_COLLECTION_END HID_MAIN_ITEM(ITEM_TAG_COLLECTION_END, \
0)
#define HID_MI_INPUT HID_MAIN_ITEM(ITEM_TAG_INPUT, 1)
#define HID_MI_OUTPUT HID_MAIN_ITEM(ITEM_TAG_OUTPUT, 1)
#define HID_MI_COLLECTION HID_MAIN_ITEM(ITEM_TAG_COLLECTION, 1)
#define HID_MI_COLLECTION_END HID_MAIN_ITEM(ITEM_TAG_COLLECTION_END, \
0)
#define HID_MI_INPUT HID_MAIN_ITEM(ITEM_TAG_INPUT, 1)
#define HID_MI_OUTPUT HID_MAIN_ITEM(ITEM_TAG_OUTPUT, 1)
#define HID_GI_USAGE_PAGE HID_GLOBAL_ITEM(ITEM_TAG_USAGE_PAGE, 1)
#define HID_GI_LOGICAL_MIN(size) HID_GLOBAL_ITEM(ITEM_TAG_LOGICAL_MIN, \
size)
#define HID_GI_LOGICAL_MAX(size) HID_GLOBAL_ITEM(ITEM_TAG_LOGICAL_MAX, \
size)
#define HID_GI_REPORT_SIZE HID_GLOBAL_ITEM(ITEM_TAG_REPORT_SIZE, \
1)
#define HID_GI_REPORT_ID HID_GLOBAL_ITEM(ITEM_TAG_REPORT_ID, \
1)
#define HID_GI_REPORT_COUNT HID_GLOBAL_ITEM(ITEM_TAG_REPORT_COUNT, \
1)
#define HID_GI_USAGE_PAGE HID_GLOBAL_ITEM(ITEM_TAG_USAGE_PAGE, 1)
#define HID_GI_LOGICAL_MIN(size) HID_GLOBAL_ITEM(ITEM_TAG_LOGICAL_MIN, \
size)
#define HID_GI_LOGICAL_MAX(size) HID_GLOBAL_ITEM(ITEM_TAG_LOGICAL_MAX, \
size)
#define HID_GI_REPORT_SIZE HID_GLOBAL_ITEM(ITEM_TAG_REPORT_SIZE, \
1)
#define HID_GI_REPORT_ID HID_GLOBAL_ITEM(ITEM_TAG_REPORT_ID, \
1)
#define HID_GI_REPORT_COUNT HID_GLOBAL_ITEM(ITEM_TAG_REPORT_COUNT, \
1)
#define HID_LI_USAGE HID_LOCAL_ITEM(ITEM_TAG_USAGE, 1)
#define HID_LI_USAGE_MIN(size) HID_LOCAL_ITEM(ITEM_TAG_USAGE_MIN, \
size)
#define HID_LI_USAGE_MAX(size) HID_LOCAL_ITEM(ITEM_TAG_USAGE_MAX, \
size)
#define HID_LI_USAGE HID_LOCAL_ITEM(ITEM_TAG_USAGE, 1)
#define HID_LI_USAGE_MIN(size) HID_LOCAL_ITEM(ITEM_TAG_USAGE_MIN, \
size)
#define HID_LI_USAGE_MAX(size) HID_LOCAL_ITEM(ITEM_TAG_USAGE_MAX, \
size)
/* Defined in Universal Serial Bus HID Usage Tables version 1.11 */
#define USAGE_GEN_DESKTOP 0x01
#define USAGE_GEN_KEYBOARD 0x07
#define USAGE_GEN_LEDS 0x08
#define USAGE_GEN_BUTTON 0x09
#define USAGE_GEN_DESKTOP 0x01
#define USAGE_GEN_KEYBOARD 0x07
#define USAGE_GEN_LEDS 0x08
#define USAGE_GEN_BUTTON 0x09
/* Generic Desktop Page usages */
#define USAGE_GEN_DESKTOP_UNDEFINED 0x00
#define USAGE_GEN_DESKTOP_POINTER 0x01
#define USAGE_GEN_DESKTOP_MOUSE 0x02
#define USAGE_GEN_DESKTOP_JOYSTICK 0x04
#define USAGE_GEN_DESKTOP_GAMEPAD 0x05
#define USAGE_GEN_DESKTOP_KEYBOARD 0x06
#define USAGE_GEN_DESKTOP_KEYPAD 0x07
#define USAGE_GEN_DESKTOP_X 0x30
#define USAGE_GEN_DESKTOP_Y 0x31
#define USAGE_GEN_DESKTOP_WHEEL 0x38
#define USAGE_GEN_DESKTOP_UNDEFINED 0x00
#define USAGE_GEN_DESKTOP_POINTER 0x01
#define USAGE_GEN_DESKTOP_MOUSE 0x02
#define USAGE_GEN_DESKTOP_JOYSTICK 0x04
#define USAGE_GEN_DESKTOP_GAMEPAD 0x05
#define USAGE_GEN_DESKTOP_KEYBOARD 0x06
#define USAGE_GEN_DESKTOP_KEYPAD 0x07
#define USAGE_GEN_DESKTOP_X 0x30
#define USAGE_GEN_DESKTOP_Y 0x31
#define USAGE_GEN_DESKTOP_WHEEL 0x38
/* Collection types */
#define COLLECTION_PHYSICAL 0x00
#define COLLECTION_APPLICATION 0x01
#define COLLECTION_PHYSICAL 0x00
#define COLLECTION_APPLICATION 0x01
/* Protocols */
#define HID_PROTOCOL_BOOT 0x00
#define HID_PROTOCOL_REPORT 0x01
#define HID_PROTOCOL_BOOT 0x00
#define HID_PROTOCOL_REPORT 0x01
/* Example HID report descriptors */
/**
* @brief Simple HID mouse report descriptor for n button mouse.
*
* @param bcnt Button count. Allowed values from 1 to 8.
* @param bcnt Button count. Allowed values from 1 to 8.
*/
#define HID_MOUSE_REPORT_DESC(bcnt) { \
/* USAGE_PAGE (Generic Desktop) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP, \
/* USAGE (Mouse) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_MOUSE, \
/* COLLECTION (Application) */ \
HID_MI_COLLECTION, COLLECTION_APPLICATION, \
/* USAGE (Pointer) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_POINTER, \
/* COLLECTION (Physical) */ \
HID_MI_COLLECTION, COLLECTION_PHYSICAL, \
/* Bits used for button signalling */ \
/* USAGE_PAGE (Button) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_BUTTON, \
/* USAGE_MINIMUM (Button 1) */ \
HID_LI_USAGE_MIN(1), 0x01, \
/* USAGE_MAXIMUM (Button bcnt) */ \
HID_LI_USAGE_MAX(1), bcnt, \
/* LOGICAL_MINIMUM (0) */ \
HID_GI_LOGICAL_MIN(1), 0x00, \
/* LOGICAL_MAXIMUM (1) */ \
HID_GI_LOGICAL_MAX(1), 0x01, \
/* REPORT_SIZE (1) */ \
HID_GI_REPORT_SIZE, 0x01, \
/* REPORT_COUNT (bcnt) */ \
HID_GI_REPORT_COUNT, bcnt, \
/* INPUT (Data,Var,Abs) */ \
HID_MI_INPUT, 0x02, \
/* Unused bits */ \
/* REPORT_SIZE (8 - bcnt) */ \
HID_GI_REPORT_SIZE, (8 - bcnt), \
/* REPORT_COUNT (1) */ \
HID_GI_REPORT_COUNT, 0x01, \
/* INPUT (Cnst,Ary,Abs) */ \
HID_MI_INPUT, 0x01, \
/* X and Y axis, scroll */ \
/* USAGE_PAGE (Generic Desktop) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP, \
/* USAGE (X) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_X, \
/* USAGE (Y) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_Y, \
/* USAGE (WHEEL) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_WHEEL, \
/* LOGICAL_MINIMUM (-127) */ \
HID_GI_LOGICAL_MIN(1), -127, \
/* LOGICAL_MAXIMUM (127) */ \
HID_GI_LOGICAL_MAX(1), 127, \
/* REPORT_SIZE (8) */ \
HID_GI_REPORT_SIZE, 0x08, \
/* REPORT_COUNT (3) */ \
HID_GI_REPORT_COUNT, 0x03, \
/* INPUT (Data,Var,Rel) */ \
HID_MI_INPUT, 0x06, \
/* END_COLLECTION */ \
HID_MI_COLLECTION_END, \
/* END_COLLECTION */ \
HID_MI_COLLECTION_END, \
}
#define HID_MOUSE_REPORT_DESC(bcnt) \
{ \
/* USAGE_PAGE (Generic Desktop) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP, /* USAGE (Mouse) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_MOUSE, /* COLLECTION (Application) */ \
HID_MI_COLLECTION, COLLECTION_APPLICATION, /* USAGE (Pointer) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_POINTER, /* COLLECTION (Physical) */ \
HID_MI_COLLECTION, COLLECTION_PHYSICAL, /* Bits used for button signalling */ /* USAGE_PAGE (Button) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_BUTTON, /* USAGE_MINIMUM (Button 1) */ \
HID_LI_USAGE_MIN(1), 0x01, /* USAGE_MAXIMUM (Button bcnt) */ \
HID_LI_USAGE_MAX(1), bcnt, /* LOGICAL_MINIMUM (0) */ \
HID_GI_LOGICAL_MIN(1), 0x00, /* LOGICAL_MAXIMUM (1) */ \
HID_GI_LOGICAL_MAX(1), 0x01, /* REPORT_SIZE (1) */ \
HID_GI_REPORT_SIZE, 0x01, /* REPORT_COUNT (bcnt) */ \
HID_GI_REPORT_COUNT, bcnt, /* INPUT (Data,Var,Abs) */ \
HID_MI_INPUT, 0x02, /* Unused bits */ /* REPORT_SIZE (8 - bcnt) */ \
HID_GI_REPORT_SIZE, (8 - bcnt), /* REPORT_COUNT (1) */ \
HID_GI_REPORT_COUNT, 0x01, /* INPUT (Cnst,Ary,Abs) */ \
HID_MI_INPUT, 0x01, /* X and Y axis, scroll */ /* USAGE_PAGE (Generic Desktop) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP, /* USAGE (X) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_X, /* USAGE (Y) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_Y, /* USAGE (WHEEL) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_WHEEL, /* LOGICAL_MINIMUM (-127) */ \
HID_GI_LOGICAL_MIN(1), -127, /* LOGICAL_MAXIMUM (127) */ \
HID_GI_LOGICAL_MAX(1), 127, /* REPORT_SIZE (8) */ \
HID_GI_REPORT_SIZE, 0x08, /* REPORT_COUNT (3) */ \
HID_GI_REPORT_COUNT, 0x03, /* INPUT (Data,Var,Rel) */ \
HID_MI_INPUT, 0x06, /* END_COLLECTION */ \
HID_MI_COLLECTION_END, /* END_COLLECTION */ \
HID_MI_COLLECTION_END, \
}
/**
* @brief Simple HID keyboard report descriptor.
*/
#define HID_KEYBOARD_REPORT_DESC() { \
/* USAGE_PAGE (Generic Desktop) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP, \
/* USAGE (Keyboard) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_KEYBOARD, \
/* COLLECTION (Application) */ \
HID_MI_COLLECTION, COLLECTION_APPLICATION, \
/* USAGE_PAGE (Keypad) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP_KEYPAD, \
/* USAGE_MINIMUM (Keyboard LeftControl) */ \
HID_LI_USAGE_MIN(1), 0xE0, \
/* USAGE_MAXIMUM (Keyboard Right GUI) */ \
HID_LI_USAGE_MAX(1), 0xE7, \
/* LOGICAL_MINIMUM (0) */ \
HID_GI_LOGICAL_MIN(1), 0x00, \
/* LOGICAL_MAXIMUM (1) */ \
HID_GI_LOGICAL_MAX(1), 0x01, \
/* REPORT_SIZE (1) */ \
HID_GI_REPORT_SIZE, 0x01, \
/* REPORT_COUNT (8) */ \
HID_GI_REPORT_COUNT, 0x08, \
/* INPUT (Data,Var,Abs) */ \
HID_MI_INPUT, 0x02, \
/* REPORT_SIZE (8) */ \
HID_GI_REPORT_SIZE, 0x08, \
/* REPORT_COUNT (1) */ \
HID_GI_REPORT_COUNT, 0x01, \
/* INPUT (Cnst,Var,Abs) */ \
HID_MI_INPUT, 0x03, \
/* REPORT_SIZE (1) */ \
HID_GI_REPORT_SIZE, 0x01, \
/* REPORT_COUNT (5) */ \
HID_GI_REPORT_COUNT, 0x05, \
/* USAGE_PAGE (LEDs) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_LEDS, \
/* USAGE_MINIMUM (Num Lock) */ \
HID_LI_USAGE_MIN(1), 0x01, \
/* USAGE_MAXIMUM (Kana) */ \
HID_LI_USAGE_MAX(1), 0x05, \
/* OUTPUT (Data,Var,Abs) */ \
HID_MI_OUTPUT, 0x02, \
/* REPORT_SIZE (3) */ \
HID_GI_REPORT_SIZE, 0x03, \
/* REPORT_COUNT (1) */ \
HID_GI_REPORT_COUNT, 0x01, \
/* OUTPUT (Cnst,Var,Abs) */ \
HID_MI_OUTPUT, 0x03, \
/* REPORT_SIZE (8) */ \
HID_GI_REPORT_SIZE, 0x08, \
/* REPORT_COUNT (6) */ \
HID_GI_REPORT_COUNT, 0x06, \
/* LOGICAL_MINIMUM (0) */ \
HID_GI_LOGICAL_MIN(1), 0x00, \
/* LOGICAL_MAXIMUM (101) */ \
HID_GI_LOGICAL_MAX(1), 0x65, \
/* USAGE_PAGE (Keypad) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP_KEYPAD, \
/* USAGE_MINIMUM (Reserved) */ \
HID_LI_USAGE_MIN(1), 0x00, \
/* USAGE_MAXIMUM (Keyboard Application) */ \
HID_LI_USAGE_MAX(1), 0x65, \
/* INPUT (Data,Ary,Abs) */ \
HID_MI_INPUT, 0x00, \
/* END_COLLECTION */ \
HID_MI_COLLECTION_END, \
}
#define HID_KEYBOARD_REPORT_DESC() \
{ \
/* USAGE_PAGE (Generic Desktop) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP, /* USAGE (Keyboard) */ \
HID_LI_USAGE, USAGE_GEN_DESKTOP_KEYBOARD, /* COLLECTION (Application) */ \
HID_MI_COLLECTION, COLLECTION_APPLICATION, /* USAGE_PAGE (Keypad) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP_KEYPAD, /* USAGE_MINIMUM (Keyboard LeftControl) */ \
HID_LI_USAGE_MIN(1), 0xE0, /* USAGE_MAXIMUM (Keyboard Right GUI) */ \
HID_LI_USAGE_MAX(1), 0xE7, /* LOGICAL_MINIMUM (0) */ \
HID_GI_LOGICAL_MIN(1), 0x00, /* LOGICAL_MAXIMUM (1) */ \
HID_GI_LOGICAL_MAX(1), 0x01, /* REPORT_SIZE (1) */ \
HID_GI_REPORT_SIZE, 0x01, /* REPORT_COUNT (8) */ \
HID_GI_REPORT_COUNT, 0x08, /* INPUT (Data,Var,Abs) */ \
HID_MI_INPUT, 0x02, /* REPORT_SIZE (8) */ \
HID_GI_REPORT_SIZE, 0x08, /* REPORT_COUNT (1) */ \
HID_GI_REPORT_COUNT, 0x01, /* INPUT (Cnst,Var,Abs) */ \
HID_MI_INPUT, 0x03, /* REPORT_SIZE (1) */ \
HID_GI_REPORT_SIZE, 0x01, /* REPORT_COUNT (5) */ \
HID_GI_REPORT_COUNT, 0x05, /* USAGE_PAGE (LEDs) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_LEDS, /* USAGE_MINIMUM (Num Lock) */ \
HID_LI_USAGE_MIN(1), 0x01, /* USAGE_MAXIMUM (Kana) */ \
HID_LI_USAGE_MAX(1), 0x05, /* OUTPUT (Data,Var,Abs) */ \
HID_MI_OUTPUT, 0x02, /* REPORT_SIZE (3) */ \
HID_GI_REPORT_SIZE, 0x03, /* REPORT_COUNT (1) */ \
HID_GI_REPORT_COUNT, 0x01, /* OUTPUT (Cnst,Var,Abs) */ \
HID_MI_OUTPUT, 0x03, /* REPORT_SIZE (8) */ \
HID_GI_REPORT_SIZE, 0x08, /* REPORT_COUNT (6) */ \
HID_GI_REPORT_COUNT, 0x06, /* LOGICAL_MINIMUM (0) */ \
HID_GI_LOGICAL_MIN(1), 0x00, /* LOGICAL_MAXIMUM (101) */ \
HID_GI_LOGICAL_MAX(1), 0x65, /* USAGE_PAGE (Keypad) */ \
HID_GI_USAGE_PAGE, USAGE_GEN_DESKTOP_KEYPAD, /* USAGE_MINIMUM (Reserved) */ \
HID_LI_USAGE_MIN(1), 0x00, /* USAGE_MAXIMUM (Keyboard Application) */ \
HID_LI_USAGE_MAX(1), 0x65, /* INPUT (Data,Ary,Abs) */ \
HID_MI_INPUT, 0x00, /* END_COLLECTION */ \
HID_MI_COLLECTION_END, \
}
/**
* @brief HID keyboard button codes.
*/
enum hid_kbd_code {
HID_KEY_A = 4,
HID_KEY_B = 5,
HID_KEY_C = 6,
HID_KEY_D = 7,
HID_KEY_E = 8,
HID_KEY_F = 9,
HID_KEY_G = 10,
HID_KEY_H = 11,
HID_KEY_I = 12,
HID_KEY_J = 13,
HID_KEY_K = 14,
HID_KEY_L = 15,
HID_KEY_M = 16,
HID_KEY_N = 17,
HID_KEY_O = 18,
HID_KEY_P = 19,
HID_KEY_Q = 20,
HID_KEY_R = 21,
HID_KEY_S = 22,
HID_KEY_T = 23,
HID_KEY_U = 24,
HID_KEY_V = 25,
HID_KEY_W = 26,
HID_KEY_X = 27,
HID_KEY_Y = 28,
HID_KEY_Z = 29,
HID_KEY_1 = 30,
HID_KEY_2 = 31,
HID_KEY_3 = 32,
HID_KEY_4 = 33,
HID_KEY_5 = 34,
HID_KEY_6 = 35,
HID_KEY_7 = 36,
HID_KEY_8 = 37,
HID_KEY_9 = 38,
HID_KEY_0 = 39,
HID_KEY_ENTER = 40,
HID_KEY_ESC = 41,
HID_KEY_BACKSPACE = 42,
HID_KEY_TAB = 43,
HID_KEY_SPACE = 44,
HID_KEY_MINUS = 45,
HID_KEY_EQUAL = 46,
HID_KEY_LEFTBRACE = 47,
HID_KEY_RIGHTBRACE = 48,
HID_KEY_BACKSLASH = 49,
HID_KEY_HASH = 50, /* Non-US # and ~ */
HID_KEY_SEMICOLON = 51,
HID_KEY_APOSTROPHE = 52,
HID_KEY_GRAVE = 53,
HID_KEY_COMMA = 54,
HID_KEY_DOT = 55,
HID_KEY_SLASH = 56,
HID_KEY_CAPSLOCK = 57,
HID_KEY_F1 = 58,
HID_KEY_F2 = 59,
HID_KEY_F3 = 60,
HID_KEY_F4 = 61,
HID_KEY_F5 = 62,
HID_KEY_F6 = 63,
HID_KEY_F7 = 64,
HID_KEY_F8 = 65,
HID_KEY_F9 = 66,
HID_KEY_F10 = 67,
HID_KEY_F11 = 68,
HID_KEY_F12 = 69,
HID_KEY_SYSRQ = 70, /* PRINTSCREEN */
HID_KEY_SCROLLLOCK = 71,
HID_KEY_PAUSE = 72,
HID_KEY_INSERT = 73,
HID_KEY_HOME = 74,
HID_KEY_PAGEUP = 75,
HID_KEY_DELETE = 76,
HID_KEY_END = 77,
HID_KEY_PAGEDOWN = 78,
HID_KEY_RIGHT = 79,
HID_KEY_LEFT = 80,
HID_KEY_DOWN = 81,
HID_KEY_UP = 82,
HID_KEY_NUMLOCK = 83,
HID_KEY_KPSLASH = 84, /* NUMPAD DIVIDE */
HID_KEY_KPASTERISK = 85, /* NUMPAD MULTIPLY */
HID_KEY_KPMINUS = 86,
HID_KEY_KPPLUS = 87,
HID_KEY_KPENTER = 88,
HID_KEY_KP_1 = 89,
HID_KEY_KP_2 = 90,
HID_KEY_KP_3 = 91,
HID_KEY_KP_4 = 92,
HID_KEY_KP_5 = 93,
HID_KEY_KP_6 = 94,
HID_KEY_KP_7 = 95,
HID_KEY_KP_8 = 96,
HID_KEY_KP_9 = 97,
HID_KEY_KP_0 = 98,
HID_KEY_A = 4,
HID_KEY_B = 5,
HID_KEY_C = 6,
HID_KEY_D = 7,
HID_KEY_E = 8,
HID_KEY_F = 9,
HID_KEY_G = 10,
HID_KEY_H = 11,
HID_KEY_I = 12,
HID_KEY_J = 13,
HID_KEY_K = 14,
HID_KEY_L = 15,
HID_KEY_M = 16,
HID_KEY_N = 17,
HID_KEY_O = 18,
HID_KEY_P = 19,
HID_KEY_Q = 20,
HID_KEY_R = 21,
HID_KEY_S = 22,
HID_KEY_T = 23,
HID_KEY_U = 24,
HID_KEY_V = 25,
HID_KEY_W = 26,
HID_KEY_X = 27,
HID_KEY_Y = 28,
HID_KEY_Z = 29,
HID_KEY_1 = 30,
HID_KEY_2 = 31,
HID_KEY_3 = 32,
HID_KEY_4 = 33,
HID_KEY_5 = 34,
HID_KEY_6 = 35,
HID_KEY_7 = 36,
HID_KEY_8 = 37,
HID_KEY_9 = 38,
HID_KEY_0 = 39,
HID_KEY_ENTER = 40,
HID_KEY_ESC = 41,
HID_KEY_BACKSPACE = 42,
HID_KEY_TAB = 43,
HID_KEY_SPACE = 44,
HID_KEY_MINUS = 45,
HID_KEY_EQUAL = 46,
HID_KEY_LEFTBRACE = 47,
HID_KEY_RIGHTBRACE = 48,
HID_KEY_BACKSLASH = 49,
HID_KEY_HASH = 50, /* Non-US # and ~ */
HID_KEY_SEMICOLON = 51,
HID_KEY_APOSTROPHE = 52,
HID_KEY_GRAVE = 53,
HID_KEY_COMMA = 54,
HID_KEY_DOT = 55,
HID_KEY_SLASH = 56,
HID_KEY_CAPSLOCK = 57,
HID_KEY_F1 = 58,
HID_KEY_F2 = 59,
HID_KEY_F3 = 60,
HID_KEY_F4 = 61,
HID_KEY_F5 = 62,
HID_KEY_F6 = 63,
HID_KEY_F7 = 64,
HID_KEY_F8 = 65,
HID_KEY_F9 = 66,
HID_KEY_F10 = 67,
HID_KEY_F11 = 68,
HID_KEY_F12 = 69,
HID_KEY_SYSRQ = 70, /* PRINTSCREEN */
HID_KEY_SCROLLLOCK = 71,
HID_KEY_PAUSE = 72,
HID_KEY_INSERT = 73,
HID_KEY_HOME = 74,
HID_KEY_PAGEUP = 75,
HID_KEY_DELETE = 76,
HID_KEY_END = 77,
HID_KEY_PAGEDOWN = 78,
HID_KEY_RIGHT = 79,
HID_KEY_LEFT = 80,
HID_KEY_DOWN = 81,
HID_KEY_UP = 82,
HID_KEY_NUMLOCK = 83,
HID_KEY_KPSLASH = 84, /* NUMPAD DIVIDE */
HID_KEY_KPASTERISK = 85, /* NUMPAD MULTIPLY */
HID_KEY_KPMINUS = 86,
HID_KEY_KPPLUS = 87,
HID_KEY_KPENTER = 88,
HID_KEY_KP_1 = 89,
HID_KEY_KP_2 = 90,
HID_KEY_KP_3 = 91,
HID_KEY_KP_4 = 92,
HID_KEY_KP_5 = 93,
HID_KEY_KP_6 = 94,
HID_KEY_KP_7 = 95,
HID_KEY_KP_8 = 96,
HID_KEY_KP_9 = 97,
HID_KEY_KP_0 = 98,
};
/**
* @brief HID keyboard modifiers.
*/
enum hid_kbd_modifier {
HID_KBD_MODIFIER_NONE = 0x00,
HID_KBD_MODIFIER_LEFT_CTRL = 0x01,
HID_KBD_MODIFIER_LEFT_SHIFT = 0x02,
HID_KBD_MODIFIER_LEFT_ALT = 0x04,
HID_KBD_MODIFIER_LEFT_UI = 0x08,
HID_KBD_MODIFIER_RIGHT_CTRL = 0x10,
HID_KBD_MODIFIER_RIGHT_SHIFT = 0x20,
HID_KBD_MODIFIER_RIGHT_ALT = 0x40,
HID_KBD_MODIFIER_RIGHT_UI = 0x80,
HID_KBD_MODIFIER_NONE = 0x00,
HID_KBD_MODIFIER_LEFT_CTRL = 0x01,
HID_KBD_MODIFIER_LEFT_SHIFT = 0x02,
HID_KBD_MODIFIER_LEFT_ALT = 0x04,
HID_KBD_MODIFIER_LEFT_UI = 0x08,
HID_KBD_MODIFIER_RIGHT_CTRL = 0x10,
HID_KBD_MODIFIER_RIGHT_SHIFT = 0x20,
HID_KBD_MODIFIER_RIGHT_ALT = 0x40,
HID_KBD_MODIFIER_RIGHT_UI = 0x80,
};
/**
* @brief HID keyboard LEDs.
*/
enum hid_kbd_led {
HID_KBD_LED_NUM_LOCK = 0x01,
HID_KBD_LED_CAPS_LOCK = 0x02,
HID_KBD_LED_SCROLL_LOCK = 0x04,
HID_KBD_LED_COMPOSE = 0x08,
HID_KBD_LED_KANA = 0x10,
HID_KBD_LED_NUM_LOCK = 0x01,
HID_KBD_LED_CAPS_LOCK = 0x02,
HID_KBD_LED_SCROLL_LOCK = 0x04,
HID_KBD_LED_COMPOSE = 0x08,
HID_KBD_LED_KANA = 0x10,
};
void usbd_hid_descriptor_register(uint8_t intf_num, const uint8_t *desc);
void usbd_hid_report_descriptor_register(uint8_t intf_num, const uint8_t *desc, uint32_t desc_len);
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);
#ifdef __cplusplus
}
#endif
void usbd_hid_descriptor_register(const uint8_t* desc);
void usbd_hid_report_descriptor_register(const uint8_t* desc, uint32_t desc_len);
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);
#endif /* _USB_HID_H_ */

File diff suppressed because it is too large Load diff

View file

@ -12,85 +12,90 @@
#ifndef _USBD_MSC_H__
#define _USBD_MSC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* MSC Subclass Codes */
#define MSC_SUBCLASS_RBC 0x01
#define MSC_SUBCLASS_SFF8020I_MMC2 0x02
#define MSC_SUBCLASS_QIC157 0x03
#define MSC_SUBCLASS_UFI 0x04
#define MSC_SUBCLASS_SFF8070I 0x05
#define MSC_SUBCLASS_SCSI 0x06
#define MSC_SUBCLASS_RBC 0x01
#define MSC_SUBCLASS_SFF8020I_MMC2 0x02
#define MSC_SUBCLASS_QIC157 0x03
#define MSC_SUBCLASS_UFI 0x04
#define MSC_SUBCLASS_SFF8070I 0x05
#define MSC_SUBCLASS_SCSI 0x06
/* MSC Protocol Codes */
#define MSC_PROTOCOL_CBI_INT 0x00
#define MSC_PROTOCOL_CBI_NOINT 0x01
#define MSC_PROTOCOL_BULK_ONLY 0x50
#define MSC_PROTOCOL_CBI_INT 0x00
#define MSC_PROTOCOL_CBI_NOINT 0x01
#define MSC_PROTOCOL_BULK_ONLY 0x50
/* MSC Request Codes */
#define MSC_REQUEST_RESET 0xFF
#define MSC_REQUEST_GET_MAX_LUN 0xFE
#define MSC_REQUEST_RESET 0xFF
#define MSC_REQUEST_GET_MAX_LUN 0xFE
/** MSC Command Block Wrapper (CBW) Signature */
#define MSC_CBW_Signature 0x43425355
#define MSC_CBW_Signature 0x43425355
/** Bulk-only Command Status Wrapper (CSW) Signature */
#define MSC_CSW_Signature 0x53425355
#define MSC_CSW_Signature 0x53425355
/** MSC Command Block Status Values */
#define CSW_STATUS_CMD_PASSED 0x00
#define CSW_STATUS_CMD_FAILED 0x01
#define CSW_STATUS_PHASE_ERROR 0x02
#define CSW_STATUS_CMD_PASSED 0x00
#define CSW_STATUS_CMD_FAILED 0x01
#define CSW_STATUS_PHASE_ERROR 0x02
/** MSC Bulk-Only Command Block Wrapper (CBW) */
struct CBW {
uint32_t Signature;
uint32_t Tag;
uint32_t DataLength;
uint8_t Flags;
uint8_t LUN;
uint8_t CBLength;
uint8_t CB[16];
uint32_t Signature;
uint32_t Tag;
uint32_t DataLength;
uint8_t Flags;
uint8_t LUN;
uint8_t CBLength;
uint8_t CB[16];
} __packed;
/** MSC Bulk-Only Command Status Wrapper (CSW) */
struct CSW {
uint32_t Signature;
uint32_t Tag;
uint32_t DataResidue;
uint8_t Status;
uint32_t Signature;
uint32_t Tag;
uint32_t DataResidue;
uint8_t Status;
} __packed;
/*Length of template descriptor: 23 bytes*/
#define MSC_DESCRIPTOR_LEN (9 + 7 + 7)
#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 */
#define MSC_DESCRIPTOR_LEN (9 + 7 + 7)
#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 */
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);
int usbd_msc_sector_read(uint32_t sector,uint8_t* buffer,uint32_t length);
int usbd_msc_sector_write(uint32_t sector,uint8_t* buffer,uint32_t length);
int usbd_msc_sector_read(uint32_t sector, uint8_t *buffer, uint32_t length);
int usbd_msc_sector_write(uint32_t sector, uint8_t *buffer, uint32_t length);
#ifdef __cplusplus
}
#endif
#endif /* USB_MSC_H_ */

View file

@ -48,233 +48,222 @@
#define SCSI_VERIFY12 0xAF
/* SCSI Sense Key */
#define SCSI_SENSE_NONE 0x00
#define SCSI_SENSE_RECOVERED_ERROR 0x01
#define SCSI_SENSE_NOT_READY 0x02
#define SCSI_SENSE_MEDIUM_ERROR 0x03
#define SCSI_SENSE_HARDWARE_ERROR 0x04
#define SCSI_SENSE_ILLEGAL_REQUEST 0x05
#define SCSI_SENSE_UNIT_ATTENTION 0x06
#define SCSI_SENSE_DATA_PROTECT 0x07
#define SCSI_SENSE_FIRMWARE_ERROR 0x08
#define SCSI_SENSE_ABORTED_COMMAND 0x0b
#define SCSI_SENSE_EQUAL 0x0c
#define SCSI_SENSE_VOLUME_OVERFLOW 0x0d
#define SCSI_SENSE_MISCOMPARE 0x0e
#define SCSI_SENSE_NONE 0x00
#define SCSI_SENSE_RECOVERED_ERROR 0x01
#define SCSI_SENSE_NOT_READY 0x02
#define SCSI_SENSE_MEDIUM_ERROR 0x03
#define SCSI_SENSE_HARDWARE_ERROR 0x04
#define SCSI_SENSE_ILLEGAL_REQUEST 0x05
#define SCSI_SENSE_UNIT_ATTENTION 0x06
#define SCSI_SENSE_DATA_PROTECT 0x07
#define SCSI_SENSE_FIRMWARE_ERROR 0x08
#define SCSI_SENSE_ABORTED_COMMAND 0x0b
#define SCSI_SENSE_EQUAL 0x0c
#define SCSI_SENSE_VOLUME_OVERFLOW 0x0d
#define SCSI_SENSE_MISCOMPARE 0x0e
//--------------------------------------------------------------------+
// SCSI Primary Command (SPC-4)
//--------------------------------------------------------------------+
/// SCSI Test Unit Ready Command
typedef struct __packed
{
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY
uint8_t lun ; ///< Logical Unit
uint8_t reserved[3] ;
uint8_t control ;
typedef struct __packed {
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_TEST_UNIT_READY
uint8_t lun; ///< Logical Unit
uint8_t reserved[3];
uint8_t control;
} scsi_test_unit_ready_cmd_t;
/// SCSI Inquiry Command
typedef struct __packed
{
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY
uint8_t reserved1 ;
uint8_t page_code ;
uint8_t reserved2 ;
uint8_t alloc_length ; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred.
uint8_t control ;
typedef struct __packed {
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_INQUIRY
uint8_t reserved1;
uint8_t page_code;
uint8_t reserved2;
uint8_t alloc_length; ///< specifies the maximum number of bytes that USB host has allocated in the Data-In Buffer. An allocation length of zero specifies that no data shall be transferred.
uint8_t control;
} scsi_inquiry_cmd_t, scsi_request_sense_cmd_t;
/// SCSI Inquiry Response Data
typedef struct __packed
{
uint8_t peripheral_device_type : 5;
uint8_t peripheral_qualifier : 3;
typedef struct __packed {
uint8_t peripheral_device_type : 5;
uint8_t peripheral_qualifier : 3;
uint8_t : 7;
uint8_t is_removable : 1;
uint8_t : 7;
uint8_t is_removable : 1;
uint8_t version;
uint8_t version;
uint8_t response_data_format : 4;
uint8_t hierarchical_support : 1;
uint8_t normal_aca : 1;
uint8_t : 2;
uint8_t response_data_format : 4;
uint8_t hierarchical_support : 1;
uint8_t normal_aca : 1;
uint8_t : 2;
uint8_t additional_length;
uint8_t additional_length;
uint8_t protect : 1;
uint8_t : 2;
uint8_t third_party_copy : 1;
uint8_t target_port_group_support : 2;
uint8_t access_control_coordinator : 1;
uint8_t scc_support : 1;
uint8_t protect : 1;
uint8_t : 2;
uint8_t third_party_copy : 1;
uint8_t target_port_group_support : 2;
uint8_t access_control_coordinator : 1;
uint8_t scc_support : 1;
uint8_t addr16 : 1;
uint8_t : 3;
uint8_t multi_port : 1;
uint8_t : 1; // vendor specific
uint8_t enclosure_service : 1;
uint8_t : 1;
uint8_t addr16 : 1;
uint8_t : 3;
uint8_t multi_port : 1;
uint8_t : 1; // vendor specific
uint8_t enclosure_service : 1;
uint8_t : 1;
uint8_t : 1; // vendor specific
uint8_t cmd_que : 1;
uint8_t : 2;
uint8_t sync : 1;
uint8_t wbus16 : 1;
uint8_t : 2;
uint8_t : 1; // vendor specific
uint8_t cmd_que : 1;
uint8_t : 2;
uint8_t sync : 1;
uint8_t wbus16 : 1;
uint8_t : 2;
uint8_t vendor_id[8] ; ///< 8 bytes of ASCII data identifying the vendor of the product.
uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor.
uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor.
uint8_t vendor_id[8]; ///< 8 bytes of ASCII data identifying the vendor of the product.
uint8_t product_id[16]; ///< 16 bytes of ASCII data defined by the vendor.
uint8_t product_rev[4]; ///< 4 bytes of ASCII data defined by the vendor.
} scsi_inquiry_resp_t;
typedef struct __packed
{
uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format
uint8_t valid : 1;
typedef struct __packed {
uint8_t response_code : 7; ///< 70h - current errors, Fixed Format 71h - deferred errors, Fixed Format
uint8_t valid : 1;
uint8_t reserved;
uint8_t reserved;
uint8_t sense_key : 4;
uint8_t : 1;
uint8_t ili : 1; ///< Incorrect length indicator
uint8_t end_of_medium : 1;
uint8_t filemark : 1;
uint8_t sense_key : 4;
uint8_t : 1;
uint8_t ili : 1; ///< Incorrect length indicator
uint8_t end_of_medium : 1;
uint8_t filemark : 1;
uint32_t information;
uint8_t add_sense_len;
uint32_t command_specific_info;
uint8_t add_sense_code;
uint8_t add_sense_qualifier;
uint8_t field_replaceable_unit_code;
uint32_t information;
uint8_t add_sense_len;
uint32_t command_specific_info;
uint8_t add_sense_code;
uint8_t add_sense_qualifier;
uint8_t field_replaceable_unit_code;
uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout
uint8_t sense_key_specific[3]; ///< sense key specific valid bit is bit 7 of key[0], aka MSB in Big Endian layout
} scsi_sense_fixed_resp_t;
typedef struct __packed
{
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6
typedef struct __packed {
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_MODE_SENSE_6
uint8_t : 3;
uint8_t disable_block_descriptor : 1;
uint8_t : 4;
uint8_t : 3;
uint8_t disable_block_descriptor : 1;
uint8_t : 4;
uint8_t page_code : 6;
uint8_t page_control : 2;
uint8_t page_code : 6;
uint8_t page_control : 2;
uint8_t subpage_code;
uint8_t alloc_length;
uint8_t control;
uint8_t subpage_code;
uint8_t alloc_length;
uint8_t control;
} scsi_mode_sense6_cmd_t;
// This is only a Mode parameter header(6).
typedef struct __packed
{
uint8_t data_len;
uint8_t medium_type;
typedef struct __packed {
uint8_t data_len;
uint8_t medium_type;
uint8_t reserved : 7;
bool write_protected : 1;
uint8_t reserved : 7;
bool write_protected : 1;
uint8_t block_descriptor_len;
uint8_t block_descriptor_len;
} scsi_mode_sense6_resp_t;
typedef struct
typedef struct
{
uint8_t cmd_code;
uint8_t cmd_code;
uint8_t reserved1:3;
uint8_t disable_block_descriptor: 1;
uint8_t long_LBA:1;
uint8_t reserved2:3;
uint8_t reserved1 : 3;
uint8_t disable_block_descriptor : 1;
uint8_t long_LBA : 1;
uint8_t reserved2 : 3;
uint8_t page_code:6;
uint8_t page_control:2;
uint8_t page_code : 6;
uint8_t page_control : 2;
uint8_t subpage_code;
uint8_t subpage_code;
uint8_t reserved3;
uint8_t reserved4;
uint8_t reserved5;
uint8_t reserved3;
uint8_t reserved4;
uint8_t reserved5;
uint8_t length[2];
uint8_t length[2];
uint8_t control;
}scsi_mode_sense_10_cmd_t;
uint8_t control;
} scsi_mode_sense_10_cmd_t;
typedef struct
typedef struct
{
uint8_t mode_data_length_high;
uint8_t mode_data_length_low;
uint8_t medium_type;
uint8_t mode_data_length_high;
uint8_t mode_data_length_low;
uint8_t medium_type;
uint8_t reserved1:4;
uint8_t DPO_FUA:1; /**< [Disable Page Out] and [Force Unit Access] in the SCSI_READ10 command is valid or not */
uint8_t reserved2:2;
uint8_t write_protect:1;
uint8_t reserved1 : 4;
uint8_t DPO_FUA : 1; /**< [Disable Page Out] and [Force Unit Access] in the SCSI_READ10 command is valid or not */
uint8_t reserved2 : 2;
uint8_t write_protect : 1;
uint8_t long_LBA:1;
uint8_t reserved3:7;
uint8_t long_LBA : 1;
uint8_t reserved3 : 7;
uint8_t reserved4;
uint8_t block_desc_length[2];
}scsi_mode_10_resp_t;
uint8_t reserved4;
uint8_t block_desc_length[2];
} scsi_mode_10_resp_t;
typedef struct __packed
{
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
uint8_t reserved[3];
uint8_t prohibit_removal;
uint8_t control;
typedef struct __packed {
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL
uint8_t reserved[3];
uint8_t prohibit_removal;
uint8_t control;
} scsi_prevent_allow_medium_removal_t;
typedef struct __packed
{
uint8_t cmd_code;
typedef struct __packed {
uint8_t cmd_code;
uint8_t immded : 1;
uint8_t : 7;
uint8_t immded : 1;
uint8_t : 7;
uint8_t TU_RESERVED;
uint8_t TU_RESERVED;
uint8_t power_condition_mod : 4;
uint8_t : 4;
uint8_t power_condition_mod : 4;
uint8_t : 4;
uint8_t start : 1;
uint8_t load_eject : 1;
uint8_t no_flush : 1;
uint8_t : 1;
uint8_t power_condition : 4;
uint8_t start : 1;
uint8_t load_eject : 1;
uint8_t no_flush : 1;
uint8_t : 1;
uint8_t power_condition : 4;
uint8_t control;
uint8_t control;
} scsi_start_stop_unit_cmd_t;
//--------------------------------------------------------------------+
// SCSI MMC
//--------------------------------------------------------------------+
/// SCSI Read Format Capacity: Write Capacity
typedef struct __packed
{
uint8_t cmd_code;
uint8_t reserved[6];
uint16_t alloc_length;
uint8_t control;
typedef struct __packed {
uint8_t cmd_code;
uint8_t reserved[6];
uint16_t alloc_length;
uint8_t control;
} scsi_read_format_capacity_cmd_t;
typedef struct __packed {
uint8_t reserved[3];
uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it.
typedef struct __packed{
uint8_t reserved[3];
uint8_t list_length; /// must be 8*n, length in bytes of formattable capacity descriptor followed it.
uint32_t block_num; /// Number of Logical Blocks
uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present
uint32_t block_num; /// Number of Logical Blocks
uint8_t descriptor_type; // 00: reserved, 01 unformatted media , 10 Formatted media, 11 No media present
uint8_t reserved2;
uint16_t block_size_u16;
uint8_t reserved2;
uint16_t block_size_u16;
} scsi_read_format_capacity_resp_t;
@ -284,31 +273,30 @@ typedef struct __packed{
//--------------------------------------------------------------------+
/// SCSI Read Capacity 10 Command: Read Capacity
typedef struct __packed
{
uint8_t cmd_code ; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10
uint8_t reserved1 ;
uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
uint16_t reserved2 ;
uint8_t partial_medium_indicator ;
uint8_t control ;
typedef struct __packed {
uint8_t cmd_code; ///< SCSI OpCode for \ref SCSI_CMD_READ_CAPACITY_10
uint8_t reserved1;
uint32_t lba; ///< The first Logical Block Address (LBA) accessed by this command
uint16_t reserved2;
uint8_t partial_medium_indicator;
uint8_t control;
} scsi_read_capacity10_cmd_t;
/// SCSI Read Capacity 10 Response Data
typedef struct {
uint32_t last_lba ; ///< The last Logical Block Address of the device
uint32_t block_size ; ///< Block size in bytes
typedef struct
{
uint32_t last_lba; ///< The last Logical Block Address of the device
uint32_t block_size; ///< Block size in bytes
} scsi_read_capacity10_resp_t;
/// SCSI Read 10 Command
typedef struct __packed
{
uint8_t cmd_code ; ///< SCSI OpCode
uint8_t reserved ; // has LUN according to wiki
uint32_t lba ; ///< The first Logical Block Address (LBA) accessed by this command
uint8_t reserved2 ;
uint16_t block_count ; ///< Number of Blocks used by this command
uint8_t control ;
} scsi_read10_t, scsi_write10_t,scsi_read_write_10_t;
typedef struct __packed {
uint8_t cmd_code; ///< SCSI OpCode
uint8_t reserved; // has LUN according to wiki
uint32_t lba; ///< The first Logical Block Address (LBA) accessed by this command
uint8_t reserved2;
uint16_t block_count; ///< Number of Blocks used by this command
uint8_t control;
} scsi_read10_t, scsi_write10_t, scsi_read_write_10_t;
#endif /* ZEPHYR_INCLUDE_USB_CLASS_USB_CDC_H_ */

View file

@ -0,0 +1,282 @@
/**
* @file usbd_ftdi.c
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#include "usbd_core.h"
#include "usbd_ftdi.h"
extern const uint16_t ftdi_eeprom_info[];
static volatile uint32_t sof_tick = 0;
static uint8_t Latency_Timer1 = 0x0004;
static uint8_t Latency_Timer2 = 0x0004;
const char *stop_name[] = { "1", "1.5", "2" };
const char *parity_name[] = { "N", "O", "E", "M", "S" };
static void usbd_ftdi_reset(void)
{
Latency_Timer1 = 0x0010;
Latency_Timer2 = 0x0010;
sof_tick = 0;
}
/* Requests */
#define SIO_RESET_REQUEST 0x00 /* Reset the port */
#define SIO_SET_MODEM_CTRL_REQUEST 0x01 /* Set the modem control register */
#define SIO_SET_FLOW_CTRL_REQUEST 0x02 /* Set flow control register */
#define SIO_SET_BAUDRATE_REQUEST 0x03 /* Set baud rate */
#define SIO_SET_DATA_REQUEST 0x04 /* Set the data characteristics of the port */
#define SIO_POLL_MODEM_STATUS_REQUEST 0x05
#define SIO_SET_EVENT_CHAR_REQUEST 0x06
#define SIO_SET_ERROR_CHAR_REQUEST 0x07
#define SIO_SET_LATENCY_TIMER_REQUEST 0x09
#define SIO_GET_LATENCY_TIMER_REQUEST 0x0A
#define SIO_SET_BITMODE_REQUEST 0x0B
#define SIO_READ_PINS_REQUEST 0x0C
#define SIO_READ_EEPROM_REQUEST 0x90
#define SIO_WRITE_EEPROM_REQUEST 0x91
#define SIO_ERASE_EEPROM_REQUEST 0x92
#define SIO_DISABLE_FLOW_CTRL 0x0
#define SIO_RTS_CTS_HS (0x1 << 8)
#define SIO_DTR_DSR_HS (0x2 << 8)
#define SIO_XON_XOFF_HS (0x4 << 8)
#define SIO_SET_DTR_MASK 0x1
#define SIO_SET_DTR_HIGH (1 | (SIO_SET_DTR_MASK << 8))
#define SIO_SET_DTR_LOW (0 | (SIO_SET_DTR_MASK << 8))
#define SIO_SET_RTS_MASK 0x2
#define SIO_SET_RTS_HIGH (2 | (SIO_SET_RTS_MASK << 8))
#define SIO_SET_RTS_LOW (0 | (SIO_SET_RTS_MASK << 8))
#define SIO_RTS_CTS_HS (0x1 << 8)
static void ftdi_set_baudrate(uint32_t itdf_divisor, uint32_t *actual_baudrate)
{
#define FTDI_USB_CLK 48000000
int baudrate;
uint8_t frac[] = { 0, 8, 4, 2, 6, 10, 12, 14 };
int divisor = itdf_divisor & 0x3fff;
divisor <<= 4;
divisor |= frac[(itdf_divisor >> 14) & 0x07];
if (itdf_divisor == 0x01) {
baudrate = 2000000;
} else if (itdf_divisor == 0x00) {
baudrate = 3000000;
} else {
baudrate = FTDI_USB_CLK / divisor;
}
if (baudrate > 100000 && baudrate < 12000) {
*actual_baudrate = (baudrate - 100000) * 100000;
} else {
*actual_baudrate = baudrate;
}
}
static int ftdi_vendor_request_handler(struct usb_setup_packet *pSetup, uint8_t **data, uint32_t *len)
{
static uint32_t actual_baudrate = 1200;
switch (pSetup->bRequest) {
case SIO_READ_EEPROM_REQUEST:
*data = (uint8_t *)&ftdi_eeprom_info[pSetup->wIndexL];
*len = 2;
break;
case SIO_RESET_REQUEST:
break;
case SIO_SET_MODEM_CTRL_REQUEST:
if (pSetup->wValue == SIO_SET_DTR_HIGH) {
//USBD_LOG("DTR 1\r\n");
usbd_ftdi_set_dtr(true);
} else if (pSetup->wValue == SIO_SET_DTR_LOW) {
//USBD_LOG("DTR 0\r\n");
usbd_ftdi_set_dtr(false);
} else if (pSetup->wValue == SIO_SET_RTS_HIGH) {
//USBD_LOG("RTS 1\r\n");
usbd_ftdi_set_rts(true);
} else if (pSetup->wValue == SIO_SET_RTS_LOW) {
//USBD_LOG("RTS 0\r\n");
usbd_ftdi_set_rts(false);
}
break;
case SIO_SET_FLOW_CTRL_REQUEST:
break;
case SIO_SET_BAUDRATE_REQUEST: //wValue2个字节波特率
{
uint8_t baudrate_high = (pSetup->wIndex >> 8);
ftdi_set_baudrate(pSetup->wValue | (baudrate_high << 16), &actual_baudrate);
break;
}
case SIO_SET_DATA_REQUEST:
/**
* D0-D7 databits BITS_7=7, BITS_8=8
* D8-D10 parity NONE=0, ODD=1, EVEN=2, MARK=3, SPACE=4
* D11-D12 STOP_BIT_1=0, STOP_BIT_15=1, STOP_BIT_2=2
* D14 BREAK_OFF=0, BREAK_ON=1
**/
if (actual_baudrate != 1200) {
//USBD_LOG("CDC_SET_LINE_CODING <%d %d %s %s>\r\n",actual_baudrate,(uint8_t)pSetup->wValue,parity_name[(uint8_t)(pSetup->wValue>>8)],stop_name[(uint8_t)(pSetup->wValue>>11)]);
usbd_ftdi_set_line_coding(actual_baudrate, (uint8_t)pSetup->wValue, (uint8_t)(pSetup->wValue >> 8), (uint8_t)(pSetup->wValue >> 11));
}
break;
case SIO_POLL_MODEM_STATUS_REQUEST:
/* Poll modem status information
This function allows the retrieve the two status bytes of the device.
The device sends these bytes also as a header for each read access
where they are discarded by ftdi_read_data(). The chip generates
the two stripped status bytes in the absence of data every 40 ms.
Layout of the first byte:
- B0..B3 - must be 0
- B4 Clear to send (CTS)
0 = inactive
1 = active
- B5 Data set ready (DTS)
0 = inactive
1 = active
- B6 Ring indicator (RI)
0 = inactive
1 = active
- B7 Receive line signal detect (RLSD)
0 = inactive
1 = active
Layout of the second byte:
- B0 Data ready (DR)
- B1 Overrun error (OE)
- B2 Parity error (PE)
- B3 Framing error (FE)
- B4 Break interrupt (BI)
- B5 Transmitter holding register (THRE)
- B6 Transmitter empty (TEMT)
- B7 Error in RCVR FIFO */
*data = (uint8_t *)&ftdi_eeprom_info[2];
*len = 2;
break;
case SIO_SET_EVENT_CHAR_REQUEST:
break;
case SIO_SET_ERROR_CHAR_REQUEST:
break;
case SIO_SET_LATENCY_TIMER_REQUEST:
if (pSetup->wIndexL == 1) {
Latency_Timer1 = pSetup->wValueL;
} else {
Latency_Timer2 = pSetup->wValueL;
}
break;
case SIO_GET_LATENCY_TIMER_REQUEST:
if (pSetup->wIndexL == 1) {
*data = &Latency_Timer1;
} else {
*data = &Latency_Timer2;
}
*len = 1;
//USBD_LOG("get latency:%d,len:%d\r\n",Latency_Timer1,*len);
break;
case SIO_SET_BITMODE_REQUEST:
break;
default:
USBD_LOG_DBG("CDC ACM request 0x%x, value 0x%x\r\n",
pSetup->bRequest, pSetup->wValue);
return -1;
}
return 0;
}
static void ftdi_notify_handler(uint8_t event, void *arg)
{
switch (event) {
case USB_EVENT_RESET:
usbd_ftdi_reset();
break;
case USB_EVENT_SOF:
sof_tick++;
USBD_LOG_DBG("tick: %d\r\n", sof_tick);
break;
default:
break;
}
}
__weak void usbd_ftdi_set_line_coding(uint32_t baudrate, uint8_t databits, uint8_t parity, uint8_t stopbits)
{
}
__weak void usbd_ftdi_set_dtr(bool dtr)
{
}
__weak void usbd_ftdi_set_rts(bool rts)
{
}
uint32_t usbd_ftdi_get_sof_tick(void)
{
return sof_tick;
}
uint32_t usbd_ftdi_get_latency_timer1(void)
{
return Latency_Timer1;
}
uint32_t usbd_ftdi_get_latency_timer2(void)
{
return Latency_Timer2;
}
void usbd_ftdi_add_interface(usbd_class_t *class, usbd_interface_t *intf)
{
static usbd_class_t *last_class = NULL;
if (last_class != class) {
last_class = class;
usbd_class_register(class);
}
intf->class_handler = NULL;
intf->custom_handler = NULL;
intf->vendor_handler = ftdi_vendor_request_handler;
intf->notify_handler = ftdi_notify_handler;
usbd_class_add_interface(class, intf);
}

View file

@ -0,0 +1,34 @@
/**
* @file usbd_ftdi.h
* @brief
*
* Copyright (c) 2021 Bouffalolab team
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
#ifndef _USBD_FTDI_H
#define _USBD_FTDI_H
void usbd_ftdi_add_interface(usbd_class_t *class, usbd_interface_t *intf);
void usbd_ftdi_set_line_coding(uint32_t baudrate, uint8_t databits, uint8_t parity, uint8_t stopbits);
void usbd_ftdi_set_dtr(bool dtr);
void usbd_ftdi_set_rts(bool rts);
uint32_t usbd_ftdi_get_sof_tick(void);
uint32_t usbd_ftdi_get_latency_timer1(void);
uint32_t usbd_ftdi_get_latency_timer2(void);
#endif /* USB_FTDI_H_ */

View file

@ -1,23 +1,23 @@
/**
* @file usbd_video.c
*
*
* Copyright (c) 2021 Bouffalolab team
*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#include "usbd_core.h"
#include "usbd_video.h"
@ -31,85 +31,104 @@ int video_class_request_handler(struct usb_setup_packet *setup, uint8_t **data,
"bRequest 0x%02x, bmRequestType 0x%02x len %d",
setup->bRequest, setup->bmRequestType, *len);
switch (setup->bRequest)
{
switch (setup->bRequest) {
case VIDEO_REQUEST_SET_CUR:
if (setup->wValue == 256)
memcpy((uint8_t *)&probe,*data,setup->wLength);
else if (setup->wValue == 512)
memcpy((uint8_t *)&commit,*data,setup->wLength);
if (setup->wValue == 256) {
memcpy((uint8_t *)&probe, *data, setup->wLength);
} else if (setup->wValue == 512) {
memcpy((uint8_t *)&commit, *data, setup->wLength);
}
break;
case VIDEO_REQUEST_GET_CUR:
if (setup->wValue == 256)
if (setup->wValue == 256) {
*data = (uint8_t *)&probe;
else if (setup->wValue == 512)
} else if (setup->wValue == 512) {
*data = (uint8_t *)&commit;
}
break;
case VIDEO_REQUEST_GET_MIN:
if (setup->wValue == 256)
if (setup->wValue == 256) {
*data = (uint8_t *)&probe;
else if (setup->wValue == 512)
} else if (setup->wValue == 512) {
*data = (uint8_t *)&commit;
}
break;
case VIDEO_REQUEST_GET_MAX:
if (setup->wValue == 256)
if (setup->wValue == 256) {
*data = (uint8_t *)&probe;
else if (setup->wValue == 512)
} else if (setup->wValue == 512) {
*data = (uint8_t *)&commit;
}
break;
case VIDEO_REQUEST_GET_RES:
break;
case VIDEO_REQUEST_GET_LEN:
break;
case VIDEO_REQUEST_GET_INFO:
break;
case VIDEO_REQUEST_GET_DEF:
if (setup->wLength == 256)
if (setup->wLength == 256) {
*data = (uint8_t *)&probe;
else if (setup->wLength == 512)
} else if (setup->wLength == 512) {
*data = (uint8_t *)&commit;
}
break;
default:
USBD_LOG_ERR("Unhandled request 0x%02x", setup->bRequest);
break;
}
return 0;
}
void video_notify_handler(uint8_t event, void* arg)
void video_notify_handler(uint8_t event, void *arg)
{
switch (event)
{
case USB_EVENT_RESET:
switch (event) {
case USB_EVENT_RESET:
break;
case USB_EVENT_SOF:
break;
case USB_EVENT_SOF:
usbd_video_sof_callback();
break;
case USB_EVENT_SET_INTERFACE:
usbd_video_set_interface_callback(((uint8_t*)arg)[3]);
break;
default:
break;
}
break;
case USB_EVENT_SET_INTERFACE:
usbd_video_set_interface_callback(((uint8_t *)arg)[3]);
break;
default:
break;
}
}
void usbd_video_add_interface(usbd_class_t *class, usbd_interface_t *intf)
{
static usbd_class_t *last_class = NULL;
static usbd_class_t *last_class = NULL;
if(last_class != class)
{
last_class = class;
usbd_class_register(class);
}
if (last_class != class) {
last_class = class;
usbd_class_register(class);
}
intf->class_handler = video_class_request_handler;
intf->custom_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = video_notify_handler;
usbd_class_add_interface(class,intf);
intf->class_handler = video_class_request_handler;
intf->custom_handler = NULL;
intf->vendor_handler = NULL;
intf->notify_handler = video_notify_handler;
usbd_class_add_interface(class, intf);
}

File diff suppressed because it is too large Load diff

View file

@ -8,11 +8,11 @@
#define WEBUSB_URL_TYPE 0x03
/* WebUSB Request Codes */
#define WEBUSB_REQUEST_GET_URL 0x02
#define WEBUSB_REQUEST_GET_URL 0x02
/* bScheme in URL descriptor */
#define WEBUSB_URL_SCHEME_HTTP 0x00
#define WEBUSB_URL_SCHEME_HTTPS 0x01
#define WEBUSB_URL_SCHEME_HTTP 0x00
#define WEBUSB_URL_SCHEME_HTTPS 0x01
/* WebUSB Descriptor sizes */
#define WEBUSB_DESCRIPTOR_SET_HEADER_SIZE 5
@ -21,16 +21,16 @@
/* 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;
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;
struct webusb_url_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bScheme;
char URL[];
} __packed;

View file

@ -2,56 +2,34 @@
#define _USBD_WINUSB_H
/* WinUSB Microsoft OS 2.0 descriptor request codes */
#define WINUSB_REQUEST_GET_DESCRIPTOR_SET 0x07
#define WINUSB_REQUEST_SET_ALT_ENUM 0x08
#define WINUSB_REQUEST_GET_DESCRIPTOR_SET 0x07
#define WINUSB_REQUEST_SET_ALT_ENUM 0x08
/* WinUSB Microsoft OS 2.0 descriptor sizes */
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
#define WINUSB_DESCRIPTOR_SET_HEADER_SIZE 10
#define WINUSB_FUNCTION_SUBSET_HEADER_SIZE 8
#define WINUSB_FEATURE_COMPATIBLE_ID_SIZE 20
/* WinUSB Microsoft OS 2.0 Descriptor Types */
#define WINUSB_SET_HEADER_DESCRIPTOR_TYPE 0x00
#define WINUSB_SUBSET_HEADER_CONFIGURATION_TYPE 0x01
#define WINUSB_SUBSET_HEADER_FUNCTION_TYPE 0x02
#define WINUSB_FEATURE_COMPATIBLE_ID_TYPE 0x03
#define WINUSB_FEATURE_REG_PROPERTY_TYPE 0x04
#define WINUSB_FEATURE_MIN_RESUME_TIME_TYPE 0x05
#define WINUSB_FEATURE_MODEL_ID_TYPE 0x06
#define WINUSB_FEATURE_CCGP_DEVICE_TYPE 0x07
#define WINUSB_PROP_DATA_TYPE_REG_SZ 0x01
#define WINUSB_PROP_DATA_TYPE_REG_MULTI_SZ 0x07
/* WebUSB Descriptor Types */
#define WEBUSB_DESCRIPTOR_SET_HEADER_TYPE 0x00
#define WEBUSB_CONFIGURATION_SUBSET_HEADER_TYPE 0x01
#define WEBUSB_FUNCTION_SUBSET_HEADER_TYPE 0x02
#define WEBUSB_URL_TYPE 0x03
/* WebUSB Request Codes */
#define WEBUSB_REQUEST_GET_URL 0x02
/* bScheme in URL descriptor */
#define WEBUSB_URL_SCHEME_HTTP 0x00
#define WEBUSB_URL_SCHEME_HTTPS 0x01
/* WebUSB Descriptor sizes */
#define WEBUSB_DESCRIPTOR_SET_HEADER_SIZE 5
#define WEBUSB_CONFIGURATION_SUBSET_HEADER_SIZE 4
#define WEBUSB_FUNCTION_SUBSET_HEADER_SIZE 3
#define WINUSB_SET_HEADER_DESCRIPTOR_TYPE 0x00
#define WINUSB_SUBSET_HEADER_CONFIGURATION_TYPE 0x01
#define WINUSB_SUBSET_HEADER_FUNCTION_TYPE 0x02
#define WINUSB_FEATURE_COMPATIBLE_ID_TYPE 0x03
#define WINUSB_FEATURE_REG_PROPERTY_TYPE 0x04
#define WINUSB_FEATURE_MIN_RESUME_TIME_TYPE 0x05
#define WINUSB_FEATURE_MODEL_ID_TYPE 0x06
#define WINUSB_FEATURE_CCGP_DEVICE_TYPE 0x07
#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;
struct usb_bos_capability_descriptor winusb_platform;
uint32_t dwWindowsVersion;
uint16_t wMSOSDescriptorSetTotalLength;
uint8_t bMS_VendorCode;
uint8_t bAltEnumCode;
} __packed;
#endif

View file

@ -14,32 +14,32 @@ extern "C" {
* @{
*/
/**< maximum packet size (MPS) for EP 0 */
#define USB_CTRL_EP_MPS 64
#define USB_CTRL_EP_MPS 64
/**
* USB endpoint Transfer Type mask.
*/
#define USBD_EP_TYPE_CTRL 0
#define USBD_EP_TYPE_ISOC 1
#define USBD_EP_TYPE_BULK 2
#define USBD_EP_TYPE_INTR 3
#define USBD_EP_TYPE_MASK 3
#define USBD_EP_TYPE_CTRL 0
#define USBD_EP_TYPE_ISOC 1
#define USBD_EP_TYPE_BULK 2
#define USBD_EP_TYPE_INTR 3
#define USBD_EP_TYPE_MASK 3
/* Default USB control EP, always 0 and 0x80 */
#define USB_CONTROL_OUT_EP0 0
#define USB_CONTROL_IN_EP0 0x80
#define USB_CONTROL_OUT_EP0 0
#define USB_CONTROL_IN_EP0 0x80
/**
* @brief USB Endpoint Transfer Type
*/
enum usb_dc_ep_transfer_type {
/** Control type endpoint */
USB_DC_EP_CONTROL = 0,
/** Isochronous type endpoint */
USB_DC_EP_ISOCHRONOUS,
/** Bulk type endpoint */
USB_DC_EP_BULK,
/** Interrupt type endpoint */
USB_DC_EP_INTERRUPT
/** Control type endpoint */
USB_DC_EP_CONTROL = 0,
/** Isochronous type endpoint */
USB_DC_EP_ISOCHRONOUS,
/** Bulk type endpoint */
USB_DC_EP_BULK,
/** Interrupt type endpoint */
USB_DC_EP_INTERRUPT
};
/**
@ -48,18 +48,18 @@ enum usb_dc_ep_transfer_type {
* Structure containing the USB endpoint configuration.
*/
struct usbd_endpoint_cfg {
/** The number associated with the EP in the device
* configuration structure
* IN EP = 0x80 | \<endpoint number\>
* OUT EP = 0x00 | \<endpoint number\>
*/
uint8_t ep_addr;
/** Endpoint max packet size */
uint16_t ep_mps;
/** Endpoint Transfer Type.
* May be Bulk, Interrupt, Control or Isochronous
*/
enum usb_dc_ep_transfer_type ep_type;
/** The number associated with the EP in the device
* configuration structure
* IN EP = 0x80 | \<endpoint number\>
* OUT EP = 0x00 | \<endpoint number\>
*/
uint8_t ep_addr;
/** Endpoint max packet size */
uint16_t ep_mps;
/** Endpoint Transfer Type.
* May be Bulk, Interrupt, Control or Isochronous
*/
enum usb_dc_ep_transfer_type ep_type;
};
/**
@ -166,7 +166,7 @@ int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint
*
* @return 0 on success, negative errno code on fail.
*/
int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len,uint32_t *read_bytes);
int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes);
/**
* @}
@ -177,4 +177,3 @@ int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len,uint32_t
#endif
#endif

View file

@ -2,354 +2,348 @@
#define USB_REQUEST_H
/* Useful define */
#define USB_1_1 0x0110
#define USB_2_0 0x0200
#define USB_1_1 0x0110
#define USB_2_0 0x0200
/* Set USB version to 2.1 so that the host will request the BOS descriptor */
#define USB_2_1 0x0210
#define USB_2_1 0x0210
// USB Speed
#define USB_SPEED_LOW 0U
#define USB_SPEED_FULL 1U
#define USB_SPEED_HIGH 2U
#define USB_SPEED_LOW 0U
#define USB_SPEED_FULL 1U
#define USB_SPEED_HIGH 2U
// USB PID Types
#define USB_PID_RESERVED 0U
#define USB_PID_OUT 1U
#define USB_PID_ACK 2U
#define USB_PID_DATA0 3U
#define USB_PID_PING 4U
#define USB_PID_SOF 5U
#define USB_PID_DATA2 7U
#define USB_PID_NYET 6U
#define USB_PID_SPLIT 8U
#define USB_PID_IN 9U
#define USB_PID_NAK 10U
#define USB_PID_DATA1 11U
#define USB_PID_PRE 12U
#define USB_PID_ERR 12U
#define USB_PID_SETUP 13U
#define USB_PID_STALL 14U
#define USB_PID_MDATA 15U
#define USB_PID_RESERVED 0U
#define USB_PID_OUT 1U
#define USB_PID_ACK 2U
#define USB_PID_DATA0 3U
#define USB_PID_PING 4U
#define USB_PID_SOF 5U
#define USB_PID_DATA2 7U
#define USB_PID_NYET 6U
#define USB_PID_SPLIT 8U
#define USB_PID_IN 9U
#define USB_PID_NAK 10U
#define USB_PID_DATA1 11U
#define USB_PID_PRE 12U
#define USB_PID_ERR 12U
#define USB_PID_SETUP 13U
#define USB_PID_STALL 14U
#define USB_PID_MDATA 15U
// bmRequestType.Dir
#define USB_REQUEST_HOST_TO_DEVICE 0U
#define USB_REQUEST_DEVICE_TO_HOST 1U
#define USB_REQUEST_HOST_TO_DEVICE 0U
#define USB_REQUEST_DEVICE_TO_HOST 1U
// bmRequestType.Type
#define USB_REQUEST_STANDARD 0U
#define USB_REQUEST_CLASS 1U
#define USB_REQUEST_VENDOR 2U
#define USB_REQUEST_RESERVED 3U
#define USB_REQUEST_STANDARD 0U
#define USB_REQUEST_CLASS 1U
#define USB_REQUEST_VENDOR 2U
#define USB_REQUEST_RESERVED 3U
// bmRequestType.Recipient
#define USB_REQUEST_TO_DEVICE 0U
#define USB_REQUEST_TO_INTERFACE 1U
#define USB_REQUEST_TO_ENDPOINT 2U
#define USB_REQUEST_TO_OTHER 3U
#define USB_REQUEST_TO_DEVICE 0U
#define USB_REQUEST_TO_INTERFACE 1U
#define USB_REQUEST_TO_ENDPOINT 2U
#define USB_REQUEST_TO_OTHER 3U
/* USB Standard Request Codes */
#define USB_REQUEST_GET_STATUS 0x00
#define USB_REQUEST_CLEAR_FEATURE 0x01
#define USB_REQUEST_SET_FEATURE 0x03
#define USB_REQUEST_SET_ADDRESS 0x05
#define USB_REQUEST_GET_DESCRIPTOR 0x06
#define USB_REQUEST_SET_DESCRIPTOR 0x07
#define USB_REQUEST_GET_CONFIGURATION 0x08
#define USB_REQUEST_SET_CONFIGURATION 0x09
#define USB_REQUEST_GET_INTERFACE 0x0A
#define USB_REQUEST_SET_INTERFACE 0x0B
#define USB_REQUEST_SYNCH_FRAME 0x0C
#define USB_REQUEST_SET_ENCRYPTION 0x0D
#define USB_REQUEST_GET_ENCRYPTION 0x0E
#define USB_REQUEST_RPIPE_ABORT 0x0E
#define USB_REQUEST_SET_HANDSHAKE 0x0F
#define USB_REQUEST_RPIPE_RESET 0x0F
#define USB_REQUEST_GET_HANDSHAKE 0x10
#define USB_REQUEST_SET_CONNECTION 0x11
#define USB_REQUEST_SET_SECURITY_DATA 0x12
#define USB_REQUEST_GET_SECURITY_DATA 0x13
#define USB_REQUEST_SET_WUSB_DATA 0x14
#define USB_REQUEST_LOOPBACK_DATA_WRITE 0x15
#define USB_REQUEST_LOOPBACK_DATA_READ 0x16
#define USB_REQUEST_SET_INTERFACE_DS 0x17
#define USB_REQUEST_GET_STATUS 0x00
#define USB_REQUEST_CLEAR_FEATURE 0x01
#define USB_REQUEST_SET_FEATURE 0x03
#define USB_REQUEST_SET_ADDRESS 0x05
#define USB_REQUEST_GET_DESCRIPTOR 0x06
#define USB_REQUEST_SET_DESCRIPTOR 0x07
#define USB_REQUEST_GET_CONFIGURATION 0x08
#define USB_REQUEST_SET_CONFIGURATION 0x09
#define USB_REQUEST_GET_INTERFACE 0x0A
#define USB_REQUEST_SET_INTERFACE 0x0B
#define USB_REQUEST_SYNCH_FRAME 0x0C
#define USB_REQUEST_SET_ENCRYPTION 0x0D
#define USB_REQUEST_GET_ENCRYPTION 0x0E
#define USB_REQUEST_RPIPE_ABORT 0x0E
#define USB_REQUEST_SET_HANDSHAKE 0x0F
#define USB_REQUEST_RPIPE_RESET 0x0F
#define USB_REQUEST_GET_HANDSHAKE 0x10
#define USB_REQUEST_SET_CONNECTION 0x11
#define USB_REQUEST_SET_SECURITY_DATA 0x12
#define USB_REQUEST_GET_SECURITY_DATA 0x13
#define USB_REQUEST_SET_WUSB_DATA 0x14
#define USB_REQUEST_LOOPBACK_DATA_WRITE 0x15
#define USB_REQUEST_LOOPBACK_DATA_READ 0x16
#define USB_REQUEST_SET_INTERFACE_DS 0x17
/* USB GET_STATUS Bit Values */
#define USB_GETSTATUS_SELF_POWERED 0x01
#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
#define USB_GETSTATUS_ENDPOINT_STALL 0x01
#define USB_GETSTATUS_SELF_POWERED 0x01
#define USB_GETSTATUS_REMOTE_WAKEUP 0x02
#define USB_GETSTATUS_ENDPOINT_STALL 0x01
/* USB Standard Feature selectors */
#define USB_FEATURE_ENDPOINT_STALL 0
#define USB_FEATURE_REMOTE_WAKEUP 1
#define USB_FEATURE_TEST_MODE 2
#define USB_FEATURE_ENDPOINT_STALL 0
#define USB_FEATURE_REMOTE_WAKEUP 1
#define USB_FEATURE_TEST_MODE 2
/* Descriptor size in bytes */
#define USB_DEVICE_DESC_SIZE 0x12
#define USB_CONFIGURATION_DESC_SIZE 0x09
#define USB_INTERFACE_DESC_SIZE 0x09
#define USB_ENDPOINT_DESC_SIZE 0x07
#define USB_LANGID_STRING_DESC_SIZE 0x04
#define USB_OTHER_SPEED_DESC_SIZE 0x09
#define USB_DEVICE_QUAL_DESC_SIZE 0x0A
#define USB_INTERFACE_ASSOC_DESC_SIZE 0x08
#define USB_FUNCTION_DESC_SIZE 0x03
#define USB_OTG_DESC_SIZE 0x03
#define USB_DEVICE_DESC_SIZE 0x12
#define USB_CONFIGURATION_DESC_SIZE 0x09
#define USB_INTERFACE_DESC_SIZE 0x09
#define USB_ENDPOINT_DESC_SIZE 0x07
#define USB_LANGID_STRING_DESC_SIZE 0x04
#define USB_OTHER_SPEED_DESC_SIZE 0x09
#define USB_DEVICE_QUAL_DESC_SIZE 0x0A
#define USB_INTERFACE_ASSOC_DESC_SIZE 0x08
#define USB_FUNCTION_DESC_SIZE 0x03
#define USB_OTG_DESC_SIZE 0x03
/* USB Descriptor Types */
#define USB_DESCRIPTOR_TYPE_DEVICE 0x01U
#define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02U
#define USB_DESCRIPTOR_TYPE_STRING 0x03U
#define USB_DESCRIPTOR_TYPE_INTERFACE 0x04U
#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05U
#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESCRIPTOR_TYPE_OTHER_SPEED 0x07U
#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 0x08U
#define USB_DESCRIPTOR_TYPE_OTG 0x09U
#define USB_DESCRIPTOR_TYPE_DEBUG 0x0AU
#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0BU
#define USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE 0x0FU
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY 0x10U
#define USB_DESCRIPTOR_TYPE_DEVICE 0x01U
#define USB_DESCRIPTOR_TYPE_CONFIGURATION 0x02U
#define USB_DESCRIPTOR_TYPE_STRING 0x03U
#define USB_DESCRIPTOR_TYPE_INTERFACE 0x04U
#define USB_DESCRIPTOR_TYPE_ENDPOINT 0x05U
#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 0x06U
#define USB_DESCRIPTOR_TYPE_OTHER_SPEED 0x07U
#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 0x08U
#define USB_DESCRIPTOR_TYPE_OTG 0x09U
#define USB_DESCRIPTOR_TYPE_DEBUG 0x0AU
#define USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0BU
#define USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE 0x0FU
#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY 0x10U
#define USB_DESCRIPTOR_TYPE_FUNCTIONAL 0x21U
#define USB_DESCRIPTOR_TYPE_FUNCTIONAL 0x21U
// Class Specific Descriptor
#define USB_CS_DESCRIPTOR_TYPE_DEVICE 0x21U
#define USB_CS_DESCRIPTOR_TYPE_CONFIGURATION 0x22U
#define USB_CS_DESCRIPTOR_TYPE_STRING 0x23U
#define USB_CS_DESCRIPTOR_TYPE_INTERFACE 0x24U
#define USB_CS_DESCRIPTOR_TYPE_ENDPOINT 0x25U
#define USB_CS_DESCRIPTOR_TYPE_DEVICE 0x21U
#define USB_CS_DESCRIPTOR_TYPE_CONFIGURATION 0x22U
#define USB_CS_DESCRIPTOR_TYPE_STRING 0x23U
#define USB_CS_DESCRIPTOR_TYPE_INTERFACE 0x24U
#define USB_CS_DESCRIPTOR_TYPE_ENDPOINT 0x25U
#define USB_DESCRIPTOR_TYPE_SUPERSPEED_ENDPOINT_COMPANION 0x30U
#define USB_DESCRIPTOR_TYPE_SUPERSPEED_ISO_ENDPOINT_COMPANION 0x31U
#define USB_DESCRIPTOR_TYPE_SUPERSPEED_ENDPOINT_COMPANION 0x30U
#define USB_DESCRIPTOR_TYPE_SUPERSPEED_ISO_ENDPOINT_COMPANION 0x31U
/* USB Device Classes */
#define USB_DEVICE_CLASS_RESERVED 0x00
#define USB_DEVICE_CLASS_AUDIO 0x01
#define USB_DEVICE_CLASS_CDC 0x02
#define USB_DEVICE_CLASS_HID 0x03
#define USB_DEVICE_CLASS_MONITOR 0x04
#define USB_DEVICE_CLASS_PHYSICAL 0x05
#define USB_DEVICE_CLASS_IMAGE 0x06
#define USB_DEVICE_CLASS_PRINTER 0x07
#define USB_DEVICE_CLASS_MASS_STORAGE 0x08
#define USB_DEVICE_CLASS_HUB 0x09
#define USB_DEVICE_CLASS_CDC_DATA 0x0a
#define USB_DEVICE_CLASS_SMART_CARD 0x0b
#define USB_DEVICE_CLASS_SECURITY 0x0d
#define USB_DEVICE_CLASS_VIDEO 0x0e
#define USB_DEVICE_CLASS_HEALTHCARE 0x0f
#define USB_DEVICE_CLASS_DIAG_DEVICE 0xdc
#define USB_DEVICE_CLASS_WIRELESS 0xe0
#define USB_DEVICE_CLASS_MISC 0xef
#define USB_DEVICE_CLASS_APP_SPECIFIC 0xfe
#define USB_DEVICE_CLASS_VEND_SPECIFIC 0xff
#define USB_DEVICE_CLASS_RESERVED 0x00
#define USB_DEVICE_CLASS_AUDIO 0x01
#define USB_DEVICE_CLASS_CDC 0x02
#define USB_DEVICE_CLASS_HID 0x03
#define USB_DEVICE_CLASS_MONITOR 0x04
#define USB_DEVICE_CLASS_PHYSICAL 0x05
#define USB_DEVICE_CLASS_IMAGE 0x06
#define USB_DEVICE_CLASS_PRINTER 0x07
#define USB_DEVICE_CLASS_MASS_STORAGE 0x08
#define USB_DEVICE_CLASS_HUB 0x09
#define USB_DEVICE_CLASS_CDC_DATA 0x0a
#define USB_DEVICE_CLASS_SMART_CARD 0x0b
#define USB_DEVICE_CLASS_SECURITY 0x0d
#define USB_DEVICE_CLASS_VIDEO 0x0e
#define USB_DEVICE_CLASS_HEALTHCARE 0x0f
#define USB_DEVICE_CLASS_DIAG_DEVICE 0xdc
#define USB_DEVICE_CLASS_WIRELESS 0xe0
#define USB_DEVICE_CLASS_MISC 0xef
#define USB_DEVICE_CLASS_APP_SPECIFIC 0xfe
#define USB_DEVICE_CLASS_VEND_SPECIFIC 0xff
/* usb string index define */
#define USB_STRING_LANGID_INDEX 0x00
#define USB_STRING_MFC_INDEX 0x01
#define USB_STRING_PRODUCT_INDEX 0x02
#define USB_STRING_SERIAL_INDEX 0x03
#define USB_STRING_CONFIG_INDEX 0x04
#define USB_STRING_INTERFACE_INDEX 0x05
#define USB_STRING_OS_INDEX 0x06
#define USB_STRING_MAX USB_STRING_OS_INDEX
#define USB_STRING_LANGID_INDEX 0x00
#define USB_STRING_MFC_INDEX 0x01
#define USB_STRING_PRODUCT_INDEX 0x02
#define USB_STRING_SERIAL_INDEX 0x03
#define USB_STRING_CONFIG_INDEX 0x04
#define USB_STRING_INTERFACE_INDEX 0x05
#define USB_STRING_OS_INDEX 0x06
#define USB_STRING_MAX USB_STRING_OS_INDEX
/*
* Devices supporting Microsoft OS Descriptors store special string
* descriptor at fixed index (0xEE). It is read when a new device is
* attached to a computer for the first time.
*/
#define USB_OSDESC_STRING_DESC_INDEX 0xEE
#define USB_OSDESC_STRING_DESC_INDEX 0xEE
/* bmAttributes in Configuration Descriptor */
#define USB_CONFIG_POWERED_MASK 0x40
#define USB_CONFIG_BUS_POWERED 0x80
#define USB_CONFIG_SELF_POWERED 0xC0
#define USB_CONFIG_REMOTE_WAKEUP 0x20
#define USB_CONFIG_POWERED_MASK 0x40
#define USB_CONFIG_BUS_POWERED 0x80
#define USB_CONFIG_SELF_POWERED 0xC0
#define USB_CONFIG_REMOTE_WAKEUP 0x20
/* bMaxPower in Configuration Descriptor */
#define USB_CONFIG_POWER_MA(mA) ((mA)/2)
#define USB_CONFIG_POWER_MA(mA) ((mA) / 2)
/* bEndpointAddress in Endpoint Descriptor */
#define USB_ENDPOINT_DIRECTION_MASK 0x80
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
#define USB_ENDPOINT_DIRECTION_MASK 0x80
#define USB_ENDPOINT_OUT(addr) ((addr) | 0x00)
#define USB_ENDPOINT_IN(addr) ((addr) | 0x80)
/* bmAttributes in Endpoint Descriptor */
#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
#define USB_ENDPOINT_SYNC_MASK 0x0C
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
#define USB_ENDPOINT_USAGE_MASK 0x30
#define USB_ENDPOINT_USAGE_DATA 0x00
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
#define USB_ENDPOINT_USAGE_RESERVED 0x30
#define USB_ENDPOINT_TYPE_MASK 0x03
#define USB_ENDPOINT_TYPE_CONTROL 0x00
#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
#define USB_ENDPOINT_TYPE_BULK 0x02
#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
#define USB_ENDPOINT_SYNC_MASK 0x0C
#define USB_ENDPOINT_SYNC_NO_SYNCHRONIZATION 0x00
#define USB_ENDPOINT_SYNC_ASYNCHRONOUS 0x04
#define USB_ENDPOINT_SYNC_ADAPTIVE 0x08
#define USB_ENDPOINT_SYNC_SYNCHRONOUS 0x0C
#define USB_ENDPOINT_USAGE_MASK 0x30
#define USB_ENDPOINT_USAGE_DATA 0x00
#define USB_ENDPOINT_USAGE_FEEDBACK 0x10
#define USB_ENDPOINT_USAGE_IMPLICIT_FEEDBACK 0x20
#define USB_ENDPOINT_USAGE_RESERVED 0x30
/* bDevCapabilityType in Device Capability Descriptor */
#define USB_DEVICE_CAPABILITY_WIRELESS_USB 1
#define USB_DEVICE_CAPABILITY_USB_2_0_EXTENSION 2
#define USB_DEVICE_CAPABILITY_SUPERSPEED_USB 3
#define USB_DEVICE_CAPABILITY_CONTAINER_ID 4
#define USB_DEVICE_CAPABILITY_PLATFORM 5
#define USB_DEVICE_CAPABILITY_POWER_DELIVERY_CAPABILITY 6
#define USB_DEVICE_CAPABILITY_BATTERY_INFO_CAPABILITY 7
#define USB_DEVICE_CAPABILITY_PD_CONSUMER_PORT_CAPABILITY 8
#define USB_DEVICE_CAPABILITY_PD_PROVIDER_PORT_CAPABILITY 9
#define USB_DEVICE_CAPABILITY_SUPERSPEED_PLUS 10
#define USB_DEVICE_CAPABILITY_PRECISION_TIME_MEASUREMENT 11
#define USB_DEVICE_CAPABILITY_WIRELESS_USB_EXT 12
#define USB_DEVICE_CAPABILITY_WIRELESS_USB 1
#define USB_DEVICE_CAPABILITY_USB_2_0_EXTENSION 2
#define USB_DEVICE_CAPABILITY_SUPERSPEED_USB 3
#define USB_DEVICE_CAPABILITY_CONTAINER_ID 4
#define USB_DEVICE_CAPABILITY_PLATFORM 5
#define USB_DEVICE_CAPABILITY_POWER_DELIVERY_CAPABILITY 6
#define USB_DEVICE_CAPABILITY_BATTERY_INFO_CAPABILITY 7
#define USB_DEVICE_CAPABILITY_PD_CONSUMER_PORT_CAPABILITY 8
#define USB_DEVICE_CAPABILITY_PD_PROVIDER_PORT_CAPABILITY 9
#define USB_DEVICE_CAPABILITY_SUPERSPEED_PLUS 10
#define USB_DEVICE_CAPABILITY_PRECISION_TIME_MEASUREMENT 11
#define USB_DEVICE_CAPABILITY_WIRELESS_USB_EXT 12
#define USB_BOS_CAPABILITY_EXTENSION 0x02
#define USB_BOS_CAPABILITY_PLATFORM 0x05
#define USB_BOS_CAPABILITY_EXTENSION 0x02
#define USB_BOS_CAPABILITY_PLATFORM 0x05
/* Setup packet definition used to read raw data from USB line */
struct usb_setup_packet
{
__packed union
{
uint8_t bmRequestType; /* bmRequestType */
struct
{
uint8_t Recipient : 5; /* D4..0: Recipient */
uint8_t Type : 2; /* D6..5: Type */
uint8_t Dir : 1; /* D7: Data Phase Txsfer Direction */
}bmRequestType_b;
};
uint8_t bRequest;
__packed union
{
uint16_t wValue; /* wValue */
struct
{
uint8_t wValueL;
uint8_t wValueH;
};
};
__packed union
{
uint16_t wIndex; /* wIndex */
struct
{
uint8_t wIndexL;
uint8_t wIndexH;
};
};
uint16_t wLength;
struct usb_setup_packet {
__packed union {
uint8_t bmRequestType; /* bmRequestType */
struct
{
uint8_t Recipient : 5; /* D4..0: Recipient */
uint8_t Type : 2; /* D6..5: Type */
uint8_t Dir : 1; /* D7: Data Phase Txsfer Direction */
} bmRequestType_b;
};
uint8_t bRequest;
__packed union {
uint16_t wValue; /* wValue */
struct
{
uint8_t wValueL;
uint8_t wValueH;
};
};
__packed union {
uint16_t wIndex; /* wIndex */
struct
{
uint8_t wIndexL;
uint8_t wIndexH;
};
};
uint16_t wLength;
} __packed;
/** Standard Device Descriptor */
struct usb_device_descriptor {
uint8_t bLength; /* Descriptor size in bytes = 18 */
uint8_t bDescriptorType; /* DEVICE descriptor type = 1 */
uint16_t bcdUSB; /* USB spec in BCD, e.g. 0x0200 */
uint8_t bDeviceClass; /* Class code, if 0 see interface */
uint8_t bDeviceSubClass; /* Sub-Class code, 0 if class = 0 */
uint8_t bDeviceProtocol; /* Protocol, if 0 see interface */
uint8_t bMaxPacketSize0; /* Endpoint 0 max. size */
uint16_t idVendor; /* Vendor ID per USB-IF */
uint16_t idProduct; /* Product ID per manufacturer */
uint16_t bcdDevice; /* Device release # in BCD */
uint8_t iManufacturer; /* Index to manufacturer string */
uint8_t iProduct; /* Index to product string */
uint8_t iSerialNumber; /* Index to serial number string */
uint8_t bNumConfigurations; /* Number of possible configurations */
uint8_t bLength; /* Descriptor size in bytes = 18 */
uint8_t bDescriptorType; /* DEVICE descriptor type = 1 */
uint16_t bcdUSB; /* USB spec in BCD, e.g. 0x0200 */
uint8_t bDeviceClass; /* Class code, if 0 see interface */
uint8_t bDeviceSubClass; /* Sub-Class code, 0 if class = 0 */
uint8_t bDeviceProtocol; /* Protocol, if 0 see interface */
uint8_t bMaxPacketSize0; /* Endpoint 0 max. size */
uint16_t idVendor; /* Vendor ID per USB-IF */
uint16_t idProduct; /* Product ID per manufacturer */
uint16_t bcdDevice; /* Device release # in BCD */
uint8_t iManufacturer; /* Index to manufacturer string */
uint8_t iProduct; /* Index to product string */
uint8_t iSerialNumber; /* Index to serial number string */
uint8_t bNumConfigurations; /* Number of possible configurations */
} __packed;
/** USB device_qualifier descriptor */
struct usb_device_qualifier_descriptor {
uint8_t bLength; /* Descriptor size in bytes = 10 */
uint8_t bDescriptorType; /* DEVICE QUALIFIER type = 6 */
uint16_t bcdUSB; /* USB spec in BCD, e.g. 0x0200 */
uint8_t bDeviceClass; /* Class code, if 0 see interface */
uint8_t bDeviceSubClass; /* Sub-Class code, 0 if class = 0 */
uint8_t bDeviceProtocol; /* Protocol, if 0 see interface */
uint8_t bMaxPacketSize; /* Endpoint 0 max. size */
uint8_t bNumConfigurations; /* Number of possible configurations */
uint8_t bReserved; /* Reserved = 0 */
uint8_t bLength; /* Descriptor size in bytes = 10 */
uint8_t bDescriptorType; /* DEVICE QUALIFIER type = 6 */
uint16_t bcdUSB; /* USB spec in BCD, e.g. 0x0200 */
uint8_t bDeviceClass; /* Class code, if 0 see interface */
uint8_t bDeviceSubClass; /* Sub-Class code, 0 if class = 0 */
uint8_t bDeviceProtocol; /* Protocol, if 0 see interface */
uint8_t bMaxPacketSize; /* Endpoint 0 max. size */
uint8_t bNumConfigurations; /* Number of possible configurations */
uint8_t bReserved; /* Reserved = 0 */
} __packed;
/** Standard Configuration Descriptor */
struct usb_configuration_descriptor {
uint8_t bLength; /* Descriptor size in bytes = 9 */
uint8_t bDescriptorType; /* CONFIGURATION type = 2 or 7 */
uint16_t wTotalLength; /* Length of concatenated descriptors */
uint8_t bNumInterfaces; /* Number of interfaces, this config. */
uint8_t bConfigurationValue; /* Value to set this config. */
uint8_t iConfiguration; /* Index to configuration string */
uint8_t bmAttributes; /* Config. characteristics */
uint8_t bMaxPower; /* Max.power from bus, 2mA units */
uint8_t bLength; /* Descriptor size in bytes = 9 */
uint8_t bDescriptorType; /* CONFIGURATION type = 2 or 7 */
uint16_t wTotalLength; /* Length of concatenated descriptors */
uint8_t bNumInterfaces; /* Number of interfaces, this config. */
uint8_t bConfigurationValue; /* Value to set this config. */
uint8_t iConfiguration; /* Index to configuration string */
uint8_t bmAttributes; /* Config. characteristics */
uint8_t bMaxPower; /* Max.power from bus, 2mA units */
} __packed;
/** Standard Interface Descriptor */
struct usb_interface_descriptor {
uint8_t bLength; /* Descriptor size in bytes = 9 */
uint8_t bDescriptorType; /* INTERFACE descriptor type = 4 */
uint8_t bInterfaceNumber; /* Interface no.*/
uint8_t bAlternateSetting; /* Value to select this IF */
uint8_t bNumEndpoints; /* Number of endpoints excluding 0 */
uint8_t bInterfaceClass; /* Class code, 0xFF = vendor */
uint8_t bInterfaceSubClass; /* Sub-Class code, 0 if class = 0 */
uint8_t bInterfaceProtocol; /* Protocol, 0xFF = vendor */
uint8_t iInterface; /* Index to interface string */
uint8_t bLength; /* Descriptor size in bytes = 9 */
uint8_t bDescriptorType; /* INTERFACE descriptor type = 4 */
uint8_t bInterfaceNumber; /* Interface no.*/
uint8_t bAlternateSetting; /* Value to select this IF */
uint8_t bNumEndpoints; /* Number of endpoints excluding 0 */
uint8_t bInterfaceClass; /* Class code, 0xFF = vendor */
uint8_t bInterfaceSubClass; /* Sub-Class code, 0 if class = 0 */
uint8_t bInterfaceProtocol; /* Protocol, 0xFF = vendor */
uint8_t iInterface; /* Index to interface string */
} __packed;
/** Standard Endpoint Descriptor */
struct usb_endpoint_descriptor {
uint8_t bLength; /* Descriptor size in bytes = 7 */
uint8_t bDescriptorType; /* ENDPOINT descriptor type = 5 */
uint8_t bEndpointAddress; /* Endpoint # 0 - 15 | IN/OUT */
uint8_t bmAttributes; /* Transfer type */
uint16_t wMaxPacketSize; /* Bits 10:0 = max. packet size */
uint8_t bInterval; /* Polling interval in (micro) frames */
} __packed;
uint8_t bLength; /* Descriptor size in bytes = 7 */
uint8_t bDescriptorType; /* ENDPOINT descriptor type = 5 */
uint8_t bEndpointAddress; /* Endpoint # 0 - 15 | IN/OUT */
uint8_t bmAttributes; /* Transfer type */
uint16_t wMaxPacketSize; /* Bits 10:0 = max. packet size */
uint8_t bInterval; /* Polling interval in (micro) frames */
} __packed;
/** Unicode (UTF16LE) String Descriptor */
struct usb_string_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bString;
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bString;
} __packed;
/* USB Interface Association Descriptor */
struct usb_interface_association_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bFirstInterface;
uint8_t bInterfaceCount;
uint8_t bFunctionClass;
uint8_t bFunctionSubClass;
uint8_t bFunctionProtocol;
uint8_t iFunction;
} __packed;
/* MS OS 1.0 string descriptor */
struct usb_msosv1_string_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bString[14];
uint8_t bMS_VendorCode; /* Vendor Code, used for a control request */
uint8_t bPad; /* Padding byte for VendorCode look as UTF16 */
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bString[14];
uint8_t bMS_VendorCode; /* Vendor Code, used for a control request */
uint8_t bPad; /* Padding byte for VendorCode look as UTF16 */
} __packed;
/* MS OS 1.0 Header descriptor */
struct usb_msosv1_compat_id_header_descriptor
{
struct usb_msosv1_compat_id_header_descriptor {
uint32_t dwLength;
uint16_t bcdVersion;
uint16_t wIndex;
uint8_t bCount;
uint8_t reserved[7];
uint8_t bCount;
uint8_t reserved[7];
} __packed;
/* MS OS 1.0 Function descriptor */
struct usb_msosv1_comp_id_function_descriptor
{
struct usb_msosv1_comp_id_function_descriptor {
uint8_t bFirstInterfaceNumber;
uint8_t reserved1;
uint8_t compatibleID[8];
@ -357,30 +351,28 @@ 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 \
{\
struct usb_msosv1_compat_id_header_descriptor compat_id_header;\
struct usb_msosv1_comp_id_function_descriptor compat_id_function[x];\
};
#define usb_msosv1_comp_id_property_create(x) \
struct usb_msosv1_comp_id_property { \
struct usb_msosv1_compat_id_header_descriptor compat_id_header; \
struct usb_msosv1_comp_id_function_descriptor compat_id_function[x]; \
};
struct usb_msosv1_descriptor
{
uint8_t *string;
uint8_t string_len;
uint8_t vendor_code;
uint8_t *compat_id;
uint16_t compat_id_len;
struct usb_msosv1_descriptor {
uint8_t *string;
uint8_t string_len;
uint8_t vendor_code;
uint8_t *compat_id;
uint16_t compat_id_len;
uint8_t *comp_id_property;
uint16_t comp_id_property_len;
};
/* MS OS 2.0 Header descriptor */
struct usb_msosv2_property_header_descriptor
{
struct usb_msosv2_property_header_descriptor {
uint32_t dwLength;
uint16_t bcdVersion;
uint16_t wIndex;
uint8_t bCount;
uint8_t bCount;
} __packed;
/* WinUSB Microsoft OS 2.0 descriptor set header */
@ -401,8 +393,7 @@ struct winusb_subset_function_descriptor {
} __packed;
/* MS OS 2.0 Function Section */
struct usb_msosv2_comp_id_function_descriptor
{
struct usb_msosv2_comp_id_function_descriptor {
uint16_t wLength;
uint16_t wDescriptorType;
uint8_t compatibleID[8];
@ -410,125 +401,122 @@ struct usb_msosv2_comp_id_function_descriptor
} __packed;
/* MS OS 2.0 property descriptor */
struct usb_msosv2_proerty_descriptor
{
struct usb_msosv2_proerty_descriptor {
uint16_t wLength;
uint16_t wDescriptorType;
uint32_t dwPropertyDataType;
uint16_t wPropertyNameLength;
const char * bPropertyName;
const char *bPropertyName;
uint32_t dwPropertyDataLength;
const char * bPropertyData;
const char *bPropertyData;
};
struct usb_msosv2_descriptor
{
uint8_t* compat_id;
struct usb_msosv2_descriptor {
uint8_t *compat_id;
uint16_t compat_id_len;
};
/* BOS Descriptor */
struct usb_bos_header_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumDeviceCaps;
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumDeviceCaps;
} __packed;
/* BOS Capability Descriptor */
struct usb_bos_capability_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint8_t bReserved;
uint8_t PlatformCapabilityUUID[16];
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint8_t bReserved;
uint8_t PlatformCapabilityUUID[16];
} __packed;
struct usb_bos_capability_lpm {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint32_t bmAttributes;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint32_t bmAttributes;
} __packed;
struct usb_bos_descriptor
{
uint8_t* bos_id;
struct usb_bos_descriptor {
uint8_t *bos_id;
uint8_t bos_id_len;
};
/* USB Device Capability Descriptor */
struct usb_device_capability__descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
} __packed;
/** USB descriptor header */
struct usb_desc_header {
uint8_t bLength; /**< descriptor length */
uint8_t bDescriptorType; /**< descriptor type */
uint8_t bLength; /**< descriptor length */
uint8_t bDescriptorType; /**< descriptor type */
};
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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 */
#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_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 */
#define USB_LANGID_INIT(id) \
0x04, /* bLength */\
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */\
WBVAL(id) /* wLangID0 */
#endif

View file

@ -15,16 +15,13 @@ extern "C" {
#define usb_container_of(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
/**
* Single List structure
*/
struct usb_slist_node
{
struct usb_slist_node *next; /**< point to next node. */
struct usb_slist_node {
struct usb_slist_node *next; /**< point to next node. */
};
typedef struct usb_slist_node usb_slist_t; /**< Type for single list. */
typedef struct usb_slist_node usb_slist_t; /**< Type for single list. */
/**
* @brief initialize a single list
@ -38,13 +35,15 @@ static inline void usb_slist_init(usb_slist_t *l)
static inline void usb_slist_add_head(usb_slist_t *l, usb_slist_t *n)
{
n->next = l->next;
l->next = n;
n->next = l->next;
l->next = n;
}
static inline void usb_slist_add_tail(usb_slist_t *l, usb_slist_t *n)
{
while (l->next) l = l->next;
while (l->next) {
l = l->next;
}
/* append the node to the tail */
l->next = n;
@ -53,18 +52,15 @@ static inline void usb_slist_add_tail(usb_slist_t *l, usb_slist_t *n)
static inline void usb_slist_insert(usb_slist_t *l, usb_slist_t *next, usb_slist_t *n)
{
if (!next)
{
if (!next) {
usb_slist_add_tail(next, l);
return;
}
while (l->next)
{
if (l->next == next)
{
l->next = n;
n->next = next;
while (l->next) {
if (l->next == next) {
l->next = n;
n->next = next;
}
l = l->next;
@ -74,10 +70,14 @@ static inline void usb_slist_insert(usb_slist_t *l, usb_slist_t *next, usb_slist
static inline usb_slist_t *usb_slist_remove(usb_slist_t *l, usb_slist_t *n)
{
/* remove slist head */
while (l->next && l->next != n) l = l->next;
while (l->next && l->next != n) {
l = l->next;
}
/* remove node */
if (l->next != (usb_slist_t *)0) l->next = l->next->next;
if (l->next != (usb_slist_t *)0) {
l->next = l->next->next;
}
return l;
}
@ -86,10 +86,10 @@ static inline unsigned int usb_slist_len(const usb_slist_t *l)
{
unsigned int len = 0;
const usb_slist_t *list = l->next;
while (list != NULL)
{
while (list != NULL) {
list = list->next;
len ++;
len++;
}
return len;
@ -97,10 +97,8 @@ static inline unsigned int usb_slist_len(const usb_slist_t *l)
static inline unsigned int usb_slist_contains(usb_slist_t *l, usb_slist_t *n)
{
while (l->next)
{
if (l->next == n)
{
while (l->next) {
if (l->next == n) {
return 0;
}
@ -117,7 +115,9 @@ static inline usb_slist_t *usb_slist_head(usb_slist_t *l)
static inline usb_slist_t *usb_slist_tail(usb_slist_t *l)
{
while (l->next) l = l->next;
while (l->next) {
l = l->next;
}
return l;
}
@ -135,14 +135,17 @@ static inline int usb_slist_isempty(usb_slist_t *l)
/**
* @brief initialize a slist object
*/
#define USB_SLIST_OBJECT_INIT(object) { NULL }
#define USB_SLIST_OBJECT_INIT(object) \
{ \
NULL \
}
/**
* @brief initialize a slist object
*/
#define USB_SLIST_DEFINE(slist) \
usb_slist_t slist = { NULL }
/**
* @brief get the struct for this single list node
* @param node the entry point
@ -193,9 +196,9 @@ static inline int usb_slist_isempty(usb_slist_t *l)
#define usb_slist_for_each(pos, head) \
for (pos = (head)->next; pos != NULL; pos = pos->next)
#define usb_slist_for_each_safe(pos, next, head) \
#define usb_slist_for_each_safe(pos, next, head) \
for (pos = (head)->next, next = pos->next; pos; \
pos = next, next = pos->next)
pos = next, next = pos->next)
/**
* usb_slist_for_each_entry - iterate over single list of given type
@ -203,16 +206,16 @@ static inline int usb_slist_isempty(usb_slist_t *l)
* @head: the head for your single list.
* @member: the name of the list_struct within the struct.
*/
#define usb_slist_for_each_entry(pos, head, member) \
#define usb_slist_for_each_entry(pos, head, member) \
for (pos = usb_slist_entry((head)->next, typeof(*pos), member); \
&pos->member != (NULL); \
&pos->member != (NULL); \
pos = usb_slist_entry(pos->member.next, typeof(*pos), member))
#define usb_slist_for_each_entry_safe(pos, n, head, member) \
for (pos = usb_slist_entry((head)->next, typeof(*pos), member), \
n = usb_slist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (NULL); \
pos = n, n = usb_slist_entry(pos->member.next, typeof(*pos), member))
#define usb_slist_for_each_entry_safe(pos, n, head, member) \
for (pos = usb_slist_entry((head)->next, typeof(*pos), member), \
n = usb_slist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (NULL); \
pos = n, n = usb_slist_entry(pos->member.next, typeof(*pos), member))
#ifdef __cplusplus
}

View file

@ -70,10 +70,10 @@
#define BCD(x) ((((x) / 10) << 4) | ((x) % 10))
#define BIT(x) (1<<(x))
#define BIT(x) (1 << (x))
#define ARRAY_SIZE(array) \
((int)((sizeof(array) / sizeof((array)[0]))))
((int)((sizeof(array) / sizeof((array)[0]))))
#define USB_DESC_SECTION __attribute__((section("usb_desc"))) __used __aligned(1)
@ -81,44 +81,41 @@
#define BSWAP32(u32) (__builtin_bswap32(u32))
#define GET_BE16(field) \
(((uint16_t)(field)[0] << 8) | ((uint16_t)(field)[1]))
(((uint16_t)(field)[0] << 8) | ((uint16_t)(field)[1]))
#define GET_BE32(field) \
(((uint32_t)(field)[0] << 24) | ((uint32_t)(field)[1] << 16) | ((uint32_t)(field)[2] << 8) | ((uint32_t)(field)[3] << 0))
(((uint32_t)(field)[0] << 24) | ((uint32_t)(field)[1] << 16) | ((uint32_t)(field)[2] << 8) | ((uint32_t)(field)[3] << 0))
#define SET_BE16(field, value) \
do \
{ \
(field)[0] = (uint8_t)((value) >> 8); \
(field)[1] = (uint8_t)((value) >> 0); \
} while (0)
#define SET_BE16(field, value) \
do { \
(field)[0] = (uint8_t)((value) >> 8); \
(field)[1] = (uint8_t)((value) >> 0); \
} while (0)
#define SET_BE24(field, value) \
do \
{ \
(field)[0] = (uint8_t)((value) >> 16); \
(field)[1] = (uint8_t)((value) >> 8); \
(field)[2] = (uint8_t)((value) >> 0); \
} while (0)
#define SET_BE24(field, value) \
do { \
(field)[0] = (uint8_t)((value) >> 16); \
(field)[1] = (uint8_t)((value) >> 8); \
(field)[2] = (uint8_t)((value) >> 0); \
} while (0)
#define SET_BE32(field, value) \
do \
{ \
(field)[0] = (uint8_t)((value) >> 24); \
(field)[1] = (uint8_t)((value) >> 16); \
(field)[2] = (uint8_t)((value) >> 8); \
(field)[3] = (uint8_t)((value) >> 0); \
} while (0)
#define SET_BE32(field, value) \
do { \
(field)[0] = (uint8_t)((value) >> 24); \
(field)[1] = (uint8_t)((value) >> 16); \
(field)[2] = (uint8_t)((value) >> 8); \
(field)[3] = (uint8_t)((value) >> 0); \
} while (0)
#define REQTYPE_GET_DIR(x) (((x) >> 7) & 0x01)
#define REQTYPE_GET_TYPE(x) (((x) >> 5) & 0x03U)
#define REQTYPE_GET_DIR(x) (((x) >> 7) & 0x01)
#define REQTYPE_GET_TYPE(x) (((x) >> 5) & 0x03U)
#define REQTYPE_GET_RECIP(x) ((x)&0x1F)
#define GET_DESC_TYPE(x) (((x) >> 8) & 0xFFU)
#define GET_DESC_TYPE(x) (((x) >> 8) & 0xFFU)
#define GET_DESC_INDEX(x) ((x)&0xFFU)
#define WBVAL(x) (x & 0xFF),((x >> 8) & 0xFF)
#define DBVAL(x) (x & 0xFF),((x >> 8) & 0xFF),((x >> 16) & 0xFF),((x >> 24) & 0xFF)
#define WBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF)
#define DBVAL(x) (x & 0xFF), ((x >> 8) & 0xFF), ((x >> 16) & 0xFF), ((x >> 24) & 0xFF)
#if 0
#define USBD_LOG_WRN(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
@ -126,9 +123,9 @@
#define USBD_LOG_ERR(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#else
#define USBD_LOG_WRN(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#define USBD_LOG_DBG(a, ...)
#define USBD_LOG_DBG(a, ...)
#define USBD_LOG_ERR(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#define USBD_LOG(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#define USBD_LOG(a, ...) bflb_platform_printf(a, ##__VA_ARGS__)
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,75 +1,75 @@
/**
* @file usbd_core.h
*
*
* Copyright (c) 2021 Bouffalolab team
*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*
*/
#ifndef _USBD_CORE_H
#define _USBD_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "usb_util.h"
#include "usb_def.h"
#include "usb_dc.h"
#ifdef __cplusplus
extern "C" {
#endif
enum usb_event_type
{
/** USB error reported by the controller */
USB_EVENT_ERROR,
/** USB reset */
USB_EVENT_RESET,
/** Start of Frame received */
USB_EVENT_SOF,
/** USB connection established, hardware enumeration is completed */
USB_EVENT_CONNECTED,
/** USB configuration done */
USB_EVENT_CONFIGURED,
/** USB connection suspended by the HOST */
USB_EVENT_SUSPEND,
/** USB connection lost */
USB_EVENT_DISCONNECTED,
/** USB connection resumed by the HOST */
USB_EVENT_RESUME,
enum usb_event_type {
/** USB error reported by the controller */
USB_EVENT_ERROR,
/** USB reset */
USB_EVENT_RESET,
/** Start of Frame received */
USB_EVENT_SOF,
/** USB connection established, hardware enumeration is completed */
USB_EVENT_CONNECTED,
/** USB configuration done */
USB_EVENT_CONFIGURED,
/** USB connection suspended by the HOST */
USB_EVENT_SUSPEND,
/** USB connection lost */
USB_EVENT_DISCONNECTED,
/** USB connection resumed by the HOST */
USB_EVENT_RESUME,
/** USB interface selected */
USB_EVENT_SET_INTERFACE,
/** USB interface selected */
USB_EVENT_SET_REMOTE_WAKEUP,
/** USB interface selected */
USB_EVENT_CLEAR_REMOTE_WAKEUP,
/** Set Feature ENDPOINT_HALT received */
USB_EVENT_SET_HALT,
/** Clear Feature ENDPOINT_HALT received */
USB_EVENT_CLEAR_HALT,
/** setup packet received */
USB_EVENT_SETUP_NOTIFY,
/** ep0 in packet received */
USB_EVENT_EP0_IN_NOTIFY,
/** ep0 out packet received */
USB_EVENT_EP0_OUT_NOTIFY,
/** ep in packet except ep0 received */
USB_EVENT_EP_IN_NOTIFY,
/** ep out packet except ep0 received */
USB_EVENT_EP_OUT_NOTIFY,
/** Initial USB connection status */
USB_EVENT_UNKNOWN
/** USB interface selected */
USB_EVENT_SET_INTERFACE,
/** USB interface selected */
USB_EVENT_SET_REMOTE_WAKEUP,
/** USB interface selected */
USB_EVENT_CLEAR_REMOTE_WAKEUP,
/** Set Feature ENDPOINT_HALT received */
USB_EVENT_SET_HALT,
/** Clear Feature ENDPOINT_HALT received */
USB_EVENT_CLEAR_HALT,
/** setup packet received */
USB_EVENT_SETUP_NOTIFY,
/** ep0 in packet received */
USB_EVENT_EP0_IN_NOTIFY,
/** ep0 out packet received */
USB_EVENT_EP0_OUT_NOTIFY,
/** ep in packet except ep0 received */
USB_EVENT_EP_IN_NOTIFY,
/** ep out packet except ep0 received */
USB_EVENT_EP_OUT_NOTIFY,
/** Initial USB connection status */
USB_EVENT_UNKNOWN
};
/**
@ -89,47 +89,44 @@ typedef void (*usbd_endpoint_callback)(uint8_t ep);
* data to be transmitted buffer respectively.
*/
typedef int (*usbd_request_handler)(struct usb_setup_packet *setup,
uint8_t **data,uint32_t *transfer_len);
uint8_t **data, uint32_t *transfer_len);
/* callback function pointer structure for Application to handle events */
typedef void (*usbd_notify_handler)(uint8_t event, void* arg);
typedef void (*usbd_notify_handler)(uint8_t event, void *arg);
typedef struct usbd_endpoint
{
usb_slist_t list;
uint8_t ep_addr;
usbd_endpoint_callback ep_cb;
typedef struct usbd_endpoint {
usb_slist_t list;
uint8_t ep_addr;
usbd_endpoint_callback ep_cb;
} usbd_endpoint_t;
typedef struct usbd_interface
{
usb_slist_t list;
/** Handler for USB Class specific Control (EP 0) communications */
usbd_request_handler class_handler;
/** Handler for USB Vendor specific commands */
usbd_request_handler vendor_handler;
/** Handler for USB custom specific commands */
usbd_request_handler custom_handler;
/** Handler for USB event notify commands */
usbd_notify_handler notify_handler;
uint8_t intf_num;
usb_slist_t ep_list;
typedef struct usbd_interface {
usb_slist_t list;
/** Handler for USB Class specific Control (EP 0) communications */
usbd_request_handler class_handler;
/** Handler for USB Vendor specific commands */
usbd_request_handler vendor_handler;
/** Handler for USB custom specific commands */
usbd_request_handler custom_handler;
/** Handler for USB event notify commands */
usbd_notify_handler notify_handler;
uint8_t intf_num;
usb_slist_t ep_list;
} usbd_interface_t;
typedef struct usbd_class
{
usb_slist_t list;
const char *name;
usb_slist_t intf_list;
typedef struct usbd_class {
usb_slist_t list;
const char *name;
usb_slist_t intf_list;
} usbd_class_t;
void usbd_event_notify_handler(uint8_t event, void* arg);
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_class_add_interface(usbd_class_t *class,usbd_interface_t *intf);
void usbd_interface_add_endpoint(usbd_interface_t *intf,usbd_endpoint_t *ep);
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);
#ifdef __cplusplus
@ -137,4 +134,3 @@ bool usb_device_is_configured(void);
#endif
#endif