Merge branch 'master' into DEV_IMP_FB

This commit is contained in:
Ross Owen
2015-08-25 11:32:25 +01:00
42 changed files with 3938 additions and 3365 deletions

View File

@@ -43,7 +43,7 @@
</outputEntries>
</builder>
<tool id = "com.xmos.cdt.xc.compiler.55196333" name="com.xmos.cdt.xc.compiler" superClass="com.xmos.cdt.xc.compiler">
<option id = "com.xmos.c.compiler.option.defined.symbols.36159420" name="com.xmos.c.compiler.option.defined.symbols" superClass="com.xmos.c.compiler.option.defined.symbols" valueType="definedSymbols">
<option id = "com.xmos.xc.compiler.option.defined.symbols.36159420" name="com.xmos.xc.compiler.option.defined.symbols" superClass="com.xmos.xc.compiler.option.defined.symbols" valueType="definedSymbols">
<listOptionValue builtIn="false" value="__SHRT_MAX__=32767"/>
<listOptionValue builtIn="false" value="__SCHAR_MAX__=127"/>
<listOptionValue builtIn="false" value="__SIZE_TYPE__=unsigned"/>

View File

@@ -2,6 +2,7 @@
#define __audio_h__
#include "devicedefines.h"
#include "dfu_interface.h"
/** The audio driver thread.
*
* This function drives I2S ports and handles samples to/from other digital
@@ -15,9 +16,18 @@
* CODEC configuration functions.
*/
void audio(chanend c_in,
#if (defined(SPDIF_RX) || defined(ADAT_RX))
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
chanend c_spdif_tx,
#endif
#if(defined(SPDIF_RX) || defined(ADAT_RX))
chanend c_dig,
#endif
chanend ?c_config, chanend ?c_adc);
chanend ?c_config, chanend ?c_adc
#if (XUD_TILE != 0)
, server interface i_dfu dfuInterface
#endif
);
void SpdifTxWrapper(chanend c_spdif_tx);
#endif // __audio_h__

View File

