v2.0.0 Add support for ESP32S2 and update ESP-IDF to 4.4 (#4996)

This is very much still work in progress and much more will change before the final 2.0.0

Some APIs have changed. New libraries have been added. LittleFS included.

Co-authored-by: Seon Rozenblum <seonr@3sprockets.com>
Co-authored-by: Me No Dev <me-no-dev@users.noreply.github.com>
Co-authored-by: geeksville <kevinh@geeksville.com>
Co-authored-by: Mike Dunston <m_dunston@comcast.net>
Co-authored-by: Unexpected Maker <seon@unexpectedmaker.com>
Co-authored-by: Seon Rozenblum <seonr@3sprockets.com>
Co-authored-by: microDev <70126934+microDev1@users.noreply.github.com>
Co-authored-by: tobozo <tobozo@users.noreply.github.com>
Co-authored-by: bobobo1618 <bobobo1618@users.noreply.github.com>
Co-authored-by: lorol <lorolouis@gmail.com>
Co-authored-by: geeksville <kevinh@geeksville.com>
Co-authored-by: Limor "Ladyada" Fried <limor@ladyada.net>
Co-authored-by: Sweety <switi.mhaiske@espressif.com>
Co-authored-by: Loick MAHIEUX <loick111@gmail.com>
Co-authored-by: Larry Bernstone <lbernstone@gmail.com>
Co-authored-by: Valerii Koval <valeros@users.noreply.github.com>
Co-authored-by: 快乐的我531 <2302004040@qq.com>
Co-authored-by: chegewara <imperiaonline4@gmail.com>
Co-authored-by: Clemens Kirchgatterer <clemens@1541.org>
Co-authored-by: Aron Rubin <aronrubin@gmail.com>
Co-authored-by: Pete Lewis <601236+lewispg228@users.noreply.github.com>
This commit is contained in:
Me No Dev
2021-04-05 14:23:58 +03:00
committed by GitHub
parent 46d5afb17f
commit 5502879a5b
5209 changed files with 826360 additions and 322816 deletions

View File

@ -0,0 +1,934 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
* Copyright (c) 2020 Reinhard Panhuber
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup group_class
* \defgroup ClassDriver_Audio Audio
* Currently only MIDI subclass is supported
* @{ */
#ifndef _TUSB_AUDIO_H__
#define _TUSB_AUDIO_H__
#include "common/tusb_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Audio Device Class Codes
/// A.2 - Audio Function Subclass Codes
typedef enum
{
AUDIO_FUNCTION_SUBCLASS_UNDEFINED = 0x00,
} audio_function_subclass_type_t;
/// A.3 - Audio Function Protocol Codes
typedef enum
{
AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00,
AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0
} audio_function_protocol_code_t;
/// A.5 - Audio Interface Subclass Codes
typedef enum
{
AUDIO_SUBCLASS_UNDEFINED = 0x00,
AUDIO_SUBCLASS_CONTROL , ///< Audio Control
AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming
AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
} audio_subclass_type_t;
/// A.6 - Audio Interface Protocol Codes
typedef enum
{
AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00,
AUDIO_INT_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0
} audio_interface_protocol_code_t;
/// A.7 - Audio Function Category Codes
typedef enum
{
AUDIO_FUNC_UNDEF = 0x00,
AUDIO_FUNC_DESKTOP_SPEAKER = 0x01,
AUDIO_FUNC_HOME_THEATER = 0x02,
AUDIO_FUNC_MICROPHONE = 0x03,
AUDIO_FUNC_HEADSET = 0x04,
AUDIO_FUNC_TELEPHONE = 0x05,
AUDIO_FUNC_CONVERTER = 0x06,
AUDIO_FUNC_SOUND_RECODER = 0x07,
AUDIO_FUNC_IO_BOX = 0x08,
AUDIO_FUNC_MUSICAL_INSTRUMENT = 0x09,
AUDIO_FUNC_PRO_AUDIO = 0x0A,
AUDIO_FUNC_AUDIO_VIDEO = 0x0B,
AUDIO_FUNC_CONTROL_PANEL = 0x0C,
AUDIO_FUNC_OTHER = 0xFF,
} audio_function_code_t;
/// A.9 - Audio Class-Specific AC Interface Descriptor Subtypes UAC2
typedef enum
{
AUDIO_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00,
AUDIO_CS_AC_INTERFACE_HEADER = 0x01,
AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02,
AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL = 0x03,
AUDIO_CS_AC_INTERFACE_MIXER_UNIT = 0x04,
AUDIO_CS_AC_INTERFACE_SELECTOR_UNIT = 0x05,
AUDIO_CS_AC_INTERFACE_FEATURE_UNIT = 0x06,
AUDIO_CS_AC_INTERFACE_EFFECT_UNIT = 0x07,
AUDIO_CS_AC_INTERFACE_PROCESSING_UNIT = 0x08,
AUDIO_CS_AC_INTERFACE_EXTENSION_UNIT = 0x09,
AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE = 0x0A,
AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B,
AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C,
AUDIO_CS_AC_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D,
} audio_cs_ac_interface_subtype_t;
/// A.10 - Audio Class-Specific AS Interface Descriptor Subtypes UAC2
typedef enum
{
AUDIO_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00,
AUDIO_CS_AS_INTERFACE_AS_GENERAL = 0x01,
AUDIO_CS_AS_INTERFACE_FORMAT_TYPE = 0x02,
AUDIO_CS_AS_INTERFACE_ENCODER = 0x03,
AUDIO_CS_AS_INTERFACE_DECODER = 0x04,
} audio_cs_as_interface_subtype_t;
/// A.11 - Effect Unit Effect Types
typedef enum
{
AUDIO_EFFECT_TYPE_UNDEF = 0x00,
AUDIO_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01,
AUDIO_EFFECT_TYPE_REVERBERATION = 0x02,
AUDIO_EFFECT_TYPE_MOD_DELAY = 0x03,
AUDIO_EFFECT_TYPE_DYN_RANGE_COMP = 0x04,
} audio_effect_unit_effect_type_t;
/// A.12 - Processing Unit Process Types
typedef enum
{
AUDIO_PROCESS_TYPE_UNDEF = 0x00,
AUDIO_PROCESS_TYPE_UP_DOWN_MIX = 0x01,
AUDIO_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02,
AUDIO_PROCESS_TYPE_STEREO_EXTENDER = 0x03,
} audio_processing_unit_process_type_t;
/// A.13 - Audio Class-Specific EP Descriptor Subtypes UAC2
typedef enum
{
AUDIO_CS_EP_SUBTYPE_UNDEF = 0x00,
AUDIO_CS_EP_SUBTYPE_GENERAL = 0x01,
} audio_cs_ep_subtype_t;
/// A.14 - Audio Class-Specific Request Codes
typedef enum
{
AUDIO_CS_REQ_UNDEF = 0x00,
AUDIO_CS_REQ_CUR = 0x01,
AUDIO_CS_REQ_RANGE = 0x02,
AUDIO_CS_REQ_MEM = 0x03,
} audio_cs_req_t;
/// A.17 - Control Selector Codes
/// A.17.1 - Clock Source Control Selectors
typedef enum
{
AUDIO_CS_CTRL_UNDEF = 0x00,
AUDIO_CS_CTRL_SAM_FREQ = 0x01,
AUDIO_CS_CTRL_CLK_VALID = 0x02,
} audio_clock_src_control_selector_t;
/// A.17.2 - Clock Selector Control Selectors
typedef enum
{
AUDIO_CX_CTRL_UNDEF = 0x00,
AUDIO_CX_CTRL_CONTROL = 0x01,
} audio_clock_sel_control_selector_t;
/// A.17.3 - Clock Multiplier Control Selectors
typedef enum
{
AUDIO_CM_CTRL_UNDEF = 0x00,
AUDIO_CM_CTRL_NUMERATOR_CONTROL = 0x01,
AUDIO_CM_CTRL_DENOMINATOR_CONTROL = 0x02,
} audio_clock_mul_control_selector_t;
/// A.17.4 - Terminal Control Selectors
typedef enum
{
AUDIO_TE_CTRL_UNDEF = 0x00,
AUDIO_TE_CTRL_COPY_PROTECT = 0x01,
AUDIO_TE_CTRL_CONNECTOR = 0x02,
AUDIO_TE_CTRL_OVERLOAD = 0x03,
AUDIO_TE_CTRL_CLUSTER = 0x04,
AUDIO_TE_CTRL_UNDERFLOW = 0x05,
AUDIO_TE_CTRL_OVERFLOW = 0x06,
AUDIO_TE_CTRL_LATENCY = 0x07,
} audio_terminal_control_selector_t;
/// A.17.5 - Mixer Control Selectors
typedef enum
{
AUDIO_MU_CTRL_UNDEF = 0x00,
AUDIO_MU_CTRL_MIXER = 0x01,
AUDIO_MU_CTRL_CLUSTER = 0x02,
AUDIO_MU_CTRL_UNDERFLOW = 0x03,
AUDIO_MU_CTRL_OVERFLOW = 0x04,
AUDIO_MU_CTRL_LATENCY = 0x05,
} audio_mixer_control_selector_t;
/// A.17.6 - Selector Control Selectors
typedef enum
{
AUDIO_SU_CTRL_UNDEF = 0x00,
AUDIO_SU_CTRL_SELECTOR = 0x01,
AUDIO_SU_CTRL_LATENCY = 0x02,
} audio_sel_control_selector_t;
/// A.17.7 - Feature Unit Control Selectors
typedef enum
{
AUDIO_FU_CTRL_UNDEF = 0x00,
AUDIO_FU_CTRL_MUTE = 0x01,
AUDIO_FU_CTRL_VOLUME = 0x02,
AUDIO_FU_CTRL_BASS = 0x03,
AUDIO_FU_CTRL_MID = 0x04,
AUDIO_FU_CTRL_TREBLE = 0x05,
AUDIO_FU_CTRL_GRAPHIC_EQUALIZER = 0x06,
AUDIO_FU_CTRL_AGC = 0x07,
AUDIO_FU_CTRL_DELAY = 0x08,
AUDIO_FU_CTRL_BASS_BOOST = 0x09,
AUDIO_FU_CTRL_LOUDNESS = 0x0A,
AUDIO_FU_CTRL_INPUT_GAIN = 0x0B,
AUDIO_FU_CTRL_GAIN_PAD = 0x0C,
AUDIO_FU_CTRL_INVERTER = 0x0D,
AUDIO_FU_CTRL_UNDERFLOW = 0x0E,
AUDIO_FU_CTRL_OVERVLOW = 0x0F,
AUDIO_FU_CTRL_LATENCY = 0x10,
} audio_feature_unit_control_selector_t;
/// A.17.8 Effect Unit Control Selectors
/// A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors
typedef enum
{
AUDIO_PE_CTRL_UNDEF = 0x00,
AUDIO_PE_CTRL_ENABLE = 0x01,
AUDIO_PE_CTRL_CENTERFREQ = 0x02,
AUDIO_PE_CTRL_QFACTOR = 0x03,
AUDIO_PE_CTRL_GAIN = 0x04,
AUDIO_PE_CTRL_UNDERFLOW = 0x05,
AUDIO_PE_CTRL_OVERFLOW = 0x06,
AUDIO_PE_CTRL_LATENCY = 0x07,
} audio_parametric_equalizer_control_selector_t;
/// A.17.8.2 Reverberation Effect Unit Control Selectors
typedef enum
{
AUDIO_RV_CTRL_UNDEF = 0x00,
AUDIO_RV_CTRL_ENABLE = 0x01,
AUDIO_RV_CTRL_TYPE = 0x02,
AUDIO_RV_CTRL_LEVEL = 0x03,
AUDIO_RV_CTRL_TIME = 0x04,
AUDIO_RV_CTRL_FEEDBACK = 0x05,
AUDIO_RV_CTRL_PREDELAY = 0x06,
AUDIO_RV_CTRL_DENSITY = 0x07,
AUDIO_RV_CTRL_HIFREQ_ROLLOFF = 0x08,
AUDIO_RV_CTRL_UNDERFLOW = 0x09,
AUDIO_RV_CTRL_OVERFLOW = 0x0A,
AUDIO_RV_CTRL_LATENCY = 0x0B,
} audio_reverberation_effect_control_selector_t;
/// A.17.8.3 Modulation Delay Effect Unit Control Selectors
typedef enum
{
AUDIO_MD_CTRL_UNDEF = 0x00,
AUDIO_MD_CTRL_ENABLE = 0x01,
AUDIO_MD_CTRL_BALANCE = 0x02,
AUDIO_MD_CTRL_RATE = 0x03,
AUDIO_MD_CTRL_DEPTH = 0x04,
AUDIO_MD_CTRL_TIME = 0x05,
AUDIO_MD_CTRL_FEEDBACK = 0x06,
AUDIO_MD_CTRL_UNDERFLOW = 0x07,
AUDIO_MD_CTRL_OVERFLOW = 0x08,
AUDIO_MD_CTRL_LATENCY = 0x09,
} audio_modulation_delay_control_selector_t;
/// A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors
typedef enum
{
AUDIO_DR_CTRL_UNDEF = 0x00,
AUDIO_DR_CTRL_ENABLE = 0x01,
AUDIO_DR_CTRL_COMPRESSION_RATE = 0x02,
AUDIO_DR_CTRL_MAXAMPL = 0x03,
AUDIO_DR_CTRL_THRESHOLD = 0x04,
AUDIO_DR_CTRL_ATTACK_TIME = 0x05,
AUDIO_DR_CTRL_RELEASE_TIME = 0x06,
AUDIO_DR_CTRL_UNDERFLOW = 0x07,
AUDIO_DR_CTRL_OVERFLOW = 0x08,
AUDIO_DR_CTRL_LATENCY = 0x09,
} audio_dynamic_range_compression_control_selector_t;
/// A.17.9 Processing Unit Control Selectors
/// A.17.9.1 Up/Down-mix Processing Unit Control Selectors
typedef enum
{
AUDIO_UD_CTRL_UNDEF = 0x00,
AUDIO_UD_CTRL_ENABLE = 0x01,
AUDIO_UD_CTRL_MODE_SELECT = 0x02,
AUDIO_UD_CTRL_CLUSTER = 0x03,
AUDIO_UD_CTRL_UNDERFLOW = 0x04,
AUDIO_UD_CTRL_OVERFLOW = 0x05,
AUDIO_UD_CTRL_LATENCY = 0x06,
} audio_up_down_mix_control_selector_t;
/// A.17.9.2 Dolby Prologic ™ Processing Unit Control Selectors
typedef enum
{
AUDIO_DP_CTRL_UNDEF = 0x00,
AUDIO_DP_CTRL_ENABLE = 0x01,
AUDIO_DP_CTRL_MODE_SELECT = 0x02,
AUDIO_DP_CTRL_CLUSTER = 0x03,
AUDIO_DP_CTRL_UNDERFLOW = 0x04,
AUDIO_DP_CTRL_OVERFLOW = 0x05,
AUDIO_DP_CTRL_LATENCY = 0x06,
} audio_dolby_prologic_control_selector_t;
/// A.17.9.3 Stereo Extender Processing Unit Control Selectors
typedef enum
{
AUDIO_ST_EXT_CTRL_UNDEF = 0x00,
AUDIO_ST_EXT_CTRL_ENABLE = 0x01,
AUDIO_ST_EXT_CTRL_WIDTH = 0x02,
AUDIO_ST_EXT_CTRL_UNDERFLOW = 0x03,
AUDIO_ST_EXT_CTRL_OVERFLOW = 0x04,
AUDIO_ST_EXT_CTRL_LATENCY = 0x05,
} audio_stereo_extender_control_selector_t;
/// A.17.10 Extension Unit Control Selectors
typedef enum
{
AUDIO_XU_CTRL_UNDEF = 0x00,
AUDIO_XU_CTRL_ENABLE = 0x01,
AUDIO_XU_CTRL_CLUSTER = 0x02,
AUDIO_XU_CTRL_UNDERFLOW = 0x03,
AUDIO_XU_CTRL_OVERFLOW = 0x04,
AUDIO_XU_CTRL_LATENCY = 0x05,
} audio_extension_unit_control_selector_t;
/// A.17.11 AudioStreaming Interface Control Selectors
typedef enum
{
AUDIO_AS_CTRL_UNDEF = 0x00,
AUDIO_AS_CTRL_ACT_ALT_SETTING = 0x01,
AUDIO_AS_CTRL_VAL_ALT_SETTINGS = 0x02,
AUDIO_AS_CTRL_AUDIO_DATA_FORMAT = 0x03,
} audio_audiostreaming_interface_control_selector_t;
/// A.17.12 Encoder Control Selectors
typedef enum
{
AUDIO_EN_CTRL_UNDEF = 0x00,
AUDIO_EN_CTRL_BIT_RATE = 0x01,
AUDIO_EN_CTRL_QUALITY = 0x02,
AUDIO_EN_CTRL_VBR = 0x03,
AUDIO_EN_CTRL_TYPE = 0x04,
AUDIO_EN_CTRL_UNDERFLOW = 0x05,
AUDIO_EN_CTRL_OVERFLOW = 0x06,
AUDIO_EN_CTRL_ENCODER_ERROR = 0x07,
AUDIO_EN_CTRL_PARAM1 = 0x08,
AUDIO_EN_CTRL_PARAM2 = 0x09,
AUDIO_EN_CTRL_PARAM3 = 0x0A,
AUDIO_EN_CTRL_PARAM4 = 0x0B,
AUDIO_EN_CTRL_PARAM5 = 0x0C,
AUDIO_EN_CTRL_PARAM6 = 0x0D,
AUDIO_EN_CTRL_PARAM7 = 0x0E,
AUDIO_EN_CTRL_PARAM8 = 0x0F,
} audio_encoder_control_selector_t;
/// A.17.13 Decoder Control Selectors
/// A.17.13.1 MPEG Decoder Control Selectors
typedef enum
{
AUDIO_MPD_CTRL_UNDEF = 0x00,
AUDIO_MPD_CTRL_DUAL_CHANNEL = 0x01,
AUDIO_MPD_CTRL_SECOND_STEREO = 0x02,
AUDIO_MPD_CTRL_MULTILINGUAL = 0x03,
AUDIO_MPD_CTRL_DYN_RANGE = 0x04,
AUDIO_MPD_CTRL_SCALING = 0x05,
AUDIO_MPD_CTRL_HILO_SCALING = 0x06,
AUDIO_MPD_CTRL_UNDERFLOW = 0x07,
AUDIO_MPD_CTRL_OVERFLOW = 0x08,
AUDIO_MPD_CTRL_DECODER_ERROR = 0x09,
} audio_MPEG_decoder_control_selector_t;
/// A.17.13.2 AC-3 Decoder Control Selectors
typedef enum
{
AUDIO_AD_CTRL_UNDEF = 0x00,
AUDIO_AD_CTRL_MODE = 0x01,
AUDIO_AD_CTRL_DYN_RANGE = 0x02,
AUDIO_AD_CTRL_SCALING = 0x03,
AUDIO_AD_CTRL_HILO_SCALING = 0x04,
AUDIO_AD_CTRL_UNDERFLOW = 0x05,
AUDIO_AD_CTRL_OVERFLOW = 0x06,
AUDIO_AD_CTRL_DECODER_ERROR = 0x07,
} audio_AC3_decoder_control_selector_t;
/// A.17.13.3 WMA Decoder Control Selectors
typedef enum
{
AUDIO_WD_CTRL_UNDEF = 0x00,
AUDIO_WD_CTRL_UNDERFLOW = 0x01,
AUDIO_WD_CTRL_OVERFLOW = 0x02,
AUDIO_WD_CTRL_DECODER_ERROR = 0x03,
} audio_WMA_decoder_control_selector_t;
/// A.17.13.4 DTS Decoder Control Selectors
typedef enum
{
AUDIO_DD_CTRL_UNDEF = 0x00,
AUDIO_DD_CTRL_UNDERFLOW = 0x01,
AUDIO_DD_CTRL_OVERFLOW = 0x02,
AUDIO_DD_CTRL_DECODER_ERROR = 0x03,
} audio_DTS_decoder_control_selector_t;
/// A.17.14 Endpoint Control Selectors
typedef enum
{
AUDIO_EP_CTRL_UNDEF = 0x00,
AUDIO_EP_CTRL_PITCH = 0x01,
AUDIO_EP_CTRL_DATA_OVERRUN = 0x02,
AUDIO_EP_CTRL_DATA_UNDERRUN = 0x03,
} audio_EP_control_selector_t;
/// Terminal Types
/// 2.1 - Audio Class-Terminal Types UAC2
typedef enum
{
AUDIO_TERM_TYPE_USB_UNDEFINED = 0x0100,
AUDIO_TERM_TYPE_USB_STREAMING = 0x0101,
AUDIO_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF,
} audio_terminal_type_t;
/// 2.2 - Audio Class-Input Terminal Types UAC2
typedef enum
{
AUDIO_TERM_TYPE_IN_UNDEFINED = 0x0200,
AUDIO_TERM_TYPE_IN_GENERIC_MIC = 0x0201,
AUDIO_TERM_TYPE_IN_DESKTOP_MIC = 0x0202,
AUDIO_TERM_TYPE_IN_PERSONAL_MIC = 0x0203,
AUDIO_TERM_TYPE_IN_OMNI_MIC = 0x0204,
AUDIO_TERM_TYPE_IN_ARRAY_MIC = 0x0205,
AUDIO_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206,
} audio_terminal_input_type_t;
/// 2.3 - Audio Class-Output Terminal Types UAC2
typedef enum
{
AUDIO_TERM_TYPE_OUT_UNDEFINED = 0x0300,
AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301,
AUDIO_TERM_TYPE_OUT_HEADPHONES = 0x0302,
AUDIO_TERM_TYPE_OUT_HEAD_MNT_DISP_AUIDO = 0x0303,
AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER = 0x0304,
AUDIO_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305,
AUDIO_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306,
AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307,
} audio_terminal_output_type_t;
/// Rest is yet to be implemented
/// Additional Audio Device Class Codes - Source: Audio Data Formats
/// A.1 - Audio Class-Format Type Codes UAC2
//typedef enum
//{
// AUDIO_FORMAT_TYPE_UNDEFINED = 0x00,
// AUDIO_FORMAT_TYPE_I = 0x01,
// AUDIO_FORMAT_TYPE_II = 0x02,
// AUDIO_FORMAT_TYPE_III = 0x03,
// AUDIO_FORMAT_TYPE_IV = 0x04,
// AUDIO_EXT_FORMAT_TYPE_I = 0x81,
// AUDIO_EXT_FORMAT_TYPE_II = 0x82,
// AUDIO_EXT_FORMAT_TYPE_III = 0x83,
//} audio_format_type_t;
#define AUDIO_FORMAT_TYPE_UNDEFINED 0x00
#define AUDIO_FORMAT_TYPE_I 0x01
#define AUDIO_FORMAT_TYPE_II 0x02
#define AUDIO_FORMAT_TYPE_III 0x03
#define AUDIO_FORMAT_TYPE_IV 0x04
#define AUDIO_EXT_FORMAT_TYPE_I 0x81
#define AUDIO_EXT_FORMAT_TYPE_II 0x82
#define AUDIO_EXT_FORMAT_TYPE_III 0x83
/// A.2.1 - Audio Class-Audio Data Format Type I UAC2
//typedef enum
//{
// AUDIO_DATA_FORMAT_TYPE_I_PCM = (uint32_t) (1 << 0),
// AUDIO_DATA_FORMAT_TYPE_I_PCM8 = (uint32_t) (1 << 1),
// AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2),
// AUDIO_DATA_FORMAT_TYPE_I_ALAW = (uint32_t) (1 << 3),
// AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4),
// AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = 0x100000000,
//} audio_data_format_type_I_t;
#define AUDIO_DATA_FORMAT_TYPE_I_PCM ((uint32_t) (1 << 0))
#define AUDIO_DATA_FORMAT_TYPE_I_PCM8 ((uint32_t) (1 << 1))
#define AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT ((uint32_t) (1 << 2))
#define AUDIO_DATA_FORMAT_TYPE_I_ALAW ((uint32_t) (1 << 3))
#define AUDIO_DATA_FORMAT_TYPE_I_MULAW ((uint32_t) (1 << 4))
#define AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA 0x100000000
/// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification
/// Isochronous End Point Attributes
typedef enum
{
TUSB_ISO_EP_ATT_NO_SYNC = 0x00,
TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04,
TUSB_ISO_EP_ATT_ADAPTIVE = 0x08,
TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C,
TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point
TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point
TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback
} tusb_iso_ep_attribute_t;
/// Audio Class-Control Values UAC2
typedef enum
{
AUDIO_CTRL_NONE = 0x00, ///< No Host access
AUDIO_CTRL_R = 0x01, ///< Host read access only
AUDIO_CTRL_RW = 0x03, ///< Host read write access
} audio_control_t;
/// Audio Class-Specific AC Interface Descriptor Controls UAC2
typedef enum
{
AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0,
} audio_cs_ac_interface_control_pos_t;
/// Audio Class-Specific AS Interface Descriptor Controls UAC2
typedef enum
{
AUDIO_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0,
AUDIO_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2,
} audio_cs_as_interface_control_pos_t;
/// Audio Class-Specific AS Isochronous Data EP Attributes UAC2
typedef enum
{
AUDIO_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80,
AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK = 0x00,
} audio_cs_as_iso_data_ep_attribute_t;
/// Audio Class-Specific AS Isochronous Data EP Controls UAC2
typedef enum
{
AUDIO_CS_AS_ISO_DATA_EP_CTRL_PITCH_POS = 0,
AUDIO_CS_AS_ISO_DATA_EP_CTRL_DATA_OVERRUN_POS = 2,
AUDIO_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4,
} audio_cs_as_iso_data_ep_control_pos_t;
/// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC2
typedef enum
{
AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00,
AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_MILLISEC = 0x01,
AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02,
} audio_cs_as_iso_data_ep_lock_delay_unit_t;
/// Audio Class-Clock Source Attributes UAC2
typedef enum
{
AUDIO_CLOCK_SOURCE_ATT_EXT_CLK = 0x00,
AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01,
AUDIO_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02,
AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03,
AUDIO_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04,
} audio_clock_source_attribute_t;
/// Audio Class-Clock Source Controls UAC2
typedef enum
{
AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0,
AUDIO_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2,
} audio_clock_source_control_pos_t;
/// Audio Class-Clock Selector Controls UAC2
typedef enum
{
AUDIO_CLOCK_SELECTOR_CTRL_POS = 0,
} audio_clock_selector_control_pos_t;
/// Audio Class-Clock Multiplier Controls UAC2
typedef enum
{
AUDIO_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0,
AUDIO_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2,
} audio_clock_multiplier_control_pos_t;
/// Audio Class-Input Terminal Controls UAC2
typedef enum
{
AUDIO_IN_TERM_CTRL_CPY_PROT_POS = 0,
AUDIO_IN_TERM_CTRL_CONNECTOR_POS = 2,
AUDIO_IN_TERM_CTRL_OVERLOAD_POS = 4,
AUDIO_IN_TERM_CTRL_CLUSTER_POS = 6,
AUDIO_IN_TERM_CTRL_UNDERFLOW_POS = 8,
AUDIO_IN_TERM_CTRL_OVERFLOW_POS = 10,
} audio_terminal_input_control_pos_t;
/// Audio Class-Output Terminal Controls UAC2
typedef enum
{
AUDIO_OUT_TERM_CTRL_CPY_PROT_POS = 0,
AUDIO_OUT_TERM_CTRL_CONNECTOR_POS = 2,
AUDIO_OUT_TERM_CTRL_OVERLOAD_POS = 4,
AUDIO_OUT_TERM_CTRL_UNDERFLOW_POS = 6,
AUDIO_OUT_TERM_CTRL_OVERFLOW_POS = 8,
} audio_terminal_output_control_pos_t;
/// Audio Class-Feature Unit Controls UAC2
typedef enum
{
AUDIO_FEATURE_UNIT_CTRL_MUTE_POS = 0,
AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS = 2,
AUDIO_FEATURE_UNIT_CTRL_BASS_POS = 4,
AUDIO_FEATURE_UNIT_CTRL_MID_POS = 6,
AUDIO_FEATURE_UNIT_CTRL_TREBLE_POS = 8,
AUDIO_FEATURE_UNIT_CTRL_GRAPHIC_EQU_POS = 10,
AUDIO_FEATURE_UNIT_CTRL_AGC_POS = 12,
AUDIO_FEATURE_UNIT_CTRL_DELAY_POS = 14,
AUDIO_FEATURE_UNIT_CTRL_BASS_BOOST_POS = 16,
AUDIO_FEATURE_UNIT_CTRL_LOUDNESS_POS = 18,
AUDIO_FEATURE_UNIT_CTRL_INPUT_GAIN_POS = 20,
AUDIO_FEATURE_UNIT_CTRL_INPUT_GAIN_PAD_POS = 22,
AUDIO_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24,
AUDIO_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26,
AUDIO_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28,
} audio_feature_unit_control_pos_t;
/// Audio Class-Audio Channel Configuration UAC2
typedef enum
{
AUDIO_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000,
AUDIO_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001,
AUDIO_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002,
AUDIO_CHANNEL_CONFIG_FRONT_CENTER = 0x00000004,
AUDIO_CHANNEL_CONFIG_LOW_FRQ_EFFECTS = 0x00000008,
AUDIO_CHANNEL_CONFIG_BACK_LEFT = 0x00000010,
AUDIO_CHANNEL_CONFIG_BACK_RIGHT = 0x00000020,
AUDIO_CHANNEL_CONFIG_FRONT_LEFT_OF_CENTER = 0x00000040,
AUDIO_CHANNEL_CONFIG_FRONT_RIGHT_OF_CENTER = 0x00000080,
AUDIO_CHANNEL_CONFIG_BACK_CENTER = 0x00000100,
AUDIO_CHANNEL_CONFIG_SIDE_LEFT = 0x00000200,
AUDIO_CHANNEL_CONFIG_SIDE_RIGHT = 0x00000400,
AUDIO_CHANNEL_CONFIG_TOP_CENTER = 0x00000800,
AUDIO_CHANNEL_CONFIG_TOP_FRONT_LEFT = 0x00001000,
AUDIO_CHANNEL_CONFIG_TOP_FRONT_CENTER = 0x00002000,
AUDIO_CHANNEL_CONFIG_TOP_FRONT_RIGHT = 0x00004000,
AUDIO_CHANNEL_CONFIG_TOP_BACK_LEFT = 0x00008000,
AUDIO_CHANNEL_CONFIG_TOP_BACK_CENTER = 0x00010000,
AUDIO_CHANNEL_CONFIG_TOP_BACK_RIGHT = 0x00020000,
AUDIO_CHANNEL_CONFIG_TOP_FRONT_LEFT_OF_CENTER = 0x00040000,
AUDIO_CHANNEL_CONFIG_TOP_FRONT_RIGHT_OF_CENTER = 0x00080000,
AUDIO_CHANNEL_CONFIG_LEFT_LOW_FRQ_EFFECTS = 0x00100000,
AUDIO_CHANNEL_CONFIG_RIGHT_LOW_FRQ_EFFECTS = 0x00200000,
AUDIO_CHANNEL_CONFIG_TOP_SIDE_LEFT = 0x00400000,
AUDIO_CHANNEL_CONFIG_TOP_SIDE_RIGHT = 0x00800000,
AUDIO_CHANNEL_CONFIG_BOTTOM_CENTER = 0x01000000,
AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000,
AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000,
AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000,
} audio_channel_config_t;
/// AUDIO Channel Cluster Descriptor (4.1)
typedef struct TU_ATTR_PACKED {
uint8_t bNrChannels; ///< Number of channels currently connected.
audio_channel_config_t bmChannelConfig; ///< Bitmap according to 'audio_channel_config_t' with a 1 set if channel is connected and 0 else. In case channels are non-predefined ignore them here (see UAC2 specification 4.1 Audio Channel Cluster Descriptor.
uint8_t iChannelNames; ///< Index of a string descriptor, describing the name of the first inserted channel with a non-predefined spatial location.
} audio_desc_channel_cluster_t;
/// AUDIO Class-Specific AC Interface Header Descriptor (4.7.2)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes: 9.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_HEADER.
uint16_t bcdADC ; ///< Audio Device Class Specification Release Number in Binary-Coded Decimal. Value: U16_TO_U8S_LE(0x0200).
uint8_t bCategory ; ///< Constant, indicating the primary use of this audio function, as intended by the manufacturer. See: audio_function_t.
uint16_t wTotalLength ; ///< Total number of bytes returned for the class-specific AudioControl interface descriptor. Includes the combined length of this descriptor header and all Clock Source, Unit and Terminal descriptors.
uint8_t bmControls ; ///< See: audio_cs_ac_interface_control_pos_t.
} audio_desc_cs_ac_interface_t;
/// AUDIO Clock Source Descriptor (4.7.2.1)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes: 8.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE.
uint8_t bClockID ; ///< Constant uniquely identifying the Clock Source Entity within the audio function. This value is used in all requests to address this Entity.
uint8_t bmAttributes ; ///< See: audio_clock_source_attribute_t.
uint8_t bmControls ; ///< See: audio_clock_source_control_pos_t.
uint8_t bAssocTerminal ; ///< Terminal ID of the Terminal that is associated with this Clock Source.
uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Source Entity.
} audio_desc_clock_source_t;
/// AUDIO Clock Selector Descriptor (4.7.2.2) for ONE pin
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 7+p.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR.
uint8_t bClockID ; ///< Constant uniquely identifying the Clock Selector Entity within the audio function. This value is used in all requests to address this Entity.
uint8_t bNrInPins ; ///< Number of Input Pins of this Unit: p = 1 thus bNrInPins = 1.
uint8_t baCSourceID ; ///< ID of the Clock Entity to which the first Clock Input Pin of this Clock Selector Entity is connected..
uint8_t bmControls ; ///< See: audio_clock_selector_control_pos_t.
uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Selector Entity.
} audio_desc_clock_selector_t;
/// AUDIO Clock Selector Descriptor (4.7.2.2) for multiple pins
#define audio_desc_clock_selector_n_t(source_num) \
struct TU_ATTR_PACKED { \
uint8_t bLength ; \
uint8_t bDescriptorType ; \
uint8_t bDescriptorSubType ; \
uint8_t bClockID ; \
uint8_t bNrInPins ; \
struct TU_ATTR_PACKED { \
uint8_t baSourceID ; \
} sourceID[source_num] ; \
uint8_t bmControls ; \
uint8_t iClockSource ; \
}
/// AUDIO Clock Multiplier Descriptor (4.7.2.3)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 7.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER.
uint8_t bClockID ; ///< Constant uniquely identifying the Clock Multiplier Entity within the audio function. This value is used in all requests to address this Entity.
uint8_t bCSourceID ; ///< ID of the Clock Entity to which the last Clock Input Pin of this Clock Selector Entity is connected.
uint8_t bmControls ; ///< See: audio_clock_multiplier_control_pos_t.
uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Multiplier Entity.
} audio_desc_clock_multiplier_t;
/// AUDIO Input Terminal Descriptor(4.7.2.4)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 17.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL.
uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_input_type_t for other input types.
uint8_t bAssocTerminal ; ///< ID of the Output Terminal to which this Input Terminal is associated.
uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Input Terminal is connected.
uint8_t bNrChannels ; ///< Number of logical output channels in the Terminals output audio channel cluster.
uint32_t bmChannelConfig ; ///< Describes the spatial location of the logical channels. See:audio_channel_config_t.
uint16_t bmControls ; ///< See: audio_terminal_input_control_pos_t.
uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal.
} audio_desc_input_terminal_t;
/// AUDIO Output Terminal Descriptor(4.7.2.5)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 12.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL.
uint8_t bTerminalID ; ///< Constant uniquely identifying the Terminal within the audio function. This value is used in all requests to address this Terminal.
uint16_t wTerminalType ; ///< Constant characterizing the type of Terminal. See: audio_terminal_type_t for USB streaming and audio_terminal_output_type_t for other output types.
uint8_t bAssocTerminal ; ///< Constant, identifying the Input Terminal to which this Output Terminal is associated.
uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Terminal is connected.
uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Output Terminal is connected.
uint16_t bmControls ; ///< See: audio_terminal_output_type_t.
uint8_t iTerminal ; ///< Index of a string descriptor, describing the Output Terminal.
} audio_desc_output_terminal_t;
/// AUDIO Feature Unit Descriptor(4.7.2.8) for ONE channel
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 14.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_FEATURE_UNIT.
uint8_t bUnitID ; ///< Constant uniquely identifying the Unit within the audio function. This value is used in all requests to address this Unit.
uint8_t bSourceID ; ///< ID of the Unit or Terminal to which this Feature Unit is connected.
struct TU_ATTR_PACKED {
uint32_t bmaControls ; ///< See: audio_feature_unit_control_pos_t. Controls0 is master channel 0 (always present) and Controls1 is logical channel 1.
} controls[2] ;
uint8_t iTerminal ; ///< Index of a string descriptor, describing this Feature Unit.
} audio_desc_feature_unit_t;
/// AUDIO Feature Unit Descriptor(4.7.2.8) for multiple channels
#define audio_desc_feature_unit_n_t(ch_num)\
struct TU_ATTR_PACKED { \
uint8_t bLength ; /* 6+(ch_num+1)*4 */\
uint8_t bDescriptorType ; \
uint8_t bDescriptorSubType ; \
uint8_t bUnitID ; \
uint8_t bSourceID ; \
struct TU_ATTR_PACKED { \
uint32_t bmaControls ; \
} controls[ch_num+1] ; \
uint8_t iTerminal ; \
}
/// AUDIO Class-Specific AS Interface Descriptor(4.9.2)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 16.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AS_INTERFACE_AS_GENERAL.
uint8_t bTerminalLink ; ///< The Terminal ID of the Terminal to which this interface is connected.
uint8_t bmControls ; ///< See: audio_cs_as_interface_control_pos_t.
uint8_t bFormatType ; ///< Constant identifying the Format Type the AudioStreaming interface is using. See: audio_format_type_t.
uint32_t bmFormats ; ///< The Audio Data Format(s) that can be used to communicate with this interface.See: audio_data_format_type_I_t.
uint8_t bNrChannels ; ///< Number of physical channels in the AS Interface audio channel cluster.
uint32_t bmChannelConfig ; ///< Describes the spatial location of the physical channels. See: audio_channel_config_t.
uint8_t iChannelNames ; ///< Index of a string descriptor, describing the name of the first physical channel.
} audio_desc_cs_as_interface_t;
/// AUDIO Type I Format Type Descriptor(2.3.1.6 - Audio Formats)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 6.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AS_INTERFACE_FORMAT_TYPE.
uint8_t bFormatType ; ///< Constant identifying the Format Type the AudioStreaming interface is using. Value: AUDIO_FORMAT_TYPE_I.
uint8_t bSubslotSize ; ///< The number of bytes occupied by one audio subslot. Can be 1, 2, 3 or 4.
uint8_t bBitResolution ; ///< The number of effectively used bits from the available bits in an audio subslot.
} audio_desc_type_I_format_t;
/// AUDIO Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor, in bytes: 8.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_ENDPOINT.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_EP_SUBTYPE_GENERAL.
uint8_t bmAttributes ; ///< See: audio_cs_as_iso_data_ep_attribute_t.
uint8_t bmControls ; ///< See: audio_cs_as_iso_data_ep_control_pos_t.
uint8_t bLockDelayUnits ; ///< Indicates the units used for the wLockDelay field. See: audio_cs_as_iso_data_ep_lock_delay_unit_t.
uint16_t wLockDelay ; ///< Indicates the time it takes this endpoint to reliably lock its internal clock recovery circuitry. Units used depend on the value of the bLockDelayUnits field.
} audio_desc_cs_as_iso_data_ep_t;
//// 5.2.3 Control Request Parameter Block Layout
// 5.2.3.1 1-byte Control CUR Parameter Block
typedef struct TU_ATTR_PACKED
{
int8_t bCur ; ///< The setting for the CUR attribute of the addressed Control
} audio_control_cur_1_t;
// 5.2.3.2 2-byte Control CUR Parameter Block
typedef struct TU_ATTR_PACKED
{
int16_t bCur ; ///< The setting for the CUR attribute of the addressed Control
} audio_control_cur_2_t;
// 5.2.3.3 4-byte Control CUR Parameter Block
typedef struct TU_ATTR_PACKED
{
int32_t bCur ; ///< The setting for the CUR attribute of the addressed Control
} audio_control_cur_4_t;
// Use the following ONLY for RECEIVED data - compiler does not know how many subranges are defined! Use the one below for predefined lengths - or if you know what you are doing do what you like
// 5.2.3.1 1-byte Control RANGE Parameter Block
typedef struct TU_ATTR_PACKED {
uint16_t wNumSubRanges;
struct TU_ATTR_PACKED {
int8_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/
int8_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/
uint8_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/
} subrange[] ;
} audio_control_range_1_t;
// 5.2.3.2 2-byte Control RANGE Parameter Block
typedef struct TU_ATTR_PACKED {
uint16_t wNumSubRanges;
struct TU_ATTR_PACKED {
int16_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/
int16_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/
uint16_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/
} subrange[] ;
} audio_control_range_2_t;
// 5.2.3.3 4-byte Control RANGE Parameter Block
typedef struct TU_ATTR_PACKED {
uint16_t wNumSubRanges;
struct TU_ATTR_PACKED {
int32_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/
int32_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/
uint32_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/
} subrange[] ;
} audio_control_range_4_t;
// 5.2.3.1 1-byte Control RANGE Parameter Block
#define audio_control_range_1_n_t(numSubRanges) \
struct TU_ATTR_PACKED { \
uint16_t wNumSubRanges; \
struct TU_ATTR_PACKED { \
int8_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\
int8_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\
uint8_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\
} subrange[numSubRanges] ; \
}
/// 5.2.3.2 2-byte Control RANGE Parameter Block
#define audio_control_range_2_n_t(numSubRanges) \
struct TU_ATTR_PACKED { \
uint16_t wNumSubRanges; \
struct TU_ATTR_PACKED { \
int16_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\
int16_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\
uint16_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\
} subrange[numSubRanges]; \
}
// 5.2.3.3 4-byte Control RANGE Parameter Block
#define audio_control_range_4_n_t(numSubRanges) \
struct TU_ATTR_PACKED { \
uint16_t wNumSubRanges; \
struct TU_ATTR_PACKED { \
int32_t bMin ; /*The setting for the MIN attribute of the nth subrange of the addressed Control*/\
int32_t bMax ; /*The setting for the MAX attribute of the nth subrange of the addressed Control*/\
uint32_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\
} subrange[numSubRanges]; \
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/** @} */

View File

@ -0,0 +1,400 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ha Thach (tinyusb.org)
* Copyright (c) 2020 Reinhard Panhuber
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_AUDIO_DEVICE_H_
#define _TUSB_AUDIO_DEVICE_H_
#include "assert.h"
#include "common/tusb_common.h"
#include "device/usbd.h"
#include "audio.h"
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
// Number of Standard AS Interface Descriptors (4.9.1) defined per audio function - this is required to be able to remember the current alternate settings of these interfaces - We restrict us here to have a constant number for all audio functions (which means this has to be the maximum number of AS interfaces an audio function has and a second audio function with less AS interfaces just waste a few bytes)
#ifndef CFG_TUD_AUDIO_N_AS_INT
#define CFG_TUD_AUDIO_N_AS_INT 0
#endif
// Size of control buffer used to receive and send control messages via EP0 - has to be big enough to hold your biggest request structure e.g. range requests with multiple intervals defined or cluster descriptors
#ifndef CFG_TUD_AUDIO_CTRL_BUF_SIZE
#error You must define an audio class control request buffer size!
#endif
// Use of TX/RX FIFOs - If sizes are not zero, audio.c implements FIFOs for RX and TX (whatever defined).
// For RX: the input stream gets decoded into its corresponding channels, where for each channel a FIFO is setup to hold its data -> see: audio_rx_done_cb().
// For TX: the output stream is composed from CFG_TUD_AUDIO_N_CHANNELS_TX channels, where for each channel a FIFO is defined.
// Further, it implements encoding and decoding of the individual channels (parameterized by the defines below).
// If you don't use the FIFOs you need to handle encoding and decoding on your own in audio_rx_done_cb() and audio_tx_done_cb(). This, however, allows for optimizations.
#ifndef CFG_TUD_AUDIO_TX_FIFO_SIZE
#define CFG_TUD_AUDIO_TX_FIFO_SIZE 0 // Buffer size per channel
#endif
#ifndef CFG_TUD_AUDIO_RX_FIFO_SIZE
#define CFG_TUD_AUDIO_RX_FIFO_SIZE 0 // Buffer size per channel
#endif
// End point sizes - Limits: Full Speed <= 1023, High Speed <= 1024
#ifndef CFG_TUD_AUDIO_EPSIZE_IN
#define CFG_TUD_AUDIO_EPSIZE_IN 0 // TX
#endif
#ifndef CFG_TUD_AUDIO_EPSIZE_OUT
#define CFG_TUD_AUDIO_EPSIZE_OUT 0 // RX
#endif
#ifndef CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
#define CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP 0 // Feedback
#endif
#ifndef CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
#define CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN 0 // Audio interrupt control
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
#ifndef CFG_TUD_AUDIO_INT_CTR_BUFSIZE
#define CFG_TUD_AUDIO_INT_CTR_BUFSIZE 6 // Buffer size of audio control interrupt EP - 6 Bytes according to UAC 2 specification (p. 74)
#endif
#endif
#ifndef CFG_TUD_AUDIO_N_CHANNELS_TX
#define CFG_TUD_AUDIO_N_CHANNELS_TX 1
#endif
#ifndef CFG_TUD_AUDIO_N_CHANNELS_RX
#define CFG_TUD_AUDIO_N_CHANNELS_RX 1
#endif
// Audio data format types
#ifndef CFG_TUD_AUDIO_FORMAT_TYPE_TX
#define CFG_TUD_AUDIO_FORMAT_TYPE_TX AUDIO_FORMAT_TYPE_UNDEFINED // If this option is used, an encoding function has to be implemented in audio_device.c
#endif
#ifndef CFG_TUD_AUDIO_FORMAT_TYPE_RX
#define CFG_TUD_AUDIO_FORMAT_TYPE_RX AUDIO_FORMAT_TYPE_UNDEFINED // If this option is used, a decoding function has to be implemented in audio_device.c
#endif
// Audio data format type I specifications
#if CFG_TUD_AUDIO_FORMAT_TYPE_TX == AUDIO_FORMAT_TYPE_I
// Type definitions - for possible formats see: audio_data_format_type_I_t and further in UAC2 specifications.
#ifndef CFG_TUD_AUDIO_FORMAT_TYPE_I_TX
#define CFG_TUD_AUDIO_FORMAT_TYPE_I_TX AUDIO_DATA_FORMAT_TYPE_I_PCM
#endif
#ifndef CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX // bSubslotSize
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 1
#endif
#ifndef CFG_TUD_AUDIO_TX_ITEMSIZE
#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == 1
#define CFG_TUD_AUDIO_TX_ITEMSIZE 1
#elif CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX == 2
#define CFG_TUD_AUDIO_TX_ITEMSIZE 2
#else
#define CFG_TUD_AUDIO_TX_ITEMSIZE 4
#endif
#endif
#if CFG_TUD_AUDIO_TX_ITEMSIZE < CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX
#error FIFO element size (ITEMSIZE) must not be smaller then sample size
#endif
#endif
#if CFG_TUD_AUDIO_FORMAT_TYPE_RX == AUDIO_FORMAT_TYPE_I
#ifndef CFG_TUD_AUDIO_FORMAT_TYPE_I_RX
#define CFG_TUD_AUDIO_FORMAT_TYPE_I_RX AUDIO_DATA_FORMAT_TYPE_I_PCM
#endif
#ifndef CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX // bSubslotSize
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX 1
#endif
#if CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX == 1
#define CFG_TUD_AUDIO_RX_ITEMSIZE 1
#elif CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_RX == 2
#define CFG_TUD_AUDIO_RX_ITEMSIZE 2
#else
#define CFG_TUD_AUDIO_RX_ITEMSIZE 4
#endif
#endif
//static_assert(sizeof(tud_audio_desc_lengths) != CFG_TUD_AUDIO, "Supply audio function descriptor pack length!");
// Supported types of this driver:
// AUDIO_DATA_FORMAT_TYPE_I_PCM - Required definitions: CFG_TUD_AUDIO_N_CHANNELS and CFG_TUD_AUDIO_BYTES_PER_CHANNEL
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup AUDIO_Serial Serial
* @{
* \defgroup AUDIO_Serial_Device Device
* @{ */
//--------------------------------------------------------------------+
// Application API (Multiple Interfaces)
// CFG_TUD_AUDIO > 1
//--------------------------------------------------------------------+
bool tud_audio_n_mounted (uint8_t itf);
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
#if CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
uint16_t tud_audio_n_available (uint8_t itf, uint8_t channelId);
uint16_t tud_audio_n_read (uint8_t itf, uint8_t channelId, void* buffer, uint16_t bufsize);
void tud_audio_n_read_flush (uint8_t itf, uint8_t channelId);
#else
uint16_t tud_audio_n_available (uint8_t itf);
uint16_t tud_audio_n_read (uint8_t itf, void* buffer, uint16_t bufsize);
void tud_audio_n_read_flush (uint8_t itf);
#endif
#endif
/* This function is intended for later use once EP buffers (at least for ISO EPs) are implemented as ring buffers
#if CFG_TUD_AUDIO_EPSIZE_IN && !CFG_TUD_AUDIO_TX_FIFO_SIZE
uint16_t tud_audio_n_write_ep_in_buffer(uint8_t itf, const void * data, uint16_t len)
#endif
*/
#ifndef CFG_TUD_AUDIO_TX_FIFO_COUNT
#define CFG_TUD_AUDIO_TX_FIFO_COUNT 1
#endif
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
#if CFG_TUD_AUDIO_TX_FIFO_COUNT > 1
uint16_t tud_audio_n_write (uint8_t itf, uint8_t channelId, const void * data, uint16_t len);
#else
uint16_t tud_audio_n_write (uint8_t itf, const void * data, uint16_t len);
#endif
uint16_t tud_audio_n_write_flush(uint8_t itf);
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0
uint16_t tud_audio_int_ctr_n_available (uint8_t itf);
uint16_t tud_audio_int_ctr_n_read (uint8_t itf, void* buffer, uint16_t bufsize);
void tud_audio_int_ctr_n_read_flush (uint8_t itf);
uint16_t tud_audio_int_ctr_n_write (uint8_t itf, uint8_t const* buffer, uint16_t bufsize);
#endif
//--------------------------------------------------------------------+
// Application API (Interface0)
//--------------------------------------------------------------------+
static inline bool tud_audio_mounted (void);
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
static inline uint16_t tud_audio_available (void);
static inline uint16_t tud_audio_read (void* buffer, uint16_t bufsize);
static inline void tud_audio_read_flush (void);
#endif
#if CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
#if CFG_TUD_AUDIO_TX_FIFO_COUNT > 1
static inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t bufsize);
#else
static inline uint16_t tud_audio_write (uint8_t const* buffer, uint16_t bufsize);
#endif
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0
static inline uint32_t tud_audio_int_ctr_available (void);
static inline uint32_t tud_audio_int_ctr_read (void* buffer, uint32_t bufsize);
static inline void tud_audio_int_ctr_read_flush (void);
static inline uint32_t tud_audio_int_ctr_write (uint8_t const* buffer, uint32_t bufsize);
#endif
// Buffer control EP data and schedule a transmit
// This function is intended to be used if you do not have a persistent buffer or memory location available (e.g. non-local variables) and need to answer onto a
// get request. This function buffers your answer request frame into the control buffer of the corresponding audio driver and schedules a transmit for sending it.
// Since transmission is triggered via interrupts, a persistent memory location is required onto which the buffer pointer in pointing. If you already have such
// available you may directly use 'tud_control_xfer(...)'. In this case data does not need to be copied into an additional buffer and you save some time.
// If the request's wLength is zero, a status packet is sent instead.
bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len);
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
#if CFG_TUD_AUDIO_EPSIZE_IN
TU_ATTR_WEAK bool tud_audio_tx_done_pre_load_cb(uint8_t rhport, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting);
TU_ATTR_WEAK bool tud_audio_tx_done_post_load_cb(uint8_t rhport, uint16_t n_bytes_copied, uint8_t itf, uint8_t ep_in, uint8_t cur_alt_setting);
#endif
#if CFG_TUD_AUDIO_EPSIZE_OUT
TU_ATTR_WEAK bool tud_audio_rx_done_cb(uint8_t rhport, uint8_t * buffer, uint16_t bufsize);
#endif
#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport);
// User code should call this function with feedback value in 16.16 format for FS and HS.
// Value will be corrected for FS to 10.14 format automatically.
// (see Universal Serial Bus Specification Revision 2.0 5.12.4.2).
// Feedback value will be sent at FB endpoint interval till it's changed.
bool tud_audio_fb_set(uint8_t rhport, uint32_t feedback);
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t * n_bytes_copied);
#endif
// Invoked when audio set interface request received
TU_ATTR_WEAK bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request);
// Invoked when audio set interface request received which closes an EP
TU_ATTR_WEAK bool tud_audio_set_itf_close_EP_cb(uint8_t rhport, tusb_control_request_t const * p_request);
// Invoked when audio class specific set request received for an EP
TU_ATTR_WEAK bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff);
// Invoked when audio class specific set request received for an interface
TU_ATTR_WEAK bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff);
// Invoked when audio class specific set request received for an entity
TU_ATTR_WEAK bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff);
// Invoked when audio class specific get request received for an EP
TU_ATTR_WEAK bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request);
// Invoked when audio class specific get request received for an interface
TU_ATTR_WEAK bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request);
// Invoked when audio class specific get request received for an entity
TU_ATTR_WEAK bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request);
//--------------------------------------------------------------------+
// Inline Functions
//--------------------------------------------------------------------+
static inline bool tud_audio_mounted(void)
{
return tud_audio_n_mounted(0);
}
#if CFG_TUD_AUDIO_EPSIZE_IN
#if CFG_TUD_AUDIO_TX_FIFO_SIZE && CFG_TUD_AUDIO_TX_FIFO_COUNT > 1
static inline uint16_t tud_audio_write (uint8_t channelId, uint8_t const* buffer, uint16_t n_bytes) // Short version if only one audio function is used
{
return tud_audio_n_write(0, channelId, buffer, n_bytes);
}
#else
static inline uint16_t tud_audio_write (uint8_t const* buffer, uint16_t n_bytes) // Short version if only one audio function is used
{
return tud_audio_n_write(0, buffer, n_bytes);
}
#endif
static inline uint16_t tud_audio_write_flush (void) // Short version if only one audio function is used
{
#if CFG_TUD_AUDIO_TX_FIFO_SIZE
return tud_audio_n_write_flush(0);
#else
return 0;
#endif
}
#endif // CFG_TUD_AUDIO_EPSIZE_IN && CFG_TUD_AUDIO_TX_FIFO_SIZE
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_RX_FIFO_SIZE
#if CFG_TUD_AUDIO_RX_FIFO_COUNT > 1
static inline uint16_t tud_audio_available(uint8_t channelId)
{
return tud_audio_n_available(0, channelId);
}
static inline uint16_t tud_audio_read(uint8_t channelId, void* buffer, uint16_t bufsize)
{
return tud_audio_n_read(0, channelId, buffer, bufsize);
}
static inline void tud_audio_read_flush(uint8_t channelId)
{
tud_audio_n_read_flush(0, channelId);
}
#else
static inline uint16_t tud_audio_available(void)
{
return tud_audio_n_available(0);
}
static inline uint16_t tud_audio_read(void *buffer, uint16_t bufsize)
{
return tud_audio_n_read(0, buffer, bufsize);
}
static inline void tud_audio_read_flush(void)
{
tud_audio_n_read_flush(0);
}
#endif
#endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN > 0
static inline uint16_t tud_audio_int_ctr_available(void)
{
return tud_audio_int_ctr_n_available(0);
}
static inline uint16_t tud_audio_int_ctr_read(void* buffer, uint16_t bufsize)
{
return tud_audio_int_ctr_n_read(0, buffer, bufsize);
}
static inline void tud_audio_int_ctr_read_flush(void)
{
return tud_audio_int_ctr_n_read_flush(0);
}
static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t bufsize)
{
return tud_audio_int_ctr_n_write(0, buffer, bufsize);
}
#endif
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void audiod_init (void);
void audiod_reset (uint8_t rhport);
uint16_t audiod_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool audiod_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool audiod_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_AUDIO_DEVICE_H_ */
/** @} */
/** @} */

