16. GPIO
16.1. Overview
The GPIO example shows how to change GPIO output pin level and use GPIO input pin trigger interrupt.
16.2. Board Setting
No special settings are required
16.3. Known Issue
When GPIO is used as the key input pin detection, the input level jitter will cause GPIO to detect the change of input level multiple times due to the mechanical jitter of the key.
16.4. Running the example
chips that support both-edge trigger mode, the project are configured in both-edge trigger mode,so every time a button is pressed and released, the LED state will be toggle, and the LED toggle logs will be printed twice.
When the example runs successfully, the LED will flash 5 times, then press GPIO button (please check Button section of specific board) will toggle the LED status, and the following message is displayed in the terminal:
toggling led 5 times in total
toggling led 1/5 times
toggling led 2/5 times
toggling led 3/5 times
toggling led 4/5 times
toggling led 5/5 times
input interrupt
user led will be switched on off based on user switch
toggle led pin output
toggle led pin output
16.5. API Usage
The I/O subsystem comprises General-purpose IO Control Module (IOC), GPIO Controller, Fast GPIO Controller, and GPIO Manager
For detailed API specifications, refer to hpm_gpio_drv.h and relevant user manuals
For Fast GPIO Controller and GPIO Manager usage examples, see gpiom
16.5.1. IO Initialization
Primarily initializes the General-purpose IO Control Module (IOC), including configuration of:
IO electrical characteristics via PAD_CTL
Peripheral functionality via FUNC_CTL
Power Management Domain IO Controller (PIOC):
Controls PY ports with equivalent functionality to general IOC
Battery Backup Domain IO Controller (BIOC):
Controls PZ ports with equivalent functionality to general IOC
16.5.1.1. Configuring IO Properties via PAD_CTL
PAD_CTL configures electrical characteristics including:
Open-drain selection
Drive strength
Pull-up/pull-down configuration
Refer to hpm_ioc_regs.h for register definitions
Example configuration:
/* Configure PA09 with pull-up enabled and Schmitt trigger enabled */ HPM_IOC->PAD[IOC_PAD_PA09].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_HYS_SET(1);
16.5.1.2. Peripheral Function Configuration via FUNC_CTL
FUNC_CTL controls three key functions (definitions in hpm_iomux.h):
Loopback functionality (LOOP_BACK)
Analog mode (ANALOG)
Peripheral function mapping (ALT_SELECT)
Key applications:
Loopback: Essential for clock-dependent peripherals (e.g., SPI SCLK, I2C SCL)
Analog mode: Used for analog signal processing (ADC, MIPI interfaces)
ALT_SELECT: Determines peripheral function mapping (GPIO, I2C, SPI, etc.)
Important Notes:
For GPIOY pins:
Configure as GPIO in IOC’s FUNC_CTL
Example: Configure PY06 as UART1_RXD
HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_SOC_PY_06; HPM_IOC->PAD[IOC_PAD_PY06].FUNC_CTL = IOC_PY06_FUNC_CTL_UART1_RXD;
For GPIOZ pins:
Configure as GPIO in IOC’s FUNC_CTL
Example: Configure PZ02 as GPIO
HPM_IOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_GPIO_Z_02; HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = BIOC_PZ02_FUNC_CTL_SOC_PZ_02;
SPI Configuration Example:
/* Configure SPI1 pins with SCLK loopback */ HPM_IOC->PAD[IOC_PAD_PA26].FUNC_CTL = IOC_PA26_FUNC_CTL_SPI1_CS_0; HPM_IOC->PAD[IOC_PAD_PA27].FUNC_CTL = IOC_PA27_FUNC_CTL_SPI1_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_SET(1); HPM_IOC->PAD[IOC_PAD_PA28].FUNC_CTL = IOC_PA28_FUNC_CTL_SPI1_MISO; HPM_IOC->PAD[IOC_PAD_PA29].FUNC_CTL = IOC_PA29_FUNC_CTL_SPI1_MOSI;
16.5.2. GPIO Controller
The GPIO controller is primarily used to control the input/output modes of IOs, read input states, set output states, and configure interrupt trigger modes.
The default controller for IOs is GPIO. To use FGPIO, refer to the gpiom example via GPIO Manager.
The hpm_ioc_regs.h header file defines PAD register groups for each IO (e.g., PA26 is defined as IOC_PAD_PA26).
The hpm_gpio_drv.h header file provides GPIO_GET_PORT_INDEX and GPIO_GET_PIN_INDEX macros to determine the port number and pin index for each IO.
These macros allow quick identification of port/pin configuration. For example,
IOC_PAD_PA26has port number GPIO_GET_PORT_INDEX(IOC_PAD_PA26) and pin index GPIO_GET_PIN_INDEX(IOC_PAD_PA26).
16.5.2.1. Configuring IO Modes
Two methods are provided for setting output mode: with or without initial level.
API with initial level:
void gpio_set_pin_output_with_initial(GPIO_Type *ptr, uint32_t port, uint8_t pin, uint8_t initial);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DO_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
initial
uint8_t
Initial level (0: low, 1: high)
Example: Configure PA26 as output with initial high level:
gpio_set_pin_output_with_initial(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26), 1);
API without initial level:
void gpio_set_pin_output(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DO_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Example: Configure PA26 as output:
gpio_set_pin_output(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26));
Input Mode Configuration API:
void gpio_set_pin_input(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DI_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Example: Configure PA26 as input:
gpio_set_pin_input(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26));
16.5.2.2. IO Level Control
Output APIs support three operations: set single pin level, toggle pin level, and set port level.
Prerequisite: IO must be in output mode
Set Single Pin Level:
void gpio_write_pin(GPIO_Type *ptr, uint32_t port, uint8_t pin, uint8_t high);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DO_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
high
uint8_t
Output level (0: low, 1: high)
Example: Set PA26 to high:
gpio_write_pin(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26), 1);
Toggle Pin Level:
void gpio_toggle_pin(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DO_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Example: Toggle PA26:
gpio_toggle_pin(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26));
Set Port Level:
void gpio_write_port(GPIO_Type *ptr, uint32_t port, uint32_t value);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DO_GPIOA)
value
uint32_t
Port level (0x00000000-0xFFFFFFFF)
Example: Set all PA pins to high:
gpio_write_port(HPM_GPIO, GPIO_DO_GPIOA, 0xFFFFFFFF);
Clear Specified Pins to Low:
void gpio_set_port_low_with_mask(GPIO_Type *ptr, uint32_t port, uint32_t mask);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DO_GPIOA)
mask
uint32_t
Bitmask for pins to clear (1=clear to low)
Example: Clear PA01 and PA02 to low:
uint32_t mask = (1 << GPIO_GET_PIN_INDEX(IOC_PAD_PA01)) | (1 << GPIO_GET_PIN_INDEX(IOC_PAD_PA02)); gpio_set_port_low_with_mask(HPM_GPIO, GPIO_DO_GPIOA, mask);
16.5.2.3. Input State Reading
Note: Works even when IO is configured for peripheral function (e.g., SPI MISO)
Read Single Pin:
uint8_t gpio_read_pin(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DI_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Example: Read PA26:
uint8_t level = gpio_read_pin(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26));
Read Entire Port:
uint32_t gpio_read_port(GPIO_Type *ptr, uint32_t port);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g., GPIO_DI_GPIOA)
Example: Read PA port:
uint32_t level = gpio_read_port(HPM_GPIO, GPIO_DI_GPIOA);
16.5.2.4. GPIO Interrupts
FGPIO does not support interrupts
Interrupt Related Enumerations:
Interrupt Trigger Modes:
typedef enum gpio_interrupt_trigger { /* Level-triggered high (interrupt persists during high state) */ gpio_interrupt_trigger_level_high = 0, /* Level-triggered low (interrupt persists during low state) */ gpio_interrupt_trigger_level_low, /* Rising-edge triggered */ gpio_interrupt_trigger_edge_rising, /* Falling-edge triggered */ gpio_interrupt_trigger_edge_falling, /* Dual-edge triggered */ #if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1) gpio_interrupt_trigger_edge_both, #endif } gpio_interrupt_trigger_t;
Note:
Dual-edge triggering is not supported by all SOCs. Check hpm_soc_feature.h for GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT macro definition
Before using interrupts: 1. Configure IO in input mode 2. Set interrupt trigger mode
Interrupt Configuration API:
void gpio_config_pin_interrupt(GPIO_Type *ptr, uint32_t gpio_index, uint8_t pin_index, gpio_interrupt_trigger_t trigger);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
gpio_index
uint32_t
GPIO port number (e.g. GPIO_DI_GPIOA)
pin_index
uint8_t
GPIO pin index (0-31)
trigger
gpio_interrupt_trigger_t
Trigger mode from gpio_interrupt_trigger_t enum
Example: Configure PA26 as input with rising-edge trigger
gpio_config_pin_interrupt(HPM_GPIO, GPIO_GET_PORT_INDEX(IOC_PAD_PA26), GPIO_GET_PIN_INDEX(IOC_PAD_PA26), gpio_interrupt_trigger_edge_rising);
Interrupt Enable API:
void gpio_enable_pin_interrupt(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g. GPIO_DI_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Interrupt Disable API:
void gpio_disable_pin_interrupt(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g. GPIO_DI_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Interrupt Clear API (Call in ISR):
bool gpio_check_clear_interrupt_flag(GPIO_Type *ptr, uint32_t port, uint8_t pin);
Parameter Description:
Parameter
Type
Description
ptr
GPIO_Type *
Base address of GPIO controller
port
uint32_t
GPIO port number (e.g. GPIO_DI_GPIOA)
pin
uint8_t
GPIO pin index (0-31)
Return Value:
true: Interrupt flag cleared successfully
false: No interrupt flag to clear