GPS Device
Loading...
Searching...
No Matches
GPIO Public API

Public functions to interact with the GPIO peripheral. More...

Collaboration diagram for GPIO Public API:

Functions

void gpio_init (GPIO_CFG_ts *gpio_cfg)
 Initializes a GPIO pin according to the given configuration.
void gpio_deinit (GPIO_REGDEF_ts const *gpio_port)
 Deinitializes a GPIO port by resetting its registers to reset values.
void gpio_write (GPIO_REGDEF_ts *gpio_port, uint8_t gpio_pin, PIN_STATUS_te pin_status)
 Drives a GPIO output pin high or low.
PIN_STATUS_te gpio_read (GPIO_REGDEF_ts const *gpio_port, uint8_t gpio_pin)
 Reads the current logic level of a GPIO input pin.
void gpio_clear_interrupt (EXTI_LINES_te exti_line)
 Clears the EXTI pending flag for the given interrupt line.
void gpio_get_name (GPIO_REGDEF_ts const *gpio_port, char *name)
 Returns the name string of a GPIO port (e.g. "GPIOA").

Detailed Description

Public functions to interact with the GPIO peripheral.

Function Documentation

◆ gpio_init()

void gpio_init ( GPIO_CFG_ts * gpio_cfg)

Initializes a GPIO pin according to the given configuration.

Enables the peripheral clock for the port, then configures output type, speed, pull mode, alternate function, and pin mode. For interrupt mode, also configures SYSCFG EXTICR, EXTI IMR, RTSR/FTSR, and enables the corresponding NVIC interrupt line.

Parameters
[in]gpio_cfgPointer to the GPIO configuration structure.
See also
gpio_init

Definition at line 29 of file stm32f401re_gpio.c.