View File

@ -0,0 +1,109 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Jerzy Kasenberg
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_BTH_DEVICE_H_
#define _TUSB_BTH_DEVICE_H_
#include <common/tusb_common.h>
#include <device/usbd.h>
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUD_BTH_EVENT_EPSIZE
#define CFG_TUD_BTH_EVENT_EPSIZE 16
#endif
#ifndef CFG_TUD_BTH_DATA_EPSIZE
#define CFG_TUD_BTH_DATA_EPSIZE 64
#endif
typedef struct TU_ATTR_PACKED
{
uint16_t op_code;
uint8_t param_length;
uint8_t param[255];
} bt_hci_cmd_t;
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
// Invoked when HCI command was received over USB from Bluetooth host.
// Detailed format is described in Bluetooth core specification Vol 2,
// Part E, 5.4.1.
// Length of the command is from 3 bytes (2 bytes for OpCode,
// 1 byte for parameter total length) to 258.
TU_ATTR_WEAK void tud_bt_hci_cmd_cb(void *hci_cmd, size_t cmd_len);
// Invoked when ACL data was received over USB from Bluetooth host.
// Detailed format is described in Bluetooth core specification Vol 2,
// Part E, 5.4.2.
// Length is from 4 bytes, (12 bits for Handle, 4 bits for flags
// and 16 bits for data total length) to endpoint size.
TU_ATTR_WEAK void tud_bt_acl_data_received_cb(void *acl_data, uint16_t data_len);
// Called when event sent with tud_bt_event_send() was delivered to BT stack.
// Controller can release/reuse buffer with Event packet at this point.
TU_ATTR_WEAK void tud_bt_event_sent_cb(uint16_t sent_bytes);
// Called when ACL data that was sent with tud_bt_acl_data_send()
// was delivered to BT stack.
// Controller can release/reuse buffer with ACL packet at this point.
TU_ATTR_WEAK void tud_bt_acl_data_sent_cb(uint16_t sent_bytes);
// Bluetooth controller calls this function when it wants to send even packet
// as described in Bluetooth core specification Vol 2, Part E, 5.4.4.
// Event has at least 2 bytes, first is Event code second contains parameter
// total length. Controller can release/reuse event memory after
// tud_bt_event_sent_cb() is called.
bool tud_bt_event_send(void *event, uint16_t event_len);
// Bluetooth controller calls this to send ACL data packet
// as described in Bluetooth core specification Vol 2, Part E, 5.4.2
// Minimum length is 4 bytes, (12 bits for Handle, 4 bits for flags
// and 16 bits for data total length). Upper limit is not limited
// to endpoint size since buffer is allocate by controller
// and must not be reused till tud_bt_acl_data_sent_cb() is called.
bool tud_bt_acl_data_send(void *acl_data, uint16_t data_len);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void btd_init (void);
void btd_reset (uint8_t rhport);
uint16_t btd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool btd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *request);
bool btd_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_BTH_DEVICE_H_ */

