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
Header¶
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¶
Initialization¶
embsec_gpio_init¶
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¶
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: DirectionEMBSEC_GPIO_INPUT- Configure as inputEMBSEC_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¶
Write to GPIO pin(s).
Parameters:
port: GPIO port ('A' through 'F')pin: Pin maskvalue:truefor high,falsefor 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¶
Read from GPIO pin(s).
Parameters:
port: GPIO port ('A' through 'F')pin: Pin mask
Returns:
trueif any masked pin is highfalseif 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¶
Toggle GPIO pin state(s).
Parameters:
port: GPIO port ('A' through 'F')pin: Pin mask
Example:
LED Control¶
embsec_led_set¶
Control onboard LEDs.
Parameters:
led: LED mask (can combine multiple LEDs)EMBSEC_LED_REDEMBSEC_LED_BLUE-
EMBSEC_LED_GREEN -
on:trueto turn on,falseto 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¶
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¶
Read switch state.
Parameters:
sw: Switch mask (EMBSEC_SW1orEMBSEC_SW2)
Returns:
trueif switch is pressed (active low)falseif 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¶
Wait for switch press with debouncing. Blocks until switch is pressed and debounce time expires.
Parameters:
sw: Switch maskdebounce_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