first commit
This commit is contained in:
96
class/audio/usbd_audio.c
Normal file
96
class/audio/usbd_audio.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
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)
|
||||
{
|
||||
USBD_LOG_DBG("Class request:"
|
||||
"bRequest 0x%02x, bmRequestType 0x%02x len %d",
|
||||
setup->bRequest, setup->bmRequestType, *len);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_GET_CUR:
|
||||
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;
|
||||
*len = 2;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_SET_RES:
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_GET_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;
|
||||
*len = 2;
|
||||
break;
|
||||
|
||||
case AUDIO_REQUEST_GET_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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_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 = audio_class_request_handler;
|
||||
intf->custom_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = audio_notify_handler;
|
||||
usbd_class_add_interface(class, intf);
|
||||
}
|
||||
277
class/audio/usbd_audio.h
Normal file
277
class/audio/usbd_audio.h
Normal file
@@ -0,0 +1,277 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief USB Audio Device Class public header
|
||||
*
|
||||
* Header follows below documentation:
|
||||
* - USB Device Class Definition for Audio Devices (audio10.pdf)
|
||||
*
|
||||
* Additional documentation considered a part of USB Audio v1.0:
|
||||
* - USB Device Class Definition for Audio Data Formats (frmts10.pdf)
|
||||
* - USB Device Class Definition for Terminal Types (termt10.pdf)
|
||||
*/
|
||||
|
||||
#ifndef _USBD_AUDIO_H_
|
||||
#define _USBD_AUDIO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** 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_PROTOCOL_UNDEFINED 0x00U
|
||||
|
||||
#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
|
||||
|
||||
/** 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
|
||||
|
||||
/** 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
|
||||
|
||||
/* 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
|
||||
|
||||
/** 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/** 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,
|
||||
|
||||
/* 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,
|
||||
|
||||
/* 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,
|
||||
};
|
||||
|
||||
/**
|
||||
* @warning Size of baInterface is 2 just to make it useable
|
||||
* for all kind of devices: headphones, microphone and headset.
|
||||
* Actual size of the struct should be checked by reading
|
||||
* .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];
|
||||
} __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;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* @note Size of Feature unit descriptor is not fixed.
|
||||
* 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];
|
||||
} __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;
|
||||
} __packed;
|
||||
|
||||
struct as_cs_interface_descriptor {
|
||||
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];
|
||||
} __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;
|
||||
} __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;
|
||||
} __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;
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
#endif /* _USB_AUDIO_H_ */
|
||||
168
class/cdc/usbd_cdc.c
Normal file
168
class/cdc/usbd_cdc.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/**
|
||||
* @file usbd_cdc.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_cdc.h"
|
||||
|
||||
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;
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handler called for Class requests not handled by the USB stack.
|
||||
*
|
||||
* @param pSetup Information about the request to execute.
|
||||
* @param len Size of the buffer.
|
||||
* @param data Buffer containing the request result.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
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_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;
|
||||
|
||||
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);
|
||||
}
|
||||
374
class/cdc/usbd_cdc.h
Normal file
374
class/cdc/usbd_cdc.h
Normal file
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief USB Communications Device Class (CDC) public header
|
||||
*
|
||||
* Header follows the Class Definitions for
|
||||
* Communications Devices Specification (CDC120-20101103-track.pdf),
|
||||
* PSTN Devices Specification (PSTN120.pdf) and
|
||||
* Ethernet Control Model Devices Specification (ECM120.pdf).
|
||||
* Header is limited to ACM and ECM Subclasses.
|
||||
*/
|
||||
|
||||
#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
|
||||
// Communication device class specification version 1.2
|
||||
#define CDC_V1_2_0 0x0120U
|
||||
|
||||
/* Communication interface class code */
|
||||
/* (usbcdc11.pdf, 4.2, Table 15) */
|
||||
#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
|
||||
|
||||
/* 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
|
||||
// NCM Communication Interface Protocol Codes
|
||||
// (usbncm10.pdf, 4.2, Table 4-2)
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* Communication feature selector codes */
|
||||
/* (usbcdc11.pdf, 6.2.2..6.2.4, Table 47) */
|
||||
#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
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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)
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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)
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Structures based on usbcdc11.pdf (www.usb.org)
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Header functional descriptor */
|
||||
/* (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 */
|
||||
} __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) */
|
||||
} __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 */
|
||||
} __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 */
|
||||
} __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;
|
||||
} __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 */
|
||||
} __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;
|
||||
} __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;
|
||||
} __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_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_ */
|
||||
227
class/hid/usbd_hid.c
Normal file
227
class/hid/usbd_hid.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @file usbd_hid.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_hid.h"
|
||||
|
||||
#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;
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
USBD_LOG_DBG("Standard request:"
|
||||
"bmRequestType 0x%02x, bRequest 0x%02x, len %d\r\n",
|
||||
setup->bmRequestType, setup->bRequest, *len);
|
||||
|
||||
if (REQTYPE_GET_DIR(setup->bmRequestType) == USB_REQUEST_DEVICE_TO_HOST &&
|
||||
setup->bRequest == USB_REQUEST_GET_DESCRIPTOR) {
|
||||
uint8_t value = (uint8_t)(setup->wValue >> 8);
|
||||
uint8_t intf_num = (uint8_t)setup->wIndex;
|
||||
|
||||
struct usbd_hid_cfg_private *current_hid_intf = NULL;
|
||||
usb_slist_t *i;
|
||||
usb_slist_for_each(i, &usbd_hid_class_head)
|
||||
{
|
||||
struct usbd_hid_cfg_private *hid_intf = usb_slist_entry(i, struct usbd_hid_cfg_private, list);
|
||||
|
||||
if (hid_intf->current_intf_num == intf_num) {
|
||||
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;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
struct usbd_hid_cfg_private *current_hid_intf = NULL;
|
||||
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);
|
||||
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 *)¤t_hid_intf->report;
|
||||
*len = 1;
|
||||
break;
|
||||
case HID_REQUEST_GET_IDLE:
|
||||
*data = (uint8_t *)¤t_hid_intf->idle_state;
|
||||
*len = 1;
|
||||
break;
|
||||
case HID_REQUEST_GET_PROTOCOL:
|
||||
*data = (uint8_t *)¤t_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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void usbd_hid_send_report(uint8_t ep, uint8_t *data, uint8_t len)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
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_add_interface(usbd_class_t *class, usbd_interface_t *intf)
|
||||
{
|
||||
static usbd_class_t *last_class = NULL;
|
||||
static uint8_t hid_num = 0;
|
||||
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);
|
||||
|
||||
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++;
|
||||
}
|
||||
344
class/hid/usbd_hid.h
Normal file
344
class/hid/usbd_hid.h
Normal file
@@ -0,0 +1,344 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief USB Human Interface Device (HID) Class public header
|
||||
*
|
||||
* Header follows Device Class Definition for Human Interface Devices (HID)
|
||||
* Version 1.11 document (HID1_11-1.pdf).
|
||||
*/
|
||||
#ifndef _USBD_HID_H_
|
||||
#define _USBD_HID_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
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
|
||||
|
||||
/* 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
|
||||
|
||||
/* HID Report Definitions */
|
||||
struct usb_hid_class_subdescriptor {
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* HID Local Items tags */
|
||||
#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_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_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)
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* Collection types */
|
||||
#define COLLECTION_PHYSICAL 0x00
|
||||
#define COLLECTION_APPLICATION 0x01
|
||||
|
||||
/* Protocols */
|
||||
#define HID_PROTOCOL_BOOT 0x00
|
||||
#define HID_PROTOCOL_REPORT 0x01
|
||||
|
||||
/* Example HID report descriptors */
|
||||
/**
|
||||
* @brief Simple HID mouse report descriptor for n button mouse.
|
||||
*
|
||||
* @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, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,
|
||||
};
|
||||
|
||||
/**
|
||||
* @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,
|
||||
};
|
||||
|
||||
/**
|
||||
* @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,
|
||||
};
|
||||
|
||||
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
|
||||
|
||||
#endif /* _USB_HID_H_ */
|
||||
838
class/msc/usbd_msc.c
Normal file
838
class/msc/usbd_msc.c
Normal file
@@ -0,0 +1,838 @@
|
||||
/**
|
||||
* @file usbd_msc.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_scsi.h"
|
||||
#include "usbd_msc.h"
|
||||
|
||||
/* max USB packet size */
|
||||
#define MASS_STORAGE_BULK_EP_MPS 64
|
||||
#define MASS_STORAGE_BLOCK_SIZE 512
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
#define MSD_IN_EP_IDX 1
|
||||
|
||||
/* Describe EndPoints configuration */
|
||||
static usbd_endpoint_t mass_ep_data[2];
|
||||
|
||||
/* MSC Bulk-only Stage */
|
||||
enum Stage {
|
||||
/* MSC Bulk-only Stage */
|
||||
MSC_BS_CBW = 0, /* Command Block Wrapper */
|
||||
MSC_BS_DATA_OUT = 1, /* Data Out Phase */
|
||||
MSC_BS_DATA_IN = 2, /* Data In Phase */
|
||||
MSC_BS_DATA_IN_LAST = 3, /* Data In Last Phase */
|
||||
MSC_BS_DATA_IN_LAST_STALL = 4, /* Data In Last Phase with Stall */
|
||||
MSC_BS_CSW = 5, /* Command Status Wrapper */
|
||||
MSC_BS_ERROR = 6, /* Error */
|
||||
MSC_BS_RESET = 7, /* Bulk-Only Mass Storage Reset */
|
||||
};
|
||||
|
||||
/* Device data structure */
|
||||
struct usbd_msc_cfg_private {
|
||||
/* state of the bulk-only state machine */
|
||||
enum Stage stage;
|
||||
struct CBW cbw;
|
||||
struct CSW csw;
|
||||
|
||||
uint8_t max_lun_count;
|
||||
uint16_t scsi_blk_size;
|
||||
uint32_t scsi_blk_nbr;
|
||||
|
||||
uint32_t scsi_blk_addr;
|
||||
uint32_t scsi_blk_len;
|
||||
uint8_t block_buffer[MASS_STORAGE_BLOCK_SIZE];
|
||||
|
||||
} usbd_msc_cfg;
|
||||
|
||||
/*memory OK (after a usbd_msc_memory_verify)*/
|
||||
static bool memOK;
|
||||
|
||||
static void usbd_msc_reset(void)
|
||||
{
|
||||
usbd_msc_cfg.stage = MSC_BS_CBW;
|
||||
(void)memset((void *)&usbd_msc_cfg.cbw, 0, sizeof(struct CBW));
|
||||
(void)memset((void *)&usbd_msc_cfg.csw, 0, sizeof(struct CSW));
|
||||
usbd_msc_cfg.scsi_blk_addr = 0U;
|
||||
usbd_msc_cfg.scsi_blk_len = 0U;
|
||||
usbd_msc_get_cap(0, &usbd_msc_cfg.scsi_blk_nbr, &usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.max_lun_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handler called for Class requests not handled by the USB stack.
|
||||
*
|
||||
* @param pSetup Information about the request to execute.
|
||||
* @param len Size of the buffer.
|
||||
* @param data Buffer containing the request result.
|
||||
*
|
||||
* @return 0 on success, negative errno code on fail.
|
||||
*/
|
||||
static int msc_storage_class_request_handler(struct usb_setup_packet *pSetup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
switch (pSetup->bRequest) {
|
||||
case MSC_REQUEST_RESET:
|
||||
USBD_LOG_DBG("MSC_REQUEST_RESET");
|
||||
|
||||
if (pSetup->wLength) {
|
||||
USBD_LOG_WRN("Invalid length");
|
||||
return -1;
|
||||
}
|
||||
|
||||
usbd_msc_reset();
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_GET_MAX_LUN:
|
||||
USBD_LOG_DBG("MSC_REQUEST_GET_MAX_LUN");
|
||||
|
||||
if (pSetup->wLength != 1) {
|
||||
USBD_LOG_WRN("Invalid length");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data = (uint8_t *)(&usbd_msc_cfg.max_lun_count);
|
||||
*len = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_LOG_WRN("Unknown request 0x%02x, value 0x%02x",
|
||||
pSetup->bRequest, pSetup->wValue);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbd_msc_send_csw(void)
|
||||
{
|
||||
usbd_msc_cfg.csw.Signature = MSC_CSW_Signature;
|
||||
|
||||
if (usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, (uint8_t *)&usbd_msc_cfg.csw,
|
||||
sizeof(struct CSW), NULL) != 0) {
|
||||
USBD_LOG_ERR("usb write failure");
|
||||
}
|
||||
|
||||
usbd_msc_cfg.stage = MSC_BS_CSW;
|
||||
}
|
||||
|
||||
static bool usbd_msc_datain_check(void)
|
||||
{
|
||||
if (!usbd_msc_cfg.cbw.DataLength) {
|
||||
USBD_LOG_WRN("Zero length in CBW");
|
||||
//SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
usbd_msc_send_csw();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((usbd_msc_cfg.cbw.Flags & 0x80) == 0) {
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
usbd_msc_send_csw();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool usbd_msc_send_to_host(uint8_t *buffer, uint16_t size)
|
||||
{
|
||||
if (size >= usbd_msc_cfg.cbw.DataLength) {
|
||||
size = usbd_msc_cfg.cbw.DataLength;
|
||||
usbd_msc_cfg.stage = MSC_BS_DATA_IN_LAST;
|
||||
} else {
|
||||
usbd_msc_cfg.stage = MSC_BS_DATA_IN_LAST_STALL;
|
||||
}
|
||||
|
||||
if (usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, buffer, size, NULL)) {
|
||||
USBD_LOG_ERR("USB write failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.csw.DataResidue -= size;
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void usbd_msc_memory_verify(uint8_t *buf, uint16_t size)
|
||||
{
|
||||
uint32_t n;
|
||||
|
||||
if ((usbd_msc_cfg.scsi_blk_addr + size) > (usbd_msc_cfg.scsi_blk_nbr * usbd_msc_cfg.scsi_blk_size)) {
|
||||
size = usbd_msc_cfg.scsi_blk_nbr * usbd_msc_cfg.scsi_blk_size - usbd_msc_cfg.scsi_blk_addr;
|
||||
usbd_msc_cfg.stage = MSC_BS_ERROR;
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
USBD_LOG_WRN("addr overflow,verify error\r\n");
|
||||
}
|
||||
|
||||
/* beginning of a new block -> load a whole block in RAM */
|
||||
if (!(usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size)) {
|
||||
USBD_LOG_DBG("Disk READ sector %d", usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size);
|
||||
// if (disk_access_read(disk_pdrv, page, addr / BLOCK_SIZE, 1))
|
||||
// {
|
||||
// USBD_LOG_ERR("---- Disk Read Error %d", addr / BLOCK_SIZE);
|
||||
// }
|
||||
}
|
||||
|
||||
/* info are in RAM -> no need to re-read memory */
|
||||
for (n = 0U; n < size; n++) {
|
||||
if (usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size + n] != buf[n]) {
|
||||
USBD_LOG_DBG("Mismatch sector %d offset %d",
|
||||
usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size, n);
|
||||
memOK = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
usbd_msc_cfg.scsi_blk_addr += size;
|
||||
usbd_msc_cfg.scsi_blk_len -= size;
|
||||
usbd_msc_cfg.csw.DataResidue -= size;
|
||||
|
||||
if (!usbd_msc_cfg.scsi_blk_len || (usbd_msc_cfg.stage == MSC_BS_CSW)) {
|
||||
usbd_msc_cfg.csw.Status = (memOK) ? CSW_STATUS_CMD_PASSED : CSW_STATUS_CMD_FAILED;
|
||||
usbd_msc_send_csw();
|
||||
}
|
||||
}
|
||||
|
||||
static void usbd_msc_memory_write(uint8_t *buf, uint16_t size)
|
||||
{
|
||||
USBD_LOG_DBG("w:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
|
||||
|
||||
if ((usbd_msc_cfg.scsi_blk_addr + size) > (usbd_msc_cfg.scsi_blk_nbr * usbd_msc_cfg.scsi_blk_size)) {
|
||||
size = usbd_msc_cfg.scsi_blk_nbr * usbd_msc_cfg.scsi_blk_size - usbd_msc_cfg.scsi_blk_addr;
|
||||
usbd_msc_cfg.stage = MSC_BS_ERROR;
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
USBD_LOG_WRN("addr overflow,write error\r\n");
|
||||
}
|
||||
|
||||
/* we fill an array in RAM of 1 block before writing it in memory */
|
||||
for (int i = 0; i < size; i++) {
|
||||
usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size + i] = buf[i];
|
||||
}
|
||||
|
||||
/* if the array is filled, write it in memory */
|
||||
if ((usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size) + size >= usbd_msc_cfg.scsi_blk_size) {
|
||||
usbd_msc_sector_write((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size);
|
||||
}
|
||||
|
||||
usbd_msc_cfg.scsi_blk_addr += size;
|
||||
usbd_msc_cfg.scsi_blk_len -= size;
|
||||
usbd_msc_cfg.csw.DataResidue -= size;
|
||||
|
||||
if ((!usbd_msc_cfg.scsi_blk_len) || (usbd_msc_cfg.stage == MSC_BS_CSW)) {
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
usbd_msc_send_csw();
|
||||
}
|
||||
}
|
||||
|
||||
static void usbd_msc_memory_read(void)
|
||||
{
|
||||
uint32_t transfer_len;
|
||||
|
||||
transfer_len = MIN(usbd_msc_cfg.scsi_blk_len, MASS_STORAGE_BULK_EP_MPS);
|
||||
|
||||
/* we read an entire block */
|
||||
if (!(usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size)) {
|
||||
usbd_msc_sector_read((usbd_msc_cfg.scsi_blk_addr / usbd_msc_cfg.scsi_blk_size), usbd_msc_cfg.block_buffer, usbd_msc_cfg.scsi_blk_size);
|
||||
}
|
||||
|
||||
USBD_LOG_DBG("addr:%d\r\n", usbd_msc_cfg.scsi_blk_addr);
|
||||
|
||||
usbd_ep_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
|
||||
&usbd_msc_cfg.block_buffer[usbd_msc_cfg.scsi_blk_addr % usbd_msc_cfg.scsi_blk_size], transfer_len, NULL);
|
||||
|
||||
usbd_msc_cfg.scsi_blk_addr += transfer_len;
|
||||
usbd_msc_cfg.scsi_blk_len -= transfer_len;
|
||||
usbd_msc_cfg.csw.DataResidue -= transfer_len;
|
||||
|
||||
if (!usbd_msc_cfg.scsi_blk_len) {
|
||||
usbd_msc_cfg.stage = MSC_BS_DATA_IN_LAST;
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************SCSI CMD*******************************************************************/
|
||||
static bool scsi_test_unit_ready(void)
|
||||
{
|
||||
if (usbd_msc_cfg.cbw.DataLength != 0U) {
|
||||
if ((usbd_msc_cfg.cbw.Flags & 0x80) != 0U) {
|
||||
USBD_LOG_WRN("Stall IN endpoint\r\n");
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
} else {
|
||||
USBD_LOG_WRN("Stall OUT endpoint\r\n");
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
usbd_msc_send_csw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool scsi_request_sense(void)
|
||||
{
|
||||
if (!usbd_msc_datain_check()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_sense_fixed_resp_t sense_rsp = {
|
||||
.response_code = 0x70,
|
||||
.valid = 1
|
||||
};
|
||||
|
||||
sense_rsp.add_sense_len = sizeof(scsi_sense_fixed_resp_t) - 8;
|
||||
sense_rsp.sense_key = 0x00;
|
||||
sense_rsp.add_sense_code = 0x00;
|
||||
sense_rsp.add_sense_qualifier = 0x00;
|
||||
|
||||
/* Win host requests maximum number of bytes but as all we have is 4 bytes we have
|
||||
to tell host back that it is all we have, that's why we correct residue */
|
||||
if (usbd_msc_cfg.csw.DataResidue > sizeof(sense_rsp)) {
|
||||
usbd_msc_cfg.cbw.DataLength = sizeof(sense_rsp);
|
||||
usbd_msc_cfg.csw.DataResidue = sizeof(sense_rsp);
|
||||
}
|
||||
|
||||
#if 0
|
||||
request_sense[ 2] = 0x06; /* UNIT ATTENTION */
|
||||
request_sense[12] = 0x28; /* Additional Sense Code: Not ready to ready transition */
|
||||
request_sense[13] = 0x00; /* Additional Sense Code Qualifier */
|
||||
#endif
|
||||
#if 0
|
||||
request_sense[ 2] = 0x02; /* NOT READY */
|
||||
request_sense[12] = 0x3A; /* Additional Sense Code: Medium not present */
|
||||
request_sense[13] = 0x00; /* Additional Sense Code Qualifier */
|
||||
#endif
|
||||
#if 0
|
||||
request_sense[ 2] = 0x05; /* ILLEGAL REQUEST */
|
||||
request_sense[12] = 0x20; /* Additional Sense Code: Invalid command */
|
||||
request_sense[13] = 0x00; /* Additional Sense Code Qualifier */
|
||||
#endif
|
||||
#if 0
|
||||
request_sense[ 2] = 0x00; /* NO SENSE */
|
||||
request_sense[12] = 0x00; /* Additional Sense Code: No additional code */
|
||||
request_sense[13] = 0x00; /* Additional Sense Code Qualifier */
|
||||
#endif
|
||||
|
||||
return usbd_msc_send_to_host((uint8_t *)&sense_rsp, sizeof(sense_rsp));
|
||||
}
|
||||
|
||||
static bool scsi_inquiry_request(void)
|
||||
{
|
||||
if (!usbd_msc_datain_check()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_inquiry_resp_t inquiry_rsp = {
|
||||
.is_removable = 1, /* RMB = 1: Removable Medium */
|
||||
.version = 2,
|
||||
.response_data_format = 2,
|
||||
.additional_length = 31
|
||||
};
|
||||
// vendor_id, product_id, product_rev is space padded string
|
||||
memcpy(inquiry_rsp.vendor_id, "BL702USB", sizeof(inquiry_rsp.vendor_id));
|
||||
memcpy(inquiry_rsp.product_id, "FAT16 RAM DEMO ", sizeof(inquiry_rsp.product_id));
|
||||
memcpy(inquiry_rsp.product_rev, "1.0 ", sizeof(inquiry_rsp.product_rev));
|
||||
|
||||
/* Win host requests maximum number of bytes but as all we have is 4 bytes we have
|
||||
to tell host back that it is all we have, that's why we correct residue */
|
||||
if (usbd_msc_cfg.csw.DataResidue > sizeof(inquiry_rsp)) {
|
||||
usbd_msc_cfg.cbw.DataLength = sizeof(inquiry_rsp);
|
||||
usbd_msc_cfg.csw.DataResidue = sizeof(inquiry_rsp);
|
||||
}
|
||||
|
||||
return usbd_msc_send_to_host((uint8_t *)&inquiry_rsp, sizeof(inquiry_rsp));
|
||||
}
|
||||
|
||||
static bool scsi_mode_sense_6(void)
|
||||
{
|
||||
if (!usbd_msc_datain_check()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_mode_sense6_resp_t mode_resp = {
|
||||
.data_len = 3,
|
||||
.medium_type = 0,
|
||||
.write_protected = false,
|
||||
.reserved = 0,
|
||||
.block_descriptor_len = 0 // no block descriptor are included
|
||||
};
|
||||
|
||||
/* Win host requests maximum number of bytes but as all we have is 4 bytes we have
|
||||
to tell host back that it is all we have, that's why we correct residue */
|
||||
if (usbd_msc_cfg.csw.DataResidue > sizeof(mode_resp)) {
|
||||
usbd_msc_cfg.cbw.DataLength = sizeof(mode_resp);
|
||||
usbd_msc_cfg.csw.DataResidue = sizeof(mode_resp);
|
||||
}
|
||||
|
||||
return usbd_msc_send_to_host((uint8_t *)&mode_resp, sizeof(mode_resp));
|
||||
}
|
||||
|
||||
static bool scsi_start_stop_unit(void)
|
||||
{
|
||||
// if (!cbw.CB[3]) { /* If power condition modifier is 0 */
|
||||
// USBD_MSC_MediaReady = cbw.CB[4] & 0x01; /* Media ready = START bit value */
|
||||
// usbd_msc_start_stop(USBD_MSC_MediaReady);
|
||||
// cbw.bStatus = CSW_CMD_PASSED; /* Start Stop Unit -> pass */
|
||||
// USBD_MSC_SetCSW();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// cbw.bStatus = CSW_CMD_FAILED; /* Start Stop Unit -> fail */
|
||||
// usbd_msc_send_csw();
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
usbd_msc_send_csw();
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* USB Device MSC SCSI Media Removal Callback
|
||||
* Parameters: None
|
||||
* Return Value: None
|
||||
*/
|
||||
|
||||
static bool scsi_media_removal(void)
|
||||
{
|
||||
// if (USBD_MSC_CBW.CB[4] & 1) { /* If prevent */
|
||||
// USBD_MSC_CSW.bStatus = CSW_CMD_FAILED; /* Prevent media removal -> fail */
|
||||
// } else { /* If allow */
|
||||
// USBD_MSC_CSW.bStatus = CSW_CMD_PASSED; /* Allow media removal -> pass */
|
||||
// }
|
||||
|
||||
// USBD_MSC_SetCSW();
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
usbd_msc_send_csw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool scsi_read_format_capacity(void)
|
||||
{
|
||||
if (!usbd_msc_datain_check()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_read_format_capacity_resp_t read_fmt_capa = {
|
||||
.list_length = 8, /* Capacity List Length */
|
||||
.block_num = 0,
|
||||
.descriptor_type = 2, /* Descriptor Code: Formatted Media */
|
||||
.block_size_u16 = 0
|
||||
};
|
||||
/* Block Count */
|
||||
read_fmt_capa.block_num = BSWAP32(usbd_msc_cfg.scsi_blk_nbr);
|
||||
/* Block Length */
|
||||
read_fmt_capa.block_size_u16 = BSWAP16(usbd_msc_cfg.scsi_blk_size);
|
||||
|
||||
/* Win host requests maximum number of bytes but as all we have is 4 bytes we have
|
||||
to tell host back that it is all we have, that's why we correct residue */
|
||||
if (usbd_msc_cfg.csw.DataResidue > sizeof(read_fmt_capa)) {
|
||||
usbd_msc_cfg.cbw.DataLength = sizeof(read_fmt_capa);
|
||||
usbd_msc_cfg.csw.DataResidue = sizeof(read_fmt_capa);
|
||||
}
|
||||
|
||||
return usbd_msc_send_to_host((uint8_t *)&read_fmt_capa, sizeof(read_fmt_capa));
|
||||
}
|
||||
|
||||
static bool scsi_read_capacity(void)
|
||||
{
|
||||
if (!usbd_msc_datain_check()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_read_capacity10_resp_t read_capa10;
|
||||
/* Last Logical Block */
|
||||
read_capa10.last_lba = BSWAP32((usbd_msc_cfg.scsi_blk_nbr - 1));
|
||||
/* Block Length */
|
||||
read_capa10.block_size = BSWAP32(usbd_msc_cfg.scsi_blk_size);
|
||||
|
||||
/* Win host requests maximum number of bytes but as all we have is 4 bytes we have
|
||||
to tell host back that it is all we have, that's why we correct residue */
|
||||
if (usbd_msc_cfg.csw.DataResidue > sizeof(read_capa10)) {
|
||||
usbd_msc_cfg.cbw.DataLength = sizeof(read_capa10);
|
||||
usbd_msc_cfg.csw.DataResidue = sizeof(read_capa10);
|
||||
}
|
||||
|
||||
return usbd_msc_send_to_host((uint8_t *)&read_capa10, sizeof(read_capa10));
|
||||
}
|
||||
|
||||
static bool usbd_msc_read_write_process(void)
|
||||
{
|
||||
/* Logical Block Address of First Block */
|
||||
uint32_t lba;
|
||||
uint32_t len = 0;
|
||||
|
||||
if (!usbd_msc_cfg.cbw.DataLength) {
|
||||
USBD_LOG_WRN("Zero length in CBW\r\n");
|
||||
//SCSI_SenseCode(pdev, hmsc->cbw.bLUN, ILLEGAL_REQUEST, INVALID_CDB);
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
usbd_msc_send_csw();
|
||||
return false;
|
||||
}
|
||||
|
||||
lba = GET_BE32(&usbd_msc_cfg.cbw.CB[2]);
|
||||
|
||||
USBD_LOG_DBG("LBA (block) : 0x%x\r\n", lba);
|
||||
usbd_msc_cfg.scsi_blk_addr = lba * usbd_msc_cfg.scsi_blk_size;
|
||||
|
||||
/* Number of Blocks to transfer */
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
case SCSI_READ10:
|
||||
case SCSI_WRITE10:
|
||||
case SCSI_VERIFY10:
|
||||
len = GET_BE16(&usbd_msc_cfg.cbw.CB[7]);
|
||||
break;
|
||||
|
||||
case SCSI_READ12:
|
||||
case SCSI_WRITE12:
|
||||
len = GET_BE32(&usbd_msc_cfg.cbw.CB[6]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
USBD_LOG_DBG("len (block) : 0x%x\r\n", len);
|
||||
usbd_msc_cfg.scsi_blk_len = len * usbd_msc_cfg.scsi_blk_size;
|
||||
|
||||
if ((lba + len) > usbd_msc_cfg.scsi_blk_nbr) {
|
||||
USBD_LOG_ERR("LBA out of range\r\n");
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_FAILED;
|
||||
usbd_msc_send_csw();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usbd_msc_cfg.cbw.DataLength != usbd_msc_cfg.scsi_blk_len) {
|
||||
if ((usbd_msc_cfg.cbw.Flags & 0x80) != 0U) {
|
||||
USBD_LOG_WRN("read write process error\r\n");
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
} else {
|
||||
USBD_LOG_WRN("read write process error\r\n");
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
}
|
||||
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_FAILED;
|
||||
usbd_msc_send_csw();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool scsi_mode_sense_10(void)
|
||||
{
|
||||
if (!usbd_msc_datain_check()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_mode_10_resp_t mode10_resp = {
|
||||
.mode_data_length_low = 0x06,
|
||||
.write_protect = 1,
|
||||
};
|
||||
|
||||
/* Win host requests maximum number of bytes but as all we have is 4 bytes we have
|
||||
to tell host back that it is all we have, that's why we correct residue */
|
||||
if (usbd_msc_cfg.csw.DataResidue > sizeof(mode10_resp)) {
|
||||
usbd_msc_cfg.cbw.DataLength = sizeof(mode10_resp);
|
||||
usbd_msc_cfg.csw.DataResidue = sizeof(mode10_resp);
|
||||
}
|
||||
|
||||
return usbd_msc_send_to_host((uint8_t *)&mode10_resp, sizeof(mode10_resp));
|
||||
}
|
||||
|
||||
static void usbd_msc_cbw_decode(uint8_t *buf, uint16_t size)
|
||||
{
|
||||
if (size != sizeof(usbd_msc_cfg.cbw)) {
|
||||
USBD_LOG_ERR("size != sizeof(cbw)");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy((uint8_t *)&usbd_msc_cfg.cbw, buf, size);
|
||||
|
||||
if (usbd_msc_cfg.cbw.Signature != MSC_CBW_Signature) {
|
||||
USBD_LOG_ERR("CBW Signature Mismatch");
|
||||
return;
|
||||
}
|
||||
|
||||
usbd_msc_cfg.csw.Tag = usbd_msc_cfg.cbw.Tag;
|
||||
usbd_msc_cfg.csw.DataResidue = usbd_msc_cfg.cbw.DataLength;
|
||||
|
||||
if ((usbd_msc_cfg.cbw.CBLength < 1) || (usbd_msc_cfg.cbw.CBLength > 16) || (usbd_msc_cfg.cbw.LUN != 0U)) {
|
||||
USBD_LOG_WRN("cbw.CBLength %d", usbd_msc_cfg.cbw.CBLength);
|
||||
/* Stall data stage */
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_FAILED;
|
||||
usbd_msc_send_csw();
|
||||
} else {
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
case SCSI_TEST_UNIT_READY:
|
||||
USBD_LOG_DBG(">> TUR");
|
||||
scsi_test_unit_ready();
|
||||
break;
|
||||
|
||||
case SCSI_REQUEST_SENSE:
|
||||
USBD_LOG_DBG(">> REQ_SENSE");
|
||||
scsi_request_sense();
|
||||
break;
|
||||
|
||||
case SCSI_INQUIRY:
|
||||
USBD_LOG_DBG(">> INQ");
|
||||
scsi_inquiry_request();
|
||||
break;
|
||||
|
||||
case SCSI_START_STOP_UNIT:
|
||||
scsi_start_stop_unit();
|
||||
break;
|
||||
|
||||
case SCSI_MEDIA_REMOVAL:
|
||||
scsi_media_removal();
|
||||
break;
|
||||
|
||||
case SCSI_MODE_SENSE6:
|
||||
USBD_LOG_DBG(">> MODE_SENSE6");
|
||||
scsi_mode_sense_6();
|
||||
break;
|
||||
|
||||
case SCSI_MODE_SENSE10:
|
||||
USBD_LOG_DBG(">> MODE_SENSE10");
|
||||
scsi_mode_sense_10();
|
||||
break;
|
||||
|
||||
case SCSI_READ_FORMAT_CAPACITIES:
|
||||
USBD_LOG_DBG(">> READ_FORMAT_CAPACITY");
|
||||
scsi_read_format_capacity();
|
||||
break;
|
||||
|
||||
case SCSI_READ_CAPACITY:
|
||||
USBD_LOG_DBG(">> READ_CAPACITY");
|
||||
scsi_read_capacity();
|
||||
break;
|
||||
|
||||
case SCSI_READ10:
|
||||
case SCSI_READ12:
|
||||
USBD_LOG_DBG(">> READ");
|
||||
|
||||
if (usbd_msc_read_write_process()) {
|
||||
if ((usbd_msc_cfg.cbw.Flags & 0x80)) {
|
||||
usbd_msc_cfg.stage = MSC_BS_DATA_IN;
|
||||
usbd_msc_memory_read();
|
||||
} else {
|
||||
usbd_ep_set_stall(
|
||||
mass_ep_data[MSD_OUT_EP_IDX].ep_addr);
|
||||
USBD_LOG_WRN("Stall OUT endpoint");
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
usbd_msc_send_csw();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCSI_WRITE10:
|
||||
case SCSI_WRITE12:
|
||||
USBD_LOG_DBG(">> WRITE");
|
||||
|
||||
if (usbd_msc_read_write_process()) {
|
||||
if (!(usbd_msc_cfg.cbw.Flags & 0x80)) {
|
||||
usbd_msc_cfg.stage = MSC_BS_DATA_OUT;
|
||||
} else {
|
||||
usbd_ep_set_stall(
|
||||
mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
USBD_LOG_WRN("Stall IN endpoint");
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
usbd_msc_send_csw();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCSI_VERIFY10:
|
||||
USBD_LOG_DBG(">> VERIFY10");
|
||||
|
||||
if (!(usbd_msc_cfg.cbw.CB[1] & 0x02)) {
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_CMD_PASSED;
|
||||
usbd_msc_send_csw();
|
||||
break;
|
||||
}
|
||||
|
||||
if (usbd_msc_read_write_process()) {
|
||||
if (!(usbd_msc_cfg.cbw.Flags & 0x80)) {
|
||||
usbd_msc_cfg.stage = MSC_BS_DATA_OUT;
|
||||
memOK = true;
|
||||
} else {
|
||||
usbd_ep_set_stall(
|
||||
mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
USBD_LOG_WRN("Stall IN endpoint");
|
||||
usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
usbd_msc_send_csw();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_LOG_WRN(">> default CB[0] %x", usbd_msc_cfg.cbw.CB[0]);
|
||||
/* Stall data stage */
|
||||
usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
usbd_msc_cfg.stage = MSC_BS_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mass_storage_bulk_out(uint8_t ep)
|
||||
{
|
||||
uint32_t bytes_read = 0U;
|
||||
uint8_t bo_buf[MASS_STORAGE_BULK_EP_MPS];
|
||||
|
||||
usbd_ep_read(ep, bo_buf, MASS_STORAGE_BULK_EP_MPS,
|
||||
&bytes_read);
|
||||
|
||||
switch (usbd_msc_cfg.stage) {
|
||||
/*the device has to decode the CBW received*/
|
||||
case MSC_BS_CBW:
|
||||
USBD_LOG_DBG("> BO - MSC_BS_CBW\r\n");
|
||||
usbd_msc_cbw_decode(bo_buf, bytes_read);
|
||||
break;
|
||||
|
||||
/*the device has to receive data from the host*/
|
||||
case MSC_BS_DATA_OUT:
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
case SCSI_WRITE10:
|
||||
case SCSI_WRITE12:
|
||||
/* USBD_LOG_DBG("> BO - PROC_CBW WR");*/
|
||||
usbd_msc_memory_write(bo_buf, bytes_read);
|
||||
break;
|
||||
|
||||
case SCSI_VERIFY10:
|
||||
USBD_LOG_DBG("> BO - PROC_CBW VER\r\n");
|
||||
usbd_msc_memory_verify(bo_buf, bytes_read);
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_LOG_ERR("> BO - PROC_CBW default <<ERROR!!!>>\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MSC_BS_CSW:
|
||||
break;
|
||||
|
||||
/*an error has occurred: stall endpoint and send CSW*/
|
||||
default:
|
||||
USBD_LOG_WRN("Stall OUT endpoint, stage: %d\r\n", usbd_msc_cfg.stage);
|
||||
// usbd_ep_set_stall(ep);
|
||||
// usbd_msc_cfg.csw.Status = CSW_STATUS_PHASE_ERROR;
|
||||
// usbd_msc_send_csw();
|
||||
break;
|
||||
}
|
||||
|
||||
/*set ep ack to recv next data*/
|
||||
usbd_ep_read(ep, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EP Bulk IN handler, used to send data to the Host
|
||||
*
|
||||
* @param ep Endpoint address.
|
||||
* @param ep_status Endpoint status code.
|
||||
*
|
||||
* @return N/A.
|
||||
*/
|
||||
static void mass_storage_bulk_in(uint8_t ep)
|
||||
{
|
||||
USBD_LOG_DBG("I:%d\r\n", usbd_msc_cfg.stage);
|
||||
|
||||
switch (usbd_msc_cfg.stage) {
|
||||
/*the device has to send data to the host*/
|
||||
case MSC_BS_DATA_IN:
|
||||
switch (usbd_msc_cfg.cbw.CB[0]) {
|
||||
case SCSI_READ10:
|
||||
case SCSI_READ12:
|
||||
/* USBD_LOG_DBG("< BI - PROC_CBW READ"); */
|
||||
usbd_msc_memory_read();
|
||||
break;
|
||||
|
||||
default:
|
||||
USBD_LOG_ERR("< BI-PROC_CBW default <<ERROR!!>>\r\n");
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/*the device has to send a CSW*/
|
||||
case MSC_BS_DATA_IN_LAST:
|
||||
USBD_LOG_DBG("< BI - MSC_BS_DATA_IN_LAST\r\n");
|
||||
usbd_msc_send_csw();
|
||||
break;
|
||||
|
||||
case MSC_BS_DATA_IN_LAST_STALL:
|
||||
USBD_LOG_WRN("Stall IN endpoint, stage: %d\r\n", usbd_msc_cfg.stage);
|
||||
//usbd_ep_set_stall(mass_ep_data[MSD_IN_EP_IDX].ep_addr);
|
||||
usbd_msc_send_csw();
|
||||
break;
|
||||
|
||||
/*the host has received the CSW -> we wait a CBW*/
|
||||
case MSC_BS_CSW:
|
||||
USBD_LOG_DBG("< BI - MSC_BS_CSW\r\n");
|
||||
usbd_msc_cfg.stage = MSC_BS_CBW;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void msc_storage_notify_handler(uint8_t event, void *arg)
|
||||
{
|
||||
switch (event) {
|
||||
case USB_EVENT_RESET:
|
||||
usbd_msc_reset();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static usbd_class_t msc_class;
|
||||
|
||||
static usbd_interface_t msc_intf = {
|
||||
.class_handler = msc_storage_class_request_handler,
|
||||
.vendor_handler = NULL,
|
||||
.notify_handler = msc_storage_notify_handler,
|
||||
};
|
||||
|
||||
void usbd_msc_class_init(uint8_t out_ep, uint8_t in_ep)
|
||||
{
|
||||
msc_class.name = "usbd_msc";
|
||||
|
||||
usbd_class_register(&msc_class);
|
||||
usbd_class_add_interface(&msc_class, &msc_intf);
|
||||
|
||||
mass_ep_data[0].ep_addr = out_ep;
|
||||
mass_ep_data[0].ep_cb = mass_storage_bulk_out;
|
||||
mass_ep_data[1].ep_addr = in_ep;
|
||||
mass_ep_data[1].ep_cb = mass_storage_bulk_in;
|
||||
|
||||
usbd_interface_add_endpoint(&msc_intf, &mass_ep_data[0]);
|
||||
usbd_interface_add_endpoint(&msc_intf, &mass_ep_data[1]);
|
||||
}
|
||||
101
class/msc/usbd_msc.h
Normal file
101
class/msc/usbd_msc.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief USB Mass Storage Class public header
|
||||
*
|
||||
* Header follows the Mass Storage Class Specification
|
||||
* (Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf) and
|
||||
* Mass Storage Class Bulk-Only Transport Specification
|
||||
* (usbmassbulk_10.pdf).
|
||||
* Header is limited to Bulk-Only Transfer protocol.
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
/* MSC Protocol Codes */
|
||||
#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
|
||||
|
||||
/** MSC Command Block Wrapper (CBW) Signature */
|
||||
#define MSC_CBW_Signature 0x43425355
|
||||
/** Bulk-only Command Status Wrapper (CSW) Signature */
|
||||
#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
|
||||
|
||||
/** 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];
|
||||
} __packed;
|
||||
|
||||
/** MSC Bulk-Only Command Status Wrapper (CSW) */
|
||||
struct CSW {
|
||||
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 */
|
||||
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USB_MSC_H_ */
|
||||
302
class/msc/usbd_scsi.h
Normal file
302
class/msc/usbd_scsi.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief USB Mass Storage Class SCSI public header
|
||||
*
|
||||
* Header follows the Mass Storage Class Specification
|
||||
* (Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf) and
|
||||
* Mass Storage Class Bulk-Only Transport Specification
|
||||
* (usbmassbulk_10.pdf).
|
||||
* Header is limited to Bulk-Only Transfer protocol.
|
||||
*/
|
||||
|
||||
#ifndef _USBD_SCSI_H_
|
||||
#define _USBD_SCSI_H_
|
||||
|
||||
/* SCSI Commands */
|
||||
#define SCSI_TEST_UNIT_READY 0x00
|
||||
#define SCSI_REQUEST_SENSE 0x03
|
||||
#define SCSI_FORMAT_UNIT 0x04
|
||||
#define SCSI_INQUIRY 0x12
|
||||
#define SCSI_MODE_SELECT6 0x15
|
||||
#define SCSI_MODE_SENSE6 0x1A
|
||||
#define SCSI_START_STOP_UNIT 0x1B
|
||||
#define SCSI_SEND_DIAGNOSTIC 0x1D
|
||||
#define SCSI_MEDIA_REMOVAL 0x1E
|
||||
#define SCSI_READ_FORMAT_CAPACITIES 0x23
|
||||
#define SCSI_READ_CAPACITY 0x25
|
||||
#define SCSI_READ10 0x28
|
||||
#define SCSI_WRITE10 0x2A
|
||||
#define SCSI_VERIFY10 0x2F
|
||||
#define SCSI_SYNC_CACHE10 0x35
|
||||
#define SCSI_READ12 0xA8
|
||||
#define SCSI_WRITE12 0xAA
|
||||
#define SCSI_MODE_SELECT10 0x55
|
||||
#define SCSI_MODE_SENSE10 0x5A
|
||||
#define SCSI_ATA_COMMAND_PASS_THROUGH16 0x85
|
||||
#define SCSI_READ16 0x88
|
||||
#define SCSI_WRITE16 0x8A
|
||||
#define SCSI_VERIFY16 0x8F
|
||||
#define SCSI_SYNC_CACHE16 0x91
|
||||
#define SCSI_SERVICE_ACTION_IN16 0x9E
|
||||
#define SCSI_READ_CAPACITY16 0x9E
|
||||
#define SCSI_SERVICE_ACTION_OUT16 0x9F
|
||||
#define SCSI_ATA_COMMAND_PASS_THROUGH12 0xA1
|
||||
#define SCSI_REPORT_ID_INFO 0xA3
|
||||
#define SCSI_READ12 0xA8
|
||||
#define SCSI_SERVICE_ACTION_OUT12 0xA9
|
||||
#define SCSI_SERVICE_ACTION_IN12 0xAB
|
||||
#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
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// 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;
|
||||
} 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;
|
||||
} 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;
|
||||
|
||||
uint8_t : 7;
|
||||
uint8_t is_removable : 1;
|
||||
|
||||
uint8_t version;
|
||||
|
||||
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 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 : 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.
|
||||
} 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;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
||||
} scsi_sense_fixed_resp_t;
|
||||
|
||||
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 page_code : 6;
|
||||
uint8_t page_control : 2;
|
||||
|
||||
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;
|
||||
|
||||
uint8_t reserved : 7;
|
||||
bool write_protected : 1;
|
||||
|
||||
uint8_t block_descriptor_len;
|
||||
} scsi_mode_sense6_resp_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
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 page_code : 6;
|
||||
uint8_t page_control : 2;
|
||||
|
||||
uint8_t subpage_code;
|
||||
|
||||
uint8_t reserved3;
|
||||
uint8_t reserved4;
|
||||
uint8_t reserved5;
|
||||
|
||||
uint8_t length[2];
|
||||
|
||||
uint8_t control;
|
||||
} scsi_mode_sense_10_cmd_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
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 long_LBA : 1;
|
||||
uint8_t reserved3 : 7;
|
||||
|
||||
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;
|
||||
} scsi_prevent_allow_medium_removal_t;
|
||||
|
||||
typedef struct __packed {
|
||||
uint8_t cmd_code;
|
||||
|
||||
uint8_t immded : 1;
|
||||
uint8_t : 7;
|
||||
|
||||
uint8_t TU_RESERVED;
|
||||
|
||||
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 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;
|
||||
} 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.
|
||||
|
||||
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;
|
||||
|
||||
} scsi_read_format_capacity_resp_t;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// SCSI Block Command (SBC-3)
|
||||
// NOTE: All data in SCSI command are in Big Endian
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
/// 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;
|
||||
} 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
|
||||
} 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;
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_USB_CLASS_USB_CDC_H_ */
|
||||
134
class/video/usbd_video.c
Normal file
134
class/video/usbd_video.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* @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"
|
||||
|
||||
extern struct video_probe_and_commit_controls probe;
|
||||
extern struct video_probe_and_commit_controls commit;
|
||||
|
||||
int video_class_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
USBD_LOG_DBG("Class request:"
|
||||
"bRequest 0x%02x, bmRequestType 0x%02x len %d",
|
||||
setup->bRequest, setup->bmRequestType, *len);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIDEO_REQUEST_GET_CUR:
|
||||
if (setup->wValue == 256) {
|
||||
*data = (uint8_t *)&probe;
|
||||
} else if (setup->wValue == 512) {
|
||||
*data = (uint8_t *)&commit;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIDEO_REQUEST_GET_MIN:
|
||||
if (setup->wValue == 256) {
|
||||
*data = (uint8_t *)&probe;
|
||||
} else if (setup->wValue == 512) {
|
||||
*data = (uint8_t *)&commit;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case VIDEO_REQUEST_GET_MAX:
|
||||
if (setup->wValue == 256) {
|
||||
*data = (uint8_t *)&probe;
|
||||
} 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) {
|
||||
*data = (uint8_t *)&probe;
|
||||
} 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)
|
||||
{
|
||||
switch (event) {
|
||||
case USB_EVENT_RESET:
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_video_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 = video_class_request_handler;
|
||||
intf->custom_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = video_notify_handler;
|
||||
usbd_class_add_interface(class, intf);
|
||||
}
|
||||
821
class/video/usbd_video.h
Normal file
821
class/video/usbd_video.h
Normal file
@@ -0,0 +1,821 @@
|
||||
/**
|
||||
* @file
|
||||
* @brief USB Video Device Class public header
|
||||
*
|
||||
* Header follows below documentation:
|
||||
* - USB Device Class Definition for Video Devices UVC 1.5 Class specification.pdf
|
||||
*/
|
||||
|
||||
#ifndef _USBD_VIDEO_H_
|
||||
#define _USBD_VIDEO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define USB_DEVICE_VIDEO_CLASS_VERSION_1_5 0
|
||||
|
||||
/*! @brief Video device subclass code */
|
||||
#define VIDEO_SC_UNDEFINED 0x00U
|
||||
#define VIDEO_SC_VIDEOCONTROL 0x01U
|
||||
#define VIDEO_SC_VIDEOSTREAMING 0x02U
|
||||
#define VIDEO_SC_VIDEO_INTERFACE_COLLECTION 0x03U
|
||||
|
||||
/*! @brief Video device protocol code */
|
||||
#define VIDEO_PC_PROTOCOL_UNDEFINED 0x00U
|
||||
#define VIDEO_PC_PROTOCOL_15 0x01U
|
||||
|
||||
/*! @brief Video device class-specific descriptor type */
|
||||
#define VIDEO_CS_UNDEFINED_DESCRIPTOR_TYPE 0x20U
|
||||
#define VIDEO_CS_DEVICE_DESCRIPTOR_TYPE 0x21U
|
||||
#define VIDEO_CS_CONFIGURATION_DESCRIPTOR_TYPE 0x22U
|
||||
#define VIDEO_CS_STRING_DESCRIPTOR_TYPE 0x23U
|
||||
#define VIDEO_CS_INTERFACE_DESCRIPTOR_TYPE 0x24U
|
||||
#define VIDEO_CS_ENDPOINT_DESCRIPTOR_TYPE 0x25U
|
||||
|
||||
/*! @brief Video device class-specific VC interface descriptor subtype */
|
||||
#define VIDEO_VC_DESCRIPTOR_UNDEFINED_DESCRIPTOR_SUBTYPE 0x00U
|
||||
#define VIDEO_VC_HEADER_DESCRIPTOR_SUBTYPE 0x01U
|
||||
#define VIDEO_VC_INPUT_TERMINAL_DESCRIPTOR_SUBTYPE 0x02U
|
||||
#define VIDEO_VC_OUTPUT_TERMINAL_DESCRIPTOR_SUBTYPE 0x03U
|
||||
#define VIDEO_VC_SELECTOR_UNIT_DESCRIPTOR_SUBTYPE 0x04U
|
||||
#define VIDEO_VC_PROCESSING_UNIT_DESCRIPTOR_SUBTYPE 0x05U
|
||||
#define VIDEO_VC_EXTENSION_UNIT_DESCRIPTOR_SUBTYPE 0x06U
|
||||
#define VIDEO_VC_ENCODING_UNIT_DESCRIPTOR_SUBTYPE 0x07U
|
||||
|
||||
/*! @brief Video device class-specific VS interface descriptor subtype */
|
||||
#define VIDEO_VS_UNDEFINED_DESCRIPTOR_SUBTYPE 0x00U
|
||||
#define VIDEO_VS_INPUT_HEADER_DESCRIPTOR_SUBTYPE 0x01U
|
||||
#define VIDEO_VS_OUTPUT_HEADER_DESCRIPTOR_SUBTYPE 0x02U
|
||||
#define VIDEO_VS_STILL_IMAGE_FRAME_DESCRIPTOR_SUBTYPE 0x03U
|
||||
#define VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_SUBTYPE 0x04U
|
||||
#define VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_SUBTYPE 0x05U
|
||||
#define VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_SUBTYPE 0x06U
|
||||
#define VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_SUBTYPE 0x07U
|
||||
#define VIDEO_VS_FORMAT_MPEG2TS_DESCRIPTOR_SUBTYPE 0x0AU
|
||||
#define VIDEO_VS_FORMAT_DV_DESCRIPTOR_SUBTYPE 0x0CU
|
||||
#define VIDEO_VS_COLORFORMAT_DESCRIPTOR_SUBTYPE 0x0DU
|
||||
#define VIDEO_VS_FORMAT_FRAME_BASED_DESCRIPTOR_SUBTYPE 0x10U
|
||||
#define VIDEO_VS_FRAME_FRAME_BASED_DESCRIPTOR_SUBTYPE 0x11U
|
||||
#define VIDEO_VS_FORMAT_STREAM_BASED_DESCRIPTOR_SUBTYPE 0x12U
|
||||
#define VIDEO_VS_FORMAT_H264_DESCRIPTOR_SUBTYPE 0x13U
|
||||
#define VIDEO_VS_FRAME_H264_DESCRIPTOR_SUBTYPE 0x14U
|
||||
#define VIDEO_VS_FORMAT_H264_SIMULCAST_DESCRIPTOR_SUBTYPE 0x15U
|
||||
#define VIDEO_VS_FORMAT_VP8_DESCRIPTOR_SUBTYPE 0x16U
|
||||
#define VIDEO_VS_FRAME_VP8_DESCRIPTOR_SUBTYPE 0x17U
|
||||
#define VIDEO_VS_FORMAT_VP8_SIMULCAST_DESCRIPTOR_SUBTYPE 0x18U
|
||||
|
||||
/*! @brief Video device class-specific VC endpoint descriptor subtype */
|
||||
#define VIDEO_EP_UNDEFINED_DESCRIPTOR_SUBTYPE 0x00U
|
||||
#define VIDEO_EP_GENERAL_DESCRIPTOR_SUBTYPE 0x01U
|
||||
#define VIDEO_EP_ENDPOINT_DESCRIPTOR_SUBTYPE 0x02U
|
||||
#define VIDEO_EP_INTERRUPT_DESCRIPTOR_SUBTYPE 0x03U
|
||||
|
||||
/*! @brief Video device class-specific request code */
|
||||
#define VIDEO_REQUEST_UNDEFINED 0x00U
|
||||
#define VIDEO_REQUEST_SET_CUR 0x01U
|
||||
#define VIDEO_REQUEST_SET_CUR_ALL 0x11U
|
||||
#define VIDEO_REQUEST_GET_CUR 0x81U
|
||||
#define VIDEO_REQUEST_GET_MIN 0x82U
|
||||
#define VIDEO_REQUEST_GET_MAX 0x83U
|
||||
#define VIDEO_REQUEST_GET_RES 0x84U
|
||||
#define VIDEO_REQUEST_GET_LEN 0x85U
|
||||
#define VIDEO_REQUEST_GET_INFO 0x86U
|
||||
#define VIDEO_REQUEST_GET_DEF 0x87U
|
||||
#define VIDEO_REQUEST_GET_CUR_ALL 0x91U
|
||||
#define VIDEO_REQUEST_GET_MIN_ALL 0x92U
|
||||
#define VIDEO_REQUEST_GET_MAX_ALL 0x93U
|
||||
#define VIDEO_REQUEST_GET_RES_ALL 0x94U
|
||||
#define VIDEO_REQUEST_GET_DEF_ALL 0x97U
|
||||
|
||||
/*! @brief Video device class-specific VideoControl interface control selector */
|
||||
#define VIDEO_VC_CONTROL_UNDEFINED 0x00U
|
||||
#define VIDEO_VC_VIDEO_POWER_MODE_CONTROL 0x01U
|
||||
#define VIDEO_VC_REQUEST_ERROR_CODE_CONTROL 0x02U
|
||||
|
||||
/*! @brief Video device class-specific Terminal control selector */
|
||||
#define VIDEO_TE_CONTROL_UNDEFINED 0x00U
|
||||
|
||||
/*! @brief Video device class-specific Selector Unit control selector */
|
||||
#define VIDEO_SU_CONTROL_UNDEFINED 0x00U
|
||||
#define VIDEO_SU_INPUT_SELECT_CONTROL 0x01U
|
||||
|
||||
/*! @brief Video device class-specific Camera Terminal control selector */
|
||||
#define VIDEO_CT_CONTROL_UNDEFINED 0x00U
|
||||
#define VIDEO_CT_SCANNING_MODE_CONTROL 0x01U
|
||||
#define VIDEO_CT_AE_MODE_CONTROL 0x02U
|
||||
#define VIDEO_CT_AE_PRIORITY_CONTROL 0x03U
|
||||
#define VIDEO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04U
|
||||
#define VIDEO_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05U
|
||||
#define VIDEO_CT_FOCUS_ABSOLUTE_CONTROL 0x06U
|
||||
#define VIDEO_CT_FOCUS_RELATIVE_CONTROL 0x07U
|
||||
#define VIDEO_CT_FOCUS_AUTO_CONTROL 0x08U
|
||||
#define VIDEO_CT_IRIS_ABSOLUTE_CONTROL 0x09U
|
||||
#define VIDEO_CT_IRIS_RELATIVE_CONTROL 0x0AU
|
||||
#define VIDEO_CT_ZOOM_ABSOLUTE_CONTROL 0x0BU
|
||||
#define VIDEO_CT_ZOOM_RELATIVE_CONTROL 0x0CU
|
||||
#define VIDEO_CT_PANTILT_ABSOLUTE_CONTROL 0x0DU
|
||||
#define VIDEO_CT_PANTILT_RELATIVE_CONTROL 0x0EU
|
||||
#define VIDEO_CT_ROLL_ABSOLUTE_CONTROL 0x0FU
|
||||
#define VIDEO_CT_ROLL_RELATIVE_CONTROL 0x10U
|
||||
#define VIDEO_CT_PRIVACY_CONTROL 0x11U
|
||||
#define VIDEO_CT_FOCUS_SIMPLE_CONTROL 0x12U
|
||||
#define VIDEO_CT_WINDOW_CONTROL 0x13U
|
||||
#define VIDEO_CT_REGION_OF_INTEREST_CONTROL 0x14U
|
||||
|
||||
/*! @brief Video device class-specific Processing Unit control selector */
|
||||
#define VIDEO_PU_CONTROL_UNDEFINED 0x00U
|
||||
#define VIDEO_PU_BACKLIGHT_COMPENSATION_CONTROL 0x01U
|
||||
#define VIDEO_PU_BRIGHTNESS_CONTROL 0x02U
|
||||
#define VIDEO_PU_CONTRAST_CONTROL 0x03U
|
||||
#define VIDEO_PU_GAIN_CONTROL 0x04U
|
||||
#define VIDEO_PU_POWER_LINE_FREQUENCY_CONTROL 0x05U
|
||||
#define VIDEO_PU_HUE_CONTROL 0x06U
|
||||
#define VIDEO_PU_SATURATION_CONTROL 0x07U
|
||||
#define VIDEO_PU_SHARPNESS_CONTROL 0x08U
|
||||
#define VIDEO_PU_GAMMA_CONTROL 0x09U
|
||||
#define VIDEO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0AU
|
||||
#define VIDEO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0BU
|
||||
#define VIDEO_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0CU
|
||||
#define VIDEO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0DU
|
||||
#define VIDEO_PU_DIGITAL_MULTIPLIER_CONTROL 0x0EU
|
||||
#define VIDEO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0FU
|
||||
#define VIDEO_PU_HUE_AUTO_CONTROL 0x10U
|
||||
#define VIDEO_PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11U
|
||||
#define VIDEO_PU_ANALOG_LOCK_STATUS_CONTROL 0x12U
|
||||
#define VIDEO_PU_CONTRAST_AUTO_CONTROL 0x13U
|
||||
|
||||
/*! @brief Video device class-specific Encoding Unit control selector */
|
||||
#define VIDEO_EU_CONTROL_UNDEFINED 0x00U
|
||||
#define VIDEO_EU_SELECT_LAYER_CONTROL 0x01U
|
||||
#define VIDEO_EU_PROFILE_TOOLSET_CONTROL 0x02U
|
||||
#define VIDEO_EU_VIDEO_RESOLUTION_CONTROL 0x03U
|
||||
#define VIDEO_EU_MIN_FRAME_INTERVAL_CONTROL 0x04U
|
||||
#define VIDEO_EU_SLICE_MODE_CONTROL 0x05U
|
||||
#define VIDEO_EU_RATE_CONTROL_MODE_CONTROL 0x06U
|
||||
#define VIDEO_EU_AVERAGE_BITRATE_CONTROL 0x07U
|
||||
#define VIDEO_EU_CPB_SIZE_CONTROL 0x08U
|
||||
#define VIDEO_EU_PEAK_BIT_RATE_CONTROL 0x09U
|
||||
#define VIDEO_EU_QUANTIZATION_PARAMS_CONTROL 0x0AU
|
||||
#define VIDEO_EU_SYNC_REF_FRAME_CONTROL 0x0BU
|
||||
#define VIDEO_EU_LTR_BUFFER_ CONTROL0x0CU
|
||||
#define VIDEO_EU_LTR_PICTURE_CONTROL 0x0DU
|
||||
#define VIDEO_EU_LTR_VALIDATION_CONTROL 0x0EU
|
||||
#define VIDEO_EU_LEVEL_IDC_LIMIT_CONTROL 0x0FU
|
||||
#define VIDEO_EU_SEI_PAYLOADTYPE_CONTROL 0x10U
|
||||
#define VIDEO_EU_QP_RANGE_CONTROL 0x11U
|
||||
#define VIDEO_EU_PRIORITY_CONTROL 0x12U
|
||||
#define VIDEO_EU_START_OR_STOP_LAYER_CONTROL 0x13U
|
||||
#define VIDEO_EU_ERROR_RESILIENCY_CONTROL 0x14U
|
||||
|
||||
/*! @brief Video device class-specific Extension Unit control selector */
|
||||
#define VIDEO_XU_CONTROL_UNDEFINED 0x00U
|
||||
|
||||
/*! @brief Video device class-specific VideoStreaming Interface control selector */
|
||||
#define VIDEO_VS_CONTROL_UNDEFINED 0x00U
|
||||
#define VIDEO_VS_PROBE_CONTROL 0x01U
|
||||
#define VIDEO_VS_COMMIT_CONTROL 0x02U
|
||||
#define VIDEO_VS_STILL_PROBE_CONTROL 0x03U
|
||||
#define VIDEO_VS_STILL_COMMIT_CONTROL 0x04U
|
||||
#define VIDEO_VS_STILL_IMAGE_TRIGGER_CONTROL 0x05U
|
||||
#define VIDEO_VS_STREAM_ERROR_CODE_CONTROL 0x06U
|
||||
#define VIDEO_VS_GENERATE_KEY_FRAME_CONTROL 0x07U
|
||||
#define VIDEO_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08U
|
||||
#define VIDEO_VS_SYNCH_DELAY_CONTROL 0x09U
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name USB Video class terminal types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @brief Video device USB terminal type */
|
||||
#define VIDEO_TT_VENDOR_SPECIFIC 0x0100U
|
||||
#define VIDEO_TT_STREAMING 0x0101U
|
||||
|
||||
/*! @brief Video device input terminal type */
|
||||
#define VIDEO_ITT_VENDOR_SPECIFIC 0x0200U
|
||||
#define VIDEO_ITT_CAMERA 0x0201U
|
||||
#define VIDEO_ITT_MEDIA_TRANSPORT_INPUT 0x0202U
|
||||
|
||||
/*! @brief Video device output terminal type */
|
||||
#define VIDEO_OTT_VENDOR_SPECIFIC 0x0300U
|
||||
#define VIDEO_OTT_DISPLAY 0x0301U
|
||||
#define VIDEO_OTT_MEDIA_TRANSPORT_OUTPUT 0x0302U
|
||||
|
||||
/*! @brief Video device external terminal type */
|
||||
#define VIDEO_ET_VENDOR_SPECIFIC 0x0400U
|
||||
#define VIDEO_ET_COMPOSITE_CONNECTOR 0x0401U
|
||||
#define VIDEO_ET_SVIDEO_CONNECTOR 0x0402U
|
||||
#define VIDEO_ET_COMPONENT_CONNECTOR 0x0403U
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*!
|
||||
* @name USB Video class setup request types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @brief Video device class setup request set type */
|
||||
#define VIDEO_SET_REQUEST_INTERFACE 0x21U
|
||||
#define VIDEO_SET_REQUEST_ENDPOINT 0x22U
|
||||
|
||||
/*! @brief Video device class setup request get type */
|
||||
#define VIDEO_GET_REQUEST_INTERFACE 0xA1U
|
||||
#define VIDEO_GET_REQUEST_ENDPOINT 0xA2U
|
||||
|
||||
/*! @}*/
|
||||
|
||||
/*! @brief Video device still image trigger control */
|
||||
#define VIDEO_STILL_IMAGE_TRIGGER_NORMAL_OPERATION 0x00U
|
||||
#define VIDEO_STILL_IMAGE_TRIGGER_TRANSMIT_STILL_IMAGE 0x01U
|
||||
#define VIDEO_STILL_IMAGE_TRIGGER_TRANSMIT_STILL_IMAGE_VS_DEDICATED_BULK_PIPE 0x02U
|
||||
#define VIDEO_STILL_IMAGE_TRIGGER_ABORT_STILL_IMAGE_TRANSMISSION 0x03U
|
||||
|
||||
/*!
|
||||
* @name USB Video device class-specific request commands
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*! @brief Video device class-specific request GET CUR COMMAND */
|
||||
#define VIDEO_GET_CUR_VC_POWER_MODE_CONTROL 0x8101U
|
||||
#define VIDEO_GET_CUR_VC_ERROR_CODE_CONTROL 0x8102U
|
||||
|
||||
#define VIDEO_GET_CUR_PU_BACKLIGHT_COMPENSATION_CONTROL 0x8121U
|
||||
#define VIDEO_GET_CUR_PU_BRIGHTNESS_CONTROL 0x8122U
|
||||
#define VIDEO_GET_CUR_PU_CONTRACT_CONTROL 0x8123U
|
||||
#define VIDEO_GET_CUR_PU_GAIN_CONTROL 0x8124U
|
||||
#define VIDEO_GET_CUR_PU_POWER_LINE_FREQUENCY_CONTROL 0x8125U
|
||||
#define VIDEO_GET_CUR_PU_HUE_CONTROL 0x8126U
|
||||
#define VIDEO_GET_CUR_PU_SATURATION_CONTROL 0x8127U
|
||||
#define VIDEO_GET_CUR_PU_SHARRNESS_CONTROL 0x8128U
|
||||
#define VIDEO_GET_CUR_PU_GAMMA_CONTROL 0x8129U
|
||||
#define VIDEO_GET_CUR_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x812AU
|
||||
#define VIDEO_GET_CUR_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x812BU
|
||||
#define VIDEO_GET_CUR_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x812CU
|
||||
#define VIDEO_GET_CUR_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x812DU
|
||||
#define VIDEO_GET_CUR_PU_DIGITAL_MULTIPLIER_CONTROL 0x812EU
|
||||
#define VIDEO_GET_CUR_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x812FU
|
||||
#define VIDEO_GET_CUR_PU_HUE_AUTO_CONTROL 0x8130U
|
||||
#define VIDEO_GET_CUR_PU_ANALOG_VIDEO_STANDARD_CONTROL 0x8131U
|
||||
#define VIDEO_GET_CUR_PU_ANALOG_LOCK_STATUS_CONTROL 0x8132U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_CUR_PU_CONTRAST_AUTO_CONTROL 0x8133U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_CUR_CT_SCANNING_MODE_CONTROL 0x8141U
|
||||
#define VIDEO_GET_CUR_CT_AE_MODE_CONTROL 0x8142U
|
||||
#define VIDEO_GET_CUR_CT_AE_PRIORITY_CONTROL 0x8143U
|
||||
#define VIDEO_GET_CUR_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x8144U
|
||||
#define VIDEO_GET_CUR_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x8145U
|
||||
#define VIDEO_GET_CUR_CT_FOCUS_ABSOLUTE_CONTROL 0x8146U
|
||||
#define VIDEO_GET_CUR_CT_FOCUS_RELATIVE_CONTROL 0x8147U
|
||||
#define VIDEO_GET_CUR_CT_FOCUS_AUTO_CONTROL 0x8148U
|
||||
#define VIDEO_GET_CUR_CT_IRIS_ABSOLUTE_CONTROL 0x8149U
|
||||
#define VIDEO_GET_CUR_CT_IRIS_RELATIVE_CONTROL 0x814AU
|
||||
#define VIDEO_GET_CUR_CT_ZOOM_ABSOLUTE_CONTROL 0x814BU
|
||||
#define VIDEO_GET_CUR_CT_ZOOM_RELATIVE_CONTROL 0x814CU
|
||||
#define VIDEO_GET_CUR_CT_PANTILT_ABSOLUTE_CONTROL 0x814DU
|
||||
#define VIDEO_GET_CUR_CT_PANTILT_RELATIVE_CONTROL 0x814EU
|
||||
#define VIDEO_GET_CUR_CT_ROLL_ABSOLUTE_CONTROL 0x814FU
|
||||
#define VIDEO_GET_CUR_CT_ROLL_RELATIVE_CONTROL 0x8150U
|
||||
#define VIDEO_GET_CUR_CT_PRIVACY_CONTROL 0x8151U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_CUR_CT_FOCUS_SIMPLE_CONTROL 0x8152U
|
||||
#define VIDEO_GET_CUR_CT_DIGITAL_WINDOW_CONTROL 0x8153U
|
||||
#define VIDEO_GET_CUR_CT_REGION_OF_INTEREST_CONTROL 0x8154U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_CUR_VS_PROBE_CONTROL 0x8161U
|
||||
#define VIDEO_GET_CUR_VS_COMMIT_CONTROL 0x8162U
|
||||
#define VIDEO_GET_CUR_VS_STILL_PROBE_CONTROL 0x8163U
|
||||
#define VIDEO_GET_CUR_VS_STILL_COMMIT_CONTROL 0x8164U
|
||||
#define VIDEO_GET_CUR_VS_STILL_IMAGE_TRIGGER_CONTROL 0x8165U
|
||||
#define VIDEO_GET_CUR_VS_STREAM_ERROR_CODE_CONTROL 0x8166U
|
||||
#define VIDEO_GET_CUR_VS_GENERATE_KEY_FRAME_CONTROL 0x8167U
|
||||
#define VIDEO_GET_CUR_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x8168U
|
||||
#define VIDEO_GET_CUR_VS_SYNCH_DELAY_CONTROL 0x8169U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_CUR_EU_SELECT_LAYER_CONTROL 0x8181U
|
||||
#define VIDEO_GET_CUR_EU_PROFILE_TOOLSET_CONTROL 0x8182U
|
||||
#define VIDEO_GET_CUR_EU_VIDEO_RESOLUTION_CONTROL 0x8183U
|
||||
#define VIDEO_GET_CUR_EU_MIN_FRAME_INTERVAL_CONTROL 0x8184U
|
||||
#define VIDEO_GET_CUR_EU_SLICE_MODE_CONTROL 0x8185U
|
||||
#define VIDEO_GET_CUR_EU_RATE_CONTROL_MODE_CONTROL 0x8186U
|
||||
#define VIDEO_GET_CUR_EU_AVERAGE_BITRATE_CONTROL 0x8187U
|
||||
#define VIDEO_GET_CUR_EU_CPB_SIZE_CONTROL 0x8188U
|
||||
#define VIDEO_GET_CUR_EU_PEAK_BIT_RATE_CONTROL 0x8189U
|
||||
#define VIDEO_GET_CUR_EU_QUANTIZATION_PARAMS_CONTROL 0x818AU
|
||||
#define VIDEO_GET_CUR_EU_SYNC_REF_FRAME_CONTROL 0x818BU
|
||||
#define VIDEO_GET_CUR_EU_LTR_BUFFER_CONTROL 0x818CU
|
||||
#define VIDEO_GET_CUR_EU_LTR_PICTURE_CONTROL 0x818DU
|
||||
#define VIDEO_GET_CUR_EU_LTR_VALIDATION_CONTROL 0x818EU
|
||||
#define VIDEO_GET_CUR_EU_LEVEL_IDC_LIMIT_CONTROL 0x818FU
|
||||
#define VIDEO_GET_CUR_EU_SEI_PAYLOADTYPE_CONTROL 0x8190U
|
||||
#define VIDEO_GET_CUR_EU_QP_RANGE_CONTROL 0x8191U
|
||||
#define VIDEO_GET_CUR_EU_PRIORITY_CONTROL 0x8192U
|
||||
#define VIDEO_GET_CUR_EU_START_OR_STOP_LAYER_CONTROL 0x8193U
|
||||
#define VIDEO_GET_CUR_EU_ERROR_RESILIENCY_CONTROL 0x8194U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request GET MIN COMMAND */
|
||||
#define VIDEO_GET_MIN_PU_BACKLIGHT_COMPENSATION_CONTROL 0x8221U
|
||||
#define VIDEO_GET_MIN_PU_BRIGHTNESS_CONTROL 0x8222U
|
||||
#define VIDEO_GET_MIN_PU_CONTRACT_CONTROL 0x8223U
|
||||
#define VIDEO_GET_MIN_PU_GAIN_CONTROL 0x8224U
|
||||
#define VIDEO_GET_MIN_PU_HUE_CONTROL 0x8226U
|
||||
#define VIDEO_GET_MIN_PU_SATURATION_CONTROL 0x8227U
|
||||
#define VIDEO_GET_MIN_PU_SHARRNESS_CONTROL 0x8228U
|
||||
#define VIDEO_GET_MIN_PU_GAMMA_CONTROL 0x8229U
|
||||
#define VIDEO_GET_MIN_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x822AU
|
||||
#define VIDEO_GET_MIN_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x822CU
|
||||
#define VIDEO_GET_MIN_PU_DIGITAL_MULTIPLIER_CONTROL 0x822EU
|
||||
#define VIDEO_GET_MIN_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x822FU
|
||||
|
||||
#define VIDEO_GET_MIN_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x8244U
|
||||
#define VIDEO_GET_MIN_CT_FOCUS_ABSOLUTE_CONTROL 0x8246U
|
||||
#define VIDEO_GET_MIN_CT_FOCUS_RELATIVE_CONTROL 0x8247U
|
||||
#define VIDEO_GET_MIN_CT_IRIS_ABSOLUTE_CONTROL 0x8249U
|
||||
#define VIDEO_GET_MIN_CT_ZOOM_ABSOLUTE_CONTROL 0x824BU
|
||||
#define VIDEO_GET_MIN_CT_ZOOM_RELATIVE_CONTROL 0x824CU
|
||||
#define VIDEO_GET_MIN_CT_PANTILT_ABSOLUTE_CONTROL 0x824DU
|
||||
#define VIDEO_GET_MIN_CT_PANTILT_RELATIVE_CONTROL 0x824EU
|
||||
#define VIDEO_GET_MIN_CT_ROLL_ABSOLUTE_CONTROL 0x824FU
|
||||
#define VIDEO_GET_MIN_CT_ROLL_RELATIVE_CONTROL 0x8250U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_MIN_CT_DIGITAL_WINDOW_CONTROL 0x8251U
|
||||
#define VIDEO_GET_MIN_CT_REGION_OF_INTEREST_CONTROL 0x8252U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_MIN_VS_PROBE_CONTROL 0x8261U
|
||||
#define VIDEO_GET_MIN_VS_STILL_PROBE_CONTROL 0x8263U
|
||||
#define VIDEO_GET_MIN_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x8268U
|
||||
#define VIDEO_GET_MIN_VS_SYNCH_DELAY_CONTROL 0x8269U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_MIN_EU_VIDEO_RESOLUTION_CONTROL 0x8283U
|
||||
#define VIDEO_GET_MIN_EU_MIN_FRAME_INTERVAL_CONTROL 0x8284U
|
||||
#define VIDEO_GET_MIN_EU_SLICE_MODE_CONTROL 0x8285U
|
||||
#define VIDEO_GET_MIN_EU_AVERAGE_BITRATE_CONTROL 0x8287U
|
||||
#define VIDEO_GET_MIN_EU_CPB_SIZE_CONTROL 0x8288U
|
||||
#define VIDEO_GET_MIN_EU_PEAK_BIT_RATE_CONTROL 0x8289U
|
||||
#define VIDEO_GET_MIN_EU_QUANTIZATION_PARAMS_CONTROL 0x828AU
|
||||
#define VIDEO_GET_MIN_EU_SYNC_REF_FRAME_CONTROL 0x828BU
|
||||
#define VIDEO_GET_MIN_EU_LEVEL_IDC_LIMIT_CONTROL 0x828FU
|
||||
#define VIDEO_GET_MIN_EU_SEI_PAYLOADTYPE_CONTROL 0x8290U
|
||||
#define VIDEO_GET_MIN_EU_QP_RANGE_CONTROL 0x8291U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request GET MAX COMMAND */
|
||||
#define VIDEO_GET_MAX_PU_BACKLIGHT_COMPENSATION_CONTROL 0x8321U
|
||||
#define VIDEO_GET_MAX_PU_BRIGHTNESS_CONTROL 0x8322U
|
||||
#define VIDEO_GET_MAX_PU_CONTRACT_CONTROL 0x8323U
|
||||
#define VIDEO_GET_MAX_PU_GAIN_CONTROL 0x8324U
|
||||
#define VIDEO_GET_MAX_PU_HUE_CONTROL 0x8326U
|
||||
#define VIDEO_GET_MAX_PU_SATURATION_CONTROL 0x8327U
|
||||
#define VIDEO_GET_MAX_PU_SHARRNESS_CONTROL 0x8328U
|
||||
#define VIDEO_GET_MAX_PU_GAMMA_CONTROL 0x8329U
|
||||
#define VIDEO_GET_MAX_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x832AU
|
||||
#define VIDEO_GET_MAX_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x832CU
|
||||
#define VIDEO_GET_MAX_PU_DIGITAL_MULTIPLIER_CONTROL 0x832EU
|
||||
#define VIDEO_GET_MAX_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x832FU
|
||||
|
||||
#define VIDEO_GET_MAX_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x8344U
|
||||
#define VIDEO_GET_MAX_CT_FOCUS_ABSOLUTE_CONTROL 0x8346U
|
||||
#define VIDEO_GET_MAX_CT_FOCUS_RELATIVE_CONTROL 0x8347U
|
||||
#define VIDEO_GET_MAX_CT_IRIS_ABSOLUTE_CONTROL 0x8349U
|
||||
#define VIDEO_GET_MAX_CT_ZOOM_ABSOLUTE_CONTROL 0x834BU
|
||||
#define VIDEO_GET_MAX_CT_ZOOM_RELATIVE_CONTROL 0x834CU
|
||||
#define VIDEO_GET_MAX_CT_PANTILT_ABSOLUTE_CONTROL 0x834DU
|
||||
#define VIDEO_GET_MAX_CT_PANTILT_RELATIVE_CONTROL 0x834EU
|
||||
#define VIDEO_GET_MAX_CT_ROLL_ABSOLUTE_CONTROL 0x834FU
|
||||
#define VIDEO_GET_MAX_CT_ROLL_RELATIVE_CONTROL 0x8350U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_MAX_CT_DIGITAL_WINDOW_CONTROL 0x8351U
|
||||
#define VIDEO_GET_MAX_CT_REGION_OF_INTEREST_CONTROL 0x8352U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_MAX_VS_PROBE_CONTROL 0x8361U
|
||||
#define VIDEO_GET_MAX_VS_STILL_PROBE_CONTROL 0x8363U
|
||||
#define VIDEO_GET_MAX_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x8368U
|
||||
#define VIDEO_GET_MAX_VS_SYNCH_DELAY_CONTROL 0x8369U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_MAX_EU_VIDEO_RESOLUTION_CONTROL 0x8383U
|
||||
#define VIDEO_GET_MAX_EU_MIN_FRAME_INTERVAL_CONTROL 0x8384U
|
||||
#define VIDEO_GET_MAX_EU_SLICE_MODE_CONTROL 0x8385U
|
||||
#define VIDEO_GET_MAX_EU_AVERAGE_BITRATE_CONTROL 0x8387U
|
||||
#define VIDEO_GET_MAX_EU_CPB_SIZE_CONTROL 0x8388U
|
||||
#define VIDEO_GET_MAX_EU_PEAK_BIT_RATE_CONTROL 0x8389U
|
||||
#define VIDEO_GET_MAX_EU_QUANTIZATION_PARAMS_CONTROL 0x838AU
|
||||
#define VIDEO_GET_MAX_EU_SYNC_REF_FRAME_CONTROL 0x838BU
|
||||
#define VIDEO_GET_MAX_EU_LTR_BUFFER_CONTROL 0x838CU
|
||||
#define VIDEO_GET_MAX_EU_LEVEL_IDC_LIMIT_CONTROL 0x838FU
|
||||
#define VIDEO_GET_MAX_EU_SEI_PAYLOADTYPE_CONTROL 0x8390U
|
||||
#define VIDEO_GET_MAX_EU_QP_RANGE_CONTROL 0x8391U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request GET RES COMMAND */
|
||||
#define VIDEO_GET_RES_PU_BACKLIGHT_COMPENSATION_CONTROL 0x8421U
|
||||
#define VIDEO_GET_RES_PU_BRIGHTNESS_CONTROL 0x8422U
|
||||
#define VIDEO_GET_RES_PU_CONTRACT_CONTROL 0x8423U
|
||||
#define VIDEO_GET_RES_PU_GAIN_CONTROL 0x8424U
|
||||
#define VIDEO_GET_RES_PU_HUE_CONTROL 0x8426U
|
||||
#define VIDEO_GET_RES_PU_SATURATION_CONTROL 0x8427U
|
||||
#define VIDEO_GET_RES_PU_SHARRNESS_CONTROL 0x8428U
|
||||
#define VIDEO_GET_RES_PU_GAMMA_CONTROL 0x8429U
|
||||
#define VIDEO_GET_RES_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x842AU
|
||||
#define VIDEO_GET_RES_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x842CU
|
||||
#define VIDEO_GET_RES_PU_DIGITAL_MULTIPLIER_CONTROL 0x842EU
|
||||
#define VIDEO_GET_RES_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x842FU
|
||||
|
||||
#define VIDEO_GET_RES_CT_AE_MODE_CONTROL 0x8442U
|
||||
#define VIDEO_GET_RES_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x8444U
|
||||
#define VIDEO_GET_RES_CT_FOCUS_ABSOLUTE_CONTROL 0x8446U
|
||||
#define VIDEO_GET_RES_CT_FOCUS_RELATIVE_CONTROL 0x8447U
|
||||
#define VIDEO_GET_RES_CT_IRIS_ABSOLUTE_CONTROL 0x8449U
|
||||
#define VIDEO_GET_RES_CT_ZOOM_ABSOLUTE_CONTROL 0x844BU
|
||||
#define VIDEO_GET_RES_CT_ZOOM_RELATIVE_CONTROL 0x844CU
|
||||
#define VIDEO_GET_RES_CT_PANTILT_ABSOLUTE_CONTROL 0x844DU
|
||||
#define VIDEO_GET_RES_CT_PANTILT_RELATIVE_CONTROL 0x844EU
|
||||
#define VIDEO_GET_RES_CT_ROLL_ABSOLUTE_CONTROL 0x844FU
|
||||
#define VIDEO_GET_RES_CT_ROLL_RELATIVE_CONTROL 0x8450U
|
||||
|
||||
#define VIDEO_GET_RES_VS_PROBE_CONTROL 0x8461U
|
||||
#define VIDEO_GET_RES_VS_STILL_PROBE_CONTROL 0x8463U
|
||||
#define VIDEO_GET_RES_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x8468U
|
||||
#define VIDEO_GET_RES_VS_SYNCH_DELAY_CONTROL 0x8469U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_RES_EU_AVERAGE_BITRATE_CONTROL 0x8487U
|
||||
#define VIDEO_GET_RES_EU_CPB_SIZE_CONTROL 0x8488U
|
||||
#define VIDEO_GET_RES_EU_PEAK_BIT_RATE_CONTROL 0x8489U
|
||||
#define VIDEO_GET_RES_EU_QUANTIZATION_PARAMS_CONTROL 0x848AU
|
||||
#define VIDEO_GET_RES_EU_ERROR_RESILIENCY_CONTROL 0x8494U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request GET LEN COMMAND */
|
||||
|
||||
#define VIDEO_GET_LEN_VS_PROBE_CONTROL 0x8561U
|
||||
#define VIDEO_GET_LEN_VS_COMMIT_CONTROL 0x8562U
|
||||
#define VIDEO_GET_LEN_VS_STILL_PROBE_CONTROL 0x8563U
|
||||
#define VIDEO_GET_LEN_VS_STILL_COMMIT_CONTROL 0x8564U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_LEN_EU_SELECT_LAYER_CONTROL 0x8581U
|
||||
#define VIDEO_GET_LEN_EU_PROFILE_TOOLSET_CONTROL 0x8582U
|
||||
#define VIDEO_GET_LEN_EU_VIDEO_RESOLUTION_CONTROL 0x8583U
|
||||
#define VIDEO_GET_LEN_EU_MIN_FRAME_INTERVAL_CONTROL 0x8584U
|
||||
#define VIDEO_GET_LEN_EU_SLICE_MODE_CONTROL 0x8585U
|
||||
#define VIDEO_GET_LEN_EU_RATE_CONTROL_MODE_CONTROL 0x8586U
|
||||
#define VIDEO_GET_LEN_EU_AVERAGE_BITRATE_CONTROL 0x8587U
|
||||
#define VIDEO_GET_LEN_EU_CPB_SIZE_CONTROL 0x8588U
|
||||
#define VIDEO_GET_LEN_EU_PEAK_BIT_RATE_CONTROL 0x8589U
|
||||
#define VIDEO_GET_LEN_EU_QUANTIZATION_PARAMS_CONTROL 0x858AU
|
||||
#define VIDEO_GET_LEN_EU_SYNC_REF_FRAME_CONTROL 0x858BU
|
||||
#define VIDEO_GET_LEN_EU_LTR_BUFFER_CONTROL 0x858CU
|
||||
#define VIDEO_GET_LEN_EU_LTR_PICTURE_CONTROL 0x858DU
|
||||
#define VIDEO_GET_LEN_EU_LTR_VALIDATION_CONTROL 0x858EU
|
||||
#define VIDEO_GET_LEN_EU_QP_RANGE_CONTROL 0x8591U
|
||||
#define VIDEO_GET_LEN_EU_PRIORITY_CONTROL 0x8592U
|
||||
#define VIDEO_GET_LEN_EU_START_OR_STOP_LAYER_CONTROL 0x8593U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request GET INFO COMMAND */
|
||||
#define VIDEO_GET_INFO_VC_POWER_MODE_CONTROL 0x8601U
|
||||
#define VIDEO_GET_INFO_VC_ERROR_CODE_CONTROL 0x8602U
|
||||
|
||||
#define VIDEO_GET_INFO_PU_BACKLIGHT_COMPENSATION_CONTROL 0x8621U
|
||||
#define VIDEO_GET_INFO_PU_BRIGHTNESS_CONTROL 0x8622U
|
||||
#define VIDEO_GET_INFO_PU_CONTRACT_CONTROL 0x8623U
|
||||
#define VIDEO_GET_INFO_PU_GAIN_CONTROL 0x8624U
|
||||
#define VIDEO_GET_INFO_PU_POWER_LINE_FREQUENCY_CONTROL 0x8625U
|
||||
#define VIDEO_GET_INFO_PU_HUE_CONTROL 0x8626U
|
||||
#define VIDEO_GET_INFO_PU_SATURATION_CONTROL 0x8627U
|
||||
#define VIDEO_GET_INFO_PU_SHARRNESS_CONTROL 0x8628U
|
||||
#define VIDEO_GET_INFO_PU_GAMMA_CONTROL 0x8629U
|
||||
#define VIDEO_GET_INFO_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x862AU
|
||||
#define VIDEO_GET_INFO_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x862BU
|
||||
#define VIDEO_GET_INFO_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x862CU
|
||||
#define VIDEO_GET_INFO_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x862DU
|
||||
#define VIDEO_GET_INFO_PU_DIGITAL_MULTIPLIER_CONTROL 0x862EU
|
||||
#define VIDEO_GET_INFO_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x862FU
|
||||
#define VIDEO_GET_INFO_PU_HUE_AUTO_CONTROL 0x8630U
|
||||
#define VIDEO_GET_INFO_PU_ANALOG_VIDEO_STANDARD_CONTROL 0x8631U
|
||||
#define VIDEO_GET_INFO_PU_ANALOG_LOCK_STATUS_CONTROL 0x8632U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_INFO_PU_CONTRAST_AUTO_CONTROL 0x8633U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_INFO_CT_SCANNING_MODE_CONTROL 0x8641U
|
||||
#define VIDEO_GET_INFO_CT_AE_MODE_CONTROL 0x8642U
|
||||
#define VIDEO_GET_INFO_CT_AE_PRIORITY_CONTROL 0x8643U
|
||||
#define VIDEO_GET_INFO_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x8644U
|
||||
#define VIDEO_GET_INFO_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x8645U
|
||||
#define VIDEO_GET_INFO_CT_FOCUS_ABSOLUTE_CONTROL 0x8646U
|
||||
#define VIDEO_GET_INFO_CT_FOCUS_RELATIVE_CONTROL 0x8647U
|
||||
#define VIDEO_GET_INFO_CT_FOCUS_AUTO_CONTROL 0x8648U
|
||||
#define VIDEO_GET_INFO_CT_IRIS_ABSOLUTE_CONTROL 0x8649U
|
||||
#define VIDEO_GET_INFO_CT_IRIS_RELATIVE_CONTROL 0x864AU
|
||||
#define VIDEO_GET_INFO_CT_ZOOM_ABSOLUTE_CONTROL 0x864BU
|
||||
#define VIDEO_GET_INFO_CT_ZOOM_RELATIVE_CONTROL 0x864CU
|
||||
#define VIDEO_GET_INFO_CT_PANTILT_ABSOLUTE_CONTROL 0x864DU
|
||||
#define VIDEO_GET_INFO_CT_PANTILT_RELATIVE_CONTROL 0x864EU
|
||||
#define VIDEO_GET_INFO_CT_ROLL_ABSOLUTE_CONTROL 0x864FU
|
||||
#define VIDEO_GET_INFO_CT_ROLL_RELATIVE_CONTROL 0x8650U
|
||||
#define VIDEO_GET_INFO_CT_PRIVACY_CONTROL 0x8651U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_INFO_CT_FOCUS_SIMPLE_CONTROL 0x8652U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_INFO_VS_PROBE_CONTROL 0x8661U
|
||||
#define VIDEO_GET_INFO_VS_COMMIT_CONTROL 0x8662U
|
||||
#define VIDEO_GET_INFO_VS_STILL_PROBE_CONTROL 0x8663U
|
||||
#define VIDEO_GET_INFO_VS_STILL_COMMIT_CONTROL 0x8664U
|
||||
#define VIDEO_GET_INFO_VS_STILL_IMAGE_TRIGGER_CONTROL 0x8665U
|
||||
#define VIDEO_GET_INFO_VS_STREAM_ERROR_CODE_CONTROL 0x8666U
|
||||
#define VIDEO_GET_INFO_VS_GENERATE_KEY_FRAME_CONTROL 0x8667U
|
||||
#define VIDEO_GET_INFO_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x8668U
|
||||
#define VIDEO_GET_INFO_VS_SYNCH_DELAY_CONTROL 0x8669U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_INFO_EU_SELECT_LAYER_CONTROL 0x8681U
|
||||
#define VIDEO_GET_INFO_EU_PROFILE_TOOLSET_CONTROL 0x8682U
|
||||
#define VIDEO_GET_INFO_EU_VIDEO_RESOLUTION_CONTROL 0x8683U
|
||||
#define VIDEO_GET_INFO_EU_MIN_FRAME_INTERVAL_CONTROL 0x8684U
|
||||
#define VIDEO_GET_INFO_EU_SLICE_MODE_CONTROL 0x8685U
|
||||
#define VIDEO_GET_INFO_EU_RATE_CONTROL_MODE_CONTROL 0x8686U
|
||||
#define VIDEO_GET_INFO_EU_AVERAGE_BITRATE_CONTROL 0x8687U
|
||||
#define VIDEO_GET_INFO_EU_CPB_SIZE_CONTROL 0x8688U
|
||||
#define VIDEO_GET_INFO_EU_PEAK_BIT_RATE_CONTROL 0x8689U
|
||||
#define VIDEO_GET_INFO_EU_QUANTIZATION_PARAMS_CONTROL 0x868AU
|
||||
#define VIDEO_GET_INFO_EU_SYNC_REF_FRAME_CONTROL 0x868BU
|
||||
#define VIDEO_GET_INFO_EU_LTR_BUFFER_CONTROL 0x868CU
|
||||
#define VIDEO_GET_INFO_EU_LTR_PICTURE_CONTROL 0x868DU
|
||||
#define VIDEO_GET_INFO_EU_LTR_VALIDATION_CONTROL 0x868EU
|
||||
#define VIDEO_GET_INFO_EU_SEI_PAYLOADTYPE_CONTROL 0x8690U
|
||||
#define VIDEO_GET_INFO_EU_QP_RANGE_CONTROL 0x8691U
|
||||
#define VIDEO_GET_INFO_EU_PRIORITY_CONTROL 0x8692U
|
||||
#define VIDEO_GET_INFO_EU_START_OR_STOP_LAYER_CONTROL 0x8693U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request GET DEF COMMAND */
|
||||
#define VIDEO_GET_DEF_PU_BACKLIGHT_COMPENSATION_CONTROL 0x8721U
|
||||
#define VIDEO_GET_DEF_PU_BRIGHTNESS_CONTROL 0x8722U
|
||||
#define VIDEO_GET_DEF_PU_CONTRACT_CONTROL 0x8723U
|
||||
#define VIDEO_GET_DEF_PU_GAIN_CONTROL 0x8724U
|
||||
#define VIDEO_GET_DEF_PU_POWER_LINE_FREQUENCY_CONTROL 0x8725U
|
||||
#define VIDEO_GET_DEF_PU_HUE_CONTROL 0x8726U
|
||||
#define VIDEO_GET_DEF_PU_SATURATION_CONTROL 0x8727U
|
||||
#define VIDEO_GET_DEF_PU_SHARRNESS_CONTROL 0x8728U
|
||||
#define VIDEO_GET_DEF_PU_GAMMA_CONTROL 0x8729U
|
||||
#define VIDEO_GET_DEF_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x872AU
|
||||
#define VIDEO_GET_DEF_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x872BU
|
||||
#define VIDEO_GET_DEF_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x872CU
|
||||
#define VIDEO_GET_DEF_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x872DU
|
||||
#define VIDEO_GET_DEF_PU_DIGITAL_MULTIPLIER_CONTROL 0x872EU
|
||||
#define VIDEO_GET_DEF_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x872FU
|
||||
#define VIDEO_GET_DEF_PU_HUE_AUTO_CONTROL 0x8730U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_DEF_PU_CONTRAST_AUTO_CONTROL 0x8731U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_DEF_CT_AE_MODE_CONTROL 0x8742U
|
||||
#define VIDEO_GET_DEF_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x8744U
|
||||
#define VIDEO_GET_DEF_CT_FOCUS_ABSOLUTE_CONTROL 0x8746U
|
||||
#define VIDEO_GET_DEF_CT_FOCUS_RELATIVE_CONTROL 0x8747U
|
||||
#define VIDEO_GET_DEF_CT_FOCUS_AUTO_CONTROL 0x8748U
|
||||
#define VIDEO_GET_DEF_CT_IRIS_ABSOLUTE_CONTROL 0x8749U
|
||||
#define VIDEO_GET_DEF_CT_ZOOM_ABSOLUTE_CONTROL 0x874BU
|
||||
#define VIDEO_GET_DEF_CT_ZOOM_RELATIVE_CONTROL 0x874CU
|
||||
#define VIDEO_GET_DEF_CT_PANTILT_ABSOLUTE_CONTROL 0x874DU
|
||||
#define VIDEO_GET_DEF_CT_PANTILT_RELATIVE_CONTROL 0x874EU
|
||||
#define VIDEO_GET_DEF_CT_ROLL_ABSOLUTE_CONTROL 0x874FU
|
||||
#define VIDEO_GET_DEF_CT_ROLL_RELATIVE_CONTROL 0x8750U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_DEF_CT_FOCUS_SIMPLE_CONTROL 0x8751U
|
||||
#define VIDEO_GET_DEF_CT_DIGITAL_WINDOW_CONTROL 0x8752U
|
||||
#define VIDEO_GET_DEF_CT_REGION_OF_INTEREST_CONTROL 0x8753U
|
||||
#endif
|
||||
|
||||
#define VIDEO_GET_DEF_VS_PROBE_CONTROL 0x8761U
|
||||
#define VIDEO_GET_DEF_VS_STILL_PROBE_CONTROL 0x8763U
|
||||
#define VIDEO_GET_DEF_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x8768U
|
||||
#define VIDEO_GET_DEF_VS_SYNCH_DELAY_CONTROL 0x8769U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_GET_DEF_EU_PROFILE_TOOLSET_CONTROL 0x8782U
|
||||
#define VIDEO_GET_DEF_EU_VIDEO_RESOLUTION_CONTROL 0x8783U
|
||||
#define VIDEO_GET_DEF_EU_MIN_FRAME_INTERVAL_CONTROL 0x8784U
|
||||
#define VIDEO_GET_DEF_EU_SLICE_MODE_CONTROL 0x8785U
|
||||
#define VIDEO_GET_DEF_EU_RATE_CONTROL_MODE_CONTROL 0x8786U
|
||||
#define VIDEO_GET_DEF_EU_AVERAGE_BITRATE_CONTROL 0x8787U
|
||||
#define VIDEO_GET_DEF_EU_CPB_SIZE_CONTROL 0x8788U
|
||||
#define VIDEO_GET_DEF_EU_PEAK_BIT_RATE_CONTROL 0x8789U
|
||||
#define VIDEO_GET_DEF_EU_QUANTIZATION_PARAMS_CONTROL 0x878AU
|
||||
#define VIDEO_GET_DEF_EU_LTR_BUFFER_CONTROL 0x878CU
|
||||
#define VIDEO_GET_DEF_EU_LTR_PICTURE_CONTROL 0x878DU
|
||||
#define VIDEO_GET_DEF_EU_LTR_VALIDATION_CONTROL 0x878EU
|
||||
#define VIDEO_GET_DEF_EU_LEVEL_IDC_LIMIT_CONTROL 0x878FU
|
||||
#define VIDEO_GET_DEF_EU_SEI_PAYLOADTYPE_CONTROL 0x8790U
|
||||
#define VIDEO_GET_DEF_EU_QP_RANGE_CONTROL 0x8791U
|
||||
#define VIDEO_GET_DEF_EU_ERROR_RESILIENCY_CONTROL 0x8794U
|
||||
#endif
|
||||
|
||||
/*! @brief Video device class-specific request SET CUR COMMAND */
|
||||
#define VIDEO_SET_CUR_VC_POWER_MODE_CONTROL 0x0101U
|
||||
|
||||
#define VIDEO_SET_CUR_PU_BACKLIGHT_COMPENSATION_CONTROL 0x0121U
|
||||
#define VIDEO_SET_CUR_PU_BRIGHTNESS_CONTROL 0x0122U
|
||||
#define VIDEO_SET_CUR_PU_CONTRACT_CONTROL 0x0123U
|
||||
#define VIDEO_SET_CUR_PU_GAIN_CONTROL 0x0124U
|
||||
#define VIDEO_SET_CUR_PU_POWER_LINE_FREQUENCY_CONTROL 0x0125U
|
||||
#define VIDEO_SET_CUR_PU_HUE_CONTROL 0x0126U
|
||||
#define VIDEO_SET_CUR_PU_SATURATION_CONTROL 0x0127U
|
||||
#define VIDEO_SET_CUR_PU_SHARRNESS_CONTROL 0x0128U
|
||||
#define VIDEO_SET_CUR_PU_GAMMA_CONTROL 0x0129U
|
||||
#define VIDEO_SET_CUR_PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x012AU
|
||||
#define VIDEO_SET_CUR_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x012BU
|
||||
#define VIDEO_SET_CUR_PU_WHITE_BALANCE_COMPONENT_CONTROL 0x012CU
|
||||
#define VIDEO_SET_CUR_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x012DU
|
||||
#define VIDEO_SET_CUR_PU_DIGITAL_MULTIPLIER_CONTROL 0x012EU
|
||||
#define VIDEO_SET_CUR_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x012FU
|
||||
#define VIDEO_SET_CUR_PU_HUE_AUTO_CONTROL 0x0130U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_SET_CUR_PU_CONTRAST_AUTO_CONTROL 0x0131U
|
||||
#endif
|
||||
|
||||
#define VIDEO_SET_CUR_CT_SCANNING_MODE_CONTROL 0x0141U
|
||||
#define VIDEO_SET_CUR_CT_AE_MODE_CONTROL 0x0142U
|
||||
#define VIDEO_SET_CUR_CT_AE_PRIORITY_CONTROL 0x0143U
|
||||
#define VIDEO_SET_CUR_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x0144U
|
||||
#define VIDEO_SET_CUR_CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x0145U
|
||||
#define VIDEO_SET_CUR_CT_FOCUS_ABSOLUTE_CONTROL 0x0146U
|
||||
#define VIDEO_SET_CUR_CT_FOCUS_RELATIVE_CONTROL 0x0147U
|
||||
#define VIDEO_SET_CUR_CT_FOCUS_AUTO_CONTROL 0x0148U
|
||||
#define VIDEO_SET_CUR_CT_IRIS_ABSOLUTE_CONTROL 0x0149U
|
||||
#define VIDEO_SET_CUR_CT_IRIS_RELATIVE_CONTROL 0x014AU
|
||||
#define VIDEO_SET_CUR_CT_ZOOM_ABSOLUTE_CONTROL 0x014BU
|
||||
#define VIDEO_SET_CUR_CT_ZOOM_RELATIVE_CONTROL 0x014CU
|
||||
#define VIDEO_SET_CUR_CT_PANTILT_ABSOLUTE_CONTROL 0x014DU
|
||||
#define VIDEO_SET_CUR_CT_PANTILT_RELATIVE_CONTROL 0x014EU
|
||||
#define VIDEO_SET_CUR_CT_ROLL_ABSOLUTE_CONTROL 0x014FU
|
||||
#define VIDEO_SET_CUR_CT_ROLL_RELATIVE_CONTROL 0x0150U
|
||||
#define VIDEO_SET_CUR_CT_PRIVACY_CONTROL 0x0151U
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_SET_CUR_CT_FOCUS_SIMPLE_CONTROL 0x0152U
|
||||
#define VIDEO_SET_CUR_CT_DIGITAL_WINDOW_CONTROL 0x0153U
|
||||
#define VIDEO_SET_CUR_CT_REGION_OF_INTEREST_CONTROL 0x0154U
|
||||
#endif
|
||||
|
||||
#define VIDEO_SET_CUR_VS_PROBE_CONTROL 0x0161U
|
||||
#define VIDEO_SET_CUR_VS_COMMIT_CONTROL 0x0162U
|
||||
#define VIDEO_SET_CUR_VS_STILL_PROBE_CONTROL 0x0163U
|
||||
#define VIDEO_SET_CUR_VS_STILL_COMMIT_CONTROL 0x0164U
|
||||
#define VIDEO_SET_CUR_VS_STILL_IMAGE_TRIGGER_CONTROL 0x0165U
|
||||
#define VIDEO_SET_CUR_VS_STREAM_ERROR_CODE_CONTROL 0x0166U
|
||||
#define VIDEO_SET_CUR_VS_GENERATE_KEY_FRAME_CONTROL 0x0167U
|
||||
#define VIDEO_SET_CUR_VS_UPDATE_FRAME_SEGMENT_CONTROL 0x0168U
|
||||
#define VIDEO_SET_CUR_VS_SYNCH_DELAY_CONTROL 0x0169U
|
||||
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
#define VIDEO_SET_CUR_EU_SELECT_LAYER_CONTROL 0x0181U
|
||||
#define VIDEO_SET_CUR_EU_PROFILE_TOOLSET_CONTROL 0x0182U
|
||||
#define VIDEO_SET_CUR_EU_VIDEO_RESOLUTION_CONTROL 0x0183U
|
||||
#define VIDEO_SET_CUR_EU_MIN_FRAME_INTERVAL_CONTROL 0x0184U
|
||||
#define VIDEO_SET_CUR_EU_SLICE_MODE_CONTROL 0x0185U
|
||||
#define VIDEO_SET_CUR_EU_RATE_CONTROL_MODE_CONTROL 0x0186U
|
||||
#define VIDEO_SET_CUR_EU_AVERAGE_BITRATE_CONTROL 0x0187U
|
||||
#define VIDEO_SET_CUR_EU_CPB_SIZE_CONTROL 0x0188U
|
||||
#define VIDEO_SET_CUR_EU_PEAK_BIT_RATE_CONTROL 0x0189U
|
||||
#define VIDEO_SET_CUR_EU_QUANTIZATION_PARAMS_CONTROL 0x018AU
|
||||
#define VIDEO_SET_CUR_EU_SYNC_REF_FRAME_CONTROL 0x018BU
|
||||
#define VIDEO_SET_CUR_EU_LTR_BUFFER_CONTROL 0x018CU
|
||||
#define VIDEO_SET_CUR_EU_LTR_PICTURE_CONTROL 0x018DU
|
||||
#define VIDEO_SET_CUR_EU_LTR_VALIDATION_CONTROL 0x018EU
|
||||
#define VIDEO_SET_CUR_EU_LEVEL_IDC_LIMIT_CONTROL 0x018FU
|
||||
#define VIDEO_SET_CUR_EU_SEI_PAYLOADTYPE_CONTROL 0x0190U
|
||||
#define VIDEO_SET_CUR_EU_QP_RANGE_CONTROL 0x0191U
|
||||
#define VIDEO_SET_CUR_EU_PRIORITY_CONTROL 0x0192U
|
||||
#define VIDEO_SET_CUR_EU_START_OR_STOP_LAYER_CONTROL 0x0193U
|
||||
#define VIDEO_SET_CUR_EU_ERROR_RESILIENCY_CONTROL 0x0194U
|
||||
#endif
|
||||
|
||||
/*! @brief The payload header structure for MJPEG payload format. */
|
||||
struct video_mjpeg_payload_header {
|
||||
uint8_t bHeaderLength; /*!< The payload header length. */
|
||||
union {
|
||||
uint8_t bmheaderInfo; /*!< The payload header bitmap field. */
|
||||
struct
|
||||
{
|
||||
uint8_t frameIdentifier : 1U; /*!< Frame Identifier. This bit toggles at each frame start boundary and stays
|
||||
constant for the rest of the frame.*/
|
||||
uint8_t endOfFrame : 1U; /*!< End of Frame. This bit indicates the end of a video frame and is set in the
|
||||
last video sample that belongs to a frame.*/
|
||||
uint8_t
|
||||
presentationTimeStamp : 1U; /*!< Presentation Time Stamp. This bit, when set, indicates the presence of
|
||||
a PTS field.*/
|
||||
uint8_t sourceClockReference : 1U; /*!< Source Clock Reference. This bit, when set, indicates the presence
|
||||
of a SCR field.*/
|
||||
uint8_t reserved : 1U; /*!< Reserved. Set to 0. */
|
||||
uint8_t stillImage : 1U; /*!< Still Image. This bit, when set, identifies a video sample that belongs to a
|
||||
still image.*/
|
||||
uint8_t errorBit : 1U; /*!< Error Bit. This bit, when set, indicates an error in the device streaming.*/
|
||||
uint8_t endOfHeader : 1U; /*!< End of Header. This bit, when set, indicates the end of the BFH fields.*/
|
||||
} headerInfoBits;
|
||||
struct
|
||||
{
|
||||
uint8_t FID : 1U; /*!< Frame Identifier. This bit toggles at each frame start boundary and stays constant
|
||||
for the rest of the frame.*/
|
||||
uint8_t EOI : 1U; /*!< End of Frame. This bit indicates the end of a video frame and is set in the last
|
||||
video sample that belongs to a frame.*/
|
||||
uint8_t PTS : 1U; /*!< Presentation Time Stamp. This bit, when set, indicates the presence of a PTS field.*/
|
||||
uint8_t SCR : 1U; /*!< Source Clock Reference. This bit, when set, indicates the presence of a SCR field.*/
|
||||
uint8_t RES : 1U; /*!< Reserved. Set to 0. */
|
||||
uint8_t STI : 1U; /*!< Still Image. This bit, when set, identifies a video sample that belongs to a still
|
||||
image.*/
|
||||
uint8_t ERR : 1U; /*!< Error Bit. This bit, when set, indicates an error in the device streaming.*/
|
||||
uint8_t EOH : 1U; /*!< End of Header. This bit, when set, indicates the end of the BFH fields.*/
|
||||
} headerInfoBitmap;
|
||||
} headerInfoUnion;
|
||||
uint32_t dwPresentationTime; /*!< Presentation time stamp (PTS) field.*/
|
||||
uint8_t bSourceClockReference[6]; /*!< Source clock reference (SCR) field.*/
|
||||
} __packed;
|
||||
|
||||
/*! @brief The Video probe and commit controls structure.*/
|
||||
struct video_probe_and_commit_controls {
|
||||
union {
|
||||
uint8_t bmHint; /*!< Bit-field control indicating to the function what fields shall be kept fixed. */
|
||||
struct
|
||||
{
|
||||
uint8_t dwFrameInterval : 1U; /*!< dwFrameInterval field.*/
|
||||
uint8_t wKeyFrameRate : 1U; /*!< wKeyFrameRate field.*/
|
||||
uint8_t wPFrameRate : 1U; /*!< wPFrameRate field.*/
|
||||
uint8_t wCompQuality : 1U; /*!< wCompQuality field.*/
|
||||
uint8_t wCompWindowSize : 1U; /*!< wCompWindowSize field.*/
|
||||
uint8_t reserved : 3U; /*!< Reserved field.*/
|
||||
} hintBitmap;
|
||||
} hintUnion;
|
||||
union {
|
||||
uint8_t bmHint; /*!< Bit-field control indicating to the function what fields shall be kept fixed. */
|
||||
struct
|
||||
{
|
||||
uint8_t reserved : 8U; /*!< Reserved field.*/
|
||||
} hintBitmap;
|
||||
} hintUnion1;
|
||||
uint8_t bFormatIndex; /*!< Video format index from a format descriptor.*/
|
||||
uint8_t bFrameIndex; /*!< Video frame index from a frame descriptor.*/
|
||||
uint32_t dwFrameInterval; /*!< Frame interval in 100ns units.*/
|
||||
uint16_t wKeyFrameRate; /*!< Key frame rate in key-frame per video-frame units.*/
|
||||
uint16_t wPFrameRate; /*!< PFrame rate in PFrame/key frame units.*/
|
||||
uint16_t wCompQuality; /*!< Compression quality control in abstract units 0U (lowest) to 10000U (highest).*/
|
||||
uint16_t wCompWindowSize; /*!< Window size for average bit rate control.*/
|
||||
uint16_t wDelay; /*!< Internal video streaming interface latency in ms from video data capture to presentation on
|
||||
the USB.*/
|
||||
uint32_t dwMaxVideoFrameSize; /*!< Maximum video frame or codec-specific segment size in bytes.*/
|
||||
uint32_t dwMaxPayloadTransferSize; /*!< Specifies the maximum number of bytes that the device can transmit or
|
||||
receive in a single payload transfer.*/
|
||||
uint32_t dwClockFrequency; /*!< The device clock frequency in Hz for the specified format. This specifies the
|
||||
units used for the time information fields in the Video Payload Headers in the data
|
||||
stream.*/
|
||||
uint8_t bmFramingInfo; /*!< Bit-field control supporting the following values: D0 Frame ID, D1 EOF.*/
|
||||
uint8_t bPreferedVersion; /*!< The preferred payload format version supported by the host or device for the
|
||||
specified bFormatIndex value.*/
|
||||
uint8_t bMinVersion; /*!< The minimum payload format version supported by the device for the specified bFormatIndex
|
||||
value.*/
|
||||
uint8_t bMaxVersion; /*!< The maximum payload format version supported by the device for the specified bFormatIndex
|
||||
value.*/
|
||||
#if defined(USB_DEVICE_VIDEO_CLASS_VERSION_1_5) && USB_DEVICE_VIDEO_CLASS_VERSION_1_5
|
||||
uint8_t bUsage; /*!< This bitmap enables features reported by the bmUsages field of the Video Frame Descriptor.*/
|
||||
uint8_t
|
||||
bBitDepthLuma; /*!< Represents bit_depth_luma_minus8 + 8U, which must be the same as bit_depth_chroma_minus8 +
|
||||
8.*/
|
||||
uint8_t bmSettings; /*!< A bitmap of flags that is used to discover and control specific features of a temporally
|
||||
encoded video stream.*/
|
||||
uint8_t bMaxNumberOfRefFramesPlus1; /*!< Host indicates the maximum number of frames stored for use as references.*/
|
||||
uint16_t bmRateControlModes; /*!< This field contains 4U sub-fields, each of which is a 4U bit number.*/
|
||||
uint64_t bmLayoutPerStream; /*!< This field contains 4U sub-fields, each of which is a 2U byte number.*/
|
||||
#endif
|
||||
} __packed;
|
||||
|
||||
/*! @brief The Video still probe and still commit controls structure.*/
|
||||
struct video_still_probe_and_commit_controls {
|
||||
uint8_t bFormatIndex; /*!< Video format index from a format descriptor.*/
|
||||
uint8_t bFrameIndex; /*!< Video frame index from a frame descriptor.*/
|
||||
uint8_t bCompressionIndex; /*!< Compression index from a frame descriptor.*/
|
||||
uint32_t dwMaxVideoFrameSize; /*!< Maximum still image size in bytes.*/
|
||||
uint32_t dwMaxPayloadTransferSize; /*!< Specifies the maximum number of bytes that the device can transmit or
|
||||
receive in a single payload transfer.*/
|
||||
} __packed;
|
||||
|
||||
void usbd_video_sof_callback(void);
|
||||
void usbd_video_set_interface_callback(uint8_t value);
|
||||
void usbd_video_add_interface(usbd_class_t *class, usbd_interface_t *intf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USB_VIDEO_H_ */
|
||||
37
class/webusb/usbd_webusb.h
Normal file
37
class/webusb/usbd_webusb.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef _USBD_WEBUSB_H
|
||||
#define _USBD_WEBUSB_H
|
||||
|
||||
/* 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
|
||||
|
||||
/* BOS Capability webusb */
|
||||
struct usb_bos_webusb_platform_capability_descriptor {
|
||||
struct usb_bos_capability_descriptor webusb_platform;
|
||||
uint16_t bcdVersion;
|
||||
uint8_t bVendorCode;
|
||||
uint8_t iLandingPage;
|
||||
} __packed;
|
||||
|
||||
struct webusb_url_descriptor {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint8_t bScheme;
|
||||
char URL[];
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
35
class/winusb/usbd_winusb.h
Normal file
35
class/winusb/usbd_winusb.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _USBD_WINUSB_H
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
/* WinUSB Microsoft OS 2.0 descriptor Platform Capability Descriptor */
|
||||
struct usb_bos_winusb_platform_capability_descriptor {
|
||||
struct usb_bos_capability_descriptor winusb_platform;
|
||||
uint32_t dwWindowsVersion;
|
||||
uint16_t wMSOSDescriptorSetTotalLength;
|
||||
uint8_t bMS_VendorCode;
|
||||
uint8_t bAltEnumCode;
|
||||
} __packed;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user