View File

@ -0,0 +1,405 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup group_class
* \defgroup ClassDriver_CDC Communication Device Class (CDC)
* Currently only Abstract Control Model subclass is supported
* @{ */
#ifndef _TUSB_CDC_H__
#define _TUSB_CDC_H__
#include "common/tusb_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup ClassDriver_CDC_Common Common Definitions
* @{ */
// TODO remove
/// CDC Pipe ID, used to indicate which pipe the API is addressing to (Notification, Out, In)
typedef enum
{
CDC_PIPE_NOTIFICATION , ///< Notification pipe
CDC_PIPE_DATA_IN , ///< Data in pipe
CDC_PIPE_DATA_OUT , ///< Data out pipe
CDC_PIPE_ERROR , ///< Invalid Pipe ID
}cdc_pipeid_t;
//--------------------------------------------------------------------+
// CDC Communication Interface Class
//--------------------------------------------------------------------+
/// Communication Interface Subclass Codes
typedef enum
{
CDC_COMM_SUBCLASS_DIRECT_LINE_CONTROL_MODEL = 0x01 , ///< Direct Line Control Model [USBPSTN1.2]
CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL , ///< Abstract Control Model [USBPSTN1.2]
CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL , ///< Telephone Control Model [USBPSTN1.2]
CDC_COMM_SUBCLASS_MULTICHANNEL_CONTROL_MODEL , ///< Multi-Channel Control Model [USBISDN1.2]
CDC_COMM_SUBCLASS_CAPI_CONTROL_MODEL , ///< CAPI Control Model [USBISDN1.2]
CDC_COMM_SUBCLASS_ETHERNET_CONTROL_MODEL , ///< Ethernet Networking Control Model [USBECM1.2]
CDC_COMM_SUBCLASS_ATM_NETWORKING_CONTROL_MODEL , ///< ATM Networking Control Model [USBATM1.2]
CDC_COMM_SUBCLASS_WIRELESS_HANDSET_CONTROL_MODEL , ///< Wireless Handset Control Model [USBWMC1.1]
CDC_COMM_SUBCLASS_DEVICE_MANAGEMENT , ///< Device Management [USBWMC1.1]
CDC_COMM_SUBCLASS_MOBILE_DIRECT_LINE_MODEL , ///< Mobile Direct Line Model [USBWMC1.1]
CDC_COMM_SUBCLASS_OBEX , ///< OBEX [USBWMC1.1]
CDC_COMM_SUBCLASS_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model [USBEEM1.0]
} cdc_comm_sublcass_type_t;
/// Communication Interface Protocol Codes
typedef enum
{
CDC_COMM_PROTOCOL_NONE = 0x00 , ///< No specific protocol
CDC_COMM_PROTOCOL_ATCOMMAND , ///< AT Commands: V.250 etc
CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101 , ///< AT Commands defined by PCCA-101
CDC_COMM_PROTOCOL_ATCOMMAND_PCCA_101_AND_ANNEXO , ///< AT Commands defined by PCCA-101 & Annex O
CDC_COMM_PROTOCOL_ATCOMMAND_GSM_707 , ///< AT Commands defined by GSM 07.07
CDC_COMM_PROTOCOL_ATCOMMAND_3GPP_27007 , ///< AT Commands defined by 3GPP 27.007
CDC_COMM_PROTOCOL_ATCOMMAND_CDMA , ///< AT Commands defined by TIA for CDMA
CDC_COMM_PROTOCOL_ETHERNET_EMULATION_MODEL ///< Ethernet Emulation Model
} cdc_comm_protocol_type_t;
//------------- SubType Descriptor in COMM Functional Descriptor -------------//
/// Communication Interface SubType Descriptor
typedef enum
{
CDC_FUNC_DESC_HEADER = 0x00 , ///< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface.
CDC_FUNC_DESC_CALL_MANAGEMENT = 0x01 , ///< Call Management Functional Descriptor.
CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT = 0x02 , ///< Abstract Control Management Functional Descriptor.
CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT = 0x03 , ///< Direct Line Management Functional Descriptor.
CDC_FUNC_DESC_TELEPHONE_RINGER = 0x04 , ///< Telephone Ringer Functional Descriptor.
CDC_FUNC_DESC_TELEPHONE_CALL_AND_LINE_STATE_REPORTING_CAPACITY = 0x05 , ///< Telephone Call and Line State Reporting Capabilities Functional Descriptor.
CDC_FUNC_DESC_UNION = 0x06 , ///< Union Functional Descriptor
CDC_FUNC_DESC_COUNTRY_SELECTION = 0x07 , ///< Country Selection Functional Descriptor
CDC_FUNC_DESC_TELEPHONE_OPERATIONAL_MODES = 0x08 , ///< Telephone Operational ModesFunctional Descriptor
CDC_FUNC_DESC_USB_TERMINAL = 0x09 , ///< USB Terminal Functional Descriptor
CDC_FUNC_DESC_NETWORK_CHANNEL_TERMINAL = 0x0A , ///< Network Channel Terminal Descriptor
CDC_FUNC_DESC_PROTOCOL_UNIT = 0x0B , ///< Protocol Unit Functional Descriptor
CDC_FUNC_DESC_EXTENSION_UNIT = 0x0C , ///< Extension Unit Functional Descriptor
CDC_FUNC_DESC_MULTICHANEL_MANAGEMENT = 0x0D , ///< Multi-Channel Management Functional Descriptor
CDC_FUNC_DESC_CAPI_CONTROL_MANAGEMENT = 0x0E , ///< CAPI Control Management Functional Descriptor
CDC_FUNC_DESC_ETHERNET_NETWORKING = 0x0F , ///< Ethernet Networking Functional Descriptor
CDC_FUNC_DESC_ATM_NETWORKING = 0x10 , ///< ATM Networking Functional Descriptor
CDC_FUNC_DESC_WIRELESS_HANDSET_CONTROL_MODEL = 0x11 , ///< Wireless Handset Control Model Functional Descriptor
CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL = 0x12 , ///< Mobile Direct Line Model Functional Descriptor
CDC_FUNC_DESC_MOBILE_DIRECT_LINE_MODEL_DETAIL = 0x13 , ///< MDLM Detail Functional Descriptor
CDC_FUNC_DESC_DEVICE_MANAGEMENT_MODEL = 0x14 , ///< Device Management Model Functional Descriptor
CDC_FUNC_DESC_OBEX = 0x15 , ///< OBEX Functional Descriptor
CDC_FUNC_DESC_COMMAND_SET = 0x16 , ///< Command Set Functional Descriptor
CDC_FUNC_DESC_COMMAND_SET_DETAIL = 0x17 , ///< Command Set Detail Functional Descriptor
CDC_FUNC_DESC_TELEPHONE_CONTROL_MODEL = 0x18 , ///< Telephone Control Model Functional Descriptor
CDC_FUNC_DESC_OBEX_SERVICE_IDENTIFIER = 0x19 ///< OBEX Service Identifier Functional Descriptor
}cdc_func_desc_type_t;
//--------------------------------------------------------------------+
// CDC Data Interface Class
//--------------------------------------------------------------------+
// SUBCLASS code of Data Interface is not used and should/must be zero
/// Data Interface Protocol Codes
typedef enum{
CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, ///< Physical interface protocol for ISDN BRI
CDC_DATA_PROTOCOL_HDLC = 0x31, ///< HDLC
CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, ///< Transparent
CDC_DATA_PROTOCOL_Q921_MANAGEMENT = 0x50, ///< Management protocol for Q.921 data link protocol
CDC_DATA_PROTOCOL_Q921_DATA_LINK = 0x51, ///< Data link protocol for Q.931
CDC_DATA_PROTOCOL_Q921_TEI_MULTIPLEXOR = 0x52, ///< TEI-multiplexor for Q.921 data link protocol
CDC_DATA_PROTOCOL_V42BIS_DATA_COMPRESSION = 0x90, ///< Data compression procedures
CDC_DATA_PROTOCOL_EURO_ISDN = 0x91, ///< Euro-ISDN protocol control
CDC_DATA_PROTOCOL_V24_RATE_ADAPTION_TO_ISDN = 0x92, ///< V.24 rate adaptation to ISDN
CDC_DATA_PROTOCOL_CAPI_COMMAND = 0x93, ///< CAPI Commands
CDC_DATA_PROTOCOL_HOST_BASED_DRIVER = 0xFD, ///< Host based driver. Note: This protocol code should only be used in messages between host and device to identify the host driver portion of a protocol stack.
CDC_DATA_PROTOCOL_IN_PROTOCOL_UNIT_FUNCTIONAL_DESCRIPTOR = 0xFE ///< The protocol(s) are described using a ProtocolUnit Functional Descriptors on Communications Class Interface
}cdc_data_protocol_type_t;
//--------------------------------------------------------------------+
// Management Element Request (Control Endpoint)
//--------------------------------------------------------------------+
/// Communication Interface Management Element Request Codes
typedef enum
{
CDC_REQUEST_SEND_ENCAPSULATED_COMMAND = 0x00, ///< is used to issue a command in the format of the supported control protocol of the Communications Class interface
CDC_REQUEST_GET_ENCAPSULATED_RESPONSE = 0x01, ///< is used to request a response in the format of the supported control protocol of the Communications Class interface.
CDC_REQUEST_SET_COMM_FEATURE = 0x02,
CDC_REQUEST_GET_COMM_FEATURE = 0x03,
CDC_REQUEST_CLEAR_COMM_FEATURE = 0x04,
CDC_REQUEST_SET_AUX_LINE_STATE = 0x10,
CDC_REQUEST_SET_HOOK_STATE = 0x11,
CDC_REQUEST_PULSE_SETUP = 0x12,
CDC_REQUEST_SEND_PULSE = 0x13,
CDC_REQUEST_SET_PULSE_TIME = 0x14,
CDC_REQUEST_RING_AUX_JACK = 0x15,
CDC_REQUEST_SET_LINE_CODING = 0x20,
CDC_REQUEST_GET_LINE_CODING = 0x21,
CDC_REQUEST_SET_CONTROL_LINE_STATE = 0x22,
CDC_REQUEST_SEND_BREAK = 0x23,
CDC_REQUEST_SET_RINGER_PARMS = 0x30,
CDC_REQUEST_GET_RINGER_PARMS = 0x31,
CDC_REQUEST_SET_OPERATION_PARMS = 0x32,
CDC_REQUEST_GET_OPERATION_PARMS = 0x33,
CDC_REQUEST_SET_LINE_PARMS = 0x34,
CDC_REQUEST_GET_LINE_PARMS = 0x35,
CDC_REQUEST_DIAL_DIGITS = 0x36,
CDC_REQUEST_SET_UNIT_PARAMETER = 0x37,
CDC_REQUEST_GET_UNIT_PARAMETER = 0x38,
CDC_REQUEST_CLEAR_UNIT_PARAMETER = 0x39,
CDC_REQUEST_GET_PROFILE = 0x3A,
CDC_REQUEST_SET_ETHERNET_MULTICAST_FILTERS = 0x40,
CDC_REQUEST_SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x41,
CDC_REQUEST_GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER = 0x42,
CDC_REQUEST_SET_ETHERNET_PACKET_FILTER = 0x43,
CDC_REQUEST_GET_ETHERNET_STATISTIC = 0x44,
CDC_REQUEST_SET_ATM_DATA_FORMAT = 0x50,
CDC_REQUEST_GET_ATM_DEVICE_STATISTICS = 0x51,
CDC_REQUEST_SET_ATM_DEFAULT_VC = 0x52,
CDC_REQUEST_GET_ATM_VC_STATISTICS = 0x53,
CDC_REQUEST_MDLM_SEMANTIC_MODEL = 0x60,
}cdc_management_request_t;
//--------------------------------------------------------------------+
// Management Elemenent Notification (Notification Endpoint)
//--------------------------------------------------------------------+
/// Communication Interface Management Element Notification Codes
typedef enum
{
NETWORK_CONNECTION = 0x00, ///< This notification allows the device to notify the host about network connection status.
RESPONSE_AVAILABLE = 0x01, ///< This notification allows the device to notify the hostthat a response is available. This response can be retrieved with a subsequent \ref CDC_REQUEST_GET_ENCAPSULATED_RESPONSE request.
AUX_JACK_HOOK_STATE = 0x08,
RING_DETECT = 0x09,
SERIAL_STATE = 0x20,
CALL_STATE_CHANGE = 0x28,
LINE_STATE_CHANGE = 0x29,
CONNECTION_SPEED_CHANGE = 0x2A, ///< This notification allows the device to inform the host-networking driver that a change in either the upstream or the downstream bit rate of the connection has occurred
MDLM_SEMANTIC_MODEL_NOTIFICATION = 0x40,
}cdc_notification_request_t;
//--------------------------------------------------------------------+
// Class Specific Functional Descriptor (Communication Interface)
//--------------------------------------------------------------------+
/// Header Functional Descriptor (Communication Interface)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUNC_DESC_
uint16_t bcdCDC ; ///< CDC release number in Binary-Coded Decimal
}cdc_desc_func_header_t;
/// Union Functional Descriptor (Communication Interface)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
uint8_t bControlInterface ; ///< Interface number of Communication Interface
uint8_t bSubordinateInterface ; ///< Array of Interface number of Data Interface
}cdc_desc_func_union_t;
#define cdc_desc_func_union_n_t(no_slave)\
struct TU_ATTR_PACKED { \
uint8_t bLength ;\
uint8_t bDescriptorType ;\
uint8_t bDescriptorSubType ;\
uint8_t bControlInterface ;\
uint8_t bSubordinateInterface[no_slave] ;\
}
/// Country Selection Functional Descriptor (Communication Interface)
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
uint8_t iCountryCodeRelDate ; ///< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
uint16_t wCountryCode ; ///< Country code in the format as defined in [ISO3166], release date as specified inoffset 3 for the first supported country.
}cdc_desc_func_country_selection_t;
#define cdc_desc_func_country_selection_n_t(no_country) \
struct TU_ATTR_PACKED {\
uint8_t bLength ;\
uint8_t bDescriptorType ;\
uint8_t bDescriptorSubType ;\
uint8_t iCountryCodeRelDate ;\
uint16_t wCountryCode[no_country] ;\
}
//--------------------------------------------------------------------+
// PUBLIC SWITCHED TELEPHONE NETWORK (PSTN) SUBCLASS
//--------------------------------------------------------------------+
/// \brief Call Management Functional Descriptor
/// \details This functional descriptor describes the processing of calls for the Communications Class interface.
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
struct {
uint8_t handle_call : 1; ///< 0 - Device sends/receives call management information only over the Communications Class interface. 1 - Device can send/receive call management information over a Data Class interface.
uint8_t send_recv_call : 1; ///< 0 - Device does not handle call management itself. 1 - Device handles call management itself.
uint8_t TU_RESERVED : 6;
} bmCapabilities;
uint8_t bDataInterface;
}cdc_desc_func_call_management_t;
typedef struct TU_ATTR_PACKED
{
uint8_t support_comm_request : 1; ///< Device supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature.
uint8_t support_line_request : 1; ///< Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State.
uint8_t support_send_break : 1; ///< Device supports the request Send_Break
uint8_t support_notification_network_connection : 1; ///< Device supports the notification Network_Connection.
uint8_t TU_RESERVED : 4;
}cdc_acm_capability_t;
TU_VERIFY_STATIC(sizeof(cdc_acm_capability_t) == 1, "mostly problem with compiler");
/// \brief Abstract Control Management Functional Descriptor
/// \details This functional descriptor describes the commands supported by by the Communications Class interface with SubClass code of \ref CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
cdc_acm_capability_t bmCapabilities ;
}cdc_desc_func_acm_t;
/// \brief Direct Line Management Functional Descriptor
/// \details This functional descriptor describes the commands supported by the Communications Class interface with SubClass code of \ref CDC_FUNC_DESC_DIRECT_LINE_MANAGEMENT
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
struct {
uint8_t require_pulse_setup : 1; ///< Device requires extra Pulse_Setup request during pulse dialing sequence to disengage holding circuit.
uint8_t support_aux_request : 1; ///< Device supports the request combination of Set_Aux_Line_State, Ring_Aux_Jack, and notification Aux_Jack_Hook_State.
uint8_t support_pulse_request : 1; ///< Device supports the request combination of Pulse_Setup, Send_Pulse, and Set_Pulse_Time.
uint8_t TU_RESERVED : 5;
} bmCapabilities;
}cdc_desc_func_direct_line_management_t;
/// \brief Telephone Ringer Functional Descriptor
/// \details The Telephone Ringer functional descriptor describes the ringer capabilities supported by the Communications Class interface,
/// with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
uint8_t bRingerVolSteps ;
uint8_t bNumRingerPatterns ;
}cdc_desc_func_telephone_ringer_t;
/// \brief Telephone Operational Modes Functional Descriptor
/// \details The Telephone Operational Modes functional descriptor describes the operational modes supported by
/// the Communications Class interface, with the SubClass code of \ref CDC_COMM_SUBCLASS_TELEPHONE_CONTROL_MODEL
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
struct {
uint8_t simple_mode : 1;
uint8_t standalone_mode : 1;
uint8_t computer_centric_mode : 1;
uint8_t TU_RESERVED : 5;
} bmCapabilities;
}cdc_desc_func_telephone_operational_modes_t;
/// \brief Telephone Call and Line State Reporting Capabilities Descriptor
/// \details The Telephone Call and Line State Reporting Capabilities functional descriptor describes the abilities of a
/// telephone device to report optional call and line states.
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType one of above CDC_FUCN_DESC_
struct {
uint32_t interrupted_dialtone : 1; ///< 0 : Reports only dialtone (does not differentiate between normal and interrupted dialtone). 1 : Reports interrupted dialtone in addition to normal dialtone
uint32_t ringback_busy_fastbusy : 1; ///< 0 : Reports only dialing state. 1 : Reports ringback, busy, and fast busy states.
uint32_t caller_id : 1; ///< 0 : Does not report caller ID. 1 : Reports caller ID information.
uint32_t incoming_distinctive : 1; ///< 0 : Reports only incoming ringing. 1 : Reports incoming distinctive ringing patterns.
uint32_t dual_tone_multi_freq : 1; ///< 0 : Cannot report dual tone multi-frequency (DTMF) digits input remotely over the telephone line. 1 : Can report DTMF digits input remotely over the telephone line.
uint32_t line_state_change : 1; ///< 0 : Does not support line state change notification. 1 : Does support line state change notification
uint32_t TU_RESERVED : 26;
} bmCapabilities;
}cdc_desc_func_telephone_call_state_reporting_capabilities_t;
static inline uint8_t cdc_functional_desc_typeof(uint8_t const * p_desc)
{
return p_desc[2];
}
//--------------------------------------------------------------------+
// Requests
//--------------------------------------------------------------------+
typedef struct TU_ATTR_PACKED
{
uint32_t bit_rate;
uint8_t stop_bits; ///< 0: 1 stop bit - 1: 1.5 stop bits - 2: 2 stop bits
uint8_t parity; ///< 0: None - 1: Odd - 2: Even - 3: Mark - 4: Space
uint8_t data_bits; ///< can be 5, 6, 7, 8 or 16
} cdc_line_coding_t;
TU_VERIFY_STATIC(sizeof(cdc_line_coding_t) == 7, "size is not correct");
typedef struct TU_ATTR_PACKED
{
uint16_t dte_is_present : 1; ///< Indicates to DCE if DTE is presentor not. This signal corresponds to V.24 signal 108/2 and RS-232 signal DTR.
uint16_t half_duplex_carrier_control : 1;
uint16_t : 14;
} cdc_line_control_state_t;
TU_VERIFY_STATIC(sizeof(cdc_line_control_state_t) == 2, "size is not correct");
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/** @} */