@@ -14,14 +14,25 @@
#include <xs1_su.h>
#include "devicedefines.h"
#include "dfu_interface.h"
#include "audioports.h"
#include "audiohw.h"
#ifdef SPDIF
#ifdef SPDIF_TX
#include "SpdifTransmit.h"
#endif
#ifdef ADAT_TX
#include "adat_tx.h"
#ifndef ADAT_TX_USE_SHARED_BUFF
#error Designed for ADAT tx shared buffer mode ONLY
#endif
#endif
#include "commands.h"
#include "xc_ptr.h"
#include "print.h"
static unsigned samplesOut[NUM_USB_CHAN_OUT];
@@ -71,11 +82,16 @@ unsigned dsdMode = DSD_MODE_OFF;
/* Master clock input */
extern port p_mclk_in;
extern in port p_mclk_in2;
#ifdef SPDIF
#ifdef SPDIF_TX
extern buffered out port:32 p_spdif_tx;
#endif
#ifdef ADAT_TX
extern buffered out port:32 p_adat_tx;
#endif
extern clock clk_audio_mclk;
extern clock clk_audio_bclk;
extern clock clk_mst_spd;
@@ -153,113 +169,152 @@ static inline void doI2SClocks(unsigned divide)
}
#endif
#ifdef ADAT_TX
unsigned adatCounter = 0;
unsigned adatSamples[8];
#pragma unsafe arrays
static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samplesFromHost[], int smux, int handshake)
{
/* Do some re-arranging for SMUX.. */
unsafe
{
unsigned * unsafe samplesFromHostAdat = &samplesFromHost[ADAT_TX_INDEX];
/* Note, when smux == 1 this loop just does a straight 1:1 copy */
//if(smux != 1)
{
int adatSampleIndex = adatCounter;
for(int i = 0; i < (8/smux); i++)
{
adatSamples[adatSampleIndex] = samplesFromHostAdat[i];
adatSampleIndex += smux;
}
}
}
adatCounter++;
if(adatCounter == smux)
{
#ifdef ADAT_TX_USE_SHARED_BUFF
unsafe
{
/* Wait for ADAT core to be done with buffer */
/* Note, we are "running ahead" of the ADAT core */
inuint(c_adat_out);
/* Send buffer pointer over to ADAT core */
volatile unsigned * unsafe samplePtr = &adatSamples;
outuint(c_adat_out, (unsigned) samplePtr);
}
#else
#pragma loop unroll
for (int i = 0; i < 8; i++)
{
outuint(c_adat_out, samplesFromHost[ADAT_TX_INDEX + i]);
}
#endif
adatCounter = 0;
}
}
#endif
#pragma unsafe arrays
static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned underflowWord)
{
unsigned command;
unsigned underflow;
outuint(c_out, underflowWord);
outuint(c_out, 0);
/* Check for sample freq change (or other command) or new samples from mixer*/
if(testct(c_out))
{
unsigned command = inct(c_out);
/* Check for sample freq change (or other command) or new samples from mixer*/
if(testct(c_out))
{
unsigned command = inct(c_out);
#ifndef CODEC_MASTER
if(dsdMode == DSD_MODE_OFF)
{
// Set clocks low
p_lrclk <: 0;
p_bclk <: 0;
}
else
{
#if(DSD_CHANS_DAC != 0)
/* DSD Clock might not be shared with lrclk or bclk... */
p_dsd_clk <: 0;
#endif
}
#endif
#if (DSD_CHANS_DAC > 0)
if(dsdMode == DSD_MODE_DOP)
dsdMode = DSD_MODE_OFF;
if(dsdMode == DSD_MODE_DOP)
dsdMode = DSD_MODE_OFF;
#endif
#pragma xta endpoint "received_command"
return command;
}
else
{
underflow = inuint(c_out);
}
else
{
#ifndef MIXER // Interfaces straight to decouple()
inuint(c_out);
#if NUM_USB_CHAN_IN > 0
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, samplesIn_0[i]);
}
#endif
#if NUM_USB_CHAN_OUT > 0
if(underflow)
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = underflowWord;
}
}
else
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = inuint(c_out);
}
}
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = inuint(c_out);
}
#endif
#else /* ifndef MIXER */
#if NUM_USB_CHAN_OUT > 0
if(underflow)
{
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
samplesOut[i] = underflowWord;
}
}
else
{
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
int tmp = inuint(c_out);
samplesOut[i] = tmp;
}
}
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
int tmp = inuint(c_out);
samplesOut[i] = tmp;
}
#endif
#if NUM_USB_CHAN_IN > 0
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i++)
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
#if NUM_USB_CHAN_IN < I2S_CHANS_ADC
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
#else
for(int i = 0; i < I2S_CHANS_ADC; i++)
#endif
{
if(readBuffNo)
outuint(c_out, samplesIn_1[i]);
else
outuint(c_out, samplesIn_0[i]);
}
#endif
#endif
}
/* Send over the digi channels - no odd buffering required */
#pragma loop unroll
for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, samplesIn_0[i]);
}
#endif
#endif
}
return 0;
return 0;
}
@@ -271,9 +326,14 @@ static inline void InitPorts(unsigned divide)
if(dsdMode == DSD_MODE_OFF)
{
#endif
/* b_clk must start high */
if(divide != 1)
{
/* b_clk must start high */
p_bclk <: 0x80000000;
sync(p_bclk);
}
/* Clear I2S port buffers */
clearbuf(p_lrclk);
@@ -307,7 +367,6 @@ static inline void InitPorts(unsigned divide)
p_lrclk @ tmp <: 0x7FFFFFFF;
#if (I2S_CHANS_ADC != 0)
for(int i = 0; i < I2S_WIRES_ADC; i++)
{
@@ -317,6 +376,8 @@ static inline void InitPorts(unsigned divide)
}
else /* Divide != 1 */
{
#if (I2S_CHANS_DAC != 0)
/* Pre-fill the DAC ports */
for(int i = 0; i < I2S_WIRES_DAC; i++)
@@ -329,6 +390,17 @@ static inline void InitPorts(unsigned divide)
doI2SClocks(divide);
#if (I2S_CHANS_DAC != 0)
/* Pre-fill the DAC ports */
for(int i = 0; i < I2S_WIRES_DAC; i++)
{
p_i2s_dac[i] <: 0;
}
#endif
/* Pre-fill the LR clock output port */
p_lrclk <: 0x0;
doI2SClocks(divide);
}
#if (DSD_CHANS_DAC > 0)
} /* if (!dsdMode) */
@@ -350,8 +422,8 @@ static inline void InitPorts(unsigned divide)
p_lrclk when pinseq(1) :> void @ tmp;
#else
p_lrclk when pinseq(0) :> void @ tmp;
#endif
#endif
tmp += (I2S_CHANS_PER_FRAME * 32) - 32 + 1 ;
/* E.g. 2 * 32 - 32 + 1 = 33 for stereo */
/* E..g 8 * 32 - 32 + 1 = 225 for 8 chan TDM */
@@ -378,23 +450,25 @@ static inline void InitPorts(unsigned divide)
/* I2S delivery thread */
#pragma unsafe arrays
unsigned static deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, unsigned curSamFreq,
unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#ifdef ADAT_TX
chanend c_adat_out,
unsigned adatSmuxMode,
#endif
unsigned divide, unsigned curSamFreq,
#if(defined(SPDIF_RX) || defined(ADAT_RX))
chanend c_dig_rx,
chanend c_dig_rx,
#endif
chanend ?c_adc)
chanend ?c_adc)
{
#if (I2S_CHANS_ADC != 0) || defined(SPDIF)
#if (I2S_CHANS_ADC != 0) || defined(SPDIF_TX)
unsigned sample;
#endif
unsigned underflow = 0;
#if NUM_USB_CHAN_OUT > 0
#endif
//#if NUM_USB_CHAN_IN > 0
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
unsigned readBuffNo = 0;
//#endif
unsigned tmp;
unsigned index;
#ifdef RAMP_CHECK
@@ -412,6 +486,9 @@ chanend ?c_adc)
unsigned underflowWord = 0;
unsigned frameCount = 0;
#ifdef ADAT_TX
adatCounter = 0;
#endif
#if(DSD_CHANS_DAC != 0)
if(dsdMode == DSD_MODE_DOP)
@@ -424,14 +501,18 @@ chanend ?c_adc)
}
#endif
#if 1
unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord);
#ifdef ADAT_TX
unsafe{
//TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 0);
volatile unsigned * unsafe samplePtr = &samplesOut[ADAT_TX_INDEX];
outuint(c_adat_out, (unsigned) samplePtr);
}
#endif
if(command)
{
return command;
}
#endif
InitPorts(divide);
@@ -549,6 +630,31 @@ chanend ?c_adc)
else
#endif
{
#if (I2S_CHANS_ADC != 0)
/* Input previous L sample into L in buffer */
index = 0;
/* First input (i.e. frameCount == 0) we read last ADC channel of previous frame.. */
unsigned buffIndex = (frameCount < 3) ? !readBuffNo : readBuffNo;
#pragma loop unroll
/* First time around we get channel 7 of TDM8 */
for(int i = 0; i < I2S_CHANS_ADC; i+=I2S_CHANS_PER_FRAME)
{
// p_i2s_adc[index++] :> sample;
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
/* Note the use of readBuffNo changes based on frameCount */
if(buffIndex)
samplesIn_1[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line.
else
samplesIn_0[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample);
}
#endif
#ifndef CODEC_MASTER
/* LR clock delayed by one clock, This is so MSB is output on the falling edge of BCLK
* after the falling edge on which LRCLK was toggled. (see I2S spec) */
@@ -578,26 +684,8 @@ chanend ?c_adc)
doI2SClocks(divide);
#endif
#if (I2S_CHANS_ADC != 0)
/* Input previous L sample into L in buffer */
index = 0;
/* First input (i.e. frameCoint == 0) we read last ADC channel of previous frame.. */
unsigned buffIndex = frameCount ? !readBuffNo : readBuffNo;
#pragma loop unroll
/* First time around we get channel 7 of TDM8 */
for(int i = 0; i < I2S_CHANS_ADC; i+=I2S_CHANS_PER_FRAME)
{
// p_i2s_adc[index++] :> sample;
// Manual IN instruction since compiler generates an extra setc per IN (bug #15256)
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
/* Note the use of readBuffNo changes based on frameCount */
if(buffIndex)
samplesIn_1[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
else
samplesIn_0[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
}
#ifdef ADAT_TX
TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 1);
#endif
if(frameCount == 0)
@@ -629,13 +717,39 @@ chanend ?c_adc)
/* Request digital data (with prefill) */
outuint(c_dig_rx, 0);
#endif
#if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0)
#if defined(SPDIF_TX) && (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];
outuint(c_spd_out, sample); /* Forward sample to S/PDIF Tx thread */
#endif
}
#if (I2S_CHANS_ADC != 0)
index = 0;
/* Channels 0, 2, 4.. on each line */
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i += I2S_CHANS_PER_FRAME)
{
/* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
if(buffIndex)
samplesIn_1[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
else
samplesIn_0[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
}
#ifdef SU1_ADC_ENABLE
{
unsigned x;
x = inuint(c_adc);
inct(c_adc);
asm volatile("stw %0, dp[g_adcVal]"::"r"(x));
}
#endif
#endif
#ifndef CODEC_MASTER
#ifdef I2S_MODE_TDM
if(frameCount == (I2S_CHANS_PER_FRAME-2))
@@ -662,29 +776,7 @@ chanend ?c_adc)
doI2SClocks(divide);
#endif
#if (I2S_CHANS_ADC != 0)
index = 0;
/* Channels 0, 2, 4.. on each line */
#pragma loop unroll
for(int i = 0; i < I2S_CHANS_ADC; i += I2S_CHANS_PER_FRAME)
{
/* Manual IN instruction since compiler generates an extra setc per IN (bug #15256) */
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
if(readBuffNo)
samplesIn_0[frameCount+i] = bitrev(sample);
else
samplesIn_1[frameCount+i] = bitrev(sample);
}
#ifdef SU1_ADC_ENABLE
{
unsigned x;
x = inuint(c_adc);
inct(c_adc);
asm volatile("stw %0, dp[g_adcVal]"::"r"(x));
}
#endif
#endif
} // !dsdMode
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
@@ -763,51 +855,92 @@ chanend ?c_adc)
return 0;
}
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
void SpdifTxWrapper(chanend c_spdif_tx)
{
unsigned portId;
//configure_clock_src(clk, p_mclk);
// TODO could share clock block here..
// NOTE, Assuming SPDIF tile == USB tile here..
asm("ldw %0, dp[p_mclk_in2]":"=r"(portId));
asm("setclk res[%0], %1"::"r"(clk_mst_spd), "r"(portId));
configure_out_port_no_ready(p_spdif_tx, clk_mst_spd, 0);
set_clock_fall_delay(clk_mst_spd, 7);
start_clock(clk_mst_spd);
while(1)
{
SpdifTransmit(p_spdif_tx, c_spdif_tx);
}
}
#endif
/* This function is a dummy version of the deliver thread that does not
connect to the codec ports. It is used during DFU reset. */
unsigned static dummy_deliver(chanend c_out)
[[distributable]]
void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd);
#pragma select handler
void testct_byref(chanend c, int &returnVal)
{
returnVal = 0;
if(testct(c))
returnVal = 1;
}
[[combinable]]
static void dummy_deliver(chanend c_out, unsigned &command)
{
int ct;
while (1)
{
outuint(c_out, 0);
/* Check for sample freq change or new samples from mixer*/
if(testct(c_out))
{
unsigned command = inct(c_out);
return command;
}
else
select
{
/* Check for sample freq change or new samples from mixer*/
case testct_byref(c_out, ct):
if(ct)
{
unsigned command = inct(c_out);
return;
}
else
{
#ifndef MIXER // Interfaces straight to decouple()
(void) inuint(c_out);
(void) inuint(c_out);
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, 0);
}
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, 0);
}
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
(void) inuint(c_out);
}
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
(void) inuint(c_out);
}
#else
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
(void) inuint(c_out);
}
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
(void) inuint(c_out);
}
#pragma loop unroll
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, 0);
}
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
{
outuint(c_out, 0);
}
#endif
}
outuint(c_out, 0);
break;
}
}
return 0;
}
#define SAMPLE_RATE 200000
#define NUMBER_CHANNELS 1
@@ -816,14 +949,27 @@ unsigned static dummy_deliver(chanend c_out)
#define SAMPLES_PER_PRINT 1
void audio(chanend c_mix_out,
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
chanend c_spdif_out,
#endif
#if (defined(ADAT_RX) || defined(SPDIF_RX))
chanend c_dig_rx,
#endif
chanend ?c_config, chanend ?c)
chanend ?c_config, chanend ?c
#if XUD_TILE != 0
, server interface i_dfu dfuInterface
#endif
)
{
#ifdef SPDIF
#if defined (SPDIF_TX) && (SPDIF_TX_TILE == AUDIO_IO_TILE)
chan c_spdif_out;
#endif
#ifdef ADAT_TX
chan c_adat_out;
unsigned adatSmuxMode = 0;
unsigned adatMultiple = 0;
#endif
unsigned curSamFreq = DEFAULT_FREQ;
unsigned curSamRes_DAC = STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; /* Default to something reasonable */
unsigned curSamRes_ADC = STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; /* Default to something reasonable - note, currently this never changes*/
@@ -878,8 +1024,17 @@ chanend ?c_config, chanend ?c)
EnableBufferedPort(p_dsd_dac[i], 32);
}
#endif
#ifdef SPDIF
#ifdef ADAT_TX
/* Share SPDIF clk blk */
configure_clock_src(clk_mst_spd, p_mclk_in);
configure_out_port_no_ready(p_adat_tx, clk_mst_spd, 0);
set_clock_fall_delay(clk_mst_spd, 7);
#ifndef SPDIF
start_clock(clk_mst_spd);
#endif
#endif
/* Configure ADAT/SPDIF tx ports */
#if defined(SPDIF_TX) && (SPDIF_TX_TILE == AUDIO_IO_TILE)
SpdifTransmitPortConfig(p_spdif_tx, clk_mst_spd, p_mclk_in);
#endif
@@ -892,10 +1047,20 @@ chanend ?c_config, chanend ?c)
if ((MCLK_441 % curSamFreq) == 0)
{
mClk = MCLK_441;
#ifdef ADAT_TX
/* Calculate ADAT SMUX mode (1, 2, 4) */
adatSmuxMode = curSamFreq / 44100;
adatMultiple = mClk / 44100;
#endif
}
else if ((MCLK_48 % curSamFreq) == 0)
{
mClk = MCLK_48;
#ifdef ADAT_TX
/* Calculate ADAT SMUX mode (1, 2, 4) */
adatSmuxMode = curSamFreq / 48000;
adatMultiple = mClk / 48000;
#endif
}
/* Calculate master clock to bit clock (or DSD clock) divide for current sample freq
@@ -1011,30 +1176,51 @@ chanend ?c_config, chanend ?c)
}
firstRun = 0;
par
{
#ifdef SPDIF
#if defined(SPDIF_TX) && (SPDIF_TX_TILE == AUDIO_IO_TILE)
{
set_thread_fast_mode_on();
SpdifTransmit(p_spdif_tx, c_spdif_out);
}
#endif
#ifdef ADAT_TX
{
#ifdef SPDIF
set_thread_fast_mode_on();
adat_tx_port(c_adat_out, p_adat_tx);
}
#endif
{
#ifdef SPDIF_TX
/* Communicate master clock and sample freq to S/PDIF thread */
outuint(c_spdif_out, curSamFreq);
outuint(c_spdif_out, mClk);
#endif
#ifdef ADAT_TX
// Configure ADAT parameters ...
//
// adat_oversampling = 256 for MCLK = 12M288 or 11M2896
// = 512 for MCLK = 24M576 or 22M5792
// = 1024 for MCLK = 49M152 or 45M1584
//
// adatSmuxMode = 1 for FS = 44K1 or 48K0
// = 2 for FS = 88K2 or 96K0
// = 4 for FS = 176K4 or 192K0
outuint(c_adat_out, adatMultiple);
outuint(c_adat_out, adatSmuxMode);
#endif
command = deliver(c_mix_out,
#ifdef SPDIF
#ifdef SPDIF_TX
c_spdif_out,
#else
null,
#endif
#ifdef ADAT_TX
c_adat_out,
adatSmuxMode,
#endif
divide, curSamFreq,
#if defined (ADAT_RX) || defined (SPDIF_RX)
@@ -1061,10 +1247,20 @@ chanend ?c_config, chanend ?c)
{
outct(c_mix_out, XS1_CT_END);
outuint(c_mix_out, 0);
while (1)
{
command = dummy_deliver(c_mix_out);
#if XUD_TILE != 0
[[combine]]
par
{
DFUHandler(dfuInterface, null);
dummy_deliver(c_mix_out, command);
}
#else
dummy_deliver(c_mix_out, command);
#endif
curSamFreq = inuint(c_mix_out);
if (curSamFreq == AUDIO_START_FROM_DFU)
@@ -1074,10 +1270,17 @@ chanend ?c_config, chanend ?c)
}
}
}
#ifdef SPDIF
#ifdef SPDIF_TX
/* Notify S/PDIF thread of impending new freq... */
outct(c_spdif_out, XS1_CT_END);
#endif
#ifdef ADAT_TX
#ifdef ADAT_TX_USE_SHARED_BUFF
/* Take out-standing handshake from ADAT core */
inuint(c_adat_out);
#endif
/* Notify ADAT Tx thread of impending new freq... */
outct(c_adat_out, XS1_CT_END);
#endif
}
}

