Changes to support DSD Native mode

This commit is contained in:
Ross Owen
2013-08-23 14:23:37 +01:00
parent bbb4999318
commit 1e33bf819d
7 changed files with 217 additions and 72 deletions

View File

@@ -18,7 +18,10 @@
#include "audioports.h" #include "audioports.h"
#include "audiohw.h" #include "audiohw.h"
#include "SpdifTransmit.h" #include "SpdifTransmit.h"
#include "clockcmds.h"
unsigned testsamples[100];
int p = 0;
unsigned lastSample =0;
#if (DSD_CHANS_DAC != 0) #if (DSD_CHANS_DAC != 0)
extern unsigned p_dsd_dac[DSD_CHANS_DAC]; extern unsigned p_dsd_dac[DSD_CHANS_DAC];
extern port p_dsd_clk; extern port p_dsd_clk;
@@ -78,7 +81,7 @@ extern void device_reboot(void);
/* I2S delivery thread */ /* I2S delivery thread */
#pragma unsafe arrays #pragma unsafe arrays
unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc) {unsigned, unsigned} deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc)
{ {
unsigned sample; unsigned sample;
#if NUM_USB_CHAN_OUT > 0 #if NUM_USB_CHAN_OUT > 0
@@ -118,9 +121,8 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
/* Check for sample freq change or new samples from mixer*/ /* Check for sample freq change or new samples from mixer*/
if(testct(c_out)) if(testct(c_out))
{ {
inct(c_out); unsigned command = inct(c_out);
return inuint(c_out); return {command, inuint(c_out)};
} }
else else
{ {
@@ -250,7 +252,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
break; break;
} }
} }
} } /* if (!dsdMode) */
#else #else
/* CODEC is master */ /* CODEC is master */
/* Wait for LRCLK edge */ /* Wait for LRCLK edge */
@@ -287,15 +289,21 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
{ {
outuint(c_out, 0); outuint(c_out, 0);
/* Check for sample freq change or new samples from mixer*/ /* Check for sample freq change (or other command) or new samples from mixer*/
if(testct(c_out)) if(testct(c_out))
{ {
unsigned command;
// Set clocks low // Set clocks low
p_lrclk <: 0; p_lrclk <: 0;
p_bclk <: 0; p_bclk <: 0;
#if(DSD_CHANS_DAC != 0)
inct(c_out); /* DSD Clock might not be shared with lrclk or bclk... */
return inuint(c_out); if(dsdMode)
p_dsd_clk <: 0;
#endif
command = inct(c_out);
return {command, inuint(c_out)};
} }
else else
@@ -363,10 +371,80 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
tmp = 0; tmp = 0;
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0) #if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
if(dsdMode) if(dsdMode == DSD_MODE_NATIVE)
{
/* 8 bits per chan, 1st 1-bit sample in MSB */
dsdSample_l = samplesOut[0];
dsdSample_r = samplesOut[1];
dsdSample_r = bitrev(byterev(dsdSample_r));
dsdSample_l = bitrev(byterev(dsdSample_l));
//if(dsdSample_l != 0)
//testsamples[p++] = dsdSample_l;
//if(p > 20)
//for (int i = 0; i < 20; i++)
// printhexln(testsamples[i]);
//if(lastSample+1 != dsdSample_l)
//{
// printhexln(lastSample);
//}
//lastSample = dsdSample_l;
// Output 32 clocks DSD to all
//p_dsd_dac[0] <: bitrev(dsdSample_l);
//p_dsd_dac[1] <: bitrev(dsdSample_r);
switch (divide*2)
{
case 8:
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[0]),"r"(dsdSample_l));
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[1]),"r"(dsdSample_r));
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
break;
case 4:
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[0]),"r"(dsdSample_l));
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[1]),"r"(dsdSample_r));
p_dsd_clk <: 0xCCCCCCCC;
p_dsd_clk <: 0xCCCCCCCC;
p_dsd_clk <: 0xCCCCCCCC;
p_dsd_clk <: 0xCCCCCCCC;
break;
case 2:
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[0]),"r"(dsdSample_l));
asm volatile("out res[%0], %1"::"r"(p_dsd_dac[1]),"r"(dsdSample_r));
p_dsd_clk <: 0xAAAAAAAA;
p_dsd_clk <: 0xAAAAAAAA;
break;
default:
/* Do some clocks anyway - this will stop us interrupting decouple too much */
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
p_dsd_clk <: 0xF0F0F0F0;
break;
}
}
else if(dsdMode == DSD_MODE_DOP)
{ {
//while(1)
{
if(!everyOther) if(!everyOther)
{ {
dsdSample_l = ((samplesOut[0] & 0xffff00) << 8); dsdSample_l = ((samplesOut[0] & 0xffff00) << 8);
@@ -428,7 +506,6 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
} }
} }
}
} }
else else
#endif #endif
@@ -610,7 +687,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
dsdMarker ^= DSD_MARKER_XOR; dsdMarker ^= DSD_MARKER_XOR;
if(dsdCount == DSD_EN_THRESH) if(dsdCount == DSD_EN_THRESH)
{ {
dsdMode = 1; dsdMode = DSD_MODE_DOP;
dsdCount = 0; dsdCount = 0;
dsdMarker = DSD_MARKER_2; dsdMarker = DSD_MARKER_2;
@@ -618,7 +695,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
p_lrclk <: 0; p_lrclk <: 0;
p_bclk <: 0; p_bclk <: 0;
return 0; return {0,0};
} }
} }
else else
@@ -627,8 +704,9 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
dsdMarker = DSD_MARKER_2; dsdMarker = DSD_MARKER_2;
} }
} }
else // DSD Mode else if(dsdMode == DSD_MODE_DOP) // DSD Mode
{ {
/* If we are running in DOP mode, check if we need to come out */
if((DSD_MASK(samplesOut[0]) != dsdMarker) && (DSD_MASK(samplesOut[1]) != dsdMarker)) if((DSD_MASK(samplesOut[0]) != dsdMarker) && (DSD_MASK(samplesOut[1]) != dsdMarker))
{ {
if(!((dsdCount == 0) && (DSD_MASK(samplesOut[0]) == (dsdMarker ^DSD_MARKER_XOR)) if(!((dsdCount == 0) && (DSD_MASK(samplesOut[0]) == (dsdMarker ^DSD_MARKER_XOR))
@@ -638,19 +716,20 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
dsdMode = 0; dsdMode = 0;
// Set clocks low // Set clocks low
p_dsd_clk <: 0; p_dsd_clk <: 0;
return 0; return {0,0};
} }
} }
} }
#endif #endif
} }
return 0; return {0,0};
} }
/* This function is a dummy version of the deliver thread that does not /* This function is a dummy version of the deliver thread that does not
connect to the codec ports. It is used during DFU reset. */ connect to the codec ports. It is used during DFU reset. */
static unsigned dummy_deliver(chanend c_out) { {unsigned,unsigned} dummy_deliver(chanend c_out)
{
while (1) while (1)
{ {
outuint(c_out, 0); outuint(c_out, 0);
@@ -658,8 +737,8 @@ static unsigned dummy_deliver(chanend c_out) {
/* Check for sample freq change or new samples from mixer*/ /* Check for sample freq change or new samples from mixer*/
if(testct(c_out)) if(testct(c_out))
{ {
inct(c_out); unsigned command = inct(c_out);
return inuint(c_out); return {command, inuint(c_out)};
} }
else else
@@ -692,7 +771,7 @@ static unsigned dummy_deliver(chanend c_out) {
#endif #endif
} }
} }
return 0; return {0,0};
} }
#define SAMPLE_RATE 200000 #define SAMPLE_RATE 200000
#define NUMBER_CHANNELS 1 #define NUMBER_CHANNELS 1
@@ -707,7 +786,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
chan c_spdif_out; chan c_spdif_out;
#endif #endif
unsigned curSamFreq = DEFAULT_FREQ; unsigned curSamFreq = DEFAULT_FREQ;
unsigned retVal; unsigned retVal1, retVal2;
unsigned mClk; unsigned mClk;
unsigned divide; unsigned divide;
unsigned firstRun = 1; unsigned firstRun = 1;
@@ -821,7 +900,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
{ {
/* TODO wait for good mclk instead of delay */ /* TODO wait for good mclk instead of delay */
/* No delay for DFU modes */ /* No delay for DFU modes */
if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU) && retVal) if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU) && retVal1)
{ {
timer t; timer t;
unsigned time; unsigned time;
@@ -853,33 +932,30 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
outuint(c_spdif_out, mClk); outuint(c_spdif_out, mClk);
#endif #endif
retVal = deliver(c_mix_out, {retVal1, retVal2} = deliver(c_mix_out,
#ifdef SPDIF #ifdef SPDIF
c_spdif_out, c_spdif_out,
#else #else
null, null,
#endif #endif
divide, c_dig_rx, c); divide, c_dig_rx, c);
// TODO TIDY THIS!
//if(dsdMode)
//p_dsd_clk <: 0;
//else
//p_bclk <: 0;
#if (DSD_CHANS_DAC != 0) #if (DSD_CHANS_DAC != 0)
if(retVal == 0) if(retVal1 == SET_SAMPLE_FREQ)
{ {
// Check DSD mode here.. curSamFreq = retVal2;
} }
else else if(retVal1 == SET_DSD_MODE)
{ {
curSamFreq = retVal; /* Off = 0
* DOP = 1
* Native = 2
*/
dsdMode = retVal2;
} }
#else #else
curSamFreq = retVal; curSamFreq = retVal2;
#endif #endif
// Currently no more audio will happen after this point // Currently no more audio will happen after this point
@@ -890,7 +966,7 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
while (1) while (1)
{ {
curSamFreq = dummy_deliver(c_mix_out); {retVal1, curSamFreq} = dummy_deliver(c_mix_out);
if (curSamFreq == AUDIO_START_FROM_DFU) if (curSamFreq == AUDIO_START_FROM_DFU)
{ {

View File

@@ -26,5 +26,10 @@
#define SET_CHAN_COUNT_IN 5 #define SET_CHAN_COUNT_IN 5
#define SET_CHAN_COUNT_OUT 6 #define SET_CHAN_COUNT_OUT 6
#define SET_DSD_MODE 7
#define DSD_MODE_OFF 0
#define DSD_MODE_DOP 1
#define DSD_MODE_NATIVE 2

View File

@@ -216,34 +216,35 @@ unsigned char devQualDesc_Null[] =
#ifdef ADAT_RX #ifdef ADAT_RX
#define INPUT_ALT_LENGTH (46) #define INPUT_ALT_LENGTH (46)
#else #else
#define INPUT_ALT_LENGTH (0) #define INPUT_ALT_LENGTH (0)
#endif #endif
#ifdef ADAT_TX #ifdef ADAT_TX
#define OUTPUT_ALT_LENGTH_ADAT (46) #define OUTPUT_ALT_LENGTH_ADAT (46)
#else #else
#define OUTPUT_ALT_LENGTH_ADAT (0) #define OUTPUT_ALT_LENGTH_ADAT (0)
#endif #endif
#ifdef NATIVE_DSD #ifdef NATIVE_DSD
#define ALT_SETTING_DSD (2) #define ALT_SETTING_DSD (2)
#endif #endif
#ifdef ALT_SETTING_DSD #ifdef ALT_SETTING_DSD
#define ALT_SETTING_ADAT_TX (3) #define ALT_SETTING_ADAT_TX (3)
#define OUTPUT_ALT_LENGTH_DSD (46) #define OUTPUT_ALT_LENGTH_DSD (53)
#else #else
#define ALT_SETTING_ADAT_TX (2) #define ALT_SETTING_ADAT_TX (2)
#define OUTPUT_ALT_LENGTH_DSD (0) #define OUTPUT_ALT_LENGTH_DSD (0)
#endif #endif
#define OUTPUT_ALT_LENGTH (OUTPUT_ALT_LENGTH_ADAT + OUTPUT_ALT_LENGTH_DSD) #define OUTPUT_ALT_LENGTH (OUTPUT_ALT_LENGTH_ADAT + OUTPUT_ALT_LENGTH_DSD)
// Positions in strDescs_Audio2 // Positions in strDescs_Audio2
#define INTERNAL_CLOCK_STRING_INDEX 14 #define INTERNAL_CLOCK_STRING_INDEX (14)
#define SPDIF_CLOCK_STRING_INDEX 15 #define SPDIF_CLOCK_STRING_INDEX (15)
#ifdef SPDIF_RX #ifdef SPDIF_RX
#define ADAT_CLOCK_STRING_INDEX (SPDIF_CLOCK_STRING_INDEX + 1) #define ADAT_CLOCK_STRING_INDEX (SPDIF_CLOCK_STRING_INDEX + 1)
@@ -304,7 +305,7 @@ unsigned char hidReportDescriptor[] = {
#endif #endif
#define HID_LENGTH (25*HID_INTERFACES) #define HID_LENGTH (25 * HID_INTERFACES)
/* Total length of config descriptor */ /* Total length of config descriptor */
#define CFG_TOTAL_LENGTH_A2 (7 + 19 + (AUD_INT_EP_LEN) + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH + HID_LENGTH) #define CFG_TOTAL_LENGTH_A2 (7 + 19 + (AUD_INT_EP_LEN) + (INPUT_INTERFACES * 55) + (OUTPUT_INTERFACES * 62) + (MIDI_LENGTH) + (DFU_INTERFACES * 18) + TLEN_AC + (MIXER_LENGTH) + IAP_LENGTH + INPUT_ALT_LENGTH + OUTPUT_ALT_LENGTH + HID_LENGTH)
@@ -439,7 +440,7 @@ unsigned char cfgDesc_Audio2[] =
0x03, /* 5 bmControls 0x03, /* 5 bmControls
D[1:0] : Clock Selector Control D[1:0] : Clock Selector Control
D[7:4] : Reserved (0) */ D[7:4] : Reserved (0) */
8, /* 7 iClockSel (String Index) */ 13, /* 7 iClockSel (String Index) */
#ifdef OUTPUT #ifdef OUTPUT
/* OUTPUT PATH FROM HOST TO DEVICE */ /* OUTPUT PATH FROM HOST TO DEVICE */
@@ -825,7 +826,7 @@ unsigned char cfgDesc_Audio2[] =
PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ PCM, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */
NUM_USB_CHAN_OUT, /* 11 bNrChannels */ NUM_USB_CHAN_OUT, /* 11 bNrChannels */
0,0,0,0, /* 12:14: bmChannelConfig */ 0,0,0,0, /* 12:14: bmChannelConfig */
OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */
/* Type 1 Format Type Descriptor */ /* Type 1 Format Type Descriptor */
0x06, /* 0 bLength (in bytes): 6 */ 0x06, /* 0 bLength (in bytes): 6 */
@@ -858,7 +859,7 @@ unsigned char cfgDesc_Audio2[] =
0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
17, /* 3 bmAttributes (bitmap) */ 17, /* 3 bmAttributes (bitmap) */
4,0, /* 4 wMaxPacketSize */ 4,0, /* 4 wMaxPacketSize */
4, /* 6 bInterval. Only values <= 1 frame (8) supported by MS */ 4, /* 6 bInterval. Only values <= 1 frame (4) supported by MS */
#ifdef NATIVE_DSD #ifdef NATIVE_DSD
/* Standard AS Interface Descriptor (4.9.1) (Alt) */ /* Standard AS Interface Descriptor (4.9.1) (Alt) */
@@ -879,10 +880,10 @@ unsigned char cfgDesc_Audio2[] =
ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */ ID_IT_USB, /* 3 bTerminalLink (Linked to USB input terminal) */
0x00, /* 4 bmControls */ 0x00, /* 4 bmControls */
0x01, /* 5 bFormatType */ 0x01, /* 5 bFormatType */
TYPE_1_RAW_DATA, 0x00, 0x00, 0x00, /* 6:10 bmFormats (note this is a bitmap) */ 0x00, 0x00, 0x00, TYPE_1_RAW_DATA, /* 6:10 bmFormats (note this is a bitmap) */
NUM_USB_CHAN_OUT, /* 11 bNrChannels */ NUM_USB_CHAN_OUT, /* 11 bNrChannels */
0,0,0,0, /* 12:14: bmChannelConfig */ 0,0,0,0, /* 12:14: bmChannelConfig */
INPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */ OUTPUT_INTERFACE_STRING_INDEX, /* 15 iChannelNames */
/* Type 1 Format Type Descriptor */ /* Type 1 Format Type Descriptor */
0x06, /* 0 bLength (in bytes): 6 */ 0x06, /* 0 bLength (in bytes): 6 */
@@ -915,7 +916,7 @@ unsigned char cfgDesc_Audio2[] =
0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
17, /* 3 bmAttributes (bitmap) */ 17, /* 3 bmAttributes (bitmap) */
4,0, /* 4 wMaxPacketSize */ 4,0, /* 4 wMaxPacketSize */
8, /* 6 bInterval */ 4, /* 6 bInterval */
#endif /* NATIVE_DSD */ #endif /* NATIVE_DSD */
@@ -975,7 +976,7 @@ unsigned char cfgDesc_Audio2[] =
0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */
17, /* 3 bmAttributes (bitmap) */ 17, /* 3 bmAttributes (bitmap) */
4,0, /* 4 wMaxPacketSize */ 4,0, /* 4 wMaxPacketSize */
8, /* 6 bInterval */ 4, /* 6 bInterval */
#endif /* ADAT_TX */ #endif /* ADAT_TX */
#endif /* OUTPUT */ #endif /* OUTPUT */

View File

@@ -5,7 +5,6 @@
*/ */
#include <xs1.h> #include <xs1.h>
#include <print.h>
#include <safestring.h> #include <safestring.h>
#include "xud.h" /* XUD user defines and functions */ #include "xud.h" /* XUD user defines and functions */
@@ -302,6 +301,12 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
switch(sp.wValue) switch(sp.wValue)
{ {
case 0: case 0:
#ifdef NATIVE_DSD
outuint(c_audioControl, SET_DSD_MODE);
outuint(c_audioControl, DSD_MODE_OFF);
// Handshake
chkct(c_audioControl, XS1_CT_END);
#endif /* NATIVE_DSD */
break; break;
case 1: case 1:
/* Stream active + 0 chans */ /* Stream active + 0 chans */
@@ -317,7 +322,28 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
outuint(c_audioControl, SET_CHAN_COUNT_OUT); outuint(c_audioControl, SET_CHAN_COUNT_OUT);
outuint(c_audioControl, NUM_USB_CHAN_OUT_A1); outuint(c_audioControl, NUM_USB_CHAN_OUT_A1);
} }
#ifdef NATIVE_DSD
outuint(c_audioControl, SET_DSD_MODE);
outuint(c_audioControl, DSD_MODE_OFF);
// Handshake
chkct(c_audioControl, XS1_CT_END);
#endif /* NATIVE_DSD */
break; break;
#ifdef NATIVE_DSD
case 2:
outuint(c_audioControl, SET_DSD_MODE);
outuint(c_audioControl, DSD_MODE_NATIVE);
// Handshake
chkct(c_audioControl, XS1_CT_END);
break;
#endif /* NATIVE_DSD */
} }
} }
else if(sp.wIndex == 2) // Input interface else if(sp.wIndex == 2) // Input interface

View File

@@ -164,7 +164,7 @@ XUD_EpType epTypeTableIn[EP_CNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE,
XUD_EPTYPE_BUL, XUD_EPTYPE_BUL,
#endif #endif
#ifdef HID_CONTROLS #ifdef HID_CONTROLS
XUD_EPTYPE_BUL, XUD_EPTYPE_INT,
#endif #endif
#ifdef IAP #ifdef IAP
XUD_EPTYPE_BUL, XUD_EPTYPE_BUL,

View File

@@ -190,6 +190,7 @@ void handle_audio_request(chanend c_mix_out)
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i)); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multIn),"r"(i));
{h, l} = macs(mult, sample, 0, 0); {h, l} = macs(mult, sample, 0, 0);
sample = h << 3; sample = h << 3;
sample |= (l >> 29) & 0x7; // Note, this step is not required if we assume sample depth is 24 (rather than 32)
#elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX) #elif defined(IN_VOLUME_IN_MIXER) && defined(IN_VOLUME_AFTER_MIX)
sample = sample << 3; sample = sample << 3;
#endif #endif
@@ -296,6 +297,7 @@ void handle_audio_request(chanend c_mix_out)
asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i)); asm("ldw %0, %1[%2]":"=r"(mult):"r"(p_multOut),"r"(i));
{h, l} = macs(mult, sample, 0, 0); {h, l} = macs(mult, sample, 0, 0);
h <<= 3; h <<= 3;
h |= (l >>29)& 0x7; // Note this step is not required if we assume sample depth is 24bit (rather than 32bit)
outuint(c_mix_out, h); outuint(c_mix_out, h);
#else #else
outuint(c_mix_out, sample); outuint(c_mix_out, sample);
@@ -670,7 +672,7 @@ void decouple(chanend c_mix_out,
/* Pass on to mixer */ /* Pass on to mixer */
DISABLE_INTERRUPTS(); DISABLE_INTERRUPTS();
inuint(c_mix_out); inuint(c_mix_out);
outct(c_mix_out, 9); outct(c_mix_out, SET_SAMPLE_FREQ);
outuint(c_mix_out, sampFreq); outuint(c_mix_out, sampFreq);
inOverflow = 0; inOverflow = 0;
@@ -778,6 +780,41 @@ void decouple(chanend c_mix_out,
SET_SHARED_GLOBAL(g_freqChange, 0); SET_SHARED_GLOBAL(g_freqChange, 0);
ENABLE_INTERRUPTS(); ENABLE_INTERRUPTS();
} }
#ifdef NATIVE_DSD
else if(tmp == SET_DSD_MODE)
{
unsigned dsdMode;
DISABLE_INTERRUPTS();
/* Clear the buffer as we dont want to send out old PCM samples.. */
SET_SHARED_GLOBAL(g_freqChange_flag, 0);
GET_SHARED_GLOBAL(dsdMode, g_freqChange_sampFreq); /* Misuse of g_freqChange_sampFreq */
/* Reset OUT buffer state */
SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start);
SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start);
outUnderflow = 1;
if(outOverflow)
{
/* If we were previously in overflow we wont have marked as ready */
XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_fifo_start+4);
outOverflow = 0;
}
inuint(c_mix_out);
outct(c_mix_out, SET_DSD_MODE);
outuint(c_mix_out, dsdMode);
/* Wait for handshake back */
chkct(c_mix_out, XS1_CT_END);
SET_SHARED_GLOBAL(g_freqChange, 0);
asm("outct res[%0],%1"::"r"(buffer_aud_ctl_chan),"r"(XS1_CT_END));
ENABLE_INTERRUPTS();
}
#endif
} }
#ifdef OUTPUT #ifdef OUTPUT

