Switch RX SPDIF input port on the fly #2 Topic is solved

Sub forums for various specialist XMOS applications. e.g. USB audio, motor control and robotics.
Post Reply
ffomich
Experienced Member
Posts: 119
Joined: Mon Sep 15, 2014 1:32 pm

Switch RX SPDIF input port on the fly #2

Post by ffomich »

Hi,
In breif
parseSpDifTerminate() in SpdifReceive.S crashes after receiving CT_END from streaming channel.

In detail
this post is the continue of https://www.xcore.com/forum/viewtopic.p ... it=#p24231.
The scheme of my solution was:

Code: Select all

XMOS input port1 -> spdifReceive(ch1, clock1) -\ 
                                                  -> clockGen(ch1, ch2) -> ... -> mixer() -> USB rec
XMOS input port2 -> spdifReceive(ch2, clock2) -/
clock1 & clock2 are clocked from diffferent CLKBLK.

My code was:

Code: Select all

par
{
     ...
        on tile[SPDIF_RX_TILE]:
        {
            thread_speed();
            SpdifReceive(p1, ch1, 1, clk1);
        }
        on tile[SPDIF_RX_TILE]:
        {
            thread_speed();
            SpdifReceive(p2, ch2, 1, clk2);
        }
}
It works correclty.

=====================================================

Now I have new challenge. After adding some modules to my project there are only two free clockblocks: CLKBLK_REF & CLKBLK_1.

I can't use CLKBLK_REF for spdifReceive() because CLKBLK_REF doesn't allow to set frequency divider.
So I must share CLKBLK_1 between two spdifReceive() modules.

Code: Select all

XMOS input port1 -> spdifReceive1(ch1, clock) -\ 
                                                  -> clockGen(ch1, ch2) -> ... -> mixer() -> USB rec
XMOS input port2 -> spdifReceive2(ch2, clock) -/
I tried many methods to share CLKBLK including this but I either got build error "use of clk violates parallel usage rules" or my program crashed after run.

Now I try to realize the second method from Ross:
Ross:
SpdifReceive() would then exits and you can call it with another port. This isn't something it supports at the moment by the looks of it and would need adding.

After analyzing spdifReceive.S code (in ASM) I found parseSpDifTerminate() in it.

Code: Select all

parseSpDifTerminate:
    INCT   r11, r1
#ifdef TEST
parseSpDifE:
#endif
    CLRSR  XS1_SR_EEBLE_MASK
    CLRSR  XS1_SR_FAST_MASK
    EDU    r1

    OR     r0, r4, r4
    OR     r1, r5, r5
    LDWSP  r2, 8
    LDWSP  r4, 1
    LDWSP  r5, 2
    LDWSP  r6, 3
    LDWSP  r7, 4
    LDWSP  r8, 5
    LDWSP  r9, 6
    LDWSP  r10, 7
    RETSP  STACK
This event monitors channel r1 and after receiving ControlToken if forces exit from spdifReceive().

Now my scheme is:

Code: Select all

XMOS input port1 -> spdifReceive1(ch1, clock) -> clockGen(ch1, ch2) -> ... -> mixer() -> USB rec
user change input -> stop spdifReceive1, start spdifReceive2
XMOS input port2 -> spdifReceive2(ch2, clock) -> clockGen(ch1, ch2) -> ... -> mixer() -> USB rec
user change input -> stop spdifReceive2, start spdifReceive1
XMOS input port1 -> spdifReceive1(ch1, clock) -> clockGen(ch1, ch2) -> ... -> mixer() -> USB rec
...
and my code is:

Code: Select all

par
{
     ...
        on tile[SPDIF_RX_TILE]:
        {
            thread_speed();
            SpdifReceiveWrapper(p1, ch1, p2, ch2, 1, clk);
        }
}

void  SpdifReceiveWrapper(p1, ch1, p2, ch2, initial_divider, clk)
{
    while(1)
    {
        SpdifReceive1(p1, ch1, initial_divider, clk);
        SpdifReceive2(p2, ch2, initial_divider, clk);
    }
}
For test purpose I use simplified version of SpdifReceiveWrapper()

Code: Select all

void  SpdifReceiveWrapper(p1, ch1, p2, ch2, initial_divider, clk)
{
    while(1)
    {
        SpdifReceive1(p1, ch1, initial_divider, clk);
    }
}
Results:
Send CT_END from clockGen() to SpdifReceive1()

Code: Select all

 c <: XS1_CT_END;
SpdifReceive1 crashes and stops in _TrapHandler().


View Solution
ffomich
Experienced Member
Posts: 119
Joined: Mon Sep 15, 2014 1:32 pm

Post by ffomich »

Solution:

Send CT_END from clockGen() to SpdifReceive1() with command:

Code: Select all

asm ("outct res[%0], %1"::"r"(c_spdif_rx),"r"(XS1_CT_END));
Note:
This code generate build error.

Code: Select all

outct(c, XS1_CT_END);
Post Reply