View File

@@ -38,6 +38,13 @@
#define MIDI_TILE AUDIO_IO_TILE
#endif
/**
* @brief Location (tile) of SPDIF Tx. Default: AUDIO_IO_TILE
*/
#ifndef SPDIF_TX_TILE
#define SPDIF_TX_TILE AUDIO_IO_TILE
#endif
/**
* @brief Number of input channels (device to host). Default: NONE (Must be defined by app)
*/
@@ -67,6 +74,21 @@
#define DSD_CHANS_DAC 0
#endif
/**
* @brief Channels per I2S frame. *
*
* Default: 2 i.e standard stereo I2S (8 if using TDM i.e. I2S_MODE_TDM).
*
**/
#ifndef I2S_CHANS_PER_FRAME
#ifdef I2S_MODE_TDM
#define I2S_CHANS_PER_FRAME 8
#else
#define I2S_CHANS_PER_FRAME 2
#endif
#endif
/**
* @brief Number of IS2 channesl to DAC/CODEC. Must be a multiple of 2.
*
@@ -76,13 +98,9 @@
#error I2S_CHANS_DAC not defined
#define I2S_CHANS_DAC 2 /* Define anyway for doxygen */
#else
#define I2S_WIRES_DAC (I2S_CHANS_DAC / I2S_CHANS_PER_FRAME)
#endif
#ifdef I2S_MODE_TDM
#define I2S_WIRES_DAC (I2S_CHANS_DAC >> 3)
#else
#define I2S_WIRES_DAC (I2S_CHANS_DAC >> 1)
#endif
#endif
/**
* @brief Number of I2S channels from ADC/CODEC. Must be a multiple of 2.
@@ -93,27 +111,9 @@
#error I2S_CHANS_ADC not defined
#define I2S_CHANS_ADC 2 /* Define anyway for doxygen */
#else
#ifdef I2S_MODE_TDM
#define I2S_WIRES_ADC (I2S_CHANS_ADC >> 3)
#else
#define I2S_WIRES_ADC (I2S_CHANS_ADC >> 1)
#endif
#define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME)
#endif
/**
* @brief Channels per I2S frame. *
*
* Default: 2 i.e standard stereo I2S (8 if using TDM i.e. I2S_MODE_TDM).
*
**/
#ifndef I2S_CHANS_PER_FRAME
#ifdef I2S_MODE_TDM
#define I2S_CHANS_PER_FRAME 8
#else
#define I2S_CHANS_PER_FRAME 2
#endif
#endif
/**
* @brief Max supported sample frequency for device (Hz). Default: 192000
@@ -222,13 +222,13 @@
/**
* @brief Enables SPDIF Tx. Default: 0 (Disabled)
*/
#ifndef SPDIF
#define SPDIF (0)
#ifndef SPDIF_TX
#define SPDIF_TX (0)
#endif
/* Tidy up old SPDIF usage */
#if defined(SPDIF) && (SPDIF == 0)
#undef SPDIF
#if defined(SPDIF_TX) && (SPDIF_TX == 0)
#undef SPDIF_TX
#endif
/**
@@ -237,7 +237,28 @@
* Default: 0 (i.e. channels 0 & 1)
* */
#ifndef SPDIF_TX_INDEX
#define SPDIF_TX_INDEX (0)
#define SPDIF_TX_INDEX (0)
#endif
/**
* @brief Enables ADAT Tx. Default: 0 (Disabled)
*/
#ifndef ADAT_TX
#define ADAT_TX (0)
#endif
/* Tidy up old SPDIF usage */
#if defined(ADAT_TX) && (ADAT_TX == 0)
#undef ADAT_TX
#endif
/**
* @brief Defines which output channels (8) should be output on ADAT. Note, Output channels indexed from 0.
*
* Default: 0 (i.e. channels [0:7])
* */
#ifndef ADAT_TX_INDEX
#define ADAT_TX_INDEX (0)
#endif
/**
@@ -430,14 +451,14 @@
* @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 11
#define BCD_DEVICE_M 12
#endif
/**
* @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number.
*/
#ifndef BCD_DEVICE_N
#define BCD_DEVICE_N 0
#define BCD_DEVICE_N 5
#endif
/**
@@ -447,8 +468,9 @@
*
* Default: XMOS USB Audio Release version (e.g. 0x0651 for 6.5.1).
*/
#ifndef BCD_DEVICE
#define BCD_DEVICE ((BCD_DEVICE_J << 8) | ((BCD_DEVICE_M & 0xF) << 4) | (BCD_DEVICE_N & 0xF))
#endif
/**
* @brief Number of supported output stream formats.
@@ -917,10 +939,12 @@
*/
#ifdef MIXER
#ifndef MAX_MIX_COUNT
#define MAX_MIX_COUNT (8)
#define MAX_MIX_COUNT (8)
#endif
#else
#define MAX_MIX_COUNT (0)
#ifndef MAX_MIX_COUNT
#define MAX_MIX_COUNT (0)
#endif
#endif
/**
@@ -931,7 +955,7 @@
* Default: 18
*/
#ifndef MIX_INPUTS
#define MIX_INPUTS (18)
#define MIX_INPUTS (18)
#endif
/* Volume processing defines */

View File

