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 figure below shows the expansion capability of the SOM1-EK1.

ATSAMA5D27_SOM1_EK1_expansion_01.png

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

For more details of the package and pinout of the SAMA5D2, refer to “Table 6-2. Pinouts” in "SAMA5D2 Series Datasheet".

mikroBUS 1

mikrobus1_R1.png

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 pins 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
uart_to_usb.png

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 in the topic Create Project with Default Configuration. In the topic, 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 whic are located in the Buildroot output directory: /output/build/linux-linux4sam_6.0/arch/arm/boot/dts/.

1

Examine the sama5d2.dtsi file and observe the UART peripheral assignments:

727   uart4_clk: uart4_clk {
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.

2

Examine the at91-sama5d27_som1_ek.dts file and observe the UART device assignments:

56    aliases {
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.

1

From the buildroot directory, run the Linux kernel menuconfig:

$ make linux-menuconfig

The top-level menu will be displayed:

linux-config-top-level.png

Device Driver

2

Select Device Drivers —->.

linux-config-device-drivers.png

3

Select Multifunction device drivers —->.

4

Observe -*- AT91 USART Driver is selected.

AT91_uart_driver.png

With the default setting, a UART device will be added via the Multifunction Device Driver (MFD).

Some of the ATSAM USART controllers are compatible with the SPI function. However, the UART module does not support this feature.

5

Exit (ESC-ESC) and go back to the Device Drivers configuration.

6

Select Character devices —->.

7

Select Serial Drivers —->.

character_devices.png

8

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.

AT91_serial_support.png

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:

$ buildroot/output/host/bin/arm-buildroot-linux-uclibcgnueabihf-gcc uart.c -o uart_test

Be sure to type in the location of the cross-compiler on your host computer.

Source code:

#include <stdio.h>
#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.

# chmod +x uart_test
# ./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.

com_window_hello_world.png

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.

1

From the Buildroot directory, run the BusyBox menuconfig:

$ make busybox-menuconfig

2

Select Miscellaneous Utilities.

3

Observe the [*] microcom utility program has been selected.

busybox_microcom.png

Using Microcom

On the target (SOM1-EK1) execute the following command (CTRL + X will exit). Then, type any string of characters:

# microcom -s 115200 /dev/ttyS1
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.

com_window_2.png

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.

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.