View File

@ -0,0 +1,261 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_CDC_DEVICE_H_
#define _TUSB_CDC_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#include "cdc.h"
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
#if !defined(CFG_TUD_CDC_EP_BUFSIZE) && defined(CFG_TUD_CDC_EPSIZE)
#warning CFG_TUD_CDC_EPSIZE is renamed to CFG_TUD_CDC_EP_BUFSIZE, please update to use the new name
#define CFG_TUD_CDC_EP_BUFSIZE CFG_TUD_CDC_EPSIZE
#endif
#ifndef CFG_TUD_CDC_EP_BUFSIZE
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup CDC_Serial Serial
* @{
* \defgroup CDC_Serial_Device Device
* @{ */
//--------------------------------------------------------------------+
// Application API (Multiple Ports)
// CFG_TUD_CDC > 1
//--------------------------------------------------------------------+
// Check if terminal is connected to this port
bool tud_cdc_n_connected (uint8_t itf);
// Get current line state. Bit 0: DTR (Data Terminal Ready), Bit 1: RTS (Request to Send)
uint8_t tud_cdc_n_get_line_state (uint8_t itf);
// Get current line encoding: bit rate, stop bits parity etc ..
void tud_cdc_n_get_line_coding (uint8_t itf, cdc_line_coding_t* coding);
// Set special character that will trigger tud_cdc_rx_wanted_cb() callback on receiving
void tud_cdc_n_set_wanted_char (uint8_t itf, char wanted);
// Get the number of bytes available for reading
uint32_t tud_cdc_n_available (uint8_t itf);
// Read received bytes
uint32_t tud_cdc_n_read (uint8_t itf, void* buffer, uint32_t bufsize);
// Read a byte, return -1 if there is none
static inline
int32_t tud_cdc_n_read_char (uint8_t itf);
// Clear the received FIFO
void tud_cdc_n_read_flush (uint8_t itf);
// Get a byte from FIFO at the specified position without removing it
bool tud_cdc_n_peek (uint8_t itf, int pos, uint8_t* u8);
// Write bytes to TX FIFO, data may remain in the FIFO for a while
uint32_t tud_cdc_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
// Write a byte
static inline
uint32_t tud_cdc_n_write_char (uint8_t itf, char ch);
// Write a null-terminated string
static inline
uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str);
// Force sending data if possible, return number of forced bytes
uint32_t tud_cdc_n_write_flush (uint8_t itf);
// Return the number of bytes (characters) available for writing to TX FIFO buffer in a single n_write operation.
uint32_t tud_cdc_n_write_available (uint8_t itf);
// Clear the transmit FIFO
bool tud_cdc_n_write_clear (uint8_t itf);
//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
static inline bool tud_cdc_connected (void);
static inline uint8_t tud_cdc_get_line_state (void);
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding);
static inline void tud_cdc_set_wanted_char (char wanted);
static inline uint32_t tud_cdc_available (void);
static inline int32_t tud_cdc_read_char (void);
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize);
static inline void tud_cdc_read_flush (void);
static inline bool tud_cdc_peek (int pos, uint8_t* u8);
static inline uint32_t tud_cdc_write_char (char ch);
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize);
static inline uint32_t tud_cdc_write_str (char const* str);
static inline uint32_t tud_cdc_write_flush (void);
static inline uint32_t tud_cdc_write_available (void);
static inline bool tud_cdc_write_clear (void);
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
// Invoked when received new data
TU_ATTR_WEAK void tud_cdc_rx_cb(uint8_t itf);
// Invoked when received `wanted_char`
TU_ATTR_WEAK void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char);
// Invoked when space becomes available in TX buffer
TU_ATTR_WEAK void tud_cdc_tx_complete_cb(uint8_t itf);
// Invoked when line state DTR & RTS are changed via SET_CONTROL_LINE_STATE
TU_ATTR_WEAK void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts);
// Invoked when line coding is change via SET_LINE_CODING
TU_ATTR_WEAK void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding);
// Invoked when received send break
TU_ATTR_WEAK void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms);
//--------------------------------------------------------------------+
// Inline Functions
//--------------------------------------------------------------------+
static inline int32_t tud_cdc_n_read_char (uint8_t itf)
{
uint8_t ch;
return tud_cdc_n_read(itf, &ch, 1) ? (int32_t) ch : -1;
}
static inline uint32_t tud_cdc_n_write_char(uint8_t itf, char ch)
{
return tud_cdc_n_write(itf, &ch, 1);
}
static inline uint32_t tud_cdc_n_write_str (uint8_t itf, char const* str)
{
return tud_cdc_n_write(itf, str, strlen(str));
}
static inline bool tud_cdc_connected (void)
{
return tud_cdc_n_connected(0);
}
static inline uint8_t tud_cdc_get_line_state (void)
{
return tud_cdc_n_get_line_state(0);
}
static inline void tud_cdc_get_line_coding (cdc_line_coding_t* coding)
{
tud_cdc_n_get_line_coding(0, coding);
}
static inline void tud_cdc_set_wanted_char (char wanted)
{
tud_cdc_n_set_wanted_char(0, wanted);
}
static inline uint32_t tud_cdc_available (void)
{
return tud_cdc_n_available(0);
}
static inline int32_t tud_cdc_read_char (void)
{
return tud_cdc_n_read_char(0);
}
static inline uint32_t tud_cdc_read (void* buffer, uint32_t bufsize)
{
return tud_cdc_n_read(0, buffer, bufsize);
}
static inline void tud_cdc_read_flush (void)
{
tud_cdc_n_read_flush(0);
}
static inline bool tud_cdc_peek (int pos, uint8_t* u8)
{
return tud_cdc_n_peek(0, pos, u8);
}
static inline uint32_t tud_cdc_write_char (char ch)
{
return tud_cdc_n_write_char(0, ch);
}
static inline uint32_t tud_cdc_write (void const* buffer, uint32_t bufsize)
{
return tud_cdc_n_write(0, buffer, bufsize);
}
static inline uint32_t tud_cdc_write_str (char const* str)
{
return tud_cdc_n_write_str(0, str);
}
static inline uint32_t tud_cdc_write_flush (void)
{
return tud_cdc_n_write_flush(0);
}
static inline uint32_t tud_cdc_write_available(void)
{
return tud_cdc_n_write_available(0);
}
static inline bool tud_cdc_write_clear(void)
{
return tud_cdc_n_write_clear(0);
}
/** @} */
/** @} */
//--------------------------------------------------------------------+
// INTERNAL USBD-CLASS DRIVER API
//--------------------------------------------------------------------+
void cdcd_init (void);
void cdcd_reset (uint8_t rhport);
uint16_t cdcd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool cdcd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool cdcd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CDC_DEVICE_H_ */

