# How to use the SERIAL ports

<abstract>
Using the serial port from user space
</abstract>

## Python3 examples

Send a sequence of bytes

	import serial
	import time
	
	ser = serial.Serial(
	    port='/dev/ttyUSB0',
	    baudrate=9600,
	    timeout=1,
	    parity=serial.PARITY_NONE,
	    stopbits=serial.STOPBITS_ONE,
	    bytesize=serial.EIGHTBITS
	)
	
	packet = [0x54,0x51,0x41,0x12,0x00,0x02,0xFF,0xFF]
	
	# convert list to bytearray
	byte_array = bytearray(packet)

	while True:
	        ser.write(byte_array)
	        time.sleep(1)

	ser.close()


Read any bytes received on serial line and print out 
on stdout in hex format:

	import sys
	import serial
	
	ser = serial.Serial(
	    port='/dev/ttyUSB0',
	    baudrate=9600,
	    timeout=1,
	    parity=serial.PARITY_NONE,
	    stopbits=serial.STOPBITS_ONE,
	    bytesize=serial.EIGHTBITS
	)
	
	linecounter=0
	bytecounter=0
	bytesperline = 8
	while True:
	    bytesToRead = ser.inWaiting()
	
	    if bytesToRead>0:
	        value=ser.read(1)
	        if (bytecounter % bytesperline) == 0:
	            print("\n[%04X] - " % bytecounter,end='')
	            sys.stdout.flush()
	            linecounter=linecounter+1
	
	        print("%02X " % ord(value),end='')
	        sys.stdout.flush()
	        bytecounter=bytecounter+1
	        if bytecounter==0:
	            print
	            bytecounter=0

## C example

This is a basic example on how to use a serial port in C.

Refer to these links to understand how it works.

<ul>
<li><a href="http://linux.about.com/library/cmd/blcmdl3_termios.htm">Termios</a></li>
<li><a href="http://www.gnu.org/software/libc/manual/html_node/Low_002dLevel-I_002fO.html#Low_002dLevel-I_002fO">GNU Low-level I/O doc</a></li>
</ul>

	#include "stdio.h"     
	#include "string.h"    
	#include "unistd.h"    
	#include "fcntl.h"     
	#include "errno.h"     
	#include "sys/types.h"
	#include "sys/stat.h"
	#include "stdlib.h"
	#include "stdarg.h"
	#include "termios.h"
	 
	int main(void) {
		char txBuffer[10];
		char rxBuffer[10];
		int fd;
		struct termios tty_attributes;
	 
		if ((fd = open("/dev/ttyS1",O_RDWR|O_NOCTTY|O_NONBLOCK))<0) {
			fprintf (stderr,"Open error on %s\n", strerror(errno));
			exit(EXIT_FAILURE);
		} else {
			tcgetattr(fd,&tty_attributes);
	 
			// c_cflag
			// Enable receiver
			tty_attributes.c_cflag |= CREAD;		
	 
			// 8 data bit
			tty_attributes.c_cflag |= CS8;			
	 
			// c_iflag
			// Ignore framing errors and parity errors. 
			tty_attributes.c_iflag |= IGNPAR;		
	 
			// c_lflag
			// DISABLE canonical mode.
			// Disables the special characters EOF, EOL, EOL2, 
			// ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers by lines.
	 
			// DISABLE this: Echo input characters.
			tty_attributes.c_lflag &= ~(ICANON); 	 
	 
			tty_attributes.c_lflag &= ~(ECHO);		
	 
			// DISABLE this: If ICANON is also set, the ERASE character erases the preceding input 	
			// character, and WERASE erases the preceding word.
			tty_attributes.c_lflag &= ~(ECHOE);		
	 
			// DISABLE this: When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal.	
			tty_attributes.c_lflag &= ~(ISIG);		
	 
			// Minimum number of characters for non-canonical read.
			tty_attributes.c_cc[VMIN]=1;			
	 
			// Timeout in deciseconds for non-canonical read.
			tty_attributes.c_cc[VTIME]=0;			
	 
			// Set the baud rate
			cfsetospeed(&tty_attributes,B9600);		
			cfsetispeed(&tty_attributes,B9600);
	 
			tcsetattr(fd, TCSANOW, &tty_attributes);
	 
			txBuffer[0]='A';
			write(fd,txBuffer,1);
	 
			// Read a char
			if (read(fd,&rxBuffer,1)==1) {
				printf("%c",rxBuffer[0]);
				printf("\n");
			}	
		}	
	 
		close(fd);	
		return EXIT_SUCCESS;
	}

* For the RoadRunner SOM please read: @article='roadrunner_serial'

## Pinout of the serial ports

