Xuartctl: Difference between revisions
No edit summary |
No edit summary |
||
Line 27: | Line 27: | ||
== Help == | == Help == | ||
<source lang=bash> | <source lang=bash> | ||
Usage: xuartctl [OPTION] ... | Usage: xuartctl [OPTION] ... | ||
xuartctl --port=PORT [OPTION] ... -- [COMMAND] [ARGS] | xuartctl --port=PORT [OPTION] ... -- [COMMAND] [ARGS] | ||
Technologic Systems XUART core userspace driver utility. | Technologic Systems XUART core userspace driver utility. | ||
Example: xuartctl --server | 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 | |||
</source> | </source> | ||
Line 81: | Line 81: | ||
|- | |- | ||
| 9n1 | | 9n1 | ||
| The pseudo-tty is incompatible with this mode. | | The pseudo-tty is incompatible with this mode. This mode must be used with raw. | ||
|- | |- | ||
| raw | | raw | ||
| Allows RAW 16 bit communication with the main server | | 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 to use a strange data/stop bit size 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: | |||
{| class="wikitable" | |||
|- | |||
! Bit | |||
! Used for | |||
|- | |||
|0-10 | |||
|RX Data | |||
|- | |||
|11-12 | |||
|RX Type | |||
|- | |||
|13-15 | |||
|UART# character received from | |||
|} | |||
RX Types: | |||
{| class="wikitable" | |||
|- | |||
! 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. | |||
{| class="wikitable" | |||
|- | |||
! 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: | |||
{| class="wikitable" | |||
|- | |||
! 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 = | = 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: | |||
<source lang=bash> | |||
xuartctl --server --bind=127.0.0.1 | |||
</source> | |||
== Change the default mode and baud rate for all ports == | == Change the default mode and baud rate for all ports == |
Revision as of 22:41, 23 June 2011
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 to use a strange data/stop bit size 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
Edit your /etc/rc.local file and add in these lines before exit:
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. If you want this consistancy, it is usually best to link the files to the output of xuartctl's ttyname.