View File

@ -0,0 +1,136 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_CDC_HOST_H_
#define _TUSB_CDC_HOST_H_
#include "common/tusb_common.h"
#include "host/usbh.h"
#include "cdc.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// CDC APPLICATION PUBLIC API
//--------------------------------------------------------------------+
/** \ingroup ClassDriver_CDC Communication Device Class (CDC)
* \addtogroup CDC_Serial Serial
* @{
* \defgroup CDC_Serial_Host Host
* @{ */
bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_control_complete_cb_t complete_cb);
static inline bool tuh_cdc_connect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb)
{
return tuh_cdc_set_control_line_state(dev_addr, true, true, complete_cb);
}
static inline bool tuh_cdc_disconnect(uint8_t dev_addr, tuh_control_complete_cb_t complete_cb)
{
return tuh_cdc_set_control_line_state(dev_addr, false, false, complete_cb);
}
/** \brief Check if device support CDC Serial interface or not
* \param[in] dev_addr device address
* \retval true if device supports
* \retval false if device does not support or is not mounted
*/
bool tuh_cdc_serial_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
* \param[in] pipeid value from \ref cdc_pipeid_t to indicate target pipe.
* \retval true if the interface is busy, meaning the stack is still transferring/waiting data from/to device
* \retval false if the interface is not busy, meaning the stack successfully transferred data from/to device
* \note This function is used to check if previous transfer is complete (success or error), so that the next transfer
* can be scheduled. User needs to make sure the corresponding interface is mounted
* (by \ref tuh_cdc_serial_is_mounted) before calling this function.
*/
bool tuh_cdc_is_busy(uint8_t dev_addr, cdc_pipeid_t pipeid);
/** \brief Perform USB OUT transfer to device
* \param[in] dev_addr device address
* \param[in] p_data Buffer containing data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
* \param[in] length Number of bytes to be transferred via USB bus
* \retval TUSB_ERROR_NONE on success
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
*/
bool tuh_cdc_send(uint8_t dev_addr, void const * p_data, uint32_t length, bool is_notify);
/** \brief Perform USB IN transfer to get data from device
* \param[in] dev_addr device address
* \param[in] p_buffer Buffer containing received data. Must be accessible by USB controller (see \ref CFG_TUSB_MEM_SECTION)
* \param[in] length Number of bytes to be transferred via USB bus
* \retval TUSB_ERROR_NONE on success
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of USB transfer will be reported by the
* interface's callback function. \a p_data must be declared with \ref CFG_TUSB_MEM_SECTION.
*/
bool tuh_cdc_receive(uint8_t dev_addr, void * p_buffer, uint32_t length, bool is_notify);
//--------------------------------------------------------------------+
// CDC APPLICATION CALLBACKS
//--------------------------------------------------------------------+
/** \brief Callback function that is invoked when an transferring event occurred
* \param[in] dev_addr Address of device
* \param[in] event an value from \ref xfer_result_t
* \param[in] pipe_id value from \ref cdc_pipeid_t indicate the pipe
* \param[in] xferred_bytes Number of bytes transferred via USB bus
* \note event can be one of following
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
* \note
*/
void tuh_cdc_xfer_isr(uint8_t dev_addr, xfer_result_t event, cdc_pipeid_t pipe_id, uint32_t xferred_bytes);
/// @} // group CDC_Serial_Host
/// @}
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void cdch_init(void);
bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
bool cdch_set_config(uint8_t dev_addr, uint8_t itf_num);
bool cdch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void cdch_close(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CDC_HOST_H_ */

View File

@ -0,0 +1,301 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup ClassDriver_CDC Communication Device Class (CDC)
* \defgroup CDC_RNDIS Remote Network Driver Interface Specification (RNDIS)
* @{
* \defgroup CDC_RNDIS_Common Common Definitions
* @{ */
#ifndef _TUSB_CDC_RNDIS_H_
#define _TUSB_CDC_RNDIS_H_
#include "cdc.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __CC_ARM
#pragma diag_suppress 66 // Suppress Keil warnings #66-D: enumeration value is out of "int" range
#endif
/// RNDIS Message Types
typedef enum
{
RNDIS_MSG_PACKET = 0x00000001UL, ///< The host and device use this to send network data to one another.
RNDIS_MSG_INITIALIZE = 0x00000002UL, ///< Sent by the host to initialize the device.
RNDIS_MSG_INITIALIZE_CMPLT = 0x80000002UL, ///< Device response to an initialize message.
RNDIS_MSG_HALT = 0x00000003UL, ///< Sent by the host to halt the device. This does not have a response. It is optional for the device to send this message to the host.
RNDIS_MSG_QUERY = 0x00000004UL, ///< Sent by the host to send a query OID.
RNDIS_MSG_QUERY_CMPLT = 0x80000004UL, ///< Device response to a query OID.
RNDIS_MSG_SET = 0x00000005UL, ///< Sent by the host to send a set OID.
RNDIS_MSG_SET_CMPLT = 0x80000005UL, ///< Device response to a set OID.
RNDIS_MSG_RESET = 0x00000006UL, ///< Sent by the host to perform a soft reset on the device.
RNDIS_MSG_RESET_CMPLT = 0x80000006UL, ///< Device response to reset message.
RNDIS_MSG_INDICATE_STATUS = 0x00000007UL, ///< Sent by the device to indicate its status or an error when an unrecognized message is received.
RNDIS_MSG_KEEP_ALIVE = 0x00000008UL, ///< During idle periods, sent every few seconds by the host to check that the device is still responsive. It is optional for the device to send this message to check if the host is active.
RNDIS_MSG_KEEP_ALIVE_CMPLT = 0x80000008UL ///< The device response to a keepalivemessage. The host can respond with this message to a keepalive message from the device when the device implements the optional KeepAliveTimer.
}rndis_msg_type_t;
/// RNDIS Message Status Values
typedef enum
{
RNDIS_STATUS_SUCCESS = 0x00000000UL, ///< Success
RNDIS_STATUS_FAILURE = 0xC0000001UL, ///< Unspecified error
RNDIS_STATUS_INVALID_DATA = 0xC0010015UL, ///< Invalid data error
RNDIS_STATUS_NOT_SUPPORTED = 0xC00000BBUL, ///< Unsupported request error
RNDIS_STATUS_MEDIA_CONNECT = 0x4001000BUL, ///< Device is connected to a network medium.
RNDIS_STATUS_MEDIA_DISCONNECT = 0x4001000CUL ///< Device is disconnected from the medium.
}rndis_msg_status_t;
#ifdef __CC_ARM
#pragma diag_default 66 // return Keil 66 to normal severity
#endif
//--------------------------------------------------------------------+
// MESSAGE STRUCTURE
//--------------------------------------------------------------------+
//------------- Initialize -------------//
/// \brief Initialize Message
/// \details This message MUST be sent by the host to initialize the device.
typedef struct {
uint32_t type ; ///< Message type, must be \ref RNDIS_MSG_INITIALIZE
uint32_t length ; ///< Message length in bytes, must be 0x18
uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device.
uint32_t major_version ; ///< The major version of the RNDIS Protocol implemented by the host.
uint32_t minor_version ; ///< The minor version of the RNDIS Protocol implemented by the host
uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the host expects to receive from the device.
}rndis_msg_initialize_t;
/// \brief Initialize Complete Message
/// \details This message MUST be sent by the device in response to an initialize message.
typedef struct {
uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_INITIALIZE_CMPLT
uint32_t length ; ///< Message length in bytes, must be 0x30
uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_initialize_t to which this message is a response.
uint32_t status ; ///< The initialization status of the device, has value from \ref rndis_msg_status_t
uint32_t major_version ; ///< the highest-numbered RNDIS Protocol version supported by the device.
uint32_t minor_version ; ///< the highest-numbered RNDIS Protocol version supported by the device.
uint32_t device_flags ; ///< MUST be set to 0x000000010. Other values are reserved for future use.
uint32_t medium ; ///< is 0x00 for RNDIS_MEDIUM_802_3
uint32_t max_packet_per_xfer ; ///< The maximum number of concatenated \ref RNDIS_MSG_PACKET messages that the device can handle in a single bus transfer to it. This value MUST be at least 1.
uint32_t max_xfer_size ; ///< The maximum size, in bytes, of any single bus data transfer that the device expects to receive from the host.
uint32_t packet_alignment_factor ; ///< The byte alignment the device expects for each RNDIS message that is part of a multimessage transfer to it. The value is specified as an exponent of 2; for example, the host uses 2<SUP>{PacketAlignmentFactor}</SUP> as the alignment value.
uint32_t reserved[2] ;
} rndis_msg_initialize_cmplt_t;
//------------- Query -------------//
/// \brief Query Message
/// \details This message MUST be sent by the host to query an OID.
typedef struct {
uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY
uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer
uint32_t request_id ; ///< A 32-bit integer value, generated by the host, used to match the host's sent request to the response from the device.
uint32_t oid ; ///< The integer value of the host operating system-defined identifier, for the parameter of the device being queried for.
uint32_t buffer_length ; ///< The length, in bytes, of the input data required for the OID query. This MUST be set to 0 when there is no input data associated with the OID.
uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the input data for the query is located in the message. This value MUST be set to 0 when there is no input data associated with the OID.
uint32_t reserved ;
uint8_t oid_buffer[] ; ///< Flexible array contains the input data supplied by the host, required for the OID query request processing by the device, as per the host NDIS specification.
} rndis_msg_query_t, rndis_msg_set_t;
TU_VERIFY_STATIC(sizeof(rndis_msg_query_t) == 28, "Make sure flexible array member does not affect layout");
/// \brief Query Complete Message
/// \details This message MUST be sent by the device in response to a query OID message.
typedef struct {
uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_QUERY_CMPLT
uint32_t length ; ///< Message length in bytes, including the header and the \a oid_buffer
uint32_t request_id ; ///< A 32-bit integer value from \a request_id field of the \ref rndis_msg_query_t to which this message is a response.
uint32_t status ; ///< The status of processing for the query request, has value from \ref rndis_msg_status_t.
uint32_t buffer_length ; ///< The length, in bytes, of the data in the response to the query. This MUST be set to 0 when there is no OIDInputBuffer.
uint32_t buffer_offset ; ///< The offset, in bytes, from the beginning of \a request_id field where the response data for the query is located in the message. This MUST be set to 0 when there is no \ref oid_buffer.
uint8_t oid_buffer[] ; ///< Flexible array member contains the response data to the OID query request as specified by the host.
} rndis_msg_query_cmplt_t;
TU_VERIFY_STATIC(sizeof(rndis_msg_query_cmplt_t) == 24, "Make sure flexible array member does not affect layout");
//------------- Reset -------------//
/// \brief Reset Message
/// \details This message MUST be sent by the host to perform a soft reset on the device.
typedef struct {
uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET
uint32_t length ; ///< Message length in bytes, MUST be 0x06
uint32_t reserved ;
} rndis_msg_reset_t;
/// \brief Reset Complete Message
/// \details This message MUST be sent by the device in response to a reset message.
typedef struct {
uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_RESET_CMPLT
uint32_t length ; ///< Message length in bytes, MUST be 0x10
uint32_t status ; ///< The status of processing for the \ref rndis_msg_reset_t, has value from \ref rndis_msg_status_t.
uint32_t addressing_reset ; ///< This field indicates whether the addressing information, which is the multicast address list or packet filter, has been lost during the reset operation. This MUST be set to 0x00000001 if the device requires that the host to resend addressing information or MUST be set to zero otherwise.
} rndis_msg_reset_cmplt_t;
//typedef struct {
// uint32_t type;
// uint32_t length;
// uint32_t status;
// uint32_t buffer_length;
// uint32_t buffer_offset;
// uint32_t diagnostic_status; // optional
// uint32_t diagnostic_error_offset; // optional
// uint32_t status_buffer[0]; // optional
//} rndis_msg_indicate_status_t;
/// \brief Keep Alive Message
/// \details This message MUST be sent by the host to check that device is still responsive. It is optional for the device to send this message to check if the host is active
typedef struct {
uint32_t type ; ///< Message Type
uint32_t length ; ///< Message length in bytes, MUST be 0x10
uint32_t request_id ;
} rndis_msg_keep_alive_t, rndis_msg_halt_t;
/// \brief Set Complete Message
/// \brief This message MUST be sent in response to a the request message
typedef struct {
uint32_t type ; ///< Message Type
uint32_t length ; ///< Message length in bytes, MUST be 0x10
uint32_t request_id ; ///< must be the same as requesting message
uint32_t status ; ///< The status of processing for the request message request by the device to which this message is the response.
} rndis_msg_set_cmplt_t, rndis_msg_keep_alive_cmplt_t;
/// \brief Packet Data Message
/// \brief This message MUST be used by the host and the device to send network data to one another.
typedef struct {
uint32_t type ; ///< Message Type, must be \ref RNDIS_MSG_PACKET
uint32_t length ; ///< Message length in bytes, The total length of this RNDIS message including the header, payload, and padding.
uint32_t data_offset ; ///< Specifies the offset, in bytes, from the start of this \a data_offset field of this message to the start of the data. This MUST be an integer multiple of 4.
uint32_t data_length ; ///< Specifies the number of bytes in the payload of this message.
uint32_t out_of_band_data_offet ; ///< Specifies the offset, in bytes, of the first out-of-band data record from the start of the DataOffset field in this message. MUST be an integer multiple of 4 when out-of-band data is present or set to 0 otherwise. When there are multiple out-ofband data records, each subsequent record MUST immediately follow the previous out-of-band data record.
uint32_t out_of_band_data_length ; ///< Specifies, in bytes, the total length of the out-of-band data.
uint32_t num_out_of_band_data_elements ; ///< Specifies the number of out-of-band records in this message.
uint32_t per_packet_info_offset ; ///< Specifies the offset, in bytes, of the start of per-packet-info data record from the start of the \a data_offset field in this message. MUST be an integer multiple of 4 when per-packet-info data record is present or MUST be set to 0 otherwise. When there are multiple per-packet-info data records, each subsequent record MUST immediately follow the previous record.
uint32_t per_packet_info_length ; ///< Specifies, in bytes, the total length of per-packetinformation contained in this message.
uint32_t reserved[2] ;
uint32_t payload[0] ; ///< Network data contained in this message.
// uint8_t padding[0]
// Additional bytes of zeros added at the end of the message to comply with
// the internal and external padding requirements. Internal padding SHOULD be as per the
// specification of the out-of-band data record and per-packet-info data record. The external
//padding size SHOULD be determined based on the PacketAlignmentFactor field specification
//in REMOTE_NDIS_INITIALIZE_CMPLT message by the device, when multiple
//REMOTE_NDIS_PACKET_MSG messages are bundled together in a single bus-native message.
//In this case, all but the very last REMOTE_NDIS_PACKET_MSG MUST respect the
//PacketAlignmentFactor field.
// rndis_msg_packet_t [0] : (optional) more packet if multiple packet per bus transaction is supported
} rndis_msg_packet_t;
typedef struct {
uint32_t size ; ///< Length, in bytes, of this header and appended data and padding. This value MUST be an integer multiple of 4.
uint32_t type ; ///< MUST be as per host operating system specification.
uint32_t offset ; ///< The byte offset from the beginning of this record to the beginning of data.
uint32_t data[0] ; ///< Flexible array contains data
} rndis_msg_out_of_band_data_t, rndis_msg_per_packet_info_t;
//--------------------------------------------------------------------+
// NDIS Object ID
//--------------------------------------------------------------------+
/// NDIS Object ID
typedef enum
{
//------------- General Required OIDs -------------//
RNDIS_OID_GEN_SUPPORTED_LIST = 0x00010101, ///< List of supported OIDs
RNDIS_OID_GEN_HARDWARE_STATUS = 0x00010102, ///< Hardware status
RNDIS_OID_GEN_MEDIA_SUPPORTED = 0x00010103, ///< Media types supported (encoded)
RNDIS_OID_GEN_MEDIA_IN_USE = 0x00010104, ///< Media types in use (encoded)
RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD = 0x00010105, ///<
RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE = 0x00010106, ///< Maximum frame size in bytes
RNDIS_OID_GEN_LINK_SPEED = 0x00010107, ///< Link speed in units of 100 bps
RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE = 0x00010108, ///< Transmit buffer space
RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE = 0x00010109, ///< Receive buffer space
RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE = 0x0001010A, ///< Minimum amount of storage, in bytes, that a single packet occupies in the transmit buffer space of the NIC
RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE = 0x0001010B, ///< Amount of storage, in bytes, that a single packet occupies in the receive buffer space of the NIC
RNDIS_OID_GEN_VENDOR_ID = 0x0001010C, ///< Vendor NIC code
RNDIS_OID_GEN_VENDOR_DESCRIPTION = 0x0001010D, ///< Vendor network card description
RNDIS_OID_GEN_CURRENT_PACKET_FILTER = 0x0001010E, ///< Current packet filter (encoded)
RNDIS_OID_GEN_CURRENT_LOOKAHEAD = 0x0001010F, ///< Current lookahead size in bytes
RNDIS_OID_GEN_DRIVER_VERSION = 0x00010110, ///< NDIS version number used by the driver
RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE = 0x00010111, ///< Maximum total packet length in bytes
RNDIS_OID_GEN_PROTOCOL_OPTIONS = 0x00010112, ///< Optional protocol flags (encoded)
RNDIS_OID_GEN_MAC_OPTIONS = 0x00010113, ///< Optional NIC flags (encoded)
RNDIS_OID_GEN_MEDIA_CONNECT_STATUS = 0x00010114, ///< Whether the NIC is connected to the network
RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS = 0x00010115, ///< The maximum number of send packets the driver can accept per call to its MiniportSendPacketsfunction
//------------- General Optional OIDs -------------//
RNDIS_OID_GEN_VENDOR_DRIVER_VERSION = 0x00010116, ///< Vendor-assigned version number of the driver
RNDIS_OID_GEN_SUPPORTED_GUIDS = 0x00010117, ///< The custom GUIDs (Globally Unique Identifier) supported by the miniport driver
RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES = 0x00010118, ///< List of network-layer addresses associated with the binding between a transport and the driver
RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET = 0x00010119, ///< Size of packets' additional headers
RNDIS_OID_GEN_MEDIA_CAPABILITIES = 0x00010201, ///<
RNDIS_OID_GEN_PHYSICAL_MEDIUM = 0x00010202, ///< Physical media supported by the miniport driver (encoded)
//------------- 802.3 Objects (Ethernet) -------------//
RNDIS_OID_802_3_PERMANENT_ADDRESS = 0x01010101, ///< Permanent station address
RNDIS_OID_802_3_CURRENT_ADDRESS = 0x01010102, ///< Current station address
RNDIS_OID_802_3_MULTICAST_LIST = 0x01010103, ///< Current multicast address list
RNDIS_OID_802_3_MAXIMUM_LIST_SIZE = 0x01010104, ///< Maximum size of multicast address list
} rndis_oid_type_t;
/// RNDIS Packet Filter Bits \ref RNDIS_OID_GEN_CURRENT_PACKET_FILTER.
typedef enum
{
RNDIS_PACKET_TYPE_DIRECTED = 0x00000001, ///< Directed packets. Directed packets contain a destination address equal to the station address of the NIC.
RNDIS_PACKET_TYPE_MULTICAST = 0x00000002, ///< Multicast address packets sent to addresses in the multicast address list.
RNDIS_PACKET_TYPE_ALL_MULTICAST = 0x00000004, ///< All multicast address packets, not just the ones enumerated in the multicast address list.
RNDIS_PACKET_TYPE_BROADCAST = 0x00000008, ///< Broadcast packets.
RNDIS_PACKET_TYPE_SOURCE_ROUTING = 0x00000010, ///< All source routing packets. If the protocol driver sets this bit, the NDIS library attempts to act as a source routing bridge.
RNDIS_PACKET_TYPE_PROMISCUOUS = 0x00000020, ///< Specifies all packets regardless of whether VLAN filtering is enabled or not and whether the VLAN identifier matches or not.
RNDIS_PACKET_TYPE_SMT = 0x00000040, ///< SMT packets that an FDDI NIC receives.
RNDIS_PACKET_TYPE_ALL_LOCAL = 0x00000080, ///< All packets sent by installed protocols and all packets indicated by the NIC that is identified by a given NdisBindingHandle.
RNDIS_PACKET_TYPE_GROUP = 0x00001000, ///< Packets sent to the current group address.
RNDIS_PACKET_TYPE_ALL_FUNCTIONAL = 0x00002000, ///< All functional address packets, not just the ones in the current functional address.
RNDIS_PACKET_TYPE_FUNCTIONAL = 0x00004000, ///< Functional address packets sent to addresses included in the current functional address.
RNDIS_PACKET_TYPE_MAC_FRAME = 0x00008000, ///< NIC driver frames that a Token Ring NIC receives.
RNDIS_PACKET_TYPE_NO_LOCAL = 0x00010000,
} rndis_packet_filter_type_t;
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CDC_RNDIS_H_ */
/** @} */
/** @} */

View File

@ -0,0 +1,63 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup CDC_RNDIS
* \defgroup CDC_RNSID_Host Host
* @{ */
#ifndef _TUSB_CDC_RNDIS_HOST_H_
#define _TUSB_CDC_RNDIS_HOST_H_
#include "common/tusb_common.h"
#include "host/usbh.h"
#include "cdc_rndis.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// INTERNAL RNDIS-CDC Driver API
//--------------------------------------------------------------------+
typedef struct {
OSAL_SEM_DEF(semaphore_notification);
osal_semaphore_handle_t sem_notification_hdl; // used to wait on notification pipe
uint32_t max_xfer_size; // got from device's msg initialize complete
uint8_t mac_address[6];
}rndish_data_t;
void rndish_init(void);
tusb_error_t rndish_open_subtask(uint8_t dev_addr, cdch_data_t *p_cdc);
void rndish_xfer_isr(cdch_data_t *p_cdc, pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
void rndish_close(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CDC_RNDIS_HOST_H_ */
/** @} */

View File

@ -0,0 +1,76 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Sylvain Munaut <tnt@246tNt.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_DFU_RT_DEVICE_H_
#define _TUSB_DFU_RT_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Common Definitions
//--------------------------------------------------------------------+
// DFU Protocol
typedef enum
{
DFU_PROTOCOL_RT = 1,
DFU_PROTOCOL_DFU = 2,
} dfu_protocol_type_t;
// DFU Descriptor Type
typedef enum
{
DFU_DESC_FUNCTIONAL = 0x21,
} dfu_descriptor_type_t;
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
// Invoked when received new data
TU_ATTR_WEAK void tud_dfu_runtime_reboot_to_dfu_cb(void);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void dfu_rtd_init(void);
void dfu_rtd_reset(uint8_t rhport);
uint16_t dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool dfu_rtd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_DFU_RT_DEVICE_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,379 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_HID_DEVICE_H_
#define _TUSB_HID_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#include "hid.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Class Driver Default Configure & Validation
//--------------------------------------------------------------------+
#if !defined(CFG_TUD_HID_EP_BUFSIZE) & defined(CFG_TUD_HID_BUFSIZE)
// TODO warn user to use new name later on
// #warning CFG_TUD_HID_BUFSIZE is renamed to CFG_TUD_HID_EP_BUFSIZE, please update to use the new name
#define CFG_TUD_HID_EP_BUFSIZE CFG_TUD_HID_BUFSIZE
#endif
#ifndef CFG_TUD_HID_EP_BUFSIZE
#define CFG_TUD_HID_EP_BUFSIZE 64
#endif
//--------------------------------------------------------------------+
// Application API (Multiple Ports)
// CFG_TUD_HID > 1
//--------------------------------------------------------------------+
// Check if the interface is ready to use
bool tud_hid_n_ready(uint8_t itf);
// Check if current mode is Boot (true) or Report (false)
bool tud_hid_n_boot_mode(uint8_t itf);
// Send report to host
bool tud_hid_n_report(uint8_t itf, uint8_t report_id, void const* report, uint8_t len);
// KEYBOARD: convenient helper to send keyboard report if application
// use template layout report as defined by hid_keyboard_report_t
bool tud_hid_n_keyboard_report(uint8_t itf, uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
// MOUSE: convenient helper to send mouse report if application
// use template layout report as defined by hid_mouse_report_t
bool tud_hid_n_mouse_report(uint8_t itf, uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
// Gamepad: convenient helper to send mouse report if application
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
bool tud_hid_n_gamepad_report(uint8_t itf, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint16_t buttons);
//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
static inline bool tud_hid_ready(void);
static inline bool tud_hid_boot_mode(void);
static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len);
static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
//--------------------------------------------------------------------+
// Callbacks (Weak is optional)
//--------------------------------------------------------------------+
// Invoked when received GET HID REPORT DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf);
// Invoked when received GET_REPORT control request
// Application must fill buffer report's content and return its length.
// Return zero will cause the stack to STALL request
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen);
// Invoked when received SET_REPORT control request or
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize);
// Invoked when received SET_PROTOCOL request ( mode switch Boot <-> Report )
TU_ATTR_WEAK void tud_hid_boot_mode_cb(uint8_t itf, uint8_t boot_mode);
// Invoked when received SET_IDLE request. return false will stall the request
// - Idle Rate = 0 : only send report if there is changes, i.e skip duplication
// - Idle Rate > 0 : skip duplication, but send at least 1 report every idle rate (in unit of 4 ms).
TU_ATTR_WEAK bool tud_hid_set_idle_cb(uint8_t itf, uint8_t idle_rate);
// Invoked when sent REPORT successfully to host
// Application can use this to send the next report
// Note: For composite reports, report[0] is report ID
TU_ATTR_WEAK void tud_hid_report_complete_cb(uint8_t itf, uint8_t const* report, uint8_t len);
//--------------------------------------------------------------------+
// Inline Functions
//--------------------------------------------------------------------+
static inline bool tud_hid_ready(void)
{
return tud_hid_n_ready(0);
}
static inline bool tud_hid_boot_mode(void)
{
return tud_hid_n_boot_mode(0);
}
static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len)
{
return tud_hid_n_report(0, report_id, report, len);
}
static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6])
{
return tud_hid_n_keyboard_report(0, report_id, modifier, keycode);
}
static inline bool tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal)
{
return tud_hid_n_mouse_report(0, report_id, buttons, x, y, vertical, horizontal);
}
/* --------------------------------------------------------------------+
* HID Report Descriptor Template
*
* Convenient for declaring popular HID device (keyboard, mouse, consumer,
* gamepad etc...). Templates take "HID_REPORT_ID(n)" as input, leave
* empty if multiple reports is not used
*
* - Only 1 report: no parameter
* uint8_t const report_desc[] = { TUD_HID_REPORT_DESC_KEYBOARD() };
*
* - Multiple Reports: "HID_REPORT_ID(ID)" must be passed to template
* uint8_t const report_desc[] =
* {
* TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(1) ) ,
* TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(2) )
* };
*--------------------------------------------------------------------*/
// Keyboard Report Descriptor Template
#define TUD_HID_REPORT_DESC_KEYBOARD(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_KEYBOARD ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
/* 8 bits Modifier Keys (Shfit, Control, Alt) */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
HID_USAGE_MIN ( 224 ) ,\
HID_USAGE_MAX ( 231 ) ,\
HID_LOGICAL_MIN ( 0 ) ,\
HID_LOGICAL_MAX ( 1 ) ,\
HID_REPORT_COUNT ( 8 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 8 bit reserved */ \
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_CONSTANT ) ,\
/* 6-byte Keycodes */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_KEYBOARD ) ,\
HID_USAGE_MIN ( 0 ) ,\
HID_USAGE_MAX ( 255 ) ,\
HID_LOGICAL_MIN ( 0 ) ,\
HID_LOGICAL_MAX ( 255 ) ,\
HID_REPORT_COUNT ( 6 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
/* 5-bit LED Indicator Kana | Compose | ScrollLock | CapsLock | NumLock */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_LED ) ,\
HID_USAGE_MIN ( 1 ) ,\
HID_USAGE_MAX ( 5 ) ,\
HID_REPORT_COUNT ( 5 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* led padding */ \
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 3 ) ,\
HID_OUTPUT ( HID_CONSTANT ) ,\
HID_COLLECTION_END \
// Mouse Report Descriptor Template
#define TUD_HID_REPORT_DESC_MOUSE(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
HID_USAGE_MIN ( 1 ) ,\
HID_USAGE_MAX ( 5 ) ,\
HID_LOGICAL_MIN ( 0 ) ,\
HID_LOGICAL_MAX ( 1 ) ,\
/* Left, Right, Middle, Backward, Forward buttons */ \
HID_REPORT_COUNT( 5 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 3 bit padding */ \
HID_REPORT_COUNT( 1 ) ,\
HID_REPORT_SIZE ( 3 ) ,\
HID_INPUT ( HID_CONSTANT ) ,\
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
/* X, Y position [-127, 127] */ \
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
HID_LOGICAL_MIN ( 0x81 ) ,\
HID_LOGICAL_MAX ( 0x7f ) ,\
HID_REPORT_COUNT( 2 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
/* Verital wheel scroll [-127, 127] */ \
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
HID_LOGICAL_MIN ( 0x81 ) ,\
HID_LOGICAL_MAX ( 0x7f ) ,\
HID_REPORT_COUNT( 1 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
/* Horizontal wheel scroll [-127, 127] */ \
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
HID_LOGICAL_MIN ( 0x81 ), \
HID_LOGICAL_MAX ( 0x7f ), \
HID_REPORT_COUNT( 1 ), \
HID_REPORT_SIZE ( 8 ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
HID_COLLECTION_END , \
HID_COLLECTION_END \
// Consumer Control Report Descriptor Template
#define TUD_HID_REPORT_DESC_CONSUMER(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\
HID_USAGE ( HID_USAGE_CONSUMER_CONTROL ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
HID_LOGICAL_MIN ( 0x00 ) ,\
HID_LOGICAL_MAX_N( 0x03FF, 2 ) ,\
HID_USAGE_MIN ( 0x00 ) ,\
HID_USAGE_MAX_N ( 0x03FF, 2 ) ,\
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 16 ) ,\
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
HID_COLLECTION_END \
/* System Control Report Descriptor Template
* 0x00 - do nothing
* 0x01 - Power Off
* 0x02 - Standby
* 0x04 - Wake Host
*/
#define TUD_HID_REPORT_DESC_SYSTEM_CONTROL(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_CONTROL ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
/* 2 bit system power control */ \
HID_LOGICAL_MIN ( 1 ) ,\
HID_LOGICAL_MAX ( 3 ) ,\
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 2 ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_SLEEP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_POWER_DOWN ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_SYSTEM_WAKE_UP ) ,\
HID_INPUT ( HID_DATA | HID_ARRAY | HID_ABSOLUTE ) ,\
/* 6 bit padding */ \
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 6 ) ,\
HID_INPUT ( HID_CONSTANT ) ,\
HID_COLLECTION_END \
// Gamepad Report Descriptor Template
// with 16 buttons, 2 joysticks and 1 hat/dpad with following layout
// | X | Y | Z | Rz | Rx | Ry (1 byte each) | hat/DPAD (1 byte) | Button Map (2 bytes) |
#define TUD_HID_REPORT_DESC_GAMEPAD(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_GAMEPAD ) ,\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
/* Report ID if any */\
__VA_ARGS__ \
/* 8 bit X, Y, Z, Rz, Rx, Ry (min -127, max 127 ) */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_Z ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RZ ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RX ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_RY ) ,\
HID_LOGICAL_MIN ( 0x81 ) ,\
HID_LOGICAL_MAX ( 0x7f ) ,\
HID_REPORT_COUNT ( 6 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 8 bit DPad/Hat Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
HID_USAGE ( HID_USAGE_DESKTOP_HAT_SWITCH ) ,\
HID_LOGICAL_MIN ( 1 ) ,\
HID_LOGICAL_MAX ( 8 ) ,\
HID_PHYSICAL_MIN ( 0 ) ,\
HID_PHYSICAL_MAX_N ( 315, 2 ) ,\
HID_REPORT_COUNT ( 1 ) ,\
HID_REPORT_SIZE ( 8 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
/* 16 bit Button Map */ \
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
HID_USAGE_MIN ( 1 ) ,\
HID_USAGE_MAX ( 16 ) ,\
HID_LOGICAL_MIN ( 0 ) ,\
HID_LOGICAL_MAX ( 1 ) ,\
HID_REPORT_COUNT ( 16 ) ,\
HID_REPORT_SIZE ( 1 ) ,\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
HID_COLLECTION_END \
// HID Generic Input & Output
// - 1st parameter is report size (mandatory)
// - 2nd parameter is report id HID_REPORT_ID(n) (optional)
#define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \
HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2 ),\
HID_USAGE ( 0x01 ),\
HID_COLLECTION ( HID_COLLECTION_APPLICATION ),\
/* Report ID if any */\
__VA_ARGS__ \
/* Input */ \
HID_USAGE ( 0x02 ),\
HID_LOGICAL_MIN ( 0x00 ),\
HID_LOGICAL_MAX ( 0xff ),\
HID_REPORT_SIZE ( 8 ),\
HID_REPORT_COUNT( report_size ),\
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
/* Output */ \
HID_USAGE ( 0x03 ),\
HID_LOGICAL_MIN ( 0x00 ),\
HID_LOGICAL_MAX ( 0xff ),\
HID_REPORT_SIZE ( 8 ),\
HID_REPORT_COUNT( report_size ),\
HID_OUTPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
HID_COLLECTION_END \
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void hidd_init (void);
void hidd_reset (uint8_t rhport);
uint16_t hidd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool hidd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool hidd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_HID_DEVICE_H_ */

View File

@ -0,0 +1,210 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \addtogroup ClassDriver_HID
* @{ */
#ifndef _TUSB_HID_HOST_H_
#define _TUSB_HID_HOST_H_
#include "common/tusb_common.h"
#include "host/usbh.h"
#include "hid.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// KEYBOARD Application API
//--------------------------------------------------------------------+
/** \addtogroup ClassDriver_HID_Keyboard Keyboard
* @{ */
/** \defgroup Keyboard_Host Host
* The interface API includes status checking function, data transferring function and callback functions
* @{ */
extern uint8_t const hid_keycode_to_ascii_tbl[2][128]; // TODO used weak attr if build failed without KEYBOARD enabled
/** \brief Check if device supports Keyboard interface or not
* \param[in] dev_addr device address
* \retval true if device supports Keyboard interface
* \retval false if device does not support Keyboard interface or is not mounted
*/
bool tuh_hid_keyboard_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_keyboard_get_report.
* Alternatively, asynchronous event API can be used
*/
bool tuh_hid_keyboard_is_busy(uint8_t dev_addr);
/** \brief Perform a get report from Keyboard interface
* \param[in] dev_addr device address
* \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_MEM_SECTION)
* \returns \ref tusb_error_t type to indicate success or error condition.
* \retval TUSB_ERROR_NONE on success
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
*/
tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void * p_report);
//------------- Application Callback -------------//
/** \brief Callback function that is invoked when an transferring event occurred
* \param[in] dev_addr Address of device
* \param[in] event an value from \ref xfer_result_t
* \note event can be one of following
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
* \note Application should schedule the next report by calling \ref tuh_hid_keyboard_get_report within this callback
*/
void tuh_hid_keyboard_isr(uint8_t dev_addr, xfer_result_t event);
/** \brief Callback function that will be invoked when a device with Keyboard interface is mounted
* \param[in] dev_addr Address of newly mounted device
* \note This callback should be used by Application to set-up interface-related data
*/
void tuh_hid_keyboard_mounted_cb(uint8_t dev_addr);
/** \brief Callback function that will be invoked when a device with Keyboard interface is unmounted
* \param[in] dev_addr Address of newly unmounted device
* \note This callback should be used by Application to tear-down interface-related data
*/
void tuh_hid_keyboard_unmounted_cb(uint8_t dev_addr);
/** @} */ // Keyboard_Host
/** @} */ // ClassDriver_HID_Keyboard
//--------------------------------------------------------------------+
// MOUSE Application API
//--------------------------------------------------------------------+
/** \addtogroup ClassDriver_HID_Mouse Mouse
* @{ */
/** \defgroup Mouse_Host Host
* The interface API includes status checking function, data transferring function and callback functions
* @{ */
/** \brief Check if device supports Mouse interface or not
* \param[in] dev_addr device address
* \retval true if device supports Mouse interface
* \retval false if device does not support Mouse interface or is not mounted
*/
bool tuh_hid_mouse_is_mounted(uint8_t dev_addr);
/** \brief Check if the interface is currently busy or not
* \param[in] dev_addr device address
* \retval true if the interface is busy meaning the stack is still transferring/waiting data from/to device
* \retval false if the interface is not busy meaning the stack successfully transferred data from/to device
* \note This function is primarily used for polling/waiting result after \ref tuh_hid_mouse_get_report.
* Alternatively, asynchronous event API can be used
*/
bool tuh_hid_mouse_is_busy(uint8_t dev_addr);
/** \brief Perform a get report from Mouse interface
* \param[in] dev_addr device address
* \param[in,out] p_report address that is used to store data from device. Must be accessible by usb controller (see \ref CFG_TUSB_MEM_SECTION)
* \returns \ref tusb_error_t type to indicate success or error condition.
* \retval TUSB_ERROR_NONE on success
* \retval TUSB_ERROR_INTERFACE_IS_BUSY if the interface is already transferring data with device
* \retval TUSB_ERROR_DEVICE_NOT_READY if device is not yet configured (by SET CONFIGURED request)
* \retval TUSB_ERROR_INVALID_PARA if input parameters are not correct
* \note This function is non-blocking and returns immediately. The result of usb transfer will be reported by the interface's callback function
*/
tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void* p_report);
//------------- Application Callback -------------//
/** \brief Callback function that is invoked when an transferring event occurred
* \param[in] dev_addr Address of device
* \param[in] event an value from \ref xfer_result_t
* \note event can be one of following
* - XFER_RESULT_SUCCESS : previously scheduled transfer completes successfully.
* - XFER_RESULT_FAILED : previously scheduled transfer encountered a transaction error.
* - XFER_RESULT_STALLED : previously scheduled transfer is stalled by device.
* \note Application should schedule the next report by calling \ref tuh_hid_mouse_get_report within this callback
*/
void tuh_hid_mouse_isr(uint8_t dev_addr, xfer_result_t event);
/** \brief Callback function that will be invoked when a device with Mouse interface is mounted
* \param[in] dev_addr Address of newly mounted device
* \note This callback should be used by Application to set-up interface-related data
*/
void tuh_hid_mouse_mounted_cb(uint8_t dev_addr);
/** \brief Callback function that will be invoked when a device with Mouse interface is unmounted
* \param[in] dev_addr Address of newly unmounted device
* \note This callback should be used by Application to tear-down interface-related data
*/
void tuh_hid_mouse_unmounted_cb(uint8_t dev_addr);
/** @} */ // Mouse_Host
/** @} */ // ClassDriver_HID_Mouse
//--------------------------------------------------------------------+
// GENERIC Application API
//--------------------------------------------------------------------+
/** \addtogroup ClassDriver_HID_Generic Generic (not supported yet)
* @{ */
/** \defgroup Generic_Host Host
* The interface API includes status checking function, data transferring function and callback functions
* @{ */
bool tuh_hid_generic_is_mounted(uint8_t dev_addr);
tusb_error_t tuh_hid_generic_get_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
tusb_error_t tuh_hid_generic_set_report(uint8_t dev_addr, void* p_report, bool int_on_complete);
tusb_interface_status_t tuh_hid_generic_get_status(uint8_t dev_addr);
tusb_interface_status_t tuh_hid_generic_set_status(uint8_t dev_addr);
//------------- Application Callback -------------//
void tuh_hid_generic_isr(uint8_t dev_addr, xfer_result_t event);
/** @} */ // Generic_Host
/** @} */ // ClassDriver_HID_Generic
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void hidh_init(void);
bool hidh_open_subtask(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num);
bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void hidh_close(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_HID_HOST_H_ */
/** @} */ // ClassDriver_HID

View File

@ -0,0 +1,212 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup group_class
* \defgroup ClassDriver_CDC Communication Device Class (CDC)
* Currently only Abstract Control Model subclass is supported
* @{ */
#ifndef _TUSB_MIDI_H__
#define _TUSB_MIDI_H__
#include "common/tusb_common.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Class Specific Descriptor
//--------------------------------------------------------------------+
typedef enum
{
MIDI_CS_INTERFACE_HEADER = 0x01,
MIDI_CS_INTERFACE_IN_JACK = 0x02,
MIDI_CS_INTERFACE_OUT_JACK = 0x03,
MIDI_CS_INTERFACE_ELEMENT = 0x04,
} midi_cs_interface_subtype_t;
typedef enum
{
MIDI_CS_ENDPOINT_GENERAL = 0x01
} midi_cs_endpoint_subtype_t;
typedef enum
{
MIDI_JACK_EMBEDDED = 0x01,
MIDI_JACK_EXTERNAL = 0x02
} midi_jack_type_t;
typedef enum
{
MIDI_CIN_MISC = 0,
MIDI_CIN_CABLE_EVENT = 1,
MIDI_CIN_SYSCOM_2BYTE = 2, // 2 byte system common message e.g MTC, SongSelect
MIDI_CIN_SYSCOM_3BYTE = 3, // 3 byte system common message e.g SPP
MIDI_CIN_SYSEX_START = 4, // SysEx starts or continue
MIDI_CIN_SYSEX_END_1BYTE = 5, // SysEx ends with 1 data, or 1 byte system common message
MIDI_CIN_SYSEX_END_2BYTE = 6, // SysEx ends with 2 data
MIDI_CIN_SYSEX_END_3BYTE = 7, // SysEx ends with 3 data
MIDI_CIN_NOTE_ON = 8,
MIDI_CIN_NOTE_OFF = 9,
MIDI_CIN_POLY_KEYPRESS = 10,
MIDI_CIN_CONTROL_CHANGE = 11,
MIDI_CIN_PROGRAM_CHANGE = 12,
MIDI_CIN_CHANNEL_PRESSURE = 13,
MIDI_CIN_PITCH_BEND_CHANGE = 14,
MIDI_CIN_1BYTE_DATA = 15
} midi_code_index_number_t;
// MIDI 1.0 status byte
enum
{
//------------- System Exclusive -------------//
MIDI_STATUS_SYSEX_START = 0xF0,
MIDI_STATUS_SYSEX_END = 0xF7,
//------------- System Common -------------//
MIDI_STATUS_SYSCOM_TIME_CODE_QUARTER_FRAME = 0xF1,
MIDI_STATUS_SYSCOM_SONG_POSITION_POINTER = 0xF2,
MIDI_STATUS_SYSCOM_SONG_SELECT = 0xF3,
// F4, F5 is undefined
MIDI_STATUS_SYSCOM_TUNE_REQUEST = 0xF6,
//------------- System RealTime -------------//
MIDI_STATUS_SYSREAL_TIMING_CLOCK = 0xF8,
// 0xF9 is undefined
MIDI_STATUS_SYSREAL_START = 0xFA,
MIDI_STATUS_SYSREAL_CONTINUE = 0xFB,
MIDI_STATUS_SYSREAL_STOP = 0xFC,
// 0xFD is undefined
MIDI_STATUS_SYSREAL_ACTIVE_SENSING = 0xFE,
MIDI_STATUS_SYSREAL_SYSTEM_RESET = 0xFF,
};
/// MIDI Interface Header Descriptor
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType
uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal
uint16_t wTotalLength ;
} midi_desc_header_t;
/// MIDI In Jack Descriptor
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType
uint8_t bJackType ; ///< Embedded or External
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
uint8_t iJack ; ///< string descriptor
} midi_desc_in_jack_t;
/// MIDI Out Jack Descriptor with single pin
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType
uint8_t bJackType ; ///< Embedded or External
uint8_t bJackID ; ///< Unique ID for MIDI IN Jack
uint8_t bNrInputPins;
uint8_t baSourceID;
uint8_t baSourcePin;
uint8_t iJack ; ///< string descriptor
} midi_desc_out_jack_t ;
/// MIDI Out Jack Descriptor with multiple pins
#define midi_desc_out_jack_n_t(input_num) \
struct TU_ATTR_PACKED { \
uint8_t bLength ; \
uint8_t bDescriptorType ; \
uint8_t bDescriptorSubType ; \
uint8_t bJackType ; \
uint8_t bJackID ; \
uint8_t bNrInputPins ; \
struct TU_ATTR_PACKED { \
uint8_t baSourceID; \
uint8_t baSourcePin; \
} pins[input_num]; \
uint8_t iJack ; \
}
/// MIDI Element Descriptor
typedef struct TU_ATTR_PACKED
{
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< Descriptor Type, must be Class-Specific
uint8_t bDescriptorSubType ; ///< Descriptor SubType
uint8_t bElementID;
uint8_t bNrInputPins;
uint8_t baSourceID;
uint8_t baSourcePin;
uint8_t bNrOutputPins;
uint8_t bInTerminalLink;
uint8_t bOutTerminalLink;
uint8_t bElCapsSize;
uint16_t bmElementCaps;
uint8_t iElement;
} midi_desc_element_t;
/// MIDI Element Descriptor with multiple pins
#define midi_desc_element_n_t(input_num) \
struct TU_ATTR_PACKED { \
uint8_t bLength; \
uint8_t bDescriptorType; \
uint8_t bDescriptorSubType; \
uint8_t bElementID; \
uint8_t bNrInputPins; \
struct TU_ATTR_PACKED { \
uint8_t baSourceID; \
uint8_t baSourcePin; \
} pins[input_num]; \
uint8_t bNrOutputPins; \
uint8_t bInTerminalLink; \
uint8_t bOutTerminalLink; \
uint8_t bElCapsSize; \
uint16_t bmElementCaps; \
uint8_t iElement; \
}
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/** @} */