| Signal  | Dir | Description        | Acqua        | Aria G25   | Arietta     | 
|---------|-----|--------------------|--------------|------------|-------------|
| TXD0    | O   | Transmit data      | J2.14 (PD18) | S23 (PA0)  | J4.23 (PA0) | 
| RXD0    | I   | Receive data       | J2.11 (PD17) | S22 (PA1)  | J4.24 (PA1) | 
| RTS0    | O   | Request to send    | J2.12 (PD16) | S21 (PA2)  |             |
| CTS0    | I   | Clear to send      | J2.9  (PD15) | S20 (PA3)  |             |
| TXD1    | O   | Transmit data      | J2.46 (PB29) | S18 (PA5)  | J4.28 (PA5) |
| RXD1    | I   | Receive data       | J2.45 (PB28) | S17 (PA6)  | J4.27 (PA6) |
| RTS1    | O   | Request to send    |              | E7  (PC27) | J4.30 (PC27)|  
| CTS1    | I   | Clear to send      |              | E8  (PC28) | J4.29 (PC28)|  
| TXD2    | O   | Transmit data      | J3.13 (PE26) | S16 (PA7)  | J4.26 (PA7) |
| RXD2    | I   | Receive data       | J3.12 (PE25) | S15 (PA8)  | J4.25 (PA8) |
| RTS2    | O   | Request to send    | J3.11 (PE24) |            |             |
| CTS2    | I   | Clear to send      | J3.10 (PE23) |            |             |
| TXD3    | O   | Transmit data      | J3.7  (PE19) | E2  (PC22) |             |
| RXD3    | I   | Receive data       | J3.8  (PE18) | E3  (PC23) |             |
| RTS3    | O   | Request to send    | J3.5  (PE17) | E4  (PC24) |             |
| CTS3    | I   | Clear to send      | J3.6  (PE16) | E5  (PC25) |             |
| UTXD0   | O   | Transmit data      | J3.30 (PC30) | N10 (PC8)  |             |
| URXD0   | I   | Receive data       | J3.31 (PC29) | N11 (PC9)  |             |
| UTXD1   | O   | Transmit data      | J3.41 (PA31) | N18 (PC16) |             |
| URXD1   | I   | Receive data       | J3.32 (PA30) | N19 (PC17) |             |
| UTXD2   | O   | Transmit data      |              |            |             |
| URXD2   | I   | Receive data       |              |            |             |
| UTXD4   | O   | Transmit data      |              |            |             |
| URXD4   | I   | Receive data       |              |            |             |
| DTXD    | O   | Debug port tx data | J3.4  (PB31) | S13 (PA10) |             |
| DRXD    | I   | Debug port rx data | J3.3  (PB30) | S14 (PA9)  |             |

## Configure the device tree

### Acqua

	usart0: serial@f001c000 {
		status = "okay";
	};
	
	usart1: serial@f0020000 {
		status = "okay";
	};
	
	usart2: serial@f8020000 {
		status = "okay";
	};
	
	usart3: serial@f8024000 {
		status = "okay";
	};
	
	uart1: serial@f8028000 {
		status = "okay";
	};
	
	uart0: serial@f0024000 {
		status = "okay";
	};



##Related links

* [Atmel usart binding](https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/devicetree/bindings/serial/atmel-usart.txt?id=refs/tags/v3.13.11)
* [DMA bindings](https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/devicetree/bindings/dma/atmel-dma.txt?id=refs/tags/v3.13.11)

#Using the RS485 lines

<div class="text-success lead">
RS-485 is a standard defining the electrical characteristics of drivers and 
receivers for use in balanced digital multipoint systems. This standard is widely used for communications in 
industrial automation because it can be used effectively over long distances and in electrically noisy environments
</div>

