i2s data is delayed 50ns

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

i2s data is delayed 50ns

Postby hushange » Sat Apr 08, 2017 11:21 am

Hi xmos:

now i have a strange isssue, when codec is the master, my i2s data is delayed 50ns compare with the falling edge of bclk.
when play 192khz file, the i2s data is seted at the rising edge of bclk, so this is error, it should be seted at falling edge of bclk.
now when the sample frequency is great than 17600, it can't be play well, so any one has some advise:
1. why there is a 50ns delay ?
2. how to fix it ?

many thanks
hu yongfa


following is my app infomation:

1. the app is based on app_usb_aud_skc_su1, the firmware version is 6.15.2.

2. #define CODEC_MASTER 1

3. my simple change in audioports.xc

Code: Select all

...
configure_clock_src(clk_audio_bclk, p_bclk);
configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
configure_in_port_no_ready(p_lrclk, clk_audio_bclk);
start_clock(clk_audio_bclk);

while(1)
        p_i2s_dac[0] <: 0x55555555;// i2s data
...

Image
User avatar
mon2
XCore Expert
Posts: 664
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Postby mon2 » Sat Apr 08, 2017 2:39 pm

Hi. Not an audio expert but reviewing:

https://github.com/marcan/xmos-speaker- ... ioports.xc

try to test with the following:

Code: Select all


/* Clock master clock-block from master-clock port */
configure_clock_src(clk_audio_mclk, p_mclk);

configure_port_clock_output(p_bclk, clk_audio_mclk);

configure_clock_src(clk_audio_bclk, p_bclk);
configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
configure_in_port_no_ready(p_lrclk, clk_audio_bclk);

    /* Start clock blocks ticking */
    start_clock(clk_audio_mclk);
    start_clock(clk_audio_bclk);

    /* bclk initial state needs to be high  */
    p_bclk <: 0xFFFFFFFF;

    /* Pause until output completes */
sync(p_bclk);

while(1)
        p_i2s_dac[0] <: 0x55555555;// i2s data
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Postby hushange » Mon Apr 10, 2017 2:30 am

Hi Mon2:

thanks for your replying.
i have some difference with you.
my codec is the master, the mclk bclk lrclk is come frome codec.
i also take a test with sync(p_bclk), but the delay is still exist.

follow is my code:

Code: Select all

#if !defined(CODEC_MASTER)

......
......
......

#else /* CODEC_MASTER */

    /* Stop bit and master clock blocks */
    stop_clock(clk_audio_bclk);
    stop_clock(clk_audio_mclk); // add by hu

    clearbuf(p_bclk);

    /* Clock bclk clock-block from bclk pin */
    configure_clock_src(clk_audio_bclk, p_bclk);


    /* Do some clocking shifting to get data in the valid window */
    /* E.g. Only shift when running at 88.2+ kHz TDM slave */
    int bClkDelay_fall = 0;
    if(curSamFreq * I2S_CHANS_PER_FRAME * 32 >= 20000000)//20000000
    {
        /* 18 * 2ns = 36ns. This results in a -4ns (36 - 40) shift at 96KHz and -8ns (36 - 44) at 88.4KHz */
        bClkDelay_fall = 18;
    }

    set_clock_fall_delay(clk_audio_bclk, bClkDelay_fall);

#if (I2S_CHANS_DAC != 0)
     /* Clock I2S output data ports from b-clock clock block */

    clearbuf(p_i2s_dac[0]);
    for(int i = 0; i < I2S_WIRES_DAC; i++)
    {
        configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
    }
#endif

#if (I2S_CHANS_ADC != 0)
    /* Clock I2S input data ports from clock block */
    for(int i = 0; i < I2S_WIRES_ADC; i++)
    {
        configure_in_port_no_ready(p_i2s_adc[i], clk_audio_bclk);
    }
#endif

    configure_in_port_no_ready(p_lrclk, clk_audio_bclk);

    start_clock(clk_audio_mclk);// add by hu
    start_clock(clk_audio_bclk);

    sync(p_bclk); // add by hu
    while(1)
        p_i2s_dac[0] <: 0x55555555; // add by hu
#endif
User avatar
mon2
XCore Expert
Posts: 664
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Postby mon2 » Mon Apr 10, 2017 1:04 pm

This issue may be the following line of code:

Code: Select all

void configure_out_port_no_ready(void port p,const clock clk,unsigned initial)


Code: Select all

     /* Clock I2S output data ports from b-clock clock block */

    clearbuf(p_i2s_dac[0]);
    for(int i = 0; i < I2S_WIRES_DAC; i++)
    {
        configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 0);
    }


In the above, you are clocking out data using the bclk as the reference and the initial value will be a value of 0. Maybe this is causing the extra leading value of 0 shown on the scope.

What if you change this to:

Code: Select all

configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 1);


What does the scope show then ? Will the 50 ns leading zero get changed to a logic 1 ?

Reference reading:

https://www.xmos.com/download/private/X ... 20A%29.pdf

