how to implement I2S slave and DSD port

Technical questions regarding the XTC tools and programming with XMOS.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

how to implement I2S slave and DSD port

Post by hushange »

with firmware 6.15.2, we know I2S port shared some pins with DSD ports in app_usb_aud_skc_su1.

DSD ports:
<Port Location="XS1_PORT_1A" Name="PORT_DSD_CLK"/>
<Port Location="XS1_PORT_1C" Name="PORT_DSD_DAC0"/>
<Port Location="XS1_PORT_1D" Name="PORT_DSD_DAC1"/>

I2S ports:
<Port Location="XS1_PORT_1A" Name="PORT_I2S_BCLK"/>
<Port Location="XS1_PORT_1C" Name="PORT_I2S_LRCLK"/>
<Port Location="XS1_PORT_1D" Name="PORT_I2S_DAC0"/>

this is working well for CODEC_MASTER=0 with DSD_CHANS_DAC=2.

but now i want make some diffrience: we need to set xmos as I2S slave, also support DSD,
so it is: CODEC_MASTER=1 with DSD_CHANS_DAC=2, when i compile there is some errors:

sc_usb_audio/module_usb_audio/audio.xc:793:21: error: output to an input-designated port
p_lrclk <: 0;
^~~~~~~
sc_usb_audio/module_usb_audio/audio.xc:794:21: error: output to an input-designated port
p_bclk <: 0;

1. i know this error's mean: I2S port is input, but used for output, so how to haddle this error?
2. whether the firmware can support CODEC_MASTER=1 with DSD_CHANS_DAC=2 ? how to implement it ?
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1142
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

Hi - can you clarify what you need?

Is it:
- I2S slave with DSD master
or
- I2S slave with DSD slave?

DSD currently assumes I2S master in the reference design, as you can see from the errors. DSD also assumes to always be the master. This can be changed (all of the I/O is soft) but will require you to do some modification/testing.
Let me know what your goal is and I'll try to provide some pointers.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Post by hushange »

yes, we want I2S slave with DSD slave.
now dsd always be master, how to implement dsd slave.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Post by hushange »

we want I2S slave with DSD slave.
1. codec is I2S master, receive data from xmos
2. codec is dsd master, receive data from xmos
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1142
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

OK, I think this looks possible. There is no frame synch or anything to worry about - just clocked data in a 1b stream.

So you will need to:

Code: Select all

change extern buffered out port:32 p_dsd_clk:
to

Code: Select all

extern buffered in port:32 p_dsd_clk:
remove all:
p_dsd_clk <: xxxxx
and ensure p_dsd_clk gets set to an input. This can be found in audioports.xc with the right code guareded by

Code: Select all

CODEC_MASTER
This is a quick (and very high level) answer and I have not tried this. It will require some time to do this, but I think it should be feasible.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Post by hushange »

infiniteimprobability wrote:OK, I think this looks possible. There is no frame synch or anything to worry about - just clocked data in a 1b stream.

So you will need to:

Code: Select all

change extern buffered out port:32 p_dsd_clk:
to

Code: Select all

extern buffered in port:32 p_dsd_clk:
remove all:
p_dsd_clk <: xxxxx
and ensure p_dsd_clk gets set to an input. This can be found in audioports.xc with the right code guareded by

Code: Select all

CODEC_MASTER
This is a quick (and very high level) answer and I have not tried this. It will require some time to do this, but I think it should be feasible.
---- as you described above, now i can listen the audio as xmos is DSD slave, but there is some noise. many thanks to you. i will take more hard to improve it.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Post by hushange »

i have make some change as you descripbed with app_usb_aud_skc_su1 in firmware 6.15.2. and i take a testing this changes on board XP-SKC-SU1:

test condition:
1. set XMOS as I2S slave
2. change p_dsd_clk as input, and get p_dsd_clk input from other board, which aways playing DSD song repeatly.

the testing result:
1. playing well with 44.1K 48K 88K ... 192k. the time start from 00:00 to end is ok.
2. but when playing DSD128 or DSD256, the playing is always blocked at 00:00, also i can't see wave with oscilloscope monitor on either PORT_DSD_DAC0 or PORT_DSD_DAC1.

may be my changes is not enough, i will upload my changed firmware later, could you give some clues?
many thanks.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Post by hushange »

i attached my firmware, as the total size is more than 2MB, so only attached app_usb_aud_skc_su1 and sc_usb_audio.
describe my main changes at here:
1. audio.xc
change p_dsd_clk as input.
extern buffered in port:32 p_dsd_clk;
remove all :p_dsd_clk <: *;

2. Makefile
add -DDSD_CHANS_DAC=2 for XCC_FLAGS_2xoxx

3. xp-skc-su.xn
add DSD ports
PORT_MIDI_IN --> PORT_DSD_DAC1
PORT_I2S_ADC0 --> PORT_DSD_CLK
PORT_I2S_ADC1 --> PORT_DSD_DAC0

4. customdefines.h
add #define NATIVE_DSD 1
set #define CODEC_MASTER 1

5. audioports.c audioports.h
p_dsd_clk changed as input, inorder to compatible with it, i rename some fuctions
EnableBufferedPorthyf
ConfigAudioPortsWrapperhyf
ConfigAudioPortshyf

6. audioports.xc
comment the fowlling in ConfigAudioPortshyf because jtag debug will stop at the following code.
//configure_in_port_no_ready(p_lrclk, clk_audio_bclk);


***EDIT - SOURCE FILES DELETED BECAUSE LICENSE DOES NOT PERMIT REDISTRIBUTION OF SOURCE***
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Post by hushange »

now our project is blocked by implementing DSD slave in xmos.
so any suggestion is wellcome.
User avatar
infiniteimprobability
Verified
XCore Legend
Posts: 1142
Joined: Thu May 27, 2010 10:08 am

Post by infiniteimprobability »

You say..
---- as you described above, now i can listen the audio as xmos is DSD slave, but there is some noise. many thanks to you. i will take more hard to improve it.
and
2. but when playing DSD128 or DSD256, the playing is always blocked at 00:00, also i can't see wave with oscilloscope monitor on either PORT_DSD_DAC0 or PORT_DSD_DAC1.
Does this mean DSD64 "kind of" works? i.e. does it get DSD data at the pins. It is important to understand this before next steps.

I had a quick look at your code (I downloaded it before it was deleted by moderators - sorry you cannot post that much of the code due to license restrictions) and the changes you made all look sensible. Actually, you seem to have understood the code quite well - there are lots of layers (xc to c to xc etc.) and inline asm to work around compiler restrictions and get performance. The key thing is that p_dsd_dac ports are clocked by the input port p_dsd_clk. As long as this happens, the rate at which deliver() in audio.xc loops will be determined by the p_dsd_clk/32b because we have ports with 32b shift registers inside.

When "playing is always blocked at 00:00" this normally means something is stuck at the audio end. Can you use a debugger to find out where in audio.xc the code is when this happens? Also, can you see activity on p_dsd_clk at this point? (I guess not).

Also, in the two sections of audio.xc where you have done this:

Code: Select all

                    // Set clocks low
                    //p_lrclk <: 0;
                    //p_bclk <: 0;
                    //p_dsd_clk <: 0;
can you un-comment the p_lrclk and p_bclk lines - I seem to recall getting the right level for lrclk and bclk is important to avoid port lockup, which is why those lines are in there.