Skip to content

GPIO API

The GPIO API provides functions for digital input/output operations, including LED and switch control.

Overview

The GPIO module provides:

  • Pin configuration (input/output)
  • Digital read/write operations
  • Built-in LED control (red, blue, green)
  • Switch input with debouncing
  • Pin toggle operations
#include <embsec/gpio.h>

Pin Definitions

LED Pins

#define EMBSEC_LED_RED    0x02  // PF1 - Red LED
#define EMBSEC_LED_BLUE   0x04  // PF2 - Blue LED  
#define EMBSEC_LED_GREEN  0x08  // PF3 - Green LED

Switch Pins

#define EMBSEC_SW1        0x10  // PF4 - Switch 1
#define EMBSEC_SW2        0x01  // PF0 - Switch 2

Initialization

embsec_gpio_init

void embsec_gpio_init(void);

Initialize GPIO for LEDs and switches. This is automatically called by embsec_init().

Configures:

  • Port F for onboard LEDs and switches
  • Pull-up resistors for switches
  • LEDs as outputs (initially off)
  • Switches as inputs

Pin Configuration

embsec_gpio_config

void embsec_gpio_config(char port, uint8_t pin, embsec_gpio_dir_t dir);

Configure a GPIO pin as input or output.

Parameters:

  • port: GPIO port ('A' through 'F')
  • pin: Pin mask (e.g., 0x01 for pin 0, 0x80 for pin 7)
  • dir: Direction
  • EMBSEC_GPIO_INPUT - Configure as input
  • EMBSEC_GPIO_OUTPUT - Configure as output

Example:

// Configure PA5 as output
embsec_gpio_config('A', 0x20, EMBSEC_GPIO_OUTPUT);

// Configure PB0 and PB1 as inputs
embsec_gpio_config('B', 0x03, EMBSEC_GPIO_INPUT);

Pin Operations

embsec_gpio_write

void embsec_gpio_write(char port, uint8_t pin, bool value);

Write to GPIO pin(s).

Parameters:

  • port: GPIO port ('A' through 'F')
  • pin: Pin mask
  • value: true for high, false for low

Example:

// Set PA5 high
embsec_gpio_write('A', 0x20, true);

// Set multiple pins low
embsec_gpio_write('A', 0x0F, false);  // PA0-PA3

embsec_gpio_read

bool embsec_gpio_read(char port, uint8_t pin);

Read from GPIO pin(s).

Parameters:

  • port: GPIO port ('A' through 'F')
  • pin: Pin mask

Returns:

  • true if any masked pin is high
  • false if all masked pins are low

Example:

// Read single pin
if (embsec_gpio_read('A', 0x01)) {
    embsec_printf("PA0 is high\n");
}

// Check multiple pins
if (embsec_gpio_read('B', 0x0F)) {
    embsec_printf("At least one of PB0-PB3 is high\n");
}

embsec_gpio_toggle

void embsec_gpio_toggle(char port, uint8_t pin);

Toggle GPIO pin state(s).

Parameters:

  • port: GPIO port ('A' through 'F')
  • pin: Pin mask

Example:

// Toggle PA5 every second
while (1) {
    embsec_gpio_toggle('A', 0x20);
    embsec_delay_ms(1000);
}

LED Control

embsec_led_set

void embsec_led_set(uint8_t led, bool on);

Control onboard LEDs.

Parameters:

  • led: LED mask (can combine multiple LEDs)
  • EMBSEC_LED_RED
  • EMBSEC_LED_BLUE
  • EMBSEC_LED_GREEN

  • on: true to turn on, false to turn off

Example:

// Turn on red LED
embsec_led_set(EMBSEC_LED_RED, true);

// Turn on multiple LEDs
embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_BLUE, true);

// Turn off all LEDs
embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_BLUE | EMBSEC_LED_GREEN, false);

embsec_led_toggle

void embsec_led_toggle(uint8_t led);

Toggle onboard LED state(s).

Parameters:

  • led: LED mask

Example:

// Blink green LED
while (1) {
    embsec_led_toggle(EMBSEC_LED_GREEN);
    embsec_delay_ms(500);
}

// Alternate between red and blue
while (1) {
    embsec_led_toggle(EMBSEC_LED_RED | EMBSEC_LED_BLUE);
    embsec_delay_ms(250);
}

Switch Input

embsec_switch_read

bool embsec_switch_read(uint8_t sw);

Read switch state.

Parameters:

  • sw: Switch mask (EMBSEC_SW1 or EMBSEC_SW2)

Returns:

  • true if switch is pressed (active low)
  • false if switch is released

Example:

// Check if SW1 is pressed
if (embsec_switch_read(EMBSEC_SW1)) {
    embsec_printf("Switch 1 pressed!\n");
}

