diff --git a/.gitignore b/.gitignore index 901d2cee..5becd162 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.log xmosdfu xmosdfu.* */.build_*/* diff --git a/module_dfu/src/dfu.h b/module_dfu/src/dfu.h index 96ae11f8..810f502f 100644 --- a/module_dfu/src/dfu.h +++ b/module_dfu/src/dfu.h @@ -2,6 +2,9 @@ #ifndef _DFU_H_ #define _DFU_H_ 1 +#include +#include "usb_std_descriptors.h" + #ifndef DFU_VENDOR_ID #error DFU_VENDOR_ID not defined! #endif @@ -51,7 +54,7 @@ unsigned char DFUdevDesc[] = { unsigned char DFUcfgDesc[] = { /* Standard USB device descriptor */ 0x09, /* 0 bLength */ - USB_CONFIGURATION, /* 1 bDescriptorType */ + USB_DESCTYPE_CONFIGURATION, /* 1 bDescriptorType */ 0x1b, /* 2 wTotalLength */ 0x00, /* 3 wTotalLength */ 1, /* 4 bNumInterface: Number of interfaces*/ @@ -83,8 +86,12 @@ unsigned char DFUcfgDesc[] = { 0x01, /* 8 bcdDFUVersion */ }; -int DFUReportResetState(chanend ?c_user_cmd); -int DFUDeviceRequests(XUD_ep c_ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset); +int DFUReportResetState(NULLABLE_RESOURCE(chanend , c_user_cmd)); +int DFUDeviceRequests(XUD_ep c_ep0_out, NULLABLE_REFERENCE_PARAM(XUD_ep, ep0_in), REFERENCE_PARAM(USB_SetupPacket_t, sp), + NULLABLE_RESOURCE(chanend, c_user_cmd), unsigned int altInterface, unsigned int user_reset); + +/* Helper function for C */ +void DFUDelay(unsigned d); #endif /* _DFU_H_ */ diff --git a/module_dfu/src/dfu.xc b/module_dfu/src/dfu.xc index 6792dad4..03d37a0a 100644 --- a/module_dfu/src/dfu.xc +++ b/module_dfu/src/dfu.xc @@ -3,7 +3,7 @@ #include "devicedefines.h" #include "xud.h" -#include "usb.h" +#include "usb_std_requests.h" #include "dfu_types.h" #include "flash_interface.h" @@ -22,6 +22,15 @@ extern int DFU_reset_override; extern void DFUCustomFlashEnable(); extern void DFUCustomFlashDisable(); +void DFUDelay(unsigned d) +{ + timer tmr; + unsigned s; + tmr :> s; + tmr when timerafter(s + d) :> void; +} + + void temp() { asm(".linkset DFU_reset_override, _edp.bss"); diff --git a/module_usb_audio/commands.h b/module_usb_audio/commands.h index bf9f824b..c0339859 100644 --- a/module_usb_audio/commands.h +++ b/module_usb_audio/commands.h @@ -22,10 +22,11 @@ #define SET_SMUX 7 /* c_audioControl */ +//TODO should be an enum #define SET_SAMPLE_FREQ 4 -#define SET_CHAN_COUNT_IN 5 -#define SET_CHAN_COUNT_OUT 6 #define SET_DSD_MODE 7 +#define SET_STREAM_FORMAT_OUT 8 +#define SET_STREAM_FORMAT_IN 9 #include "dsd_support.h" diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index 16ff6835..66b5b2d3 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -104,10 +104,6 @@ #endif #endif -#if defined(IO_EXPANSION) && (IO_EXPANSION == 0) -#undef IO_EXPANSION -#endif - #if defined(IAP) && (IAP == 0) #undef IAP #endif @@ -148,7 +144,10 @@ #undef ADAT_RX #endif -#if defined(DFU) && (DFU == 0) +#if !defined(DFU) +/* Enable DFU by default */ +#define DFU 1 +#elif defined(DFU) && (DFU == 0) #undef DFU #endif @@ -303,40 +302,241 @@ #define BCD_DEVICE ((BCD_DEVICE_J << 8) | ((BCD_DEVICE_M & 0xF) << 4) | (BCD_DEVICE_N & 0xF)) #endif -/* Sample Sub-slot size (bytes) for High Speed. Default is 4 bytes */ -#ifndef SAMPLE_SUBSLOT_SIZE_HS -#define SAMPLE_SUBSLOT_SIZE_HS 4 +#define OUTPUT_FORMAT_COUNT 3 + +#ifndef OUTPUT_FORMAT_COUNT + #ifndef NATIVE_DSD + /* Default format count is 2 (16bit, 24bit) */ + #define OUTPUT_FORMAT_COUNT 2 + #else + /* Default format count is 3 (16bit, 24bit, DSD) */ + #define OUTPUT_FORMAT_COUNT 3 + #endif #endif -#if (SAMPLE_SUBSLOT_SIZE_HS != 2) && (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_HS != 4) -#error Only SAMPLE_SUBSLOT_SIZE_HS 2, 3 or 4 supported #SAMPLE_SUBSLOT_SIZE_HS + + +#if(OUTPUT_FORMAT_COUNT > 3) + #error only OUTPUT_FORMAT_COUNT of 3 or less supported #endif -/* Sample Sub-slot size (bytes) for Full Speed. Default is 3 bytes */ -#ifndef SAMPLE_SUBSLOT_SIZE_FS -#define SAMPLE_SUBSLOT_SIZE_FS 3 +#if defined(NATIVE_DSD) && (OUTPUT_FORMAT_COUNT == 1) + #error OUTPUT_FORMAT_COUNT should be >= 2 when NATIVE_DSD enabled #endif -#if (SAMPLE_SUBSLOT_SIZE_FS != 2) && (SAMPLE_SUBSLOT_SIZE_FS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 4) -#error Only SAMPLE_SUBSLOT_SIZE_FS 2, 3 or 4 supported +#ifdef NATIVE_DSD + /* DSD always the last format */ + #define NATIVE_DSD_FORMAT_NUM (OUTPUT_FORMAT_COUNT) #endif -/* Sample bit resolution for High Speed. Default 24bit*/ -#ifndef SAMPLE_BIT_RESOLUTION_HS -#define SAMPLE_BIT_RESOLUTION_HS 24 +/* Default resolutions */ +/* Note, 24 on the lowests in case OUTPUT_FORMAT_COUNT = 1 */ +#ifndef STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS + #if (NATIVE_DSD_FORMAT_NUM == 1) + #define STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS 32 /* DSD requires 32bits */ + #else + #define STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS 24 + #endif #endif -#if (SAMPLE_BIT_RESOLUTION_HS/8) > SAMPLE_SUBSLOT_SIZE_HS -#error SAMPLE_BIT_RESOLUTION_HS is too big for SAMPLE_SUBSLOT_SIZE_HS +#ifndef STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS +#if (NATIVE_DSD_FORMAT_NUM == 2) + #define STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS 32 /* DSD requires 32bits */ + #else + #define STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS 16 + #endif #endif -/* Sample bit resolution for Full Speed. Default 24bit*/ -#ifndef SAMPLE_BIT_RESOLUTION_FS -#define SAMPLE_BIT_RESOLUTION_FS 24 +#ifndef STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS + #if (NATIVE_DSD_FORMAT_NUM == 3) + #define STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS 32 /* DSD requires 32bits */ + #else + #define STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS 32 + #endif #endif -#if (SAMPLE_BIT_RESOLUTION_FS/8) > SAMPLE_SUBSLOT_SIZE_FS -#error SAMPLE_BIT_RESOLUTION_FS is too big for SAMPLE_SUBSLOT_SIZE_FS +/* Default resolutions for HS */ +#ifndef HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS + #define HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS +#endif + +#ifndef HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS + #define HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS +#endif + +#ifndef HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS + #define HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS +#endif + +/* Default resolutions for FS (same as HS) */ +#ifndef FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS + #define FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS +#endif + +#ifndef FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS + #define FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS +#endif + +#ifndef FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS + #define FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS +#endif + +/* Setup default subslot size based on resolution + * Catch special 24bit case where 4 byte subslot is nicer for our 32-bit machine. + * Typically do not care about this extra bus overhead at High-speed */ +#ifndef HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES + #if (HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS == 24) + #define HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */ + #else + #define HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES (HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS/8) + #endif +#endif + +#ifndef HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES + #if (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS == 24) + #define HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */ + #else + #define HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES (HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS/8) + #endif +#endif + +#ifndef HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES + #if (HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS == 24) + #define HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */ + #else + #define HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES (HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS/8) + #endif +#endif + +/* Setup default FS subslot sizes - make as small as possible */ +#ifndef FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES + #define FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES (FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS/8) +#endif + +#ifndef FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES + #define FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES (FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS/8) +#endif + +#ifndef FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES + #define FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES (FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS/8) +#endif + +/* Setup default formats */ +#ifndef STREAM_FORMAT_OUTPUT_1_DATAFORMAT + #if (NATIVE_DSD_FORMAT_NUM == 1) + #define STREAM_FORMAT_OUTPUT_1_DATAFORMAT UAC_FORMAT_TYPEI_RAW_DATA + #else + #define STREAM_FORMAT_OUTPUT_1_DATAFORMAT UAC_FORMAT_TYPEI_PCM + #endif +#endif + +#ifndef STREAM_FORMAT_OUTPUT_2_DATAFORMAT + #if (NATIVE_DSD_FORMAT_NUM == 2) + #define STREAM_FORMAT_OUTPUT_2_DATAFORMAT UAC_FORMAT_TYPEI_RAW_DATA + #else + #define STREAM_FORMAT_OUTPUT_2_DATAFORMAT UAC_FORMAT_TYPEI_PCM + #endif +#endif + +#ifndef STREAM_FORMAT_OUTPUT_3_DATAFORMAT + #if (NATIVE_DSD_FORMAT_NUM == 3) + #define STREAM_FORMAT_OUTPUT_3_DATAFORMAT UAC_FORMAT_TYPEI_RAW_DATA + #else + #define STREAM_FORMAT_OUTPUT_3_DATAFORMAT UAC_FORMAT_TYPEI_PCM + #endif +#endif + +/* Some stream format checks */ +#if (OUTPUT_FORMAT_COUNT > 0) + #if !defined(HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS) || \ + !defined(HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES) || \ + !defined(STREAM_FORMAT_OUTPUT_1_DATAFORMAT) + #error HS_OUTPUT_STREAM_1 not properly defined + #endif +#endif + +#if (OUTPUT_FORMAT_COUNT > 1) + #if !defined(HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS) || \ + !defined(HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES) || \ + !defined(STREAM_FORMAT_OUTPUT_2_DATAFORMAT) + #error HS_OUTPUT_STREAM_2 not properly defined + #endif +#endif + +#if (OUTPUT_FORMAT_COUNT > 2) + #if !defined(HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS) || \ + !defined(HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES) || \ + !defined(STREAM_FORMAT_OUTPUT_3_DATAFORMAT) + #error HS_OUTPUT_STREAM_3 not properly defined + #endif +#endif + + + +//#ifdef INPUT +#if 1 + + /* Only one Input stream format currently supported */ + #ifndef INPUT_FORMAT_COUNT + #define INPUT_FORMAT_COUNT 1 + #endif + + #if (INPUT_FORMAT_COUNT > 1) + #error + #endif + + #ifndef STREAM_FORMAT_INPUT_1_RESOLUTION_BITS + #define STREAM_FORMAT_INPUT_1_RESOLUTION_BITS 16 + #endif + + /* Default resolutions for HS */ + #ifndef HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS + #define HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS STREAM_FORMAT_INPUT_1_RESOLUTION_BITS + #endif + + /* Default resolutions for FS (same as HS) */ + #ifndef FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS + #define FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS STREAM_FORMAT_INPUT_1_RESOLUTION_BITS + #endif + + /* Setup default subslot sized based on resolution */ + #ifndef HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES + // #if (HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS == 24) + // #define HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */ + //#else + #define HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES (HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS/8) + //#endif + #endif + + /* Setup default FS subslot sizes */ + #ifndef FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES + #define FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS/8) + #endif + + /* Setup default formats */ + #ifndef STREAM_FORMAT_INPUT_1_DATAFORMAT + #define STREAM_FORMAT_INPUT_1_DATAFORMAT UAC_FORMAT_TYPEI_PCM + #endif + +#if 0 + #if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 4) || HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 4) + #define STREAM_FORMAT_INPUT_SUBSLOT_4_USED 1 + #else + #define STREAM_FORMAT_INPUT_SUBSLOT_4_USED 0 + #endif + + #if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 3) || HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 3) + #define STREAM_FORMAT_INPUT_SUBSLOT_3_USED 1 + #else + #define STREAM_FORMAT_INPUT_SUBSLOT_3_USED 0 + #endif + + #if((FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 2) || HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES == 2) + #define STREAM_FORMAT_INPUT_SUBSLOT_2_USED 1 + #else + #define STREAM_FORMAT_INPUT_SUBSLOT_2_USED 0 + #endif +#endif #endif /* Addition interfaces based on defines */ diff --git a/module_usb_audio/endpoint0/audiorequests.xc b/module_usb_audio/endpoint0/audiorequests.xc index 73704d61..65e15db9 100644 --- a/module_usb_audio/endpoint0/audiorequests.xc +++ b/module_usb_audio/endpoint0/audiorequests.xc @@ -5,7 +5,7 @@ #include #include "xud.h" -#include "usb.h" +#include "usb_std_requests.h" #include "usbaudio20.h" #include "usbaudio10.h" #include "dbcalc.h" diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index d55aae92..df45bbb6 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -9,18 +9,22 @@ #ifndef _DEVICE_DESCRIPTORS_ #define _DEVICE_DESCRIPTORS_ -#include "usb.h" -#include "usbaudio20.h" /* Defines from the USB Audio 2.0 Specifications */ #include "devicedefines.h" /* Device specific define */ +#include "usbaudio20.h" /* Defines from the USB Audio 2.0 Specifications */ +#include "usbaudiocommon.h" +#include "usb_std_descriptors.h" /***** Device Descriptors *****/ +// TODO Enum for unit ids? +// TODO structure for string table + #if defined(AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS==1) /* Device Descriptor for Audio Class 1.0 (Assumes Full-Speed) */ unsigned char devDesc_Audio1[] = { 18, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - USB_DEVICE, /* 1 bdescriptorType */ + USB_DESCTYPE_DEVICE, /* 1 bdescriptorType */ 0x0, /* 2 bcd USB */ 0x2, /* 3 bcdUSB */ 0, /* 4 bDeviceClass */ @@ -41,34 +45,33 @@ unsigned char devDesc_Audio1[] = #endif /* Device Descriptor for Audio Class 2.0 (Assumes High-Speed ) */ -unsigned char devDesc_Audio2[] = +USB_Descriptor_Device_t devDesc_Audio2 = { - 18, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - USB_DEVICE, /* 1 bdescriptorType */ - 0, /* 2 bcdUSB */ - 2, /* 3 bcdUSB */ - 0xEF, /* 4 bDeviceClass (See Audio Class Spec page 45) */ - 0x02, /* 5 bDeviceSubClass */ - 0x01, /* 6 bDeviceProtocol */ - 64, /* 7 bMaxPacketSize */ - (VENDOR_ID & 0xFF), /* 8 idVendor */ - (VENDOR_ID >> 8), /* 9 idVendor */ - (PID_AUDIO_2 & 0xFF), /* 10 idProduct */ - (PID_AUDIO_2 >> 8), /* 11 idProduct */ - (BCD_DEVICE & 0xFF), /* 12 bcdDevice : Device release number */ - (BCD_DEVICE >> 8), /* 13 bcdDevice : Device release number */ - MANUFACTURER_STR_INDEX, /* 14 iManufacturer : Index of manufacturer string */ - PRODUCT_STR_INDEX_A2, /* 15 iProduct : Index of product string descriptor */ - 0,// SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */ - 0x02 /* 17 bNumConfigurations : Number of possible configs. - Set to 2 so that Windows does not load Composite driver. */ + .bLength = sizeof(USB_Descriptor_Device_t), + .bDescriptorType = USB_DESCTYPE_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = 0xEF, + .bDeviceSubClass = 0x02, + .bDeviceProtocol = 0x01, + + .bMaxPacketSize0 = 64, + + .idVendor = VENDOR_ID, + .idProduct = PID_AUDIO_2, + .bcdDevice = BCD_DEVICE, + + .iManufacturer = MANUFACTURER_STR_INDEX, + .iProduct = PRODUCT_STR_INDEX_A2, + .iSerialNumber = 0, + + .bNumConfigurations = 0x02 /* Set to 2 such that windows does not load composite driver */ }; /* Device Descriptor for Null Device */ unsigned char devDesc_Null[] = { 18, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - USB_DEVICE, /* 1 bdescriptorType */ + USB_DESCTYPE_DEVICE, /* 1 bdescriptorType */ 0, /* 2 bcdUSB */ 2, /* 3 bcdUSB */ 0x0, /* 4 bDeviceClass */ @@ -94,7 +97,7 @@ unsigned char devDesc_Null[] = unsigned char devQualDesc_Audio2[] = { 10, /* 0 bLength (10 Bytes) */ - USB_DEVICE_QUALIFIER, /* 1 bDescriptorType */ + USB_DESCTYPE_DEVICE_QUALIFIER, /* 1 bDescriptorType */ 0x00, /* 2 bcdUSB (Binary Coded Decimal of usb version) */ 0x02, /* 3 bcdUSB */ 0xEF, /* 4 bDeviceClass */ @@ -110,7 +113,7 @@ unsigned char devQualDesc_Audio2[] = unsigned char devQualDesc_Audio1[] = { 10, /* 0 bLength (10 Bytes) */ - USB_DEVICE_QUALIFIER, /* 1 bDescriptorType */ + USB_DESCTYPE_DEVICE_QUALIFIER, /* 1 bDescriptorType */ 0x00, /* 2 bcdUSB (Binary Coded Decimal of usb version) */ 0x02, /* 3 bcdUSB */ 0x00, /* 4 bDeviceClass */ @@ -126,7 +129,7 @@ unsigned char devQualDesc_Audio1[] = unsigned char devQualDesc_Null[] = { 10, /* 0 bLength (10 Bytes) */ - USB_DEVICE_QUALIFIER, /* 1 bDescriptorType */ + USB_DESCTYPE_DEVICE_QUALIFIER, /* 1 bDescriptorType */ 0x00, /* 2 bcdUSB (Binary Coded Decimal of usb version) */ 0x02, /* 3 bcdUSB */ 0x00, /* 4 bDeviceClass */ @@ -144,25 +147,25 @@ unsigned char devQualDesc_Null[] = #endif /* Lenths of input/output term descriptors - from spec */ -#define LEN_OUTPUT_TERMINAL (0x0C) -#define LEN_INPUT_TERMINAL (0x11) +//#define LEN_OUTPUT_TERMINAL (0x0C) +//#define LEN_INPUT_TERMINAL (0x11) /* Lengh of out terminal descriptors in total */ -#define LEN_TERMS_OUT ((LEN_OUTPUT_TERMINAL + LEN_INPUT_TERMINAL) * OUTPUT_INTERFACES) -#define LEN_TERMS_IN ((LEN_OUTPUT_TERMINAL + LEN_INPUT_TERMINAL) * INPUT_INTERFACES) +//#define LEN_TERMS_OUT ((LEN_OUTPUT_TERMINAL + LEN_INPUT_TERMINAL) * OUTPUT_INTERFACES) +//#define LEN_TERMS_IN ((LEN_OUTPUT_TERMINAL + LEN_INPUT_TERMINAL) * INPUT_INTERFACES) /* Calc total length of configuration desc based on defines */ -#ifdef OUTPUT -#define LEN_FU_OUT (6 + (NUM_USB_CHAN_OUT + 1) * 4) -#else -#define LEN_FU_OUT 0 -#endif +//#ifdef OUTPUT +//#define LEN_FU_OUT (6 + (NUM_USB_CHAN_OUT + 1) * 4) +//#else +//#define LEN_FU_OUT 0 +//#endif -#ifdef INPUT -#define LEN_FU_IN (6 + (NUM_USB_CHAN_IN + 1) * 4) -#else -#define LEN_FU_IN 0 -#endif +//#ifdef INPUT +//#define LEN_FU_IN (6 + (NUM_USB_CHAN_IN + 1) * 4) +//#else +//#define LEN_FU_IN 0 +//#endif #ifdef MIDI @@ -171,65 +174,71 @@ unsigned char devQualDesc_Null[] = #define MIDI_LENGTH (0) #endif -#ifdef IAP -#ifdef IAP_INT_EP -#define IAP_LENGTH (30) +#ifdef DFU +#define DFU_LENGTH (18) #else -#define IAP_LENGTH (23) -#endif -#else -#define IAP_LENGTH (0) +#define DFU_LENGTH (0) #endif -#if defined(SPDIF_RX) || defined(ADAT_RX) -#define AUD_INT_EP_LEN (7) -#else -#define AUD_INT_EP_LEN (0) -#endif +//#ifdef IAP +//#ifdef IAP_INT_EP +//#define IAP_LENGTH (30) +//#else +//#define IAP_LENGTH (23) +//#endif +//#else +//#define IAP_LENGTH (0) +//#endif -#ifdef AUDIO_PATH_XUS -#define LEN_XU_OUT (16 * OUTPUT_INTERFACES) -#define LEN_XU_IN (16 * INPUT_INTERFACES) -#else -#define LEN_XU_OUT (0) -#define LEN_XU_IN (0) -#endif +//#if defined(SPDIF_RX) || defined(ADAT_RX) +//#define AUD_INT_EP_LEN (7) +//#else +//#define AUD_INT_EP_LEN (0) +//#endif -#if defined (MIXER) && (MAX_MIX_COUNT > 0) - #define LEN_XU_MIX (17) - #define MIX_BMCONTROLS_LEN_TMP ((MAX_MIX_COUNT * MIX_INPUTS) / 8) +//#ifdef AUDIO_PATH_XUS +//#define LEN_XU_OUT (16 * OUTPUT_INTERFACES) +//#define LEN_XU_IN (16 * INPUT_INTERFACES) +//#else +//#define LEN_XU_OUT (0) +//#define LEN_XU_IN (0) +//#endif - #if ((MAX_MIX_COUNT * MIX_INPUTS)%8)==0 - #define MIX_BMCONTROLS_LEN (MIX_BMCONTROLS_LEN_TMP) - #else - #define MIX_BMCONTROLS_LEN (MIX_BMCONTROLS_LEN_TMP+1) - #endif - #define MIXER_LENGTH (13+1+MIX_BMCONTROLS_LEN) -#else - #define LEN_XU_MIX (0) - #define MIXER_LENGTH (0) -#endif +//#if defined (MIXER) && (MAX_MIX_COUNT > 0) + // #define LEN_XU_MIX (17) + // #define MIX_BMCONTROLS_LEN_TMP ((MAX_MIX_COUNT * MIX_INPUTS) / 8) -#define LEN_CLK (8) -#define LEN_CLK_SEL (7 + NUM_CLOCKS) -#define LEN_CLOCKING (LEN_CLK_SEL + (NUM_CLOCKS * LEN_CLK)) + //#if ((MAX_MIX_COUNT * MIX_INPUTS)%8)==0 + // #define MIX_BMCONTROLS_LEN (MIX_BMCONTROLS_LEN_TMP) + //#else + // #define MIX_BMCONTROLS_LEN (MIX_BMCONTROLS_LEN_TMP+1) + //#endif + //#define MIXER_LENGTH (13+1+MIX_BMCONTROLS_LEN) +//#else + // #define LEN_XU_MIX (0) + // #define MIXER_LENGTH (0) +//#endif + +//#define LEN_CLK (8) +//#define LEN_CLK_SEL (7 + NUM_CLOCKS) +//#define LEN_CLOCKING (LEN_CLK_SEL + (NUM_CLOCKS * LEN_CLK)) /* Total length of the Class-Specific AC Interface Descriptor - Clock Entities, Units and Terminals */ -#define LEN_AC (9) -#define TLEN_AC (LEN_AC + LEN_FU_OUT + LEN_FU_IN + LEN_CLOCKING + LEN_TERMS_OUT + LEN_TERMS_IN + LEN_XU_OUT + LEN_XU_IN + LEN_XU_MIX) +//#define LEN_AC (9) +//#define TLEN_AC (LEN_AC + LEN_FU_OUT + LEN_FU_IN + LEN_CLOCKING + LEN_TERMS_OUT + LEN_TERMS_IN + LEN_XU_OUT + LEN_XU_IN + LEN_XU_MIX) -#ifdef ADAT_RX -#define INPUT_ALT_LENGTH (46) -#else -#define INPUT_ALT_LENGTH (0) -#endif +//#ifdef ADAT_RX +//#define INPUT_ALT_LENGTH (46) +//#else +//#define INPUT_ALT_LENGTH (0) +//#endif -#ifdef ADAT_TX -#define OUTPUT_ALT_LENGTH_ADAT (46) -#else -#define OUTPUT_ALT_LENGTH_ADAT (0) -#endif +//#ifdef ADAT_TX +//#define OUTPUT_ALT_LENGTH_ADAT (46) +//#else +//#define OUTPUT_ALT_LENGTH_ADAT (0) +//#endif #ifdef NATIVE_DSD #define ALT_SETTING_DSD (2) @@ -237,13 +246,13 @@ unsigned char devQualDesc_Null[] = #ifdef ALT_SETTING_DSD #define ALT_SETTING_ADAT_TX (3) -#define OUTPUT_ALT_LENGTH_DSD (53) +//#define OUTPUT_ALT_LENGTH_DSD (53) #else #define ALT_SETTING_ADAT_TX (2) -#define OUTPUT_ALT_LENGTH_DSD (0) +//#define OUTPUT_ALT_LENGTH_DSD (0) #endif -#define OUTPUT_ALT_LENGTH (OUTPUT_ALT_LENGTH_ADAT + OUTPUT_ALT_LENGTH_DSD) +//#define OUTPUT_ALT_LENGTH (OUTPUT_ALT_LENGTH_ADAT + OUTPUT_ALT_LENGTH_DSD) // Positions in strDescs @@ -281,894 +290,796 @@ enum { }; #ifdef HID_CONTROLS -unsigned char hidReportDescriptor[] = { -0x05, 0x0c, /* Usage Page (Consumer Device) */ -0x09, 0x01, /* Usage (Consumer Control) */ -0xa1, 0x01, /* Collection (Application) */ -0x15, 0x00, /* Logical Minimum (0) */ -0x25, 0x01, /* Logical Maximum (1) */ -0x09, 0xb0, /* Usage (Play) */ -0x09, 0xb5, /* Usage (Scan Next Track) */ -0x09, 0xb6, /* Usage (Scan Previous Track) */ -0x09, 0xe9, /* Usage (Volume Up) */ -0x09, 0xea, /* Usage (Volume Down) */ -0x09, 0xe2, /* Usage (Mute) */ -0x75, 0x01, /* Report Size (1) */ -0x95, 0x06, /* Report Count (6) */ -0x81, 0x02, /* Input (Data, Var, Abs) */ -0x95, 0x02, /* Report Count (2) */ -0x81, 0x01, /* Input (Cnst, Ary, Abs) */ -0xc0 /* End collection */ +unsigned char hidReportDescriptor[] = +{ + 0x05, 0x0c, /* Usage Page (Consumer Device) */ + 0x09, 0x01, /* Usage (Consumer Control) */ + 0xa1, 0x01, /* Collection (Application) */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x25, 0x01, /* Logical Maximum (1) */ + 0x09, 0xb0, /* Usage (Play) */ + 0x09, 0xb5, /* Usage (Scan Next Track) */ + 0x09, 0xb6, /* Usage (Scan Previous Track) */ + 0x09, 0xe9, /* Usage (Volume Up) */ + 0x09, 0xea, /* Usage (Volume Down) */ + 0x09, 0xe2, /* Usage (Mute) */ + 0x75, 0x01, /* Report Size (1) */ + 0x95, 0x06, /* Report Count (6) */ + 0x81, 0x02, /* Input (Data, Var, Abs) */ + 0x95, 0x02, /* Report Count (2) */ + 0x81, 0x01, /* Input (Cnst, Ary, Abs) */ + 0xc0 /* End collection */ }; - #endif -#define HID_LENGTH (25 * HID_INTERFACES) +//#define HID_LENGTH (25 * HID_INTERFACES) /* Total length of config descriptor */ -#define CONFIG_DESC_LENGTH (9) -#define INTERFACE_ASS_LENGTH (8) -#define AUD_CTRL_INT_LENGTH (9) -#define AUD_CS_INT_LENGTH (9) +//#define CONFIG_DESC_LENGTH (9) +//#define INTERFACE_ASS_LENGTH (8) +//#define AUD_CTRL_INT_LENGTH (9) +//#define AUD_CS_INT_LENGTH (9) -#define CFG_TOTAL_LENGTH_A2 (CONFIG_DESC_LENGTH + INTERFACE_ASS_LENGTH + AUD_CTRL_INT_LENGTH + (AUD_INT_EP_LEN) + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH + HID_LENGTH) +//#define CFG_TOTAL_LENGTH_A2 (CONFIG_DESC_LENGTH + INTERFACE_ASS_LENGTH + AUD_CTRL_INT_LENGTH + (AUD_INT_EP_LEN) + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH + HID_LENGTH) /* We need to this for patching descriptors for FS/HS switching */ -#define STREAMING_OUTPUT_ALT1_OFFSET (CONFIG_DESC_LENGTH + INTERFACE_ASS_LENGTH + AUD_CTRL_INT_LENGTH + TLEN_AC + AUD_INT_EP_LEN + 9 + 9) +//#define STREAMING_OUTPUT_ALT1_OFFSET (CONFIG_DESC_LENGTH + INTERFACE_ASS_LENGTH + AUD_CTRL_INT_LENGTH + TLEN_AC + AUD_INT_EP_LEN + 9 + 9) -#define STREAMING_INPUT_ALT1_OFFSET (CONFIG_DESC_LENGTH + INTERFACE_ASS_LENGTH + AUD_CTRL_INT_LENGTH + TLEN_AC + AUD_INT_EP_LEN + (OUTPUT_INTERFACES *62)+OUTPUT_ALT_LENGTH + 9 + 9) +//#define STREAMING_INPUT_ALT1_OFFSET (CONFIG_DESC_LENGTH + INTERFACE_ASS_LENGTH + AUD_CTRL_INT_LENGTH + TLEN_AC + AUD_INT_EP_LEN + (OUTPUT_INTERFACES *62)+OUTPUT_ALT_LENGTH + 9 + 9) /* Max packet sizes: * Samples per channel. e.g (192000+7999/8000) = 24 * Must allow 1 sample extra per chan (24 + 1) = 25 * Multiply by number of channels and bytes 25 * 2 * 4 = 200 bytes */ -#define MAX_PACKET_SIZE_OUT_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_OUT * SAMPLE_SUBSLOT_SIZE_HS) -#define MAX_PACKET_SIZE_OUT_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_OUT_FS * SAMPLE_SUBSLOT_SIZE_FS) // Samples per channel -#define MAX_PACKET_SIZE_IN_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_IN * SAMPLE_SUBSLOT_SIZE_HS) -#define MAX_PACKET_SIZE_IN_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_IN_FS * SAMPLE_SUBSLOT_SIZE_FS) // Samples per channel +#define MAX_PACKET_SIZE_MULT_OUT_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_OUT) +#define MAX_PACKET_SIZE_MULT_OUT_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_OUT_FS) +#define MAX_PACKET_SIZE_MULT_IN_HS ((((MAX_FREQ+7999)/8000)+1) * NUM_USB_CHAN_IN) +#define MAX_PACKET_SIZE_MULT_IN_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_IN_FS) -/* Configuration Descriptor for Audio 2.0 (HS) operation */ -unsigned char cfgDesc_Audio2[] = +#define HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_HS * HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES) +#define HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_HS * HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES) +#define HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_HS * HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES) + +#define FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_FS * FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES) +#define FS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_FS * FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES) +#define FS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_OUT_FS * FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES) + +#define HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_IN_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) +#define FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_IN_FS * FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES) + +typedef struct { - 0x09, /* 0 bLength */ - USB_CONFIGURATION, /* 1 bDescriptorType */ - (CFG_TOTAL_LENGTH_A2 & 0xFF), /* 2 wTotalLength */ - (CFG_TOTAL_LENGTH_A2 >> 8), /* 3 wTotalLength */ - NUM_INTERFACES, /* 4 bNumInterface: Number of interfaces*/ - 0x01, /* 5 bConfigurationValue */ - 0x00, /* 6 iConfiguration */ + /* Class Specific Audio Control Interface Header Descriptor */ + UAC_Descriptor_Interface_AC_t Audio_ClassControlInterface; + USB_Descriptor_Audio_ClockSource_t Audio_ClockSource; + USB_Descriptor_Audio_ClockSelector_t Audio_ClockSelector; +#ifdef OUTPUT + /* Output path */ + USB_Descriptor_Audio_InputTerminal_t Audio_Out_InputTerminal; + USB_Descriptor_Audio_FeatureUnit_Out_t Audio_Out_FeatureUnit; + USB_Descriptor_Audio_OutputTerminal_t Audio_Out_OutputTerminal; +#endif +#ifdef INPUT + /* Input path */ + USB_Descriptor_Audio_InputTerminal_t Audio_In_InputTerminal; + USB_Descriptor_Audio_FeatureUnit_In_t Audio_In_FeatureUnit; + USB_Descriptor_Audio_OutputTerminal_t Audio_In_OutputTerminal; +#endif +} __attribute__((packed)) USB_CfgDesc_Audio2_CS_Control_Int; + +typedef struct +{ + /* Configuration header */ + USB_Descriptor_Configuration_Header_t Config; + + /* Audio Control */ + USB_Descriptor_Interface_Association_t Audio_InterfaceAssociation; + USB_Descriptor_Interface_t Audio_StdControlInterface; /* Standard Audio Control Interface Header Descriptor */ + + USB_CfgDesc_Audio2_CS_Control_Int Audio_CS_Control_Int; +#ifdef OUTPUT + /* Audio streaming: Output stream */ + USB_Descriptor_Interface_t Audio_Out_StreamInterface_Alt0; /* Zero bandwith alternative */ + USB_Descriptor_Interface_t Audio_Out_StreamInterface_Alt1; + USB_Descriptor_Audio_Interface_AS_t Audio_Out_ClassStreamInterface; + USB_Descriptor_Audio_Format_Type1_t Audio_Out_Format; + USB_Descriptor_Endpoint_t Audio_Out_Endpoint; + USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_Out_ClassEndpoint; + USB_Descriptor_Endpoint_t Audio_Out_Fb_Endpoint; +#if (OUTPUT_FORMAT_COUNT > 1) + USB_Descriptor_Interface_t Audio_Out_StreamInterface_Alt2; + USB_Descriptor_Audio_Interface_AS_t Audio_Out_ClassStreamInterface_2; + USB_Descriptor_Audio_Format_Type1_t Audio_Out_Format_2; + USB_Descriptor_Endpoint_t Audio_Out_Endpoint_2; + USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_Out_ClassEndpoint_2; + USB_Descriptor_Endpoint_t Audio_Out_Fb_Endpoint_2; +#endif +#if (OUTPUT_FORMAT_COUNT > 2) + USB_Descriptor_Interface_t Audio_Out_StreamInterface_Alt3; + USB_Descriptor_Audio_Interface_AS_t Audio_Out_ClassStreamInterface_3; + USB_Descriptor_Audio_Format_Type1_t Audio_Out_Format_3; + USB_Descriptor_Endpoint_t Audio_Out_Endpoint_3; + USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_Out_ClassEndpoint_3; + USB_Descriptor_Endpoint_t Audio_Out_Fb_Endpoint_3; +#endif +#endif +#ifdef INPUT + /* Audio Streaming: Input stream */ + USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt0; /* Zero bandwith alternative */ + USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt1; + USB_Descriptor_Audio_Interface_AS_t Audio_In_ClassStreamInterface; + USB_Descriptor_Audio_Format_Type1_t Audio_In_Format; + USB_Descriptor_Endpoint_t Audio_In_Endpoint; + USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_In_ClassEndpoint; +#endif + +#ifdef MIDI + /* MIDI descriptors currently handled as a single block */ + unsigned char configDesc_Midi[MIDI_LENGTH]; +#endif + +#ifdef DFU + /* DFU descriptors currently handled as a single block */ + unsigned char configDesc_DFU[DFU_LENGTH]; +#endif + +#ifdef IAP + USB_Descriptor_Interface_t iAP_Interface; + USB_Descriptor_Endpoint_t iAP_Out_Endpoint; + USB_Descriptor_Endpoint_t iAP_In_Endpoint; +#ifdef IAP_INT_EP + USB_Descriptor_Endpoint_t iAP_Interrupt_Endpoint; +#endif +#endif + +#ifdef HID_CONTROLS + USB_Descriptor_Interface_t HID_Interface; + unsigned char hidDesc[9]; //TODO ideally we would have a struct for this. + USB_Descriptor_Endpoint_t HID_In_Endpoint; +#endif + +}__attribute__((packed)) USB_Config_Descriptor_Audio2_t; + +#if 1 +USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= +{ + .Config = + { + .bLength = sizeof(USB_Descriptor_Configuration_Header_t), + .bDescriptorType = USB_DESCTYPE_CONFIGURATION, + .wTotalLength = sizeof(USB_Config_Descriptor_Audio2_t), + .bNumInterfaces = NUM_INTERFACES, + .bConfigurationValue = 0x01, + .iConfiguration = 0x00, #ifdef SELF_POWERED - 192, /* 7 bmAttributes */ + .bmAttributes = 192, #else - 128, /* 7 bmAttributes */ -#endif - BMAX_POWER, /* 8 bMaxPower */ - - /* Interface Association Descriptor */ - 0x08, /* 0 bLength */ - 0x0b, /* 1 bDescriptorType */ - 0x00, /* 2 bFirstInterface */ - AUDIO_INTERFACES, /* 3 bInterfaceCount */ - AUDIO_FUNCTION, /* 4 bFunctionClass: AUDIO_FUNCTION */ - FUNCTION_SUBCLASS_UNDEFINED, /* 5 bFunctionSubClass: FUNCTION_SUBCLASS_UNDEFINED */ - AF_VERSION_02_00, /* 6 bFunctionProtocol: AF_VERSION_02_00 */ - 0x00, /* 7 iFunction (String Index) */ + .bmAttributes = 128, +#endif + .bMaxPower = BMAX_POWER, + }, + .Audio_InterfaceAssociation = + { + .bLength = sizeof(USB_Descriptor_Interface_Association_t), + .bDescriptorType = USB_DESCTYPE_INTERFACE_ASSOCIATION, + .bFirstInterface = 0x00, + .bInterfaceCount = AUDIO_INTERFACES, + .bFunctionClass = AUDIO_FUNCTION, + .bFunctionSubClass = FUNCTION_SUBCLASS_UNDEFINED, + .bFunctionProtocol = UAC_FUNC_PROTOCOL_AF_VERSION_02_00, + .iFunction = 0x00, + }, + /* Standard Audio Control Interface Descriptor (Note: Must be first with lowest interface number)r */ - 0x09, /* 0 bLength: 9 */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - 0x00, /* 2 bInterfaceNumber */ - 0x00, /* 3 bAlternateSetting: Must be 0 */ + .Audio_StdControlInterface = + { + .bLength = sizeof(USB_Descriptor_Interface_t), + .bDescriptorType = USB_DESCTYPE_INTERFACE, + .bInterfaceNumber = 0x00, + .bAlternateSetting = 0x00, /* Must be 0 */ #if defined(SPDIF_RX) || defined(ADAT_RX) - 0x01, /* 4 bNumEndpoints (0 or 1 if optional interrupt endpoint is present */ + .bNumEndpoints = 0x01, /* 0 or 1 if optional interrupt endpoint is present */ #else - 0x00, + .bNumEndpoints = 0x00, #endif - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOCONTROL, /* 6 bInterfaceSubClass: AUDIOCONTROL*/ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - PRODUCT_STR_INDEX_A2, /* 8 iInterface (re-use iProduct) */ + .bInterfaceClass = USB_CLASS_AUDIO, + .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOCONTROL, + .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00, + .iInterface = PRODUCT_STR_INDEX_A2, + }, - /* Class Specific Audio Control Interface Header Descriptor: */ - LEN_AC, /* 0 bLength */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - HEADER, /* 2 bDescriptorSubtype: HEADER */ - 0x00, 0x02, /* 3:4 bcdUSB */ - IO_BOX, /* 5 bCatagory (Primary use of audio function) */ - (TLEN_AC & 0xFF), /* 6 wTotalLength */ - (TLEN_AC >> 8), /* 7 wTotalLength */ - 0x00, /* 8 bmControls (0:1 Latency Control, 2:7 must be 0 */ + .Audio_CS_Control_Int = + { + /* Class Specific Audio Control Interface Header Descriptor: */ + .Audio_ClassControlInterface = + { + .bLength = sizeof(UAC_Descriptor_Interface_AC_t), + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubtype = UAC_CS_AC_INTERFACE_SUBTYPE_HEADER, + .bcdADC = 0x0200, + .bCatagory = UAC_FUNCTION_IO_BOX, /*(Primary use of audio function) */ + .wTotalLength = sizeof(USB_CfgDesc_Audio2_CS_Control_Int), + .bmControls = 0x00, /* 0:1 Latency Control, 2:7 must be 0 */ + }, - /* Clock Source Descriptor (4.7.2.1) */ - LEN_CLK, /* 0 bLength: 8 */ - CS_INTERFACE, /* 1 bDescriptorType */ - CLOCK_SOURCE, /* 2 bDescriptorSubtype */ - ID_CLKSRC_INT, /* 3 bClockID */ - 0x03, /* 4 bmAttributes: - D[1:0] : - 00: External Clock - 01: Internal Fixed Clock - 10: Internal Variable Clock - 11: Internal Progamable Clock - D[2] : Clock synced to SOF - D[7:3] : Reserved (0) */ - 0x07, /* 5 bmControls - D[1:0] : Clock Freq Control - D[3:2] : Clock Validity Control - D[7:4] : Reserved (0) */ - 0x00, /* 6 bAssocTerminal */ - INTERNAL_CLOCK_STRING_INDEX, /* 7 iClockSource (String Index) */ + /* Clock Source Descriptor (4.7.2.1) */ + .Audio_ClockSource = + { + .bLength = sizeof(USB_Descriptor_Audio_ClockSource_t), + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubType = UAC_CS_AC_INTERFACE_SUBTYPE_CLOCK_SOURCE, + .bClockID = ID_CLKSRC_INT, + .bmAttributes = 0x03, /* D[1:0] : + 00: External Clock + 01: Internal Fixed Clock + 10: Internal Variable Clock + 11: Internal Progamable Clock + D[2] : Clock synced to SOF + D[7:3] : Reserved (0) */ + .bmControls = 0x07, /* + D[1:0] : Clock Freq Control + D[3:2] : Clock Validity Control + D[7:4] : Reserved (0) */ + .bAssocTerminal = 0x00, + .iClockSource = INTERNAL_CLOCK_STRING_INDEX, + }, + /* Clock Selector Descriptor (4.7.2.2) */ + .Audio_ClockSelector = + { + .bLength = sizeof(USB_Descriptor_Audio_ClockSelector_t), + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubType = UAC_CS_AC_INTERFACE_SUBTYPE_CLOCK_SELECTOR, + .bClockID = ID_CLKSEL, + .bNrPins = NUM_CLOCKS, + .baCSourceId[0] = ID_CLKSRC_INT, #ifdef SPDIF_RX - /* Clock Source Descriptor (4.7.2.1) */ - LEN_CLK, /* 0 bLength: 8 */ - CS_INTERFACE, /* 1 bDescriptorType */ - CLOCK_SOURCE, /* 2 bDescriptorSubtype */ - ID_CLKSRC_EXT, /* 3 bClockID */ - 0x00, /* 4 bmAttributes: - D[1:0] : - 00: External Clock - 01: Internal Fixed Clock - 10: Internal Variable Clock - 11: Internal Progamable Clock - D[2] : Clock synced to SOF - D[7:3] : Reserved (0) */ - 0x07, /* 5 bmControls - D[1:0] : Clock Freq Control - D[3:2] : Clock Validity Control - D[7:4] : Reserved (0) */ - 0x00, /* 6 bAssocTerminal */ - SPDIF_CLOCK_STRING_INDEX, /* 7 iClockSource (String Index) */ + ID_CLKSRC_EXT, #endif #ifdef ADAT_RX - /* Clock Source Descriptor (4.7.2.1) */ - LEN_CLK, /* 0 bLength: 8 */ - CS_INTERFACE, /* 1 bDescriptorType */ - CLOCK_SOURCE, /* 2 bDescriptorSubtype */ - ID_CLKSRC_ADAT, /* 3 bClockID */ - 0x00, /* 4 bmAttributes: - D[1:0] : - 00: External Clock - 01: Internal Fixed Clock - 10: Internal Variable Clock - 11: Internal Progamable Clock - D[2] : Clock synced to SOF - D[7:3] : Reserved (0) */ - 0x07, /* 5 bmControls - D[1:0] : Clock Freq Control - D[3:2] : Clock Validity Control - D[7:4] : Reserved (0) */ - 0x00, /* 6 bAssocTerminal */ - ADAT_CLOCK_STRING_INDEX, /* 7 iClockSource (String Index) */ + ID_CLKSRC_ADAT, #endif - /* Clock Selector Descriptor (4.7.2.2) */ - LEN_CLK_SEL, /* 0 bLength */ - CS_INTERFACE, /* 1 bDescriptorType */ - CLOCK_SELECTOR, /* 2 bDescriptorSubtype */ - ID_CLKSEL, /* 3 bClockID */ - NUM_CLOCKS, /* 4 Number of input pins*/ - ID_CLKSRC_INT, -#ifdef SPDIF_RX - ID_CLKSRC_EXT, -#endif -#ifdef ADAT_RX - ID_CLKSRC_ADAT, -#endif - 0x03, /* 5 bmControls - D[1:0] : Clock Selector Control - D[7:4] : Reserved (0) */ - 13, /* 7 iClockSel (String Index) */ + .bmControl = 0x03, + .iClockSelector = 13, /* TODO Shoudn't be hard-coded */ + }, #ifdef OUTPUT - /* OUTPUT PATH FROM HOST TO DEVICE */ - /* Input Terminal Descriptor (USB Input Terminal) */ - 0x11, /* 0 bLength in bytes: 17 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - INPUT_TERMINAL, /* 2 bDescriptorSubType: INPUT_TERMINAL */ - ID_IT_USB, /* 3 bTerminalID */ - USB_TERMTYPE_USB_STREAMING&0xff, - USB_TERMTYPE_USB_STREAMING>>8, /* 5 wTerminalType: USB Streaming */ - 0x00, /* 6 bAssocTerminal */ - ID_CLKSEL, /* 7 bCSourceID: ID of Clock Entity */ - NUM_USB_CHAN_OUT, /* 8 bNrChannels */ - 0,0,0,0, /* 9 bmChannelConfig */ - OUTPUT_INTERFACE_STRING_INDEX, /* 13 iChannelNames */ - 0x00, 0x00, /* 14 bmControls */ - 6, /* 16 iTerminal */ + /* Input Terminal Descriptor (USB Input Terminal) */ + .Audio_Out_InputTerminal = + { + .bLength = sizeof(USB_Descriptor_Audio_InputTerminal_t), + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType */ + UAC_CS_AC_INTERFACE_SUBTYPE_INPUT_TERMINAL, /* 2 bDescriptorSubType: INPUT_TERMINAL */ + ID_IT_USB, /* 3 bTerminalID */ + USB_TERMTYPE_USB_STREAMING, /* 5 wTerminalType: USB Streaming */ + 0x00, /* 6 bAssocTerminal */ + ID_CLKSEL, /* 7 bCSourceID: ID of Clock Entity */ + NUM_USB_CHAN_OUT, /* 8 bNrChannels */ + 0x00000000, /* 9 bmChannelConfig TODO. Set me! */ + OUTPUT_INTERFACE_STRING_INDEX, /* 13 iChannelNames */ + 0x0000, /* 14 bmControls */ + 6, /* 16 iTerminal */ + }, + /* Feature Unit Descriptor */ + .Audio_Out_FeatureUnit = + { + .bLength = sizeof(USB_Descriptor_Audio_FeatureUnit_Out_t), /* 0 bLength: 6+(ch + 1)*4 */ + 0x24, /* 1 bDescriptorType: CS_INTERFACE */ + 0x06, /* 2 bDescriptorSubType: FEATURE_UNIT */ + FU_USBOUT, /* 3 bUnitID */ #ifdef AUDIO_PATH_XUS - /* Extension Unit Descriptor (4.7.2.12) */ - LEN_XU_OUT, /* 0 bLength (15 + p, when p is number of sources) */ - CS_INTERFACE, /* 1 bDescriptorType */ - EXTENSION_UNIT, /* 2 bDescriptorSubtype */ - ID_XU_OUT, /* 3 bUnitID */ - 0, /* 4 wExtensionCode */ - 0, /* 5 wExtensionCode */ - 1, /* 6 bNrPins */ - ID_IT_USB, /* 7 baSourceId(1) */ - NUM_USB_CHAN_OUT, /* 8+p bNrChannels */ - 0, /* 9+p bmChannelConfig */ - 0, /* 10+p bmChannelConfig */ - 0, /* 11+p bmChannelConfig */ - 0, /* 12+p bmChannelConfig */ - 0, /* 13+p iChannelNames */ - 3, /* 14+p bmControls */ - 0, /* 15+p iExtension */ -#endif - - /* Feature Unit Descriptor */ - LEN_FU_OUT, /* 0 bLength: 6+(ch + 1)*4 */ - 0x24, /* 1 bDescriptorType: CS_INTERFACE */ - 0x06, /* 2 bDescriptorSubType: FEATURE_UNIT */ - FU_USBOUT, /* 3 bUnitID */ -#ifdef AUDIO_PATH_XUS - ID_XU_OUT, /* 4 bSourceID */ + ID_XU_OUT, /* 4 bSourceID */ #else - ID_IT_USB, /* 4 bSourceID */ + ID_IT_USB, /* 4 bSourceID */ #endif + { #if (NUM_USB_CHAN_OUT > 0) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(0) : Mute and Volume host read and writable */ - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(1) */ + 0x0000000F, /* bmaControls(0) : Mute and Volume host read and writable */ + 0x0000000F, /* bmaControls(1) */ #endif #if (NUM_USB_CHAN_OUT > 1) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(2) */ + 0x0000000F, /* bmaControls(2) */ #endif #if (NUM_USB_CHAN_OUT > 2) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(3) */ + 0x0000000F, /* bmaControls(3) */ #endif #if (NUM_USB_CHAN_OUT > 3) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(4) */ + 0x0000000F, /* bmaControls(4) */ #endif #if (NUM_USB_CHAN_OUT > 4) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(5) */ + 0x0000000F, /* bmaControls(5) */ #endif #if (NUM_USB_CHAN_OUT > 5) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(6) */ + 0x0000000F, /* bmaControls(6) */ #endif #if (NUM_USB_CHAN_OUT > 6) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(7) */ + 0x0000000F, /* bmaControls(7) */ #endif #if (NUM_USB_CHAN_OUT > 7) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(8) */ + 0x0000000F, /* bmaControls(8) */ #endif #if (NUM_USB_CHAN_OUT > 8) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(9) */ + 0x0000000F, /* bmaControls(9) */ #endif #if (NUM_USB_CHAN_OUT > 9) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(10) */ + 0x0000000F, /* bmaControls(10) */ #endif #if (NUM_USB_CHAN_OUT > 10) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(11) */ + 0x0000000F, /* bmaControls(11) */ #endif #if (NUM_USB_CHAN_OUT > 11) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(12) */ + 0x0000000F, /* bmaControls(12) */ #endif #if (NUM_USB_CHAN_OUT > 12) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(13) */ + 0x0000000F, /* bmaControls(13) */ #endif #if (NUM_USB_CHAN_OUT > 13) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(14) */ + 0x0000000F, /* bmaControls(14) */ #endif #if (NUM_USB_CHAN_OUT > 14) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(15) */ + 0x0000000F, /* bmaControls(15) */ #endif #if (NUM_USB_CHAN_OUT > 15) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(16) */ + 0x0000000F, /* bmaControls(16) */ #endif #if (NUM_USB_CHAN_OUT > 16) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(17) */ + 0x0000000F, /* bmaControls(17) */ #endif #if (NUM_USB_CHAN_OUT > 17) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(18) */ + 0x0000000F, /* bmaControls(18) */ #endif #if (NUM_USB_CHAN_OUT > 18) #error NUM_USB_CHAN_OUT > 18 #endif - 0, /* 60 iFeature */ + }, + 0, /* 60 iFeature */ + }, - /* Output Terminal Descriptor (Audio) */ - 0x0C, /* 0 bLength */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - OUTPUT_TERMINAL, /* 2 bDescriptorSubType: OUTPUT_TERMINAL */ - ID_OT_AUD, /* 3 bTerminalID */ - (SPEAKER&0xff),SPEAKER>>8, /* 4 wTerminalType */ - 0x00, /* 6 bAssocTerminal */ - FU_USBOUT, /* 7 bSourceID Connect to analog input feature unit*/ - ID_CLKSEL, /* 8 bCSourceUD */ - 0x00, 0x00, /* 9 bmControls */ - 0, /* 11 iTerminal */ + /* Output Terminal Descriptor (Audio) */ + .Audio_Out_OutputTerminal = + { + 0x0C, /* 0 bLength */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL, /* 2 bDescriptorSubType: OUTPUT_TERMINAL */ + ID_OT_AUD, /* 3 bTerminalID */ + SPEAKER, /* 4 wTerminalType */ + 0x00, /* 6 bAssocTerminal */ + FU_USBOUT, /* 7 bSourceID Connect to analog input feature unit*/ + ID_CLKSEL, /* 8 bCSourceUD */ + 0x0000, /* 9 bmControls */ + 0, /* 11 iTerminal */ + }, #endif - #ifdef INPUT - /* INPUT FROM DEVICE TO HOST PATH */ /* Input Terminal Descriptor (Analogue Input Terminal) */ - 0x11, /* 0 bLength in bytes: 17 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - INPUT_TERMINAL, /* 2 bDescriptorSubType: INPUT_TERMINAL */ - ID_IT_AUD, /* 3 bTerminalID */ - (MICROPHONE_&0xff),MICROPHONE_>>8, /* 4 wTerminalType: USB Streaming */ - 0x00, /* 6 bAssocTerminal */ - ID_CLKSEL, /* 7 bCSourceID: ID of Clock Entity */ - NUM_USB_CHAN_IN, /* 8 bNrChannels */ - 0,0,0,0, /* 9 bmChannelConfig */ - INPUT_INTERFACE_STRING_INDEX, /* 13 iChannelNames */ - 0x00, 0x00, /* 14 bmControls */ - 0, /* 16 iTerminal */ + .Audio_In_InputTerminal = + { + .bLength = sizeof(USB_Descriptor_Audio_InputTerminal_t), + .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE, + .bDescriptorSubtype = UAC_CS_AC_INTERFACE_SUBTYPE_INPUT_TERMINAL, + .bTerminalID = ID_IT_AUD, + .wTerminalType = UAC_TT_INPUT_TERMTYPE_MICROPHONE, + .bAssocTerminal = 0x00, + .bCSourceID = ID_CLKSEL, + .bNrChannels = NUM_USB_CHAN_IN, + .bmChannelConfig = 0x00000000, + .iChannelNames = INPUT_INTERFACE_STRING_INDEX, + .bmControls = 0x0000, + .iTerminal = 0, + }, + .Audio_In_FeatureUnit = + { + .bLength = sizeof(USB_Descriptor_Audio_FeatureUnit_In_t), /* 0 bLength: 6+(ch + 1)*4 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: CS_INTERFACE */ + UAC_CS_AC_INTERFACE_SUBTYPE_FEATURE_UNIT, /* 2 bDescriptorSubType: FEATURE_UNIT */ + FU_USBIN, /* 3 bUnitID */ #ifdef AUDIO_PATH_XUS - /* Extension Unit Descriptor (4.7.2.12) */ - LEN_XU_IN, /* 0 bLength (15 + p, when p is number of sources) */ - CS_INTERFACE, /* 1 bDescriptorType */ - EXTENSION_UNIT, /* 2 bDescriptorSubtype */ - ID_XU_IN, /* 3 bUnitID */ - 0, /* 4 wExtensionCode */ - 0, /* 5 wExtensionCode */ - 1, /* 6 bNrPins */ - ID_IT_AUD, /* 7 baSourceId(1) */ - NUM_USB_CHAN_OUT, /* 8+p bNrChannels */ - 0, /* 9+p bmChannelConfig */ - 0, /* 10+p bmChannelConfig */ - 0, /* 11+p bmChannelConfig */ - 0, /* 12+p bmChannelConfig */ - 0, /* 13+p iChannelNames */ - 3, /* 14+p bmControls */ - 0, /* 15+p iExtension */ -#endif - - /* Feature Unit Descriptor */ - LEN_FU_IN, /* 0 bLength: 6+(ch+1)*4 */ - CS_INTERFACE, /* 1 bDescriptorType: CS_INTERFACE */ - FEATURE_UNIT, /* 2 bDescriptorSubType: FEATURE_UNIT */ - FU_USBIN, /* 3 bUnitID */ -#ifdef AUDIO_PATH_XUS - ID_XU_IN, /* 4 bSourceID */ + ID_XU_IN, /* 4 bSourceID */ #else - ID_IT_AUD, /* 4 bSourceID */ + ID_IT_AUD, /* 4 bSourceID */ #endif + { #if (NUM_USB_CHAN_IN > 0) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(0) : Mute and Volume host read and writable */ - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(1) */ + 0x0000000F, /* bmaControls(0) : Mute and Volume host read and writable */ + 0x0000000F, /* bmaControls(1) */ #endif #if (NUM_USB_CHAN_IN > 1) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(2) */ + 0x0000000F, /* bmaControls(2) */ #endif #if (NUM_USB_CHAN_IN > 2) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(3) */ + 0x0000000F, /* bmaControls(3) */ #endif #if (NUM_USB_CHAN_IN > 3) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(4) */ + 0x0000000F, /* bmaControls(4) */ #endif #if (NUM_USB_CHAN_IN > 4) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(5) */ + 0x0000000F, /* bmaControls(5) */ #endif #if (NUM_USB_CHAN_IN > 5) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(6) */ + 0x0000000F, /* bmaControls(6) */ #endif #if (NUM_USB_CHAN_IN > 6) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(7) */ + 0x0000000F, /* bmaControls(7) */ #endif #if (NUM_USB_CHAN_IN > 7) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(8) */ + 0x0000000F, /* bmaControls(8) */ #endif #if (NUM_USB_CHAN_IN > 8) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(9) */ + 0x0000000F, /* bmaControls(9) */ #endif #if (NUM_USB_CHAN_IN > 9) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(10) */ + 0x0000000F, /* bmaControls(10) */ #endif #if (NUM_USB_CHAN_IN > 10) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(11) */ + 0x0000000F, /* bmaControls(11) */ #endif #if (NUM_USB_CHAN_IN > 11) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(12) */ + 0x0000000F, /* bmaControls(12) */ #endif #if (NUM_USB_CHAN_IN > 12) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(13) */ + 0x0000000F, /* bmaControls(13) */ #endif #if (NUM_USB_CHAN_IN > 13) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(14) */ + 0x0000000F, /* bmaControls(14) */ #endif #if (NUM_USB_CHAN_IN > 14) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(15) */ + 0x0000000F, /* bmaControls(15) */ #endif #if (NUM_USB_CHAN_IN > 15) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(16) */ + 0x0000000F, /* bmaControls(16) */ #endif #if (NUM_USB_CHAN_IN > 16) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(17) */ + 0x0000000F, /* bmaControls(17) */ #endif #if (NUM_USB_CHAN_IN > 17) - 0x0F, 0x00, 0x00, 0x00, /* bmaControls(18) */ + 0x0000000F, /* bmaControls(18) */ #endif #if (NUM_USB_CHAN_IN > 18) -#error NUM_USB_CHAN > 18 +#error NUM_USB_CHAN_IN > 18 #endif - 0, /* 60 iFeature */ - - /* Output Terminal Descriptor (USB Streaming) */ - 0x0C, /* 0 bLength */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - OUTPUT_TERMINAL, /* 2 bDescriptorSubType: OUTPUT_TERMINAL */ - ID_OT_USB, /* 3 bTerminalID */ - (USB_TERMTYPE_USB_STREAMING&0xff), - (USB_TERMTYPE_USB_STREAMING>>8),/* 5 wTerminalType */ - 0x00, /* 6 bAssocTerminal */ - FU_USBIN, /* 7 bSourceID Connect to analog input feature unit*/ - ID_CLKSEL, /* 8 bCSourceUD */ - 0x00, 0x00, /* 9 bmControls */ - 7, /* 11 iTerminal */ -#endif - - - -#if defined (MIXER) && (MAX_MIX_COUNT > 0) - /* Extension Unit Descriptor (4.7.2.12) */ - LEN_XU_MIX, /* 0 bLength (15 + p, when p is number of sources) */ - CS_INTERFACE, /* 1 bDescriptorType */ - EXTENSION_UNIT, /* 2 bDescriptorSubtype */ - ID_XU_MIXSEL, /* 3 bUnitID */ - 0, /* 4 wExtensionCode */ - 0, /* 5 wExtensionCode */ - 2, /* 6 bNrPins */ - ID_IT_USB, /* 7 baSourceId(1) */ - ID_IT_AUD, /* 7 baSourceId(2) */ - MIX_INPUTS, /* 8+p bNrChannels */ - 0, /* 9+p bmChannelConfig */ - 0, /* 10+p bmChannelConfig */ - 0, /* 11+p bmChannelConfig */ - 0, /* 12+p bmChannelConfig */ - 0, /* 13+p iChannelNames */ - 3, /* 14+p bmControls */ - 0, /* 15+p iExtension */ - - - - -/* Mixer Unit Descriptors */ - - -/* N = 144 (18 * 8) */ -/* Mixer Unit Bitmap - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff */ - MIXER_LENGTH, /* 0 bLength : 13 + num inputs + bit map (inputs * outputs) */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - 0x04, /* bDescriptorSubtype: MIXER_UNIT */ - ID_MIXER_1, /* Mixer unit id */ - 0x01, /* Number of input pins */ - ID_XU_MIXSEL, /* Connected terminal or unit id for input pin */ - MAX_MIX_COUNT, /* Number of mixer output channels */ - 0x00, 0x00, 0x00, 0x00, /* Spacial location ???? */ - MIXER_STRING_INDEX, /* Channel name index */ -#if MIX_BMCONTROLS_LEN > 0 /* Mixer programmable control bitmap */ - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 1 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 2 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 3 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 4 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 5 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 6 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 7 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 8 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 9 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 10 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 11 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 12 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 13 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 14 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 15 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 16 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 17 - 0xff, -#endif -#if MIX_BMCONTROLS_LEN > 18 -#error unxpected BMCONTROLS_LEN -#endif - 0x00, /* bmControls */ - 0, /* Mixer unit string descriptor index */ -#endif - -#if defined(SPDIF_RX) || defined (ADAT_RX) - /* Standard AS Interrupt Endpoint Descriptor (4.8.2.1): */ - 0x07, /* 0 bLength: 7 */ - 0x05, /* 1 bDescriptorType: ENDPOINT */ - EP_ADR_IN_AUD_INT, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 3, /* 3 bmAttributes (bitmap) */ - 6,0, /* 4 wMaxPacketSize */ - 8, /* 6 bInterval */ + }, + 0, /* 60 iFeature */ + }, + + .Audio_In_OutputTerminal = + { + /* Output Terminal Descriptor (USB Streaming) */ + 0x0C, /* 0 bLength */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AC_INTERFACE_SUBTYPE_OUTPUT_TERMINAL, /* 2 bDescriptorSubType: OUTPUT_TERMINAL */ + ID_OT_USB, /* 3 bTerminalID */ + USB_TERMTYPE_USB_STREAMING, /* 5 wTerminalType */ + 0x00, /* 6 bAssocTerminal */ + FU_USBIN, /* 7 bSourceID Connect to analog input feature unit*/ + ID_CLKSEL, /* 8 bCSourceUD */ + 0x0000, /* 9 bmControls */ + 7, /* 11 iTerminal */ + }, #endif + }, /* End of .Audio_CS_Control_Int */ #ifdef OUTPUT /* Zero bandwith alternative 0 */ /* Standard AS Interface Descriptor (4.9.1) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - 1, /* 2 bInterfaceNumber: Number of interface */ - 0, /* 3 bAlternateSetting */ - 0, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 4, /* 8 iInterface: (Sting index) */ + .Audio_Out_StreamInterface_Alt0 = + { + 0x09, /* 0 bLength: (in bytes, 9) */ + USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ + 1, /* 2 bInterfaceNumber: Number of interface */ + 0, /* 3 bAlternateSetting */ + 0, /* 4 bNumEndpoints */ + USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ + UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ + UAC_INT_PROTOCOL_IP_VERSION_02_00,/* 7 bInterfaceProtocol: IP_VERSION_02_00 */ + 4, /* 8 iInterface: (Sting index) */ + }, /* Alternative 1 */ /* Standard AS Interface Descriptor (4.9.1) (Alt) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - 1, /* 2 bInterfaceNumber: Number of interface */ - 1, /* 3 bAlternateSetting */ - 2, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 4, /* 8 iInterface: (Sting index) */ - + .Audio_Out_StreamInterface_Alt1 = + { + 0x09, /* 0 bLength: (in bytes, 9) */ + USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ + 1, /* 2 bInterfaceNumber: Number of interface */ + 1, /* 3 bAlternateSetting */ + 2, /* 4 bNumEndpoints */ + USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ + UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ + UAC_INT_PROTOCOL_IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ + 4, /* 8 iInterface: (Sting index) */ + }, /* STREAMING_OUTPUT_ALT1_OFFSET: */ /* Class Specific AS Interface Descriptor */ - 0x10, /* 0 bLength: 16 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - AS_GENERAL, /* 2 bDescriptorSubType */ - ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_OUT, /* 11 bNrChannels */ - 0,0,0,0, /* 12:14: bmChannelConfig */ - OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + .Audio_Out_ClassStreamInterface = + { + 0x10, /* 0 bLength: 16 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, /* 2 bDescriptorSubType */ + ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ + 0x00, /* 4 bmControls */ + UAC_FORMAT_TYPE_I, /* 5 bFormatType */ + STREAM_FORMAT_OUTPUT_1_DATAFORMAT,/* 6:10 bmFormats (note this is a bitmap) */ + NUM_USB_CHAN_OUT, /* 11 bNrChannels */ + 0x00000000, /* 12:14: bmChannelConfig */ + OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + }, /* Type 1 Format Type Descriptor */ - 0x06, /* 0 bLength (in bytes): 6 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */ - SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */ - + .Audio_Out_Format = + { + 0x06, /* 0 bLength (in bytes): 6 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ + UAC_FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ + .bSubslotSize = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, + .bBitResolution = HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS, + }, + /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 0x05, /* 3 bmAttributes (bitmap) */ - MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */ - (MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */ - 1, /* 6 bInterval */ + .Audio_Out_Endpoint = + { + .bLength = sizeof(USB_Descriptor_Endpoint_t), + .bDescriptorType = USB_DESCTYPE_ENDPOINT, + .bEndpointAddress = 0x01, /* (D7: 0:out, 1:in) */ + .bmAttributes = 0x05, /* (bitmap) */ + .wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE, + .bInterval = 1, + }, /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ - 0x08, /* 0 bLength */ - CS_ENDPOINT, /* 1 bDescriptorType */ - 0x01, /* 2 bDescriptorSubtype */ - 0x00, /* 3 bmAttributes */ - 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ - 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ - 8,0, /* 6:7 bLockDelay */ + .Audio_Out_ClassEndpoint = + { + 0x08, /* 0 bLength */ + UAC_CS_DESCTYPE_ENDPOINT, /* 1 bDescriptorType */ + 0x01, /* 2 bDescriptorSubtype */ + 0x00, /* 3 bmAttributes */ + 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ + 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ + 0x0008, /* 6:7 bLockDelay */ + }, - /* Feedback EP */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 17, /* 3 bmAttributes (bitmap) */ - 4,0, /* 4 wMaxPacketSize */ - 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ - -#ifdef NATIVE_DSD + .Audio_Out_Fb_Endpoint = + { + 0x07, /* 0 bLength: 7 */ + USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ + 17, /* 3 bmAttributes (bitmap) */ + 0x0004, /* 4 wMaxPacketSize */ + 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ + }, +#if (OUTPUT_FORMAT_COUNT > 1) /* Standard AS Interface Descriptor (4.9.1) (Alt) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - 1, /* 2 bInterfaceNumber: Number of interface */ - ALT_SETTING_DSD, /* 3 bAlternateSetting */ - 2, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 4, /* 8 iInterface: (Sting index) */ + .Audio_Out_StreamInterface_Alt2 = + { + 0x09, /* 0 bLength: (in bytes, 9) */ + USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ + 1, /* 2 bInterfaceNumber: Number of interface */ + 2, /* 3 bAlternateSetting */ + 2, /* 4 bNumEndpoints */ + USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ + UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ + UAC_INT_PROTOCOL_IP_VERSION_02_00,/* 7 bInterfaceProtocol: IP_VERSION_02_00 */ + 4, /* 8 iInterface: (Sting index) */ + }, /* Class Specific AS Interface Descriptor */ - 0x10, /* 0 bLength: 16 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - AS_GENERAL, /* 2 bDescriptorSubType */ - ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - 0x00, 0x00, 0x00, TYPE_1_RAW_DATA, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_OUT, /* 11 bNrChannels */ - 0,0,0,0, /* 12:14: bmChannelConfig */ - OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + .Audio_Out_ClassStreamInterface_2 = + { + 0x10, /* 0 bLength: 16 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, /* 2 bDescriptorSubType */ + ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ + 0x00, /* 4 bmControls */ + UAC_FORMAT_TYPE_I, /* 5 bFormatType */ + STREAM_FORMAT_OUTPUT_2_DATAFORMAT,/* 6:10 bmFormats (note this is a bitmap) */ + NUM_USB_CHAN_OUT, /* 11 bNrChannels */ + 0x00000000, /* 12:14: bmChannelConfig */ + OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + }, /* Type 1 Format Type Descriptor */ - 0x06, /* 0 bLength (in bytes): 6 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */ - 32, /* 5 bBitResolution (Number of bits used per subslot) */ - + .Audio_Out_Format_2 = + { + 0x06, /* 0 bLength (in bytes): 6 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE,/* 2 bDescriptorSubtype: FORMAT_TYPE */ + UAC_FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ + .bSubslotSize = HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES, + .bBitResolution = HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS, + }, /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 0x05, /* 3 bmAttributes (bitmap) */ - MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */ - (MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */ - 1, /* 6 bInterval */ + .Audio_Out_Endpoint_2 = + { + .bLength = sizeof(USB_Descriptor_Endpoint_t), + .bDescriptorType = USB_DESCTYPE_ENDPOINT, + .bEndpointAddress = 0x01, + .bmAttributes = 0x05, + .wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE, + .bInterval = 1, + }, /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ - 0x08, /* 0 bLength */ - CS_ENDPOINT, /* 1 bDescriptorType */ - 0x01, /* 2 bDescriptorSubtype */ - 0x00, /* 3 bmAttributes */ - 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ - 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ - 8,0, /* 6:7 bLockDelay */ + .Audio_Out_ClassEndpoint_2 = + { + 0x08, /* 0 bLength */ + UAC_CS_DESCTYPE_ENDPOINT, /* 1 bDescriptorType */ + 0x01, /* 2 bDescriptorSubtype */ + 0x00, /* 3 bmAttributes */ + 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ + 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ + 0x0008, /* 6:7 bLockDelay */ + }, - /* Feedback EP */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 17, /* 3 bmAttributes (bitmap) */ - 4,0, /* 4 wMaxPacketSize */ - 4, /* 6 bInterval */ - -#endif /* NATIVE_DSD */ - -#ifdef ADAT_TX + .Audio_Out_Fb_Endpoint_2 = + { + 0x07, /* 0 bLength: 7 */ + USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ + 17, /* 3 bmAttributes (bitmap) */ + 0x0004, /* 4 wMaxPacketSize */ + 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ + }, +#endif +#if (OUTPUT_FORMAT_COUNT > 2) /* Standard AS Interface Descriptor (4.9.1) (Alt) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - 1, /* 2 bInterfaceNumber: Number of interface */ - ALT_SETTING_ADAT_TX, /* 3 bAlternateSetting */ - 2, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 4, /* 8 iInterface: (Sting index) */ + .Audio_Out_StreamInterface_Alt3 = + { + 0x09, /* 0 bLength: (in bytes, 9) */ + USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ + 1, /* 2 bInterfaceNumber: Number of interface */ + 3, /* 3 bAlternateSetting */ + 2, /* 4 bNumEndpoints */ + USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ + UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ + UAC_INT_PROTOCOL_IP_VERSION_02_00,/* 7 bInterfaceProtocol: IP_VERSION_02_00 */ + 4, /* 8 iInterface: (Sting index) */ + }, /* Class Specific AS Interface Descriptor */ - 0x10, /* 0 bLength: 16 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - AS_GENERAL, /* 2 bDescriptorSubType */ - ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_OUT, /* 11 bNrChannels */ - 0,0,0,0, /* 12:14: bmChannelConfig */ - INPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + .Audio_Out_ClassStreamInterface_3 = + { + 0x10, /* 0 bLength: 16 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, /* 2 bDescriptorSubType */ + ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ + 0x00, /* 4 bmControls */ + UAC_FORMAT_TYPE_I, /* 5 bFormatType */ + STREAM_FORMAT_OUTPUT_3_DATAFORMAT,/* 6:10 bmFormats (note this is a bitmap) */ + NUM_USB_CHAN_OUT, /* 11 bNrChannels */ + 0x00000000, /* 12:14: bmChannelConfig */ + OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + }, /* Type 1 Format Type Descriptor */ - 0x06, /* 0 bLength (in bytes): 6 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */ - SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */ - + .Audio_Out_Format_3 = + { + 0x06, /* 0 bLength (in bytes): 6 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ + UAC_FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ + .bSubslotSize = HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES, + .bBitResolution = HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS, + }, + /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 0x05, /* 3 bmAttributes (bitmap) */ - MAX_PACKET_SIZE_OUT_HS&0xff, /* 4 wMaxPacketSize */ - (MAX_PACKET_SIZE_OUT_HS&0xff00)>>8, /* 5 wMaxPacketSize */ - 1, /* 6 bInterval */ + .Audio_Out_Endpoint_3 = + { + 0x07, /* 0 bLength: 7 */ + USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ + 0x05, /* 3 bmAttributes (bitmap) */ + .wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE, + 1, /* 6 bInterval */ + }, /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ - 0x08, /* 0 bLength */ - CS_ENDPOINT, /* 1 bDescriptorType */ - 0x01, /* 2 bDescriptorSubtype */ - 0x00, /* 3 bmAttributes */ - 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ - 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ - 8,0, /* 6:7 bLockDelay */ + .Audio_Out_ClassEndpoint_3 = + { + 0x08, /* 0 bLength */ + UAC_CS_DESCTYPE_ENDPOINT, /* 1 bDescriptorType */ + 0x01, /* 2 bDescriptorSubtype */ + 0x00, /* 3 bmAttributes */ + 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ + 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ + 0x0008, /* 6:7 bLockDelay */ + }, - /* Feedback EP */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 17, /* 3 bmAttributes (bitmap) */ - 4,0, /* 4 wMaxPacketSize */ - 4, /* 6 bInterval */ - -#endif /* ADAT_TX */ + .Audio_Out_Fb_Endpoint_3 = + { + 0x07, /* 0 bLength: 7 */ + USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ + 17, /* 3 bmAttributes (bitmap) */ + 0x0004, /* 4 wMaxPacketSize */ + 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */ + }, +#endif /* OUTPUT_FORMAT_COUNT > 2 */ #endif /* OUTPUT */ - #ifdef INPUT + + /* Zero bandwith alternative 0 */ /* Standard AS Interface Descriptor (4.9.1) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ - 0, /* 3 bAlternateSetting */ - 0, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - 0x20, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 5, /* 8 iInterface: (Sting index) */ + .Audio_In_StreamInterface_Alt0 = + { + 0x09, /* 0 bLength: (in bytes, 9) */ + USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ + (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ + 0, /* 3 bAlternateSetting */ + 0, /* 4 bNumEndpoints */ + USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ + UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ + 0x20, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ + 5, /* 8 iInterface: (Sting index) */ + }, + /* Alternative 1 */ /* Standard AS Interface Descriptor (4.9.1) (Alt) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ - 1, /* 3 bAlternateSetting */ - 1, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 5, /* 8 iInterface: (Sting index) */ + .Audio_In_StreamInterface_Alt1 = + { + 0x09, /* 0 bLength: (in bytes, 9) */ + USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */ + (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ + 1, /* 3 bAlternateSetting */ + 1, /* 4 bNumEndpoints */ + USB_CLASS_AUDIO, /* 5 bInterfaceClass: AUDIO */ + UAC_INT_SUBCLASS_AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ + UAC_INT_PROTOCOL_IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ + 5, /* 8 iInterface: (Sting index) */ + }, /* Class Specific AS Interface Descriptor */ - 0x10, /* 0 bLength: 16 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - AS_GENERAL, /* 2 bDescriptorSubType */ - ID_OT_USB, /* 3 bTerminalLink */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_IN, /* 11 bNrChannels */ - 0,0,0,0, /* 12:14: bmChannelConfig */ - INPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + .Audio_In_ClassStreamInterface = + { + 0x10, /* 0 bLength: 16 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL, /* 2 bDescriptorSubType */ + ID_OT_USB, /* 3 bTerminalLink */ + 0x00, /* 4 bmControls */ + 0x01, /* 5 bFormatType */ + UAC_FORMAT_TYPEI_PCM,/* 6:10 bmFormats (note this is a bitmap) */ + NUM_USB_CHAN_IN, /* 11 bNrChannels */ + 0x00000000, /* 12:14: bmChannelConfig */ + INPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ + }, /* Type 1 Format Type Descriptor */ - 0x06, /* 0 bLength (in bytes): 6 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */ - SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */ - + .Audio_In_Format = + { + 0x06, /* 0 bLength (in bytes): 6 */ + UAC_CS_DESCTYPE_INTERFACE, /* 1 bDescriptorType: 0x24 */ + UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE,/* 2 bDescriptorSubtype: FORMAT_TYPE */ + UAC_FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ + .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* 4 bSubslotSize (Number of bytes per subslot) */ + .bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, + }, + /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 5, /* 3 bmAttributes (bitmap) */ - MAX_PACKET_SIZE_IN_HS&0xff, /* 4 wMaxPacketSize */ - (MAX_PACKET_SIZE_IN_HS&0xff00)>>8, /* 5 wMaxPacketSize */ - 1, /* 6 bInterval */ + .Audio_In_Endpoint = + { + 0x07, /* 0 bLength: 7 */ + USB_DESCTYPE_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ + 5, /* 3 bmAttributes (bitmap) */ + .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE, + .bInterval = 0x01, + }, /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ - 0x08, /* 0 bLength */ - CS_ENDPOINT, /* 1 bDescriptorType */ - 0x01, /* 2 bDescriptorSubtype */ - 0x00, /* 3 bmAttributes */ - 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ - 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ - 8,0, /* 6:7 bLockDelay */ - -#ifdef ADAT_RX - /* Standard AS Interface Descriptor (4.9.1) (Alt) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ - (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ - 2, /* 3 bAlternateSetting */ - 1, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 5, /* 8 iInterface: (Sting index) */ - - /* Class Specific AS Interface Descriptor */ - 0x10, /* 0 bLength: 16 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - AS_GENERAL, /* 2 bDescriptorSubType */ - ID_OT_USB, /* 3 bTerminalLink */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_IN - 4, /* 11 bNrChannels */ - 0,0,0,0, /* 12:14: bmChannelConfig */ - INPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ - - /* Type 1 Format Type Descriptor */ - 0x06, /* 0 bLength (in bytes): 6 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - SAMPLE_SUBSLOT_SIZE_HS, /* 4 bSubslotSize (Number of bytes per subslot) */ - SAMPLE_BIT_RESOLUTION_HS, /* 5 bBitResolution (Number of bits used per subslot) */ - - /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ - 0x07, /* 0 bLength: 7 */ - USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 5, /* 3 bmAttributes (bitmap) */ - MAX_PACKET_SIZE_IN_HS&0xff, /* 4 wMaxPacketSize */ - (MAX_PACKET_SIZE_IN_HS&0xff00)>>8, /* 5 wMaxPacketSize */ - 1, /* 6 bInterval */ - - /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ - 0x08, /* 0 bLength */ - CS_ENDPOINT, /* 1 bDescriptorType */ - 0x01, /* 2 bDescriptorSubtype */ - 0x00, /* 3 bmAttributes */ - 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ - 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ - 8,0, /* 6:7 bLockDelay */ - -#if 0 - /* Standard AS Interface Descriptor (4.9.1) (Alt) */ - 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ - (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ - 3, /* 3 bAlternateSetting */ - 1, /* 4 bNumEndpoints */ - AUDIO, /* 5 bInterfaceClass: AUDIO */ - AUDIOSTREAMING, /* 6 bInterfaceSubClass: AUDIO_STREAMING */ - IP_VERSION_02_00, /* 7 bInterfaceProtocol: IP_VERSION_02_00 */ - 11, /* 8 iInterface: (Sting index) */ - - /* Class Specific AS Interface Descriptor */ - 0x10, /* 0 bLength: 16 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - AS_GENERAL, /* 2 bDescriptorSubType */ - ID_OT_USB, /* 3 bTerminalLink */ - 0x00, /* 4 bmControls */ - 0x01, /* 5 bFormatType */ - PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ - NUM_USB_CHAN_IN-6, /* 11 bNrChannels */ - 0,0,0,0, /* 12:14: bmChannelConfig */ - 29, /* 15 iChannelNames */ - - /* Type 1 Format Type Descriptor */ - 0x06, /* 0 bLength (in bytes): 6 */ - CS_INTERFACE, /* 1 bDescriptorType: 0x24 */ - FORMAT_TYPE, /* 2 bDescriptorSubtype: FORMAT_TYPE */ - FORMAT_TYPE_I, /* 3 bFormatType: FORMAT_TYPE_1 */ - 0x04, /* 4 bSubslotSize (Number of bytes per subslot) */ - 24, /* 5 bBitResolution (Number of bits used per subslot) */ - - /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ - 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ - 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ - 5, /* 3 bmAttributes (bitmap) */ - 0,4, /* 4 wMaxPacketSize */ - 1, /* 6 bInterval */ - - /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */ - 0x08, /* 0 bLength */ - CS_ENDPOINT, /* 1 bDescriptorType */ - 0x01, /* 2 bDescriptorSubtype */ - 0x00, /* 3 bmAttributes */ - 0x00, /* 4 bmControls (Bitmap: Pitch control, over/underun etc) */ - 0x02, /* 5 bLockDelayUnits: Decoded PCM samples */ - 8,0, /* 6:7 bLockDelay */ + .Audio_In_ClassEndpoint = + { + .bLength = sizeof(USB_Descriptor_Audio_Class_AS_Endpoint_t), + .bDescriptorType = UAC_CS_DESCTYPE_ENDPOINT, + .bDescriptorSubtype = UAC_CS_ENDPOINT_SUBTYPE_EP_GENERAL, + .bmAttributes = 0x00, + .bmControls = 0x00, + .bLockDelayUnits = 0x02, + .wLockDelay = 0x0008, + }, #endif -#endif - - -#endif - #ifdef MIDI /* MIDI Descriptors */ /* Table B-3: MIDI Adapter Standard AC Interface Descriptor */ @@ -1320,52 +1231,63 @@ unsigned char cfgDesc_Audio2[] = 0x00, /* 6 wTransferSize */ 0x10, /* 7 bcdDFUVersion */ 0x01, /* 7 bcdDFUVersion */ - #endif #endif #ifdef IAP /* Interface descriptor */ - 0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ - 0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */ - (INPUT_INTERFACES+OUTPUT_INTERFACES+MIDI_INTERFACES+DFU_INTERFACES+1), /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */ - 0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */ - 0x03, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */ - 0xFF, /* 5 bInterfaceClass : DFU. (field size 1 bytes) */ - 0xF0, /* 6 bInterfaceSubclass : (field size 1 bytes) */ - 0x00, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */ - IAP_INTERFACE_STRING_INDEX, /* 8 iInterface : Used. (field size 1 bytes) */ + .iAP_Interface = + { + .bLength = sizeof(USB_Descriptor_Interface_t), + .bDescriptorType = USB_DESCTYPE_INTERFACE, + .bInterfaceNumber = (INPUT_INTERFACES+OUTPUT_INTERFACES+MIDI_INTERFACES+DFU_INTERFACES+1), + .bAlternateSetting = 0x00, +#ifdef IAP_INT_EP + .bNumEndpoints = 0x03, +#else + .bNumEndpoints = 0x02, +#endif + .bInterfaceClass = USB_CLASS_VENDOR_SPECIFIC, + .bInterfaceSubClass = 0xF0, /* MFI Accessory (Table 38-1) */ + .bInterfaceProtocol = 0x00, + .iInterface = IAP_INTERFACE_STRING_INDEX, /* Note, string is important! */ + }, /* iAP Bulk OUT Endpoint Descriptor */ - 0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ - 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ - EP_ADR_OUT_IAP, /* 2 bEndpointAddress : OUT Endpoint 3. High bit isIn (field size 1 bytes) */ - 0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */ - 0x00, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/ - 0x02, /* 5 wMaxPacketSize */ - 0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */ + .iAP_Out_Endpoint = + { + 0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ + 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ + EP_ADR_OUT_IAP, /* 2 bEndpointAddress : OUT Endpoint 3. High bit isIn (field size 1 bytes) */ + 0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */ + 0x0200, /* 4 wMaxPacketSize : Has to be 0x200 for compliance*/ + 0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */ + }, /* iAP Bulk IN Endpoint Descriptor */ - 0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ - 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ - EP_ADR_IN_IAP, /* 2 bEndpointAddress : IN Endpoint 5. (field size 1 bytes) */ - 0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */ - 0x00, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x200 for compliance*/ - 0x02, /* 5 wMaxPacketSize */ - 0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */ + .iAP_In_Endpoint = + { + 0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ + 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ + EP_ADR_IN_IAP, /* 2 bEndpointAddress : IN Endpoint 5. (field size 1 bytes) */ + 0x02, /* 3 bmAttributes : Bulk, not shared. (field size 1 bytes) */ + 0x0200, /* 4 wMaxPacketSize : Has to be 0x200 for compliance*/ + 0x00, /* 6 bInterval : Ignored for Bulk. Set to zero. (field size 1 bytes) */ + }, #ifdef IAP_INT_EP - /* iAP Interrupt IN Endpoint Descriptor */ - 0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ - 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ - EP_ADR_IN_IAP_INT, /* 2 bEndpointAddress : IN Endpoint 6. (field size 1 bytes) */ - 0x03, /* 3 bmAttributes : Interrupt, not shared. (field size 1 bytes) */ - 0x40, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x40 for compliance*/ - 0x00, /* 5 wMaxPacketSize */ - 0x08, /* 6 bInterval : (2^(bInterval-1))/8 ms. Must be between 4 and 32ms (field size 1 bytes) */ -#endif - + /* iAP Interrupt IN Endpoint Descriptor. Note, its usage is now deprecated */ + .iAP_Interrupt_Endpoint = + { + 0x07, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ + 0x05, /* 1 bDescriptorType : ENDPOINT descriptor. (field size 1 bytes) */ + EP_ADR_IN_IAP_INT, /* 2 bEndpointAddress : IN Endpoint 6. (field size 1 bytes) */ + 0x03, /* 3 bmAttributes : Interrupt, not shared. (field size 1 bytes) */ + 0x0040, /* 4 wMaxPacketSize : 64 bytes per packet. (field size 2 bytes) - has to be 0x40 for compliance*/ + 0x08, /* 6 bInterval : (2^(bInterval-1))/8 ms. Must be between 4 and 32ms (field size 1 bytes) */ + } #endif +#endif /* IAP */ #ifdef HID_CONTROLS /* HID */ @@ -1380,8 +1302,6 @@ unsigned char cfgDesc_Audio2[] = 0, /* 7: bInterfaceProtocol*/ 0, /* 8 iInterface */ - - /* The device implements HID Descriptor: */ 9, /* 0 bLength : Size of descriptor in Bytes */ 0x21, /* 1 bDescriptorType (HID) */ @@ -1399,12 +1319,13 @@ unsigned char cfgDesc_Audio2[] = EP_ADR_IN_HID, /* 2 bEndpointAddress */ 3, /* 3 bmAttributes (INTERRUPT) */ 64, /* 4 wMaxPacketSize */ - 0, /* 5 wMaxPacketSize */ 8, /* 6 bInterval */ #endif + }; +#endif #define APPEND_VENDOR_STR(x) VENDOR_STR" "#x @@ -1617,7 +1538,7 @@ static unsigned char strDescs[][40] = unsigned char cfgDesc_Null[] = { 0x09, /* 0 bLength */ - USB_CONFIGURATION, /* 1 bDescriptorType */ + USB_DESCTYPE_CONFIGURATION, /* 1 bDescriptorType */ 0x12, /* 2 wTotalLength */ 0x00, /* 3 wTotalLength */ 0x01, /* 4 bNumInterface: Number of interfaces*/ @@ -1681,7 +1602,7 @@ unsigned char cfgDesc_Audio1[] = { /* Configuration descriptor */ 0x09, - USB_CONFIGURATION, + USB_DESCTYPE_CONFIGURATION, (CFG_TOTAL_LENGTH_A1 & 0xFF), /* wTotalLength */ (CFG_TOTAL_LENGTH_A1 >> 8), /* wTotalLength */ NUM_INTERFACES_A1, /* numInterfaces - we dont support MIDI in audio 1.0 mode*/ @@ -1696,18 +1617,18 @@ unsigned char cfgDesc_Audio1[] = /* Standard AC interface descriptor */ 0x09, - USB_INTERFACE, + USB_DESCTYPE_INTERFACE, 0x00, /* Interface No */ 0x00, /* Alternate setting*/ 0x00, /* Num endpoints */ - AUDIO, - AUDIOCONTROL, + USB_CLASS_AUDIO, + UAC_INT_SUBCLASS_AUDIOCONTROL, 0x00, /* Unused */ 8, /* iInterface - re-use iProduct */ /* CS (Class Specific) AudioControl interface header descriptor (4.3.2) */ AC_LENGTH, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x01, /* HEADER */ 0x00, 0x01, /* Class spec revision - 1.0 */ (AC_TOTAL_LENGTH & 0xFF), /* wTotallength (Combined length of this descriptor and all Unit and Terminal Descriptors) */ @@ -1723,7 +1644,7 @@ unsigned char cfgDesc_Audio1[] = #ifdef OUTPUT /* CS_Interface Input Terminal 1 Descriptor - USB streaming Host to Device */ 0x0C, - CS_INTERFACE, /* CS_INTERFACE */ + UAC_CS_DESCTYPE_INTERFACE, /* UAC_CS_DESCTYPE_INTERFACE */ 0x02, /* INPUT_TERMINAL */ 0x01, /* Terminal ID */ 0x01, 0x01, /* Type - streaming */ @@ -1735,8 +1656,8 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface class specific AC interface feature unit descriptor - mute & volume for dac */ 0x0A, - CS_INTERFACE, - FEATURE_UNIT, + UAC_CS_DESCTYPE_INTERFACE, + UAC_CS_AC_INTERFACE_SUBTYPE_FEATURE_UNIT, /* 2 bDescriptorSubType: FEATURE_UNIT */ 0x0A, /* unitID */ 0x01, /* sourceID - ID of the unit/terminal to which this feature unit is connected */ 0x01, /* controlSize - 1 */ @@ -1747,7 +1668,7 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface Output Terminal Descriptor - Analogue out to speaker */ 0x09, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x03, /* OUTPUT_TERMINAL */ 0x06, /* Terminal ID */ 0x01, 0x03, /* Type - streaming out, speaker */ @@ -1760,7 +1681,7 @@ unsigned char cfgDesc_Audio1[] = #ifdef INPUT /* CS_Interface Input Terminal 2 Descriptor - Analog in from line in */ 0x0C, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x02, /* INPUT_TERMINAL */ 0x02, /* Terminal ID */ 0x01, 0x02, /* Type - streaming in, mic */ @@ -1772,7 +1693,7 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface Output Terminal Descriptor - USB Streaming Device to Host*/ 0x09, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x03, /* OUTPUT_TERMINAL */ 0x07, /* Terminal ID */ 0x01, 0x01, /* Type - streaming */ @@ -1782,8 +1703,8 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface class specific AC interface feature unit descriptor - mute & volume for adc */ 0x0A, - CS_INTERFACE, - FEATURE_UNIT, + UAC_CS_DESCTYPE_INTERFACE, + UAC_CS_AC_INTERFACE_SUBTYPE_FEATURE_UNIT, /* 2 bDescriptorSubType: FEATURE_UNIT */ 0x0B, /* unitID */ 0x02, /* sourceID - ID of the unit/terminal to which this feature unit is connected */ 0x01, /* controlSize - 1 */ @@ -1818,7 +1739,7 @@ unsigned char cfgDesc_Audio1[] = /* Class-Specific AS Interface Descriptor (4.5.2) */ 0x07, - CS_INTERFACE, /* bDescriptorType */ + UAC_CS_DESCTYPE_INTERFACE, /* bDescriptorType */ 0x01, /* bDescriptorSubtype - GENERAL */ 0x01, /* iTerminalLink - linked to Streaming IN terminal */ 0x01, /* bDelay */ @@ -1826,12 +1747,12 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface Format Type Descriptor */ 0x14, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x02, /* Subtype - FORMAT_TYPE */ 0x01, /* Format type - FORMAT_TYPE_1 */ NUM_USB_CHAN_OUT_FS, /* nrChannels */ - SAMPLE_SUBSLOT_SIZE_FS, /* subFrameSize */ - SAMPLE_BIT_RESOLUTION_FS, /* bitResolution */ + FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, /* subFrameSize */ + FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS, /* bitResolution */ 0x04, /* SamFreqType - 4 sample freq */ 0x44, 0xAC, 0x00, /* sampleFreq - 44.1Khz */ 0x80, 0xBB, 0x00, /* sampleFreq - 48KHz */ @@ -1848,8 +1769,8 @@ unsigned char cfgDesc_Audio1[] = 0x05, /* ENDPOINT */ 0x01, /* endpointAddress - D7, direction (0 OUT, 1 IN). D6..4 reserved (0). D3..0 endpoint no. */ 0x05, /* attributes - isochronous async */ - MAX_PACKET_SIZE_OUT_FS&0xff, /* 4 wMaxPacketSize (Typically 294 bytes)*/ - (MAX_PACKET_SIZE_OUT_FS&0xff00)>>8, /* 5 wMaxPacketSize */ + (FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE&0xff), /* 4 wMaxPacketSize (Typically 294 bytes)*/ + (FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE&0xff00)>>8, /* 5 wMaxPacketSize */ 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x81, /* bSynchAdddress - address of EP used to communicate sync info */ @@ -1898,7 +1819,7 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface AC interface header descriptor */ 0x07, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x01, /* subtype - GENERAL */ 0x07, /* TerminalLink - linked to Streaming OUT terminal */ 0x01, /* Interface delay */ @@ -1906,12 +1827,12 @@ unsigned char cfgDesc_Audio1[] = /* CS_Interface Terminal Descriptor */ 0x14, - CS_INTERFACE, + UAC_CS_DESCTYPE_INTERFACE, 0x02, /* Subtype - FORMAT_TYPE */ 0x01, /* Format type - FORMAT_TYPE_1 */ NUM_USB_CHAN_IN_FS, /* bNrChannels - Typically 2 */ - SAMPLE_SUBSLOT_SIZE_FS, /* subFrameSize - Typically 4 bytes per slot */ - SAMPLE_BIT_RESOLUTION_FS, /* bitResolution - Typically 24bit */ + FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* subFrameSize - Typically 4 bytes per slot */ + FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, /* bitResolution - Typically 24bit */ 0x04, /* SamFreqType - 4 sample freq */ 0x44, 0xAC, 0x00, /* sampleFreq - 44.1Khz */ 0x80, 0xBB, 0x00, /* sampleFreq - 48KHz */ @@ -1923,13 +1844,14 @@ unsigned char cfgDesc_Audio1[] = 0x00, 0x77, 0x01, /* sampleFreq - 96KHz */ #endif + /* Standard Endpoint Descriptor */ 0x09, 0x05, /* ENDPOINT */ 0x82, /* EndpointAddress */ 0x05, /* Attributes - isochronous async */ - MAX_PACKET_SIZE_IN_FS&0xff, /* 4 wMaxPacketSize (Typically 294 bytes)*/ - (MAX_PACKET_SIZE_IN_FS&0xff00)>>8, /* 5 wMaxPacketSize */ + FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE&0xff, /* 4 wMaxPacketSize (Typically 294 bytes)*/ + (FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE&0xff00)>>8, /* 5 wMaxPacketSize */ 0x01, /* bInterval */ 0x00, /* bRefresh */ 0x00, /* bSynchAddress */ diff --git a/module_usb_audio/endpoint0/endpoint0.xc b/module_usb_audio/endpoint0/endpoint0.c similarity index 69% rename from module_usb_audio/endpoint0/endpoint0.xc rename to module_usb_audio/endpoint0/endpoint0.c index 691dd347..aedb7af3 100755 --- a/module_usb_audio/endpoint0/endpoint0.xc +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -1,4 +1,5 @@ /** + * g * @file endpoint0.xc * @brief Implements endpoint zero for an USB Audio 1.0/2.0 device * @author Ross Owen, XMOS Semiconductor @@ -8,7 +9,7 @@ #include #include "xud.h" /* XUD user defines and functions */ -#include "usb.h" /* Defines from USB 2.0 Spec */ +#include "usb_std_requests.h" #include "usbaudio20.h" /* Defines from USB Audio 2.0 spec */ #include "devicedefines.h" @@ -20,6 +21,7 @@ #include "vendorrequests.h" #include "dfu_types.h" #include "xc_ptr.h" +#include "audiorequests.h" #ifdef HID_CONTROLS #include "hid.h" #endif @@ -27,6 +29,13 @@ #include "dsd_support.h" #endif +#ifndef __XC__ +/* Support for C */ +#define null 0 +#define outuint(c, x) asm ("out res[%0], %1" :: "r" (c), "r" (x)) +#define chkct(c, x) asm ("chkct res[%0], %1" :: "r" (c), "r" (x)) +#endif + /* Some warnings.... */ /* Windows does not have a built in DFU driver (windows will prompt), so warn that DFU will not be functional in Audio 1.0 mode */ @@ -52,13 +61,6 @@ unsigned int DFU_mode_active = 0; // 0 - App active, 1 - DFU active extern void device_reboot(chanend); #endif -/* Handles Audio Class requests */ -int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); -int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); -int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); - - - /* Global volume and mute tables */ int volsOut[NUM_USB_CHAN_OUT + 1]; unsigned int mutesOut[NUM_USB_CHAN_OUT + 1]; @@ -71,7 +73,6 @@ unsigned int mutesIn[NUM_USB_CHAN_IN + 1]; #ifdef MIXER unsigned char mixer1Crossbar[18]; short mixer1Weights[18*8]; -//#define MAX_MIX_COUNT 8 unsigned char channelMap[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT]; #if NUM_USB_CHAN_OUT > 0 @@ -99,11 +100,29 @@ XUD_BusSpeed_t g_curUsbSpeed = 0; unsigned g_dsdMode = 0; #endif -void VendorAudioRequestsInit(chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); +const unsigned g_subSlot_Out_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, + HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES, + HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES}; + +const unsigned g_subSlot_Out_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, + FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES, + FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES}; + +const unsigned g_dataFormat_Out[OUTPUT_FORMAT_COUNT] = {STREAM_FORMAT_OUTPUT_1_DATAFORMAT, + STREAM_FORMAT_OUTPUT_2_DATAFORMAT, + STREAM_FORMAT_OUTPUT_3_DATAFORMAT}; + +const unsigned g_subSlot_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES}; + +const unsigned g_subSlot_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES}; + +const unsigned g_dataFormat_In[INPUT_FORMAT_COUNT] = {STREAM_FORMAT_INPUT_1_DATAFORMAT}; /* Endpoint 0 function. Handles all requests to the device */ -void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, - chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_usb_test) +void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + NULLABLE_RESOURCE(chanend, c_mix_ctl), + NULLABLE_RESOURCE(chanend, c_clk_ctl), + NULLABLE_RESOURCE(chanend, c_usb_test)) { USB_SetupPacket_t sp; XUD_ep ep0_out = XUD_InitEp(c_ep0_out); @@ -227,7 +246,11 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, while(1) { /* Returns 0 for success, -1 for bus reset */ +#if defined(__XC__) XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, sp); +#else + XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, &sp); +#endif if (result == XUD_RES_OKAY) { @@ -244,67 +267,62 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, /* Check for audio stream from host start/stop */ if(sp.wIndex == 1) // Ouput interface { - switch(sp.wValue) + /* Check the alt is in range */ + if(sp.wValue <= OUTPUT_FORMAT_COUNT) { - case 0: - /* Stream stop */ -#if defined(NATIVE_DSD) && defined(DEFAULT_TO_PCM) - /* Default to PCM mode */ - if(g_dsdMode) - { - outuint(c_audioControl, SET_DSD_MODE); - outuint(c_audioControl, DSD_MODE_OFF); - - /* Handshake */ - chkct(c_audioControl, XS1_CT_END); - g_dsdMode = 0; - } -#endif - break; - case 1: - /* Stream active + 0 chans */ - /* NOTE there could be a difference between HS/UAC1 and FS/UAC1 channel count - * Also note, currently we assume with won't be doing ADAT in FS/UAC1... - * Note: This is is important. Decouple uses this to setup the size of the initial IN packet size - */ + /* Alt 0 is stream stop */ + if(sp.wValue > 0) + { + /* Send format of data onto buffering */ + outuint(c_audioControl, SET_STREAM_FORMAT_OUT); + outuint(c_audioControl, g_dataFormat_Out[sp.wValue-1]); /* Data format (PCM/DSD) */ + if(g_curUsbSpeed == XUD_SPEED_HS) { - outuint(c_audioControl, SET_CHAN_COUNT_OUT); - outuint(c_audioControl, NUM_USB_CHAN_OUT); + outuint(c_audioControl, NUM_USB_CHAN_OUT); /* Channel count */ + outuint(c_audioControl, g_subSlot_Out_HS[sp.wValue-1]); /* Subslot */ } else { - outuint(c_audioControl, SET_CHAN_COUNT_OUT); outuint(c_audioControl, NUM_USB_CHAN_OUT_FS); + outuint(c_audioControl, g_subSlot_Out_FS[sp.wValue-1]); } -#ifdef NATIVE_DSD - if(g_dsdMode) - { - outuint(c_audioControl, SET_DSD_MODE); - outuint(c_audioControl, DSD_MODE_OFF); - - // Handshake - chkct(c_audioControl, XS1_CT_END); - g_dsdMode = 0; - } -#endif /* NATIVE_DSD */ - break; -#ifdef NATIVE_DSD - case 2: - - if(!g_dsdMode) - { - outuint(c_audioControl, SET_DSD_MODE); - outuint(c_audioControl, DSD_MODE_NATIVE); - chkct(c_audioControl, XS1_CT_END); - g_dsdMode = 1; - } - break; -#endif /* NATIVE_DSD */ + + /* Handshake */ + chkct(c_audioControl, XS1_CT_END); + } } } +#warning FIXME else if(sp.wIndex == 2) // Input interface { + /* Check the alt is in range */ + if(sp.wValue <= INPUT_FORMAT_COUNT) + { + /* Alt 0 is stream stop */ + if(sp.wValue > 0) + { + /* Send format of data onto buffering */ + outuint(c_audioControl, SET_STREAM_FORMAT_IN); + outuint(c_audioControl, g_dataFormat_In[sp.wValue-1]); /* Data format (PCM/DSD) */ + + if(g_curUsbSpeed == XUD_SPEED_HS) + { + outuint(c_audioControl, NUM_USB_CHAN_IN); /* Channel count */ + outuint(c_audioControl, g_subSlot_In_HS[sp.wValue-1]); /* Subslot */ + } + else + { + outuint(c_audioControl, NUM_USB_CHAN_IN_FS); + outuint(c_audioControl, g_subSlot_In_FS[sp.wValue-1]); + } + + /* Handshake */ + chkct(c_audioControl, XS1_CT_END); + } + } + } +#if 0 switch(sp.wValue) { case 0: @@ -350,6 +368,8 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, #endif } } +#endif + #if 1 #if defined(OUTPUT) && defined(INPUT) /* Check for stream start stop on output and input audio interfaces */ @@ -381,13 +401,13 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, } #endif #endif - /* Record interface change */ - if(sp.wIndex < NUM_INTERFACES) - g_interfaceAlt[sp.wIndex] = sp.wValue; + ///* Record interface change */ + //if(sp.wIndex < NUM_INTERFACES) + // g_interfaceAlt[sp.wIndex] = sp.wValue; - /* No data stage for this request, just do data stage */ - result = XUD_DoSetRequestStatus(ep0_in); + //TODO - we should stall out of range requests + } /* if(sp.bRequest == SET_INTERFACE) */ break; /* BMREQ_H2D_STANDARD_INT */ @@ -461,10 +481,10 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, #if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) if(g_curUsbSpeed == XUD_SPEED_FS) { - result = AudioEndpointRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + result = AudioEndpointRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); } #elif (AUDIO_CLASS==1) - result = AudioEndpointRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + result = AudioEndpointRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); #endif } @@ -500,14 +520,15 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, // Handshake chkct(c_audioControl, XS1_CT_END); } - +#ifdef __XC__ /* This will return 1 if reset requested */ if (DFUDeviceRequests(ep0_out, ep0_in, sp, null, g_interfaceAlt[sp.wIndex], 1)) - { - timer tmr; - unsigned s; - tmr :> s; - tmr when timerafter(s + 50000000) :> s; +#else + /* This will return 1 if reset requested */ + if (DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], 1)) +#endif + { + DFUDelay(50000000); device_reboot(c_audioControl); } @@ -524,16 +545,16 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, #if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) if(g_curUsbSpeed == XUD_SPEED_HS) { - result = AudioClassRequests_2(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + result = AudioClassRequests_2(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); } else { - result = AudioClassRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + result = AudioClassRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); } #elif (AUDIO_CLASS==2) - result = AudioClassRequests_2(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + result = AudioClassRequests_2(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); #else - result = AudioClassRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + result = AudioClassRequests_1(ep0_out, ep0_in, &sp, c_audioControl, c_mix_ctl, c_clk_ctl); #endif #ifdef VENDOR_AUDIO_REQS @@ -566,89 +587,93 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, #ifdef AUDIO_CLASS_FALLBACK /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ result = USB_StandardRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), + (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), devDesc_Audio1, sizeof(devDesc_Audio1), cfgDesc_Audio1, sizeof(cfgDesc_Audio1), strDescs, sizeof(strDescs)/sizeof(strDescs[0]), - sp, c_usb_test, g_curUsbSpeed); + &sp, c_usb_test, g_curUsbSpeed); #elif FULL_SPEED_AUDIO_2 /* Return Audio 2.0 Descriptors for high_speed and full-speed */ /* Unfortunately we need to munge the descriptors a bit between full and high-speed */ if(g_curUsbSpeed == XUD_SPEED_HS) { + /* Modify Audio Class 2.0 Config descriptor for High-speed operation */ #if (NUM_USB_CHAN_OUT > 0) - /* Output interface - Interface 1 */ - /* Mod bSlotSize */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+20] = SAMPLE_SUBSLOT_SIZE_HS; + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_Out_InputTerminal.bNrChannels = NUM_USB_CHAN_OUT; +#if (NUM_USB_CHAN_OUT > 0) + cfgDesc_Audio2.Audio_Out_Format.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format.bBitResolution = HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_OUT; +#endif +#if (OUTPUT_FORMAT_COUNT > 1) + cfgDesc_Audio2.Audio_Out_Format_2.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_2.bBitResolution = HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_2.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_2.bNrChannels = NUM_USB_CHAN_OUT; +#endif - /* Mod bBitResolution */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+21] = SAMPLE_BIT_RESOLUTION_HS; - - /* wMaxPacketSize */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+26] = MAX_PACKET_SIZE_OUT_HS&0xff; - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+27] = (MAX_PACKET_SIZE_OUT_HS&0xff00)>>8; - - /* bNrChannels */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+10] = NUM_USB_CHAN_OUT; +#if (OUTPUT_FORMAT_COUNT > 2) + cfgDesc_Audio2.Audio_Out_Format_3.bSubslotSize = HS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_3.bBitResolution = HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_3.wMaxPacketSize = HS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_3.bNrChannels = NUM_USB_CHAN_OUT; +#endif #endif #if (NUM_USB_CHAN_IN > 0) - /* Input interface - Interface 2 */ - /* Mod bSlotSize */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+20] = SAMPLE_SUBSLOT_SIZE_HS; - - /* Mod bBitResolution */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+21] = SAMPLE_BIT_RESOLUTION_HS; - - /* wMaxPacketSize */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+26] = MAX_PACKET_SIZE_IN_HS&0xff; - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+27] = (MAX_PACKET_SIZE_IN_HS&0xff00)>>8; - - /* bNrChannels */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+10] = NUM_USB_CHAN_IN; + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_In_InputTerminal.bNrChannels = NUM_USB_CHAN_IN; + cfgDesc_Audio2.Audio_In_Format.bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_In_Format.bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_In_Endpoint.wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_In_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_IN; #endif } else - { + { + /* Modify Audio Class 2.0 Config descriptor for Full-speed operation */ #if (NUM_USB_CHAN_OUT > 0) - /* Output interface - Interface 1 */ - /* Mod bSlotSize */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+20] = SAMPLE_SUBSLOT_SIZE_FS; + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_Out_InputTerminal.bNrChannels = NUM_USB_CHAN_OUT_FS; +#if (NUM_USB_CHAN_OUT > 0) + cfgDesc_Audio2.Audio_Out_Format.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format.bBitResolution = FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_OUT_FS; +#endif +#if (OUTPUT_FORMAT_COUNT > 1) + cfgDesc_Audio2.Audio_Out_Format_2.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_2.bBitResolution = FS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_2.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_2_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_2.bNrChannels = NUM_USB_CHAN_OUT_FS; +#endif - /* Mod bBitResolution */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+21] = SAMPLE_BIT_RESOLUTION_FS; - - /* wMaxPacketSize */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+26] = MAX_PACKET_SIZE_OUT_FS&0xff; - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+27] = (MAX_PACKET_SIZE_OUT_FS&0xff00)>>8; - - /* bNrChannels */ - cfgDesc_Audio2[STREAMING_OUTPUT_ALT1_OFFSET+10] = NUM_USB_CHAN_OUT_FS; +#if (OUTPUT_FORMAT_COUNT > 2) + cfgDesc_Audio2.Audio_Out_Format_3.bSubslotSize = FS_STREAM_FORMAT_OUTPUT_3_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_Out_Format_3.bBitResolution = FS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_Out_Endpoint_3.wMaxPacketSize = FS_STREAM_FORMAT_OUTPUT_3_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_Out_ClassStreamInterface_3.bNrChannels = NUM_USB_CHAN_OUT_FS; +#endif #endif #if (NUM_USB_CHAN_IN > 0) - /* Input interface - Interface 2 */ - /* Mod bSlotSize */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+20] = SAMPLE_SUBSLOT_SIZE_FS; - - /* Mod bBitResolution */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+21] = SAMPLE_BIT_RESOLUTION_FS; - - /* wMaxPacketSize */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+26] = MAX_PACKET_SIZE_IN_FS&0xff; - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+27] = (MAX_PACKET_SIZE_IN_FS&0xff00)>>8; - - /* bNrChannels */ - cfgDesc_Audio2[STREAMING_INPUT_ALT1_OFFSET+10] = NUM_USB_CHAN_IN_FS; + cfgDesc_Audio2.Audio_CS_Control_Int.Audio_In_InputTerminal.bNrChannels = NUM_USB_CHAN_IN_FS; + cfgDesc_Audio2.Audio_In_Format.bSubslotSize = FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; + cfgDesc_Audio2.Audio_In_Format.bBitResolution = FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; + cfgDesc_Audio2.Audio_In_Endpoint.wMaxPacketSize = FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE; + cfgDesc_Audio2.Audio_In_ClassStreamInterface.bNrChannels = NUM_USB_CHAN_IN_FS; #endif } result = USB_StandardRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), + (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), null, 0, null, 0, +#ifdef __XC__ strDescs, sizeof(strDescs)/sizeof(strDescs[0]), sp, c_usb_test, g_curUsbSpeed); +#else + strDescs, sizeof(strDescs)/sizeof(strDescs[0]), &sp, c_usb_test, g_curUsbSpeed); +#endif #elif (AUDIO_CLASS == 1) /* Return Audio 1.0 Descriptors in FS, should never be in HS! */ result = USB_StandardRequests(ep0_out, ep0_in, @@ -656,15 +681,15 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, null, 0, devDesc_Audio1, sizeof(devDesc_Audio1), cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - strDescs, sizeof(strDescs)/sizeof(strDescs[0]), sp, c_usb_test, g_curUsbSpeed); + strDescs, sizeof(strDescs)/sizeof(strDescs[0]), &sp, c_usb_test, g_curUsbSpeed); #else /* Return Audio 2.0 Descriptors with Null device as fallback */ result = USB_StandardRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + (unsigned char*)&devDesc_Audio2, sizeof(devDesc_Audio2), + (unsigned char*)&cfgDesc_Audio2, sizeof(cfgDesc_Audio2), devDesc_Null, sizeof(devDesc_Null), cfgDesc_Null, sizeof(cfgDesc_Null), - strDescs, sizeof(strDescs)/sizeof(strDescs[0]), sp, c_usb_test, g_curUsbSpeed); + strDescs, sizeof(strDescs)/sizeof(strDescs[0]), &sp, c_usb_test, g_curUsbSpeed); #endif #ifdef DFU } @@ -676,15 +701,22 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, DFUcfgDesc, sizeof(DFUcfgDesc), null, 0, /* Used same descriptors for full and high-speed */ null, 0, - strDescs, sizeof(strDescs), sp, c_usb_test, g_curUsbSpeed); +#ifdef __XC__ + strDescs, sizeof(strDescs)/sizeof(strDescs[0]), sp, c_usb_test, g_curUsbSpeed); +#else + strDescs, sizeof(strDescs)/sizeof(strDescs[0]), &sp, c_usb_test, g_curUsbSpeed); +#endif } #endif } if (result == XUD_RES_RST) { +#ifdef __XC__ g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, ep0_in); - +#else + g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, &ep0_in); +#endif g_currentConfig = 0; #ifdef DFU @@ -692,8 +724,6 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, { if (!DFU_mode_active) { - timer tmr; - unsigned s; DFU_mode_active = 1; } } @@ -701,13 +731,10 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, { if (DFU_mode_active) { - timer tmr; - unsigned s; DFU_mode_active = 0; /* Send reboot command */ - tmr :> s; - tmr when timerafter(s + 5000000) :> s; + DFUDelay(5000000); device_reboot(c_audioControl); } } diff --git a/module_usb_audio/endpoint0/vendorrequests.h b/module_usb_audio/endpoint0/vendorrequests.h index 680464ba..e571ba92 100644 --- a/module_usb_audio/endpoint0/vendorrequests.h +++ b/module_usb_audio/endpoint0/vendorrequests.h @@ -1,6 +1,8 @@ #ifndef _VENDORREQUESTS_H_ #define _VENDORREQUESTS_H_ +#include + /* Functions that handle vustomer vendor requests. * * THESE NEED IMPLEMENTING FOR A SPECIFIC DESIGN @@ -10,7 +12,9 @@ * */ int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn, - unsigned short unitId, unsigned char direction, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctL); + unsigned short unitId, unsigned char direction, chanend c_audioControl, + NULLABLE_RESOURCE(chanend, c_mix_ctl), + NULLABLE_RESOURCE(chanend, c_clk_ctL)); #endif diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index e6bccb1b..c26fdd03 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -13,7 +13,6 @@ #endif #include "xud.h" /* XMOS USB Device Layer defines and functions */ -#include "usb.h" /* Defines from the USB 2.0 Specification */ #include "devicedefines.h" /* Device specific defines */ #include "endpoint0.h" diff --git a/module_usb_audio/usb_buffer/decouple.xc b/module_usb_audio/usb_buffer/decouple.xc index 0f92f9e9..c703a910 100644 --- a/module_usb_audio/usb_buffer/decouple.xc +++ b/module_usb_audio/usb_buffer/decouple.xc @@ -4,24 +4,28 @@ #include "interrupt.h" #include "commands.h" #include "xud.h" -#include "usb.h" + +#ifdef NATIVE_DSD +#include "usbaudio20.h" /* Defines from the USB Audio 2.0 Specifications */ +#endif + #ifdef HID_CONTROLS #include "user_hid.h" #endif #define MAX(x,y) ((x)>(y) ? (x) : (y)) -#define CLASS_TWO_PACKET_SIZE ((((MAX_FREQ+7999)/8000))+3) // Samples per channel -#define CLASS_ONE_PACKET_SIZE ((((MAX_FREQ_FS+999)/1000))+3) // Samples per channel +#define HS_PACKET_SIZE ((((MAX_FREQ+7999)/8000))+3) // Samples per channel +#define FS_PACKET_SIZE ((((MAX_FREQ_FS+999)/1000))+3) // Samples per channel -/* TODO user SLOTSIZE to potentially save memory */ -#define BUFF_SIZE_OUT MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * CLASS_ONE_PACKET_SIZE * NUM_USB_CHAN_OUT_FS) -#define BUFF_SIZE_IN MAX(4 * CLASS_TWO_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * CLASS_ONE_PACKET_SIZE * NUM_USB_CHAN_IN_FS) +/* TODO use SLOTSIZE to potentially save memory */ +#define BUFF_SIZE_OUT MAX(4 * HS_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * FS_PACKET_SIZE * NUM_USB_CHAN_OUT_FS) +#define BUFF_SIZE_IN MAX(4 * HS_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * FS_PACKET_SIZE * NUM_USB_CHAN_IN_FS) /* Maximum USB buffer size (1024 bytes + 1 word to store length) */ #define MAX_USB_AUD_PACKET_SIZE 1028 -#define OUT_BUFFER_PREFILL (MAX(NUM_USB_CHAN_OUT_FS*CLASS_ONE_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*CLASS_TWO_PACKET_SIZE*4+4)*1) -#define IN_BUFFER_PREFILL (MAX(CLASS_ONE_PACKET_SIZE*3+4,CLASS_TWO_PACKET_SIZE*4+4)*2) +#define OUT_BUFFER_PREFILL (MAX(NUM_USB_CHAN_OUT_FS*FS_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*HS_PACKET_SIZE*4+4)*1) +#define IN_BUFFER_PREFILL (MAX(FS_PACKET_SIZE*2+4, HS_PACKET_SIZE*4+4)*2) /* Volume and mute tables */ #ifndef OUT_VOLUME_IN_MIXER @@ -37,10 +41,14 @@ static xc_ptr p_multIn; unsigned g_numUsbChanOut = NUM_USB_CHAN_OUT; unsigned g_numUsbChanIn = NUM_USB_CHAN_IN; -#define MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO ((MAX_FREQ/8000+1)*NUM_USB_CHAN_IN*4) -#define MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE (((MAX_FREQ_FS/1000+1)*NUM_USB_CHAN_IN_FS*3)+4) +/* Note we could improve on this, for one subslot is set to 4 */ +#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS ((MAX_FREQ/8000+1)*4) +#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS ((MAX_FREQ_FS/1000+1)*4) -#define MAX_DEVICE_AUD_PACKET_SIZE (MAX(MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE, MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO)) +#define MAX_DEVICE_AUD_PACKET_SIZE_HS ((MAX_FREQ/8000+1)*NUM_USB_CHAN_IN*4) +#define MAX_DEVICE_AUD_PACKET_SIZE_FS ((MAX_FREQ_FS/1000+1)*NUM_USB_CHAN_IN_FS*4) + +#define MAX_DEVICE_AUD_PACKET_SIZE (MAX(MAX_DEVICE_AUD_PACKET_SIZE_FS, MAX_DEVICE_AUD_PACKET_SIZE_HS)) /* Circular audio buffers */ unsigned outAudioBuff[BUFF_SIZE_OUT + (MAX_USB_AUD_PACKET_SIZE>>2) + 4]; @@ -64,6 +72,11 @@ unsigned g_aud_from_host_flag = 0; unsigned g_aud_from_host_info; unsigned g_freqChange_flag = 0; unsigned g_freqChange_sampFreq; + +unsigned g_formatChange_SubSlot; +unsigned g_formatChange_DataFormat; +unsigned g_formatChange_NumChans; + int speedRem = 0; xc_ptr aud_from_host_fifo_start; @@ -96,12 +109,15 @@ unsigned unpackData = 0; unsigned packState = 0; unsigned packData = 0; +/* Default to something sensible but the following are setup at stream start: */ +unsigned g_curSubSlot_out = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; +unsigned g_curSubSlot_in = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; + +/* Init to something sensible, but expect to be re-set before stream start */ #if (AUDIO_CLASS==2) -int g_slotSize = SAMPLE_SUBSLOT_SIZE_HS; /* 4 bytes per ssample for Audio Class 2.0 */ -int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO; +int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_HS; #else -int g_slotSize = SAMPLE_SUBSLOT_SIZE_FS; /* 3 bytes per sample for Audio Class 1.0 */ -int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE; +int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_FS; #endif #pragma select handler @@ -118,23 +134,6 @@ void handle_audio_request(chanend c_mix_out) /* Reply with underflow */ outuint(c_mix_out, outUnderflow); - GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed); - - /* slotSize different for Audio Class 1.0/2.0. */ - /* TODO It is quite wasteful to run this check every interrupt. Perhaps on stream start is good enough */ -#if defined(AUDIO_CLASS_FALLBACK) || defined (FULL_SPEED_AUDIO_2) - if (usb_speed == XUD_SPEED_HS) - { - g_slotSize = SAMPLE_SUBSLOT_SIZE_HS; /* Typically 4 bytes per sample for HS */ - g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_TWO; - } - else - { - g_slotSize = SAMPLE_SUBSLOT_SIZE_FS; /* Typically 3 bytes per sample for FS */ - g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_CLASS_ONE; - } -#endif - /* If in overflow condition then receive samples and throw away */ if(inOverflow || sampsToWrite == 0) { @@ -160,14 +159,13 @@ void handle_audio_request(chanend c_mix_out) } else { - /* Not in overflow, store samples from mixer into sample buffer */ - switch(g_slotSize) + switch(g_curSubSlot_in) { case 4: { -#if (SAMPLE_SUBSLOT_SIZE_HS != 4) && (SAMPLE_SUBSLOT_SIZE_FS != 4) -__builtin_unreachable(); +#if (STREAM_FORMAT_INPUT_SUBSLOT_4_USED == 1) +//__builtin_unreachable(); #endif unsigned ptr = g_aud_to_host_dptr; @@ -183,6 +181,7 @@ __builtin_unreachable(); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); {h, l} = macs(mult, sample, 0, 0); sample = h << 3; +#warning FIXME sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32) #elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) sample = sample << 3; @@ -198,8 +197,8 @@ __builtin_unreachable(); } case 3: -#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3) -__builtin_unreachable(); +#if (STREAM_FORMAT_INPUT_SUBSLOT_3_USED == 1) +//__builtin_unreachable(); #endif for(int i = 0; i < g_numUsbChanIn; i++) { @@ -244,9 +243,8 @@ __builtin_unreachable(); break; case 2: - -#if (SAMPLE_SUBSLOT_SIZE_HS != 2) && (SAMPLE_SUBSLOT_SIZE_FS != 2) -__builtin_unreachable(); +#if (STREAM_FORMAT_INPUT_SUBSLOT_2_USED == 1) +//__builtin_unreachable(); #endif for(int i = 0; i < g_numUsbChanIn; i++) { @@ -260,24 +258,13 @@ __builtin_unreachable(); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); {h, l} = macs(mult, sample, 0, 0); sample = h << 3; -#if (SAMPLE_BIT_RESOLUTION_HS > 24) || (SAMPLE_BIT_RESOLUTION_FS > 24) - sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32) -#endif + + /* Note, in 2 byte sub slot - ignore lower bits of macs */ #elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) sample = sample << 3; #endif - /* Write into fifo */ - switch (packState&0x1) - { - case 0: - packData = sample; - break; - case 1: - packData = (packData>>16) | (sample & 0xffff0000); - write_via_xc_ptr(g_aud_to_host_dptr, packData); - g_aud_to_host_dptr+=4; - break; - } + write_short_via_xc_ptr(g_aud_to_host_dptr, sample>>16); + g_aud_to_host_dptr+=2; } break; @@ -330,11 +317,41 @@ __builtin_unreachable(); } else { - switch(g_slotSize) + switch(g_curSubSlot_out) { + + case 2: +#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3) +//__builtin_unreachable(); +#endif +/* Buffering not underflow condition send out some samples...*/ + for(int i = 0; i < g_numUsbChanOut; i++) + { +#pragma xta endpoint "mixer_request" + int sample; + int mult; + int h; + unsigned l; + + read_short_via_xc_ptr(sample, g_aud_from_host_rdptr); + g_aud_from_host_rdptr+=2; + sample <<= 16; + +#ifndef OUT_VOLUME_IN_MIXER + asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); + {h, l} = macs(mult, sample, 0, 0); + /* Note, in 2 byte subslot mode - ignore lower result of macs */ + h <<= 3; + outuint(c_mix_out, h); +#else + outuint(c_mix_out, sample); +#endif + } + break; + case 4: #if (SAMPLE_SUBSLOT_SIZE_HS != 4) && (SAMPLE_SUBSLOT_SIZE_FS != 4) -__builtin_unreachable(); +//__builtin_unreachable(); #endif /* Buffering not underflow condition send out some samples...*/ for(int i = 0; i < g_numUsbChanOut; i++) @@ -352,10 +369,11 @@ __builtin_unreachable(); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); {h, l} = macs(mult, sample, 0, 0); h <<= 3; -#if (SAMPLE_BIT_RESOLUTION_HS > 24) || (SAMPLE_BIT_RESOLUTION_FS > 24) || defined(NATIVE_DSD) +//#if (SAMPLE_BIT_RESOLUTION_HS > 24) || (SAMPLE_BIT_RESOLUTION_FS > 24) || defined(NATIVE_DSD) +#warning FIXME h |= (l >>29)& 0x7; // Note: This step is not required if we assume sample depth is 24bit (rather than 32bit) // Note: We need all 32bits for Native DSD -#endif +//#endif outuint(c_mix_out, h); #else outuint(c_mix_out, sample); @@ -366,7 +384,7 @@ __builtin_unreachable(); case 3: #if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3) -__builtin_unreachable(); +//__builtin_unreachable(); #endif /* Buffering not underflow condition send out some samples...*/ for(int i = 0; i < g_numUsbChanOut; i++) @@ -415,48 +433,12 @@ __builtin_unreachable(); } break; - case 2: -#if (SAMPLE_SUBSLOT_SIZE_HS != 3) && (SAMPLE_SUBSLOT_SIZE_FS != 3) -__builtin_unreachable(); -#endif -/* Buffering not underflow condition send out some samples...*/ - for(int i = 0; i < g_numUsbChanOut; i++) - { -#pragma xta endpoint "mixer_request" - int sample; - int mult; - int h; - unsigned l; - - switch (unpackState&0x1) - { - case 0: - read_via_xc_ptr(unpackData, g_aud_from_host_rdptr); - sample = unpackData << 16; - break; - case 1: - g_aud_from_host_rdptr+=4; - sample = unpackData & 0xffff0000; - break; - } - unpackState++; - -#ifndef OUT_VOLUME_IN_MIXER - asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); - {h, l} = macs(mult, sample, 0, 0); - h <<= 3; - outuint(c_mix_out, h); -#else - outuint(c_mix_out, sample); -#endif - } - break; - + default: - __builtin_unreachable(); + //__builtin_unreachable(); break; - } /* switch(g_slotsize) */ + } /* switch(g_curSubSlot_out) */ /* Output remaining channels. Past this point we always operate on MAX chan count */ for(int i = 0; i < NUM_USB_CHAN_OUT - g_numUsbChanOut; i++) @@ -465,7 +447,7 @@ __builtin_unreachable(); } /* 3/4 bytes per sample */ - aud_data_remaining_to_device -= (g_numUsbChanOut*g_slotSize); + aud_data_remaining_to_device -= (g_numUsbChanOut * g_curSubSlot_out); } if (!inOverflow) @@ -476,7 +458,7 @@ __builtin_unreachable(); if (totalSampsToWrite) { - unsigned datasize = totalSampsToWrite * g_slotSize * g_numUsbChanIn; + unsigned datasize = totalSampsToWrite * g_curSubSlot_in * g_numUsbChanIn; /* Round up to nearest word - note, not needed for slotsize == 4! */ datasize = (datasize+3) & (~0x3); @@ -513,7 +495,7 @@ __builtin_unreachable(); } } #else - if (totalSampsToWrite < 0 || totalSampsToWrite * g_slotSize * g_numUsbChanIn > g_maxPacketSize) + if (totalSampsToWrite < 0 || totalSampsToWrite * g_curSubSlot_in * g_numUsbChanIn > g_maxPacketSize) { totalSampsToWrite = 0; } @@ -528,12 +510,12 @@ __builtin_unreachable(); space_left = aud_to_host_fifo_end - g_aud_to_host_wrptr; } - if ((space_left <= 0) || (space_left > totalSampsToWrite*g_numUsbChanIn * 4 + 4)) + if ((space_left <= 0) || (space_left > totalSampsToWrite*g_numUsbChanIn * g_curSubSlot_in + 4)) { /* Packet okay, write to fifo */ if (totalSampsToWrite) { - write_via_xc_ptr(g_aud_to_host_wrptr, totalSampsToWrite*g_slotSize*g_numUsbChanIn); + write_via_xc_ptr(g_aud_to_host_wrptr, totalSampsToWrite * g_curSubSlot_in * g_numUsbChanIn); packState = 0; g_aud_to_host_dptr = g_aud_to_host_wrptr + 4; } @@ -547,7 +529,7 @@ __builtin_unreachable(); } } - if (!outUnderflow && (aud_data_remaining_to_device<(g_slotSize*g_numUsbChanOut))) + if (!outUnderflow && (aud_data_remaining_to_device<(g_curSubSlot_out * g_numUsbChanOut))) { /* Handle any tail - incase a bad driver sent us a datalength not a multiple of chan count */ if (aud_data_remaining_to_device) @@ -620,18 +602,20 @@ static void check_for_interrupt(chanend ?c_clk_int) { } /* Mark Endpoint (IN) ready with an appropriately sized zero buffer */ -static inline void SetupZerosSendBuffer(XUD_ep aud_to_host_usb_ep, unsigned sampFreq) +static inline void SetupZerosSendBuffer(XUD_ep aud_to_host_usb_ep, unsigned sampFreq, unsigned slotSize) { int min, mid, max, usb_speed, p; GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed); GetADCCounts(sampFreq, min, mid, max); + + // TODO, don't need to use speed. if (usb_speed == XUD_SPEED_HS) { - mid*=NUM_USB_CHAN_IN*SAMPLE_SUBSLOT_SIZE_HS; + mid *= NUM_USB_CHAN_IN * slotSize; } else { - mid*=NUM_USB_CHAN_IN_FS*SAMPLE_SUBSLOT_SIZE_FS; + mid *= NUM_USB_CHAN_IN_FS * slotSize; } asm("stw %0, %1[0]"::"r"(mid),"r"(g_aud_to_host_zeros)); @@ -793,7 +777,7 @@ void decouple(chanend c_mix_out, SET_SHARED_GLOBAL(g_aud_to_host_buffer,g_aud_to_host_zeros); /* Update size of zeros buffer */ - SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq); + SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_in); /* Reset OUT buffer state */ outUnderflow = 1; @@ -819,13 +803,18 @@ void decouple(chanend c_mix_out, speedRem = 0; continue; } - else if(tmp == SET_CHAN_COUNT_IN) + else if(tmp == SET_STREAM_FORMAT_IN) { + unsigned dataFormat, usbSpeed; + /* Change in IN channel count */ DISABLE_INTERRUPTS(); SET_SHARED_GLOBAL(g_freqChange_flag, 0); - GET_SHARED_GLOBAL(g_numUsbChanIn, g_freqChange_sampFreq); /* Misuse of g_freqChange_sampFreq */ - + + GET_SHARED_GLOBAL(g_numUsbChanIn, g_formatChange_NumChans); + GET_SHARED_GLOBAL(g_curSubSlot_in, g_formatChange_SubSlot); + GET_SHARED_GLOBAL(dataFormat, g_formatChange_DataFormat); /* Not currently used for input stream */ + /* Reset IN buffer state */ inOverflow = 0; inUnderflow = 1; @@ -838,22 +827,41 @@ void decouple(chanend c_mix_out, SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros); /* Update size of zeros buffer */ - SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq); + SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_in); + + GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed); + if (usbSpeed == XUD_SPEED_HS) + { + g_maxPacketSize = (MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS * g_numUsbChanIn); + } + else + { + g_maxPacketSize = (MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS * g_numUsbChanIn); + } SET_SHARED_GLOBAL(g_freqChange, 0); + asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END)); + ENABLE_INTERRUPTS(); } - else if(tmp == SET_CHAN_COUNT_OUT) + else if(tmp == SET_STREAM_FORMAT_OUT) { + unsigned dataFormat; + unsigned dsdMode = DSD_MODE_OFF; + /* Change in OUT channel count - note we expect this on every stream start event */ DISABLE_INTERRUPTS(); SET_SHARED_GLOBAL(g_freqChange_flag, 0); - GET_SHARED_GLOBAL(g_numUsbChanOut, g_freqChange_sampFreq); /* Misuse of g_freqChange_sampFreq */ + GET_SHARED_GLOBAL(g_numUsbChanOut, g_formatChange_NumChans); + GET_SHARED_GLOBAL(g_curSubSlot_out, g_formatChange_SubSlot); + GET_SHARED_GLOBAL(dataFormat, g_formatChange_DataFormat); /* Reset OUT buffer state */ SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start); SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start); + unpackState = 0; + outUnderflow = 1; if(outOverflow) { @@ -861,11 +869,29 @@ void decouple(chanend c_mix_out, XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4); outOverflow = 0; } + +#ifdef NATIVE_DSD + /* TODO only send when there is a change */ + if(dataFormat == UAC_FORMAT_TYPEI_RAW_DATA) + { + dsdMode = DSD_MODE_NATIVE; + } + + /* Wait for the audio code to request samples and respond with command */ + inuint(c_mix_out); + outct(c_mix_out, SET_DSD_MODE); + outuint(c_mix_out, dsdMode); + + /* Wait for handshake back */ + chkct(c_mix_out, XS1_CT_END); +#endif + asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END)); SET_SHARED_GLOBAL(g_freqChange, 0); ENABLE_INTERRUPTS(); } -#ifdef NATIVE_DSD +#if 0 +//#ifdef NATIVE_DSD else if(tmp == SET_DSD_MODE) { unsigned dsdMode; @@ -922,7 +948,7 @@ void decouple(chanend c_mix_out, read_via_xc_ptr(datalength, released_buffer); /* Ignore bad small packets */ - if ((datalength >= (g_numUsbChanOut * g_slotSize)) && (released_buffer == aud_from_host_wrptr)) + if ((datalength >= (g_numUsbChanOut * g_curSubSlot_out)) && (released_buffer == aud_from_host_wrptr)) { /* Move the write pointer of the fifo on - round up to nearest word */ diff --git a/module_usb_audio/usb_buffer/usb_buffer.xc b/module_usb_audio/usb_buffer/usb_buffer.xc index b9a61383..487a098a 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.xc +++ b/module_usb_audio/usb_buffer/usb_buffer.xc @@ -2,7 +2,6 @@ #include #include -#include "usb.h" #include "devicedefines.h" #ifdef MIDI #include "usb_midi.h" @@ -241,10 +240,11 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud else { unsigned cmd = inuint(c_aud_ctl); - sampleFreq = inuint(c_aud_ctl); if(cmd == SET_SAMPLE_FREQ) { + sampleFreq = inuint(c_aud_ctl); + /* Don't update things for DFU command.. */ if(sampleFreq != AUDIO_STOP_FOR_DFU) { @@ -262,9 +262,31 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud /* Ideally we want to wait for handshake (and pass back up) here. But we cannot keep this * core locked, it must stay responsive to packets (MIDI etc) and SOFs. So, set a flag and check for * handshake elsewhere */ + SET_SHARED_GLOBAL(g_freqChange_sampFreq, sampleFreq); } - else if (cmd == SET_CHAN_COUNT_OUT) + else if(cmd == SET_STREAM_FORMAT_IN) { + unsigned formatChange_SubSlot, formatChange_NumChans, formatChange_DataFormat; + + formatChange_DataFormat = inuint(c_aud_ctl); + formatChange_NumChans = inuint(c_aud_ctl); + formatChange_SubSlot = inuint(c_aud_ctl); + + SET_SHARED_GLOBAL(g_formatChange_NumChans, formatChange_NumChans); + SET_SHARED_GLOBAL(g_formatChange_SubSlot, formatChange_SubSlot); + SET_SHARED_GLOBAL(g_formatChange_DataFormat, formatChange_DataFormat); + } + else if (cmd == SET_STREAM_FORMAT_OUT) + { + unsigned formatChange_SubSlot, formatChange_NumChans, formatChange_DataFormat; + formatChange_DataFormat = inuint(c_aud_ctl); + formatChange_NumChans = inuint(c_aud_ctl); + formatChange_SubSlot = inuint(c_aud_ctl); + + SET_SHARED_GLOBAL(g_formatChange_NumChans, formatChange_NumChans); + SET_SHARED_GLOBAL(g_formatChange_SubSlot, formatChange_SubSlot); + SET_SHARED_GLOBAL(g_formatChange_DataFormat, formatChange_DataFormat); + /* Host is starting up the output stream. Setup (or potentially resize) feedback packet based on bus-speed * This is only really important on inital start up (when bus-speed was unknown) and when changing bus-speeds */ @@ -284,8 +306,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud /* Pass on sample freq change to decouple() via global flag (saves a chanend) */ /* Note: freqChange flags now used to communicate other commands also */ SET_SHARED_GLOBAL0(g_freqChange, cmd); /* Set command */ - SET_SHARED_GLOBAL(g_freqChange_sampFreq, sampleFreq); /* Set flag */ - SET_SHARED_GLOBAL(g_freqChange_flag, cmd); + SET_SHARED_GLOBAL(g_freqChange_flag, cmd); /* Set Flag */ } break; } @@ -422,11 +443,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud #ifdef MIDI case XUD_GetData_Select(c_midi_from_host, ep_midi_from_host, length, result): asm("#midi h->d"); - + if((result == XUD_RES_OKAY) && (length > 0)) { /* Get buffer data from host - MIDI OUT from host always into a single buffer */ - /* Write datalength (tmp) into buffer[0], data stored in buffer[4] onwards */ midi_data_remaining_to_device = length; midi_from_host_rdptr = midi_from_host_buffer; diff --git a/module_usb_audio/usb_buffer/xc_ptr.h b/module_usb_audio/usb_buffer/xc_ptr.h index bb54372b..6074c9eb 100644 --- a/module_usb_audio/usb_buffer/xc_ptr.h +++ b/module_usb_audio/usb_buffer/xc_ptr.h @@ -14,19 +14,25 @@ inline xc_ptr array_to_xc_ptr(const unsigned a[]) return x; } -#define write_via_xc_ptr(p,x) asm volatile("stw %0, %1[0]"::"r"(x),"r"(p)) +#define write_via_xc_ptr(p,x) asm volatile("stw %0, %1[0]"::"r"(x),"r"(p)) -#define write_via_xc_ptr_indexed(p,i,x) asm volatile("stw %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) -#define write_byte_via_xc_ptr_indexed(p,i,x) asm volatile("st8 %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) +#define write_via_xc_ptr_indexed(p,i,x) asm volatile("stw %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) +#define write_byte_via_xc_ptr_indexed(p,i,x) asm volatile("st8 %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) +#define write_byte_via_xc_ptr_indexed(p,i,x) asm volatile("st8 %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) +#define write_short_via_xc_ptr_indexed(p,i,x) asm volatile("st16 %0, %1[%2]"::"r"(x),"r"(p),"r"(i)) // No immediate st8 format -#define write_byte_via_xc_ptr(p,x) write_byte_via_xc_ptr_indexed(p, 0, x) +#define write_byte_via_xc_ptr(p,x) write_byte_via_xc_ptr_indexed(p, 0, x) +#define write_short_via_xc_ptr(p,x) write_short_via_xc_ptr_indexed(p, 0, x) -#define read_via_xc_ptr(x,p) asm("ldw %0, %1[0]":"=r"(x):"r"(p)); +#define read_via_xc_ptr(x,p) asm("ldw %0, %1[0]":"=r"(x):"r"(p)); + +#define read_via_xc_ptr_indexed(x,p,i) asm("ldw %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); +#define read_byte_via_xc_ptr_indexed(x,p,i) asm("ld8u %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); +#define read_short_via_xc_ptr_indexed(x,p,i) asm("ld16s %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); -#define read_via_xc_ptr_indexed(x,p,i) asm("ldw %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); -#define read_byte_via_xc_ptr_indexed(x,p,i) asm("ld8u %0, %1[%2]":"=r"(x):"r"(p),"r"(i)); // No immediate ld8u format -#define read_byte_via_xc_ptr(x,p) read_byte_via_xc_ptr_indexed(x, p, 0) +#define read_byte_via_xc_ptr(x,p) read_byte_via_xc_ptr_indexed(x, p, 0) +#define read_short_via_xc_ptr(x,p) read_short_via_xc_ptr_indexed(x, p, 0) #define GET_SHARED_GLOBAL(x, g) asm volatile("ldw %0, dp[" #g "]":"=r"(x)::"memory") #define SET_SHARED_GLOBAL(g, v) asm volatile("stw %0, dp[" #g "]"::"r"(v):"memory")