# Using the Serial ports on Aria G25 SOM

<abstract>
Aria G25 has four USARTs, two UARTs and one DBGU port.
This article illustrates how to activate and use them.
</abstract>

<div class="alert alert-info" role="alert" markdown="1">
Unfortunately not all the six ports can be activate simultaneously. I suppose that it's due to a bug in the Kernel driver. 
</div>

Using this device three I have enabled up to 3 USARTs and 2 UARTs

* [acme-aria-serial.dts](./acme-aria-serial.dts)

To test it just save this file in the /boot directory of Aria G25 or in the first microSD partition.
I have used [this image](https://www.acmesystems.it/download_aria) (Kernel Linux 4.19.128 - Debian Buster 10) to try.

* [acme-aria.dtb](./acme-aria.dtb)

To check the serial port enabled type this command:

	acme@aria:~$ dmesg | grep serial
		[    0.359375] fffff200.serial: ttyS0 at MMIO 0xfffff200 (irq = 16, base_baud = 8333333) is a ATMEL_SERIAL
		[    0.679687] f801c000.serial: ttyS1 at MMIO 0xf801c000 (irq = 23, base_baud = 8333333) is a ATMEL_SERIAL
		[    0.687500] f8020000.serial: ttyS2 at MMIO 0xf8020000 (irq = 24, base_baud = 8333333) is a ATMEL_SERIAL
		[    0.695312] f8024000.serial: ttyS3 at MMIO 0xf8024000 (irq = 25, base_baud = 8333333) is a ATMEL_SERIAL
		[    0.710937] f8040000.serial: ttyS4 at MMIO 0xf8040000 (irq = 26, base_baud = 8333333) is a ATMEL_SERIAL
		[    0.718750] f8044000.serial: ttyS5 at MMIO 0xf8044000 (irq = 27, base_baud = 8333333) is a ATMEL_SERIAL

To see the devices activated type:

	acme@aria:~$ ls -al /dev/ttyS*
		crw------- 1 acme tty     4, 64 Mar  4 19:07 /dev/ttyS0
		crw-rw---- 1 root dialout 4, 65 Mar  4 18:56 /dev/ttyS1
		crw-rw---- 1 root dialout 4, 66 Mar  4 18:56 /dev/ttyS2
		crw-rw---- 1 root dialout 4, 67 Mar  4 18:56 /dev/ttyS3
		crw-rw---- 1 root dialout 4, 68 Mar  4 18:56 /dev/ttyS4
		crw-rw---- 1 root dialout 4, 69 Mar  4 18:56 /dev/ttyS5

## Pinout and device tree definitions port by port

### USART0

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| TXD0    | O   | Transmit data      | S23 (PA0)  |
| RXD0    | I   | Receive data       | S22 (PA1)  |
| RTS0    | O   | Request to send    | S21 (PA2)  |
| CTS0    | I   | Clear to send      | S20 (PA3)  |

	usart0: serial@f801c000 {
		status = "okay";
	};

### USART1

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| TXD1    | O   | Transmit data      | S18 (PA5)  |
| RXD1    | I   | Receive data       | S17 (PA6)  |
| RTS1    | O   | Request to send    | E7  (PC27) |
| CTS1    | I   | Clear to send      | E8  (PC28) |

	usart1: serial@f8020000 {
		status = "okay";
	};

### USART2

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| TXD2    | O   | Transmit data      | S16 (PA7)  |
| RXD2    | I   | Receive data       | S15 (PA8)  |
| RTS2    | O   | Request to send    |            |
| CTS2    | I   | Clear to send      |            |

	usart2: serial@f8024000 {
		status = "okay";
	}; 

### USART3

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| TXD3    | O   | Transmit data      | E2  (PC22) |
| RXD3    | I   | Receive data       | E3  (PC23) |
| RTS3    | O   | Request to send    | E4  (PC24) |
| CTS3    | I   | Clear to send      | E5  (PC25) |

	usart3: serial@f8028000 {
		status = "okay";
	};

### UART0

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| UTXD0   | O   | Transmit data      | N10 (PC8)  |
| URXD0   | I   | Receive data       | N11 (PC9)  |

	uart0: serial@f8040000 {
		status = "okay";
	};

### UART1

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| UTXD1   | O   | Transmit data      | N18 (PC16) |
| URXD1   | I   | Receive data       | N19 (PC17) |

	uart1: serial@f8044000 {
		status = "okay";
	};

### DBGU Debug serial port (/dev/ttyS0)

The debug port is used just for the boot message

| Signal  | Dir | Description        | Aria G25   |
|---------|-----|--------------------|------------|
| DTXD    | O   | Debug port tx data | S13 (PA10) |
| DRXD    | I   | Debug port rx data | S14 (PA9)  |

	dbgu: serial@fffff200 {
		status = "okay";
	};

@eshop='USB-3V-SER'

## User space programming

<abstract>
How to use the serial port from user space
</abstract>

### Python example

Install Python3 and Python Serial by typing:

	sudo apt update
	sudo apt install python3 python3-serial

Use this basic example or go to [pySerial library](https://github.com/pyserial/pyserial) web site:

	import serial
	import time

	ser = serial.Serial(
	    port='/dev/ttyS1',
	    baudrate=460800,
	    timeout=1,
	    parity=serial.PARITY_NONE,
	    stopbits=serial.STOPBITS_ONE,
	    bytesize=serial.EIGHTBITS
	)
	
	for packet in range(100):
	        for value in range(10):
	                for i in range(50):
	                        ser.write(chr(value+0x30).encode())
	                ser.write(b'\r\n')
	        ser.write(b'\r\n\n') 
	        print(packet)
	ser.flush()
	
	time.sleep(1)
	ser.close()

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

<pre class="prettyprint">
import sys
import serial
 
ser = serial.Serial(
    port='/dev/ttyUSB1', 
    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 ,
			sys.stdout.flush()
			linecounter=linecounter+1
			 
		print "%02X " % ord(value) ,
		sys.stdout.flush()
		bytecounter=bytecounter+1
		if bytecounter==0:
			print
			bytecounter=0
</pre>


### C example

<p>
This is a basic example on how to use a serial port in C.
</p>

<p>
Refer to these links to understand how it works.
</p>

<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>

<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"
 
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;
}
</pre>


#Related links

* [Atmel SAM9G25 Datasheet](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11032-32-bit-ARM926EJ-S-Microcontroller-SAM9G25_Datasheet.pdf)
* [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)
* @article='ts_serial_overrun'
* [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)

@include='bio_tanzilli'