https://www.xmos.com/support/tools/docu ... nent=14811

https://www.xmos.com/download/private/X ... 1.0%29.pdf
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Postby hushange » Tue Apr 11, 2017 3:50 am

Hi Mon2:

after i changed the follow satament as the following:

Code: Select all

for(int i = 0; i < I2S_WIRES_DAC; i++)
 {
        configure_out_port_no_ready(p_i2s_dac[i], clk_audio_bclk, 1);
}


1. it seems the 40~50ns delay still exsit
2. the i2s data still set up at the rising edge of the bclk, we wanted set up it at the falling edge of bclk
3. following attached is the wave picture.

many thanks
hu yongfa
Attachments
new-wave.jpg
(496.59 KiB) Not downloaded yet
new-wave.jpg
(496.59 KiB) Not downloaded yet
hushange
Member++
Posts: 30
Joined: Tue Oct 11, 2016 7:08 am

Postby hushange » Tue Apr 11, 2017 10:51 am

Hi Mon2:

according your reference: XC Clocked Input and Output.pdf,
i take a simple data output test as following, but the 40ns delay is still exist, so I begin to doubt my life, haha.

Code: Select all

out port mydat = PORT_I2S_DAC0 ;
in port inClock = PORT_I2S_BCLK ;
clock myclk = XS1_CLKBLK_1 ;

int main()
{
    configure_clock_src (myclk , inClock );
    configure_in_port (mydat , myclk );
    start_clock ( myclk );

    while(1)
    {
        mydat <: 0;
        mydat <: 1;
    }

    return 0;
}
Attachments
192.jpg
(289.96 KiB) Not downloaded yet
192.jpg
(289.96 KiB) Not downloaded yet
User avatar
mon2
XCore Expert
Posts: 664
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Postby mon2 » Tue Apr 11, 2017 1:59 pm

set_port_inv(void port p)

Configures a 1-bit port to invert data which is sampled and driven on its pin.
If the port is not a 1-bit port, an exception is raised. If the port is used as the
source for a clock then setting this mode has the effect of the swapping the rising
and falling edges of the clock.

This function has the following parameters:

p The 1-bit port to configure.


looks interesting.

Try:

Code: Select all

out port mydat = PORT_I2S_DAC0 ;
in port inClock = PORT_I2S_BCLK ;
clock myclk = XS1_CLKBLK_1 ;

int main()
{
    configure_clock_src (myclk , inClock );

    set_port_inv(inClock);

    configure_in_port (mydat , myclk );
    start_clock ( myclk );

    while(1)
    {
        mydat <: 0;
        mydat <: 1;
    }

    return 0;
}


What are the results ?
akp
Experienced Member
Posts: 84
Joined: Thu Nov 26, 2015 11:47 pm

Postby akp » Tue Apr 11, 2017 3:45 pm

I wonder if inverting the BCLK might have the unintended consequence of causing errors in the LRCLK detection, since the LRCLK would change on rising edge of BCLK rather than falling edge. That means sampling LRCLK on the rising edge of BCLK will quite possibly lead to setup or hold time violations, and what's worse -- if it doesn't at room temperature then who's to say it won't at some other temperature?
User avatar
mon2
XCore Expert
Posts: 664
Joined: Thu Jun 10, 2010 11:43 am
Contact:

Postby mon2 » Tue Apr 11, 2017 11:03 pm

Hi. Just tested the following code on our StartKit using:

P1G0 ; applied an external 1.8432 Mhz clock oscillator (3v3) pin 3 on J7 header (A0 on Logic Analyzer)

P1E0 ; configured as a buffered output pin 4 on J7 header (A1 on Logic Analyzer)

Code: Select all

// Copyright (c) 2016, XMOS Ltd, All rights reserved
#include <xs1.h>

in port inClock = XS1_PORT_1G ;

out buffered port:8 mydat = XS1_PORT_1E ;

clock myclk = XS1_CLKBLK_1 ;

int main(void) {

    configure_clock_src(myclk, inClock);
    configure_out_port(mydat, myclk, 0);

    start_clock ( myclk );
    sync(mydat);

    while(1) {

        mydat <: 0x55;

    }

}




Results are shown here:

xmos_clocked_output.png
(119.24 KiB) Not downloaded yet
xmos_clocked_output.png
(119.24 KiB) Not downloaded yet


The output appears to be in sync with the falling edge of the clock source. If you try the same code, what are the results ?

Remove the following line from your code:

Code: Select all

    set_clock_fall_delay(clk_audio_bclk, bClkDelay_fall);




What are the results ?
Attachments
xmos_clock_delay.png
(161.78 KiB) Not downloaded yet
xmos_clock_delay.png
(161.78 KiB) Not downloaded yet
User avatar
Ross
XCore Expert
Posts: 726
Joined: Thu Dec 10, 2009 9:20 pm

Postby Ross » Tue May 09, 2017 9:22 am

moving out of "latest news" to "applications".

Return to “Applications”

Who is online

Users browsing this forum: GheKneek and 2 guests