29 {
30 // Enable the clock for the GPIO peripheral
31 gpio_set_pclk(gpio_cfg->port, ENABLE);
32
33 // Configure GPIO output type
34 gpio_cfg->port->GPIO_OTYPER &= ~(0b1 << gpio_cfg->pin);
35 gpio_cfg->port->GPIO_OTYPER |= gpio_cfg->output_type << gpio_cfg->pin;
36
37 // Configure GPIO speed
38 gpio_cfg->port->GPIO_OSPEEDR &= ~(0b11 << gpio_cfg->pin * 2);
39 gpio_cfg->port->GPIO_OSPEEDR |= gpio_cfg->output_speed << gpio_cfg->pin * 2;
40
41 // Configure GPIO pull-up pull-down
42 gpio_cfg->port->GPIO_PUPDR &= ~(0b11 << gpio_cfg->pin * 2);
43 gpio_cfg->port->GPIO_PUPDR |= gpio_cfg->pull_mode << gpio_cfg->pin * 2;
44
45 // Configure GPIO alternate function (2 bits per pin in AFR[0] for pins 0-7, AFR[1] for pins 8-15)
46 uint32_t afr_index = gpio_cfg->pin >> 3; // pin / 8 selects AFR[0] or AFR[1]
47 uint32_t afr_shift = (gpio_cfg->pin & 0x7) * 4; // (pin % 8) * 4 gives the bit offset
48
49 gpio_cfg->port->GPIO_AFR[afr_index] &= ~(0xFu << afr_shift);
50 gpio_cfg->port->GPIO_AFR[afr_index] |= ((uint32_t)gpio_cfg->alternate_function << afr_shift);
51
52 // Configure GPIO mode
53 if(gpio_cfg->mode != GPIO_MODE_INTERRUPT) {
54 gpio_cfg->port->GPIO_MODER &= ~(0b11 << gpio_cfg->pin * 2);
55 gpio_cfg->port->GPIO_MODER |= gpio_cfg->mode << gpio_cfg->pin * 2;
56 }
57 else {
58 // Enable the peripheral clock for SYSCFG
59 RCC->RCC_APB2ENR |= (0b1 << 14);
60
61 // Route the GPIO pin to the EXTI line via SYSCFG_EXTICRx
62 if(gpio_cfg->pin < 4) {
63 SYSCFG->SYSCFG_EXTICR1 &= ~(0b1111 << gpio_cfg->pin * 4);
64 SYSCFG->SYSCFG_EXTICR1 |= (get_syscfg_code(gpio_cfg->port)) << gpio_cfg->pin * 4;
65 }
66 else if(gpio_cfg->pin < 8) {
67 SYSCFG->SYSCFG_EXTICR2 &= ~(0b1111 << (gpio_cfg->pin - 4) * 4);
68 SYSCFG->SYSCFG_EXTICR2 |= (get_syscfg_code(gpio_cfg->port)) << (gpio_cfg->pin - 4) * 4;
69 }
70 else if(gpio_cfg->pin < 12) {
71 SYSCFG->SYSCFG_EXTICR3 &= ~(0b1111 << (gpio_cfg->pin - 8) * 4);
72 SYSCFG->SYSCFG_EXTICR3 |= (get_syscfg_code(gpio_cfg->port)) << (gpio_cfg->pin - 8) * 4;
73 }
74 else {
75 SYSCFG->SYSCFG_EXTICR4 &= ~(0b1111 << (gpio_cfg->pin - 12) * 4);
76 SYSCFG->SYSCFG_EXTICR4 |= (get_syscfg_code(gpio_cfg->port)) << (gpio_cfg->pin - 12) * 4;
77 }
78
79 // Unmask the EXTI line for this pin
80 EXTI->EXTI_IMR |= 0b1 << gpio_cfg->pin;
81
82 // Configure edge trigger
83 switch(gpio_cfg->interrupt_trigger) {
85 EXTI->EXTI_RTSR |= 0b1 << gpio_cfg->pin;
86 break;
88 EXTI->EXTI_FTSR |= 0b1 << gpio_cfg->pin;
89 break;
91 EXTI->EXTI_RTSR |= 0b1 << gpio_cfg->pin;
92 EXTI->EXTI_FTSR |= 0b1 << gpio_cfg->pin;
93 break;
94 }
95
96 // Enable the corresponding NVIC interrupt line
97 uint8_t exti_position = get_exti_position(gpio_cfg);
98 nvic_set_interrupt(exti_position, ENABLE);
99 }
100}
@ ENABLE
Definition common.h:100
void nvic_set_interrupt(IRQn_te interrupt_line, EN_STATUS_te en_status)
Enables or disables an interrupt line in the NVIC.
static PORT_CODES_ts get_syscfg_code(GPIO_REGDEF_ts const *port)
Returns the SYSCFG port code for a GPIO port instance.
static uint8_t get_exti_position(GPIO_CFG_ts const *gpio_cfg)
Returns the IRQ number for the EXTI line corresponding to a GPIO pin.
static void gpio_set_pclk(GPIO_REGDEF_ts const *gpio_port, EN_STATUS_te en_status)
Enables or disables the peripheral clock for a GPIO port.
@ GPIO_INTERRUPT_TRIGGER_RE
@ GPIO_INTERRUPT_TRIGGER_RFE
@ GPIO_INTERRUPT_TRIGGER_FE
@ GPIO_MODE_INTERRUPT
#define SYSCFG
#define RCC
#define EXTI
GPIO_REGDEF_ts * port
GPIO_PULL_MODE_te pull_mode
GPIO_ALTERNATE_FUNCTION_te alternate_function
GPIO_INTERRUPT_TRIGGER_te interrupt_trigger
GPIO_OUTPUT_TYPE_te output_type
GPIO_PIN_te pin
GPIO_OUTPUT_SPEED_te output_speed
GPIO_MODE_te mode
uint32_t volatile GPIO_PUPDR
Definition stm32f401re.h:99
uint32_t volatile GPIO_OTYPER
Definition stm32f401re.h:97
uint32_t volatile GPIO_AFR[2]
uint32_t volatile GPIO_MODER
Definition stm32f401re.h:96
uint32_t volatile GPIO_OSPEEDR
Definition stm32f401re.h:98
Here is the call graph for this function:
Here is the caller graph for this function:

◆ gpio_deinit()

void gpio_deinit ( GPIO_REGDEF_ts const * gpio_port)

Deinitializes a GPIO port by resetting its registers to reset values.

Triggers an RCC peripheral reset for the given port and then disables its peripheral clock.

Parameters
[in]gpio_portPointer to the GPIO port instance to deinitialize.
See also
gpio_deinit

Definition at line 103 of file stm32f401re_gpio.c.