@@ -0,0 +1,56 @@
def genstrings(outputChanCount, chanString, portString, structureString, adc_dac):
for i in range(1,outputChanCount):
print "#if (NUM_USB_CHAN_{c} > {i}-1)\n\
.{s}ChanStr_{i} = \"\"\n\
#if ({i} < I2S_CHANS_{adcdac}+1)\n\
\"Analogue {i}\"\n\
#endif\n\
#if (({i} < SPDIF_{p}_INDEX+2+1) && ({i} > SPDIF_{p}_INDEX)) && defined(SPDIF_{p})\n\
#if ({i} < I2S_CHANS_{adcdac}+1)\n\
\"/\"\n\
#endif\n\
#if({i} - SPDIF_{p}_INDEX == 1)\n\
\"SPDIF 1\"\n\
#elif({i} - SPDIF_{p}_INDEX == 2)\n\
\"SPDIF 2\"\n\
#endif\n\
#endif\n\
#if (({i} < ADAT_{p}_INDEX+8+1) && ({i} > ADAT_{p}_INDEX)) && defined(ADAT_{p})\n\
#if (({i} < SPDIF_{p}_INDEX+2+1) && ({i} > SPDIF_{p}_INDEX)) && defined(SPDIF_{p}) || ({i} < I2S_CHANS_{adcdac}+1)\n\
\"/\"\n\
#endif\n\
#if({i} - ADAT_TX_INDEX == 1)\n\
\"ADAT 1\"\n\
#elif({i} - ADAT_TX_INDEX == 2)\n\
\"ADAT 2\"\n\
#elif({i} - ADAT_TX_INDEX == 3)\n\
\"ADAT 3\"\n\
#elif({i} - ADAT_TX_INDEX == 4)\n\
\"ADAT 4\"\n\
#elif({i} - ADAT_TX_INDEX == 5)\n\
\"ADAT 5\"\n\
#elif({i} - ADAT_TX_INDEX == 6)\n\
\"ADAT 6\"\n\
#elif({i} - ADAT_TX_INDEX == 7)\n\
\"ADAT 7\"\n\
#elif({i} - ADAT_TX_INDEX == 8)\n\
\"ADAT 8\"\n\
#endif\n\
#endif\n\
,\n#endif\n".format(i=i, c=chanString, p=portString, s=structureString, adcdac=adc_dac);
return;
print "/* AUTOGENERATED using chanstringgen.py */\n"
print "/* Not very nice looking but the standard preprocessor is not very powerful\n and we save some memory over doing this all at runtime */"
print "/* Output Strings */\n\n"
genstrings(33, "OUT", "TX", "output", "DAC");
print "/* Input Strings */\n\n"
genstrings(33, "IN", "RX", "input", "ADC");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
#ifndef __DESCRIPTOR_DEFS_H__
#define __DESCRIPTOR_DEFS_H__
#if (NUM_USB_CHAN_IN > 0) && (NUM_USB_CHAN_OUT > 0)
#define AUDIO_INTERFACE_COUNT 3
#elif (NUM_USB_CHAN_IN > 0) || (NUM_USB_CHAN_OUT > 0)
#define AUDIO_INTERFACE_COUNT 2
#else
#define AUDIO_INTERFACE_COUNT 1
#endif
/* Endpoint address defines */
#define ENDPOINT_ADDRESS_IN_CONTROL (ENDPOINT_NUMBER_IN_CONTROL | 0x80)
#define ENDPOINT_ADDRESS_IN_FEEDBACK (ENDPOINT_NUMBER_IN_FEEDBACK | 0x80)
#define ENDPOINT_ADDRESS_IN_AUDIO (ENDPOINT_NUMBER_IN_AUDIO | 0x80)
#define ENDPOINT_ADDRESS_IN_INTERRUPT (ENDPOINT_NUMBER_IN_INTERRUPT | 0x80)
#define ENDPOINT_ADDRESS_IN_MIDI (ENDPOINT_NUMBER_IN_MIDI | 0x80)
#define ENDPOINT_ADDRESS_IN_HID (ENDPOINT_NUMBER_IN_HID | 0x80)
#define ENDPOINT_ADDRESS_IN_IAP_INT (ENDPOINT_NUMBER_IN_IAP_INT | 0x80)
#define ENDPOINT_ADDRESS_IN_IAP (ENDPOINT_NUMBER_IN_IAP | 0x80)
#define ENDPOINT_ADDRESS_IN_IAP_EA_NATIVE_TRANS (ENDPOINT_NUMBER_IN_IAP_EA_NATIVE_TRANS | 0x80)
#define ENDPOINT_ADDRESS_OUT_CONTROL (ENDPOINT_NUMBER_OUT_CONTROL)
#define ENDPOINT_ADDRESS_OUT_AUDIO (ENDPOINT_NUMBER_OUT_AUDIO)
#define ENDPOINT_ADDRESS_OUT_MIDI (ENDPOINT_NUMBER_OUT_MIDI)
#define ENDPOINT_ADDRESS_OUT_IAP (ENDPOINT_NUMBER_OUT_IAP)
#define ENDPOINT_ADDRESS_OUT_IAP_EA_NATIVE_TRANS (ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS)
/* Interface numbers enum */
enum USBInterfaceNumber
{
INTERFACE_NUMBER_AUDIO_CONTROL = 0,
#if (NUM_USB_CHAN_OUT > 0)
INTERFACE_NUMBER_AUDIO_OUTPUT,
#endif
#if (NUM_USB_CHAN_IN > 0)
INTERFACE_NUMBER_AUDIO_INPUT,
#endif
#if defined(MIDI) && (MIDI != 0)
INTERFACE_NUMBER_MIDI_CONTROL,
INTERFACE_NUMBER_MIDI_STREAM,
#endif
#if defined(DFU) && (DFU != 0)
INTERFACE_NUMBER_DFU,
#endif
#if defined(IAP) && (IAP != 0)
INTERFACE_NUMBER_IAP,
#if defined(IAP_EA_NATIVE_TRANS) && (IAP_EA_NATIVE_TRANS != 0)
INTERFACE_NUMBER_IAP_EA_NATIVE_TRANS,
#endif
#endif
#if defined(HID_CONTROLS) && (HID_CONTROLS != 0)
INTERFACE_NUMBER_HID,
#endif
INTERFACE_COUNT /* End marker */
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -49,19 +49,19 @@
#warning MIDI is currently not supported and will not be enabled in AUDIO 1.0 mode
#endif
/* If PID_DFU not defined, standard PID used.. this is probably what we want.. */
#ifndef PID_DFU
#warning PID_DFU not defined, Using PID_AUDIO_2. This is probably fine!
/* If DFU_PID not defined, standard PID used.. this is probably what we want.. */
#ifndef DFU_PID
#warning DFU_PID not defined, Using PID_AUDIO_2. This is probably fine!
#endif
#ifdef DFU
#include "dfu.h"
#define DFU_IF_NUM INPUT_INTERFACES + OUTPUT_INTERFACES + MIDI_INTERFACES + 1
unsigned int DFU_mode_active = 0; // 0 - App active, 1 - DFU active
extern void device_reboot(chanend);
#endif
unsigned int DFU_mode_active = 0; // 0 - App active, 1 - DFU active
/* Global volume and mute tables */
int volsOut[NUM_USB_CHAN_OUT + 1];
unsigned int mutesOut[NUM_USB_CHAN_OUT + 1];
@@ -204,7 +204,7 @@ const unsigned g_chanCount_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_I
/* 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_EANativeTransport_ctrl)
chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface))
{
USB_SetupPacket_t sp;
XUD_ep ep0_out = XUD_InitEp(c_ep0_out);
@@ -296,11 +296,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
while(1)
{
/* Returns XUD_RES_OKAY for success, XUD_RES_RST 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)
{
@@ -562,6 +558,8 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
if (interfaceNum == DFU_IF)
{
int reset = 0;
/* If running in application mode stop audio */
/* Don't interupt audio for save and restore cmds */
if ((DFU_IF == INTERFACE_NUMBER_DFU) && (sp.bRequest != XMOS_DFU_SAVESTATE) &&
@@ -573,27 +571,22 @@ 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))
#else
/* This will return 1 if reset requested */
if (DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], 1))
#endif
result = DFUDeviceRequests(ep0_out, &ep0_in, &sp, null, g_interfaceAlt[sp.wIndex], dfuInterface, &reset);
if(reset)
{
DFUDelay(50000000);
device_reboot(c_audioControl);
}
/* TODO we should not make the assumption that all DFU requests are handled */
result = 0;
}
#endif
/* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first
* - Audio STREAMING interface request (In or Out)
* - Audio endpoint request (Audio 1.0 Sampling freq requests are sent to the endpoint)
*/
if((interfaceNum == 0) || (interfaceNum == 1) || (interfaceNum == 2))
if(((interfaceNum == 0) || (interfaceNum == 1) || (interfaceNum == 2)) && !DFU_mode_active)
{
#if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK)
if(g_curUsbSpeed == XUD_SPEED_HS)

View File

@@ -2,6 +2,8 @@
#ifndef _ENDPOINT0_H_
#define _ENDPOINT0_H_
#include "dfu_interface.h"
/** Function implementing Endpoint 0 for enumeration, control and configuration
* of USB audio devices. It uses the descriptors defined in ``descriptors_2.h``.
*
@@ -18,7 +20,7 @@
* \param c_EANativeTransport_ctrl Optional chanend to be connected to EA Native
* endpoint manager if present
*/
void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl,
chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl);
void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl,
chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu dfuInterface);
#endif

