I've created a function to quickly set up basic UART ports. I thought I would post it here in case anyone else might find it useful or if anyone had thoughts on how it could be improved. I think when it comes to production it may be better in terms of memory management to manually configure the UARTs and avoid this but it seems useful for development. As a test in the hello example project, modify hello.c, include uartconf.h and comment out the ConfigureUART function.
#uartconf.h
#ifndef UARTCONFIG_H_
#define UARTCONFIG_H_
#include <stdint.h>
#include <stdbool.h>
#include "driverlib/gpio.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/debug.h"
#include "utils/uartstdio.h"
#include "driverlib/rom.h"
// Friendly print message macros for debug.
#define NL UARTprintf("\r\n") // print a newline
#define TAB UARTprintf("\t") // print a tab
#define PRINT(s) UARTprintf("%s", s) // print a string
#define PRINT_C(c) UARTprintf("%s: %c", #c, c) // print a char variable
#define PRINT_D(d) UARTprintf("%s: %d", #d, d) // print a decimal variable
#define PRINT_I(i) PRINT_D(i) // print an integer variable
#define PRINT_S(s) UARTprintf("%s: %s", #s, s) // print a string variable
#define PRINT_U(u) UARTprintf("%s: %u", #u, u) // print an unsigned variable
#define PRINT_X(x) UARTprintf("%s: %x", #x, x) // print a hexadecimal variable
#define PRINT_LINE UARTprintf("Line[%d]", __LINE__); // print the line number where this is called
/* ConfigureUART
* This can replace the standard ConfigureUART function found in many
* of the TivaWare example projects.
*
* This version of the function allows for variadic input and automatically
* configures the parameters based on which UART you want to use. When
* you call ConfigureUART the parameter list will be parsed/generated
* and sent to ConfigureUART_base
*
* \param ui32PortNum - UART Port number to configure (default=0)
* \param ui32Baud - Baud rate to be used on that UART (default=115200)
* \param ui32SrcClock - Source clock frequency (default=16000000)
*
* Example Usage:
* - ConfigureUART();
* - All defaults:
* Enable UART0, Rx on PA0, Tx on PA1
* Set baud rate to 115200
* Source clock frequence to 16000000
* - ConfigureUART(2);
* - Port number only:
* Enable UART2, Rx on PD6, Tx on PD7
* Default baud and clock
* - ConfigureUART(.ui32Baud=9600);
* - Baud rate only:
* Set baud rate to 9600
* Default UART0 and clock
* - ConfigureUART(.ui32PortNum=0,.ui32Baud=115200,.ui32SrcClock=16000000);
* - All explicitly defined
* - ConfigureUART(0,115200,16000000);
* - All defined
*/
void ConfigureUART_base(uint32_t ui32PortNum, uint32_t ui32Baud, uint32_t ui32SrcClock);
typedef struct {
// Arguments required ConfigureUART function
uint32_t ui32PortNum; // The UART Port number (0-7)
uint32_t ui32Baud; // Baud rate used to communicate
uint32_t ui32SrcClock; // Source clock frequency
} ConfigureUART_args;
void var_ConfigureUART(ConfigureUART_args in);
#define ConfigureUART(...) var_ConfigureUART((ConfigureUART_args){__VA_ARGS__});
/*\ConfigureUART */
/* TIVA UART Configuration Table
* This table defines the port and pins used for each UART
*/
typedef struct {
uint32_t sysctlPeriphGPIO;
uint32_t sysctlPeriphUART;
uint32_t gpioPinURx;
uint32_t gpioPinUTx;
uint32_t gpioPortBase;
uint32_t gpioPinRx;
uint32_t gpioPinTx;
uint32_t uartBase;
} uart_port;
extern const uart_port uart_ports[8];
/*\TIVA UART Configuration Table */
#endif
#uartconf.c
#include "uartconfig.h"
const uart_port uart_ports[8] = {
//UART Port Mappings for TM4C123G LaunchPad
{SYSCTL_PERIPH_GPIOA,
SYSCTL_PERIPH_UART0,
GPIO_PA0_U0RX,
GPIO_PA1_U0TX,
GPIO_PORTA_BASE,
GPIO_PIN_0,
GPIO_PIN_1,
UART0_BASE}, //UART0
{SYSCTL_PERIPH_GPIOB,
SYSCTL_PERIPH_UART1,
GPIO_PB0_U1RX,
GPIO_PB1_U1TX,
GPIO_PORTB_BASE,
GPIO_PIN_0,
GPIO_PIN_1,
UART1_BASE}, //UART1
{SYSCTL_PERIPH_GPIOD,
SYSCTL_PERIPH_UART2,
GPIO_PD6_U2RX,
GPIO_PD7_U2TX,
GPIO_PORTD_BASE,
GPIO_PIN_6,
GPIO_PIN_7,
UART2_BASE}, //UART2
{SYSCTL_PERIPH_GPIOC,
SYSCTL_PERIPH_UART3,
GPIO_PC6_U3RX,
GPIO_PC7_U3TX,
GPIO_PORTC_BASE,
GPIO_PIN_6,
GPIO_PIN_7,
UART3_BASE}, //UART3
{SYSCTL_PERIPH_GPIOC,
SYSCTL_PERIPH_UART4,
GPIO_PC4_U4RX,
GPIO_PC5_U4TX,
GPIO_PORTC_BASE,
GPIO_PIN_4,
GPIO_PIN_5,
UART4_BASE}, //UART4
{SYSCTL_PERIPH_GPIOE,
SYSCTL_PERIPH_UART5,
GPIO_PE4_U5RX,
GPIO_PE5_U5TX,
GPIO_PORTE_BASE,
GPIO_PIN_4,
GPIO_PIN_5,
UART5_BASE}, //UART5
{SYSCTL_PERIPH_GPIOD,
SYSCTL_PERIPH_UART6,
GPIO_PD4_U6RX,
GPIO_PD5_U6TX,
GPIO_PORTD_BASE,
GPIO_PIN_4,
GPIO_PIN_5,
UART6_BASE}, //UART6
{SYSCTL_PERIPH_GPIOE,
SYSCTL_PERIPH_UART7,
GPIO_PE0_U7RX,
GPIO_PE1_U7TX,
GPIO_PORTE_BASE,
GPIO_PIN_0,
GPIO_PIN_1,
UART7_BASE} //UART7
};
void ConfigureUART_base(uint32_t ui32PortNum, uint32_t ui32Baud, uint32_t ui32SrcClock) {
// Check the arguments.
ASSERT((ui32PortNum == 0) || (ui32PortNum == 1) || (ui32PortNum == 2)); // UARTStdioConfig seems to only allow 0,1,2 (not sure what happened to 3-7)
ASSERT((ui32Baud == 9600) || (ui32Baud == 115200)); // TODO: there are more valid baud rates than this
// TODO: what source clock frequencies are valid?
// Set port/pin values based on UART channel
uart_port uport = uart_ports[ui32PortNum];
// Enable the GPIO Peripheral used by the UART.
ROM_SysCtlPeripheralEnable(uport.sysctlPeriphGPIO);
// Enable UART
ROM_SysCtlPeripheralEnable(uport.sysctlPeriphUART);
// Configure GPIO Pins for UART mode.
ROM_GPIOPinConfigure(uport.gpioPinURx);
ROM_GPIOPinConfigure(uport.gpioPinUTx);
ROM_GPIOPinTypeUART(uport.gpioPortBase, uport.gpioPinRx | uport.gpioPinTx);
// Use the internal 16MHz oscillator as the UART clock source.
UARTClockSourceSet(uport.uartBase, UART_CLOCK_PIOSC);
// Initialize the UART for console I/O.
UARTStdioConfig(ui32PortNum, ui32Baud, ui32SrcClock);
}
void var_ConfigureUART (ConfigureUART_args in) {
// Sets the default values for undefined parameters when calling
// ConfigureUART
uint32_t ui32PortNum_out = in.ui32PortNum ? in.ui32PortNum : 0; // Default to 0, Port A
uint32_t ui32Baud_out = in.ui32Baud ? in.ui32Baud : 115200; // Default to 115200, max baud
uint32_t ui32SrcClock_out = in.ui32SrcClock ? in.ui32SrcClock : 16000000; // Default to 16Mhz
return ConfigureUART_base(ui32PortNum_out, ui32Baud_out, ui32SrcClock_out);
}