Introduction to TivaWare — Tiva C
- Eslam El Hefny
- Tutorials, Tiva c
- April 2, 2025
Overview
TivaWare is Texas Instruments’ official C-language peripheral driver library for the Tiva C Series microcontrollers. It abstracts low-level hardware register manipulation into clean, documented C functions that accelerate development while remaining close to the metal. Understanding TivaWare’s structure is essential before writing any peripheral code on the TM4C123.
Beginner Level — What & Why
What is TivaWare?
Imagine you want to turn on an LED. At the hardware level you must write specific bit patterns to specific memory addresses — that is tedious and error-prone. TivaWare is a pre-written collection of C functions that do this for you. Instead of writing raw hexadecimal values, you call GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1) and the library handles the register details.
Real-World Analogy
TivaWare is like the electrical wiring standards in a building. The standard does not change the physics of electricity, but it gives every electrician a common, safe way to connect things without reinventing the wheel each time.
What Problem Does It Solve?
- Portability: Switching between TM4C123 and TM4C129 requires only small changes in the application, not a complete rewrite.
- Speed of development: Ready-made, tested functions prevent common mistakes.
- Documentation: Each function has clear parameter descriptions and return values.
Key Terms
| Term | Meaning |
|---|---|
| DriverLib | Software driver library — the C source functions |
| ROM functions | Same drivers pre-burned into the MCU’s ROM; callable without flash space |
driverlib.lib |
Pre-compiled static library linked into your CCS project |
| SW-TM4C | TI’s product code for the TivaWare download |
inc/ |
Folder with hardware register definitions (hw_memmap.h, hw_types.h) |
Intermediate Level — How It Works
SDK Folder Structure
{{ $image := resources.Get “image.png” }}
After installing TivaWare (default C:\ti\TivaWare_C_Series-2.2.0.295), the layout is:
TivaWare_C_Series-2.2.0.295/
├── driverlib/ ← peripheral driver source (.c) and headers (.h)
│ ├── gpio.c / gpio.h
│ ├── uart.c / uart.h
│ ├── sysctl.c / sysctl.h
│ └── ccs/Debug/driverlib.lib ← pre-built library for CCS
├── inc/ ← hardware register address definitions
│ ├── hw_memmap.h ← base addresses (GPIO_PORTF_BASE, UART0_BASE …)
│ ├── hw_types.h ← HWREG macro, bool type
│ ├── hw_gpio.h ← GPIO register offsets
│ └── hw_uart.h ← UART register offsets
├── utils/ ← utility modules (uartstdio, ustdlib)
├── examples/ ← board-level example projects
├── boards/ ← board-specific BSP
└── usblib/ ← USB protocol library
DriverLib vs ROM Functions
TivaWare functions can run from two locations:
| Mode | Location | Flash Used | Invocation |
|---|---|---|---|
| DriverLib (.lib) | Project flash | Yes (~8 KB per module) | GPIOPinWrite(...) |
| ROM functions | MCU internal ROM (256 KB) | No | ROM_GPIOPinWrite(...) |
ROM functions are identical in behavior but save flash. Enable them by defining TARGET_IS_TM4C123_RB1 in your project preprocessor defines, then use the ROM_ prefix.
// Use ROM function — no flash consumed for this call
ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL |
SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
Key Header Include Order
#include <stdint.h> // uint32_t, uint8_t types
#include <stdbool.h> // true / false
#include "inc/hw_memmap.h" // base addresses like GPIO_PORTF_BASE
#include "inc/hw_types.h" // HWREG() macro
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
Always include <stdint.h> and <stdbool.h> before any TivaWare header.
Linking driverlib.lib in CCS
- Right-click project → Properties → Build → ARM Linker → File Search Path
- Add:
${TIVAWARE_ROOT}/driverlib/ccs/Debug/driverlib.lib - Add include path:
${TIVAWARE_ROOT}in ARM Compiler → Include Options
Define TIVAWARE_ROOT as a CCS variable pointing to your installation directory.
Advanced Level — Deep Dive
The HWREG Macro
All TivaWare functions ultimately use HWREG to read/write peripheral registers:
// From inc/hw_types.h
#define HWREG(x) (*((volatile uint32_t *)(x)))
// Example: Read PORTF data register directly
uint32_t val = HWREG(GPIO_PORTF_BASE + GPIO_O_DATA + (GPIO_PIN_1 << 2));
The GPIO_O_DATA + (pin << 2) is the GPIO “bit-banding trick” — more on this in the GPIO chapter.
ROM Table Location
The ROM function table lives at address 0x01000010 on TM4C123. The device automatically routes ROM_GPIOPinWrite to the correct offset in this table. You can verify this by inspecting rom.h:
// From driverlib/rom.h (simplified)
#define ROM_APITABLE ((uint32_t *)0x01000010)
#define ROM_GPIOAPITABLE ((uint32_t *)(ROM_APITABLE[1]))
#define ROM_GPIOPinWrite ((void (*)(uint32_t, uint8_t, uint8_t)) \
ROM_GPIOAPITABLE[5])
SW-TM4C Download
Download TivaWare from:
https://www.ti.com/tool/SW-TM4C
Use version 2.2.0.295 or newer. The installer sets up all examples and pre-built libraries automatically.
Preprocessor Defines for ROM
Add to CCS project properties → ARM Compiler → Predefined Symbols:
TARGET_IS_TM4C123_RB1
PART_TM4C123GH6PM
These enable ROM function mappings and pull in the correct device-specific definitions from inc/hw_memmap.h.
Gotchas
- Never include both
rom.handrom_map.hwithout theTARGET_IS_*define — you will get linker errors. - The pre-built
driverlib.libis compiled with-O2. If you need to debug inside DriverLib, recompile from source. - On Linux, the TivaWare installer is a
.runscript; on macOS it is unsupported — use a Linux VM or WSL.
Step-by-Step Example
The following project verifies TivaWare is correctly linked by reading the device ID from the System Control block.
/*
* tivaware_verify.c
* Reads the TM4C123 Device ID and blinks the green LED
* Board : TM4C123GXL EK LaunchPad
* SDK : TivaWare_C_Series-2.2.x
* IDE : Code Composer Studio
*/
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h" // GPIO_PORTF_BASE, SYSCTL_BASE ...
#include "inc/hw_types.h" // HWREG macro
#include "inc/hw_sysctl.h" // SYSCTL_DID0 offset
#include "driverlib/sysctl.h" // SysCtlClockSet, SysCtlPeripheralEnable
#include "driverlib/gpio.h" // GPIOPinTypeGPIOOutput, GPIOPinWrite
/* Green LED is on Port F, Pin 3 on TM4C123GXL */
#define GREEN_LED GPIO_PIN_3
int main(void)
{
uint32_t ui32DevID;
/* Step 1: Set system clock to 80 MHz using PLL and 16 MHz crystal */
SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL |
SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
/* Step 2: Enable the GPIO Port F clock */
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
/* Step 3: Wait until Port F is ready */
while (!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF));
/* Step 4: Configure PF3 (Green LED) as a digital output */
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GREEN_LED);
/* Step 5: Read Device ID register (SYSCTL base + DID0 offset)
* DID0 holds the major/minor silicon revision of the TM4C123 */
ui32DevID = HWREG(SYSCTL_BASE + SYSCTL_O_DID0);
/* Step 6: Blink fast (valid TivaWare linked) or slow (error) */
while (1)
{
GPIOPinWrite(GPIO_PORTF_BASE, GREEN_LED, GREEN_LED); // ON
/* SysCtlDelay: each call = 3 CPU cycles; 80MHz/3 ≈ 1 second */
SysCtlDelay(SysCtlClockGet() / 3 / 4); // 250 ms
GPIOPinWrite(GPIO_PORTF_BASE, GREEN_LED, 0); // OFF
SysCtlDelay(SysCtlClockGet() / 3 / 4); // 250 ms
/* Suppress unused variable warning in release builds */
(void)ui32DevID;
}
}
Expected result: Green LED blinks at ~2 Hz. If the linker fails to find driverlib.lib, you will see an “undefined symbol” error before even reaching the compile stage.
Summary
| Key Point | Details |
|---|---|
| SDK location | C:\ti\TivaWare_C_Series-2.2.0.295 |
| Main library | driverlib/ccs/Debug/driverlib.lib |
| Register headers | inc/hw_memmap.h, inc/hw_types.h |
| ROM functions | Prefix ROM_, define TARGET_IS_TM4C123_RB1 |
| HWREG macro | Direct 32-bit register read/write |
| Download URL | https://www.ti.com/tool/SW-TM4C |
| IDE | Code Composer Studio 12.x |