View File

@@ -1,10 +1,15 @@
#include "devicedefines.h"
#include "uac_hwresources.h"
#ifdef DFU
#include <xs1.h>
#include <xclib.h>
#ifdef QUAD_SPI_FLASH
#include <quadflashlib.h>
#else
#include <flashlib.h>
#endif
#include <print.h>
#define settw(a,b) {__asm__ __volatile__("settw res[%0], %1": : "r" (a) , "r" (b));}
@@ -18,25 +23,46 @@
fl_DeviceSpec flash_devices[] = {DFU_FLASH_DEVICE};
#endif
#ifdef QUAD_SPI_FLASH
/*
typedef struct {
out port qspiCS;
out port qspiSCLK;
out buffered port:32 qspiSIO;
clock qspiClkblk;
} fl_QSPIPorts;
*/
fl_QSPIPorts p_qflash =
{
XS1_PORT_1B,
XS1_PORT_1C,
XS1_PORT_4B,
CLKBLK_FLASHLIB
};
#else
fl_PortHolderStruct p_flash =
{
XS1_PORT_1A,
XS1_PORT_1B,
XS1_PORT_1C,
XS1_PORT_1D,
XS1_CLKBLK_1
CLKBLK_FLASHLIB
};
#endif
/* return 1 for opened ports successfully */
int flash_cmd_enable_ports()
{
int result = 0;
#ifdef QUAD_SPI_FLASH
/* Ports not shared */
#else
setc(p_flash.spiMISO, XS1_SETC_INUSE_OFF);
setc(p_flash.spiCLK, XS1_SETC_INUSE_OFF);
setc(p_flash.spiMOSI, XS1_SETC_INUSE_OFF);
setc(p_flash.spiSS, XS1_SETC_INUSE_OFF);
setc(p_flash.spiClkblk, XS1_SETC_INUSE_OFF);
setc(p_flash.spiMISO, XS1_SETC_INUSE_ON);
setc(p_flash.spiCLK, XS1_SETC_INUSE_ON);
setc(p_flash.spiMOSI, XS1_SETC_INUSE_ON);
@@ -54,15 +80,21 @@ int flash_cmd_enable_ports()
settw(p_flash.spiMISO, 8);
settw(p_flash.spiMOSI, 8);
#endif
#ifdef DFU_FLASH_DEVICE
result = fl_connectToDevice(&p_flash, flash_devices, 1);
#else
/* Use default flash list */
#ifdef QUAD_SPI_FLASH
result = fl_connect(&p_qflash);
#else
result = fl_connect(&p_flash);
#endif
#endif
if (!result)
{
/* All okay.. */
return 1;
}
else
@@ -75,10 +107,12 @@ int flash_cmd_disable_ports()
{
fl_disconnect();
#ifndef QUAD_SPI_FLASH
setc(p_flash.spiMISO, XS1_SETC_INUSE_OFF);
setc(p_flash.spiCLK, XS1_SETC_INUSE_OFF);
setc(p_flash.spiMOSI, XS1_SETC_INUSE_OFF);
setc(p_flash.spiSS, XS1_SETC_INUSE_OFF);
#endif
return 1;
}

View File

@@ -15,6 +15,7 @@
#include "xud.h" /* XMOS USB Device Layer defines and functions */
#include "devicedefines.h" /* Device specific defines */
#include "uac_hwresources.h"
#include "endpoint0.h"
#include "usb_buffer.h"
#include "decouple.h"
@@ -37,11 +38,14 @@
#endif
#ifdef ADAT_RX
#include "adatreceiver.h"
#include "adat_rx.h"
#endif
#include "clocking.h"
[[distributable]]
void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd);
/* Audio I/O - Port declarations */
#if I2S_WIRES_DAC > 0
on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
@@ -101,24 +105,7 @@ on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] =
};
#endif
#if (XUD_SERIES_SUPPORT == XUD_L_SERIES) && (AUDIO_IO_TILE == XUD_TILE)
/* Note: L series ref clocked clocked from USB clock when USB enabled - use another clockblock for MIDI
* if MIDI and XUD on same tile. See XUD documentation.
*
* This is a clash with S/PDIF Tx but simultaneous S/PDIF and MIDI not currently supported on single tile device
*
*/
/* TODO should include tile here */
#define CLKBLK_MIDI XS1_CLKBLK_1;
#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
#define CLKBLK_I2S_BIT XS1_CLKBLK_3
#define CLKBLK_XUD XS1_CLKBLK_4 /* Note XUD for U-series uses CLKBLK_5 also (see XUD_Ports.xc) */
#ifndef CODEC_MASTER
on tile[AUDIO_IO_TILE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK;
@@ -131,8 +118,12 @@ on tile[AUDIO_IO_TILE] : in port p_bclk = PORT_I2S_BCLK;
on tile[AUDIO_IO_TILE] : port p_mclk_in = PORT_MCLK_IN;
on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT;
#ifdef SPDIF
on tile[AUDIO_IO_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
#ifdef SPDIF_TX
on tile[SPDIF_TX_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
#endif
#ifdef ADAT_TX
on stdcore[AUDIO_IO_TILE] : buffered out port:32 p_adat_tx = PORT_ADAT_OUT;
#endif
#ifdef ADAT_RX
@@ -149,29 +140,31 @@ on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF;
#endif
#ifdef MIDI
on tile[AUDIO_IO_TILE] : port p_midi_tx = PORT_MIDI_OUT;
on tile[MIDI_TILE] : port p_midi_tx = PORT_MIDI_OUT;
#if(MIDI_RX_PORT_WIDTH == 4)
on tile[AUDIO_IO_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN;
on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN;
#elif(MIDI_RX_PORT_WIDTH == 1)
on tile[AUDIO_IO_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN;
on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN;
#endif
#endif
/* Clock blocks */
#ifdef MIDI
on tile[AUDIO_IO_TILE] : clock clk_midi = CLKBLK_MIDI;
on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI;
#endif
#ifdef SPDIF
on tile[AUDIO_IO_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX;
#if defined(SPDIF_TX) || defined(ADAT_TX)
on tile[SPDIF_TX_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX;
#endif
#ifdef SPDIF_RX
on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX;
#endif
#ifdef ADAT_RX
#if(XUD_SERIES_SUPPORT == XUD_L_SERIES) && defined(ADAT_RX)
/* Cannot use default clock (CLKBLK_REF) for ADAT RX since it is tied to the
60MHz USB clock on G/L series parts. */
on tile[XUD_TILE] : clock clk_adat_rx = CLKBLK_ADAT_RX;
#endif
@@ -195,17 +188,21 @@ on tile[XUD_TILE] : out port p_usb_rst = PORT_USB_RESET;
#define p_usb_rst null
#endif
#if (XUD_SERIES_SUPPORT != XUD_U_SERIES)
#if (XUD_SERIES_SUPPORT != XUD_U_SERIES && XUD_SERIES_SUPPORT != XUD_X200_SERIES)
/* L Series also needs a clock block for this port */
on tile[XUD_TILE] : clock clk = CLKBLK_XUD;
on tile[XUD_TILE] : clock clk = CLKBLK_USB_RST;
#else
#define clk null
#endif
#ifdef IAP
/* I2C ports - in a struct for use with module_i2s_simple */
/* I2C ports - in a struct for use with module_i2c_shared & module_i2c_simple/module_i2c_single_port */
#ifdef PORT_I2C
on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C};
#else
on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C_SCL, PORT_I2C_SDA};
#endif
#endif
/* Endpoint type tables for XUD */
@@ -281,6 +278,7 @@ void usb_audio_core(chanend c_mix_out
#endif
, chanend ?c_clk_int
, chanend ?c_clk_ctl
, client interface i_dfu dfuInterface
)
{
chan c_sof;
@@ -322,7 +320,7 @@ void usb_audio_core(chanend c_mix_out
/* Attach mclk count port to mclk clock-block (for feedback) */
//set_port_clock(p_for_mclk_count, clk_audio_mclk);
#if(AUDIO_IO_TILE != 0)
#if(AUDIO_IO_TILE != XUD_TILE)
set_clock_src(clk_audio_mclk2, p_mclk_in2);
set_port_clock(p_for_mclk_count, clk_audio_mclk2);
start_clock(clk_audio_mclk2);
@@ -375,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, c_clk_ctl, c_EANativeTransport_ctrl);
Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface);
}
/* Decoupling core */
@@ -392,14 +390,20 @@ void usb_audio_core(chanend c_mix_out
}
void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
#ifdef MIXER
chanend c_mix_ctl,
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
chanend c_spdif_tx,
#endif
#ifdef MIXER
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
#if (XUD_TILE != 0)
, server interface i_dfu dfuInterface
#endif
chanend ?c_aud_cfg,
streaming chanend ?c_spdif_rx,
chanend ?c_adat_rx,
chanend ?c_clk_ctl,
chanend ?c_clk_int
)
{
#ifdef MIXER
@@ -425,18 +429,22 @@ chanend ?c_clk_int
{
thread_speed();
#ifdef MIXER
audio(c_mix_out,
#if defined(SPDIF_RX) || defined(ADAT_RX)
c_dig_rx,
#endif
c_aud_cfg, c_adc);
#define AUDIO_CHANNEL c_mix_out
#else
audio(c_aud_in,
#define AUDIO_CHANNEL c_aud_in
#endif
audio(AUDIO_CHANNEL,
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
c_spdif_tx,
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX)
c_dig_rx,
c_dig_rx,
#endif
c_aud_cfg, c_adc);
c_aud_cfg, c_adc
#if XUD_TILE != 0
,dfuInterface
#endif
);
}
#if defined(SPDIF_RX) || defined(ADAT_RX)
@@ -501,6 +509,11 @@ int main()
#define c_adat_rx null
#endif
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
chan c_spdif_tx;
#endif
#if (defined (SPDIF_RX) || defined (ADAT_RX))
chan c_clk_ctl;
chan c_clk_int;
@@ -509,33 +522,64 @@ int main()
#define c_clk_ctl null
#endif
#ifdef DFU
interface i_dfu dfuInterface;
#else
#define dfuInterface null
#endif
USER_MAIN_DECLARATIONS
par
{
on tile[XUD_TILE]: usb_audio_core(c_mix_out
on tile[XUD_TILE]:
par
{
#if (XUD_TILE == 0)
/* Check if USB is on the flash tile (tile 0) */
[[distribute]]
DFUHandler(dfuInterface, null);
#endif
usb_audio_core(c_mix_out
#ifdef MIDI
, c_midi
, c_midi
#endif
#ifdef IAP
, c_iap
, c_iap
#ifdef IAP_EA_NATIVE_TRANS
, c_ea_data
, c_ea_data
#endif
#endif
#ifdef MIXER
, c_mix_ctl
, c_mix_ctl
#endif
, c_clk_int, c_clk_ctl
);
, c_clk_int, c_clk_ctl, dfuInterface
);
}
on tile[AUDIO_IO_TILE]: usb_audio_io(c_mix_out, c_adc
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
, c_spdif_tx
#endif
#ifdef MIXER
, c_mix_ctl
#endif
,c_aud_cfg, c_spdif_rx, c_adat_rx, c_clk_ctl, c_clk_int
#if XUD_TILE != 0
, dfuInterface
#endif
);
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
on tile[SPDIF_TX_TILE]:
{
thread_speed();
SpdifTxWrapper(c_spdif_tx);
}
#endif
#if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE)
/* MIDI and IAP share a core */
on tile[IAP_TILE]:
@@ -562,7 +606,7 @@ int main()
#endif
#ifdef SPDIF_RX
on tile[0]:
on tile[XUD_TILE]:
{
thread_speed();
SpdifReceive(p_spdif_rx, c_spdif_rx, 1, clk_spd_rx);
@@ -570,11 +614,15 @@ int main()
#endif
#ifdef ADAT_RX
on stdcore[0] :
on stdcore[XUD_TILE] :
{
set_thread_fast_mode_on();
#if(XUD_SERIES_SUPPORT == XUD_L_SERIES)
/* Can't use REF clock on L-series as this is usb clock */
set_port_clock(p_adat_rx, clk_adat_rx);
start_clock(clk_adat_rx);
#endif
while (1)
{
adatReceiver48000(p_adat_rx, c_adat_rx);

View File

@@ -4,6 +4,52 @@
#define MIX_INPUTS 18
#if defined(__XS2A__)
#define DOMIX_TOP(i) \
.cc_top doMix##i.function,doMix##i; \
.align 4 ;\
.globl doMix##i ;\
.type doMix##i, @function ;\
.globl doMix##i##.nstackwords ;\
.globl doMix##i##.maxthreads ; \
.globl doMix##i##.maxtimers ; \
.globl doMix##i##.maxchanends ; \
.globl doMix##i##.maxsync ;\
.linkset doMix##i##.locnoside, 1; \
.linkset doMix##i##.locnochandec, 1;\
.linkset doMix##i##.nstackwords, 0 ;\
.linkset doMix##i##.maxchanends, 0 ;\
.linkset doMix##i##.maxtimers, 0 ;\
.linkset doMix##i##.maxthreads, 1; \
doMix##i##: ;\
ENTSP_lu6 0; \
set cp, r0; \
set dp, r1; \
lsub r0, r1, r0, r0, r0;\
.label_##i##:
#define DOMIX_BOT(i) \
ldap r11, _dp; \
set dp, r11;\
ldap r11, _cp;\
set cp, r11;\
\
mov r0, r1;\
ldc r2, 0x19;\
sext r0, r2;\
eq r0, r0, r1;\
bf r0, .L20; \
\
shl r0, r1, 0x7;\
retsp 0x0;\
\
\
.size doMix##i, .-doMix##i; \
.cc_bottom doMix##i##.function;
#else
#define DOMIX_TOP(i) \
.cc_top doMix##i.function,doMix##i; \
@@ -46,6 +92,8 @@ doMix##i##: ;\
.size doMix##i, .-doMix##i; \
.cc_bottom doMix##i##.function;
#endif
#define N MIX_INPUTS
#define BODY(i) \
ldw r2,cp[i]; \

View File

@@ -201,9 +201,8 @@ static inline void GiveSamplesToHost(chanend c, xc_ptr ptr, xc_ptr multIn)
}
#pragma unsafe arrays
static inline void GetSamplesFromHost(chanend c, unsigned underflow)
static inline void GetSamplesFromHost(chanend c)
{
if(!underflow)
{
#pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
@@ -245,11 +244,8 @@ static inline void GetSamplesFromHost(chanend c, unsigned underflow)
}
#pragma unsafe arrays
static inline void GiveSamplesToDevice(chanend c, xc_ptr ptr, xc_ptr multOut, unsigned underflow)
static inline void GiveSamplesToDevice(chanend c, xc_ptr ptr, xc_ptr multOut)
{
outuint(c, underflow);
if(!underflow)
{
#pragma loop unroll
for (int i=0; i<NUM_USB_CHAN_OUT; i++)
@@ -354,20 +350,16 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
int mixed;
#endif
unsigned cmd;
unsigned underflow = 1;
unsigned request = 0;
while (1)
{
#pragma xta endpoint "mixer1_req"
/* Request from audio() */
inuint(c_mixer2);
/* Request from audio()/mixer2() */
request = inuint(c_mixer2);
GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut, underflow);
GetSamplesFromDevice(c_mixer2);
/* Request data from decouple thread */
outuint(c_host, 0);
/* Forward on Request for data to decouple thread */
outuint(c_host, request);
/* Between request to decouple and respose ~ 400nS latency for interrupt to fire */
select
@@ -504,9 +496,6 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
sampFreq = inuint(c_host);
mixer1_mix2_flag = sampFreq > 96000;
/* Wait for request */
inuint(c_mixer2);
/* Inform mixer2 (or audio()) about freq change */
outct(c_mixer2, command);
outuint(c_mixer2, sampFreq);
@@ -515,9 +504,6 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
case SET_STREAM_FORMAT_OUT:
case SET_STREAM_FORMAT_IN:
/* Wait for request */
inuint(c_mixer2);
/* Inform mixer2 (or audio()) about format change */
outct(c_mixer2, command);
outuint(c_mixer2, inuint(c_host));
@@ -545,14 +531,14 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
}
else
{
underflow = inuint(c_host);
inuint(c_host);
#if MAX_MIX_COUNT > 0
outuint(c_mixer2, underflow);
outuint(c_mixer2, 0);
GiveSamplesToHost(c_host, samples_to_host_map, multIn);
outuint(c_mixer2, 0);
inuint(c_mixer2);
GetSamplesFromHost(c_host, underflow);
GetSamplesFromHost(c_host);
outuint(c_mixer2, 0);
inuint(c_mixer2);
#ifdef FAST_MIXER
@@ -588,7 +574,7 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
#ifdef FAST_MIXER
mixed = doMix4(samples, mix_mult_slice(4));
#else
mixed = doMix(samples_array,mix_map_slice(4),mix_mult_slice(4));
mixed = doMix(samples, mix_map_slice(4),mix_mult_slice(4));
#endif
write_via_xc_ptr_indexed(samples_array, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 4), mixed);
@@ -601,9 +587,9 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
#ifdef FAST_MIXER
mixed = doMix6(samples, mix_mult_slice(6));
#else
mixed = doMix(samples_array,mix_map_slice(6),mix_mult_slice(6));
mixed = doMix(samples, mix_map_slice(6),mix_mult_slice(6));
#endif
write_via_xc_ptr_indexed(samples_array, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 6), mixed);
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 6), mixed);
#if defined (LEVEL_METER_HOST) || defined(LEVEL_METER_LEDS)
ComputeMixerLevel(mixed, 6);
@@ -612,9 +598,10 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2)
}
#else /* IF MAX_MIX_COUNT > 0 */
/* No mixes, this thread runs on its own doing just volume */
GiveSamplesToDevice(c_mixer2, samples_to_device_map, multOut);
GetSamplesFromDevice(c_mixer2);
GiveSamplesToHost(c_host, samples_to_host_map, multIn);
GetSamplesFromHost(c_host, underflow);
GetSamplesFromHost(c_host);
#endif
}
}
@@ -627,13 +614,16 @@ static int mixer2_mix2_flag = (DEFAULT_FREQ > 96000);
static void mixer2(chanend c_mixer1, chanend c_audio)
{
int mixed;
unsigned underflow = 0;
unsigned request;
while (1)
{
outuint(c_mixer1, 0);
#pragma xta endpoint "mixer2_req"
inuint(c_audio);
request = inuint(c_audio);
/* Forward the request on */
outuint(c_mixer1, request);
if(testct(c_mixer1))
{
int sampFreq;
@@ -678,8 +668,8 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
}
else
{
underflow = inuint(c_mixer1);
GiveSamplesToDevice(c_audio, samples_to_device_map, multOut, underflow);
(void) inuint(c_mixer1);
GiveSamplesToDevice(c_audio, samples_to_device_map, multOut);
inuint(c_mixer1);
outuint(c_mixer1, 0);
GetSamplesFromDevice(c_audio);
@@ -689,7 +679,7 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
#ifdef FAST_MIXER
mixed = doMix1(samples, mix_mult_slice(1));
#else
mixed = doMix(samples_array,mix_map_slice(1),mix_mult_slice(1));
mixed = doMix(samples, mix_map_slice(1),mix_mult_slice(1));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 1), mixed);
@@ -709,7 +699,7 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
#ifdef FAST_MIXER
mixed = doMix3(samples, mix_mult_slice(3));
#else
mixed = doMix(samples_array,mix_map_slice(3),mix_mult_slice(3));
mixed = doMix(samples, mix_map_slice(3),mix_mult_slice(3));
#endif
write_via_xc_ptr_indexed(samples, (NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 3), mixed);
@@ -723,7 +713,7 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
#ifdef FAST_MIXER
mixed = doMix5(samples, mix_mult_slice(5));
#else
mixed = doMix(samples_array,mix_map_slice(5),mix_mult_slice(5));
mixed = doMix(samples, mix_map_slice(5),mix_mult_slice(5));
#endif
write_via_xc_ptr_indexed(samples, NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 5, mixed);
@@ -736,7 +726,7 @@ static void mixer2(chanend c_mixer1, chanend c_audio)
#ifdef FAST_MIXER
mixed = doMix7(samples, mix_mult_slice(7));
#else
mixed = doMix(samples_array,mix_map_slice(7),mix_mult_slice(7));
mixed = doMix(samples, mix_map_slice(7),mix_mult_slice(7));
#endif
write_via_xc_ptr_indexed(samples, NUM_USB_CHAN_OUT + NUM_USB_CHAN_IN + 7, mixed);

View File

@@ -6,6 +6,12 @@
#define XS1_SU_PERIPH_USB_ID 0x1
#if (XUD_SERIES_SUPPORT == XUD_X200_SERIES)
#define PLL_MASK 0x7FFFFFFF
#else
#define PLL_MASK 0xFFFFFFFF
#endif
/* Note, this function is prototyped in xs1.h only from 13 tools onwards */
unsigned get_tile_id(tileref);
@@ -40,25 +46,29 @@ void device_reboot_aux(void)
if(localTileId != tileId)
{
read_sswitch_reg(tileId, 6, pllVal);
pllVal &= PLL_MASK;
write_sswitch_reg_no_ack(tileId, 6, pllVal);
}
}
/* Finally reboot this tile! */
read_sswitch_reg(localTileId, 6, pllVal);
pllVal &= PLL_MASK;
write_sswitch_reg_no_ack(localTileId, 6, pllVal);
#endif
}
/* Reboots XMOS device by writing to the PLL config register */
void device_reboot_implementation(chanend spare)
void device_reboot(chanend spare)
{
#if (XUD_SERIES_SUPPORT != XUD_U_SERIES)
outct(spare, XS1_CT_END); // have to do this before freeing the chanend
inct(spare); // Receive end ct from usb_buffer to close down in both directions
//outct(spare, XS1_CT_END); // have to do this before freeing the chanend
//inct(spare); // Receive end ct from usb_buffer to close down in both directions
/* Need a spare chanend so we can talk to the pll register */
asm("freer res[%0]"::"r"(spare));
//asm("freer res[%0]"::"r"(spare));
#endif
device_reboot_aux();
while(1);
}

