questions fast UART with hardware handshakes

Technical questions regarding the XTC tools and programming with XMOS.
pasau
Experienced Member
Posts: 77
Joined: Fri Dec 06, 2013 7:05 pm

questions fast UART with hardware handshakes

Post by pasau »

1)
Hi, i am currently trying to implement a fast UART, with data speed in the Mhz range. I need the use of handshakes, i.e. cts/rts or my uart device (FT232) will lose packets.

First of all i managed to read the rts(request to send) port and halt the streaming when my ft232 is not ready to receive. I made a host application that tests the received string and everything is good, even for large transfers, i.e. more than 4kB.

For both the rts and rx, i used a 1 bit port; rts is input and tells the microcontroller when to stop sending bytes through rx. What i don't understand is why this only works in a 1 bit port for rx (haven't tried for rts yet). If i send data to lets say bit 0 of a 4 bit port, i receive only some crap at the host.

My transmitter code is based on the simple fast uart example.

Code: Select all

extern in port p_uart_readyin;
void uart_tx_fast(out port p, streaming chanend c, int clocks) {
    int t;
    unsigned char b;
    char a= 0x21;
    while (1) {
        char e = a;
        c :> b;
        int busy=1;
        while(busy)
            p_uart_readyin :> busy;
        p <: 0 @ t;
        t += clocks;
#pragma loop unroll(8)
        for(int i = 0; i < 8; i++) {
            p @ t <: >> e;
            t += clocks;
        }
        p @ t <: 1;
        t += clocks;
        p @ t <: 1;
        if (a == 0x7e)
            a=0x21;
        else
            a++;
------------------------------

2)
As a second question (less important), since the XMOS architecture allows for configuring the ports in handshake mode, i thought i would give it a try, as it would be interesting to have the port handle the handshakes instead of the processor.

In the xs1 library, i think i need the following port configuration:

Code: Select all

configure_out_port_strobed_slave(void port p, in port readyin, clock  clk, unsigned initial)
where readyin is connected to RTS; implements the port for the transmitter

Code: Select all

configure_in_port_strobed_master(void port p, out port readyout, const clock  clk)
where readyout is connected to CTS; implements the port for the receiver

not configure_x_port_handshake, as it implements a full handshake where one side will also send a signal when sending data.

I never was able to work with the port handshakes so far. The result always fails; there is definitely something i am doing wrong. Anyone ever managed to do some UART handshakes that way? Thanks!


User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

pasau wrote:1)
Hi, i am currently trying to implement a fast UART, with data speed in the Mhz range. I need the use of handshakes, i.e. cts/rts or my uart device (FT232) will lose packets.

First of all i managed to read the rts(request to send) port and halt the streaming when my ft232 is not ready to receive. I made a host application that tests the received string and everything is good, even for large transfers, i.e. more than 4kB.

For both the rts and rx, i used a 1 bit port; rts is input and tells the microcontroller when to stop sending bytes through rx. What i don't understand is why this only works in a 1 bit port for rx (haven't tried for rts yet). If i send data to lets say bit 0 of a 4 bit port, i receive only some crap at the host.

My transmitter code is based on the simple fast uart example.

Code: Select all

extern in port p_uart_readyin;
void uart_tx_fast(out port p, streaming chanend c, int clocks) {
    int t;
    unsigned char b;
    char a= 0x21;
    while (1) {
        char e = a;
        c :> b;
        int busy=1;
        while(busy)
            p_uart_readyin :> busy;
        p <: 0 @ t;
        t += clocks;
#pragma loop unroll(8)
        for(int i = 0; i < 8; i++) {
            p @ t <: >> e;
            t += clocks;
        }
        p @ t <: 1;
        t += clocks;
        p @ t <: 1;
        if (a == 0x7e)
            a=0x21;
        else
            a++;
------------------------------
The line:

Code: Select all

p @ t <: >> e;
Will behave differently depending on the port size of P, which may explain some of the weirdness when you try to use a 4 bit port instead of a 1 bit port. if using mixed size ports you would have to be more explicit and 'And' the shift results with a 1 bit mask.
something like:

Code: Select all

p @ t <: (0x01 & (e >> 1)) // assumes bit0 of 4 bit port p for Tx
I would change:

Code: Select all

int busy=1;
        while(busy)
            p_uart_readyin :> busy;
For :

Code: Select all

p_uart_readyin when pinseq(1) :> int _;     //wait until readyin high
It's more XC like using events rather than polling.
pasau wrote: 2)
As a second question (less important), since the XMOS architecture allows for configuring the ports in handshake mode, i thought i would give it a try, as it would be interesting to have the port handle the handshakes instead of the processor.

In the xs1 library, i think i need the following port configuration:

Code: Select all

configure_out_port_strobed_slave(void port p, in port readyin, clock  clk, unsigned initial)
where readyin is connected to RTS; implements the port for the transmitter

Code: Select all

configure_in_port_strobed_master(void port p, out port readyout, const clock  clk)
where readyout is connected to CTS; implements the port for the receiver

not configure_x_port_handshake, as it implements a full handshake where one side will also send a signal when sending data.

I never was able to work with the port handshakes so far. The result always fails; there is definitely something i am doing wrong. Anyone ever managed to do some UART handshakes that way? Thanks!
Strobed slaves/master tend to be used with synchronous transfers and often use buffered ports, will you be using a synchronous uart configuration?
pasau
Experienced Member
Posts: 77
Joined: Fri Dec 06, 2013 7:05 pm

Post by pasau »

i changed

Code: Select all

p @ t <: >> e;
for

Code: Select all

p @ t <: e;
            e >>= 1;
and it solved my problem for the 4 bit port. Im not even sure what the default line is supposed to do, but with the change i made i works on all port widths.

About the strobing, i think you are right, so i can not use it since i do asynchronous UART, thanks for this precision