AnsweredAssumed Answered

Serial port I2S Timing problem

Question asked by Hfuhrhurr on May 29, 2011
Latest reply on May 30, 2011 by Hfuhrhurr

Hi all,

 

I am connecting an ADSP 21261 to a CS 42526 codec and have a problem with the data that is read by the DSP from the codec.

Below, see a timing diagram with the bit clock (bottom), LR clock (top) and the data on the codecs serial port output.

 

The serial clock has 6.144 MHz, the format is I2S, LR clk is 1/64 of the bit clock.

I overdrive one of the codec's inputs so that the data at the output is 0x7FFFFF which can be seen in the timing diagram. Up to this point, everything is fine.

SD-Timing.png

However, the data received by the DSP shows 0xFFFFFE, 0xFFFFFE, ... which is 0x7FFFFF shifted one bit to the left.

So, it seems that the DSP detects a frame start one clock cycle too late.

 

The hardware is set up like this:

The DSP gets a clock from a 12.288 MHz oscillator. The DSPs PCG B generates a 6.144 MHz clock and the LR clock which is fed to the codec from the DAI. Additionally, the codec gets a 12.288 MHz clock to it's OMCK from PCG A to ensure stable behaviour e.g. when fed by SPDIF and the clock sync is lost. Frame Sync of PCG A is not used.

 

Here's some code that is responsible for that:

 

// Setup PCG A and B

// PCG A: 12.288 clock for OMCK of codec

    //FS Divisor = 64 & FS Phase 20-29 = 0, Enable Clock
    * (volatile int *) PCG_CTLA_0 = ENCLKA | ENFSA | (0<<20) | 0x40; 

 

    //CLK Divisor = 1 & FS Phase 0-9 =0
    * (volatile int *) PCG_CTLA_1 = 0x1; 

 

// PCG B: 6.144 bit clock and I2S frame sync

    //FS Divisor = 128 & FS Phase 20-29 =0, Enable Clock
    * (volatile int *) PCG_CTLB_0 = ENCLKB | ENFSB | (0<<20) | 0x80; 

 

    //CLK Divisor = 0x2 & FS Phase 0-9 = 1
    * (volatile int *) PCG_CTLB_1 = 0x2 | (1 << 20);

 

 

The serial port 0, channel A is initialized like this

    *pSPCTL0 = (BHD | OPMODE | SLEN24 | SPEN_A | SCHEN_A | SDEN_A);

 

and the relevant part of the SRU initialization is

 

// Enable pull-up resistors on unused DAI pins
    * (volatile int *)DAI_PIN_PULLUP = 0xffc40;

 

    //Generating Code for connecting : PCG_CLKA to DAI_PIN1

    // 12.288 MHz for OMCK
    SRU (HIGH, PBEN01_I);
    SRU (PCG_CLKA_O, DAI_PB01_I);

 

    //Generating Code for connecting : PCG_CLKB to SPORT0_CLK

    // 6.144 MHz for serial port
    SRU (PCG_CLKB_O, SPORT0_CLK_I);

 

    //Generating Code for connecting : PCG_CLKB to DAI_PIN3

    // 6.144 MHz bit clock for serial port of codec
    SRU (HIGH, PBEN03_I);
    SRU (PCG_CLKB_O, DAI_PB03_I);

 

    //Generating Code for connecting : PCG_FSB to SPORT0_FS
    SRU (PCG_FSB_O, SPORT0_FS_I);

 

    //Generating Code for connecting : PCG_FSB to DAI_PIN2

    // LRCLK to codec

    SRU (HIGH, PBEN02_I);
    SRU (PCG_FSB_O, DAI_PB02_I);

 

    //Generating Code for connecting : SPORT0_DA to DAI_PIN10

    // incoming data from codec to SPORT0
    SRU (LOW,DAI_PB10_I);
    SRU (LOW,PBEN10_I);
    SRU (DAI_PB10_O,SPORT0_DA_I);

 

 

I can't see any fault in that. Any ideas what's wrong?

 

Thanks in advance,

 

Rainer

Outcomes