* [Read the original version from Linux documentation](http://lxr.free-electrons.com/source/Documentation/serial/serial-rs485.txt)

<ul class="nav nav-tabs">
	<li class="nav active"><a href="#k34" data-toggle="tab">Kernel >=3.4</a></li>
	<li class="nav"><a href="#k28" data-toggle="tab">Previous Kernel</a></li>
</ul>


<div class="tab-content">
	<div class="tab-pane fade in active" id="k34" markdown="1">

## RS485 with DTS on Kernel version >= 3.4

If you are using a recent Linux Kernel with device tree enabled you have to specify inside 
the device tree source the RS485. After that you can open the serial port as a normal RS232 port.

This is an example for the /dev/ttyS2 on Aria G25 or Arietta G25 module:

<pre class="prettyprint">
usart3: serial@f8028000 {
	compatible = "atmel,at91sam9260-usart";
	reg = <0xf8028000 0x200>;
	interrupts = <8 4 5>;
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_usart3 &pinctrl_usart3_rts &pinctrl_usart3_cts >;
	linux,rs485-enabled-at-boot-time;
	rs485-rts-delay = <0 20>;
	status = "okay";
};
</pre>

The **rs485-rts-delay** parms are in 0.1 mS instead on mS as written on the Kernel doc.

### Python example

This example sends a char on the RS485 bus using a [DAISY-10](/DAISY-10) 
board wired on the __/dev/ttyS2__ serial port. If you are using a Terra board
plug the DAISY-10 on D10 connector ([..see the Terra pinout](/pinout_terra)).

<pre class="prettyprint">
import serial,fcntl, struct
 
ser = serial.Serial(
	port='/dev/ttyS2', 
	baudrate=9600, 
	timeout=1,
	parity=serial.PARITY_NONE,
	stopbits=serial.STOPBITS_ONE,
	bytesize=serial.EIGHTBITS
)  
 
fd=ser.fileno()
 
ser.write("0123456789")	# Send some char on the RS485 bus
s = ser.read(1)			# Wait for a char
print s
ser.close()
</pre>

	</div>

	<div class="tab-pane fade in" id="k28" markdown="1">

## RS485 without DTS on Kernel version < 3.4

If you are using an old Kernel Linux without the device tree you have to setup
the rs485 hardware mode as illustrated below:

###Python example

<pre class="prettyprint">
import serial,fcntl, struct
 
ser = serial.Serial(
	port='/dev/ttyS2', 
	baudrate=9600, 
	timeout=1,
	parity=serial.PARITY_NONE,
	stopbits=serial.STOPBITS_ONE,
	bytesize=serial.EIGHTBITS
)  
 
fd=ser.fileno()
serial_rs485 = struct.pack('hhhhhhhh', 1, 0, 0, 0, 0, 0, 0, 0)
fcntl.ioctl(fd,0x542F,serial_rs485)
 
 
ser.write("A")		# Send a "A" char to the serial port
s = ser.read(1)         # Wait for a char
print s
ser.close()
</pre>

###C example

<pre class="prettyprint">
#include "stdio.h"     
#include "string.h"    
#include "unistd.h"    
#include "fcntl.h"     
#include "errno.h"     
#include "sys/types.h"
#include "sys/stat.h"
#include "stdlib.h"
#include "stdarg.h"
#include "termios.h"
#include "linux/serial.h"  
 
#define TIOCSRS485 0x542F
 
int main(void) {
	char txBuffer[10];
	char rxBuffer[10];
	int fd;
	struct termios tty_attributes;
	struct serial_rs485 rs485conf;
 
	if ((fd = open("/dev/ttyS2",O_RDWR|O_NOCTTY|O_NONBLOCK))<0) {
		fprintf (stderr,"Open error on %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	} else {
		tcgetattr(fd,&tty_attributes);
 
		// c_cflag
		// Enable receiver
		tty_attributes.c_cflag |= CREAD;		
 
		// 8 data bit
		tty_attributes.c_cflag |= CS8;			
 
		// c_iflag
		// Ignore framing errors and parity errors. 
		tty_attributes.c_iflag |= IGNPAR;		
 
		// c_lflag
		// DISABLE canonical mode.
		// Disables the special characters EOF, EOL, EOL2, 
		// ERASE, KILL, LNEXT, REPRINT, STATUS, and WERASE, and buffers 
		// by lines.
 
		// DISABLE this: Echo input characters.
		tty_attributes.c_lflag &= ~(ICANON); 	 
 
		tty_attributes.c_lflag &= ~(ECHO);		
 
		// DISABLE this: If ICANON is also set, the ERASE character 
		// erases the preceding input 	
		// character, and WERASE erases the preceding word.
		tty_attributes.c_lflag &= ~(ECHOE);		
 
		// DISABLE this: When any of the characters INTR, QUIT, SUSP, 
		// or DSUSP are received, generate the corresponding signal.	
		tty_attributes.c_lflag &= ~(ISIG);		
 
		// Minimum number of characters for non-canonical read.
		tty_attributes.c_cc[VMIN]=1;			
 
		// Timeout in deciseconds for non-canonical read.
		tty_attributes.c_cc[VTIME]=0;			
 
		// Set the baud rate
		cfsetospeed(&tty_attributes,B9600);		
		cfsetispeed(&tty_attributes,B9600);
 
		tcsetattr(fd, TCSANOW, &tty_attributes);
 
		// Set RS485 mode: 
		rs485conf.flags |= SER_RS485_ENABLED;
		if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
			printf("ioctl error\n");
		}
 
		txBuffer[0]='A';
		write(fd,txBuffer,1);
 
		// Read a char
		if (read(fd,&rxBuffer,1)==1) {
			printf("%c",rxBuffer[0]);
			printf("\n");
		}	
	}	
 
	close(fd);	
	return EXIT_SUCCESS;
}
</pre>

	</div>
</div>	


#Related links

* [Linux Kernel RS485 documentation](http://lxr.linux.no/linux+v4.4/Documentation/serial/serial-rs485.txt)
* [Device Tree Binding for RS485](http://lxr.linux.no/linux+v4.4/Documentation/devicetree/bindings/serial/rs485.txt)

@include='bio_tanzilli'
