Regarding the switching problem between ADAT and SPDIF Topic is solved

Technical questions regarding the XTC tools and programming with XMOS.
lzg
Junior Member
Posts: 6
Joined: Wed Apr 10, 2024 2:57 am

Regarding the switching problem between ADAT and SPDIF

Post by lzg »

Hello everyone, I have recently been developing the output switching function of ADAT and SPDIF on the same pin in XMOS. Specifically, this pin needs to output the SPDIF signal at the beginning. After pressing the button to trigger, the pin needs to output the ADAT signal, but I I encountered a problem. XMOS will freeze when switching. I tried many methods and spent a long time to solve this problem, but it still has not been solved. I hope you can help me. Thank you very much. In addition, I am not sure about this. Can XMOS implement the switching plan?
Here's what I've tried:
1. Create a thread to process the parsing output functions of ADAT and SPDIF in this thread, but this will cause all required clocks and pins to violate parallel rules.
2. Create two threads, one thread processes SPDIF, and the other thread processes ADAT, and uses 2 pins, one of which has no actual effect. When using spdif output, the ADAT data does not stop transmitting, but Output the data to the invalid pin. When the trigger signal is detected, the SPDIF signal is output to the invalid pin, and the ADAT signal is switched to the valid pin output. However, such processing will cause the XMOS to freeze after detecting the trigger signal. run.


View Solution
User avatar
fabriceo
XCore Addict
Posts: 213
Joined: Mon Jan 08, 2018 4:14 pm

Post by fabriceo »

Hi Izg
these 2 functions (adattx and spdiftx) use extensively the channels for pushing/receiving data.
when xmos "freezes" this is often due to an instruction trying to get a token or a data from a channel (consumer) and then the other task supposed to send it (producer) doesn't provide it...

have a look in the details of the 2 librairies, there are functions to properly stop/start each of these task by sending control-token and this might be one way to clean the situation.

regarding the idea of sharing the output port for 2 separated task (not running simultaneously of course) that is technically feasible but you have to play with the problem of parallel usage at compile time. There are many way to do the trick.
in fact when you pass a port as a parameter, you pass the content of a variable containing the address of the port.
so you can define 2 ports variable and patch the content of the second one at run time with an assembly instruction

buffered out port:32 p_spdif = { XS1_P1A };
buffered out port:32 p_adat;
and later in the code :
asm volatile("ldw r11,dp[p_spdif] ; stw r11,dp[p_adat]" :::"r11");
so that they end up with same value and then pointing on the same port.

you re gona have good time to make it work for sure :)
lzg
Junior Member
Posts: 6
Joined: Wed Apr 10, 2024 2:57 am

Post by lzg »

fabriceo wrote: Mon May 06, 2024 2:00 pm Hi Izg
these 2 functions (adattx and spdiftx) use extensively the channels for pushing/receiving data.
when xmos "freezes" this is often due to an instruction trying to get a token or a data from a channel (consumer) and then the other task supposed to send it (producer) doesn't provide it...

have a look in the details of the 2 librairies, there are functions to properly stop/start each of these task by sending control-token and this might be one way to clean the situation.

regarding the idea of sharing the output port for 2 separated task (not running simultaneously of course) that is technically feasible but you have to play with the problem of parallel usage at compile time. There are many way to do the trick.
in fact when you pass a port as a parameter, you pass the content of a variable containing the address of the port.
so you can define 2 ports variable and patch the content of the second one at run time with an assembly instruction

buffered out port:32 p_spdif = { XS1_P1A };
buffered out port:32 p_adat;
and later in the code :
asm volatile("ldw r11,dp[p_spdif] ; stw r11,dp[p_adat]" :::"r11");
so that they end up with same value and then pointing on the same port.

you re gona have good time to make it work for sure :)
Thank you very much for your reply, which gave me a deeper understanding of its implementation details.

I tried your suggested method, and the shared port problem seems to have been solved. At least for now, no error is reported and the program can run.

But I still haven't solved the stuck problem after switching. I copied the part of the code when the sampling rate changes. The functions are chkct(c_tx0, XS1_CT_END); and return;
Execute these two functions after detecting the switching trigger signal, but it will still get stuck. I am not sure whether this function is suitable, or other functions should be used to adjust the relationship between input (producer) and output (consumer).
User avatar
Ross
XCore Expert
Posts: 972
Joined: Thu Dec 10, 2009 9:20 pm
Location: Bristol, UK

Post by Ross »

make sure those two pins are both clocked from the same clock-block, other wise the output will block forever after the switch.

it would be useful to know where the code is when it is "stuck"
lzg
Junior Member
Posts: 6
Joined: Wed Apr 10, 2024 2:57 am

Post by lzg »

Ross wrote: Thu May 09, 2024 2:01 pm make sure those two pins are both clocked from the same clock-block, other wise the output will block forever after the switch.

it would be useful to know where the code is when it is "stuck"
Thank you very much for your guidance. I have already implemented the function for switching to the same port. Thank you for your assistance.