// Check both switches
if (embsec_switch_read(EMBSEC_SW1 | EMBSEC_SW2)) {
    embsec_printf("At least one switch pressed\n");
}

embsec_switch_wait

void embsec_switch_wait(uint8_t sw, uint32_t debounce_ms);

Wait for switch press with debouncing. Blocks until switch is pressed and debounce time expires.

Parameters:

  • sw: Switch mask
  • debounce_ms: Debounce time in milliseconds (typically 20-50ms)

Example:

embsec_printf("Press SW1 to continue...\n");
embsec_switch_wait(EMBSEC_SW1, 50);
embsec_printf("Switch pressed!\n");

Common Patterns

LED Status Indicator

typedef enum {
    STATUS_IDLE,
    STATUS_BUSY,
    STATUS_ERROR,
    STATUS_SUCCESS
} status_t;

void set_status_led(status_t status) {
    // Turn off all LEDs first
    embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);

    switch (status) {
        case STATUS_IDLE:
            embsec_led_set(EMBSEC_LED_BLUE, true);
            break;
        case STATUS_BUSY:
            embsec_led_set(EMBSEC_LED_GREEN, true);
            break;
        case STATUS_ERROR:
            embsec_led_set(EMBSEC_LED_RED, true);
            break;
        case STATUS_SUCCESS:
            embsec_led_set(EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, true);
            break;
    }
}

Button Menu

void button_menu(void) {
    while (1) {
        embsec_printf("\nPress SW1 for Option A, SW2 for Option B\n");

        // Wait for button press
        while (1) {
            if (embsec_switch_read(EMBSEC_SW1)) {
                embsec_switch_wait(EMBSEC_SW1, 50);  // Debounce
                embsec_printf("Option A selected\n");
                // Handle option A
                break;
            }

            if (embsec_switch_read(EMBSEC_SW2)) {
                embsec_switch_wait(EMBSEC_SW2, 50);  // Debounce
                embsec_printf("Option B selected\n");
                // Handle option B
                break;
            }

            embsec_delay_ms(10);  // Small delay to reduce CPU usage
        }
    }
}

RGB LED Patterns

void rgb_cycle(void) {
    const struct {
        uint8_t leds;
        uint32_t duration_ms;
    } pattern[] = {
        { EMBSEC_LED_RED,                           500 },
        { EMBSEC_LED_GREEN,                         500 },
        { EMBSEC_LED_BLUE,                          500 },
        { EMBSEC_LED_RED | EMBSEC_LED_GREEN,        500 },  // Yellow
        { EMBSEC_LED_RED | EMBSEC_LED_BLUE,         500 },  // Magenta
        { EMBSEC_LED_GREEN | EMBSEC_LED_BLUE,       500 },  // Cyan
        { EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, 500 },  // White
        { 0,                                        500 },  // Off
    };

    while (1) {
        for (int i = 0; i < sizeof(pattern) / sizeof(pattern[0]); i++) {
            embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);
            embsec_led_set(pattern[i].leds, true);
            embsec_delay_ms(pattern[i].duration_ms);
        }
    }
}

Morse Code

#define DOT_MS  200
#define DASH_MS 600
#define SPACE_MS 200
#define LETTER_SPACE_MS 600

void morse_dot(void) {
    embsec_led_set(EMBSEC_LED_RED, true);
    embsec_delay_ms(DOT_MS);
    embsec_led_set(EMBSEC_LED_RED, false);
    embsec_delay_ms(SPACE_MS);
}

void morse_dash(void) {
    embsec_led_set(EMBSEC_LED_RED, true);
    embsec_delay_ms(DASH_MS);
    embsec_led_set(EMBSEC_LED_RED, false);
    embsec_delay_ms(SPACE_MS);
}

void morse_sos(void) {
    // S
    morse_dot(); morse_dot(); morse_dot();
    embsec_delay_ms(LETTER_SPACE_MS);

    // O
    morse_dash(); morse_dash(); morse_dash();
    embsec_delay_ms(LETTER_SPACE_MS);

    // S
    morse_dot(); morse_dot(); morse_dot();
    embsec_delay_ms(LETTER_SPACE_MS * 2);
}

Interrupt-Driven Button Handler

volatile bool button_pressed = false;

// In main loop
if (button_pressed) {
    button_pressed = false;

    // Debounce check
    embsec_delay_ms(50);
    if (embsec_switch_read(EMBSEC_SW1)) {
        embsec_printf("Button interrupt handled\n");
    }
}

Hardware Notes

Electrical Characteristics

  • Output High: ~3.3V
  • Output Low: ~0V
  • Input Threshold: ~1.65V (VDD/2)
  • Max Current per Pin: 8mA (standard), 18mA (high drive)
  • Max Current per Port: 40mA