View File

@@ -278,7 +278,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
} }
#endif #endif
/* Sample Freq our chan count update from ep 0 */ /* Sample Freq or chan count update from ep 0 */
case testct_byref(c_aud_ctl, u_tmp): case testct_byref(c_aud_ctl, u_tmp):
{ {
if (u_tmp) if (u_tmp)
@@ -354,19 +354,18 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
else else
{ {
sampleFreq = inuint(c_aud_ctl); sampleFreq = inuint(c_aud_ctl);
SET_SHARED_GLOBAL0(g_freqChange, tmp); /* Set command */
SET_SHARED_GLOBAL0(g_freqChange, tmp); /* Set command */
SET_SHARED_GLOBAL(g_freqChange_sampFreq, sampleFreq); /* Set flag */ SET_SHARED_GLOBAL(g_freqChange_sampFreq, sampleFreq); /* Set flag */
SET_SHARED_GLOBAL(g_freqChange_flag, tmp); SET_SHARED_GLOBAL(g_freqChange_flag, tmp);
} }
} }
break; break;
} }
#define MASK_16_13 (7) // Bits that should not be transmitted as part of feedback. #define MASK_16_13 (7) /* Bits that should not be transmitted as part of feedback */
#define MASK_16_10 (127) //(63) /* For Audio 1.0 we use a mask 1 bit longer than expected to avoid Windows LSB isses */ #define MASK_16_10 (127) /* For Audio 1.0 we use a mask 1 bit longer than expected to avoid Windows LSB issues */
/* (previously used 63 instead of 127) */
case inuint_byref(c_sof, u_tmp): case inuint_byref(c_sof, u_tmp):
@@ -381,7 +380,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
if(freqChange == SET_SAMPLE_FREQ) if(freqChange == SET_SAMPLE_FREQ)
{ {
/* Keep getting MCLK counts */ /* Keep getting MCLK counts */
lastClock = u_tmp; lastClock = u_tmp;
} }
else else
{ {
@@ -434,7 +433,9 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
} }
} }
#ifdef FB_TOLERANCE_TEST #ifdef FB_TOLERANCE_TEST
else { else
{
} }
#endif #endif
clocks = 0; clocks = 0;
@@ -697,7 +698,6 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud
else else
{ {
// Too many events from device - drop // Too many events from device - drop
//printstr("DROP");
} }
/* Once we have the whole message, sent it to host */ /* Once we have the whole message, sent it to host */