diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 68789a60..288ebdaa 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,25 @@
sc_usb_audio Change Log
=======================
+6.9.0
+-----
+ - ADDED: ADAT S-MUX II functionality (i.e. 2 channels at 192kHz) - Previously only S-MUX
+ supported (4 channels at 96kHz).
+ - ADDED: Explicit build warnings if sample rate/depth & channel combination exceeds
+ available USB bus bandwidth.
+ - RESOLVED: (Major) Reinstated ADAT input functionality, including descriptors and clock
+ generation/control and stream configuration defines/tables.
+ - RESOLVED: (Major) S/PDIF/ADAT sample transfer code in audio() (from ClockGen()) moved to
+ aid timing.
+ - CHANGE: Modifying mix map now only affects specified mix, previous was applied to all
+ mixes. CS_XU_MIXSEL control selector now takes values 0 to MAX_MIX_COUNT + 1
+ (with 0 affecting all mixes).
+ - CHANGE: Channel c_dig_rx is no longer nullable, assists with timing due to removal of
+ null checks inserted by compiler.
+ - CHANGE: ADAT SMUX selection now based on device sample frequency rather than selected
+ stream format - Endpoint 0 now configures clockgen() on a sample-rate change
+ rather than stream start.
+
6.8.0
-----
- ADDED: Evaluation support for iAP EA Native Transport endpoints
diff --git a/README.rst b/README.rst
index b1c3de00..b69e3079 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
USB Audio Shared
................
-:Latest release: 6.8.0alpha2
+:Latest release: 6.9.0alpha0
:Maintainer: xross
:Description: USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs.
diff --git a/module_usb_audio/audio.h b/module_usb_audio/audio.h
index 38cb7970..bef4d5d5 100644
--- a/module_usb_audio/audio.h
+++ b/module_usb_audio/audio.h
@@ -1,6 +1,7 @@
#ifndef __audio_h__
#define __audio_h__
+#include "devicedefines.h"
/** The audio driver thread.
*
* This function drives I2S ports and handles samples to/from other digital
@@ -13,6 +14,10 @@
* \param c_config An optional channel that will be passed on to the
* CODEC configuration functions.
*/
-void audio(chanend c_in, chanend ?c_dig, chanend ?c_config, chanend ?c_adc);
+void audio(chanend c_in,
+#if (defined(SPDIF_RX) || defined(ADAT_RX))
+ chanend c_dig,
+#endif
+ chanend ?c_config, chanend ?c_adc);
#endif // __audio_h__
diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc
index 755ce13e..eab75996 100755
--- a/module_usb_audio/audio.xc
+++ b/module_usb_audio/audio.xc
@@ -144,7 +144,11 @@ static inline void doI2SClocks(unsigned divide)
/* I2S delivery thread */
#pragma unsafe arrays
-unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq, chanend ?c_dig_rx, chanend ?c_adc)
+unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq,
+#if(defined(SPDIF_RX) || defined(ADAT_RX))
+chanend c_dig_rx,
+#endif
+chanend ?c_adc)
{
#if (I2S_CHANS_ADC != 0) || defined(SPDIF)
unsigned sample;
@@ -461,30 +465,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsi
#endif
}
-#if defined(SPDIF_RX) || defined(ADAT_RX)
- /* Sync with clockgen */
- inuint(c_dig_rx);
-#endif
-#ifdef SPDIF_RX
- asm("ldw %0, dp[g_digData]":"=r"(samplesIn[SPDIF_RX_INDEX + 0]));
- asm("ldw %0, dp[g_digData+4]":"=r"(samplesIn[SPDIF_RX_INDEX + 1]));
-#endif
-#ifdef ADAT_RX
- asm("ldw %0, dp[g_digData+8]":"=r"(samplesIn[ADAT_RX_INDEX + 0]));
- asm("ldw %0, dp[g_digData+12]":"=r"(samplesIn[ADAT_RX_INDEX+ 1]));
- asm("ldw %0, dp[g_digData+16]":"=r"(samplesIn[ADAT_RX_INDEX + 2]));
- asm("ldw %0, dp[g_digData+20]":"=r"(samplesIn[ADAT_RX_INDEX + 3]));
- asm("ldw %0, dp[g_digData+24]":"=r"(samplesIn[ADAT_RX_INDEX + 4]));
- asm("ldw %0, dp[g_digData+28]":"=r"(samplesIn[ADAT_RX_INDEX + 5]));
- asm("ldw %0, dp[g_digData+32]":"=r"(samplesIn[ADAT_RX_INDEX + 6]));
- asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7]));
-#endif
-
-#if defined(SPDIF_RX) || defined(ADAT_RX)
- /* Request digital data (with prefill) */
- outuint(c_dig_rx, 0);
-#endif
tmp = 0;
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
@@ -629,7 +610,30 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsi
#endif
}
#endif
+#if defined(SPDIF_RX) || defined(ADAT_RX)
+ /* Sync with clockgen */
+ inuint(c_dig_rx);
+#endif
+#ifdef SPDIF_RX
+ asm("ldw %0, dp[g_digData]":"=r"(samplesIn[SPDIF_RX_INDEX + 0]));
+ asm("ldw %0, dp[g_digData+4]":"=r"(samplesIn[SPDIF_RX_INDEX + 1]));
+#endif
+#ifdef ADAT_RX
+ asm("ldw %0, dp[g_digData+8]":"=r"(samplesIn[ADAT_RX_INDEX]));
+ asm("ldw %0, dp[g_digData+12]":"=r"(samplesIn[ADAT_RX_INDEX + 1]));
+ asm("ldw %0, dp[g_digData+16]":"=r"(samplesIn[ADAT_RX_INDEX + 2]));
+ asm("ldw %0, dp[g_digData+20]":"=r"(samplesIn[ADAT_RX_INDEX + 3]));
+ asm("ldw %0, dp[g_digData+24]":"=r"(samplesIn[ADAT_RX_INDEX + 4]));
+ asm("ldw %0, dp[g_digData+28]":"=r"(samplesIn[ADAT_RX_INDEX + 5]));
+ asm("ldw %0, dp[g_digData+32]":"=r"(samplesIn[ADAT_RX_INDEX + 6]));
+ asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7]));
+#endif
+
+#if defined(SPDIF_RX) || defined(ADAT_RX)
+ /* Request digital data (with prefill) */
+ outuint(c_dig_rx, 0);
+#endif
#if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0)
outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to S/PDIF Tx thread */
sample = samplesOut[SPDIF_TX_INDEX + 1];
@@ -779,7 +783,11 @@ unsigned static dummy_deliver(chanend c_out)
#define SAMPLES_PER_PRINT 1
-void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
+void audio(chanend c_mix_out,
+#if (defined(ADAT_RX) || defined(SPDIF_RX))
+chanend c_dig_rx,
+#endif
+chanend ?c_config, chanend ?c)
{
#ifdef SPDIF
chan c_spdif_out;
@@ -989,7 +997,11 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
#else
null,
#endif
- divide, curSamFreq, c_dig_rx, c);
+ divide, curSamFreq,
+#if defined (ADAT_RX) || defined (SPDIF_RX)
+ c_dig_rx,
+#endif
+ c);
if(command == SET_SAMPLE_FREQ)
{
diff --git a/module_usb_audio/clocking.h b/module_usb_audio/clocking.h
index b1b85f57..72237236 100644
--- a/module_usb_audio/clocking.h
+++ b/module_usb_audio/clocking.h
@@ -13,6 +13,6 @@
* \param c_clk_int channel connected to the decouple() thread for clock
interrupts
*/
-void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_audio, chanend c_clk_ctl, chanend c_clk_int);
+void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_audio, chanend c_clk_ctl, chanend c_clk_int);
#endif
diff --git a/module_usb_audio/clocking/clockgen.xc b/module_usb_audio/clocking/clockgen.xc
index 4046e328..e7cc288b 100644
--- a/module_usb_audio/clocking/clockgen.xc
+++ b/module_usb_audio/clocking/clockgen.xc
@@ -200,7 +200,7 @@ extern int samples_to_host_inputs_buff[NUM_USB_CHAN_IN];
int VendorAudCoreReqs(unsigned cmd, chanend c);
#pragma unsafe arrays
-void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_dig_rx, chanend c_clk_ctl, chanend c_clk_int)
+void clockGen (streaming chanend ?c_spdif_rx, chanend ?c_adat_rx, out port p, chanend c_dig_rx, chanend c_clk_ctl, chanend c_clk_int)
{
timer t_local;
unsigned timeNextEdge, timeLastEdge, timeNextClockDetection;
@@ -604,16 +604,28 @@ void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, cha
/* only store left samples if not in overflow and stream is reasonably valid */
if (!adatOverflow && clockValid[CLOCK_ADAT_INDEX])
{
- if(smux)
+ /* Unpick the SMUX.. */
+ if(smux == 2)
+ {
+ adatSamples[adatWr + 0] = adatFrame[0];
+ adatSamples[adatWr + 1] = adatFrame[4];
+ adatSamples[adatWr + 2] = adatFrame[1];
+ adatSamples[adatWr + 3] = adatFrame[5];
+ adatSamples[adatWr + 4] = adatFrame[2];
+ adatSamples[adatWr + 5] = adatFrame[6];
+ adatSamples[adatWr + 6] = adatFrame[3];
+ adatSamples[adatWr + 7] = adatFrame[7];
+ }
+ else if(smux)
{
adatSamples[adatWr + 0] = adatFrame[0];
- adatSamples[adatWr + 4] = adatFrame[1];
adatSamples[adatWr + 1] = adatFrame[2];
- adatSamples[adatWr + 5] = adatFrame[3];
adatSamples[adatWr + 2] = adatFrame[4];
- adatSamples[adatWr + 6] = adatFrame[5];
adatSamples[adatWr + 3] = adatFrame[6];
+ adatSamples[adatWr + 4] = adatFrame[1];
+ adatSamples[adatWr + 5] = adatFrame[3];
+ adatSamples[adatWr + 6] = adatFrame[5];
adatSamples[adatWr + 7] = adatFrame[7];
}
else
@@ -741,10 +753,25 @@ void clockGen (streaming chanend c_spdif_rx, chanend ?c_adat_rx, out port p, cha
}
else
{
- /* TODO SMUX II mode */
/* read out samples from the ADAT buffer and send */
/* always return 8 samples */
- if (smux)
+ /* SMUX II mode */
+ if (smux == 2)
+ {
+ /* SMUX2 mode - 2 samples from fifo and 4 zero samples */
+ g_digData[2] = adatSamples[adatRd + 0];
+ g_digData[3] = adatSamples[adatRd + 1];
+
+ g_digData[4] = 0;
+ g_digData[5] = 0;
+ g_digData[6] = 0;
+ g_digData[7] = 0;
+ g_digData[8] = 0;
+ g_digData[9] = 0;
+ adatRd = (adatRd + 2) & (MAX_ADAT_SAMPLES - 1);
+ adatSamps -= 2;
+ }
+ else if(smux)
{
/* SMUX mode - 4 samples from fifo and 4 zero samples */
g_digData[2] = adatSamples[adatRd + 0];
diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h
index 766d7a9c..18dd7fff 100644
--- a/module_usb_audio/devicedefines.h
+++ b/module_usb_audio/devicedefines.h
@@ -263,6 +263,26 @@
#error ADAT_RX_INDEX not defined and ADAT_RX defined
#define ADAT_RX_INDEX (0) /* Default define for doxygen */
#endif
+
+#if (ADAT_RX_INDEX + 8 > NUM_USB_CHAN_IN)
+ #error Not enough channels for ADAT
+#endif
+#endif
+
+#ifdef ADAT_RX
+
+/* Setup input stream formats for ADAT */
+#if(MAX_FREQ > 96000)
+#define INPUT_FORMAT_COUNT 3
+#elif(MAX_FREQ > 48000)
+#define INPUT_FORMAT_COUNT 2
+#else
+#define INPUT_FORMAT_COUNT 1
+#endif
+
+#define HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT NUM_USB_CHAN_IN
+#define HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT (NUM_USB_CHAN_IN - 4)
+#define HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT (NUM_USB_CHAN_IN - 6)
#endif
/**
@@ -386,7 +406,7 @@
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
*/
#ifndef BCD_DEVICE_M
-#define BCD_DEVICE_M 8
+#define BCD_DEVICE_M 9
#endif
/**
@@ -644,22 +664,16 @@
#endif
#endif
+/***** INPUT STREAMS FORMAT ******/
+
/**
* @brief Number of supported input stream formats.
- *
- * Currenly only 1 supported
- *
* Default: 1
*/
#ifndef INPUT_FORMAT_COUNT
#define INPUT_FORMAT_COUNT 1
#endif
-#if (INPUT_FORMAT_COUNT > 1)
- /* Only 1 supported */
- #error
-#endif
-
/**
* @brief Sample resolution (bits) of input stream Alternate 1.
*
@@ -669,16 +683,59 @@
#define STREAM_FORMAT_INPUT_1_RESOLUTION_BITS 24
#endif
+#ifndef STREAM_FORMAT_INPUT_2_RESOLUTION_BITS
+ #define STREAM_FORMAT_INPUT_2_RESOLUTION_BITS 24
+#endif
+
+#ifndef STREAM_FORMAT_INPUT_3_RESOLUTION_BITS
+ #define STREAM_FORMAT_INPUT_3_RESOLUTION_BITS 24
+#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
+#ifndef HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS
+ #define HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS STREAM_FORMAT_INPUT_2_RESOLUTION_BITS
+#endif
+
+#ifndef HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS
+ #define HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS STREAM_FORMAT_INPUT_3_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
+#ifndef FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS
+ #define FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS STREAM_FORMAT_INPUT_2_RESOLUTION_BITS
+#endif
+
+#ifndef FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS
+ #define FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS STREAM_FORMAT_INPUT_3_RESOLUTION_BITS
+#endif
+
+
+/* Channel count defines for input streams */
+#ifndef HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT
+ #define HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT NUM_USB_CHAN_IN
+#endif
+
+#ifndef HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT
+ #define HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT NUM_USB_CHAN_IN
+#endif
+
+#ifndef HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT
+ #define HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT NUM_USB_CHAN_IN
+#endif
+
+
+
/**
* @brief Sample sub-slot size (bytes) of input stream Alternate 1 when running in high-speed
*
@@ -696,6 +753,22 @@
#endif
#endif
+#ifndef HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES
+ #if (HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS == 24)
+ #define HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */
+ #else
+ #define HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES (HS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS/8)
+ #endif
+#endif
+
+#ifndef HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES
+ #if (HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS == 24)
+ #define HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES 4 /* 4 byte subslot is nicer for our 32 bit machine to unpack.. */
+ #else
+ #define HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES (HS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS/8)
+ #endif
+#endif
+
/**
* @brief Sample sub-slot size (bytes) of input stream Alternate 1 when running in full-speed
*
@@ -705,7 +778,15 @@
* Default: STREAM_FORMAT_INPUT_1_RESOLUTION_BITS / 8
*/
#ifndef FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES
- #define FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS/8)
+ #define FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS/8)
+#endif
+
+#ifndef FS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES
+ #define FS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS/8)
+#endif
+
+#ifndef FS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES
+ #define FS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES (FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS/8)
#endif
/**
@@ -717,6 +798,18 @@
#define STREAM_FORMAT_INPUT_1_DATAFORMAT UAC_FORMAT_TYPEI_PCM
#endif
+#ifndef STREAM_FORMAT_INPUT_2_DATAFORMAT
+ #define STREAM_FORMAT_INPUT_2_DATAFORMAT UAC_FORMAT_TYPEI_PCM
+#endif
+
+#ifndef STREAM_FORMAT_INPUT_3_DATAFORMAT
+ #define STREAM_FORMAT_INPUT_3_DATAFORMAT UAC_FORMAT_TYPEI_PCM
+#endif
+
+
+/****** END INPUT STREAMS FORMAT *****/
+
+
/**
* @brief Enable/disable output volume control including all processing and descriptor support
*
diff --git a/module_usb_audio/endpoint0/audiorequests.xc b/module_usb_audio/endpoint0/audiorequests.xc
index 42a8b079..39452110 100644
--- a/module_usb_audio/endpoint0/audiorequests.xc
+++ b/module_usb_audio/endpoint0/audiorequests.xc
@@ -40,7 +40,7 @@ extern unsigned char channelMapAud[NUM_USB_CHAN_OUT];
extern unsigned char channelMapUsb[NUM_USB_CHAN_IN];
/* Mixer input mapping */
-extern unsigned char mixSel[MIX_INPUTS];
+extern unsigned char mixSel[MAX_MIX_COUNT][MIX_INPUTS];
#endif
/* Global var for current frequency, set to default freq */
@@ -320,7 +320,26 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
}
setG_curSamFreqMultiplier(g_curSamFreq/(i_tmp/512));
-
+#ifdef ADAT_RX
+ /* Configure ADAT SMUX based on sample rate */
+ outuint(c_clk_ctl, SET_SMUX);
+ if(g_curSamFreq < 88200)
+ {
+ /* No SMUX */
+ outuint(c_clk_ctl, 0);
+ }
+ else if(g_curSamFreq < 176400)
+ {
+ /* SMUX */
+ outuint(c_clk_ctl, 1);
+ }
+ else
+ {
+ /* SMUX II */
+ outuint(c_clk_ctl, 2);
+ }
+ outct(c_clk_ctl, XS1_CT_END);
+#endif
outuint(c_audioControl, SET_SAMPLE_FREQ);
outuint(c_audioControl, g_curSamFreq);
@@ -687,23 +706,42 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
/* cn bounds check for safety..*/
if(cn < MIX_INPUTS)
{
- if(cs == CS_XU_MIXSEL)
+ //if(cs == CS_XU_MIXSEL)
+ /* cs now contains mix number */
+ if(cs < (MAX_MIX_COUNT + 1))
{
/* Check for "off" - update local state */
if(buffer[0] == 0xFF)
- mixSel[cn] = (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT);
- else
- mixSel[cn] = buffer[0];
-
- /* Update all mix maps */
- for (int i = 0; i < MAX_MIX_COUNT; i++)
{
- outuint(c_mix_ctl, SET_MIX_MAP);
- outuint(c_mix_ctl, i); /* Mix bus */
- outuint(c_mix_ctl, cn); /* Mixer input */
- outuint(c_mix_ctl, (int) mixSel[cn]); /* Source */
- outct(c_mix_ctl, XS1_CT_END);
+ mixSel[cs][cn] = (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT);
}
+ else
+ {
+ mixSel[cs][cn] = buffer[0];
+ }
+
+ if(cs == 0)
+ {
+ /* Update all mix maps */
+ for (int i = 0; i < MAX_MIX_COUNT; i++)
+ {
+ outuint(c_mix_ctl, SET_MIX_MAP);
+ outuint(c_mix_ctl, i); /* Mix bus */
+ outuint(c_mix_ctl, cn); /* Mixer input */
+ outuint(c_mix_ctl, (int) mixSel[cn]); /* Source */
+ outct(c_mix_ctl, XS1_CT_END);
+ }
+ }
+ else
+ {
+ /* Update relevant mix map */
+ outuint(c_mix_ctl, SET_MIX_MAP); /* Command */
+ outuint(c_mix_ctl, (cs-1)); /* Mix bus */
+ outuint(c_mix_ctl, cn); /* Mixer input */
+ outuint(c_mix_ctl, (int) mixSel[cs][cn]); /* Source */
+ outct(c_mix_ctl, XS1_CT_END); /* Wait for handshake back */
+ }
+
return XUD_DoSetRequestStatus(ep0_in);
}
}
@@ -718,9 +756,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c
if(cn < MIX_INPUTS)
{
/* Inspect control selector */
- if(cs == CS_XU_MIXSEL)
+ /* TODO ideally have a return for cs = 0. I.e all mix maps */
+ if((cs > 0) && (cs < (MAX_MIX_COUNT+1)))
{
- buffer[0] = mixSel[cn];
+ buffer[0] = mixSel[cs-1][cn];
return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, 1 );
}
}
diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h
index dd5b38bd..7bf0ee20 100644
--- a/module_usb_audio/endpoint0/descriptors.h
+++ b/module_usb_audio/endpoint0/descriptors.h
@@ -14,7 +14,7 @@
#ifdef IAP_EA_NATIVE_TRANS
/*
- * FIXME currently this will not build if IAP_EA_NATIVE_TRANS_PROTOCOL_NAME is not defined in iap_conf.h,
+ * NOTE, currently this will not build if IAP_EA_NATIVE_TRANS_PROTOCOL_NAME is not defined in iap_conf.h,
* would be nice if a default string was used instead, and a warning issued.
*
* Could get a default define by including the following line, but iap2.h cannot currently be included from C
@@ -1153,21 +1153,55 @@ unsigned char hidReportDescriptor[] =
* 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
+ * TODO Output doesn't get modified by channel count
*/
#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)
#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)
+#if (HS_STEAM_FORMAT_OUPUT_1_MAXPACKETSIZE > 1024) || (HS_STEAM_FORMAT_OUPUT_2_MAXPACKETSIZE > 1024) \
+ || (HS_STEAM_FORMAT_OUPUT_3_MAXPACKETSIZE > 1024)
+#error
+#endif
+
#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)
+/* Input Packet Sizes: high-speed */
+
+#define MAX_PACKET_SIZE_MULT_INPUT_1_HS ((((MAX_FREQ+7999)/8000)+1) * HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT)
+#define MAX_PACKET_SIZE_MULT_INPUT_2_HS ((((MAX_FREQ+7999)/8000)+1) * HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT)
+#define MAX_PACKET_SIZE_MULT_INPUT_3_HS ((((MAX_FREQ+7999)/8000)+1) * HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT)
+
+/* TODO SUBSLOT_BYTES shared */
+#define HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_INPUT_1_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES)
+#define HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_INPUT_1_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES)
+#define HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_INPUT_1_HS * HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES)
+
+#if (HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE > 1024)
+#warning HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE > 1024
+#undef HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE
+#define HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE 1024
+#endif
+
+#if (HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE > 1024)
+#warning HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE > 1024
+#undef HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE
+#define HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE 1024
+#endif
+
+#if (HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE > 1024)
+#warning HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE > 1024
+#undef HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE
+#define HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE 1024
+#endif
+
+/* Input Packet Sizes: full-speed */
+#define MAX_PACKET_SIZE_MULT_IN_FS ((((MAX_FREQ_FS+999)/1000)+1) * NUM_USB_CHAN_IN_FS)
#define FS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE (MAX_PACKET_SIZE_MULT_IN_FS * FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES)
#if (NUM_CLOCKS == 1)
@@ -1268,8 +1302,21 @@ typedef struct
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;
+#if (INPUT_FORMAT_COUNT > 1)
+ USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt2;
+ USB_Descriptor_Audio_Interface_AS_t Audio_In_ClassStreamInterface_2;
+ USB_Descriptor_Audio_Format_Type1_t Audio_In_Format_2;
+ USB_Descriptor_Endpoint_t Audio_In_Endpoint_2;
+ USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_In_ClassEndpoint_2;
+#endif
+#if (INPUT_FORMAT_COUNT > 2)
+ USB_Descriptor_Interface_t Audio_In_StreamInterface_Alt3;
+ USB_Descriptor_Audio_Interface_AS_t Audio_In_ClassStreamInterface_3;
+ USB_Descriptor_Audio_Format_Type1_t Audio_In_Format_3;
+ USB_Descriptor_Endpoint_t Audio_In_Endpoint_3;
+ USB_Descriptor_Audio_Class_AS_Endpoint_t Audio_In_ClassEndpoint_3;
+#endif
#endif
-
#ifdef MIDI
/* MIDI descriptors currently handled as a single block */
unsigned char configDesc_Midi[MIDI_LENGTH];
@@ -2069,70 +2116,69 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
#endif /* OUTPUT_FORMAT_COUNT > 2 */
#endif /* OUTPUT */
#if (NUM_USB_CHAN_IN > 0)
-
/* Zero bandwith alternative 0 */
/* Standard AS Interface Descriptor (4.9.1) */
.Audio_In_StreamInterface_Alt0 =
{
- 0x09, /* 0 bLength: (in bytes, 9) */
- USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */
- INTERFACE_NUMBER_AUDIO_INPUT, /* 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) */
+ .bLength = 0x09,
+ .bDescriptorType = USB_DESCTYPE_INTERFACE,
+ .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING,
+ .bInterfaceProtocol = 0x20,
+ .iInterface = 5, /* (String index) */
},
/* Alternative 1 */
/* Standard AS Interface Descriptor (4.9.1) (Alt) */
.Audio_In_StreamInterface_Alt1 =
{
- 0x09, /* 0 bLength: (in bytes, 9) */
- USB_DESCTYPE_INTERFACE, /* 1 bDescriptorType: INTERFACE */
- INTERFACE_NUMBER_AUDIO_INPUT, /* 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) */
+ .bLength = 0x09,
+ .bDescriptorType = USB_DESCTYPE_INTERFACE,
+ .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT,
+ .bAlternateSetting = 1,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING,
+ .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00,
+ .iInterface = 5, /* (String index) */
},
/* Class Specific AS Interface Descriptor */
.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 */
+ .bLength = 0x10,
+ .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE,
+ .bDescriptorSubType = UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL,
+ .bTerminalLink = ID_OT_USB,
+ .bmControls = 0x00,
+ .bFormatType = 0x01,
+ .bmFormats = UAC_FORMAT_TYPEI_PCM,
+ .bNrChannels = HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT,
+ .bmChannelConfig = 0x00000000,
.iChannelNames = offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *),
},
/* Type 1 Format Type Descriptor */
.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) */
+ .bLength = 6,
+ .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE,
+ .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE,
+ .bFormatType = UAC_FORMAT_TYPE_I,
+ .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* Number of bytes per subslot */
.bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS,
},
/* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
.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) */
+ .bLength = 0x07,
+ .bDescriptorType = USB_DESCTYPE_ENDPOINT,
+ .bEndpointAddress = 0x82,
+ .bmAttributes = 5,
.wMaxPacketSize = HS_STREAM_FORMAT_INPUT_1_MAXPACKETSIZE,
.bInterval = 0x01,
},
@@ -2148,7 +2194,138 @@ USB_Config_Descriptor_Audio2_t cfgDesc_Audio2=
.bLockDelayUnits = 0x02,
.wLockDelay = 0x0008,
},
+#if (INPUT_FORMAT_COUNT > 1)
+ /* Alternative 2 */
+ /* Standard AS Interface Descriptor (4.9.1) (Alt) */
+ .Audio_In_StreamInterface_Alt2 =
+ {
+ .bLength = 0x09,
+ .bDescriptorType = USB_DESCTYPE_INTERFACE,
+ .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT,
+ .bAlternateSetting = 2,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING,
+ .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00,
+ .iInterface = 5, /* (String index) */
+ },
+
+ /* Class Specific AS Interface Descriptor */
+ .Audio_In_ClassStreamInterface_2 =
+ {
+ .bLength = 0x10,
+ .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE,
+ .bDescriptorSubType = UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL,
+ .bTerminalLink = ID_OT_USB,
+ .bmControls = 0x00,
+ .bFormatType = 0x01,
+ .bmFormats = UAC_FORMAT_TYPEI_PCM,
+ .bNrChannels = HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT,
+ .bmChannelConfig = 0x00000000,
+ .iChannelNames = offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *),
+ },
+
+ /* Type 1 Format Type Descriptor */
+ .Audio_In_Format_2 =
+ {
+ .bLength = 6,
+ .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE,
+ .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE,
+ .bFormatType = UAC_FORMAT_TYPE_I,
+ .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* TODO SUBSLOT_BYTES currently shared */
+ .bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, /* TODO RESOLUTION_BITS currently shared */
+ },
+
+ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
+ .Audio_In_Endpoint_2 =
+ {
+ .bLength = 0x07,
+ .bDescriptorType = USB_DESCTYPE_ENDPOINT,
+ .bEndpointAddress = 0x82,
+ .bmAttributes = 5,
+ .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_2_MAXPACKETSIZE,
+ .bInterval = 0x01,
+ },
+
+ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
+ .Audio_In_ClassEndpoint_2 =
+ {
+ .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
+#if (INPUT_FORMAT_COUNT > 2)
+ /* Alternative 3 */
+ /* Standard AS Interface Descriptor (4.9.1) (Alt) */
+ .Audio_In_StreamInterface_Alt3 =
+ {
+ .bLength = 0x09,
+ .bDescriptorType = USB_DESCTYPE_INTERFACE,
+ .bInterfaceNumber = INTERFACE_NUMBER_AUDIO_INPUT,
+ .bAlternateSetting = 3,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_AUDIO,
+ .bInterfaceSubClass = UAC_INT_SUBCLASS_AUDIOSTREAMING,
+ .bInterfaceProtocol = UAC_INT_PROTOCOL_IP_VERSION_02_00,
+ .iInterface = 5, /* (String index) */
+ },
+
+ /* Class Specific AS Interface Descriptor */
+ .Audio_In_ClassStreamInterface_3 =
+ {
+ .bLength = 0x10,
+ .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE,
+ .bDescriptorSubType = UAC_CS_AS_INTERFACE_SUBTYPE_AS_GENERAL,
+ .bTerminalLink = ID_OT_USB,
+ .bmControls = 0x00,
+ .bFormatType = 0x01,
+ .bmFormats = UAC_FORMAT_TYPEI_PCM,
+ .bNrChannels = HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT,
+ .bmChannelConfig = 0x00000000,
+ .iChannelNames = offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *),
+ },
+
+ /* Type 1 Format Type Descriptor */
+ .Audio_In_Format_3 =
+ {
+ .bLength = 6,
+ .bDescriptorType = UAC_CS_DESCTYPE_INTERFACE,
+ .bDescriptorSubtype = UAC_CS_AS_INTERFACE_SUBTYPE_FORMAT_TYPE,
+ .bFormatType = UAC_FORMAT_TYPE_I,
+ .bSubslotSize = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES, /* TODO SUBSLOT_BYTES currently shared */
+ .bBitResolution = HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS, /* TODO RESOLUTION_BITS currently shared */
+ },
+
+ /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */
+ .Audio_In_Endpoint_3 =
+ {
+ .bLength = 0x07,
+ .bDescriptorType = USB_DESCTYPE_ENDPOINT,
+ .bEndpointAddress = 0x82,
+ .bmAttributes = 5,
+ .wMaxPacketSize = HS_STREAM_FORMAT_INPUT_3_MAXPACKETSIZE,
+ .bInterval = 0x01,
+ },
+
+ /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor (4.10.1.2) */
+ .Audio_In_ClassEndpoint_3 =
+ {
+ .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 /* #if(NUM_USB_CHAN_IN > 0) */
#ifdef MIDI
/* MIDI Descriptors */
/* Table B-3: MIDI Adapter Standard AC Interface Descriptor */
diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c
index 016468c0..fd546cad 100755
--- a/module_usb_audio/endpoint0/endpoint0.c
+++ b/module_usb_audio/endpoint0/endpoint0.c
@@ -78,7 +78,7 @@ short mixer1Weights[18*8];
unsigned char channelMap[NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + MAX_MIX_COUNT];
unsigned char channelMapAud[NUM_USB_CHAN_OUT];
unsigned char channelMapUsb[NUM_USB_CHAN_IN];
-unsigned char mixSel[MIX_INPUTS];
+unsigned char mixSel[MAX_MIX_COUNT][MIX_INPUTS];
#endif
int min(int x, int y);
@@ -97,6 +97,8 @@ unsigned g_curStreamAlt_In = 0;
/* Global variable for current USB bus speed (i.e. FS/HS) */
XUD_BusSpeed_t g_curUsbSpeed = 0;
+
+/* Subslot */
const unsigned g_subSlot_Out_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES,
#if(OUTPUT_FORMAT_COUNT > 1)
HS_STREAM_FORMAT_OUTPUT_2_SUBSLOT_BYTES,
@@ -115,10 +117,25 @@ const unsigned g_subSlot_Out_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_OUTP
#endif
};
-const unsigned g_subSlot_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES};
+const unsigned g_subSlot_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES,
+#if(INPUT_FORMAT_COUNT > 1)
+ HS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES,
+#endif
+#if(INPUT_FORMAT_COUNT > 2)
+ HS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES
+#endif
+};
-const unsigned g_subSlot_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES};
+const unsigned g_subSlot_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES,
+#if(INPUT_FORMAT_COUNT > 1)
+ FS_STREAM_FORMAT_INPUT_2_SUBSLOT_BYTES,
+#endif
+#if(INPUT_FORMAT_COUNT > 2)
+ FS_STREAM_FORMAT_INPUT_3_SUBSLOT_BYTES
+#endif
+};
+/* Sample Resolution */
const unsigned g_sampRes_Out_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS,
#if(OUTPUT_FORMAT_COUNT > 1)
HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS,
@@ -137,12 +154,26 @@ const unsigned g_sampRes_Out_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_OUTP
#endif
};
-const unsigned g_sampRes_In_HS[OUTPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS};
+const unsigned g_sampRes_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS,
+#if(INPUT_FORMAT_COUNT > 1)
+ HS_STREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS,
+#endif
+#if(INPUT_FORMAT_COUNT > 2)
+ HS_STREAM_FORMAT_OUTPUT_3_RESOLUTION_BITS
+#endif
+};
-const unsigned g_sampRes_In_FS[OUTPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS};
+const unsigned g_sampRes_In_FS[INPUT_FORMAT_COUNT] = {FS_STREAM_FORMAT_INPUT_1_RESOLUTION_BITS,
+#if(INPUT_FORMAT_COUNT > 1)
+ FS_STREAM_FORMAT_INPUT_2_RESOLUTION_BITS,
+#endif
+#if(INPUT_FORMAT_COUNT > 2)
+ FS_STREAM_FORMAT_INPUT_3_RESOLUTION_BITS
+#endif
+};
+/* Data Format (Note, this is shared over HS and FS */
const unsigned g_dataFormat_Out[OUTPUT_FORMAT_COUNT] = {STREAM_FORMAT_OUTPUT_1_DATAFORMAT,
-
#if(OUTPUT_FORMAT_COUNT > 1)
STREAM_FORMAT_OUTPUT_2_DATAFORMAT,
#endif
@@ -151,7 +182,25 @@ const unsigned g_dataFormat_Out[OUTPUT_FORMAT_COUNT] = {STREAM_FORMAT_OUTPUT_
#endif
};
-const unsigned g_dataFormat_In[INPUT_FORMAT_COUNT] = {STREAM_FORMAT_INPUT_1_DATAFORMAT};
+const unsigned g_dataFormat_In[INPUT_FORMAT_COUNT] = {STREAM_FORMAT_INPUT_1_DATAFORMAT,
+#if(INPUT_FORMAT_COUNT > 1)
+ STREAM_FORMAT_INPUT_2_DATAFORMAT,
+#endif
+#if(INPUT_FORMAT_COUNT > 2)
+ STREAM_FORMAT_INPUT_3_DATAFORMAT
+#endif
+};
+
+/* Channel count */
+/* Note, currently only input changes.. */
+const unsigned g_chanCount_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_INPUT_1_CHAN_COUNT,
+#if(INPUT_FORMAT_COUNT > 1)
+ HS_STREAM_FORMAT_INPUT_2_CHAN_COUNT,
+#endif
+#if(INPUT_FORMAT_COUNT > 2)
+ HS_STREAM_FORMAT_INPUT_3_CHAN_COUNT
+#endif
+};
/* Endpoint 0 function. Handles all requests to the device */
void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
@@ -221,9 +270,10 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
#endif
/* Init mixer inputs */
+ for(int j = 0; j < MAX_MIX_COUNT; j++)
for(int i = 0; i < MIX_INPUTS; i++)
{
- mixSel[i] = i;
+ mixSel[j][i] = i;
}
#endif
@@ -319,7 +369,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
if(g_curUsbSpeed == XUD_SPEED_HS)
{
- outuint(c_audioControl, NUM_USB_CHAN_IN); /* Channel count */
+ outuint(c_audioControl, g_chanCount_In_HS[sp.wValue-1]); /* Channel count */
outuint(c_audioControl, g_subSlot_In_HS[sp.wValue-1]); /* Subslot */
outuint(c_audioControl, g_sampRes_In_HS[sp.wValue-1]); /* Resolution */
}
diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc
index 393cdd6e..32fd88ce 100755
--- a/module_usb_audio/main.xc
+++ b/module_usb_audio/main.xc
@@ -34,9 +34,13 @@
#ifdef SPDIF_RX
#include "SpdifReceive.h"
-#include "clocking.h"
#endif
+#ifdef ADAT_RX
+#include "adatreceiver.h"
+#endif
+
+#include "clocking.h"
/* Audio I/O - Port declarations */
#if I2S_WIRES_DAC > 0
@@ -109,6 +113,7 @@ on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] =
#else
#define CLKBLK_MIDI XS1_CLKBLK_REF;
#endif
+#define CLKBLK_ADAT_RX XS1_CLKBLK_3
#define CLKBLK_SPDIF_TX XS1_CLKBLK_1
#define CLKBLK_SPDIF_RX XS1_CLKBLK_1
#define CLKBLK_MCLK XS1_CLKBLK_2
@@ -130,8 +135,16 @@ on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT;
on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
#endif
+#ifdef ADAT_RX
+on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN;
+#endif
+
#ifdef SPDIF_RX
-on tile[XUD_TILE] : buffered in port:4 p_spdif_rx = PORT_SPDIF_IN; /* K: coax, J: optical */
+on tile[XUD_TILE] : buffered in port:4 p_spdif_rx = PORT_SPDIF_IN;
+#endif
+
+#if defined (SPDIF_RX) || defined (ADAT_RX)
+/* Reference to external clock multiplier */
on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF;
#endif
@@ -158,6 +171,11 @@ on tile[AUDIO_IO_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX;
on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX;
#endif
+#ifdef ADAT_RX
+on tile[XUD_TILE] : clock clk_adat_rx = CLKBLK_ADAT_RX;
+#endif
+
+
on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = CLKBLK_MCLK; /* Master clock */
#if(AUDIO_IO_TILE != XUD_TILE)
@@ -355,7 +373,7 @@ void usb_audio_core(chanend c_mix_out
/* Endpoint 0 Core */
{
thread_speed();
- Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, null, c_EANativeTransport_ctrl);
+ Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl);
}
/* Decoupling core */
@@ -377,6 +395,7 @@ chanend c_mix_ctl,
#endif
chanend ?c_aud_cfg,
streaming chanend ?c_spdif_rx,
+chanend ?c_adat_rx,
chanend ?c_clk_ctl,
chanend ?c_clk_int
)
@@ -404,17 +423,25 @@ chanend ?c_clk_int
{
thread_speed();
#ifdef MIXER
- audio(c_mix_out, c_dig_rx, c_aud_cfg, c_adc);
+ audio(c_mix_out,
+#if defined(SPDIF_RX) || defined(ADAT_RX)
+ c_dig_rx,
+#endif
+ c_aud_cfg, c_adc);
#else
- audio(c_aud_in, c_dig_rx, c_aud_cfg, c_adc);
+ audio(c_aud_in,
+#if defined(SPDIF_RX) || defined(ADAT_RX)
+ c_dig_rx,
+#endif
+ c_aud_cfg, c_adc);
#endif
}
-#ifdef SPDIF_RX
+#if defined(SPDIF_RX) || defined(ADAT_RX)
{
thread_speed();
- clockGen(c_spdif_rx, null, p_pll_clk, c_dig_rx, c_clk_ctl, c_clk_int);
+ clockGen(c_spdif_rx, c_adat_rx, p_pll_clk, c_dig_rx, c_clk_ctl, c_clk_int);
}
#endif
@@ -462,12 +489,22 @@ int main()
#ifdef SPDIF_RX
streaming chan c_spdif_rx;
+#else
+#define c_spdif_rx null
+#endif
+
+#ifdef ADAT_RX
+ chan c_adat_rx;
+#else
+#define c_adat_rx null
+#endif
+
+#if (defined (SPDIF_RX) || defined (ADAT_RX))
chan c_clk_ctl;
chan c_clk_int;
#else
#define c_clk_int null
#define c_clk_ctl null
-#define c_spdif_rx null
#endif
USER_MAIN_DECLARATIONS
@@ -494,7 +531,7 @@ int main()
#ifdef MIXER
, c_mix_ctl
#endif
- ,c_aud_cfg, c_spdif_rx, c_clk_ctl, c_clk_int
+ ,c_aud_cfg, c_spdif_rx, c_adat_rx, c_clk_ctl, c_clk_int
);
#if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE)
@@ -529,6 +566,20 @@ int main()
SpdifReceive(p_spdif_rx, c_spdif_rx, 1, clk_spd_rx);
}
#endif
+
+#ifdef ADAT_RX
+ on stdcore[0] :
+ {
+ set_thread_fast_mode_on();
+ set_port_clock(p_adat_rx, clk_adat_rx);
+ start_clock(clk_adat_rx);
+ while (1)
+ {
+ adatReceiver48000(p_adat_rx, c_adat_rx);
+ adatReceiver44100(p_adat_rx, c_adat_rx);
+ }
+ }
+#endif
USER_MAIN_CORES
}
diff --git a/module_usb_audio/usb_buffer/decouple.xc b/module_usb_audio/usb_buffer/decouple.xc
index 5a44a290..edb985e0 100644
--- a/module_usb_audio/usb_buffer/decouple.xc
+++ b/module_usb_audio/usb_buffer/decouple.xc
@@ -576,20 +576,23 @@ static inline void SetupZerosSendBuffer(XUD_ep aud_to_host_usb_ep, unsigned samp
GetADCCounts(sampFreq, min, mid, max);
// TODO, don't need to use speed.
- if (usb_speed == XUD_SPEED_HS)
- {
- mid *= NUM_USB_CHAN_IN * slotSize;
- }
- else
- {
- mid *= NUM_USB_CHAN_IN_FS * slotSize;
- }
+ //if (usb_speed == XUD_SPEED_HS)
+ //{
+ // mid *= NUM_USB_CHAN_IN * slotSize;
+ // }
+ //else
+ //{
+ // mid *= NUM_USB_CHAN_IN_FS * slotSize;
+ //}
+
+ mid *= g_numUsbChan_In * slotSize;
asm("stw %0, %1[0]"::"r"(mid),"r"(g_aud_to_host_zeros));
/* Mark EP ready with the zero buffer. Note this will simply update the packet size
* if it is already ready */
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
+
XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, mid);
}
@@ -962,7 +965,6 @@ void decouple(chanend c_mix_out
{
SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros);
}
-
}
else
{
diff --git a/module_usb_audio_adat/.cproject b/module_usb_audio_adat/.cproject
index 252164f5..e72d2d69 100644
--- a/module_usb_audio_adat/.cproject
+++ b/module_usb_audio_adat/.cproject
@@ -156,7 +156,8 @@
@@ -269,7 +270,8 @@
@@ -388,7 +390,8 @@
-
+
+
diff --git a/module_usb_audio_adat/README b/module_usb_audio_adat/README
deleted file mode 100644
index 0035e6b2..00000000
--- a/module_usb_audio_adat/README
+++ /dev/null
@@ -1,2 +0,0 @@
-MODULE_ADAT_RX_V3
-
diff --git a/xpd.xml b/xpd.xml
index 5099f87f..3657cbb3 100644
--- a/xpd.xml
+++ b/xpd.xml
@@ -74,7 +74,8 @@
-
+
+
XM-004720-SM
XMOS