RTC Website

Programming the myRIO Universal Asynchronous Receiver/Transmitters (UARTs)

TX

The myRIO C library (see section 0.5) includes facilities for programming UARTs. Unlike other myRIO I/O programming, UART programming does not interact directly with the FPGA. Rather, the low-level UART routines are implemented with the virtual instrument software architecture (VISA) library (Foundation 2020). Using the UART facilities provided in the header file UART.h and the source file UART.c provided in the myRIO C library is the focus of this section.

The UART.h header loads the visa.h header and, in turn, the visatype.h header, which provide prototypes for VISA functions (such as viWrite() and viRead()) and macros (such as VI_SUCCESS) used to define UART functions in UART.c. The UART.c source file defines five functions for programming UART communication: Uart_Open() opens a UART session, Uart_Close() closes a session, Uart_Write() writes data to a UART session’s port, Uart_Read() reads data from a UART session’s port, and Uart_Clear() clears a UART session port’s receive buffer. We will briefly consider the functionality and usage of each function, but first we must understand the custom UART types used throughout the functions.

UART types

TX

There are several custom types defined in UART.h. The first is

typedef enum {
  Uart_ParityNone  = 0,
  Uart_ParityOdd   = 1,
  Uart_ParityEven  = 2,
  Uart_ParityMark  = 3,
  Uart_ParitySpace = 4
} Uart_Parity;

For instance, one could define a variable that stores a parity scheme: Uart_Parity parity = Uart_ParityOdd. A parity variable like this will be given as an argument for Uart_Open(). The second custom type is

typedef enum {
  Uart_StopBits1_0 = 10,          // 1.0 stop bits
  Uart_StopBits1_5 = 15,          // 1.5 stop bits
  Uart_StopBits2_0 = 20           // 2.0 stop bits
} Uart_StopBits;

This defines a list of three stop bit configurations. The stop bit can the usual single stop bit with a specific duration. That duration time multiplied by \(1.5\) is the \(1.5\) stop bit, and the duration multiplied by \(2.0\) produces the \(2.0\) stop bit.

The third custom data type is not an enum but a struct:

typedef struct {
  const char  *name;              // Resource name on UART port
  ViSession   defaultRM;          // Default resource manager session
  ViSession   session;            // ViSession reference
} MyRio_Uart;

This is our first encounter with a struct. We can declare and initialize a MyRio_Uart structure with

MyRio_Uart uart;                 // declare uart a "MyRio_Uart" struct
uart.name = "ASRL1::INSTR";      // define which uart port
uart.defaultRM = 0;              // define a default resource manager
uart.session = 0;                // define session reference

The name "ASRL1::INSTR" is for the A connector UART, and "ASRL2::INSTR" is for the B connector UART. Now that we have a handle on the custom UART types, we are ready to consider the UART functions that use them.

Opening and configuring a UART session with Uart_Open()

TX

The Uart_Open() function can open and configure a UART port. The prototype for Uart_Open() is

int32_t Uart_Open(
  MyRio_Uart *port,                 // UART port
  const uint32_t baud,              // bps, e.g., 9600, max 230400
  const uint8_t dataBits,           // 8 or 7 for a parity bit
  const Uart_StopBits stopBits,     // Uart_StopBits1_0, etc.
  const Uart_Parity parity          // Uart_ParityNone, etc.
);

Three of the five arguments are of the custom types just considered. The exact-width integer types uint32_t and uint8_t are familiar from subsection 2.3.2, and the const type qualifier is familiar from subsection 2.3.5. If a parity bit is used (i.e., if parity is other than Uart_ParityNone), dataBits should be 7. If the receiver needs more time between a single stop bit (Uart_StopBits1_0) and a new start bit, choose Uart_StopBits1_5 or Uart_StopBits2_0 for stopBits. If the UART session is opened and configured correctly, the function returns VI_SUCCESS.

Closing a UART session with Uart_Close()

TX

After we have finished using the UART port, the Uart_Close() function can close the port. The prototype for Uart_Close() is simply

int32_t Uart_Close(MyRio_Uart *port);

This port should be one that has been opened with Uart_Open(). If the port is successfully closed, the function returns VI_SUCCESS.

Reading data from a UART port with Uart_Read()

TX

The Uart_Read() function can read data from an opened UART port’s input register or buffer. The prototype for the function is

int32_t Uart_Read(MyRio_Uart* port,     // UART port
                  uint8_t* const data,  // array for the read data
                  const size_t nData);  // size of data array

Since the data arrive in bytes, each byte fits into a uint8_t array. This function waits for the UART input shift register or buffer to fill completely (or for a 1 second timeout to occur) before reading its data. When the read is successful, the function returns VI_SUCCESS.

Writing data to a UART port with Uart_Write()

TX

The Uart_Write() function can write data to an opened UART port’s output register or buffer. The prototype for the function is

int32_t Uart_Write(MyRio_Uart* port,    // UART port
                   const uint8_t* const data, // data to write
                   const size_t nData); // size of data array

As with the read, the data are packed in bytes of type uint8_t. The function waits for the output buffer or register to have sufficient space before writing. When the write is successful, the function returns VI_SUCCESS.

Clearing a UART port’s receive buffer with Uart_Clear()

TX

The Uart_Clear() function can clear an open UART port’s receive buffer or register. The function’s prototype is

int32_t Uart_Clear(MyRio_Uart* port);

If the clearing of the buffer is successful, the function will return VI_SUCCESS.

Configuration for the target display

TX

Now we consider how to write a program that properly configures the myRIO for UART communication with the display.

First, we will create a MyRio_Uart structure and populate it for the UART on the B connector:

uart.name = "ASRL2::INSTR";             // use the B connector UART
uart.defaultRM = 0;                     // default resource manager
uart.session = 0;                       // session reference

The rest of the configuration happens when we open the port with

status = Uart_Open(&uart,               // port information
                   baud_rate,           // baud rate bps
                   8,                   // no. of data bits
                   Uart_StopBits1_0,    // 1 stop bit
                   Uart_ParityNone);    // No parity

The integer baud rate baud_rate given in units of bits per second (bps) depends on the specific T1 display device (see section A.2). Now we can write uint8_t character codes in an array data of size nData to the target display with

Uart_Write(&uart, data, nData);         // write characters

For instance,

uint8_t data[1] = {'h'};                // casts 'h' to uint8_t
Uart_Write(&uart, data, 1);

The display interprets a received byte with decimal values \([32,127]\) as standard American Standard Code for Information Exchange (ASCII) characters. The uint8_t casting of 'h' gives it a decimal value of 104, which corresponds to the decimal ASCII code for “h”.

The display functions of the special character escape sequences '\b', '\f', '\n', and '\v' have already been introduced (see table 1.12). shows these escape sequences and the corresponding decimal code that results from casting the characters to uint8_t. For instance, '\b' casts to the decimal 8. However, in lab 3, we will interpret these escape sequences into custom codes that correspond to the functionality of the specific target display. The escape sequence '\f', which casts to 12, will clear the display; '\n', which casts to 10, should be mapped to a code that the display uses to move the cursor to the start of the next line. In lab 3, we will write the low-level display driver putchar_lcd(), which should translate the escape sequences of table 3.1 into the corresponding target display codes.

Foundation, Interchangeable Virtual Instruments (IVI). 2020. “VPP-4.3: The VISA Library.” Web. https://www.ivifoundation.org/downloads/VISA/vpp43_2022-05-19.pdf.

Online Resources for Section 3.9

No online resources.