The intention of this module is to implement high speed uart, at the expense of threads and 1-bit ports. Other modules provide lower-speed uarts that are thread-efficient, or that may use fewer 1-bit ports. This module will support a 10 Mbaud rate with 100 MIPS threads, and correspondingly less with lower MIPS per thread.
Note: the compiler inserts a spurious ZEXT and SETC in two places which makes 10 Mbit fail with 83 MIPS threads.
This UART is supported by all the hardware platforms from XMOS having suitable IO such as XC-1,XC-1A,XC-2,XK-1,etc and can be run on any XS1-L or XS1-G series devices.
The example is prepared to run on teh XK-1 but can be easily modified for other boards. However note that a 500 MHz core clock is expected so when running on G4 devices the baud rate should be reduced until it works, which can be done by altering the last “clocks” argument to the call to uart_tx_fast and uart_rx_fast in app_uart_fast/src/main.xc.
This function implements a fast UART.
It needs an unbuffered 1-bit port, a streaming channel end, and a number of port-clocks to wait between bits. It receives a start bit, 8 bits, and a stop bit, and transmits the 8 bits over the streaming channel end as a single token. On a 62.5 MIPS thread this function should be able to keep up with a 10 MBit UART sustained (provided that the streaming channel can keep up with it too).
This function does not return.
Parameters: |
|
---|
This function implements a fast UART.
It needs an unbuffered 1-bit port, a streaming channel end, and a number of port-clocks to wait between bits. It waits for a token on the streaming channel, and then sends a start bit, 8 bits, and a stop bit. On a 62.5 MIPS thread this function should be able to keep up with a 10 MBit UART sustained (provided that the streaming channel can keep up with it too).
This function does not return.
Parameters: |
|
---|
Declare ports (and clock blocks if you do not want to run the ports of the reference clock):
clock refClk = XS1_CLKBLK_REF;
in port rx = XS1_PORT_1A;
out port tx = XS1_PORT_1B;
A function that produces data (just bytes 0..255 in this example)
void produce(streaming chanend c) {
for(int i = 0; i < 256; i++) {
c <: (unsigned char) i;
}
}
A function that consumes data (and in this example throws it away)
void consume(streaming chanend c) {
unsigned char buf[256];
unsigned char foo;
for(int i = 0; i < 200; i++) {
c :> buf[i];
}
for(int i = 0; i < 200; i++) {
printhexln(buf[i]);
}
}
And a main par that starts the threads:
int main(void) {
streaming chan c, d;
configure_out_port_no_ready(tx, refClk, 1);
configure_in_port_no_ready(rx, refClk);
clearbuf(rx);
par {
produce(d);
consume(c);
uart_tx_fast(tx, d, 100);
uart_rx_fast(rx, c, 100);
}
}