View File

@ -0,0 +1,176 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_MIDI_DEVICE_H_
#define _TUSB_MIDI_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#include "class/audio/audio.h"
#include "midi.h"
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
#if !defined(CFG_TUD_MIDI_EP_BUFSIZE) && defined(CFG_TUD_MIDI_EPSIZE)
#warning CFG_TUD_MIDI_EPSIZE is renamed to CFG_TUD_MIDI_EP_BUFSIZE, please update to use the new name
#define CFG_TUD_MIDI_EP_BUFSIZE CFG_TUD_MIDI_EPSIZE
#endif
#ifndef CFG_TUD_MIDI_EP_BUFSIZE
#define CFG_TUD_MIDI_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** \addtogroup MIDI_Serial Serial
* @{
* \defgroup MIDI_Serial_Device Device
* @{ */
//--------------------------------------------------------------------+
// Application API (Multiple Interfaces)
// CFG_TUD_MIDI > 1
//--------------------------------------------------------------------+
// Check if midi interface is mounted
bool tud_midi_n_mounted (uint8_t itf);
// Get the number of bytes available for reading
uint32_t tud_midi_n_available (uint8_t itf, uint8_t cable_num);
// Read byte stream (legacy)
uint32_t tud_midi_n_stream_read (uint8_t itf, uint8_t cable_num, void* buffer, uint32_t bufsize);
// Write byte Stream (legacy)
uint32_t tud_midi_n_stream_write (uint8_t itf, uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
// Read event packet (4 bytes)
bool tud_midi_n_packet_read (uint8_t itf, uint8_t packet[4]);
// Write event packet (4 bytes)
bool tud_midi_n_packet_write (uint8_t itf, uint8_t const packet[4]);
//--------------------------------------------------------------------+
// Application API (Single Interface)
//--------------------------------------------------------------------+
static inline bool tud_midi_mounted (void);
static inline uint32_t tud_midi_available (void);
static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize);
static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize);
static inline bool tud_midi_packet_read (uint8_t packet[4]);
static inline bool tud_midi_packet_write (uint8_t const packet[4]);
//------------- Deprecated API name -------------//
// TODO remove after 0.10.0 release
TU_ATTR_DEPRECATED("tud_midi_read() is renamed to tud_midi_stream_read()")
static inline uint32_t tud_midi_read (void* buffer, uint32_t bufsize)
{
return tud_midi_stream_read(buffer, bufsize);
}
TU_ATTR_DEPRECATED("tud_midi_write() is renamed to tud_midi_stream_write()")
static inline uint32_t tud_midi_write(uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
{
return tud_midi_stream_write(cable_num, buffer, bufsize);
}
TU_ATTR_DEPRECATED("tud_midi_send() is renamed to tud_midi_packet_write()")
static inline bool tud_midi_send(uint8_t packet[4])
{
return tud_midi_packet_write(packet);
}
TU_ATTR_DEPRECATED("tud_midi_receive() is renamed to tud_midi_packet_read()")
static inline bool tud_midi_receive(uint8_t packet[4])
{
return tud_midi_packet_read(packet);
}
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
TU_ATTR_WEAK void tud_midi_rx_cb(uint8_t itf);
//--------------------------------------------------------------------+
// Inline Functions
//--------------------------------------------------------------------+
static inline bool tud_midi_mounted (void)
{
return tud_midi_n_mounted(0);
}
static inline uint32_t tud_midi_available (void)
{
return tud_midi_n_available(0, 0);
}
static inline uint32_t tud_midi_stream_read (void* buffer, uint32_t bufsize)
{
return tud_midi_n_stream_read(0, 0, buffer, bufsize);
}
static inline uint32_t tud_midi_stream_write (uint8_t cable_num, uint8_t const* buffer, uint32_t bufsize)
{
return tud_midi_n_stream_write(0, cable_num, buffer, bufsize);
}
static inline bool tud_midi_packet_read (uint8_t packet[4])
{
return tud_midi_n_packet_read(0, packet);
}
static inline bool tud_midi_packet_write (uint8_t const packet[4])
{
return tud_midi_n_packet_write(0, packet);
}
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void midid_init (void);
void midid_reset (uint8_t rhport);
uint16_t midid_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool midid_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool midid_xfer_cb (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_MIDI_DEVICE_H_ */
/** @} */
/** @} */

View File

@ -0,0 +1,392 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup group_class
* \defgroup ClassDriver_MSC MassStorage (MSC)
* @{ */
/** \defgroup ClassDriver_MSC_Common Common Definitions
* @{ */
#ifndef _TUSB_MSC_H_
#define _TUSB_MSC_H_
#include "common/tusb_common.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Mass Storage Class Constant
//--------------------------------------------------------------------+
/// MassStorage Subclass
typedef enum
{
MSC_SUBCLASS_RBC = 1 , ///< Reduced Block Commands (RBC) T10 Project 1240-D
MSC_SUBCLASS_SFF_MMC , ///< SFF-8020i, MMC-2 (ATAPI). Typically used by a CD/DVD device
MSC_SUBCLASS_QIC , ///< QIC-157. Typically used by a tape device
MSC_SUBCLASS_UFI , ///< UFI. Typically used by Floppy Disk Drive (FDD) device
MSC_SUBCLASS_SFF , ///< SFF-8070i. Can be used by Floppy Disk Drive (FDD) device
MSC_SUBCLASS_SCSI ///< SCSI transparent command set
}msc_subclass_type_t;
enum {
MSC_CBW_SIGNATURE = 0x43425355, ///< Constant value of 43425355h (little endian)
MSC_CSW_SIGNATURE = 0x53425355 ///< Constant value of 53425355h (little endian)
};
/// \brief MassStorage Protocol.
/// \details CBI only approved to use with full-speed floopy disk & should not used with highspeed or device other than floopy
typedef enum
{
MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt)
MSC_PROTOCOL_CBI_NO_INTERRUPT = 1 , ///< Control/Bulk/Interrupt protocol (without command completion interrupt)
MSC_PROTOCOL_BOT = 0x50 ///< Bulk-Only Transport
}msc_protocol_type_t;
/// MassStorage Class-Specific Control Request
typedef enum
{
MSC_REQ_GET_MAX_LUN = 254, ///< The Get Max LUN device request is used to determine the number of logical units supported by the device. Logical Unit Numbers on the device shall be numbered contiguously starting from LUN 0 to a maximum LUN of 15
MSC_REQ_RESET = 255 ///< This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host.
}msc_request_type_t;
/// \brief Command Block Status Values
/// \details Indicates the success or failure of the command. The device shall set this byte to zero if the command completed
/// successfully. A non-zero value shall indicate a failure during command execution according to the following
typedef enum
{
MSC_CSW_STATUS_PASSED = 0 , ///< MSC_CSW_STATUS_PASSED
MSC_CSW_STATUS_FAILED , ///< MSC_CSW_STATUS_FAILED
MSC_CSW_STATUS_PHASE_ERROR ///< MSC_CSW_STATUS_PHASE_ERROR
}msc_csw_status_t;
/// Command Block Wrapper
typedef struct TU_ATTR_PACKED
{
uint32_t signature; ///< Signature that helps identify this data packet as a CBW. The signature field shall contain the value 43425355h (little endian), indicating a CBW.
uint32_t tag; ///< Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTagfield of the associated CSW. The dCSWTagpositively associates a CSW with the corresponding CBW.
uint32_t total_bytes; ///< The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as indicated by the Direction bit) during the execution of this command. If this field is zero, the device and the host shall transfer no data between the CBW and the associated CSW, and the device shall ignore the value of the Direction bit in bmCBWFlags.
uint8_t dir; ///< Bit 7 of this field define transfer direction \n - 0 : Data-Out from host to the device. \n - 1 : Data-In from the device to the host.
uint8_t lun; ///< The device Logical Unit Number (LUN) to which the command block is being sent. For devices that support multiple LUNs, the host shall place into this field the LUN to which this command block is addressed. Otherwise, the host shall set this field to zero.
uint8_t cmd_len; ///< The valid length of the CBWCBin bytes. This defines the valid length of the command block. The only legal values are 1 through 16
uint8_t command[16]; ///< The command block to be executed by the device. The device shall interpret the first cmd_len bytes in this field as a command block
}msc_cbw_t;
TU_VERIFY_STATIC(sizeof(msc_cbw_t) == 31, "size is not correct");
/// Command Status Wrapper
typedef struct TU_ATTR_PACKED
{
uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW.
uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW.
uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t
}msc_csw_t;
TU_VERIFY_STATIC(sizeof(msc_csw_t) == 13, "size is not correct");
//--------------------------------------------------------------------+
// SCSI Constant
//--------------------------------------------------------------------+
/// SCSI Command Operation Code
typedef enum
{
SCSI_CMD_TEST_UNIT_READY = 0x00, ///< The SCSI Test Unit Ready command is used to determine if a device is ready to transfer data (read/write), i.e. if a disk has spun up, if a tape is loaded and ready etc. The device does not perform a self-test operation.
SCSI_CMD_INQUIRY = 0x12, ///< The SCSI Inquiry command is used to obtain basic information from a target device.
SCSI_CMD_MODE_SELECT_6 = 0x15, ///< provides a means for the application client to specify medium, logical unit, or peripheral device parameters to the device server. Device servers that implement the MODE SELECT(6) command shall also implement the MODE SENSE(6) command. Application clients should issue MODE SENSE(6) prior to each MODE SELECT(6) to determine supported mode pages, page lengths, and other parameters.
SCSI_CMD_MODE_SENSE_6 = 0x1A, ///< provides a means for a device server to report parameters to an application client. It is a complementary command to the MODE SELECT(6) command. Device servers that implement the MODE SENSE(6) command shall also implement the MODE SELECT(6) command.
SCSI_CMD_START_STOP_UNIT = 0x1B,
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1E,
SCSI_CMD_READ_CAPACITY_10 = 0x25, ///< The SCSI Read Capacity command is used to obtain data capacity information from a target device.
SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device.
SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed
SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer.
SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from the data-out buffer and write them.
}scsi_cmd_type_t;
/// SCSI Sense Key
typedef enum
{
SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command
SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< ndicates the last command completed successfully with some recovery action performed by the disc drive.
SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed.
SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition.
SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test.
SCSI_SENSE_ILLEGAL_REQUEST = 0x05, ///< Indicates an illegal parameter in the command descriptor block or in the additional parameters
SCSI_SENSE_UNIT_ATTENTION = 0x06, ///< Indicates the disc drive may have been reset.
SCSI_SENSE_DATA_PROTECT = 0x07, ///< Indicates that a command that reads or writes the medium was attempted on a block that is protected from this operation. The read or write operation is not performed.
SCSI_SENSE_FIRMWARE_ERROR = 0x08, ///< Vendor specific sense key.
SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command.
SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison.
SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium.
SCSI_SENSE_MISCOMPARE = 0x0e ///< ndicates that the source data did not match the data read from the medium.
}scsi_sense_key_type_t;
//--------------------------------------------------------------------+
// SCSI Primary Command (SPC-4)
//--------------------------------------------------------------------+
/// SCSI Test Unit Ready Command
typedef struct TU_ATTR_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_t;
TU_VERIFY_STATIC(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct");
/// SCSI Inquiry Command
typedef struct TU_ATTR_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_t, scsi_request_sense_t;
TU_VERIFY_STATIC(sizeof(scsi_inquiry_t) == 6, "size is not correct");
/// SCSI Inquiry Response Data
typedef struct TU_ATTR_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;
TU_VERIFY_STATIC(sizeof(scsi_inquiry_resp_t) == 36, "size is not correct");
typedef struct TU_ATTR_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;
TU_VERIFY_STATIC(sizeof(scsi_sense_fixed_resp_t) == 18, "size is not correct");
typedef struct TU_ATTR_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_t;
TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_t) == 6, "size is not correct");
// This is only a Mode parameter header(6).
typedef struct TU_ATTR_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;
TU_VERIFY_STATIC( sizeof(scsi_mode_sense6_resp_t) == 4, "size is not correct");
typedef struct TU_ATTR_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;
TU_VERIFY_STATIC( sizeof(scsi_prevent_allow_medium_removal_t) == 6, "size is not correct");
typedef struct TU_ATTR_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_t;
TU_VERIFY_STATIC( sizeof(scsi_start_stop_unit_t) == 6, "size is not correct");
//--------------------------------------------------------------------+
// SCSI MMC
//--------------------------------------------------------------------+
/// SCSI Read Format Capacity: Write Capacity
typedef struct TU_ATTR_PACKED
{
uint8_t cmd_code;
uint8_t reserved[6];
uint16_t alloc_length;
uint8_t control;
} scsi_read_format_capacity_t;
TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_t) == 10, "size is not correct");
typedef struct TU_ATTR_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_data_t;
TU_VERIFY_STATIC( sizeof(scsi_read_format_capacity_data_t) == 12, "size is not correct");
//--------------------------------------------------------------------+
// SCSI Block Command (SBC-3)
// NOTE: All data in SCSI command are in Big Endian
//--------------------------------------------------------------------+
/// SCSI Read Capacity 10 Command: Read Capacity
typedef struct TU_ATTR_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_t;
TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_t) == 10, "size is not correct");
/// 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;
TU_VERIFY_STATIC(sizeof(scsi_read_capacity10_resp_t) == 8, "size is not correct");
/// SCSI Read 10 Command
typedef struct TU_ATTR_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;
TU_VERIFY_STATIC(sizeof(scsi_read10_t) == 10, "size is not correct");
TU_VERIFY_STATIC(sizeof(scsi_write10_t) == 10, "size is not correct");
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_MSC_H_ */
/// @}
/// @}

