How to use bi-directional streaming channels? Please help!

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

How to use bi-directional streaming channels? Please help!

Post by gerrykurz »

I have run into a road block that there is no documentation for that I can find.

I have two SliceKit-L16 boards connected together with a 5 wire channel between them.

I can send data from the one board to the other but not back.

How do I use a streaming channel as bidirectional?

Here is a the link portion of my xn file setting up the inter-board channel:

<!-- Inter-board Link -->
<Link Encoding="5wire" Delays="2,3">
<LinkEndpoint NodeId="1" Link="XLB"/>
<LinkEndpoint NodeId="2" Link="XLB"/>
</Link>

Here is my main function:

int main()
{
chan rx[1], tx[2], DownPort1Rx[1], DownPort1Tx[1];
streaming chan packet_channel;

par
{
//::ethernet
on ETHERNET_DEFAULT_TILE:
{
char mac_address[6];
otp_board_info_get_mac(otp_ports, 0, mac_address);
eth_phy_reset(eth_rst);
smi_init(smi);
eth_phy_config(1, smi);
ethernet_server(mii,
null,
mac_address,
rx, 1,
tx, 1);
}
//::

//::demo
// on ETHERNET_DEFAULT_TILE : demo(tx[0], rx[0]);
on ETHERNET_DEFAULT_TILE: demo(tx[0], rx[0], packet_channel);
on ETHERNET_DEFAULT_TILE: downlink_repeater (tx[1], packet_channel);
//::

// new code
on DownPort1Tile:
{
char MacAddress[6];
otp_board_info_get_mac(DownPort1OTPPorts, 0, MacAddress);
eth_phy_reset(DownPort1Reset);
smi_init(DownPort1SMIInterface);
eth_phy_config(1, DownPort1SMIInterface);
ethernet_server_lite
(
DownPort1MIIInterface,
null,
MacAddress,
DownPort1Rx, 1,
DownPort1Tx, 1
);

}

on DownPort1Tile: uplink_repeater (DownPort1Tx[0], packet_channel);
on DownPort1Tile: downlink_1_receiver(DownPort1Rx[0], packet_channel);

And here is the compiler error I get:

**** Build of configuration full for project app_ethernet_demo ****

xmake CONFIG=full all
Using modules: module_ethernet module_ethernet_smi module_ethernet_board_support module_otp_board_info module_slicekit_support module_locks
Creating dependencies for demo.xc
Compiling demo.xc
../src/demo.xc: In function `main':
../src/demo.xc:492: error: `packet_channel' used in more than two parallel statements
../src/demo.xc:469: error: previously used here
../src/demo.xc:470: error: previously used here
xmake[1]: *** [.build_full/src/demo.xc.o] Error 1
xmake: *** [bin/full/app_ethernet_demo_full.xe] Error 2


I tried to do this in main:

int main()
{
chan rx[1], tx[2], DownPort1Rx[1], DownPort1Tx[1];
streaming chan packet_channel_down, packet_channel_up;

par
{
//::ethernet
on ETHERNET_DEFAULT_TILE:
{
char mac_address[6];
otp_board_info_get_mac(otp_ports, 0, mac_address);
eth_phy_reset(eth_rst);
smi_init(smi);
eth_phy_config(1, smi);
ethernet_server(mii,
null,
mac_address,
rx, 1,
tx, 1);
}
//::

//::demo
// on ETHERNET_DEFAULT_TILE : demo(tx[0], rx[0]);
on ETHERNET_DEFAULT_TILE: demo(tx[0], rx[0], packet_channel_down);
on ETHERNET_DEFAULT_TILE: downlink_repeater (tx[1], packet_channel_up);
//::

// new code
on DownPort1Tile:
{
char MacAddress[6];
otp_board_info_get_mac(DownPort1OTPPorts, 0, MacAddress);
eth_phy_reset(DownPort1Reset);
smi_init(DownPort1SMIInterface);
eth_phy_config(1, DownPort1SMIInterface);
ethernet_server_lite
(
DownPort1MIIInterface,
null,
MacAddress,
DownPort1Rx, 1,
DownPort1Tx, 1
);

}

on DownPort1Tile: uplink_repeater (DownPort1Tx[0], packet_channel_down);
on DownPort1Tile: downlink_1_receiver(DownPort1Rx[0], packet_channel_up);

I got this compiler error:


**** Build of configuration full for project app_ethernet_demo ****

xmake CONFIG=full all
Using modules: module_ethernet module_ethernet_smi module_ethernet_board_support module_otp_board_info module_slicekit_support module_locks
Creating app_ethernet_demo_full.xe
../src/demo.xc: Error: Not enough links from node "1" to node "2" for specified number of streaming channels.
xmake[1]: *** [bin/full/app_ethernet_demo_full.xe] Error 1
xmake: *** [bin/full/app_ethernet_demo_full.xe] Error 2


I tried modifying the xn file like this:

<!-- Inter-board Link -->
<Link Encoding="5wire" Delays="2,3">
<LinkEndpoint NodeId="1" Link="XLB"/>
<LinkEndpoint NodeId="2" Link="XLB"/>
</Link>
<Link Encoding="5wire" Delays="2,3">
<LinkEndpoint NodeId="2" Link="XLB"/>
<LinkEndpoint NodeId="1" Link="XLB"/>
</Link>

but this is the error message I got:

**** Build of configuration full for project app_ethernet_demo ****

xmake CONFIG=full all
Using modules: module_ethernet module_ethernet_smi module_ethernet_board_support module_otp_board_info module_slicekit_support module_locks
Compiling checksum.c
.././src/SLICEKIT-L16-CHAIN.xn:95 Error: XN11164 LinkEndpoint "XLB" on node "1" is a duplicate.
.././src/SLICEKIT-L16-CHAIN.xn:95 Error: XN11164 Other is LinkEndpoint "XLB" on node "1".
xmake[1]: *** [.build_full/src/checksum.c.o] Error 1
xmake: *** [bin/full/app_ethernet_demo_full.xe] Error 2

What am I doing wrong and how do I make this work?


User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm

Post by Bianco »

If you have just one xCONNECT link between the two tiles you cannot have a streaming channel and 1 or more regular channels between the tiles. You can have exclusively 1 streaming channel or 1 or more regular channels.

A small workaround is sending pause tokens freeing the route, but you will need to get the stuff building first.

Can you please use code tags when posting code on the forum next time.
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Ok from what I understand of what you are saying is that a streaming channel is only unidirectional and uses all ten wires of the physical connection.

To my way of thinking, a streaming channel should be able to stream data both ways.

What are code tags?
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm

Post by Bianco »

A streaming channel is bidirectional, but will occupy the link between the two tiles at all times, hence you cannot have additional channels between the two tiles.
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

I don't understand. If a streaming channel is bi-directional, then you should be able to have four channel endpoints rather than just two. How do you get data going both ways since the compiler throws an error if I try and define four endpoints?

Are you saying that the channel in and out commands need to be within the same task?

What I am trying to do is to get a streaming channel setup to send data from XS1 part (chip 1) to
another XS1 part (chip 2) and have a streaming channel for data from chip 2 to chip 1.

From a hardware point of view, this should be possible with two five wire physical connections. I am physically connecting X0LB five wire out port on chip 1 to X1LB in port on chip 2 as well as connecting X1LB out port to X0lb in port.

What am I not getting here?
pasau
Experienced Member
Posts: 77
Joined: Fri Dec 06, 2013 7:05 pm

Post by pasau »

with a single 5 wire xconnect link you can have as much as 1 streaming channel, which is used both ways by the xconnect protocol. Personally i prefer not using streaming chan unless i really have to, since they keep the whole link busy. The streaming chan serves as input and output for one channel end. Normally, you should do something like declaring streaming chan in a main thread. Then, a thread function that will run on one of the two cores that you have needs to have a streaming chanend argument. When you call the function from a par{} statement, you give it the streaming chan as argument. Example:

Code: Select all

int main{
streaming chan myChannel;

par{
 on tile[0] : thread1(myChannel, arg1, arg2);
 on tile[1] : thread2(myChannel, arg3, arg4, arg5, arg6);
}

}

...
...

void thread1(streaming chanend someChanend, int someArg1, int someArg2)
{
  someChanend <: 1;
  someChanend :> myVar;
}

void thread2(streaming chanend someChanend, int someArg1, int someArg2, int someArg3, int someArg4)
{
  someChanend <: 2;
  someChanend :> myVar;
}
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Yes this makes total sense to me using a single 5 wire xconnect link.

However, what I am trying to do is to set up two 5 wire xconnect links so I can stream data from 2 separate tasks running in parallel.

I suspect this has something to do with what I specify in the .xn file but I don't know how to do this or at least what I am doing is not working the way I intend.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Hi Gerry, Sethu provided an example XN file for chaining 2 slices. However this only defines a single 5wire X0LB link from the first kit to the second.

Code: Select all

<Links>
        <Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
          <LinkEndpoint NodeID="SLICE_0" Link="X0LA" />
          <LinkEndpoint NodeID="XSCOPE_ID" Chanend="1" />
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLG"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLF"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLH"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLE"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLE"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLH"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLF"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLG"/>
        </Link>

        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLG"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLF"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLH"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLE"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLE"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLH"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLF"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLG"/>
        </Link>

        <Link Encoding="5wire" Delays="4,4">
            <LinkEndpoint NodeId="SLICE_1" Link="X0LB"/>
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="X0LB"/>
        </Link>

</Links>
I think you would also need to enable a further 5wire link X0LA for your requirements something like this:

Code: Select all

<Links>
        <Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
          <LinkEndpoint NodeID="SLICE_0" Link="X0LA" />
          <LinkEndpoint NodeID="XSCOPE_ID" Chanend="1" />
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLG"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLF"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLH"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLE"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLE"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLH"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE_0" Link="XLF"/>
            <LinkEndpoint NodeId="SLICE_1" Link="XLG"/>
        </Link>

        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLG"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLF"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLH"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLE"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLE"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLH"/>
        </Link>
        <Link Encoding="5wire" Delays="0,1">
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="XLF"/>
            <LinkEndpoint NodeId="SLICE-kit1_1" Link="XLG"/>
        </Link>

        <Link Encoding="5wire" Delays="4,4">
            <LinkEndpoint NodeId="SLICE_1" Link="X0LB"/>
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="X0LB"/>
        </Link>
        <Link Encoding="5wire" Delays="4,4">
            <LinkEndpoint NodeId="SLICE_1" Link="X0LA"/>
            <LinkEndpoint NodeId="SLICE-kit1_0" Link="X0LA"/>
        </Link>

</Links>
I am unfortunately not in a position to test this today but feel free to give it a shot. Also be aware that some of these pins may overlap with ports on the second Slicekit star slot (probably best to avoid the use of second Startkit star slot entirely when chaining with both 5wire links).

P.S. I got the chained example xn file from this Q&A which could probably do with an update if this is successful.

regards
Al
User avatar
gerrykurz
XCore Addict
Posts: 204
Joined: Sun Jun 01, 2014 10:25 pm

Post by gerrykurz »

Hi Al et al,

I have it figured out now. The confusion for me was that a "5 wire link" is actually in fact a 10 wire bidirectional link. Data can be sent in both directions but normally not at the same time. Also with a streaming link that is permanently set up, then the in and out commands must come from within the same task unless there is some way to trick the compiler.

There is a way to set up the link to be able to sent data in both directions simultaneously but I don't know it the compiler supports this. Maybe someone knows more about this.....

This could all be done in assembly language but I think you are right Al, my best bet to get two bidirectional streaming links is to use X0LA.

Thanks for your help everyone. I feel like I am getting towards the end of the learning curve on all of this.

Best regards,

Gerry