diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fc73742f..863e2c29 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -21,6 +21,8 @@ lib_xua Change Log events, to report Key-phrase detection as AC Search, and to report end-call detection as AC Stop * ADDED: Ability to read or modify vendor and product IDs + * ADDED: Override USB descriptor with sampling frequency and + bit-resolution set at boot time. 0.2.1 ----- diff --git a/lib_xua/api/xua_usb_params_funcs.h b/lib_xua/api/xua_usb_params_funcs.h new file mode 100644 index 00000000..0a427046 --- /dev/null +++ b/lib_xua/api/xua_usb_params_funcs.h @@ -0,0 +1,18 @@ +// Copyright (c) 2017-2020, XMOS Ltd, All rights reserved + +#ifndef __XUA_API_H__ +#define __XUA_API_H__ + +#include + +void set_usb_to_device_rate(uint32_t rate); +void set_device_to_usb_rate(uint32_t rate); +void set_usb_to_device_bit_res(uint32_t rate); +void set_device_to_usb_bit_res(uint32_t rate); + +uint32_t get_usb_to_device_rate(); +uint32_t get_device_to_usb_rate(); +uint32_t get_usb_to_device_bit_res(); +uint32_t get_device_to_usb_bit_res(); + +#endif //__XUA_API_H__ diff --git a/lib_xua/src/core/buffer/decouple/decouple.xc b/lib_xua/src/core/buffer/decouple/decouple.xc index 297dff8d..f217b0e4 100644 --- a/lib_xua/src/core/buffer/decouple/decouple.xc +++ b/lib_xua/src/core/buffer/decouple/decouple.xc @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2019, XMOS Ltd, All rights reserved +// Copyright (c) 2011-2020, XMOS Ltd, All rights reserved #include "xua.h" #if XUA_USB_EN @@ -7,6 +7,7 @@ #include "interrupt.h" #include "xua_commands.h" #include "xud.h" +#include "xua_usb_params_funcs.h" #ifdef NATIVE_DSD #include "usbaudio20.h" /* Defines from the USB Audio 2.0 Specifications */ @@ -17,6 +18,7 @@ #endif #define MAX(x,y) ((x)>(y) ? (x) : (y)) + /* TODO use SLOTSIZE to potentially save memory */ /* Note we could improve on this, for one subslot is set to 4 */ /* The *4 is conversion to bytes, note we're assuming a slotsize of 4 here whic is potentially as waste */ @@ -136,6 +138,7 @@ unsigned unpackData = 0; unsigned packState = 0; unsigned packData = 0; + /* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */ #if (AUDIO_CLASS == 2) unsigned g_curSubSlot_Out = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; @@ -145,7 +148,6 @@ unsigned g_curSubSlot_Out = FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; unsigned g_curSubSlot_In = FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; #endif - /* IN packet size. Init to something sensible, but expect to be re-set before stream start */ #if (AUDIO_CLASS==2) int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_IN_HS; @@ -158,6 +160,10 @@ int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_IN_FS; void handle_audio_request(chanend c_mix_out) { int space_left; +#if(defined XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES) + g_curSubSlot_Out = get_usb_to_device_bit_res() >> 3; + g_curSubSlot_In = get_device_to_usb_bit_res() >> 3; +#endif /* Input word that triggered interrupt and handshake back */ unsigned underflowSample = inuint(c_mix_out); diff --git a/lib_xua/src/core/endpoint0/xua_endpoint0.c b/lib_xua/src/core/endpoint0/xua_endpoint0.c index e62f5fb8..2a183c72 100755 --- a/lib_xua/src/core/endpoint0/xua_endpoint0.c +++ b/lib_xua/src/core/endpoint0/xua_endpoint0.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "xua.h" @@ -28,6 +29,8 @@ #include "dsd_support.h" #endif +#include "xua_usb_params_funcs.h" + #ifndef __XC__ /* Support for xCORE channels in C */ #define null 0 @@ -336,6 +339,38 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCont } #endif +#ifdef XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES //change USB descriptor frequencies and bit resolution values here + + cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME] = get_device_to_usb_bit_res() >> 3; //sub frame rate = bit rate /8 + cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME + 1] = (get_device_to_usb_bit_res() & 0xff); //bit resolution + + cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME] = get_usb_to_device_bit_res() >> 3; //sub frame rate = bit rate /8 + cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME + 1] = (get_usb_to_device_bit_res() & 0xff); //bit resolution + + const unsigned num_of_usb_descriptor_freq=3; //This should be =3 according to the comments "using a value of <=2 or > 7 for num_freqs_a1 causes enumeration issues on Windows" in xua_ep0_descriptors.h + int i=0; + for(i=0;i> 8; + cfgDesc_Audio1[USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i + 2] = (get_device_to_usb_rate() & 0xff0000)>> 16; + } + + for(i=0;i> 8; + cfgDesc_Audio1[USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_FREQ + 3*i + 2] = (get_usb_to_device_rate() & 0xff0000)>> 16; + } + + cfgDesc_Audio1[USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE] = ((get_device_to_usb_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_IN_FS) & 0xff; //max packet size + cfgDesc_Audio1[USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE + 1] = (((get_device_to_usb_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_IN_FS) & 0xff00) >> 8; //max packet size + + cfgDesc_Audio1[USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE] = ((get_usb_to_device_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_OUT_FS) & 0xff; //max packet size + cfgDesc_Audio1[USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE + 1] = (((get_usb_to_device_bit_res() >> 3) * MAX_PACKET_SIZE_MULT_OUT_FS) & 0xff00) >> 8; //max packet size + +#endif + } void XUA_Endpoint0_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, diff --git a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h index b3ed06fa..5e51b3dd 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h +++ b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h @@ -2361,12 +2361,27 @@ const unsigned num_freqs_a1 = MAX(3, (0 /* Note, this is different that INTERFACE_COUNT since we dont support items such as MIDI, iAP etc in UAC1 mode */ #define NUM_INTERFACES_A1 (1 + INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1 + NUM_CONTROL_USB_INTERFACES + DFU_INTERFACES_A1 + HID_INTERFACES_A1) -#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) +#if ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) #define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (58 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + HID_INTERFACE_BYTES) #else #define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + CONTROL_INTERFACE_BYTES + DFU_INTERFACE_BYTES + HID_INTERFACE_BYTES) #endif +#ifdef XUA_USB_DESCRIPTOR_OVERWRITE_RATE_RES + #define AS_INTERFACE_BYTES (7) + #define INTERFACE_DESCRIPTOR_BYTES (9) + #define AS_FORMAT_TYPE_BYTES (17) + #define USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME (18 + AC_TOTAL_LENGTH + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + 5) + #define USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_SUB_FRAME (18 + AC_TOTAL_LENGTH + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + 5) + + #define USB_AS_IN_INTERFACE_DESCRIPTOR_OFFSET_FREQ (18 + AC_TOTAL_LENGTH + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + 8) + #define USB_AS_OUT_INTERFACE_DESCRIPTOR_OFFSET_FREQ (18 + AC_TOTAL_LENGTH + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + 8) + + #define USB_AS_IN_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE (18 + AC_TOTAL_LENGTH + (OUTPUT_INTERFACES_A1 * (49 + num_freqs_a1 * 3)) + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + (AS_FORMAT_TYPE_BYTES) + 4) + #define USB_AS_OUT_EP_DESCRIPTOR_OFFSET_MAXPACKETSIZE (18 + AC_TOTAL_LENGTH + (2*INTERFACE_DESCRIPTOR_BYTES) + (AS_INTERFACE_BYTES) + (AS_FORMAT_TYPE_BYTES) + 4) + +#endif + #define CHARIFY_SR(x) (x & 0xff),((x & 0xff00)>> 8),((x & 0xff0000)>> 16) #if (MIN_FREQ_FS < 12000) && (MAX_FREQ_FS > 48000) @@ -2599,7 +2614,6 @@ unsigned char cfgDesc_Audio1[] = NUM_USB_CHAN_OUT_FS, /* nrChannels */ FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES, /* subFrameSize */ FS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS, /* bitResolution */ - num_freqs_a1, /* SamFreqType - sample freq count */ /* Windows enum issue with <= two sample rates work around */ @@ -2656,7 +2670,7 @@ unsigned char cfgDesc_Audio1[] = /* Standard AS Isochronous Audio Data Endpoint Descriptor 4.6.1.1 */ 0x09, 0x05, /* ENDPOINT */ - 0x01, /* endpointAddress - D7, direction (0 OUT, 1 IN). D6..4 reserved (0). D3..0 endpoint no. */ + ENDPOINT_ADDRESS_OUT_AUDIO, /* endpointAddress - D7, direction (0 OUT, 1 IN). D6..4 reserved (0). D3..0 endpoint no. */ #ifdef XUA_ADAPTIVE ISO_EP_ATTRIBUTES_ADAPTIVE, #else diff --git a/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.h b/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.h index ab4c613d..f8c7cc33 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.h +++ b/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2014-2018, XMOS Ltd, All rights reserved +// Copyright (c) 2014-2020, XMOS Ltd, All rights reserved #ifndef _AUDIOREQUESTS_H_ #define _AUDIOREQUESTS_H_ diff --git a/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc b/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc index 2fdd434c..2ce05108 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc +++ b/lib_xua/src/core/endpoint0/xua_ep0_uacreqs.xc @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2018, XMOS Ltd, All rights reserved +// Copyright (c) 2011-2020, XMOS Ltd, All rights reserved /** * @brief Implements relevant requests from the USB Audio 2.0 Specification * @author Ross Owen, XMOS Semiconductor