diff options
| author | hathach <[email protected]> | 2019-07-01 22:38:06 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2019-07-01 22:38:06 +0700 |
| commit | 6991b28532605ceae685cb8be1fee904e09f12fe (patch) | |
| tree | 2d383bce7e232d56ee072f5fccdf2b688228da8d | |
| parent | 991aaf0158fcb02f7951a895a0caa6637e84fd8a (diff) | |
improving midi support, adding midi exmaple
rename TUSB_DESC_CLASS_SPECIFIC to TUSB_DESC_CS_INTERFACE
| -rw-r--r-- | examples/device/cdc_msc_hid/src/usb_descriptors.c | 4 | ||||
| -rw-r--r-- | examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c | 6 | ||||
| -rw-r--r-- | examples/device/hid_generic_inout/src/usb_descriptors.c | 6 | ||||
| -rw-r--r-- | examples/device/midi/Makefile | 12 | ||||
| -rw-r--r-- | examples/device/midi/src/main.c | 115 | ||||
| -rw-r--r-- | examples/device/midi/src/tusb_config.h | 85 | ||||
| -rw-r--r-- | examples/device/midi/src/usb_descriptors.c | 149 | ||||
| -rw-r--r-- | examples/device/msc_dual_lun/src/usb_descriptors.c | 6 | ||||
| -rw-r--r-- | src/class/audio/audio.h | 44 | ||||
| -rw-r--r-- | src/class/cdc/cdc.h | 20 | ||||
| -rw-r--r-- | src/class/cdc/cdc_device.c | 2 | ||||
| -rw-r--r-- | src/class/cdc/cdc_host.c | 2 | ||||
| -rw-r--r-- | src/class/midi/midi.h | 117 | ||||
| -rw-r--r-- | src/common/tusb_types.h | 34 | ||||
| -rw-r--r-- | src/device/usbd.h | 45 |
15 files changed, 596 insertions, 51 deletions
diff --git a/examples/device/cdc_msc_hid/src/usb_descriptors.c b/examples/device/cdc_msc_hid/src/usb_descriptors.c index 8cd6062be..1692151a0 100644 --- a/examples/device/cdc_msc_hid/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid/src/usb_descriptors.c @@ -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]; diff --git a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c index b60615ca7..579e1ebcf 100644 --- a/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_hid_freertos/src/usb_descriptors.c @@ -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]; diff --git a/examples/device/hid_generic_inout/src/usb_descriptors.c b/examples/device/hid_generic_inout/src/usb_descriptors.c index 3cf0f711b..ced915935 100644 --- a/examples/device/hid_generic_inout/src/usb_descriptors.c +++ b/examples/device/hid_generic_inout/src/usb_descriptors.c @@ -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]; diff --git a/examples/device/midi/Makefile b/examples/device/midi/Makefile new file mode 100644 index 000000000..5a455078e --- /dev/null +++ b/examples/device/midi/Makefile @@ -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 diff --git a/examples/device/midi/src/main.c b/examples/device/midi/src/main.c new file mode 100644 index 000000000..60500df93 --- /dev/null +++ b/examples/device/midi/src/main.c @@ -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 +} diff --git a/examples/device/midi/src/tusb_config.h b/examples/device/midi/src/tusb_config.h new file mode 100644 index 000000000..cb6eca33c --- /dev/null +++ b/examples/device/midi/src/tusb_config.h @@ -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_ */ diff --git a/examples/device/midi/src/usb_descriptors.c b/examples/device/midi/src/usb_descriptors.c new file mode 100644 index 000000000..192dacfbe --- /dev/null +++ b/examples/device/midi/src/usb_descriptors.c @@ -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; +} diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index 24bed9ecf..26ebe190c 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -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]; diff --git a/src/class/audio/audio.h b/src/class/audio/audio.h index c655e79e2..a6f198581 100644 --- a/src/class/audio/audio.h +++ b/src/class/audio/audio.h @@ -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;
/** @} */
diff --git a/src/class/cdc/cdc.h b/src/class/cdc/cdc.h index 2e865bdbb..9cc8b82e3 100644 --- a/src/class/cdc/cdc.h +++ b/src/class/cdc/cdc.h @@ -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) \
diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 0a41147c9..d9e128307 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -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);
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index b64d4a1fe..6a6f508b3 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -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) )
{
diff --git a/src/class/midi/midi.h b/src/class/midi/midi.h index 50f2be679..b3cc17af9 100644 --- a/src/class/midi/midi.h +++ b/src/class/midi/midi.h @@ -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;
+
+/// 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 ; \
+ }
-/// Union Functional Descriptor (Communication Interface)
+/// 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 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 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; \
+ }
/** @} */
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 34ad26f15..fd6e435e6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -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
diff --git a/src/device/usbd.h b/src/device/usbd.h index 47e0e531c..a0a84304d 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -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
|