View File

@@ -1,36 +0,0 @@
# Wrapper generated from this xc code
# Then modified to fix maxchanends to 0
# Then simplified
#void device_reboot_implementation(chanend spare);
#
#// This version just exists so generate an assembly wrapper function for me.
#void device_reboot(chanend spare)
#{
# device_reboot_implementation(spare);
#}
.extern device_reboot_implementation, "f{0}(chd)"
.text
.align 2
.cc_top device_reboot.function,device_reboot
.align 4
.call device_reboot, device_reboot_implementation
.globl device_reboot, "f{0}(chd)"
.globl device_reboot.nstackwords
.globl device_reboot.maxthreads
.globl device_reboot.maxtimers
.globl device_reboot.maxchanends
.globl device_reboot.maxsync
.type device_reboot, @function
.linkset device_reboot.locnoside, 1
.linkset device_reboot.locnochandec, 1
.linkset device_reboot.nstackwords, device_reboot_implementation.nstackwords + 1
device_reboot:
entsp 0x1
bl device_reboot_implementation
retsp 0x1
.size device_reboot, .-device_reboot
.cc_bottom device_reboot.function
.linkset device_reboot.maxchanends, 0#device_reboot_implementation.maxchanends
.linkset device_reboot.maxtimers, device_reboot_implementation.maxtimers
.linkset device_reboot.maxthreads, device_reboot_implementation.maxthreads

