How to use UARTs

From IGEP - ISEE Wiki

Revision as of 19:07, 22 January 2012 by Pau (talk | contribs)

Jump to: navigation, search

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.

Minicom screenshot.png

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 things that is interesting 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 determine 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 like infinite loop or positive number determine loop max entrances

Constant WAIT: configure select max time.

Constants GPIO1 and GPIO2: they configure GPIOs used for debug via oscilloscope. Take care to configure mux and don't use this GPIO 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 test make with UART:

Decode Characters

Uart decode1withlf.JPG Uart decode0withlf.JPG Uart decode100000withlf.JPG
Decoding "1\n" Decoding "0\n" Decoding "100000\n"

Click to enlarge image

Select timeout

UART1 don't receive response and sending data every 5 seconds constant WAIT.

Uart select timeout9.JPG
UART1=Blue and UART3=Green

Click to enlarge image

RS232 Voltage params

Uart voltageparams8.JPG
Vpp=11.8V aprox , Vmin=-5.6V aprox

Click to enlarge image

Speed Overview

Uart 300 o.JPG Uart 4800 o.JPG Uart 115200 o.JPG Uart 3000000 o.JPG
Overview signal to 300 bauds Overview signal to 4800 bauds Overview signal to 115200 bauds Overview signal to 3000000 bauds
Uart 300 s.JPG Uart 4800 s.JPG Uart 115200 s.JPG Uart 3000000 s.JPG
Specific wave to 300 bauds Specific wave to 4800 bauds Specific wave to 115200 bauds
Specific wave to 3000000 bauds

Note that wave is degraded when speed is higher

Click to enlarge image

Lag

Uart lag left6.JPG Uart lag right7.JPG
Lag between UART1 and UART3 (300 bauds) Lag between UART3 and UART1 (300 bauds)

Click to enlarge image

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 operation system. 

This program have three I/O functions that connect to UART driver via ioctl (read(), write() and select()), but only select() and write() and put program in sleep mode, the proceess awake when I/O task is completed. Select functions is used to prevent that readswas blocked when there aren't data avaliable.



Under Construction