Working to add generic DSD support

This commit is contained in:
Ross Owen
2013-05-28 17:24:40 +01:00
parent ce2bcacb16
commit 5adbe0c4a6
4 changed files with 264 additions and 54 deletions

View File

@@ -14,9 +14,9 @@
#include <print.h> #include <print.h>
#include <xs1_su.h> #include <xs1_su.h>
#include "devicedefines.h"
#include "audioports.h" #include "audioports.h"
#include "audiohw.h" #include "audiohw.h"
#include "devicedefines.h"
#include "SpdifTransmit.h" #include "SpdifTransmit.h"
//#define DSD_OUTPUT 1 //#define DSD_OUTPUT 1
@@ -52,9 +52,8 @@ extern in port p_bclk;
unsigned dsdMode = 0; unsigned dsdMode = 0;
#ifdef DSD_OUTPUT #ifdef DSD_OUTPUT
#define p_dsd_clk p_bclk
#define p_dsd_left p_i2s_dac[0]
#define p_dsd_right p_lrclk
#define DSD_MARKER_1 0xFA #define DSD_MARKER_1 0xFA
#define DSD_MARKER_2 0x05 #define DSD_MARKER_2 0x05
#define DSD_MARKER_XOR 0xFF #define DSD_MARKER_XOR 0xFF
@@ -76,6 +75,9 @@ extern clock clk_mst_spd;
extern void device_reboot(void); 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 deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc)
@@ -100,7 +102,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
#ifdef DSD_OUTPUT #ifdef DSD_OUTPUT
unsigned dsdMarker = DSD_MARKER_2; /* This alternates between DSD_MARKER_1 and DSD_MARKER_2 */ unsigned dsdMarker = DSD_MARKER_2; /* This alternates between DSD_MARKER_1 and DSD_MARKER_2 */
int dsdCount = 0; int dsdCount = 0;
int everyOther = 0; int everyOther = 1;
unsigned dsdSample_l = 0; unsigned dsdSample_l = 0;
unsigned dsdSample_r = 0; unsigned dsdSample_r = 0;
#endif #endif
@@ -162,6 +164,9 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
} }
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
if(!dsdMode)
{
/* Clear I2S port buffers */ /* Clear I2S port buffers */
clearbuf(p_lrclk); clearbuf(p_lrclk);
@@ -219,6 +224,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
} }
#endif #endif
p_lrclk <: 0x7FFFFFFF; p_lrclk <: 0x7FFFFFFF;
switch (divide) switch (divide)
{ {
@@ -246,6 +252,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_
break; break;
} }
} }
}
#else #else
/* CODEC is master */ /* CODEC is master */
/* Wait for LRCLK edge */ /* Wait for LRCLK edge */
@@ -754,14 +761,40 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
/* Calculate divide required for bit clock e.g. 11.289600 / (176400 * 64) = 1 */ /* Calculate divide required for bit clock e.g. 11.289600 / (176400 * 64) = 1 */
divide = mClk / ( curSamFreq * 64 ); divide = mClk / ( curSamFreq * 64 );
/* Configure clocking for required master clock */ /* Configure Clocking/CODEC/DAC/ADC for SampleFreq/MClk */
//ClockingConfig(mClk, c_config);
/* Configure CODEC/DAC/ADC for SampleFreq/MClk */
AudioHwConfig(curSamFreq, mClk, c_config, dsdMode); AudioHwConfig(curSamFreq, mClk, c_config, dsdMode);
/* Configure audio ports */ /* Configure audio ports */
ConfigAudioPorts(divide); if(dsdMode)
{
/* re-arrange ports */
//ConfigAudioPorts_dsd(divide);
//unsigned dsdDataPorts[I2S_CHANS_DAC];
//dsdDataPorts = p_dsd_left;
}
else
{
ConfigAudioPortsWrapper(
#if (I2S_CHANS_DAC != 0)
p_i2s_dac,
#endif
#if (I2S_CHANS_ADC != 0)
p_i2s_adc,
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
p_lrclk,
p_bclk,
#else
p_lrclk,
p_bclk,
#endif
#endif
divide, dsdMode);
}
if(!firstRun) if(!firstRun)
{ {
@@ -807,6 +840,13 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c)
#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;
#ifdef DSD_OUTPUT #ifdef DSD_OUTPUT
if(retVal == 0) if(retVal == 0)
{ {

View File

@@ -30,7 +30,7 @@
/* Audio I/O */ /* Audio I/O */
#if I2S_WIRES_DAC > 0 #if I2S_WIRES_DAC > 0
on stdcore[0] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = on tile[0] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
{PORT_I2S_DAC0, {PORT_I2S_DAC0,
#endif #endif
#if I2S_WIRES_DAC > 1 #if I2S_WIRES_DAC > 1
@@ -59,7 +59,7 @@ on stdcore[0] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] =
#endif #endif
#if I2S_WIRES_ADC > 0 #if I2S_WIRES_ADC > 0
on stdcore[0] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] = on tile[0] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] =
{PORT_I2S_ADC0, {PORT_I2S_ADC0,
#endif #endif
#if I2S_WIRES_ADC > 1 #if I2S_WIRES_ADC > 1
@@ -92,40 +92,40 @@ on stdcore[0] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] =
#endif #endif
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
on stdcore[AUDIO_IO_CORE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK; on tile[AUDIO_IO_CORE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK;
on stdcore[AUDIO_IO_CORE] : buffered out port:32 p_bclk = PORT_I2S_BCLK; on tile[AUDIO_IO_CORE] : buffered out port:32 p_bclk = PORT_I2S_BCLK;
#else #else
on stdcore[AUDIO_IO_CORE] : in port p_lrclk = PORT_I2S_LRCLK; on tile[AUDIO_IO_CORE] : in port p_lrclk = PORT_I2S_LRCLK;
on stdcore[AUDIO_IO_CORE] : in port p_bclk = PORT_I2S_BCLK; on tile[AUDIO_IO_CORE] : in port p_bclk = PORT_I2S_BCLK;
#endif #endif
on stdcore[AUDIO_IO_CORE] : port p_mclk = PORT_MCLK_IN; on tile[AUDIO_IO_CORE] : port p_mclk = PORT_MCLK_IN;
on stdcore[0] : in port p_for_mclk_count = PORT_MCLK_COUNT; on tile[0] : in port p_for_mclk_count = PORT_MCLK_COUNT;
#ifdef SPDIF #ifdef SPDIF
on stdcore[AUDIO_IO_CORE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; on tile[AUDIO_IO_CORE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT;
#endif #endif
#ifdef MIDI #ifdef MIDI
on stdcore[AUDIO_IO_CORE] : port p_midi_tx = PORT_MIDI_OUT; on tile[AUDIO_IO_CORE] : port p_midi_tx = PORT_MIDI_OUT;
on stdcore[AUDIO_IO_CORE] : port p_midi_rx = PORT_MIDI_IN; on tile[AUDIO_IO_CORE] : port p_midi_rx = PORT_MIDI_IN;
#endif #endif
/* Clock blocks */ /* Clock blocks */
#ifdef MIDI #ifdef MIDI
on stdcore[AUDIO_IO_CORE] : clock clk_midi = XS1_CLKBLK_REF; on tile[AUDIO_IO_CORE] : clock clk_midi = XS1_CLKBLK_REF;
#endif #endif
on stdcore[AUDIO_IO_CORE] : clock clk_audio_mclk = XS1_CLKBLK_2; /* Master clock */ on tile[AUDIO_IO_CORE] : clock clk_audio_mclk = XS1_CLKBLK_2; /* Master clock */
on stdcore[AUDIO_IO_CORE] : clock clk_audio_bclk = XS1_CLKBLK_3; /* Bit clock */ on tile[AUDIO_IO_CORE] : clock clk_audio_bclk = XS1_CLKBLK_3; /* Bit clock */
#ifdef SPDIF #ifdef SPDIF
on stdcore[AUDIO_IO_CORE] : clock clk_mst_spd = XS1_CLKBLK_1; on tile[AUDIO_IO_CORE] : clock clk_mst_spd = XS1_CLKBLK_1;
#endif #endif
/* L Series needs a port to use for USB reset */ /* L Series needs a port to use for USB reset */
#ifdef ARCH_L #ifdef ARCH_L
#ifdef PORT_USB_RESET #ifdef PORT_USB_RESET
/* This define is checked since it could be on a shift reg or similar */ /* This define is checked since it could be on a shift reg or similar */
on stdcore[0] : out port p_usb_rst = PORT_USB_RESET; on tile[0] : out port p_usb_rst = PORT_USB_RESET;
#endif #endif
/* L Series also needs a clock for this port */ /* L Series also needs a clock for this port */
clock clk = XS1_CLKBLK_4; clock clk = XS1_CLKBLK_4;
@@ -216,22 +216,22 @@ int main()
/* USB Interface */ /* USB Interface */
#if (AUDIO_CLASS==2) #if (AUDIO_CLASS==2)
on stdcore[0]: XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN, on tile[0]: XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN,
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
clk, 1, XUD_SPEED_HS, c_usb_test); clk, 1, XUD_SPEED_HS, c_usb_test);
#else #else
on stdcore[0]:XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN, on tile[0]:XUD_Manager(c_xud_out, EP_CNT_OUT, c_xud_in, EP_CNT_IN,
c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst,
clk, 1, XUD_SPEED_FS, c_usb_test); clk, 1, XUD_SPEED_FS, c_usb_test);
#endif #endif
/* Endpoint 0 */ /* Endpoint 0 */
on stdcore[0]:{ on tile[0]:{
thread_speed(); thread_speed();
Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, null, null, c_usb_test); Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, null, null, c_usb_test);
} }
on stdcore[0]: on tile[0]:
{ {
thread_speed(); thread_speed();
@@ -266,14 +266,14 @@ int main()
} }
on stdcore[0]: on tile[0]:
{ {
thread_speed(); thread_speed();
decouple(c_mix_out, null decouple(c_mix_out, null
); );
} }
on stdcore[AUDIO_IO_CORE]: on tile[AUDIO_IO_CORE]:
{ {
thread_speed(); thread_speed();
@@ -282,7 +282,7 @@ int main()
} }
#if defined (MIDI) || defined IAP #if defined (MIDI) || defined IAP
on stdcore[AUDIO_IO_CORE]: on tile[AUDIO_IO_CORE]:
{ {
thread_speed(); thread_speed();
#ifdef MIDI #ifdef MIDI

View File

@@ -1,6 +1,104 @@
#ifndef _AUDIOPORTS_H_ #ifndef _AUDIOPORTS_H_
#define _AUDIOPORTS_H_ #define _AUDIOPORTS_H_
void ConfigAudioPorts(unsigned int divide); #include <xccompat.h>
#include "devicedefines.h"
void ConfigAudioPorts_dsd(unsigned int divide);
#ifdef __XC__
void ConfigAudioPorts(
#if (I2S_CHANS_DAC != 0)
buffered out port:32 p_i2s_dac[I2S_WIRES_DAC],
#endif #endif
#if (I2S_CHANS_ADC != 0)
buffered in port:32 p_i2s_adc[I2S_WIRES_ADC],
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
buffered out port:32 p_lrclk,
buffered out port:32 p_bclk,
#else
in port p_lrclk,
in port p_bclk,
#endif
#endif
unsigned int divide);
#else
void ConfigAudioPorts(
#if (I2S_CHANS_DAC != 0)
port p_i2s_dac[I2S_WIRES_DAC],
#endif
#if (I2S_CHANS_ADC != 0)
port p_i2s_adc[I2S_WIRES_ADC],
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
port p_lrclk,
port p_bclk,
#else
port p_lrclk,
port p_bclk,
#endif
#endif
unsigned int divide);
#endif /* __XC__*/
#ifdef __XC__
void ConfigAudioPortsWrapper(
#if (I2S_CHANS_DAC != 0)
buffered out port:32 p_i2s_dac[I2S_WIRES_DAC],
#endif
#if (I2S_CHANS_ADC != 0)
buffered in port:32 p_i2s_adc[I2S_WIRES_ADC],
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
buffered out port:32 p_lrclk,
buffered out port:32 p_bclk,
#else
in port p_lrclk,
in port p_bclk,
#endif
#endif
unsigned int divide, unsigned int dsdMode);
#else
void ConfigAudioPortsWrapper(
#if (I2S_CHANS_DAC != 0)
port p_i2s_dac[I2S_WIRES_DAC],
#endif
#if (I2S_CHANS_ADC != 0)
port p_i2s_adc[I2S_WIRES_ADC],
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
port p_lrclk,
port p_bclk,
#else
port p_lrclk,
port p_bclk,
#endif
#endif
unsigned int divide, unsigned int dsdMode);
#endif /* __XC__*/
#endif /* _AUDIOPORTS_H_ */

View File

@@ -1,33 +1,42 @@
#include <xs1.h> #include <xs1.h>
#include <xccompat.h>
#include "devicedefines.h" #include "devicedefines.h"
#include "audioports.h" #include "audioports.h"
/* Audio IOs */ /* Configure audio ports. This is in C such that can we can mess around with arrays of ports */
#if (I2S_CHANS_DAC != 0) //extern void configure_in_port_no_ready(port p, const clock clk);
extern buffered out port:32 p_i2s_dac[I2S_WIRES_DAC]; //extern void configure_out_port_no_ready(port p, const clock clk, unsigned initial);
#endif //extern void configure_clock_src(clock clk, port p);
#if (I2S_CHANS_ADC != 0)
extern buffered in port:32 p_i2s_adc[I2S_WIRES_ADC];
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
extern buffered out port:32 p_lrclk;
extern buffered out port:32 p_bclk;
#else
extern in port p_lrclk;
extern in port p_bclk;
#endif
#endif
extern port p_mclk; extern port p_mclk;
extern clock clk_audio_mclk; extern clock clk_audio_mclk;
extern clock clk_audio_bclk; extern clock clk_audio_bclk;
void ConfigAudioPorts(unsigned int divide) void ConfigAudioPorts(
#if (I2S_CHANS_DAC != 0)
buffered out port:32 p_i2s_dac[I2S_WIRES_DAC],
// port p_i2s_dac[I2S_WIRES_DAC],
#endif
#if (I2S_CHANS_ADC != 0)
buffered in port:32 p_i2s_adc[I2S_WIRES_ADC],
// port p_i2s_adc[I2S_WIRES_ADC],
#endif
#if (I2S_CHANS_DAC != 0) || (I2S_CHANS_ADC != 0)
#ifndef CODEC_MASTER
buffered out port:32 p_lrclk,
buffered out port:32 p_bclk,
//port p_lrclk,
//port p_bclk,
#else
in port p_lrclk,
in port p_bclk,
#endif
#endif
unsigned int divide)
{ {
#ifndef CODEC_MASTER #ifndef CODEC_MASTER
@@ -105,7 +114,7 @@ void ConfigAudioPorts(unsigned int divide)
start_clock(clk_audio_bclk); start_clock(clk_audio_bclk);
/* bclk initial state needs to be high */ /* bclk initial state needs to be high */
p_bclk <: 0xFFFFFFFF; //p_bclk <: 0xFFFFFFFF;
/* Pause until output completes */ /* Pause until output completes */
sync(p_bclk); sync(p_bclk);
@@ -142,3 +151,66 @@ void ConfigAudioPorts(unsigned int divide)
#endif #endif
} }
#if 0
void ConfigAudioPorts_dsd(unsigned int divide)
{
#ifndef CODEC_MASTER
/* Output 0 on BCLK to ensure clock is low
* Required as stop_clock will only complete when the clock is low
*/
//configure_out_port_no_ready(p_dsd_clk, clk_audio_bclk, 0);
//configure_clock_src(clk_audio_mclk, p_mclk);
configure_out_port_no_ready(p_dsd_clk, clk_audio_mclk, 0);
p_dsd_clk <: 0;
/* Stop bit and master clock blocks and clear port buffers */
stop_clock(clk_audio_bclk);
stop_clock(clk_audio_mclk);
clearbuf(p_dsd_clk);
clearbuf(p_dsd_left);
clearbuf(p_dsd_right);
/* Clock master clock-block from master-clock port */
configure_clock_src(clk_audio_mclk, p_mclk);
/* For a divide of one (i.e. bitclock == master-clock) BClk is set to clock_output mode.
* In this mode it outputs an edge clock on every tick of itsassociated clock_block.
*
* For all other divides, BClk is clocked by the master clock and data
* will be output to p_bclk to generate the bit clock.
*/
if (divide == 1) /* e.g. 176.4KHz from 11.2896 */
{
configure_port_clock_output(p_dsd_clk, clk_audio_mclk);
}
else
{
/* bit clock port from master clock clock-clock block */
configure_out_port_no_ready(p_dsd_clk, clk_audio_mclk, 0);
}
/* bclk clock-blocked clocked by dsd_clk pin */
configure_clock_src(clk_audio_bclk, p_dsd_clk);
configure_out_port_no_ready(p_dsd_left, clk_audio_bclk, 0);
configure_out_port_no_ready(p_dsd_right, clk_audio_bclk, 0);
/* Start clock blocks ticking */
start_clock(clk_audio_mclk);
start_clock(clk_audio_bclk);
/* bclk initial state needs to be high */
p_dsd_clk<: 0xFFFFFFFF;
/* Pause until output completes */
sync(p_dsd_clk);
#else /* CODEC_MASTER */
#error CODEC MASTER for DSD not currently implemented
#endif
}
#endif