Aria technical documentation Buy

Using the Serial ports on Aria G25 SOM

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

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

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 (Kernel Linux 4.19.128 - Debian Buster 10) to try.

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

User space programming

How to use the serial port from user space

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

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

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.

#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;
}

Related links

Sergio Tanzilli
Systems designer, webmaster of www.acmesystems.it and founder of Acme Systems srl

Personal email: tanzilli@acmesystems.it
Web pages: https://www.acmesystems.it --- https://www.acmestudio.it
Github repositories: https://github.com/tanzilli --- https://github.com/acmesystems
Telegram group dedicated to the Acme Systems boards: https://t.me/acmesystemssrl

Home page Aria technical documentation Buy