View File

@@ -0,0 +1,45 @@
#ifndef _UAC_HWRESOURCES_H_
#define _UAC_HWRESOURCES_H_
#include "xud.h" /* XMOS USB Device Layer defines and functions */
#if ((XUD_SERIES_SUPPORT != XUD_U_SERIES) && (XUD_SERIES_SUPPORT != XUD_X200_SERIES))
/* XUD_L_SERIES and XUD_G_SERIES */
#if (AUDIO_IO_TILE == XUD_TILE)
/* Note: L series ref clocked clocked from USB clock when USB enabled - use another clockblock for MIDI
* if MIDI and XUD on same tile. See XUD documentation.
*
* This is a clash with S/PDIF Tx but simultaneous S/PDIF and MIDI not currently supported on single tile device
*
*/
#define CLKBLK_MIDI XS1_CLKBLK_1;
#else
#define CLKBLK_MIDI XS1_CLKBLK_REF;
#endif
#define CLKBLK_SPDIF_TX XS1_CLKBLK_1
#define CLKBLK_SPDIF_RX XS1_CLKBLK_1
#define CLKBLK_MCLK XS1_CLKBLK_2 /* Note, potentially used twice */
#define CLKBLK_ADAT_RX XS1_CLKBLK_3
#define CLKBLK_USB_RST XS1_CLKBLK_4 /* Clock block passed into L/G series XUD */
#define CLKBLK_FLASHLIB XS1_CLKBLK_5 /* Clock block for use by flash lib */
#define CLKBLK_I2S_BIT XS1_CLKBLK_3
#else
/* XUD_U_SERIES, XUD_X200_SERIES */
/* Note, U-series XUD uses clock blocks 4 and 5 - see XUD_Ports.xc */
#define CLKBLK_MIDI XS1_CLKBLK_REF;
#define CLKBLK_SPDIF_TX XS1_CLKBLK_1
#define CLKBLK_SPDIF_RX XS1_CLKBLK_1
#define CLKBLK_MCLK XS1_CLKBLK_2 /* Note, potentially used twice */
#define CLKBLK_FLASHLIB XS1_CLKBLK_3 /* Clock block for use by flash lib */
#define CLKBLK_ADAT_RX XS1_CLKBLK_REF /* Use REF for ADAT_RX on U/x200 series */
#define CLKBLK_I2S_BIT XS1_CLKBLK_3
#endif
#endif /* _UAC_HWRESOURCES_H_ */

View File

@@ -129,10 +129,9 @@ void handle_audio_request(chanend c_mix_out)
int space_left;
/* Input word that triggered interrupt and handshake back */
(void) inuint(c_mix_out);
unsigned underflowSample = inuint(c_mix_out);
/* Reply with underflow */
outuint(c_mix_out, outUnderflow);
outuint(c_mix_out, 0);
/* If in overflow condition then receive samples and throw away */
if(inOverflow || sampsToWrite == 0)
@@ -176,7 +175,7 @@ __builtin_unreachable();
int mult;
int h;
unsigned l;
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
@@ -207,7 +206,7 @@ __builtin_unreachable();
int mult;
int h;
unsigned l;
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#if (STREAM_FORMAT_INPUT_RESOLUTION_32BIT_USED == 1)
@@ -240,7 +239,7 @@ __builtin_unreachable();
int mult;
int h;
unsigned l;
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
sample = h << 3;
#endif
@@ -290,21 +289,11 @@ __builtin_unreachable();
if(outUnderflow)
{
#pragma xta endpoint "out_underflow"
#if 0
/* We're still pre-buffering, send out 0 samps */
for(int i = 0; i < NUM_USB_CHAN_OUT; i++)
{
unsigned sample;
unsigned mode;
GET_SHARED_GLOBAL(sample, g_muteSample);
GET_SHARED_GLOBAL(mode, dsdMode);
if(mode == DSD_MODE_DOP)
outuint(c_mix_out, 0xFA969600);
else
outuint(c_mix_out, sample);
outuint(c_mix_out, underflowSample);
}
#endif
/* Calc how many samples left in buffer */
outSamps = g_aud_from_host_wrptr - g_aud_from_host_rdptr;
@@ -343,7 +332,7 @@ __builtin_unreachable();
sample <<= 16;
#if (OUTPUT_VOLUME_CONTROL == 1) && !defined(OUT_VOLUME_IN_MIXER)
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
asm volatile("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;
@@ -371,7 +360,7 @@ __builtin_unreachable();
g_aud_from_host_rdptr+=4;
#if (OUTPUT_VOLUME_CONTROL == 1) && !defined(OUT_VOLUME_IN_MIXER)
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
asm volatile("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0);
h <<= 3;
#if (STREAM_FORMAT_OUTPUT_RESOLUTION_32BIT_USED == 1)
@@ -426,7 +415,7 @@ __builtin_unreachable();
unpackState++;
#if (OUTPUT_VOLUME_CONTROL == 1) && !defined(OUT_VOLUME_IN_MIXER)
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
asm volatile("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);
@@ -476,7 +465,7 @@ __builtin_unreachable();
}
/* Get feedback val - ideally this would be syncronised */
asm("ldw %0, dp[g_speed]" : "=r" (speed) :);
asm volatile("ldw %0, dp[g_speed]" : "=r" (speed) :);
/* Calc packet size to send back based on our fb */
speedRem += speed;
@@ -587,10 +576,13 @@ static inline void SetupZerosSendBuffer(XUD_ep aud_to_host_usb_ep, unsigned samp
mid *= g_numUsbChan_In * slotSize;
asm("stw %0, %1[0]"::"r"(mid),"r"(g_aud_to_host_zeros));
asm volatile("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 */
/* g_aud_to_host_buffer is already set to g_aud_to_host_zeros */
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, mid);
@@ -648,18 +640,18 @@ void decouple(chanend c_mix_out
#ifndef OUT_VOLUME_IN_MIXER
for (int i = 0; i < NUM_USB_CHAN_OUT + 1; i++)
{
asm("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i));
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i));
}
#endif
#ifndef IN_VOLUME_IN_MIXER
for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++)
{
asm("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multIn),"r"(i));
asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multIn),"r"(i));
}
#endif
set_interrupt_handler(handle_audio_request, 200, 1, c_mix_out, 0);
set_interrupt_handler(handle_audio_request, 1, c_mix_out, 0);
/* Wait for usb_buffer() to set up globals for us to use
* Note: assumed that buffer_aud_ctl_chan is also setup before these globals are !0 */
@@ -729,7 +721,7 @@ void decouple(chanend c_mix_out
SET_SHARED_GLOBAL(totalSampsToWrite, 0);
/* Set buffer to send back to zeros buffer */
SET_SHARED_GLOBAL(g_aud_to_host_buffer,g_aud_to_host_zeros);
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, g_curSubSlot_In);
@@ -751,7 +743,7 @@ void decouple(chanend c_mix_out
chkct(c_mix_out, XS1_CT_END);
SET_SHARED_GLOBAL(g_freqChange, 0);
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
asm volatile("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
ENABLE_INTERRUPTS();
@@ -795,7 +787,7 @@ void decouple(chanend c_mix_out
}
SET_SHARED_GLOBAL(g_freqChange, 0);
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
asm volatile("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
ENABLE_INTERRUPTS();
}
@@ -840,7 +832,7 @@ void decouple(chanend c_mix_out
/* Wait for handshake back */
chkct(c_mix_out, XS1_CT_END);
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
asm volatile("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
SET_SHARED_GLOBAL(g_freqChange, 0);
ENABLE_INTERRUPTS();
@@ -1000,7 +992,7 @@ void decouple(chanend c_mix_out
{
int p, len;
GET_SHARED_GLOBAL(p, g_aud_to_host_buffer);
asm("ldw %0, %1[0]":"=r"(len):"r"(p));
asm volatile("ldw %0, %1[0]":"=r"(len):"r"(p));
XUD_SetReady_InPtr(aud_to_host_usb_ep, p+4, len);
}
continue;

View File

@@ -0,0 +1,3 @@
#include <interrupt.h>
register_interrupt_handler(handle_audio_request, 1, 200)

View File

@@ -143,9 +143,19 @@
//int ksp_enter, ksp_exit, r11_store;
#ifdef __XS2A__
#define ISSUE_MODE_SINGLE ".issue_mode single\n"
#define ISSUE_MODE_DUAL ".issue_mode dual\n"
#else
#define ISSUE_MODE_SINGLE
#define ISSUE_MODE_DUAL
#endif
#define do_interrupt_handler(f,args) \
asm("bu .L__" #f "_handler_skip;\n" \
asm(ISSUE_MODE_SINGLE\
".align 4\n" \
"__" #f "_handler:\n" \
"ENTSP_lu6 0\n" \
"kentsp " #args " + 19\n" \
"__kent:" \
save_state(f,args) \
@@ -154,19 +164,24 @@
restore_state(f,args) \
"krestsp " #args " + 19 \n" \
"__kret:\n" \
"kret\n" \
".L__" #f "_handler_skip:\n");
"kret\n");
#define set_interrupt_handler(f, nstackwords, args, c, ...) \
asm (" .section .dp.data, \"adw\", @progbits\n" \
" .align 4\n" \
#define register_interrupt_handler(f, args, nstackwords) \
asm (" .section .dp.data, \"adw\", @progbits\n" \
" .globl __" #f "_kernel_stack_end\n" \
" .globl __" #f "_handler\n" \
" .align 8\n" \
"__" #f "_kernel_stack:\n" \
" .space " #nstackwords ", 0\n" \
" .text\n"); \
asm("mov r10, %0; ldaw r11, dp[__" #f "_kernel_stack];add r11, r11, r10;ldaw r10, sp[0]; "\
"set sp,r11;stw r10, sp[0]; krestsp 0"::"r"(nstackwords-8):"r10","r11"); \
"__" #f "_kernel_stack_end:\n" \
" .space 2\n"\
" .text\n"); \
do_interrupt_handler(f, args)
#define set_interrupt_handler(f, args, c, ...) \
asm("ldaw r11, dp[__" #f "_kernel_stack_end];ldaw r10, sp[0]; " \
"set sp,r11;stw r10, sp[0]; krestsp 0":::"r10","r11"); \
store_args ## args(c, __VA_ARGS__) \
do_interrupt_handler(f, args) \
asm("ldap r11, __" #f "_handler; setv res[%0],r11"::"r"(c):"r11"); \
asm("setc res[%0], 0xa; eeu res[%0]"::"r"(c)); \
asm("setsr (((0) & ~(((1 << 0x1) - 1) << 0x1)) | (((1) << 0x1) & (((1 << 0x1) - 1) << 0x1)))");

View File

@@ -17,6 +17,8 @@
* \param c_aud_ctl Audio control channel connected to Endpoint0()
* \param p_off_mclk A port that is clocked of the MCLK input (not the MCLK input itself)
*/
#include "devicedefines.h"
void buffer(chanend c_aud_out,
chanend c_aud_in,
#if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP)

View File

@@ -317,6 +317,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
sofCount = 0;
clocks = 0;
remnant = 0;
int min, mid, max;
GetADCCounts(sampleFreq, min, mid, max);
g_speed = mid<<16;
}
/* Ideally we want to wait for handshake (and pass back up) here. But we cannot keep this
@@ -384,7 +388,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
* lastClock being incorrect */
/* Get MCLK count */
asm (" getts %0, res[%1]" : "=r" (u_tmp) : "r" (p_off_mclk));
asm volatile(" getts %0, res[%1]" : "=r" (u_tmp) : "r" (p_off_mclk));
GET_SHARED_GLOBAL(freqChange, g_freqChange);
if(freqChange == SET_SAMPLE_FREQ)
@@ -428,7 +432,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in,
#endif
{
int usb_speed;
asm("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks
asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks
GET_SHARED_GLOBAL(usb_speed, g_curUsbSpeed);

View File

@@ -1,3 +1,12 @@
/* These defines relate to the HID report desc - do not mod */
#define HID_CONTROL_PLAYPAUSE_SHIFT 0x01
#define HID_CONTROL_NEXT_SHIFT 0x02
#define HID_CONTROL_PREV_SHIFT 0x03
#define HID_CONTROL_VOLUP_SHIFT 0x04
#define HID_CONTROL_VOLDN_SHIFT 0x05
#define HID_CONTROL_MUTE_SHIFT 0x06
void UserReadHIDButtons(unsigned char hidData[]);