View File

@ -0,0 +1,171 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_MSC_DEVICE_H_
#define _TUSB_MSC_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#include "msc.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
#if !defined(CFG_TUD_MSC_EP_BUFSIZE) & defined(CFG_TUD_MSC_BUFSIZE)
// TODO warn user to use new name later on
// #warning CFG_TUD_MSC_BUFSIZE is renamed to CFG_TUD_MSC_EP_BUFSIZE, please update to use the new name
#define CFG_TUD_MSC_EP_BUFSIZE CFG_TUD_MSC_BUFSIZE
#endif
#ifndef CFG_TUD_MSC_EP_BUFSIZE
#error CFG_TUD_MSC_EP_BUFSIZE must be defined, value of a block size should work well, the more the better
#endif
TU_VERIFY_STATIC(CFG_TUD_MSC_EP_BUFSIZE < UINT16_MAX, "Size is not correct");
/** \addtogroup ClassDriver_MSC
* @{
* \defgroup MSC_Device Device
* @{ */
bool tud_msc_set_sense(uint8_t lun, uint8_t sense_key, uint8_t add_sense_code, uint8_t add_sense_qualifier);
//--------------------------------------------------------------------+
// Application Callbacks (WEAK is optional)
//--------------------------------------------------------------------+
/**
* Invoked when received \ref SCSI_CMD_READ_10 command
* \param[in] lun Logical unit number
* \param[in] lba Logical Block Address to be read
* \param[in] offset Byte offset from LBA
* \param[out] buffer Buffer which application need to update with the response data.
* \param[in] bufsize Requested bytes
*
* \return Number of byte read, if it is less than requested bytes by \a \b bufsize. Tinyusb will transfer
* this amount first and invoked this again for remaining data.
*
* \retval zero Indicate application is not ready yet to response e.g disk I/O is not complete.
* tinyusb will invoke this callback with the same parameters again some time later.
*
* \retval negative Indicate error e.g reading disk I/O. tinyusb will \b STALL the corresponding
* endpoint and return failed status in command status wrapper phase.
*/
int32_t tud_msc_read10_cb (uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize);
/**
* Invoked when received \ref SCSI_CMD_WRITE_10 command
* \param[in] lun Logical unit number
* \param[in] lba Logical Block Address to be write
* \param[in] offset Byte offset from LBA
* \param[out] buffer Buffer which holds written data.
* \param[in] bufsize Requested bytes
*
* \return Number of byte written, if it is less than requested bytes by \a \b bufsize. Tinyusb will proceed with
* other work and invoked this again with adjusted parameters.
*
* \retval zero Indicate application is not ready yet e.g disk I/O is not complete.
* Tinyusb will invoke this callback with the same parameters again some time later.
*
* \retval negative Indicate error writing disk I/O. Tinyusb will \b STALL the corresponding
* endpoint and return failed status in command status wrapper phase.
*/
int32_t tud_msc_write10_cb (uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize);
// Invoked when received SCSI_CMD_INQUIRY
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4]);
// Invoked when received Test Unit Ready command.
// return true allowing host to read/write this LUN e.g SD card inserted
bool tud_msc_test_unit_ready_cb(uint8_t lun);
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
// Application update block count and block size
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size);
/**
* Invoked when received an SCSI command not in built-in list below.
* - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE
* - READ10 and WRITE10 has their own callbacks
*
* \param[in] lun Logical unit number
* \param[in] scsi_cmd SCSI command contents which application must examine to response accordingly
* \param[out] buffer Buffer for SCSI Data Stage.
* - For INPUT: application must fill this with response.
* - For OUTPUT it holds the Data from host
* \param[in] bufsize Buffer's length.
*
* \return Actual bytes processed, can be zero for no-data command.
* \retval negative Indicate error e.g unsupported command, tinyusb will \b STALL the corresponding
* endpoint and return failed status in command status wrapper phase.
*/
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize);
/*------------- Optional callbacks -------------*/
// Invoked when received GET_MAX_LUN request, required for multiple LUNs implementation
TU_ATTR_WEAK uint8_t tud_msc_get_maxlun_cb(void);
// Invoked when received Start Stop Unit command
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
TU_ATTR_WEAK bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject);
// Invoked when Read10 command is complete
TU_ATTR_WEAK void tud_msc_read10_complete_cb(uint8_t lun);
// Invoke when Write10 command is complete, can be used to flush flash caching
TU_ATTR_WEAK void tud_msc_write10_complete_cb(uint8_t lun);
// Invoked when command in tud_msc_scsi_cb is complete
TU_ATTR_WEAK void tud_msc_scsi_complete_cb(uint8_t lun, uint8_t const scsi_cmd[16]);
// Hook to make a mass storage device read-only. TODO remove
TU_ATTR_WEAK bool tud_msc_is_writable_cb(uint8_t lun);
/** @} */
/** @} */
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void mscd_init (void);
void mscd_reset (uint8_t rhport);
uint16_t mscd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool mscd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * p_request);
bool mscd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_MSC_DEVICE_H_ */

