improving midi support, adding midi exmaple

rename TUSB_DESC_CLASS_SPECIFIC to TUSB_DESC_CS_INTERFACE
This commit is contained in:
hathach 2019-07-01 22:38:06 +07:00
parent 991aaf0158
commit 6991b28532
15 changed files with 596 additions and 51 deletions

View File

@ -32,7 +32,7 @@
* [MSB] HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) )
//------------- Device Descriptors -------------//
tusb_desc_device_t const desc_device =
@ -188,6 +188,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
chr_count = 1;
}else
{
// Convert ASCII string into UTF-16
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];

View File

@ -32,7 +32,7 @@
* [MSB] HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) )
//------------- Device Descriptors -------------//
tusb_desc_device_t const desc_device =
@ -126,7 +126,7 @@ enum
uint8_t const desc_configuration[] =
{
// Inteface count, string index, total length, attribute, power in mA
// interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
#if CFG_TUD_CDC
@ -189,6 +189,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
chr_count = 1;
}else
{
// Convert ASCII string into UTF-16
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];

View File

@ -32,7 +32,7 @@
* [MSB] HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) )
//------------- Device Descriptors -------------//
tusb_desc_device_t const desc_device =
@ -81,7 +81,7 @@ enum
uint8_t const desc_configuration[] =
{
// Inteface count, string index, total length, attribute, power in mA
// interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, protocol, report descriptor len, EP In & Out address, size & polling interval
@ -138,6 +138,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
chr_count = 1;
}else
{
// Convert ASCII string into UTF-16
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];

View File

@ -0,0 +1,12 @@
include ../../../tools/top.mk
include ../../make.mk
INC += \
src \
$(TOP)/hw \
# Example source
EXAMPLE_SOURCE += $(wildcard src/*.c)
SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE))
include ../../rules.mk

View File

@ -0,0 +1,115 @@
/*
* 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.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "bsp/board.h"
#include "tusb.h"
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+
/* Blink pattern
* - 250 ms : device not mounted
* - 1000 ms : device mounted
* - 2500 ms : device is suspended
*/
enum {
BLINK_NOT_MOUNTED = 250,
BLINK_MOUNTED = 1000,
BLINK_SUSPENDED = 2500,
};
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
void led_blinking_task(void);
/*------------- MAIN -------------*/
int main(void)
{
board_init();
tusb_init();
while (1)
{
// tinyusb device task
tud_task();
led_blinking_task();
}
return 0;
}
//--------------------------------------------------------------------+
// Device callbacks
//--------------------------------------------------------------------+
// Invoked when device is mounted
void tud_mount_cb(void)
{
blink_interval_ms = BLINK_MOUNTED;
}
// Invoked when device is unmounted
void tud_umount_cb(void)
{
blink_interval_ms = BLINK_NOT_MOUNTED;
}
// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
void tud_suspend_cb(bool remote_wakeup_en)
{
(void) remote_wakeup_en;
blink_interval_ms = BLINK_SUSPENDED;
}
// Invoked when usb bus is resumed
void tud_resume_cb(void)
{
blink_interval_ms = BLINK_MOUNTED;
}
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
void led_blinking_task(void)
{
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every 1000 ms
if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time
start_ms += blink_interval_ms;
board_led_write(led_state);
led_state = 1 - led_state; // toggle
}

View File

@ -0,0 +1,85 @@
/*
* 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.
*
*/
#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------
// defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif
#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else
#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE
#endif
#define CFG_TUSB_OS OPT_OS_NONE
// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG 0
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
* Tinyusb use follows macros to declare transferring memory so that they can be put
* into those specific section.
* e.g
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
*/
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif
#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
#endif
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#define CFG_TUD_ENDOINT0_SIZE 64
//------------- CLASS -------------//
#define CFG_TUD_CDC 0
#define CFG_TUD_MSC 0
#define CFG_TUD_HID 0
#define CFG_TUD_MIDI 1
#define CFG_TUD_CUSTOM_CLASS 0
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */

View File

@ -0,0 +1,149 @@
/*
* 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.
*
*/
#include "tusb.h"
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
*
* Auto ProductID layout's Bitmap:
* [MSB] MIDI | HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) )
//------------- Device Descriptors -------------//
tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
.bDescriptorType = TUSB_DESC_DEVICE,
.bcdUSB = 0x0200,
// Use Interface Association Descriptor (IAD) for Audio
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE,
.idVendor = 0xCafe,
.idProduct = USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
//------------- Configuration Descriptor -------------//
enum
{
ITF_NUM_MIDI = 0,
ITF_NUM_MIDI_STREAMING,
ITF_NUM_TOTAL
};
enum
{
CONFIG_TOTAL_LEN = TUD_CONFIG_DESC_LEN + TUD_MIDI_DESC_LEN
};
// Use Endpoint 2 instead of 1 due to NXP MCU
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ...
#define EPNUM_MIDI 0x02
uint8_t const desc_configuration[] =
{
// Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 0, EPNUM_MIDI, 0x80 | EPNUM_MIDI, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64)
};
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void)
{
return (uint8_t const *) &desc_device;
}
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
{
(void) index; // for multiple configurations
return desc_configuration;
}
//------------- String Descriptors -------------//
// array of pointer to string descriptors
char const* string_desc_arr [] =
{
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"TinyUSB", // 1: Manufacturer
"TinyUSB Device", // 2: Product
"123456", // 3: Serials, should use chip ID
};
static uint16_t _desc_str[32];
// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const* tud_descriptor_string_cb(uint8_t index)
{
uint8_t chr_count;
if ( index == 0)
{
memcpy(&_desc_str[1], string_desc_arr[0], 2);
chr_count = 1;
}else
{
// Convert ASCII string into UTF-16
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];
// Cap at max char
chr_count = strlen(str);
if ( chr_count > 31 ) chr_count = 31;
for(uint8_t i=0; i<chr_count; i++)
{
_desc_str[1+i] = str[i];
}
}
// first byte is len, second byte is string type
_desc_str[0] = TUD_DESC_STR_HEADER(chr_count);
return _desc_str;
}

