Hi all!
I am starting with XMOS, and I am a bit confused with ports, timed IO and so.
I have been able to link a clock with an external clock input to a port, and write and read to/from the data port, independently, but not simultaneously.
Can somebody explain how could it be done?
How the timed input works?
Why the processor is hanged waiting?
And finally, what is wrong in my code?
The data I am handling is a TDM data bus, with sync signal, bclk, data_in and data_out ports. The sync and bclk works fine, data_out works fine IF there is no read. When I read, my data write is delayed.
#include "tdm_master.h"
#include <xclib.h>
//Configures the ports
static void tdm_master_configure_ports(
out buffered port:32 p_dout[num_out],
static const size_t num_out,
in buffered port:32 p_din[num_in],
static const size_t num_in,
out buffered port:32 p_tdm_sync,
in port p_bclk,
clock clk)
{
int i;
configure_clock_src(clk, p_bclk);
configure_out_port(p_tdm_sync, clk, 0);
for (i=0;i<num_out;++i)
configure_out_port(p_dout, clk, 0);
for (i=0;i<num_in;++i)
configure_in_port(p_din, clk);
start_clock(clk);
}
#define PORT_IN(p, x) asm("in %0, res[%1]" : "=r"(x) : "r"(p))
#define PORT_SET_TIME(p, t) asm("setpt res[%0], %1" :: "r"(p), "r"(t));
//Write data to the output ports. This function processes all the outport ports, since there may be more than one
[[always_inline]]
static void tdm_master_output_ch(client tdm_callback_if tdm_i,
out buffered port:32 p_dout[num_out],
static const size_t num_out,
size_t frame_ch,
size_t channels_per_frame
)
{
for (int i=0;i<num_out;++i) {
//Ask the interface to send a new value.
p_dout <: bitrev(tdm_i.send((channels_per_frame*i)+(frame_ch)));
}
}
//Read data from the input ports. This function processes all the input ports, since there may be more than one
[[always_inline]]
static void tdm_master_input_ch(client tdm_callback_if tdm_i,
in buffered port:32 p_din[num_in],
static const size_t num_in,
size_t frame_ch,
size_t channels_per_frame
)
{
int32_t value;
for (int i=0;i<num_in;++i) {
p_din :> value;
//Notify the interface we have received a new value
tdm_i.receive((channels_per_frame*i)+(frame_ch), bitrev(value));
}
}
//Main function.
//There is only 1 output port and 1 input port, but I want the code to be ready to support more than one I/O ports.
void tdm_custom(client tdm_callback_if tdm_i,
out buffered port:32 p_dout[num_out],
static const size_t num_out,
in buffered port:32 p_din[num_in],
static const size_t num_in,
out buffered port:32 p_tdm_sync,
in port p_bclk,
clock clk
)
{
int i;
tdm_master_config_t config;
tdm_i.init(config);
uint32_t sync_mask=(1<<config.sync_len)-1;
//sync_mask=0x1
//config.channels_per_frame=8
tdm_master_configure_ports(p_dout, num_out, p_din, num_in, p_tdm_sync, p_bclk, clk);
//I configure the port time. I have seen this somewhere, but I don't know actually why I have chosen this values
for (i=0;i<num_out;++i) {
PORT_SET_TIME(p_dout, 0);
p_dout @ 64 <: 0;
}
for (i=0;i<num_in;++i) {
PORT_SET_TIME(p_din, 31);
}
PORT_SET_TIME(p_tdm_sync, 0);
p_tdm_sync @ 64 <: 0;
while (1) {
int32_t value;
//We send the first
p_tdm_sync <: sync_mask;
tdm_master_output_ch(tdm_i, p_dout, num_out, 0, config.channels_per_frame);
//Now process the other channels in the frame
for (int curr_channel=1;curr_channel<config.channels_per_frame;++curr_channel) {
//First we read them
tdm_master_input_ch(tdm_i, p_din, num_in, curr_channel-1, config.channels_per_frame);
//And now we send them
p_tdm_sync <: 0;
tdm_master_output_ch(tdm_i, p_dout, num_out, curr_channel, config.channels_per_frame);
}
//Finally read the last one.
tdm_master_input_ch(tdm_i, p_din, num_in, config.channels_per_frame-1, config.channels_per_frame);
}
}
Any help is appreciated.
Best regards,
Ruben
Read and write simultaneously from a port
-
- New User
- Posts: 2
- Joined: Fri Jun 05, 2015 8:21 am