View File

@ -0,0 +1,131 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_MSC_HOST_H_
#define _TUSB_MSC_HOST_H_
#include "common/tusb_common.h"
#include "host/usbh.h"
#include "msc.h"
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Class Driver Configuration
//--------------------------------------------------------------------+
#ifndef CFG_TUH_MSC_MAXLUN
#define CFG_TUH_MSC_MAXLUN 4
#endif
/** \addtogroup ClassDriver_MSC
* @{
* \defgroup MSC_Host Host
* The interface API includes status checking function, data transferring function and callback functions
* @{ */
typedef bool (*tuh_msc_complete_cb_t)(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw);
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
// Check if device supports MassStorage interface.
// This function true after tuh_msc_mounted_cb() and false after tuh_msc_unmounted_cb()
bool tuh_msc_mounted(uint8_t dev_addr);
// Check if the interface is currently ready or busy transferring data
bool tuh_msc_ready(uint8_t dev_addr);
// Get Max Lun
uint8_t tuh_msc_get_maxlun(uint8_t dev_addr);
// Get number of block
uint32_t tuh_msc_get_block_count(uint8_t dev_addr, uint8_t lun);
// Get block size in bytes
uint32_t tuh_msc_get_block_size(uint8_t dev_addr, uint8_t lun);
// Perform a full SCSI command (cbw, data, csw) in non-blocking manner.
// Complete callback is invoked when SCSI op is complete.
// return true if success, false if there is already pending operation.
bool tuh_msc_scsi_command(uint8_t dev_addr, msc_cbw_t const* cbw, void* data, tuh_msc_complete_cb_t complete_cb);
// Perform SCSI Inquiry command
// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_inquiry(uint8_t dev_addr, uint8_t lun, scsi_inquiry_resp_t* response, tuh_msc_complete_cb_t complete_cb);
// Perform SCSI Test Unit Ready command
// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, tuh_msc_complete_cb_t complete_cb);
// Perform SCSI Request Sense 10 command
// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_request_sense(uint8_t dev_addr, uint8_t lun, void *resposne, tuh_msc_complete_cb_t complete_cb);
// Perform SCSI Read 10 command. Read n blocks starting from LBA to buffer
// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_read10(uint8_t dev_addr, uint8_t lun, void * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb);
// Perform SCSI Write 10 command. Write n blocks starting from LBA to device
// Complete callback is invoked when SCSI op is complete.
bool tuh_msc_write10(uint8_t dev_addr, uint8_t lun, void const * buffer, uint32_t lba, uint16_t block_count, tuh_msc_complete_cb_t complete_cb);
// Perform SCSI Read Capacity 10 command
// Complete callback is invoked when SCSI op is complete.
// Note: during enumeration, host stack already carried out this request. Application can retrieve capacity by
// simply call tuh_msc_get_block_count() and tuh_msc_get_block_size()
bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_resp_t* response, tuh_msc_complete_cb_t complete_cb);
//------------- Application Callback -------------//
// Invoked when a device with MassStorage interface is mounted
void tuh_msc_mount_cb(uint8_t dev_addr);
// Invoked when a device with MassStorage interface is unmounted
void tuh_msc_unmount_cb(uint8_t dev_addr);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void msch_init(void);
bool msch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t *p_length);
bool msch_set_config(uint8_t dev_addr, uint8_t itf_num);
bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
void msch_close(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_MSC_HOST_H_ */
/// @}
/// @}

View File

@ -0,0 +1,87 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Peter Lawrence
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_NET_DEVICE_H_
#define _TUSB_NET_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#include "class/cdc/cdc.h"
/* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */
#define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
/* Maximum Tranmission Unit (in bytes) of the network, including Ethernet header */
#ifndef CFG_TUD_NET_MTU
#define CFG_TUD_NET_MTU 1514
#endif
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
// client must provide this: initialize any network state back to the beginning
void tud_network_init_cb(void);
// client must provide this: return false if the packet buffer was not accepted
bool tud_network_recv_cb(const uint8_t *src, uint16_t size);
// client must provide this: copy from network stack packet pointer to dst
uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg);
// client must provide this: 48-bit MAC address
// TODO removed later since it is not part of tinyusb stack
extern const uint8_t tud_network_mac_address[6];
// indicate to network driver that client has finished with the packet provided to network_recv_cb()
void tud_network_recv_renew(void);
// poll network driver for its ability to accept another packet to transmit
bool tud_network_can_xmit(void);
// if network_can_xmit() returns true, network_xmit() can be called once
void tud_network_xmit(void *ref, uint16_t arg);
//--------------------------------------------------------------------+
// INTERNAL USBD-CLASS DRIVER API
//--------------------------------------------------------------------+
void netd_init (void);
void netd_reset (uint8_t rhport);
uint16_t netd_open (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool netd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
bool netd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
void netd_report (uint8_t *buf, uint16_t len);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_NET_DEVICE_H_ */

View File

@ -0,0 +1,316 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 N Conrad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_USBTMC_H__
#define _TUSB_USBTMC_H__
#include "common/tusb_common.h"
/* Implements USBTMC Revision 1.0, April 14, 2003
String descriptors must have a "LANGID=0x409"/US English string.
Characters must be 0x20 (' ') to 0x7E ('~') ASCII,
But MUST not contain: "/:?\*
Also must not have leading or trailing space (' ')
Device descriptor must state USB version 0x0200 or greater
If USB488DeviceCapabilites.D2 = 1 (SR1), then there must be a INT endpoint.
*/
#define USBTMC_VERSION 0x0100
#define USBTMC_488_VERSION 0x0100
typedef enum {
USBTMC_MSGID_DEV_DEP_MSG_OUT = 1u,
USBTMC_MSGID_DEV_DEP_MSG_IN = 2u,
USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT = 126u,
USBTMC_MSGID_VENDOR_SPECIFIC_IN = 127u,
USBTMC_MSGID_USB488_TRIGGER = 128u,
} usbtmc_msgid_enum;
/// \brief Message header (For BULK OUT and BULK IN); 4 bytes
typedef struct TU_ATTR_PACKED
{
uint8_t MsgID ; ///< Message type ID (usbtmc_msgid_enum)
uint8_t bTag ; ///< Transfer ID 1<=bTag<=255
uint8_t bTagInverse ; ///< Complement of the tag
uint8_t _reserved ; ///< Must be 0x00
} usbtmc_msg_header_t;
typedef struct TU_ATTR_PACKED
{
usbtmc_msg_header_t header;
uint8_t data[8];
} usbtmc_msg_generic_t;
/* Uses on the bulk-out endpoint: */
// Next 8 bytes are message-specific
typedef struct TU_ATTR_PACKED {
usbtmc_msg_header_t header ; ///< Header
uint32_t TransferSize ; ///< Transfer size; LSB first
struct TU_ATTR_PACKED
{
unsigned int EOM : 1 ; ///< EOM set on last byte
} bmTransferAttributes;
uint8_t _reserved[3];
} usbtmc_msg_request_dev_dep_out;
TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_out) == 12u, "struct wrong length");
// Next 8 bytes are message-specific
typedef struct TU_ATTR_PACKED
{
usbtmc_msg_header_t header ; ///< Header
uint32_t TransferSize ; ///< Transfer size; LSB first
struct TU_ATTR_PACKED
{
unsigned int TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar
} bmTransferAttributes;
uint8_t TermChar;
uint8_t _reserved[2];
} usbtmc_msg_request_dev_dep_in;
TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_in) == 12u, "struct wrong length");
/* Bulk-in headers */
typedef struct TU_ATTR_PACKED
{
usbtmc_msg_header_t header;
uint32_t TransferSize;
struct TU_ATTR_PACKED
{
uint8_t EOM: 1; ///< Last byte of transfer is the end of the message
uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar
} bmTransferAttributes;
uint8_t _reserved[3];
} usbtmc_msg_dev_dep_msg_in_header_t;
TU_VERIFY_STATIC(sizeof(usbtmc_msg_dev_dep_msg_in_header_t) == 12u, "struct wrong length");
/* Unsupported vendor things.... Are these ever used?*/
typedef struct TU_ATTR_PACKED
{
usbtmc_msg_header_t header ; ///< Header
uint32_t TransferSize ; ///< Transfer size; LSB first
uint8_t _reserved[4];
} usbtmc_msg_request_vendor_specific_out;
TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_out) == 12u, "struct wrong length");
typedef struct TU_ATTR_PACKED
{
usbtmc_msg_header_t header ; ///< Header
uint32_t TransferSize ; ///< Transfer size; LSB first
uint8_t _reserved[4];
} usbtmc_msg_request_vendor_specific_in;
TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct wrong length");
// Control request type should use tusb_control_request_t
/*
typedef struct TU_ATTR_PACKED {
struct {
unsigned int Recipient : 5 ; ///< EOM set on last byte
unsigned int Type : 2 ; ///< EOM set on last byte
unsigned int DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN
} bmRequestType;
uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum
uint16_t wValue ;
uint16_t wIndex ;
uint16_t wLength ; // Number of bytes in data stage
} usbtmc_class_specific_control_req;
*/
// bulk-in protocol errors
enum {
USBTMC_BULK_IN_ERR_INCOMPLETE_HEADER = 1u,
USBTMC_BULK_IN_ERR_UNSUPPORTED = 2u,
USBTMC_BULK_IN_ERR_BAD_PARAMETER = 3u,
USBTMC_BULK_IN_ERR_DATA_TOO_SHORT = 4u,
USBTMC_BULK_IN_ERR_DATA_TOO_LONG = 5u,
};
// bult-in halt errors
enum {
USBTMC_BULK_IN_ERR = 1u, ///< receives a USBTMC command message that expects a response while a
/// Bulk-IN transfer is in progress
};
typedef enum {
USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u,
USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS = 2u,
USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN = 3u,
USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS = 4u,
USBTMC_bREQUEST_INITIATE_CLEAR = 5u,
USBTMC_bREQUEST_CHECK_CLEAR_STATUS = 6u,
USBTMC_bREQUEST_GET_CAPABILITIES = 7u,
USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional
/****** USBTMC 488 *************/
USB488_bREQUEST_READ_STATUS_BYTE = 128u,
USB488_bREQUEST_REN_CONTROL = 160u,
USB488_bREQUEST_GO_TO_LOCAL = 161u,
USB488_bREQUEST_LOCAL_LOCKOUT = 162u,
} usmtmc_request_type_enum;
typedef enum {
USBTMC_STATUS_SUCCESS = 0x01,
USBTMC_STATUS_PENDING = 0x02,
USBTMC_STATUS_FAILED = 0x80,
USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81,
USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82,
USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83
} usbtmc_status_enum;
/************************************************************
* Control Responses
*/
typedef struct TU_ATTR_PACKED {
uint8_t USBTMC_status; ///< usbtmc_status_enum
uint8_t _reserved;
uint16_t bcdUSBTMC; ///< USBTMC_VERSION
struct TU_ATTR_PACKED
{
unsigned int listenOnly :1;
unsigned int talkOnly :1;
unsigned int supportsIndicatorPulse :1;
} bmIntfcCapabilities;
struct TU_ATTR_PACKED
{
unsigned int canEndBulkInOnTermChar :1;
} bmDevCapabilities;
uint8_t _reserved2[6];
uint8_t _reserved3[12];
} usbtmc_response_capabilities_t;
TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length");
typedef struct TU_ATTR_PACKED
{
uint8_t USBTMC_status;
struct TU_ATTR_PACKED
{
unsigned int BulkInFifoBytes :1;
} bmClear;
} usbtmc_get_clear_status_rsp_t;
TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length");
// Used for both abort bulk IN and bulk OUT
typedef struct TU_ATTR_PACKED
{
uint8_t USBTMC_status;
uint8_t bTag;
} usbtmc_initiate_abort_rsp_t;
TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length");
// Used for both check_abort_bulk_in_status and check_abort_bulk_out_status
typedef struct TU_ATTR_PACKED
{
uint8_t USBTMC_status;
struct TU_ATTR_PACKED
{
unsigned int BulkInFifoBytes : 1; ///< Has queued data or a short packet that is queued
} bmAbortBulkIn;
uint8_t _reserved[2]; ///< Must be zero
uint32_t NBYTES_RXD_TXD;
} usbtmc_check_abort_bulk_rsp_t;
TU_VERIFY_STATIC(sizeof(usbtmc_check_abort_bulk_rsp_t) == 8u, "struct wrong length");
typedef struct TU_ATTR_PACKED
{
uint8_t USBTMC_status; ///< usbtmc_status_enum
uint8_t _reserved;
uint16_t bcdUSBTMC; ///< USBTMC_VERSION
struct TU_ATTR_PACKED
{
unsigned int listenOnly :1;
unsigned int talkOnly :1;
unsigned int supportsIndicatorPulse :1;
} bmIntfcCapabilities;
struct TU_ATTR_PACKED
{
unsigned int canEndBulkInOnTermChar :1;
} bmDevCapabilities;
uint8_t _reserved2[6];
uint16_t bcdUSB488;
struct TU_ATTR_PACKED
{
unsigned int is488_2 :1;
unsigned int supportsREN_GTL_LLO :1;
unsigned int supportsTrigger :1;
} bmIntfcCapabilities488;
struct TU_ATTR_PACKED
{
unsigned int SCPI :1;
unsigned int SR1 :1;
unsigned int RL1 :1;
unsigned int DT1 :1;
} bmDevCapabilities488;
uint8_t _reserved3[8];
} usbtmc_response_capabilities_488_t;
TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_488_t) == 0x18, "struct wrong length");
typedef struct TU_ATTR_PACKED
{
uint8_t USBTMC_status;
uint8_t bTag;
uint8_t statusByte;
} usbtmc_read_stb_rsp_488_t;
TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length");
typedef struct TU_ATTR_PACKED
{
struct TU_ATTR_PACKED
{
unsigned int bTag : 7;
unsigned int one : 1;
} bNotify1;
uint8_t StatusByte;
} usbtmc_read_stb_interrupt_488_t;
TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length");
#endif

View File

@ -0,0 +1,122 @@
/*
* usbtmc_device.h
*
* Created on: Sep 10, 2019
* Author: nconrad
*/
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 N Conrad
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef CLASS_USBTMC_USBTMC_DEVICE_H_
#define CLASS_USBTMC_USBTMC_DEVICE_H_
#include "usbtmc.h"
// Enable 488 mode by default
#if !defined(CFG_TUD_USBTMC_ENABLE_488)
#define CFG_TUD_USBTMC_ENABLE_488 (1)
#endif
// USB spec says that full-speed must be 8,16,32, or 64.
// However, this driver implementation requires it to be >=32
#define USBTMCD_MAX_PACKET_SIZE (64u)
/***********************************************
* Functions to be implemeted by the class implementation
*/
// In order to proceed, app must call call tud_usbtmc_start_bus_read(rhport) during or soon after:
// * tud_usbtmc_open_cb
// * tud_usbtmc_msg_data_cb
// * tud_usbtmc_msgBulkIn_complete_cb
// * tud_usbtmc_msg_trigger_cb
// * (successful) tud_usbtmc_check_abort_bulk_out_cb
// * (successful) tud_usbtmc_check_abort_bulk_in_cb
// * (successful) tud_usmtmc_bulkOut_clearFeature_cb
#if (CFG_TUD_USBTMC_ENABLE_488)
usbtmc_response_capabilities_488_t const * tud_usbtmc_get_capabilities_cb(void);
#else
usbtmc_response_capabilities_t const * tud_usbtmc_get_capabilities_cb(void);
#endif
void tud_usbtmc_open_cb(uint8_t interface_id);
bool tud_usbtmc_msgBulkOut_start_cb(usbtmc_msg_request_dev_dep_out const * msgHeader);
// transfer_complete does not imply that a message is complete.
bool tud_usbtmc_msg_data_cb( void *data, size_t len, bool transfer_complete);
void tud_usbtmc_bulkOut_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer
bool tud_usbtmc_msgBulkIn_request_cb(usbtmc_msg_request_dev_dep_in const * request);
bool tud_usbtmc_msgBulkIn_complete_cb(void);
void tud_usbtmc_bulkIn_clearFeature_cb(void); // Notice to clear and abort the pending BULK out transfer
bool tud_usbtmc_initiate_abort_bulk_in_cb(uint8_t *tmcResult);
bool tud_usbtmc_initiate_abort_bulk_out_cb(uint8_t *tmcResult);
bool tud_usbtmc_initiate_clear_cb(uint8_t *tmcResult);
bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp);
bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp);
bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp);
// Indicator pulse should be 0.5 to 1.0 seconds long
TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult);
#if (CFG_TUD_USBTMC_ENABLE_488)
uint8_t tud_usbtmc_get_stb_cb(uint8_t *tmcResult);
TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg);
//TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb();
#endif
/*******************************************
* Called from app
*
* We keep a reference to the buffer, so it MUST not change until the app is
* notified that the transfer is complete.
******************************************/
bool tud_usbtmc_transmit_dev_msg_data(
const void * data, size_t len,
bool endOfMessage, bool usingTermChar);
bool tud_usbtmc_start_bus_read(void);
/* "callbacks" from USB device core */
uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
void usbtmcd_reset_cb(uint8_t rhport);
bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
void usbtmcd_init_cb(void);
/************************************************************
* USBTMC Descriptor Templates
*************************************************************/
#endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */

View File

@ -0,0 +1,130 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_VENDOR_DEVICE_H_
#define _TUSB_VENDOR_DEVICE_H_
#include "common/tusb_common.h"
#include "device/usbd.h"
#ifndef CFG_TUD_VENDOR_EPSIZE
#define CFG_TUD_VENDOR_EPSIZE 64
#endif
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------+
// Application API (Multiple Interfaces)
//--------------------------------------------------------------------+
bool tud_vendor_n_mounted (uint8_t itf);
uint32_t tud_vendor_n_available (uint8_t itf);
uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize);
bool tud_vendor_n_peek (uint8_t itf, int pos, uint8_t* u8);
uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize);
uint32_t tud_vendor_n_write_available (uint8_t itf);
static inline
uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str);
//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
static inline bool tud_vendor_mounted (void);
static inline uint32_t tud_vendor_available (void);
static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize);
static inline bool tud_vendor_peek (int pos, uint8_t* u8);
static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize);
static inline uint32_t tud_vendor_write_str (char const* str);
static inline uint32_t tud_vendor_write_available (void);
//--------------------------------------------------------------------+
// Application Callback API (weak is optional)
//--------------------------------------------------------------------+
// Invoked when received new data
TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf);
//--------------------------------------------------------------------+
// Inline Functions
//--------------------------------------------------------------------+
static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str)
{
return tud_vendor_n_write(itf, str, strlen(str));
}
static inline bool tud_vendor_mounted (void)
{
return tud_vendor_n_mounted(0);
}
static inline uint32_t tud_vendor_available (void)
{
return tud_vendor_n_available(0);
}
static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize)
{
return tud_vendor_n_read(0, buffer, bufsize);
}
static inline bool tud_vendor_peek (int pos, uint8_t* u8)
{
return tud_vendor_n_peek(0, pos, u8);
}
static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize)
{
return tud_vendor_n_write(0, buffer, bufsize);
}
static inline uint32_t tud_vendor_write_str (char const* str)
{
return tud_vendor_n_write_str(0, str);
}
static inline uint32_t tud_vendor_write_available (void)
{
return tud_vendor_n_write_available(0);
}
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void vendord_init(void);
void vendord_reset(uint8_t rhport);
uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_VENDOR_DEVICE_H_ */

View File

@ -0,0 +1,74 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
/** \ingroup group_class
* \defgroup Group_Custom Custom Class (not supported yet)
* @{ */
#ifndef _TUSB_VENDOR_HOST_H_
#define _TUSB_VENDOR_HOST_H_
#include "common/tusb_common.h"
#include "host/usbh.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
pipe_handle_t pipe_in;
pipe_handle_t pipe_out;
}custom_interface_info_t;
//--------------------------------------------------------------------+
// USBH-CLASS DRIVER API
//--------------------------------------------------------------------+
static inline bool tusbh_custom_is_mounted(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id)
{
(void) vendor_id; // TODO check this later
(void) product_id;
// return (tusbh_device_get_mounted_class_flag(dev_addr) & TU_BIT(TUSB_CLASS_MAPPED_INDEX_END-1) ) != 0;
return false;
}
tusb_error_t tusbh_custom_read(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void * p_buffer, uint16_t length);
tusb_error_t tusbh_custom_write(uint8_t dev_addr, uint16_t vendor_id, uint16_t product_id, void const * p_data, uint16_t length);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void cush_init(void);
tusb_error_t cush_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length);
void cush_isr(pipe_handle_t pipe_hdl, xfer_result_t event);
void cush_close(uint8_t dev_addr);
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_VENDOR_HOST_H_ */
/** @} */