DSD to I2S (not converting, only bitreordering)

Technical questions regarding the XTC tools and programming with XMOS.
Post Reply
stefan_o
Newbie
Posts: 1
Joined: Sat May 27, 2017 4:14 pm

DSD to I2S (not converting, only bitreordering)

Post by stefan_o »

Hey,
I like to attach an ADC (PCM4202) to an Raspberry Pi including DSD support. Unfortunately there does not seem to be a simple way to directly feed the DSD data into the Raspberry Pi. So my simple idea is to repack the DSD data as I2S and feed it to the Raspi. I was recommended using an XMOS for this task. I never worked with XMOS before, I downloaded the XTimeComposer and I came up with the code below. In simulation it seems to work (when using a fixed input value), but problem is the output bit clock, since I multiplex to input streams the output clock is twice the input clock, how do I multiply a clock?

Code: Select all

#include <xs1.h>
#include <platform.h>

in port inClock = XS1_PORT_1E;
in buffered port:32 lIn = XS1_PORT_1F;
in buffered port:32 rIn = XS1_PORT_1G;


out port outClock = XS1_PORT_1C;
out buffered port:32 dataOut = XS1_PORT_1B;
out buffered port:32 lrClock = XS1_PORT_1H;

clock clkIn = XS1_CLKBLK_1;
clock clkOut = XS1_CLKBLK_2;

int main(void) {
    configure_clock_src(clkIn, inClock);
    configure_in_port(lIn, clkIn);
    configure_in_port(rIn, clkIn);

    //configure_clock_rate(clkOut, 100, 10); // ????????????
    configure_port_clock_output(outClock, clkOut);
    configure_out_port(dataOut, clkOut, 0);
    configure_out_port(lrClock, clkOut, 0);

    start_clock(clkIn);
    start_clock(clkOut);

    unsigned int in_l_a=0;
    unsigned int in_r_a=0;
    unsigned int in_l_b=0;
    unsigned int in_r_b=0;

    const unsigned int high=0xfffffffe;
    const unsigned int low=0x1;
    while (1) {
        par {
            lIn :> in_l_a;
            rIn :> in_r_a;
            {
                par { lrClock <: high;
                    dataOut <: in_l_b; }
                par { lrClock <: low;
                    dataOut <: in_r_b; }
            }
        }
        par {
            lIn :> in_l_b;
            rIn :> in_r_b;
            {
                par { lrClock <: high;
                    dataOut <: in_l_a; }
                par { lrClock <: low;
                    dataOut <: in_r_a; }
            }
        }
    }
    return 0;
}
Does the parallelization work like this correctly or is it more of an accident that the simulation seems to work?

Best regards
Stefan


User avatar
infiniteimprobability
XCore Legend
Posts: 1126
Joined: Thu May 27, 2010 10:08 am
Contact:

Post by infiniteimprobability »

What you have written is functional but not efficient in resources. You are spawning a thread to do a single i/o operation. In reality you don;t need that as the ports have buffers (32b transfer register and 32b shift register). So you can have a single thread which loops around reading from two ports and writing to the next two.
how do I multiply a clock?
We don't have true PLLs on chip to multiply so normally it's better to have MCLK available and divide that. Saying that, if your rates are fixed and not too high there may be a way of multiplying the clock by outputting a stream of 0101 each time you see a falling edge...

Perhaps if you draw a diagram of what you want, we could suggest some code to do it.
Post Reply