Xuartctl: Difference between revisions

From embeddedTS Manuals
Line 228: Line 228:


== When I brought up my first port it appeared as /dev/pts/1, but normally shows up as /dev/pts/0 ==
== When I brought up my first port it appeared as /dev/pts/1, but normally shows up as /dev/pts/0 ==
The psuedo terminal devices will show up in order they were brought up, and other devices can claim them as xuartctl does.  If you want this consistancy, it is usually best to link the files to the output of xuartctl's ttyname.
The psuedo terminal devices will show up in order they were brought up, and other devices can claim them as xuartctl does.  Commonly telnet or ssh will use a pts device for their terminal.  If you want this to have some consistancy, it is usually best to link the files to the output of xuartctl's ttyname.

Revision as of 22:45, 23 June 2011

xuartctl
Xuartctl-diagram.png

xuartctl is a userspace driver utility to manage the UARTs that go through the FPGA.

Overview

XUART serial ports are also implemented entirely from userspace. The 8 serial ports have a single shared 4kByte receive FIFO which makes real time interrupt latency response less of a concern and in actual implementation, the serial ports are simply polled at 100Hz and don't even use an IRQ. Even with all 8 ports running at 230400 baud, it is not possible to overflow the receive FIFO in 1/100th of a second. The "xuartctl --server" daemon is started by default in the INITRD linuxrc file which sets up listening TCP/IP ports for all 8 XUART channels on ports 7350-7357. An application may simply connect to these ports via localhost (or via the network) and use the serial ports as if they were network services.

Usage

The xuartctl utility is split into 2 parts. The first part is the main server. This server must run on the board and provides the communication between the FPGA and the TCP ports. This can be created by running:

xuartctl --server

You can also specify the speed and mode arguments to make them the default for the port servers. The port servers are created by simply specifying a port after the main server has been started:

xuartctl --server --port=0 --speed=115200

Help

Usage: xuartctl [OPTION] ...
       xuartctl --port=PORT [OPTION] ... -- [COMMAND] [ARGS]
Technologic Systems XUART core userspace driver utility.
Example: xuartctl --server
         xuartctl --port=192.168.0.50:7350 --speed=9600 -- /bin/sh -i
         xuartctl --port=0 --test

  -i, --irq=N             Use IRQ N as XUART IRQ (32)
  -r, --regstart=ADD      Use ADD address as regstart (0x600ff100)
  -m, --memstart=ADD      Use ADD address as memstart (0x60000000)
  -s, --speed=BAUD        Use BAUD as default baudrate (115200)
  -o, --mode=MODE         Use MODE as default mode (8n1)
  -d, --server            Daemonize and run as server
  -I, --bind=IPADDR       Bind server to IPADDR
  -p, --port=PORT         Connect to local or remote XUART port
  -t, --test              Run loopback and latency test
  -h, --help              This help

Supported Modes

Mode Notes
8n1 (default mode)
8n2
dmx baudrate argument is ignored, uses 250 kbaud
8e1
8o1
8e2
8o2
7n1
7n2
7e1
7o1
7e2
7o2
9n1 The pseudo-tty is incompatible with this mode. This mode must be used with raw.
raw Allows RAW 16 bit communication with the main server

Raw mode

Raw mode will set the port settings for a TCP server to allow raw communication. The port server will use this mode to abstract the other modes as pty devices, but in raw mode you can communicate with 9n1 or even use 10 bits with no parity. If you do not need a nonstandard mode, then you should use the normal port server and access the XUART through the pts device.

RX Processing

The receiver uses 4kbytes arranged as a 2048 x 16-bit ring buffer. When a character, break, or period of idle exceeding the set idle threshold is received, an entry is written to the current address in the ring buffer and the current address is incremented. When the address reaches the end of the ring buffer, it rolls over back to 0. The format of each entry into the ring buffer is as follows:

Bit Used for
0-10 RX Data
11-12 RX Type
13-15 UART# character received from

RX Types:

Value Type
00 Character
01 Break
10 Idle
11 Invalid

When RX type is '00', the received character is present in data bits 10-0 left justified. The remaining LSB bits are random and should not be used.

When the RX type is '01' or '10' -- indicating a break condition or an extended period of idle was detected -- the remaining 11 least significant bits represent the length of the condition in bit times. However, if bit 10 is set, the actual 10 bit result should be left shifted by 6. A break of any length will be reported, but an idle RX entry will only be inserted into the ring buffer if it exceeds the programmed idle threshold from above. A break must first exceed the character time before being considered a break and the counter only starts once that happens, i.e. for a 8N1 (8 data bits, 1 start bit, 1 stop bit) 10 should be added to the counted result.

Since an RX type of '11' will never be written, software may choose to write this value to all data bytes as a way to know how much of the RX ring buffer has been updated since the last RX processing event. It is expected that RX processing be not only run in response to an RX interrupt, but also as part of a low speed timer interrupt. By knowing which UARTS are activated and at what baud rates and idle thresholds, worst case ring buffer overflow time can be computed.

TX Opcodes

Each transmitter has a dedicated 256 entry ring buffer in an external memory. Each entry is 16 bits and contains not only bytes to be transmitted, but also opcodes for fixed length break/idle and commands to change UART parameters such as baud rate, idle threshold, and mode. TX memory starts at offset 0x1000 of the external UART memory and each ring buffer is laid out contiguously.

Bit Used for
0-10 Opcode data
11-12 Opcode type
13 sets TX IRQ at start of TX processing this entry
14-15 reserved, should be zero.

Opcode Types:

Value Type
00 Character
01 Break
10 Idle
11 control opcode (updates internal UART regs)

Opcode '00' data bits 10-0 are right justified character data bits. Number of data bits can be 7-10 as configured below.

Opcode '01' and '10' data bits 9-0 represent the number of bit times the chosen line condition is set for (idle or break) until the next character. If bit 10 is set, the 10 bit number is left shifted by 6 to allow for longer periods than could be represented in a 10 bit counter. Two back to back break opcodes will have at least 2 bit times of idle between them.

Examples

Run local TCP only

By default when the main XUART server is created it opens ports so they are accessible from other systems. To bind locally, create the main server by running this:

   xuartctl --server --bind=127.0.0.1

Change the default mode and baud rate for all ports

The default mode is "8N1" and default baud rate is 115200-- should the default need to be changed, modifying the linuxrc line that invokes the XUART server can be changed from:

   xuartctl --server

to

   xuartctl --server --speed=9600 --mode=7e1

Configure baud rate for specific port

xuartctl --port 0 --speed 115200

Configure xuarts on startup

During startup (usually linuxrc for fastboot, or /etc/rc.local for debian) you can add these lines to initialize the port servers so they are consistent.

eval $(xuartctl --port 0 --speed 9600 2>&1); ln -s $ttyname /dev/ttyxuart0
eval $(xuartctl --port 1 --speed 115200 2>&1); ln -s $ttyname /dev/ttyxuart1
eval $(xuartctl --port 2 --speed 38400 2>&1); ln -s $ttyname /dev/ttyxuart2

Create a local xuart port server running on a remote xuartctl main server

If the xuartctl --server is running remotely on 192.168.0.50, you could run this from any remote system:

xuartctl --port=192.168.0.50:7350 --speed=9600

FAQ

How do I kill the old xuart process controlling one port?

When you run xuartctl on a port that is already running, it will replace that instance without affecting the other configured ports.

xuartctl works in the booted environment, but not in my startup scripts

Make sure the main server is started when you try to start a port server. If you add your scripts in /etc/rc.local or your fastboot linuxrc, you should be fine. However if it doesn't start you can create the main server instance with:

xuartctl --server

When I brought up my first port it appeared as /dev/pts/1, but normally shows up as /dev/pts/0

The psuedo terminal devices will show up in order they were brought up, and other devices can claim them as xuartctl does. Commonly telnet or ssh will use a pts device for their terminal. If you want this to have some consistancy, it is usually best to link the files to the output of xuartctl's ttyname.