Applications - UART
Introduction
This topic shows how the Universal Asynchronous Receiver Transmitter (UART) functionality of the SAMA5D2 Series Arm® Cortex®-A5 Microprocessor Unit (MPU) is enabled in the Linux® kernel and how to access the UART in User Space.
The ATSAMA5D27 SOM1 contains five UART peripherals to provide two-pin serial communications.
In the Linux kernel, the UART device driver implementation is based on the TeleTYpewriter (TTY) framework. The UART device will be registered as a ttySx character device (x refers to the device number).
The ttySx character device uses standard character device node interface commands such as open(), read(), and write(). The TTY framework also has its own set of interface functions for special features.
Prerequisites
This application is developed for the ATSAMA5D27-SOM1-EK1 development platform:
This application is developed using the Buildroot build system.
Hardware
For this application, you will be controlling the UART pins of the mikroBUS™ 1 expansion socket of the ATSAMA5D27-SOM1-EK1. The accompanying Expansion figure shows the expansion capability of the SOM1-EK1.
The ATSAMA5D27 SOM1 contains five UART peripherals to provide two-pin serial communications.
mikroBUS
You will control the UART4 peripheral pins PB3 and PB4 from the ATSAMA5D27-SOM1 which connects to J25 pins 3 and 4 of the mikroBUS 1 connector (labeled RX_mBUS1 and TX_mBUS1 on the schematic).
mikroBUS 1 pin | Schematic Name | UART4 | Package Pin |
---|---|---|---|
J25 pin 3 | RX_mBUS1 | URXD4 | PB3 |
J25 pin 4 | TX_mBUS1 | UTXD4 | PB4 |
mikroBUS 1
Serial-to-USB Adapter (TTL Level)
To view the communications from the ATSAMA5D27-SOM1 UART, connect the SOM1-EK1 to a Serial-to-USB adapter with the following pin assignments:
mikroBUS 1 pin | Schematic Name | Serial-to-USB Adapter |
---|---|---|
J25 pin 3 | RX_mBUS1 | TXD |
J25 pin 4 | TX_mBUS1 | RXD |
J25 pin 8 | GND | GND |
Buildroot Configuration
Objective: Using Buildroot, build a bootable image and FLASH onto a SD Memory Card for the ATSAMA5D27-SOM1-EK1 development board.
Follow the steps for building the image on the "Buildroot - Create Project with Default Configuration" page. You will use the default configuration file, atmel_sama5d27_som1_ek_mmc_dev_defconfig.
Device Tree
Objective: Observe how the UART peripheral was configured for two-pin serial communications in the device tree. No changes are required.
Once Buildroot has completed its build, the UART definitions for the ATSAMA5D27-SOM1-EK1 were configured by a Device Tree. The Device Tree Source (DTS) includes *.dtsi and *.dts files which are located in the Buildroot output directory, /output/build/linux-linux4sam_6.0/arch/arm/boot/dts/.
Examine the sama5d2.dtsi file and observe the UART peripheral assignments:
728 #clock-cells = <0>;
729 reg = <28>;
730 atmel,clk-output-range = <0 83000000>;
731 };
.
.
1388 uart4: serial@fc00c000 {
1389 compatible = "atmel,at91sam9260-usart";
1390 reg = <0xfc00c000 0x100>;
1391 dmas = <&dma0
1392 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
1393 AT91_XDMAC_DT_PERID(43))>,
1394 <&dma0
1395 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
1396 AT91_XDMAC_DT_PERID(44))>;
1397 dma-names = "tx", "rx";
1398 interrupts = <28 IRQ_TYPE_LEVEL_HIGH 7>;
1399 clocks = <&uart4_clk>;
1400 clock-names = "usart";
1401 status = "disabled";
1402 };
Line 729: the PID of UART4 is 28. This definition of the offset will be used to enable the UART4 clock in the PMC.
Line 730: the UART4 input clock. The maximum frequency is 83 MHz.
Line 1389: specifies which driver will be used for this UART device.
Line 1390: the UART4 base address is 0xfc00c000, size is 0x100.
Line 1391: specifies two DMA channels that will be used for transmit (TX) and receive (RX).
Line 1398: the PID of UART 4 in 28, high level triggered, priority 7. This information is used to configure UART4 interrupt in the AIC.
Line 1399: the definition of the UART4 clock source.
Line 1401: status is ‘disabled’ and will be enabled in the at91-sama5d27_som1_ek.dts file below.
Examine the at91-sama5d27_som1_ek.dts file and observe the UART device assignments:
57 serial0 = &uart1; /* DBGU */
58 serial1 = &uart4; /* mikro BUS 1 */
59 serial2 = &uart2; /* mikro BUS 2 */
60 i2c1 = &i2c1;
61 i2c2 = &i2c2;
62 };
.
.
221 uart4: serial@fc00c000 {
222 atmel,use-dma-rx;
223 atmel,use-dma-tx;
224 pinctrl-names = "default";
225 pinctrl-0 = <&pinctrl_mikrobus1_uart>;
226 status = "okay";
227 };
.
.
510 pinctrl_mikrobus1_uart: mikrobus1_uart {
511 pinmux = <PIN_PB3__URXD4>,
512 <PIN_PB4__UTXD4>;
513 bias-disable;
514 };
Line 58: shows the alias of UART4 is serial1, therefore UART4 will be registered as ttyS1.
Line 222: enables DMA for RX.
Line 223: enables DMA for TX.
Line 225: shows the pin definition for UART4.
Line 226: sets status to ‘okay,’ enabling the UART4 device.
Line 511: shows the mux of pin PB3 will be switched to URXD4.
Line 512: shows the mux of pin PB4 will be switched to UTXD4.
Line 513: disables the pull-up/down feature.
Kernel
Objective: Observe how the UART functionality was configured in the Linux kernel. No changes are required.
From the buildroot directory, run the Linux kernel menuconfig:
The top-level menu will be displayed:
Device Driver
Select Device Drivers ---->.
Observe -*- AT91 USART Driver is selected.
With the default setting, a UART device will be added via the Multifunction Device Driver (MFD).
Select Serial Drivers ---->.
Observe that the [*] AT91 on-chip serial port support option has been selected.
This enables the driver for the on-chip UART’s of the AT91 processors.
Rootfs
User Space:
As discussed in the Device Tree section above, the UART4 peripheral is registered as ttyS1. Enabling the kernel feature (default), you can access UART driver via /dev/ttyS1 device node.
Application
The following is a C-Language demonstration program (uart.c) for accessing the UART port driver:
To compile:
Source code:
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#define DEV_TTY "/dev/ttyS1"
#define BUF_SIZE 256
int main(int argc, char *argv[])
{
int fd;
int ret;
char tx_buf[] = "Hello World!\n\r";
char rx_buf[BUF_SIZE] = "";
struct termios options;
/* open uart */
fd = open(DEV_TTY, O_RDWR|O_NOCTTY);
if (fd < 0) {
printf("ERROR open %s ret=%d\n\r", DEV_TTY, fd);
return -1;
}
/* configure uart */
tcgetattr(fd, &options);
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cc[VTIME] = 10; // read timeout 10*100ms
options.c_cc[VMIN] = 0;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_oflag &= ~OPOST;
options.c_iflag &= ~(ICRNL | IXON);
cfsetispeed(&options, B115200);
cfsetospeed(&options, B115200);
options.c_cflag |= (CLOCAL | CREAD);
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
while (1) {
/* read uart */
while ((ret = read(fd, rx_buf, BUF_SIZE-1)) > 0) {
puts(rx_buf);
memset(rx_buf, 0, ret);
}
/* write uart */
ret = write(fd, tx_buf, sizeof(tx_buf));
if (ret != sizeof(tx_buf))
printf("ERROR write ret=%d\n", ret);
}
/* close uart */
close(fd);
return 0;
}
Hands On
Copy the uart_test program to the target and execute.
# ./uart_test
While connected to the Serial-to-USB adapter, open a terminal program and connect to the COM port of the adapter and observe the mBUS1 UART output.
Tools and Utilities
Microcom is a minimalistic terminal program for communicating with devices over a serial connection. It is included with BusyBox. The default configuration of Buildroot configures Microcom.
From the Buildroot directory, run the BusyBox menuconfig:
Observe the [*] microcom utility program has been selected.
Using Microcom
On the target (SOM1-EK1) execute the following command (CTRL + X will exit). Then, type any string of characters:
Type “Hello World!”
While connected to the Serial-to-USB adapter, open a terminal program and connect to the COM port of the adapter and observe the mBUS1 UART output.
Summary
In this topic, you used Buildroot to build an image with UART support for the ATSAMA5D2 Series MPU. You accessed the UART via User Space by the /dev/ttyS1 device. You also accessed the UART driver using the Microcom utility program. You walked through the device tree and kernel to observe how the embedded Linux system configures the source code for building.