View File

@ -32,7 +32,7 @@
* [MSB] HID | MSC | CDC [LSB]
*/
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) )
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | _PID_MAP(MIDI, 3) )
//------------- Device Descriptors -------------//
tusb_desc_device_t const desc_device =
@ -75,7 +75,7 @@ enum
uint8_t const desc_configuration[] =
{
// Inteface count, string index, total length, attribute, power in mA
// interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
// Interface number, string index, EP Out & EP In address, EP size
@ -123,6 +123,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
chr_count = 1;
}else
{
// Convert ASCII string into UTF-16
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
const char* str = string_desc_arr[index];

View File

@ -29,8 +29,8 @@
* Currently only MIDI subclass is supported
* @{ */
#ifndef _TUSB_CDC_H__
#define _TUSB_CDC_H__
#ifndef _TUSB_AUDIO_H__
#define _TUSB_AUDIO_H__
#include "common/tusb_common.h"
@ -41,9 +41,9 @@
/// Audio Interface Subclass Codes
typedef enum
{
AUDIO_SUBCLASS_AUDIO_CONTROL = 0x01 , ///< Audio Control
AUDIO_SUBCLASS_AUDIO_STREAMING , ///< Audio Streaming
AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
AUDIO_SUBCLASS_CONTROL = 0x01 , ///< Audio Control
AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming
AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
} audio_subclass_type_t;
/// Audio Protocol Codes
@ -54,6 +54,40 @@ typedef enum
AUDIO_PROTOCOL_V3 = 0x30, ///< Version 3.0
} audio_protocol_type_t;
/// Audio Function Category Codes
typedef enum
{
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_function_t;
/// Audio Class-Specific AC Interface Descriptor Subtypes
typedef enum
{
AUDIO_CS_INTERFACE_HEADER = 0x01,
AUDIO_CS_INTERFACE_INPUT_TERMINAL = 0x02,
AUDIO_CS_INTERFACE_OUTPUT_TERMINAL = 0x03,
AUDIO_CS_INTERFACE_MIXER_UNIT = 0x04,
AUDIO_CS_INTERFACE_SELECTOR_UNIT = 0x05,
AUDIO_CS_INTERFACE_FEATURE_UNIT = 0x06,
AUDIO_CS_INTERFACE_EFFECT_UNIT = 0x07,
AUDIO_CS_INTERFACE_PROCESSING_UNIT = 0x08,
AUDIO_CS_INTERFACE_EXTENSION_UNIT = 0x09,
AUDIO_CS_INTERFACE_CLOCK_SOURCE = 0x0A,
AUDIO_CS_INTERFACE_CLOCK_SELECTOR = 0x0B,
AUDIO_CS_INTERFACE_CLOCK_MULTIPLIER = 0x0C,
AUDIO_CS_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D,
} audio_cs_interface_subtype_t;
/** @} */

View File

@ -41,7 +41,7 @@
/** \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
{
@ -52,8 +52,9 @@ typedef enum
}cdc_pipeid_t;
//--------------------------------------------------------------------+
// CDC COMMUNICATION INTERFACE CLASS
// CDC Communication Interface Class
//--------------------------------------------------------------------+
/// Communication Interface Subclass Codes
typedef enum
{
@ -117,7 +118,7 @@ typedef enum
}cdc_func_desc_type_t;
//--------------------------------------------------------------------+
// CDC DATA INTERFACE CLASS
// CDC Data Interface Class
//--------------------------------------------------------------------+
// SUBCLASS code of Data Interface is not used and should/must be zero
@ -138,8 +139,9 @@ typedef enum{
}cdc_data_protocol_type_t;
//--------------------------------------------------------------------+
// MANAGEMENT ELEMENT REQUEST (CONTROL ENDPOINT)
// Management Element Request (Control Endpoint)
//--------------------------------------------------------------------+
/// Communication Interface Management Element Request Codes
typedef enum
{
@ -189,8 +191,9 @@ typedef enum
}cdc_management_request_t;
//--------------------------------------------------------------------+
// MANAGEMENT ELEMENENT NOTIFICATION (NOTIFICATION ENDPOINT)
// Management Elemenent Notification (Notification Endpoint)
//--------------------------------------------------------------------+
/// Communication Interface Management Element Notification Codes
typedef enum
{
@ -209,14 +212,15 @@ typedef enum
}cdc_notification_request_t;
//--------------------------------------------------------------------+
// FUNCTIONAL DESCRIPTOR (COMMUNICATION INTERFACE)
// 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_FUCN_DESC_
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;
@ -246,7 +250,7 @@ typedef struct TU_ATTR_PACKED
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.
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) \

View File

@ -265,7 +265,7 @@ bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t
(*p_length) = sizeof(tusb_desc_interface_t);
// Communication Functional Descriptors
while ( TUSB_DESC_CLASS_SPECIFIC == tu_desc_type(p_desc) )
while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) )
{
(*p_length) += tu_desc_len(p_desc);
p_desc = tu_desc_next(p_desc);

View File

@ -142,7 +142,7 @@ bool cdch_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *it
(*p_length) = sizeof(tusb_desc_interface_t);
// Communication Functional Descriptors
while( TUSB_DESC_CLASS_SPECIFIC == p_desc[DESC_OFFSET_TYPE] )
while( TUSB_DESC_CS_INTERFACE == p_desc[DESC_OFFSET_TYPE] )
{
if ( CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT == cdc_functional_desc_typeof(p_desc) )
{

View File

@ -39,27 +39,122 @@
#endif
//--------------------------------------------------------------------+
// FUNCTIONAL DESCRIPTOR (COMMUNICATION INTERFACE)
// Class Specific Descriptor
//--------------------------------------------------------------------+
/// Header Functional Descriptor (Communication Interface)
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;
/// 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 one of above MIDI_FUCN_DESC_
uint8_t bDescriptorSubType ; ///< Descriptor SubType
uint16_t bcdMSC ; ///< MidiStreaming SubClass release number in Binary-Coded Decimal
uint16_t wTotalLength ;
}midi_desc_func_header_t;
} midi_desc_header_t;
/// Union Functional Descriptor (Communication Interface)
/// 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 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;
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; \
}
/** @} */

View File

@ -72,18 +72,24 @@ typedef enum
/// USB Descriptor Types (section 9.4 table 9-5)
typedef enum
{
TUSB_DESC_DEVICE = 0x01 ,
TUSB_DESC_CONFIGURATION = 0x02 ,
TUSB_DESC_STRING = 0x03 ,
TUSB_DESC_INTERFACE = 0x04 ,
TUSB_DESC_ENDPOINT = 0x05 ,
TUSB_DESC_DEVICE_QUALIFIER = 0x06 ,
TUSB_DESC_OTHER_SPEED_CONFIG = 0x07 ,
TUSB_DESC_INTERFACE_POWER = 0x08 ,
TUSB_DESC_OTG = 0x09 ,
TUSB_DESC_DEBUG = 0x0A ,
TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B ,
TUSB_DESC_CLASS_SPECIFIC = 0x24
TUSB_DESC_DEVICE = 0x01,
TUSB_DESC_CONFIGURATION = 0x02,
TUSB_DESC_STRING = 0x03,
TUSB_DESC_INTERFACE = 0x04,
TUSB_DESC_ENDPOINT = 0x05,
TUSB_DESC_DEVICE_QUALIFIER = 0x06,
TUSB_DESC_OTHER_SPEED_CONFIG = 0x07,
TUSB_DESC_INTERFACE_POWER = 0x08,
TUSB_DESC_OTG = 0x09,
TUSB_DESC_DEBUG = 0x0A,
TUSB_DESC_INTERFACE_ASSOCIATION = 0x0B,
// Class Specific Descriptor
TUSB_DESC_CS_DEVICE = 0x21,
TUSB_DESC_CS_CONFIGURATION = 0x22,
TUSB_DESC_CS_STRING = 0x23,
TUSB_DESC_CS_INTERFACE = 0x24,
TUSB_DESC_CS_ENDPOINT = 0x25,
}tusb_desc_type_t;
typedef enum
@ -105,9 +111,9 @@ typedef enum
typedef enum
{
TUSB_REQ_FEATURE_EDPT_HALT = 0,
TUSB_REQ_FEATURE_EDPT_HALT = 0,
TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1,
TUSB_REQ_FEATURE_TEST_MODE = 2
TUSB_REQ_FEATURE_TEST_MODE = 2
}tusb_request_feature_selector_t;
typedef enum

View File

@ -111,13 +111,13 @@ TU_ATTR_WEAK void tud_resume_cb(void);
/* CDC Control Interface */\
9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, _stridx,\
/* CDC Header */\
5, TUSB_DESC_CLASS_SPECIFIC, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\
/* CDC Call */\
5, TUSB_DESC_CLASS_SPECIFIC, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (_itfnum) + 1,\
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_CALL_MANAGEMENT, 0, (_itfnum) + 1,\
/* CDC ACM: support line request */\
4, TUSB_DESC_CLASS_SPECIFIC, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\
4, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT, 2,\
/* CDC Union */\
5, TUSB_DESC_CLASS_SPECIFIC, CDC_FUNC_DESC_UNION, _itfnum, (_itfnum) + 1,\
5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_UNION, _itfnum, (_itfnum) + 1,\
/* Endpoint Notification */\
7, TUSB_DESC_ENDPOINT, _ep_notif, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_notif_size), 16,\
/* CDC Data Interface */\
@ -171,6 +171,43 @@ TU_ATTR_WEAK void tud_resume_cb(void);
/* Endpoint Out */\
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_epsize), _ep_interval
//------------- MIDI -------------//
// Length of template descriptor (96 bytes)
#define TUD_MIDI_DESC_LEN (8 + 9 + 9 + 9 + 7 + 6 + 6 + 9 + 9 + 7 + 5 + 7 + 5)
// MIDI simple descriptor
// - 1 Embedded Jack In connected to 1 External Jack Out
// - 1 Embedded Jack out connected to 1 External Jack In
#define TUD_MIDI_DESCRIPTOR(_itfnum, _stridx, _epin, _epout, _epsize) \
/* Interface Associate */\
8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_AUDIO, 0x00, AUDIO_PROTOCOL_V1, 0,\
/* Audio Control (AC) Interface */\
9, TUSB_DESC_INTERFACE, _itfnum, 0, 0, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_CONTROL, AUDIO_PROTOCOL_V1, _stridx,\
/* AC Header */\
9, TUSB_DESC_CS_INTERFACE, AUDIO_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0009), 1, _itfnum+1,\
/* MIDI Streaming (MS) Interface */\
9, TUSB_DESC_INTERFACE, _itfnum+1, 0, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_PROTOCOL_V1, 0,\
/* MS Header */\
7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0100), U16_TO_U8S_LE(0x0025),\
/* MS In Jack (Embedded) */\
6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EMBEDDED, 1, 0,\
/* MS In Jack (External) */\
6, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_IN_JACK, MIDI_JACK_EXTERNAL, 2, 0,\
/* MS Out Jack (Embedded), connected to In Jack External */\
9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EMBEDDED, 3, 1, 2, 1,\
/* MS Out Jack (External), connected to In Jack Embedded */\
9, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_OUT_JACK, MIDI_JACK_EXTERNAL, 4, 1, 1, 1,\
/* Endpoint Out */\
7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
/* MS Endpoint (connected to embedded jack in) */\
5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 1,\
/* Endpoint In */\
7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0,\
/* MS Endpoint (connected to embedded jack out) */\
5, TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL, 1, 3
#ifdef __cplusplus
}
#endif