103 {
104 if(gpio_port == GPIOA) {
106 }
107 else if(gpio_port == GPIOB) {
109 }
110 else if(gpio_port == GPIOC) {
112 }
113 else if(gpio_port == GPIOD) {
115 }
116 else if(gpio_port == GPIOE) {
118 }
119 else if(gpio_port == GPIOH) {
121 }
122
123 gpio_set_pclk(gpio_port, DISABLE);
124}
@ DISABLE
Definition common.h:97
void rcc_reset_periph_ahb1(RCC_AHB1RSTR_te periph_position)
Resets an AHB1 peripheral via RCC_AHB1RSTR.
#define GPIOC
#define GPIOB
#define GPIOD
#define GPIOA
#define GPIOH
#define GPIOE
@ RCC_AHB1RSTR_GPIOHRST
@ RCC_AHB1RSTR_GPIODRST
@ RCC_AHB1RSTR_GPIOBRST
@ RCC_AHB1RSTR_GPIOARST
@ RCC_AHB1RSTR_GPIOCRST
@ RCC_AHB1RSTR_GPIOERST
Here is the call graph for this function:

◆ gpio_write()

void gpio_write ( GPIO_REGDEF_ts * gpio_port,
uint8_t gpio_pin,
PIN_STATUS_te pin_status )

Drives a GPIO output pin high or low.

Parameters
[in]gpio_portPointer to the GPIO port instance.
[in]gpio_pinPin number to write (0–15).
[in]pin_statusHIGH to drive the pin high, LOW to drive it low.
See also
gpio_write

Definition at line 127 of file stm32f401re_gpio.c.

127 {
128 switch(pin_status) {
129 case HIGH:
130 gpio_port->GPIO_ODR |= (0x1 << gpio_pin);
131 break;
132 case LOW:
133 gpio_port->GPIO_ODR &= ~(0x1 << gpio_pin);
134 break;
135 }
136}
@ HIGH
Definition common.h:89
@ LOW
Definition common.h:86
uint32_t volatile GPIO_ODR
Here is the caller graph for this function:

◆ gpio_read()

PIN_STATUS_te gpio_read ( GPIO_REGDEF_ts const * gpio_port,
uint8_t gpio_pin )

Reads the current logic level of a GPIO input pin.

Parameters
[in]gpio_portPointer to the GPIO port instance.
[in]gpio_pinPin number to read (0–15).
Returns
HIGH if the pin reads logic high, LOW if it reads logic low.
See also
gpio_read

Definition at line 139 of file stm32f401re_gpio.c.

139 {
140 PIN_STATUS_te status = (gpio_port->GPIO_IDR >> gpio_pin) & 0x1;
141 return status;
142}
PIN_STATUS_te
Represents the logical level of a GPIO pin.
Definition common.h:84
Here is the caller graph for this function:

◆ gpio_clear_interrupt()

void gpio_clear_interrupt ( EXTI_LINES_te exti_line)

Clears the EXTI pending flag for the given interrupt line.

Must be called at the end of an EXTI interrupt handler to acknowledge the interrupt and prevent immediate re-entry. Writes 1 to the EXTI_PR bit for exti_line (write-1-to-clear).

Parameters
[in]exti_lineThe EXTI line number corresponding to the GPIO pin.
See also
gpio_clear_interrupt

Definition at line 145 of file stm32f401re_gpio.c.

145 {
146 EXTI->EXTI_PR = 0x1 << exti_line;
147}

◆ gpio_get_name()

void gpio_get_name ( GPIO_REGDEF_ts const * gpio_port,
char * name )

Returns the name string of a GPIO port (e.g. "GPIOA").

Writes a null-terminated string of the form "GPIOx" into name. The caller must ensure name points to a buffer of at least GPIO_NAME_LEN + 1 bytes.

Parameters
[in]gpio_portPointer to the GPIO port instance.
[out]namePointer to the destination buffer.

Returns the name string of a GPIO port (e.g. "GPIOA").

See also
gpio_get_name

Definition at line 150 of file stm32f401re_gpio.c.

150 {
151 const char gpio[] = "GPIO";
152 uint8_t gpio_len = get_str_len(gpio);
153 uint8_t pos_counter = 0;
154
155 while(pos_counter < gpio_len) {
156 name[pos_counter] = gpio[pos_counter];
157 pos_counter++;
158 }
159
160 if(gpio_port == GPIOA) name[pos_counter] = 'A';
161 else if(gpio_port == GPIOB) name[pos_counter] = 'B';
162 else if(gpio_port == GPIOC) name[pos_counter] = 'C';
163 else if(gpio_port == GPIOD) name[pos_counter] = 'D';
164 else if(gpio_port == GPIOE) name[pos_counter] = 'E';
165 else if(gpio_port == GPIOH) name[pos_counter] = 'H';
166 pos_counter++;
167
168 name[pos_counter] = '\0';
169}
uint32_t get_str_len(char const *str)
Returns the length of a string, excluding the null terminator.
Definition common.c:22
Here is the call graph for this function: