Commit before sharing.

Setup a test example - UNTESTED!
Missing: Start transmitting audio data in set_interface.
This commit is contained in:
Reinhard Panhuber 2020-08-19 21:07:43 +02:00
parent 6309364722
commit c14f68e2c1
8 changed files with 1497 additions and 876 deletions

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,367 @@
/*
* The MIT License (MIT)
*
* 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.
*
*/
#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;
// Audio controls
// Current states
bool mute[CFG_TUD_AUDIO_N_CHANNELS_TX + 1]; // +1 for master channel 0
uint16_t volume[CFG_TUD_AUDIO_N_CHANNELS_TX + 1]; // +1 for master channel 0
uint32_t sampFreq;
uint8_t clkValid;
// Range states
audio_control_range_2_n_t(1) volumeRng[CFG_TUD_AUDIO_N_CHANNELS_TX+1]; // Volume range state
audio_control_range_4_n_t(1) sampleFreqRng; // Sample frequency range state
void led_blinking_task(void);
void audio_task(void);
/*------------- MAIN -------------*/
int main(void)
{
board_init();
tusb_init();
// Init values
sampFreq = 44100;
clkValid = 1;
sampleFreqRng.wNumSubRanges = 1;
sampleFreqRng.subrange[0].bMin = 44100;
sampleFreqRng.subrange[0].bMax = 44100;
sampleFreqRng.subrange[0].bRes = 0;
while (1)
{
tud_task(); // tinyusb device task
led_blinking_task();
audio_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;
}
//--------------------------------------------------------------------+
// AUDIO Task
//--------------------------------------------------------------------+
void audio_task(void)
{
// Yet to be filled - e.g. put meas data into TX FIFOs etc.
asm("nop");
}
//--------------------------------------------------------------------+
// Application Callback API Implementations
//--------------------------------------------------------------------+
// Invoked when audio class specific set request received for an EP
bool tud_audio_set_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
{
(void) rhport;
// We do not support any set range requests here, only current value requests
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// Page 91 in UAC2 specification
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
return false; // Yet not implemented
}
// Invoked when audio class specific set request received for an interface
bool tud_audio_set_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
{
(void) rhport;
// We do not support any set range requests here, only current value requests
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// Page 91 in UAC2 specification
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
return false; // Yet not implemented
}
// Invoked when audio class specific set request received for an entity
bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request, uint8_t *pBuff)
{
(void) rhport;
// Page 91 in UAC2 specification
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// We do not support any set range requests here, only current value requests
TU_VERIFY(p_request->bRequest == AUDIO_CS_REQ_CUR);
// If request is for our feature unit
if (entityID == 2)
{
switch (ctrlSel)
{
case AUDIO_FU_CTRL_MUTE:
// Request uses format layout 1
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_1_t));
mute[channelNum] = ((audio_control_cur_1_t *)pBuff)->bCur;
TU_LOG2(" Set Mute: %d of channel: %u\r\n", mute[channelNum], channelNum);
return true;
case AUDIO_FU_CTRL_VOLUME:
// Request uses format layout 2
TU_VERIFY(p_request->wLength == sizeof(audio_control_cur_2_t));
volume[channelNum] = ((audio_control_cur_2_t *)pBuff)->bCur;
TU_LOG2(" Set Volume: %d dB of channel: %u\r\n", volume[channelNum], channelNum);
return true;
// Unknown/Unsupported control
default: TU_BREAKPOINT(); return false;
}
}
return false; // Yet not implemented
}
// Invoked when audio class specific get request received for an EP
bool tud_audio_get_req_ep_cb(uint8_t rhport, tusb_control_request_t const * p_request)
{
(void) rhport;
// Page 91 in UAC2 specification
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t ep = TU_U16_LOW(p_request->wIndex);
// return tud_control_xfer(rhport, p_request, &tmp, 1);
return false; // Yet not implemented
}
// Invoked when audio class specific get request received for an interface
bool tud_audio_get_req_itf_cb(uint8_t rhport, tusb_control_request_t const * p_request)
{
(void) rhport;
// Page 91 in UAC2 specification
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
uint8_t itf = TU_U16_LOW(p_request->wIndex);
return false; // Yet not implemented
}
// Invoked when audio class specific get request received for an entity
bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const * p_request)
{
(void) rhport;
// Page 91 in UAC2 specification
uint8_t channelNum = TU_U16_LOW(p_request->wValue);
uint8_t ctrlSel = TU_U16_HIGH(p_request->wValue);
// uint8_t itf = TU_U16_LOW(p_request->wIndex); // Since we have only one audio function implemented, we do not need the itf value
uint8_t entityID = TU_U16_HIGH(p_request->wIndex);
// Input terminal (Microphone input)
if (entityID == 1)
{
switch (ctrlSel)
{
case AUDIO_TE_CTRL_CONNECTOR:;
// The terminal connector control only has a get request with only the CUR attribute.
audio_desc_channel_cluster_t ret;
// Those are dummy values for now
ret.bNrChannels = 1;
ret.bmChannelConfig = 0;
ret.iChannelNames = 0;
TU_LOG2(" Get terminal connector\r\n");
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*)&ret, sizeof(ret));
// Unknown/Unsupported control selector
default: TU_BREAKPOINT(); return false;
}
}
// Feature unit
if (entityID == 2)
{
switch (ctrlSel)
{
case AUDIO_FU_CTRL_MUTE:
// Audio control mute cur parameter block consists of only one byte - we thus can send it right away
// There does not exist a range parameter block for mute
TU_LOG2(" Get Mute of channel: %u\r\n", channelNum);
return tud_control_xfer(rhport, p_request, &mute[channelNum], 1);
case AUDIO_FU_CTRL_VOLUME:
switch (p_request->bRequest)
{
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Volume of channel: %u\r\n", channelNum);
return tud_control_xfer(rhport, p_request, &volume[channelNum], sizeof(volume[channelNum]));
case AUDIO_CS_REQ_RANGE:
TU_LOG2(" Get Volume range of channel: %u\r\n", channelNum);
// Copy values - only for testing - better is version below
audio_control_range_2_n_t(1) ret;
ret.wNumSubRanges = 1;
ret.subrange[0].bMin = -90; // -90 dB
ret.subrange[0].bMax = 90; // +90 dB
ret.subrange[0].bRes = 1; // 1 dB steps
return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, (void*)&ret, sizeof(ret));
// Unknown/Unsupported control
default: TU_BREAKPOINT(); return false;
}
// Unknown/Unsupported control
default: TU_BREAKPOINT(); return false;
}
}
// Clock Source unit
if (entityID == 4)
{
switch (ctrlSel)
{
case AUDIO_CS_CTRL_SAM_FREQ:
// channelNum is always zero in this case
switch (p_request->bRequest)
{
case AUDIO_CS_REQ_CUR:
TU_LOG2(" Get Sample Freq.\r\n");
return tud_control_xfer(rhport, p_request, &sampFreq, sizeof(sampFreq));
case AUDIO_CS_REQ_RANGE:
TU_LOG2(" Get Sample Freq. range\r\n");
return tud_control_xfer(rhport, p_request, &sampleFreqRng, sizeof(sampleFreqRng));
// Unknown/Unsupported control
default: TU_BREAKPOINT(); return false;
}
case AUDIO_CS_CTRL_CLK_VALID:
// Only cur attribute exists for this request
TU_LOG2(" Get Sample Freq. valid\r\n");
return tud_control_xfer(rhport, p_request, &clkValid, sizeof(clkValid));
// Unknown/Unsupported control
default: TU_BREAKPOINT(); return false;
}
}
TU_LOG2(" Unsupported entity: %d\r\n", entityID);
return false; // Yet not implemented
}
//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
void led_blinking_task(void)
{
static uint32_t start_ms = 0;
static bool led_state = false;
// Blink every interval 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,112 @@
/*
* 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 || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
#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 __attribute__ ((aligned(4)))
#endif
//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------
#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE 64
#endif
//------------- CLASS -------------//
#define CFG_TUD_CDC 0
#define CFG_TUD_MSC 0
#define CFG_TUD_HID 0
#define CFG_TUD_MIDI 0
#define CFG_TUD_AUDIO 1
#define CFG_TUD_VENDOR 0
//--------------------------------------------------------------------
// AUDIO CLASS DRIVER CONFIGURATION
//--------------------------------------------------------------------
// Audio format type
#define CFG_TUD_AUDIO_USE_TX_FIFO 1
#define CFG_TUD_AUDIO_FORMAT_TYPE_TX AUDIO_FORMAT_TYPE_I
#define CFG_TUD_AUDIO_FORMAT_TYPE_RX AUDIO_FORMAT_TYPE_UNDEFINED
// Audio format type I specifications
#define CFG_TUD_AUDIO_FORMAT_TYPE_I_TX AUDIO_DATA_FORMAT_TYPE_I_PCM
#define CFG_TUD_AUDIO_N_CHANNELS_TX 1
#define CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX 3
// EP and buffer size - for isochronous EP´s, the buffer and EP size are equal (different sizes would not make sense)
#define CFG_TUD_AUDIO_EPSIZE_IN 45*CFG_TUD_AUDIO_N_BYTES_PER_SAMPLE_TX*CFG_TUD_AUDIO_N_CHANNELS_TX // 45 Samples (44.1 kHz) x 3 Bytes/Sample x 1 Channels
#define CFG_TUD_AUDIO_TX_FIFO_SIZE 45*4 // 45 Samples (44.1 kHz) x 4 Bytes/Sample (1 word)
// 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 wastes a few bytes)
#define CFG_TUD_AUDIO_N_AS_INT 1
// Size of control request buffer
#define CFG_TUD_AUDIO_CTRL_BUF_SIZE 64
#ifdef __cplusplus
}
#endif
#endif /* _TUSB_CONFIG_H_ */

View File

@ -0,0 +1,167 @@
/*
* 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] AUDIO | 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) | _PID_MAP(AUDIO, 4) | _PID_MAP(VENDOR, 5) )
//--------------------------------------------------------------------+
// 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 CDC
// 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_ENDPOINT0_SIZE,
.idVendor = 0xCafe,
.idProduct = USB_PID,
.bcdDevice = 0x0100,
.iManufacturer = 0x01,
.iProduct = 0x02,
.iSerialNumber = 0x03,
.bNumConfigurations = 0x01
};
// 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;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
enum
{
ITF_NUM_AUDIO_CONTROL = 0,
ITF_NUM_AUDIO_STREAMING,
ITF_NUM_TOTAL
};
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_DESC_LEN)
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
// 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_AUDIO 0x03
#else
#define EPNUM_AUDIO 0x01
#endif
// These variables are required by the audio driver in audio_device.c
// List of audio descriptor lengths which is required by audio driver - you need as many entries as CFG_TUD_AUDIO - unfortunately this is not possible to determine otherwise
const uint16_t tud_audio_desc_lengths[] = {TUD_AUDIO_MIC_DESC_LEN};
// TAKE CARE - THE NUMBER OF AUDIO STREAMING INTERFACES PER AUDIO FUNCTION MUST NOT EXCEED CFG_TUD_AUDIO_N_AS_INT - IF IT DOES INCREASE CFG_TUD_AUDIO_N_AS_INT IN tusb_config.h!
uint8_t const desc_configuration[] =
{
// Interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, 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_AUDIO_MIC_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ 3, /*_nBitsUsedPerSample*/ 24, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ 45*3)
};
// 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)
"PaniRCorp", // 1: Manufacturer
"MicNode", // 2: Product
"123456", // 3: Serials, should use chip ID
"UAC2", // 4: Audio Interface
};
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, uint16_t langid)
{
(void) langid;
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 length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);
return _desc_str;
}

View File

@ -2,6 +2,7 @@
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2019 Ha Thach (tinyusb.org) * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -38,40 +39,40 @@
extern "C" { extern "C" {
#endif #endif
/// Audio Device Class Codes /// Audio Device Class Codes
/// A.2 - Audio Function Subclass Codes /// A.2 - Audio Function Subclass Codes
typedef enum typedef enum
{ {
AUDIO_FUNCTION_SUBCLASS_UNDEFINED = 0x00, AUDIO_FUNCTION_SUBCLASS_UNDEFINED = 0x00,
} audio_function_subclass_type_t; } audio_function_subclass_type_t;
/// A.3 - Audio Function Protocol Codes /// A.3 - Audio Function Protocol Codes
typedef enum typedef enum
{ {
AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00, AUDIO_FUNC_PROTOCOL_CODE_UNDEF = 0x00,
AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0 AUDIO_FUNC_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0
} audio_function_protocol_code_t; } audio_function_protocol_code_t;
/// A.5 - Audio Interface Subclass Codes /// A.5 - Audio Interface Subclass Codes
typedef enum typedef enum
{ {
AUDIO_SUBCLASS_UNDEFINED = 0x00, AUDIO_SUBCLASS_UNDEFINED = 0x00,
AUDIO_SUBCLASS_CONTROL , ///< Audio Control AUDIO_SUBCLASS_CONTROL , ///< Audio Control
AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming AUDIO_SUBCLASS_STREAMING , ///< Audio Streaming
AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming AUDIO_SUBCLASS_MIDI_STREAMING , ///< MIDI Streaming
} audio_subclass_type_t; } audio_subclass_type_t;
/// A.6 - Audio Interface Protocol Codes /// A.6 - Audio Interface Protocol Codes
typedef enum typedef enum
{ {
AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00, AUDIO_INT_PROTOCOL_CODE_UNDEF = 0x00,
AUDIO_INT_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0 AUDIO_INT_PROTOCOL_CODE_V2 = 0x20, ///< Version 2.0
} audio_interface_protocol_code_t; } audio_interface_protocol_code_t;
/// A.7 - Audio Function Category Codes /// A.7 - Audio Function Category Codes
typedef enum typedef enum
{ {
AUDIO_FUNC_UNDEF = 0x00, AUDIO_FUNC_UNDEF = 0x00,
AUDIO_FUNC_DESKTOP_SPEAKER = 0x01, AUDIO_FUNC_DESKTOP_SPEAKER = 0x01,
AUDIO_FUNC_HOME_THEATER = 0x02, AUDIO_FUNC_HOME_THEATER = 0x02,
@ -86,11 +87,11 @@ typedef enum
AUDIO_FUNC_AUDIO_VIDEO = 0x0B, AUDIO_FUNC_AUDIO_VIDEO = 0x0B,
AUDIO_FUNC_CONTROL_PANEL = 0x0C, AUDIO_FUNC_CONTROL_PANEL = 0x0C,
AUDIO_FUNC_OTHER = 0xFF, AUDIO_FUNC_OTHER = 0xFF,
} audio_function_code_t; } audio_function_code_t;
/// A.9 - Audio Class-Specific AC Interface Descriptor Subtypes UAC2 /// A.9 - Audio Class-Specific AC Interface Descriptor Subtypes UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00, AUDIO_CS_AC_INTERFACE_AC_DESCRIPTOR_UNDEF = 0x00,
AUDIO_CS_AC_INTERFACE_HEADER = 0x01, AUDIO_CS_AC_INTERFACE_HEADER = 0x01,
AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02, AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL = 0x02,
@ -105,81 +106,81 @@ typedef enum
AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B, AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR = 0x0B,
AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C, AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER = 0x0C,
AUDIO_CS_AC_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D, AUDIO_CS_AC_INTERFACE_SAMPLE_RATE_CONVERTER = 0x0D,
} audio_cs_ac_interface_subtype_t; } audio_cs_ac_interface_subtype_t;
/// A.10 - Audio Class-Specific AS Interface Descriptor Subtypes UAC2 /// A.10 - Audio Class-Specific AS Interface Descriptor Subtypes UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00, AUDIO_CS_AS_INTERFACE_AS_DESCRIPTOR_UNDEF = 0x00,
AUDIO_CS_AS_INTERFACE_AS_GENERAL = 0x01, AUDIO_CS_AS_INTERFACE_AS_GENERAL = 0x01,
AUDIO_CS_AS_INTERFACE_FORMAT_TYPE = 0x02, AUDIO_CS_AS_INTERFACE_FORMAT_TYPE = 0x02,
AUDIO_CS_AS_INTERFACE_ENCODER = 0x03, AUDIO_CS_AS_INTERFACE_ENCODER = 0x03,
AUDIO_CS_AS_INTERFACE_DECODER = 0x04, AUDIO_CS_AS_INTERFACE_DECODER = 0x04,
} audio_cs_as_interface_subtype_t; } audio_cs_as_interface_subtype_t;
/// A.11 - Effect Unit Effect Types /// A.11 - Effect Unit Effect Types
typedef enum typedef enum
{ {
AUDIO_EFFECT_TYPE_UNDEF = 0x00, AUDIO_EFFECT_TYPE_UNDEF = 0x00,
AUDIO_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01, AUDIO_EFFECT_TYPE_PARAM_EQ_SECTION = 0x01,
AUDIO_EFFECT_TYPE_REVERBERATION = 0x02, AUDIO_EFFECT_TYPE_REVERBERATION = 0x02,
AUDIO_EFFECT_TYPE_MOD_DELAY = 0x03, AUDIO_EFFECT_TYPE_MOD_DELAY = 0x03,
AUDIO_EFFECT_TYPE_DYN_RANGE_COMP = 0x04, AUDIO_EFFECT_TYPE_DYN_RANGE_COMP = 0x04,
} audio_effect_unit_effect_type_t; } audio_effect_unit_effect_type_t;
/// A.12 - Processing Unit Process Types /// A.12 - Processing Unit Process Types
typedef enum typedef enum
{ {
AUDIO_PROCESS_TYPE_UNDEF = 0x00, AUDIO_PROCESS_TYPE_UNDEF = 0x00,
AUDIO_PROCESS_TYPE_UP_DOWN_MIX = 0x01, AUDIO_PROCESS_TYPE_UP_DOWN_MIX = 0x01,
AUDIO_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02, AUDIO_PROCESS_TYPE_DOLBY_PROLOGIC = 0x02,
AUDIO_PROCESS_TYPE_STEREO_EXTENDER = 0x03, AUDIO_PROCESS_TYPE_STEREO_EXTENDER = 0x03,
} audio_processing_unit_process_type_t; } audio_processing_unit_process_type_t;
/// A.13 - Audio Class-Specific EP Descriptor Subtypes UAC2 /// A.13 - Audio Class-Specific EP Descriptor Subtypes UAC2
typedef enum typedef enum
{ {
AUDIO_CS_EP_SUBTYPE_UNDEF = 0x00, AUDIO_CS_EP_SUBTYPE_UNDEF = 0x00,
AUDIO_CS_EP_SUBTYPE_GENERAL = 0x01, AUDIO_CS_EP_SUBTYPE_GENERAL = 0x01,
} audio_cs_ep_subtype_t; } audio_cs_ep_subtype_t;
/// A.14 - Audio Class-Specific Request Codes /// A.14 - Audio Class-Specific Request Codes
typedef enum typedef enum
{ {
AUDIO_CS_REQ_UNDEF = 0x00, AUDIO_CS_REQ_UNDEF = 0x00,
AUDIO_CS_REQ_CUR = 0x01, AUDIO_CS_REQ_CUR = 0x01,
AUDIO_CS_REQ_RANGE = 0x02, AUDIO_CS_REQ_RANGE = 0x02,
AUDIO_CS_REQ_MEM = 0x03, AUDIO_CS_REQ_MEM = 0x03,
} audio_cs_req_t; } audio_cs_req_t;
/// A.17 - Control Selector Codes /// A.17 - Control Selector Codes
/// A.17.1 - Clock Source Control Selectors /// A.17.1 - Clock Source Control Selectors
typedef enum typedef enum
{ {
AUDIO_CS_CTRL_UNDEF = 0x00, AUDIO_CS_CTRL_UNDEF = 0x00,
AUDIO_CS_CTRL_SAM_FREQ = 0x01, AUDIO_CS_CTRL_SAM_FREQ = 0x01,
AUDIO_CS_CTRL_CLK_VALID = 0x02, AUDIO_CS_CTRL_CLK_VALID = 0x02,
} audio_clock_src_control_selector_t; } audio_clock_src_control_selector_t;
/// A.17.2 - Clock Selector Control Selectors /// A.17.2 - Clock Selector Control Selectors
typedef enum typedef enum
{ {
AUDIO_CX_CTRL_UNDEF = 0x00, AUDIO_CX_CTRL_UNDEF = 0x00,
AUDIO_CX_CTRL_CONTROL = 0x01, AUDIO_CX_CTRL_CONTROL = 0x01,
} audio_clock_sel_control_selector_t; } audio_clock_sel_control_selector_t;
/// A.17.3 - Clock Multiplier Control Selectors /// A.17.3 - Clock Multiplier Control Selectors
typedef enum typedef enum
{ {
AUDIO_CM_CTRL_UNDEF = 0x00, AUDIO_CM_CTRL_UNDEF = 0x00,
AUDIO_CM_CTRL_NUMERATOR_CONTROL = 0x01, AUDIO_CM_CTRL_NUMERATOR_CONTROL = 0x01,
AUDIO_CM_CTRL_DENOMINATOR_CONTROL = 0x02, AUDIO_CM_CTRL_DENOMINATOR_CONTROL = 0x02,
} audio_clock_mul_control_selector_t; } audio_clock_mul_control_selector_t;
/// A.17.4 - Terminal Control Selectors /// A.17.4 - Terminal Control Selectors
typedef enum typedef enum
{ {
AUDIO_TE_CTRL_UNDEF = 0x00, AUDIO_TE_CTRL_UNDEF = 0x00,
AUDIO_TE_CTRL_COPY_PROTECT = 0x01, AUDIO_TE_CTRL_COPY_PROTECT = 0x01,
AUDIO_TE_CTRL_CONNECTOR = 0x02, AUDIO_TE_CTRL_CONNECTOR = 0x02,
@ -188,30 +189,30 @@ typedef enum
AUDIO_TE_CTRL_UNDERFLOW = 0x05, AUDIO_TE_CTRL_UNDERFLOW = 0x05,
AUDIO_TE_CTRL_OVERFLOW = 0x06, AUDIO_TE_CTRL_OVERFLOW = 0x06,
AUDIO_TE_CTRL_LATENCY = 0x07, AUDIO_TE_CTRL_LATENCY = 0x07,
} audio_terminal_control_selector_t; } audio_terminal_control_selector_t;
/// A.17.5 - Mixer Control Selectors /// A.17.5 - Mixer Control Selectors
typedef enum typedef enum
{ {
AUDIO_MU_CTRL_UNDEF = 0x00, AUDIO_MU_CTRL_UNDEF = 0x00,
AUDIO_MU_CTRL_MIXER = 0x01, AUDIO_MU_CTRL_MIXER = 0x01,
AUDIO_MU_CTRL_CLUSTER = 0x02, AUDIO_MU_CTRL_CLUSTER = 0x02,
AUDIO_MU_CTRL_UNDERFLOW = 0x03, AUDIO_MU_CTRL_UNDERFLOW = 0x03,
AUDIO_MU_CTRL_OVERFLOW = 0x04, AUDIO_MU_CTRL_OVERFLOW = 0x04,
AUDIO_MU_CTRL_LATENCY = 0x05, AUDIO_MU_CTRL_LATENCY = 0x05,
} audio_mixer_control_selector_t; } audio_mixer_control_selector_t;
/// A.17.6 - Selector Control Selectors /// A.17.6 - Selector Control Selectors
typedef enum typedef enum
{ {
AUDIO_SU_CTRL_UNDEF = 0x00, AUDIO_SU_CTRL_UNDEF = 0x00,
AUDIO_SU_CTRL_SELECTOR = 0x01, AUDIO_SU_CTRL_SELECTOR = 0x01,
AUDIO_SU_CTRL_LATENCY = 0x02, AUDIO_SU_CTRL_LATENCY = 0x02,
} audio_sel_control_selector_t; } audio_sel_control_selector_t;
/// A.17.7 - Feature Unit Control Selectors /// A.17.7 - Feature Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_FU_CTRL_UNDEF = 0x00, AUDIO_FU_CTRL_UNDEF = 0x00,
AUDIO_FU_CTRL_MUTE = 0x01, AUDIO_FU_CTRL_MUTE = 0x01,
AUDIO_FU_CTRL_VOLUME = 0x02, AUDIO_FU_CTRL_VOLUME = 0x02,
@ -229,13 +230,13 @@ typedef enum
AUDIO_FU_CTRL_UNDERFLOW = 0x0E, AUDIO_FU_CTRL_UNDERFLOW = 0x0E,
AUDIO_FU_CTRL_OVERVLOW = 0x0F, AUDIO_FU_CTRL_OVERVLOW = 0x0F,
AUDIO_FU_CTRL_LATENCY = 0x10, AUDIO_FU_CTRL_LATENCY = 0x10,
} audio_feature_unit_control_selector_t; } audio_feature_unit_control_selector_t;
/// A.17.8 Effect Unit Control Selectors /// A.17.8 Effect Unit Control Selectors
/// A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors /// A.17.8.1 Parametric Equalizer Section Effect Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_PE_CTRL_UNDEF = 0x00, AUDIO_PE_CTRL_UNDEF = 0x00,
AUDIO_PE_CTRL_ENABLE = 0x01, AUDIO_PE_CTRL_ENABLE = 0x01,
AUDIO_PE_CTRL_CENTERFREQ = 0x02, AUDIO_PE_CTRL_CENTERFREQ = 0x02,
@ -244,11 +245,11 @@ typedef enum
AUDIO_PE_CTRL_UNDERFLOW = 0x05, AUDIO_PE_CTRL_UNDERFLOW = 0x05,
AUDIO_PE_CTRL_OVERFLOW = 0x06, AUDIO_PE_CTRL_OVERFLOW = 0x06,
AUDIO_PE_CTRL_LATENCY = 0x07, AUDIO_PE_CTRL_LATENCY = 0x07,
} audio_parametric_equalizer_control_selector_t; } audio_parametric_equalizer_control_selector_t;
/// A.17.8.2 Reverberation Effect Unit Control Selectors /// A.17.8.2 Reverberation Effect Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_RV_CTRL_UNDEF = 0x00, AUDIO_RV_CTRL_UNDEF = 0x00,
AUDIO_RV_CTRL_ENABLE = 0x01, AUDIO_RV_CTRL_ENABLE = 0x01,
AUDIO_RV_CTRL_TYPE = 0x02, AUDIO_RV_CTRL_TYPE = 0x02,
@ -261,11 +262,11 @@ typedef enum
AUDIO_RV_CTRL_UNDERFLOW = 0x09, AUDIO_RV_CTRL_UNDERFLOW = 0x09,
AUDIO_RV_CTRL_OVERFLOW = 0x0A, AUDIO_RV_CTRL_OVERFLOW = 0x0A,
AUDIO_RV_CTRL_LATENCY = 0x0B, AUDIO_RV_CTRL_LATENCY = 0x0B,
} audio_reverberation_effect_control_selector_t; } audio_reverberation_effect_control_selector_t;
/// A.17.8.3 Modulation Delay Effect Unit Control Selectors /// A.17.8.3 Modulation Delay Effect Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_MD_CTRL_UNDEF = 0x00, AUDIO_MD_CTRL_UNDEF = 0x00,
AUDIO_MD_CTRL_ENABLE = 0x01, AUDIO_MD_CTRL_ENABLE = 0x01,
AUDIO_MD_CTRL_BALANCE = 0x02, AUDIO_MD_CTRL_BALANCE = 0x02,
@ -276,11 +277,11 @@ typedef enum
AUDIO_MD_CTRL_UNDERFLOW = 0x07, AUDIO_MD_CTRL_UNDERFLOW = 0x07,
AUDIO_MD_CTRL_OVERFLOW = 0x08, AUDIO_MD_CTRL_OVERFLOW = 0x08,
AUDIO_MD_CTRL_LATENCY = 0x09, AUDIO_MD_CTRL_LATENCY = 0x09,
} audio_modulation_delay_control_selector_t; } audio_modulation_delay_control_selector_t;
/// A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors /// A.17.8.4 Dynamic Range Compressor Effect Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_DR_CTRL_UNDEF = 0x00, AUDIO_DR_CTRL_UNDEF = 0x00,
AUDIO_DR_CTRL_ENABLE = 0x01, AUDIO_DR_CTRL_ENABLE = 0x01,
AUDIO_DR_CTRL_COMPRESSION_RATE = 0x02, AUDIO_DR_CTRL_COMPRESSION_RATE = 0x02,
@ -291,13 +292,13 @@ typedef enum
AUDIO_DR_CTRL_UNDERFLOW = 0x07, AUDIO_DR_CTRL_UNDERFLOW = 0x07,
AUDIO_DR_CTRL_OVERFLOW = 0x08, AUDIO_DR_CTRL_OVERFLOW = 0x08,
AUDIO_DR_CTRL_LATENCY = 0x09, AUDIO_DR_CTRL_LATENCY = 0x09,
} audio_dynamic_range_compression_control_selector_t; } audio_dynamic_range_compression_control_selector_t;
/// A.17.9 Processing Unit Control Selectors /// A.17.9 Processing Unit Control Selectors
/// A.17.9.1 Up/Down-mix Processing Unit Control Selectors /// A.17.9.1 Up/Down-mix Processing Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_UD_CTRL_UNDEF = 0x00, AUDIO_UD_CTRL_UNDEF = 0x00,
AUDIO_UD_CTRL_ENABLE = 0x01, AUDIO_UD_CTRL_ENABLE = 0x01,
AUDIO_UD_CTRL_MODE_SELECT = 0x02, AUDIO_UD_CTRL_MODE_SELECT = 0x02,
@ -305,11 +306,11 @@ typedef enum
AUDIO_UD_CTRL_UNDERFLOW = 0x04, AUDIO_UD_CTRL_UNDERFLOW = 0x04,
AUDIO_UD_CTRL_OVERFLOW = 0x05, AUDIO_UD_CTRL_OVERFLOW = 0x05,
AUDIO_UD_CTRL_LATENCY = 0x06, AUDIO_UD_CTRL_LATENCY = 0x06,
} audio_up_down_mix_control_selector_t; } audio_up_down_mix_control_selector_t;
/// A.17.9.2 Dolby Prologic ™ Processing Unit Control Selectors /// A.17.9.2 Dolby Prologic ™ Processing Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_DP_CTRL_UNDEF = 0x00, AUDIO_DP_CTRL_UNDEF = 0x00,
AUDIO_DP_CTRL_ENABLE = 0x01, AUDIO_DP_CTRL_ENABLE = 0x01,
AUDIO_DP_CTRL_MODE_SELECT = 0x02, AUDIO_DP_CTRL_MODE_SELECT = 0x02,
@ -317,42 +318,42 @@ typedef enum
AUDIO_DP_CTRL_UNDERFLOW = 0x04, AUDIO_DP_CTRL_UNDERFLOW = 0x04,
AUDIO_DP_CTRL_OVERFLOW = 0x05, AUDIO_DP_CTRL_OVERFLOW = 0x05,
AUDIO_DP_CTRL_LATENCY = 0x06, AUDIO_DP_CTRL_LATENCY = 0x06,
} audio_dolby_prologic_control_selector_t; } audio_dolby_prologic_control_selector_t;
/// A.17.9.3 Stereo Extender Processing Unit Control Selectors /// A.17.9.3 Stereo Extender Processing Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_ST_EXT_CTRL_UNDEF = 0x00, AUDIO_ST_EXT_CTRL_UNDEF = 0x00,
AUDIO_ST_EXT_CTRL_ENABLE = 0x01, AUDIO_ST_EXT_CTRL_ENABLE = 0x01,
AUDIO_ST_EXT_CTRL_WIDTH = 0x02, AUDIO_ST_EXT_CTRL_WIDTH = 0x02,
AUDIO_ST_EXT_CTRL_UNDERFLOW = 0x03, AUDIO_ST_EXT_CTRL_UNDERFLOW = 0x03,
AUDIO_ST_EXT_CTRL_OVERFLOW = 0x04, AUDIO_ST_EXT_CTRL_OVERFLOW = 0x04,
AUDIO_ST_EXT_CTRL_LATENCY = 0x05, AUDIO_ST_EXT_CTRL_LATENCY = 0x05,
} audio_stereo_extender_control_selector_t; } audio_stereo_extender_control_selector_t;
/// A.17.10 Extension Unit Control Selectors /// A.17.10 Extension Unit Control Selectors
typedef enum typedef enum
{ {
AUDIO_XU_CTRL_UNDEF = 0x00, AUDIO_XU_CTRL_UNDEF = 0x00,
AUDIO_XU_CTRL_ENABLE = 0x01, AUDIO_XU_CTRL_ENABLE = 0x01,
AUDIO_XU_CTRL_CLUSTER = 0x02, AUDIO_XU_CTRL_CLUSTER = 0x02,
AUDIO_XU_CTRL_UNDERFLOW = 0x03, AUDIO_XU_CTRL_UNDERFLOW = 0x03,
AUDIO_XU_CTRL_OVERFLOW = 0x04, AUDIO_XU_CTRL_OVERFLOW = 0x04,
AUDIO_XU_CTRL_LATENCY = 0x05, AUDIO_XU_CTRL_LATENCY = 0x05,
} audio_extension_unit_control_selector_t; } audio_extension_unit_control_selector_t;
/// A.17.11 AudioStreaming Interface Control Selectors /// A.17.11 AudioStreaming Interface Control Selectors
typedef enum typedef enum
{ {
AUDIO_AS_CTRL_UNDEF = 0x00, AUDIO_AS_CTRL_UNDEF = 0x00,
AUDIO_AS_CTRL_ACT_ALT_SETTING = 0x01, AUDIO_AS_CTRL_ACT_ALT_SETTING = 0x01,
AUDIO_AS_CTRL_VAL_ALT_SETTINGS = 0x02, AUDIO_AS_CTRL_VAL_ALT_SETTINGS = 0x02,
AUDIO_AS_CTRL_AUDIO_DATA_FORMAT = 0x03, AUDIO_AS_CTRL_AUDIO_DATA_FORMAT = 0x03,
} audio_audiostreaming_interface_control_selector_t; } audio_audiostreaming_interface_control_selector_t;
/// A.17.12 Encoder Control Selectors /// A.17.12 Encoder Control Selectors
typedef enum typedef enum
{ {
AUDIO_EN_CTRL_UNDEF = 0x00, AUDIO_EN_CTRL_UNDEF = 0x00,
AUDIO_EN_CTRL_BIT_RATE = 0x01, AUDIO_EN_CTRL_BIT_RATE = 0x01,
AUDIO_EN_CTRL_QUALITY = 0x02, AUDIO_EN_CTRL_QUALITY = 0x02,
@ -369,13 +370,13 @@ typedef enum
AUDIO_EN_CTRL_PARAM6 = 0x0D, AUDIO_EN_CTRL_PARAM6 = 0x0D,
AUDIO_EN_CTRL_PARAM7 = 0x0E, AUDIO_EN_CTRL_PARAM7 = 0x0E,
AUDIO_EN_CTRL_PARAM8 = 0x0F, AUDIO_EN_CTRL_PARAM8 = 0x0F,
} audio_encoder_control_selector_t; } audio_encoder_control_selector_t;
/// A.17.13 Decoder Control Selectors /// A.17.13 Decoder Control Selectors
/// A.17.13.1 MPEG Decoder Control Selectors /// A.17.13.1 MPEG Decoder Control Selectors
typedef enum typedef enum
{ {
AUDIO_MPD_CTRL_UNDEF = 0x00, AUDIO_MPD_CTRL_UNDEF = 0x00,
AUDIO_MPD_CTRL_DUAL_CHANNEL = 0x01, AUDIO_MPD_CTRL_DUAL_CHANNEL = 0x01,
AUDIO_MPD_CTRL_SECOND_STEREO = 0x02, AUDIO_MPD_CTRL_SECOND_STEREO = 0x02,
@ -386,11 +387,11 @@ typedef enum
AUDIO_MPD_CTRL_UNDERFLOW = 0x07, AUDIO_MPD_CTRL_UNDERFLOW = 0x07,
AUDIO_MPD_CTRL_OVERFLOW = 0x08, AUDIO_MPD_CTRL_OVERFLOW = 0x08,
AUDIO_MPD_CTRL_DECODER_ERROR = 0x09, AUDIO_MPD_CTRL_DECODER_ERROR = 0x09,
} audio_MPEG_decoder_control_selector_t; } audio_MPEG_decoder_control_selector_t;
/// A.17.13.2 AC-3 Decoder Control Selectors /// A.17.13.2 AC-3 Decoder Control Selectors
typedef enum typedef enum
{ {
AUDIO_AD_CTRL_UNDEF = 0x00, AUDIO_AD_CTRL_UNDEF = 0x00,
AUDIO_AD_CTRL_MODE = 0x01, AUDIO_AD_CTRL_MODE = 0x01,
AUDIO_AD_CTRL_DYN_RANGE = 0x02, AUDIO_AD_CTRL_DYN_RANGE = 0x02,
@ -399,48 +400,48 @@ typedef enum
AUDIO_AD_CTRL_UNDERFLOW = 0x05, AUDIO_AD_CTRL_UNDERFLOW = 0x05,
AUDIO_AD_CTRL_OVERFLOW = 0x06, AUDIO_AD_CTRL_OVERFLOW = 0x06,
AUDIO_AD_CTRL_DECODER_ERROR = 0x07, AUDIO_AD_CTRL_DECODER_ERROR = 0x07,
} audio_AC3_decoder_control_selector_t; } audio_AC3_decoder_control_selector_t;
/// A.17.13.3 WMA Decoder Control Selectors /// A.17.13.3 WMA Decoder Control Selectors
typedef enum typedef enum
{ {
AUDIO_WD_CTRL_UNDEF = 0x00, AUDIO_WD_CTRL_UNDEF = 0x00,
AUDIO_WD_CTRL_UNDERFLOW = 0x01, AUDIO_WD_CTRL_UNDERFLOW = 0x01,
AUDIO_WD_CTRL_OVERFLOW = 0x02, AUDIO_WD_CTRL_OVERFLOW = 0x02,
AUDIO_WD_CTRL_DECODER_ERROR = 0x03, AUDIO_WD_CTRL_DECODER_ERROR = 0x03,
} audio_WMA_decoder_control_selector_t; } audio_WMA_decoder_control_selector_t;
/// A.17.13.4 DTS Decoder Control Selectors /// A.17.13.4 DTS Decoder Control Selectors
typedef enum typedef enum
{ {
AUDIO_DD_CTRL_UNDEF = 0x00, AUDIO_DD_CTRL_UNDEF = 0x00,
AUDIO_DD_CTRL_UNDERFLOW = 0x01, AUDIO_DD_CTRL_UNDERFLOW = 0x01,
AUDIO_DD_CTRL_OVERFLOW = 0x02, AUDIO_DD_CTRL_OVERFLOW = 0x02,
AUDIO_DD_CTRL_DECODER_ERROR = 0x03, AUDIO_DD_CTRL_DECODER_ERROR = 0x03,
} audio_DTS_decoder_control_selector_t; } audio_DTS_decoder_control_selector_t;
/// A.17.14 Endpoint Control Selectors /// A.17.14 Endpoint Control Selectors
typedef enum typedef enum
{ {
AUDIO_EP_CTRL_UNDEF = 0x00, AUDIO_EP_CTRL_UNDEF = 0x00,
AUDIO_EP_CTRL_PITCH = 0x01, AUDIO_EP_CTRL_PITCH = 0x01,
AUDIO_EP_CTRL_DATA_OVERRUN = 0x02, AUDIO_EP_CTRL_DATA_OVERRUN = 0x02,
AUDIO_EP_CTRL_DATA_UNDERRUN = 0x03, AUDIO_EP_CTRL_DATA_UNDERRUN = 0x03,
} audio_EP_control_selector_t; } audio_EP_control_selector_t;
/// Terminal Types /// Terminal Types
/// 2.1 - Audio Class-Terminal Types UAC2 /// 2.1 - Audio Class-Terminal Types UAC2
typedef enum typedef enum
{ {
AUDIO_TERM_TYPE_USB_UNDEFINED = 0x0100, AUDIO_TERM_TYPE_USB_UNDEFINED = 0x0100,
AUDIO_TERM_TYPE_USB_STREAMING = 0x0101, AUDIO_TERM_TYPE_USB_STREAMING = 0x0101,
AUDIO_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF, AUDIO_TERM_TYPE_USB_VENDOR_SPEC = 0x01FF,
} audio_terminal_type_t; } audio_terminal_type_t;
/// 2.2 - Audio Class-Input Terminal Types UAC2 /// 2.2 - Audio Class-Input Terminal Types UAC2
typedef enum typedef enum
{ {
AUDIO_TERM_TYPE_IN_UNDEFINED = 0x0200, AUDIO_TERM_TYPE_IN_UNDEFINED = 0x0200,
AUDIO_TERM_TYPE_IN_GENERIC_MIC = 0x0201, AUDIO_TERM_TYPE_IN_GENERIC_MIC = 0x0201,
AUDIO_TERM_TYPE_IN_DESKTOP_MIC = 0x0202, AUDIO_TERM_TYPE_IN_DESKTOP_MIC = 0x0202,
@ -448,11 +449,11 @@ typedef enum
AUDIO_TERM_TYPE_IN_OMNI_MIC = 0x0204, AUDIO_TERM_TYPE_IN_OMNI_MIC = 0x0204,
AUDIO_TERM_TYPE_IN_ARRAY_MIC = 0x0205, AUDIO_TERM_TYPE_IN_ARRAY_MIC = 0x0205,
AUDIO_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206, AUDIO_TERM_TYPE_IN_PROC_ARRAY_MIC = 0x0206,
} audio_terminal_input_type_t; } audio_terminal_input_type_t;
/// 2.3 - Audio Class-Output Terminal Types UAC2 /// 2.3 - Audio Class-Output Terminal Types UAC2
typedef enum typedef enum
{ {
AUDIO_TERM_TYPE_OUT_UNDEFINED = 0x0300, AUDIO_TERM_TYPE_OUT_UNDEFINED = 0x0300,
AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301, AUDIO_TERM_TYPE_OUT_GENERIC_SPEAKER = 0x0301,
AUDIO_TERM_TYPE_OUT_HEADPHONES = 0x0302, AUDIO_TERM_TYPE_OUT_HEADPHONES = 0x0302,
@ -461,15 +462,15 @@ typedef enum
AUDIO_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305, AUDIO_TERM_TYPE_OUT_ROOM_SPEAKER = 0x0305,
AUDIO_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306, AUDIO_TERM_TYPE_OUT_COMMUNICATION_SPEAKER = 0x0306,
AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307, AUDIO_TERM_TYPE_OUT_LOW_FRQ_EFFECTS_SPEAKER = 0x0307,
} audio_terminal_output_type_t; } audio_terminal_output_type_t;
/// Rest is yet to be implemented /// Rest is yet to be implemented
/// Additional Audio Device Class Codes - Source: Audio Data Formats /// Additional Audio Device Class Codes - Source: Audio Data Formats
/// A.1 - Audio Class-Format Type Codes UAC2 /// A.1 - Audio Class-Format Type Codes UAC2
typedef enum typedef enum
{ {
AUDIO_FORMAT_TYPE_UNDEFINED = 0x00, AUDIO_FORMAT_TYPE_UNDEFINED = 0x00,
AUDIO_FORMAT_TYPE_I = 0x01, AUDIO_FORMAT_TYPE_I = 0x01,
AUDIO_FORMAT_TYPE_II = 0x02, AUDIO_FORMAT_TYPE_II = 0x02,
@ -478,129 +479,129 @@ typedef enum
AUDIO_EXT_FORMAT_TYPE_I = 0x81, AUDIO_EXT_FORMAT_TYPE_I = 0x81,
AUDIO_EXT_FORMAT_TYPE_II = 0x82, AUDIO_EXT_FORMAT_TYPE_II = 0x82,
AUDIO_EXT_FORMAT_TYPE_III = 0x83, AUDIO_EXT_FORMAT_TYPE_III = 0x83,
} audio_format_type_t; } audio_format_type_t;
/// A.2.1 - Audio Class-Audio Data Format Type I UAC2 /// A.2.1 - Audio Class-Audio Data Format Type I UAC2
typedef enum typedef enum
{ {
AUDIO_DATA_FORMAT_TYPE_I_PCM = (uint32_t) (1 << 0), 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_PCM8 = (uint32_t) (1 << 1),
AUDIO_DATA_FORMAT_TYPE_I_IEEE_FLOAT = (uint32_t) (1 << 2), 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_ALAW = (uint32_t) (1 << 3),
AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4), AUDIO_DATA_FORMAT_TYPE_I_MULAW = (uint32_t) (1 << 4),
AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (uint32_t) (1 << 31), AUDIO_DATA_FORMAT_TYPE_I_RAW_DATA = (uint32_t) (1 << 31),
} audio_data_format_type_I_t; } audio_data_format_type_I_t;
/// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification /// All remaining definitions are taken from the descriptor descriptions in the UAC2 main specification
/// Isochronous End Point Attributes /// Isochronous End Point Attributes
typedef enum typedef enum
{ {
TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04, TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04,
TUSB_ISO_EP_ATT_ADAPTIVE = 0x08, TUSB_ISO_EP_ATT_ADAPTIVE = 0x08,
TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C, TUSB_ISO_EP_ATT_SYNCHRONOUS = 0x0C,
TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point
TUSB_ISO_EP_ATT_FB = 0x20, ///< Feedback End Point TUSB_ISO_EP_ATT_FB = 0x20, ///< Feedback End Point
} tusb_iso_ep_attribute_t; } tusb_iso_ep_attribute_t;
/// Audio Class-Control Values UAC2 /// Audio Class-Control Values UAC2
typedef enum typedef enum
{ {
AUDIO_CTRL_NONE = 0x00, ///< No Host access AUDIO_CTRL_NONE = 0x00, ///< No Host access
AUDIO_CTRL_R = 0x01, ///< Host read access only AUDIO_CTRL_R = 0x01, ///< Host read access only
AUDIO_CTRL_RW = 0x03, ///< Host read write access AUDIO_CTRL_RW = 0x03, ///< Host read write access
} audio_control_t; } audio_control_t;
/// Audio Class-Specific AC Interface Descriptor Controls UAC2 /// Audio Class-Specific AC Interface Descriptor Controls UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0, AUDIO_CS_AS_INTERFACE_CTRL_LATENCY_POS = 0,
} audio_cs_ac_interface_control_pos_t; } audio_cs_ac_interface_control_pos_t;
/// Audio Class-Specific AS Interface Descriptor Controls UAC2 /// Audio Class-Specific AS Interface Descriptor Controls UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0, AUDIO_CS_AS_INTERFACE_CTRL_ACTIVE_ALT_SET_POS = 0,
AUDIO_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2, AUDIO_CS_AS_INTERFACE_CTRL_VALID_ALT_SET_POS = 2,
} audio_cs_as_interface_control_pos_t; } audio_cs_as_interface_control_pos_t;
/// Audio Class-Specific AS Isochronous Data EP Attributes UAC2 /// Audio Class-Specific AS Isochronous Data EP Attributes UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AS_ISO_DATA_EP_ATT_MAX_PACKETS_ONLY = 0x80, 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_ATT_NON_MAX_PACKETS_OK = 0x00,
} audio_cs_as_iso_data_ep_attribute_t; } audio_cs_as_iso_data_ep_attribute_t;
/// Audio Class-Specific AS Isochronous Data EP Controls UAC2 /// Audio Class-Specific AS Isochronous Data EP Controls UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AS_ISO_DATA_EP_CTRL_PITCH_POS = 0, 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_OVERRUN_POS = 2,
AUDIO_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4, AUDIO_CS_AS_ISO_DATA_EP_CTRL_DATA_UNDERRUN_POS = 4,
} audio_cs_as_iso_data_ep_control_pos_t; } audio_cs_as_iso_data_ep_control_pos_t;
/// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC2 /// Audio Class-Specific AS Isochronous Data EP Lock Delay Units UAC2
typedef enum typedef enum
{ {
AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED = 0x00, 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_MILLISEC = 0x01,
AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02, AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_PCM_SAMPLES = 0x02,
} audio_cs_as_iso_data_ep_lock_delay_unit_t; } audio_cs_as_iso_data_ep_lock_delay_unit_t;
/// Audio Class-Clock Source Attributes UAC2 /// Audio Class-Clock Source Attributes UAC2
typedef enum typedef enum
{ {
AUDIO_CLOCK_SOURCE_ATT_EXT_CLK = 0x00, AUDIO_CLOCK_SOURCE_ATT_EXT_CLK = 0x00,
AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01, AUDIO_CLOCK_SOURCE_ATT_INT_FIX_CLK = 0x01,
AUDIO_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02, AUDIO_CLOCK_SOURCE_ATT_INT_VAR_CLK = 0x02,
AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03, AUDIO_CLOCK_SOURCE_ATT_INT_PRO_CLK = 0x03,
AUDIO_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04, AUDIO_CLOCK_SOURCE_ATT_CLK_SYC_SOF = 0x04,
} audio_clock_source_attribute_t; } audio_clock_source_attribute_t;
/// Audio Class-Clock Source Controls UAC2 /// Audio Class-Clock Source Controls UAC2
typedef enum typedef enum
{ {
AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0, AUDIO_CLOCK_SOURCE_CTRL_CLK_FRQ_POS = 0,
AUDIO_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2, AUDIO_CLOCK_SOURCE_CTRL_CLK_VAL_POS = 2,
} audio_clock_source_control_pos_t; } audio_clock_source_control_pos_t;
/// Audio Class-Clock Selector Controls UAC2 /// Audio Class-Clock Selector Controls UAC2
typedef enum typedef enum
{ {
AUDIO_CLOCK_SELECTOR_CTRL_POS = 0, AUDIO_CLOCK_SELECTOR_CTRL_POS = 0,
} audio_clock_selector_control_pos_t; } audio_clock_selector_control_pos_t;
/// Audio Class-Clock Multiplier Controls UAC2 /// Audio Class-Clock Multiplier Controls UAC2
typedef enum typedef enum
{ {
AUDIO_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0, AUDIO_CLOCK_MULTIPLIER_CTRL_NUMERATOR_POS = 0,
AUDIO_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2, AUDIO_CLOCK_MULTIPLIER_CTRL_DENOMINATOR_POS = 2,
} audio_clock_multiplier_control_pos_t; } audio_clock_multiplier_control_pos_t;
/// Audio Class-Input Terminal Controls UAC2 /// Audio Class-Input Terminal Controls UAC2
typedef enum typedef enum
{ {
AUDIO_IN_TERM_CTRL_CPY_PROT_POS = 0, AUDIO_IN_TERM_CTRL_CPY_PROT_POS = 0,
AUDIO_IN_TERM_CTRL_CONNECTOR_POS = 2, AUDIO_IN_TERM_CTRL_CONNECTOR_POS = 2,
AUDIO_IN_TERM_CTRL_OVERLOAD_POS = 4, AUDIO_IN_TERM_CTRL_OVERLOAD_POS = 4,
AUDIO_IN_TERM_CTRL_CLUSTER_POS = 6, AUDIO_IN_TERM_CTRL_CLUSTER_POS = 6,
AUDIO_IN_TERM_CTRL_UNDERFLOW_POS = 8, AUDIO_IN_TERM_CTRL_UNDERFLOW_POS = 8,
AUDIO_IN_TERM_CTRL_OVERFLOW_POS = 10, AUDIO_IN_TERM_CTRL_OVERFLOW_POS = 10,
} audio_terminal_input_control_pos_t; } audio_terminal_input_control_pos_t;
/// Audio Class-Output Terminal Controls UAC2 /// Audio Class-Output Terminal Controls UAC2
typedef enum typedef enum
{ {
AUDIO_OUT_TERM_CTRL_CPY_PROT_POS = 0, AUDIO_OUT_TERM_CTRL_CPY_PROT_POS = 0,
AUDIO_OUT_TERM_CTRL_CONNECTOR_POS = 2, AUDIO_OUT_TERM_CTRL_CONNECTOR_POS = 2,
AUDIO_OUT_TERM_CTRL_OVERLOAD_POS = 4, AUDIO_OUT_TERM_CTRL_OVERLOAD_POS = 4,
AUDIO_OUT_TERM_CTRL_UNDERFLOW_POS = 6, AUDIO_OUT_TERM_CTRL_UNDERFLOW_POS = 6,
AUDIO_OUT_TERM_CTRL_OVERFLOW_POS = 8, AUDIO_OUT_TERM_CTRL_OVERFLOW_POS = 8,
} audio_terminal_output_control_pos_t; } audio_terminal_output_control_pos_t;
/// Audio Class-Feature Unit Controls UAC2 /// Audio Class-Feature Unit Controls UAC2
typedef enum typedef enum
{ {
AUDIO_FEATURE_UNIT_CTRL_MUTE_POS = 0, AUDIO_FEATURE_UNIT_CTRL_MUTE_POS = 0,
AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS = 2, AUDIO_FEATURE_UNIT_CTRL_VOLUME_POS = 2,
AUDIO_FEATURE_UNIT_CTRL_BASS_POS = 4, AUDIO_FEATURE_UNIT_CTRL_BASS_POS = 4,
@ -616,11 +617,11 @@ typedef enum
AUDIO_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24, AUDIO_FEATURE_UNIT_CTRL_PHASE_INV_POS = 24,
AUDIO_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26, AUDIO_FEATURE_UNIT_CTRL_UNDERFLOW_POS = 26,
AUDIO_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28, AUDIO_FEATURE_UNIT_CTRL_OVERFLOW_POS = 28,
} audio_feature_unit_control_pos_t; } audio_feature_unit_control_pos_t;
/// Audio Class-Audio Channel Configuration UAC2 /// Audio Class-Audio Channel Configuration UAC2
typedef enum typedef enum
{ {
AUDIO_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000, AUDIO_CHANNEL_CONFIG_NON_PREDEFINED = 0x00000000,
AUDIO_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001, AUDIO_CHANNEL_CONFIG_FRONT_LEFT = 0x00000001,
AUDIO_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002, AUDIO_CHANNEL_CONFIG_FRONT_RIGHT = 0x00000002,
@ -650,18 +651,18 @@ typedef enum
AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000, AUDIO_CHANNEL_CONFIG_BACK_LEFT_OF_CENTER = 0x02000000,
AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000, AUDIO_CHANNEL_CONFIG_BACK_RIGHT_OF_CENTER = 0x04000000,
AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000,
} audio_channel_config_t; } audio_channel_config_t;
/// AUDIO Channel Cluster Descriptor (4.1) /// AUDIO Channel Cluster Descriptor (4.1)
typedef struct TU_ATTR_PACKED { typedef struct TU_ATTR_PACKED {
uint8_t bNrChannels; ///< Number of channels currently connected. 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. 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. 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_desc_channel_cluster_t;
/// AUDIO Class-Specific AC Interface Header Descriptor (4.7.2) /// AUDIO Class-Specific AC Interface Header Descriptor (4.7.2)
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor in bytes: 9. uint8_t bLength ; ///< Size of this descriptor in bytes: 9.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_HEADER. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_HEADER.
@ -669,11 +670,11 @@ typedef struct TU_ATTR_PACKED
uint8_t bCategory ; ///< Constant, indicating the primary use of this audio function, as intended by the manufacturer. See: audio_function_t. 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. 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. uint8_t bmControls ; ///< See: audio_cs_ac_interface_control_pos_t.
} audio_desc_cs_ac_interface_t; } audio_desc_cs_ac_interface_t;
/// AUDIO Clock Source Descriptor (4.7.2.1) /// AUDIO Clock Source Descriptor (4.7.2.1)
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor in bytes: 8. uint8_t bLength ; ///< Size of this descriptor in bytes: 8.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SOURCE.
@ -682,11 +683,11 @@ typedef struct TU_ATTR_PACKED
uint8_t bmControls ; ///< See: audio_clock_source_control_pos_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 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. uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Source Entity.
} audio_desc_clock_source_t; } audio_desc_clock_source_t;
/// AUDIO Clock Selector Descriptor (4.7.2.2) for ONE pin /// AUDIO Clock Selector Descriptor (4.7.2.2) for ONE pin
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor, in bytes: 7+p. uint8_t bLength ; ///< Size of this descriptor, in bytes: 7+p.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_SELECTOR.
@ -695,9 +696,9 @@ typedef struct TU_ATTR_PACKED
uint8_t baCSourceID ; ///< ID of the Clock Entity to which the first Clock Input Pin of this Clock Selector Entity is connected.. 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 bmControls ; ///< See: audio_clock_selector_control_pos_t.
uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Selector Entity. uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Selector Entity.
} audio_desc_clock_selector_t; } audio_desc_clock_selector_t;
/// AUDIO Clock Selector Descriptor (4.7.2.2) for multiple pins /// AUDIO Clock Selector Descriptor (4.7.2.2) for multiple pins
#define audio_desc_clock_selector_n_t(source_num) \ #define audio_desc_clock_selector_n_t(source_num) \
struct TU_ATTR_PACKED { \ struct TU_ATTR_PACKED { \
uint8_t bLength ; \ uint8_t bLength ; \
@ -712,9 +713,9 @@ typedef struct TU_ATTR_PACKED
uint8_t iClockSource ; \ uint8_t iClockSource ; \
} }
/// AUDIO Clock Multiplier Descriptor (4.7.2.3) /// AUDIO Clock Multiplier Descriptor (4.7.2.3)
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor, in bytes: 7. uint8_t bLength ; ///< Size of this descriptor, in bytes: 7.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_CLOCK_MULTIPLIER.
@ -722,11 +723,11 @@ typedef struct TU_ATTR_PACKED
uint8_t bCSourceID ; ///< ID of the Clock Entity to which the last Clock Input Pin of this Clock Selector Entity is connected. 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 bmControls ; ///< See: audio_clock_multiplier_control_pos_t.
uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Multiplier Entity. uint8_t iClockSource ; ///< Index of a string descriptor, describing the Clock Multiplier Entity.
} audio_desc_clock_multiplier_t; } audio_desc_clock_multiplier_t;
/// AUDIO Input Terminal Descriptor(4.7.2.4) /// AUDIO Input Terminal Descriptor(4.7.2.4)
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor, in bytes: 17. uint8_t bLength ; ///< Size of this descriptor, in bytes: 17.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_INPUT_TERMINAL.
@ -737,11 +738,11 @@ typedef struct TU_ATTR_PACKED
uint32_t bmChannelConfig ; ///< Describes the spatial location of the logical channels. See:audio_channel_config_t. 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. uint16_t bmControls ; ///< See: audio_terminal_input_control_pos_t.
uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal. uint8_t iTerminal ; ///< Index of a string descriptor, describing the Input Terminal.
} audio_desc_input_terminal_t; } audio_desc_input_terminal_t;
/// AUDIO Output Terminal Descriptor(4.7.2.5) /// AUDIO Output Terminal Descriptor(4.7.2.5)
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor, in bytes: 12. uint8_t bLength ; ///< Size of this descriptor, in bytes: 12.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_OUTPUT_TERMINAL.
@ -752,11 +753,11 @@ typedef struct TU_ATTR_PACKED
uint8_t bCSourceID ; ///< ID of the Clock Entity to which this Output 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. uint16_t bmControls ; ///< See: audio_terminal_output_type_t.
uint8_t iTerminal ; ///< Index of a string descriptor, describing the Output Terminal. uint8_t iTerminal ; ///< Index of a string descriptor, describing the Output Terminal.
} audio_desc_output_terminal_t; } audio_desc_output_terminal_t;
/// AUDIO Feature Unit Descriptor(4.7.2.8) for ONE channel /// AUDIO Feature Unit Descriptor(4.7.2.8) for ONE channel
typedef struct TU_ATTR_PACKED typedef struct TU_ATTR_PACKED
{ {
uint8_t bLength ; ///< Size of this descriptor, in bytes: 14. uint8_t bLength ; ///< Size of this descriptor, in bytes: 14.
uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE. uint8_t bDescriptorType ; ///< Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_FEATURE_UNIT. uint8_t bDescriptorSubType ; ///< Descriptor SubType. Value: AUDIO_CS_AC_INTERFACE_FEATURE_UNIT.
@ -766,9 +767,9 @@ typedef 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. 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] ; } controls[2] ;
uint8_t iTerminal ; ///< Index of a string descriptor, describing this Feature Unit. uint8_t iTerminal ; ///< Index of a string descriptor, describing this Feature Unit.
} audio_desc_feature_unit_t; } audio_desc_feature_unit_t;
/// AUDIO Feature Unit Descriptor(4.7.2.8) for multiple channels /// AUDIO Feature Unit Descriptor(4.7.2.8) for multiple channels
#define audio_desc_feature_unit_n_t(ch_num) \ #define audio_desc_feature_unit_n_t(ch_num) \
struct TU_ATTR_PACKED { \ struct TU_ATTR_PACKED { \
uint8_t bLength ; /* 6+(ch_num+1)*4 */\ uint8_t bLength ; /* 6+(ch_num+1)*4 */\
@ -880,7 +881,7 @@ typedef struct TU_ATTR_PACKED {
int8_t bMax ; /*The setting for the MAX 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*/\ uint8_t bRes ; /*The setting for the RES attribute of the nth subrange of the addressed Control*/\
} subrange[numSubRanges] ; \ } subrange[numSubRanges] ; \
} }
// 5.2.3.2 2-byte Control RANGE Parameter Block // 5.2.3.2 2-byte Control RANGE Parameter Block
#define audio_control_range_2_n_t(numSubRanges) \ #define audio_control_range_2_n_t(numSubRanges) \

View File

@ -384,7 +384,8 @@ static bool audio_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t
{ {
case AUDIO_FORMAT_TYPE_UNDEFINED: case AUDIO_FORMAT_TYPE_UNDEFINED:
// INDIVIDUAL ENCODING PROCEDURE REQUIRED HERE! // INDIVIDUAL ENCODING PROCEDURE REQUIRED HERE!
asm("nop"); TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT encoding not implemented!\r\n");
TU_BREAKPOINT();
break; break;
case AUDIO_FORMAT_TYPE_I: case AUDIO_FORMAT_TYPE_I:
@ -402,19 +403,21 @@ static bool audio_tx_done_cb(uint8_t rhport, audiod_interface_t* audio, uint16_t
default: default:
// YOUR ENCODING AND SENDING IS REQUIRED HERE! // YOUR ENCODING AND SENDING IS REQUIRED HERE!
asm("nop"); TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT_TYPE_I_TX encoding not implemented!\r\n");
TU_BREAKPOINT();
break; break;
} }
break; break;
default: default:
// Desired CFG_TUD_AUDIO_FORMAT_TYPE_TX not implemented! // Desired CFG_TUD_AUDIO_FORMAT_TYPE_TX not implemented!
asm("nop"); TU_LOG2(" Desired CFG_TUD_AUDIO_FORMAT_TYPE_TX not implemented!\r\n");
TU_BREAKPOINT();
break; break;
} }
// Call a weak callback here - a possibility for user to get informed TX was completed // Call a weak callback here - a possibility for user to get informed TX was completed
TU_VERIFY(tud_audio_tx_done_cb(rhport, n_bytes_copied)); if (tud_audio_tx_done_cb) TU_VERIFY(tud_audio_tx_done_cb(rhport, n_bytes_copied));
return true; return true;
} }
@ -497,7 +500,7 @@ static uint16_t audio_fb_done_cb(uint8_t rhport, audiod_interface_t* audio)
// Here we need to return the feedback value // Here we need to return the feedback value
#error RETURN YOUR FEEDBACK VALUE HERE! #error RETURN YOUR FEEDBACK VALUE HERE!
TU_VERIFY(tud_audio_fb_done_cb(rhport)); if (tud_audio_fb_done_cb) TU_VERIFY(tud_audio_fb_done_cb(rhport));
return 0; return 0;
} }
@ -522,57 +525,12 @@ static bool audio_int_ctr_done_cb(uint8_t rhport, audiod_interface_t* audio, uin
*n_bytes_copied = cnt; *n_bytes_copied = cnt;
TU_VERIFY(tud_audio_int_ctr_done_cb(rhport, n_bytes_copied)); if (tud_audio_int_ctr_done_cb) TU_VERIFY(tud_audio_int_ctr_done_cb(rhport, n_bytes_copied));
return true; return true;
} }
#endif #endif
// Callback functions
// Currently the return value has to effect so far. The return value finally is discarded in tud_task(void) in usbd.c - we just incorporate that for later use
#if CFG_TUD_AUDIO_EPSIZE_IN
TU_ATTR_WEAK bool tud_audio_tx_done_cb(uint8_t rhport, uint16_t * n_bytes_copied)
{
(void) rhport;
(void) n_bytes_copied;
/* NOTE: This function should not be modified, when the callback is needed,
the tud_audio_tx_done_cb could be implemented in the user file
*/
return true;
}
#endif
#if CFG_TUD_AUDIO_EPSIZE_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport)
{
(void) rhport;
/* NOTE: This function should not be modified, when the callback is needed,
the tud_audio_fb_done_cb could be implemented in the user file
*/
return true;
}
#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)
{
(void) rhport;
(void) n_bytes_copied;
/* NOTE: This function should not be modified, when the callback is needed,
the tud_audio_int_ctr_done_cb could be implemented in the user file
*/
return true;
}
#endif
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// USBD Driver API // USBD Driver API
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -755,6 +713,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
} }
#endif #endif
// Save current alternative interface setting
_audiod_itf[idxDriver].altSetting[idxItf] = alt;
// Open new EP if necessary - EPs are only to be closed or opened for AS interfaces - Look for AS interface with correct alternate interface // Open new EP if necessary - EPs are only to be closed or opened for AS interfaces - Look for AS interface with correct alternate interface
// Get pointer at end // Get pointer at end
@ -778,8 +738,16 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
#if CFG_TUD_AUDIO_EPSIZE_IN > 0 #if CFG_TUD_AUDIO_EPSIZE_IN > 0
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && ((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.usage == 0x00) // Check if usage is data EP if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && ((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.usage == 0x00) // Check if usage is data EP
{ {
// Save address
_audiod_itf[idxDriver].ep_in = ep_addr; _audiod_itf[idxDriver].ep_in = ep_addr;
_audiod_itf[idxDriver].ep_in_as_intf_num = itf; _audiod_itf[idxDriver].ep_in_as_intf_num = itf;
// HERE WE WOULD NEED TO SCHEDULE OUR FIRST TRANSMIT, HOWEVER, WE ALSO WOULD FIRST NEED TO ENABLE SAMPLING AT ALL - HOW TO HANDLE THIS?
// Invoke callback - fill something in the FIFO here for now
if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
uint16_t n_bytes_copied;
TU_VERIFY(audio_tx_done_cb(rhport, &_audiod_itf[idxDriver], &n_bytes_copied));
} }
#endif #endif
@ -791,6 +759,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
_audiod_itf[idxDriver].ep_out = ep_addr; _audiod_itf[idxDriver].ep_out = ep_addr;
_audiod_itf[idxDriver].ep_out_as_intf_num = itf; _audiod_itf[idxDriver].ep_out_as_intf_num = itf;
// Invoke callback
if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
// Prepare for incoming data // Prepare for incoming data
TU_ASSERT(usbd_edpt_xfer(rhport, ep_addr, _audiod_itf[idxDriver].epout_buf, CFG_TUD_AUDIO_EPSIZE_OUT), false); TU_ASSERT(usbd_edpt_xfer(rhport, ep_addr, _audiod_itf[idxDriver].epout_buf, CFG_TUD_AUDIO_EPSIZE_OUT), false);
} }
@ -799,6 +770,9 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && ((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.usage == 0x10) // Check if usage is implicit data feedback if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && ((tusb_desc_endpoint_t const *) p_desc)->bmAttributes.usage == 0x10) // Check if usage is implicit data feedback
{ {
_audiod_itf[idxDriver].ep_fb = ep_addr; _audiod_itf[idxDriver].ep_fb = ep_addr;
// Invoke callback
if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
} }
#endif #endif
@ -818,20 +792,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
p_desc = tu_desc_next(p_desc); p_desc = tu_desc_next(p_desc);
} }
// // Check for nothing found - we can rely on this since EP descriptors are never the last descriptors, there are always also class specific EP descriptors following!
// TU_VERIFY(p_desc < p_desc_end);
// Save current alternative interface setting
_audiod_itf[idxDriver].altSetting[idxItf] = alt;
// Invoke callback
if (tud_audio_set_itf_cb)
{
if (!tud_audio_set_itf_cb(rhport, p_request)) return false;
}
// Start sending or receiving?
tud_control_status(rhport, p_request); tud_control_status(rhport, p_request);
return true; return true;

View File

@ -1,7 +1,8 @@
/* /*
* The MIT License (MIT) * The MIT License (MIT)
* *
* Copyright (c) 2020 Ha Thach (tinyusb.org) and Reinhard Panhuber * 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
@ -217,15 +218,15 @@ bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_req
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#if CFG_TUD_AUDIO_EPSIZE_IN #if CFG_TUD_AUDIO_EPSIZE_IN
bool tud_audio_tx_done_cb(uint8_t rhport, uint16_t * n_bytes_copied); TU_ATTR_WEAK bool tud_audio_tx_done_cb(uint8_t rhport, uint16_t * n_bytes_copied);
#endif #endif
#if CFG_TUD_AUDIO_EPSIZE_OUT #if CFG_TUD_AUDIO_EPSIZE_OUT
bool tud_audio_rx_done_cb(uint8_t rhport, uint8_t * buffer, uint16_t bufsize); TU_ATTR_WEAK bool tud_audio_rx_done_cb(uint8_t rhport, uint8_t * buffer, uint16_t bufsize);
#endif #endif
#if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP #if CFG_TUD_AUDIO_EPSIZE_OUT > 0 && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
bool tud_audio_fb_done_cb(uint8_t rhport); TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport);
#endif #endif
#if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN

View File

@ -4,6 +4,7 @@
* Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries
* Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2019 Ha Thach (tinyusb.org)
* Copyright (c) 2020 Jan Duempelmann * Copyright (c) 2020 Jan Duempelmann
* Copyright (c) 2020 Reinhard Panhuber
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal