Difference between revisions of "How to use UARTs"
From IGEP - ISEE Wiki
(→Error test) |
|||
Line 5: | Line 5: | ||
More information about [http://en.wikipedia.org/wiki/UART UART]. | More information about [http://en.wikipedia.org/wiki/UART UART]. | ||
− | '''Note''': This program have a debug option using GPIOs to debug via oscilloscope, this option is useful to learnt about the Kernel latencies. Debug has set to "write" and "select" functions. | + | '''Note''': This program have a debug option using GPIOs to debug via oscilloscope, this option is useful to learnt about the Kernel latencies. Debug has set to "write" and "select" functions. |
= Feedback and Contributing = | = Feedback and Contributing = | ||
Line 26: | Line 26: | ||
</pre> | </pre> | ||
By default, UART3 is used by Kernel serial console, we need to disable it, go to igep.ini file, comment next line: <br> | By default, UART3 is used by Kernel serial console, we need to disable it, go to igep.ini file, comment next line: <br> | ||
− | <pre>console=ttyS2,115200n8</pre> | + | <pre>console=ttyS2,115200n8</pre> |
− | |||
=== Check UARTs devices === | === Check UARTs devices === | ||
Line 50: | Line 49: | ||
root@localhost:~/PROGRAM# </pre> | root@localhost:~/PROGRAM# </pre> | ||
If you don't have setserial installed type: | If you don't have setserial installed type: | ||
− | <pre>apt-get install setserial</pre> | + | <pre>apt-get install setserial</pre> |
− | |||
=== Connect peripherals === | === Connect peripherals === | ||
Line 63: | Line 61: | ||
(Connect to 3) o---| 9 10 |---x (Not used) | (Connect to 3) o---| 9 10 |---x (Not used) | ||
------ | ------ | ||
− | </pre> | + | </pre> |
− | |||
=== Send some data === | === Send some data === | ||
Line 79: | Line 76: | ||
| style="text-align: left;" | [[Image:Minicom screenshot.png|640x400px]] | | style="text-align: left;" | [[Image:Minicom screenshot.png|640x400px]] | ||
|} | |} | ||
+ | |||
+ | = Schematics = | ||
+ | |||
+ | p | ||
= Compile and run program = | = Compile and run program = | ||
Line 99: | Line 100: | ||
Constant SIZE: it determines the max number of char than can be sent<br> | Constant SIZE: it determines the max number of char than can be sent<br> | ||
− | Constant DEBUG: it can break program infinite loop part, it can be useful to debug some errors, 0 (infinite loop) or positive number determine loop max entrances | + | Constant DEBUG: it can break program infinite loop part, it can be useful to debug some errors, 0 (infinite loop) or positive number determine loop max entrances |
Constant WAIT: it configurea select max time. | Constant WAIT: it configurea select max time. | ||
Line 106: | Line 107: | ||
Once you have installed module. Compile program using your Cross Compiler, I used arm-linux-gnueabi-: | Once you have installed module. Compile program using your Cross Compiler, I used arm-linux-gnueabi-: | ||
− | <pre>arm-linux-gnueabi-gcc uart-test-beta1.c -o uart-test-beta1 </pre> | + | <pre>arm-linux-gnueabi-gcc uart-test-beta1.c -o uart-test-beta1 </pre> |
− | |||
= Testing UART = | = Testing UART = | ||
Line 116: | Line 116: | ||
Decoded with [http://www.asciitable.com/ ASCII table]. | Decoded with [http://www.asciitable.com/ ASCII table]. | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
| [[Image:Uart decode1withlf.JPG|350x230px]] | | [[Image:Uart decode1withlf.JPG|350x230px]] | ||
Line 133: | Line 133: | ||
Program sends information via UART1 but don't receive response via UART3, because only a process is executed. This problem is repeated every 5 seconds (constant WAIT=5) until other process sends information via UART3 at the same speed. If "select" hasn't been implemented, process would have stayed blocked.<br> | Program sends information via UART1 but don't receive response via UART3, because only a process is executed. This problem is repeated every 5 seconds (constant WAIT=5) until other process sends information via UART3 at the same speed. If "select" hasn't been implemented, process would have stayed blocked.<br> | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
| [[Image:Uart select timeout9.JPG|350x230px]] | | [[Image:Uart select timeout9.JPG|350x230px]] | ||
Line 140: | Line 140: | ||
|} | |} | ||
− | Click to enlarge image | + | Click to enlarge image |
=== RS232 Voltage params === | === RS232 Voltage params === | ||
Line 146: | Line 146: | ||
More information [http://en.wikipedia.org/wiki/RS-232#Standard_details here]. | More information [http://en.wikipedia.org/wiki/RS-232#Standard_details here]. | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
| [[Image:Uart voltageparams8.JPG|350x230px]] | | [[Image:Uart voltageparams8.JPG|350x230px]] | ||
Line 159: | Line 159: | ||
Note that wave is degraded when speed is higher | Note that wave is degraded when speed is higher | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
| [[Image:Uart 300 o.JPG|260x172px]] | | [[Image:Uart 300 o.JPG|260x172px]] | ||
Line 188: | Line 188: | ||
You can see that RS232 have some lag between transmisions. This caused mainly by kernel process management. UART peripheral is controlled by Linux and It isn't a [http://en.wikipedia.org/wiki/Real-time_operating_system real-time operating system]. | You can see that RS232 have some lag between transmisions. This caused mainly by kernel process management. UART peripheral is controlled by Linux and It isn't a [http://en.wikipedia.org/wiki/Real-time_operating_system real-time operating system]. | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
| [[Image:Uart lag left6.JPG|350x230px]] | | [[Image:Uart lag left6.JPG|350x230px]] | ||
Line 201: | Line 201: | ||
This program have three I/O functions that connect to UART driver via ioctl: (read(), write() and select()). But select() and write() change process stat to sleep mode until system don't receive or transmit all information via UART. "select" function is used to prevent that read function can be blocked when data aren't available. <br>The next images (program with debug_gpio enabled and 300 bauds speed) show when process is executed or is waiting. Blue=UART1, Violet="write" and Green="select". When GPIO has HIGH value, process is blocked.<br> | This program have three I/O functions that connect to UART driver via ioctl: (read(), write() and select()). But select() and write() change process stat to sleep mode until system don't receive or transmit all information via UART. "select" function is used to prevent that read function can be blocked when data aren't available. <br>The next images (program with debug_gpio enabled and 300 bauds speed) show when process is executed or is waiting. Blue=UART1, Violet="write" and Green="select". When GPIO has HIGH value, process is blocked.<br> | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
| [[Image:Uart select5.JPG|260x172px]] | | [[Image:Uart select5.JPG|260x172px]] | ||
Line 220: | Line 220: | ||
select: blocked until all data is available (LF char received). | select: blocked until all data is available (LF char received). | ||
− | write: blocked until all data is send to UART buffer. | + | write: blocked until all data is send to UART buffer. |
=== Error test === | === Error test === | ||
Line 226: | Line 226: | ||
Every full process the number is increased twice. Program checks that this condicion is true, if it isn't accomplished, process will be finish. | Every full process the number is increased twice. Program checks that this condicion is true, if it isn't accomplished, process will be finish. | ||
− | {| | + | {| cellspacing="1" cellpadding="1" border="1" align="center" width="200" |
|- | |- | ||
− | | [[Image: | + | | [[Image:Uart error test2.png|640x400px]] |
|- | |- | ||
| Runs 16h without any transfer error (3000000 bauds)<br> | | Runs 16h without any transfer error (3000000 bauds)<br> | ||
|} | |} | ||
− | <br> | + | <br> |
− | [[Category:Communications]] [[Category:How_to_forge]][[Category:Tutorials]] | + | [[Category:Communications]] [[Category:How_to_forge]] [[Category:Tutorials]] |
Revision as of 17:48, 23 January 2012
Contents
Overview
This How-To is meant to be a starting point for people to learn use UART for IGEP v2 devices as quickly and easily as possible. In this how-to, we use Linaro Headless with Kernel 2.6.35.y and UART test program. This program is executed twice, at the same time inside the same IGEP. Its function is get a number via UART, increase it and send result to other UART, the result will be a infinite loop between 2 UARTs. (upload source code)
More information about UART.
Note: This program have a debug option using GPIOs to debug via oscilloscope, this option is useful to learnt about the Kernel latencies. Debug has set to "write" and "select" functions.
Feedback and Contributing
At any point, if you see a mistake you can contribute to this How-To.
Preparing IGEP
Configure IGEP
To test UARTs we use UART1 (dev/ttyS0) and UART3 (dev/ttyS2) via J960 connector using RS232 standard.
NOTE: Make sure that you installed open SSH server. If you don't have it go here.
By default, UART1 is used by RS485 driver, we need to disable it, edit igep.ini file:
board.ei485= yes
Maybe you don't found this line, replaced by or type this:
board.ei485= no
By default, UART3 is used by Kernel serial console, we need to disable it, go to igep.ini file, comment next line:
console=ttyS2,115200n8
Check UARTs devices
Make sure that Kernel detects UARTs, type:
dmesg | grep tty
The result will be similar at that:
root@localhost:~/PROGRAM# dmesg | grep tty [ 0.000000] console [tty0] enabled [ 0.598999] serial8250.0: ttyS0 at MMIO 0x4806a000 (irq = 72) is a ST16654 [ 0.784057] serial8250.1: ttyS1 at MMIO 0x4806c000 (irq = 73) is a ST16654 [ 0.969085] serial8250.2: ttyS2 at MMIO 0x49020000 (irq = 74) is a ST16654 [ 1.153503] serial8250.3: ttyS3 at MMIO 0x49042000 (irq = 80) is a ST16654 root@localhost:~/PROGRAM#
Get information about UARTs, type:
setserial -g /dev/ttyS[0123]
The result will be similar at that:
root@localhost:~/PROGRAM# setserial -g /dev/ttyS[0123] /dev/ttyS0, UART: 16654, Port: 0x0000, IRQ: 72 /dev/ttyS1, UART: 16654, Port: 0x0000, IRQ: 73 /dev/ttyS2, UART: 16654, Port: 0x0000, IRQ: 74 /dev/ttyS3, UART: 16654, Port: 0x0000, IRQ: 80 root@localhost:~/PROGRAM#
If you don't have setserial installed type:
apt-get install setserial
Connect peripherals
Connect IGEPv2 board using J960 connector like this:
J960 ------ (Not used) x---| 1 2 |---o (Connect to 8) (Connect to 9) o---| 3 4 |---x (Not used) (GND)·|---| 5 6 |---|· (GND) (Not used)x---| 7 8 |---o (Connect to 2) (Connect to 3) o---| 9 10 |---x (Not used) ------
Send some data
Use minicom to prove it, open two terminals via SSH and log with root user:
Terminal 1:
minicom -D /dev/ttyS0
Terminal 2:
minicom -D /dev/ttyS2
Type something in one terminal.
Schematics
p
Compile and run program
As explained above, the program uses GPIO for debug option via oscilloscope, it is necessary install user-gpio-drv.ko driver inside Linux Kernel, more information here .
There are some interesting things to configure, before compiling the program. Open it, seek next lines:
//Define Array char size #define SIZE 30 //Define Debug mode:0==Disable #define DEBUG 0 //Define wait select #define WAIT 5 //Set GPIO Debugger port //Be sure that mux is correctly configured and GPIOs are not used #define GPIO1 136 #define GPIO2 137
Constant SIZE: it determines the max number of char than can be sent
Constant DEBUG: it can break program infinite loop part, it can be useful to debug some errors, 0 (infinite loop) or positive number determine loop max entrances
Constant WAIT: it configurea select max time.
Constants GPIO1 and GPIO2: they configure GPIOs used for debug via oscilloscope. Take care to configure mux and don't use them for other purposes
Once you have installed module. Compile program using your Cross Compiler, I used arm-linux-gnueabi-:
arm-linux-gnueabi-gcc uart-test-beta1.c -o uart-test-beta1
Testing UART
Some tests do it:
Decode Characters
Decoded with ASCII table.
Decoding "1\n" | Decoding "0\n" | Decoding "100000\n" |
Click to enlarge image
select timeout
Program sends information via UART1 but don't receive response via UART3, because only a process is executed. This problem is repeated every 5 seconds (constant WAIT=5) until other process sends information via UART3 at the same speed. If "select" hasn't been implemented, process would have stayed blocked.
UART1=Blue and UART3=Green |
Click to enlarge image
RS232 Voltage params
More information here.
Vpp=11.8V aprox , Vmin=-5.6V aprox |
Click to enlarge image
Speed Overview
Note that wave is degraded when speed is higher
Click to enlarge image
Lag
You can see that RS232 have some lag between transmisions. This caused mainly by kernel process management. UART peripheral is controlled by Linux and It isn't a real-time operating system.
select: blocked until all data is available. | |
Lag between UART1 and UART3 (300 bauds) | Lag between UART3 and UART1 (300 bauds) |
Click to enlarge image
This program have three I/O functions that connect to UART driver via ioctl: (read(), write() and select()). But select() and write() change process stat to sleep mode until system don't receive or transmit all information via UART. "select" function is used to prevent that read function can be blocked when data aren't available.
The next images (program with debug_gpio enabled and 300 bauds speed) show when process is executed or is waiting. Blue=UART1, Violet="write" and Green="select". When GPIO has HIGH value, process is blocked.
select function time | Time between select and write | write function time | Time between write and select |
Click to enlarge image
In this case:
select: blocked until all data is available (LF char received).
write: blocked until all data is send to UART buffer.
Error test
Every full process the number is increased twice. Program checks that this condicion is true, if it isn't accomplished, process will be finish.
Runs 16h without any transfer error (3000000 bauds) |