Pull Resistors

  • Switches have internal pull-up resistors enabled
  • External pins default to no pull resistors
  • Can enable pull-up/pull-down via TivaWare if needed

Pin Limitations

Some pins have special functions:

  • PF0: Also NMI, requires unlock sequence
  • PA0-PA1: Also UART0 RX/TX
  • PC0-PC3: Also JTAG/SWD

Best Practices

1. Debouncing

Always debounce mechanical switches:

bool read_switch_debounced(uint8_t sw) {
    if (!embsec_switch_read(sw)) {
        return false;
    }

    embsec_delay_ms(20);
    return embsec_switch_read(sw);
}

2. LED Brightness

For dimming effects, use PWM or rapid toggling:

void led_dim(uint8_t led, uint8_t brightness) {
    // brightness: 0-100
    for (int i = 0; i < 100; i++) {
        if (i < brightness) {
            embsec_led_set(led, true);
        } else {
            embsec_led_set(led, false);
        }
        embsec_delay_us(100);
    }
}

3. Power Management

Turn off unused LEDs to save power:

void enter_low_power(void) {
    // Turn off all LEDs
    embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);

    // Configure unused pins as inputs
    // ... additional power-saving code
}

4. Pin State Preservation

Save and restore pin states:

typedef struct {
    char port;
    uint8_t pins;
    bool state;
} gpio_state_t;

void save_gpio_state(gpio_state_t *state, char port, uint8_t pins) {
    state->port = port;
    state->pins = pins;
    state->state = embsec_gpio_read(port, pins);
}

void restore_gpio_state(const gpio_state_t *state) {
    embsec_gpio_write(state->port, state->pins, state->state);
}

Example: Complete GPIO Demo

#include <embsec/embsec.h>
#include <embsec/uart.h>
#include <embsec/gpio.h>

// LED patterns
typedef struct {
    uint8_t pattern;
    uint32_t duration;
} led_sequence_t;

const led_sequence_t startup_sequence[] = {
    { EMBSEC_LED_RED,   200 },
    { EMBSEC_LED_GREEN, 200 },
    { EMBSEC_LED_BLUE,  200 },
    { EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, 500 },
    { 0, 200 }
};

void play_sequence(const led_sequence_t *seq, size_t count) {
    for (size_t i = 0; i < count; i++) {
        embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);
        embsec_led_set(seq[i].pattern, true);
        embsec_delay_ms(seq[i].duration);
    }
    embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);
}

int main(void) {
    embsec_init();

    embsec_printf("\n=== GPIO Demo ===\n");
    embsec_printf("SW1: Change LED color\n");
    embsec_printf("SW2: Toggle blink mode\n\n");

    // Startup sequence
    play_sequence(startup_sequence, 
                  sizeof(startup_sequence) / sizeof(startup_sequence[0]));

    // State variables
    uint8_t current_led = EMBSEC_LED_RED;
    bool blink_mode = false;
    uint32_t last_blink = embsec_get_tick_ms();
    bool led_state = false;

    // Main loop
    while (1) {
        // Handle SW1 - change color
        if (embsec_switch_read(EMBSEC_SW1)) {
            embsec_switch_wait(EMBSEC_SW1, 50);

            // Cycle through colors
            if (current_led == EMBSEC_LED_RED) {
                current_led = EMBSEC_LED_GREEN;
                embsec_printf("Changed to GREEN\n");
            } else if (current_led == EMBSEC_LED_GREEN) {
                current_led = EMBSEC_LED_BLUE;
                embsec_printf("Changed to BLUE\n");
            } else {
                current_led = EMBSEC_LED_RED;
                embsec_printf("Changed to RED\n");
            }

            // Update LED immediately
            if (!blink_mode) {
                embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);
                embsec_led_set(current_led, true);
            }
        }

        // Handle SW2 - toggle blink
        if (embsec_switch_read(EMBSEC_SW2)) {
            embsec_switch_wait(EMBSEC_SW2, 50);

            blink_mode = !blink_mode;
            embsec_printf("Blink mode: %s\n", blink_mode ? "ON" : "OFF");

            if (!blink_mode) {
                // Solid on when blink disabled
                embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);
                embsec_led_set(current_led, true);
            }
        }

        // Handle blinking
        if (blink_mode) {
            if (embsec_get_tick_ms() - last_blink >= 250) {
                last_blink = embsec_get_tick_ms();
                led_state = !led_state;

                embsec_led_set(EMBSEC_LED_RED | EMBSEC_LED_GREEN | EMBSEC_LED_BLUE, false);
                if (led_state) {
                    embsec_led_set(current_led, true);
                }
            }
        }

        // Small delay to reduce CPU usage
        embsec_delay_ms(10);
    }
}

This example demonstrates:

  • LED control and patterns
  • Switch input with debouncing
  • State management
  • Non-blocking blink implementation
  • User interaction feedback