1 /**
2 ******************************************************************************
3 * @file stm32wb0x_hal_gpio.c
4 * @author MCD Application Team
5 * @brief GPIO HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the General Purpose Input/Output (GPIO) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 ******************************************************************************
11 * @attention
12 *
13 * Copyright (c) 2024 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software is licensed under terms that can be found in the LICENSE file
17 * in the root directory of this software component.
18 * If no LICENSE file comes with this software, it is provided AS-IS.
19 *
20 ******************************************************************************
21 @verbatim
22 ==============================================================================
23 ##### GPIO Peripheral features #####
24 ==============================================================================
25 [..]
26 (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
27 configured by software in several modes:
28 (++) Input mode
29 (++) Output mode
30 (++) Alternate function mode
31 (++) External interrupt/event lines
32
33 (+) Open-drain and analog features are not available on all IO ports, refer to
34 reference manual for available pins.
35
36 (+) During and just after reset, the alternate functions and external interrupt
37 lines are not active and the I/O ports are configured in input pull-up mode.
38
39 (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
40 activated or not.
41
42 (+) In Output or Alternate mode, each IO can be configured on push-pull type and the
43 IO speed can be selected depending on the VDD value.
44
45 (+) The microcontroller IO pins are connected to onboard peripherals/modules through a
46 multiplexer that allows only one peripheral alternate function (AF) connected
47 to an IO pin at a time. In this way, there can be no conflict between peripherals
48 sharing the same IO pin.
49
50 (+) All ports have external interrupt/event capability. To use external interrupt
51 lines, the port must be configured in input mode. All available GPIO pins are
52 connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
53
54 (+) The external interrupt/event controller consists of up to 28 edge detectors
55 (16 lines are connected to GPIO) for generating event/interrupt requests (each
56 input line can be independently configured to select the type (interrupt or event)
57 and the corresponding trigger event (rising or falling or both). Each line can
58 also be masked independently.
59
60 ##### How to use this driver #####
61 ==============================================================================
62 [..]
63 (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
64
65 (#) Modify the control of the product's pull-up/-down of the IO ports from PWR registers (which is
66 the default state) using either LL_PWR_EnableGPIOPullUp or LL_PWR_EnableGPIOPullDown APIs depending
67 on the requested pull mode. This will allow to switch the control to the GPIO register.
68
69 (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
70 (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
71 (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
72 structure.
73 (++) In case of Output or alternate function mode selection: the speed is
74 configured through "Speed" member from GPIO_InitTypeDef structure.
75 (++) In alternate mode is selection, the alternate function connected to the IO
76 is configured through "Alternate" member from GPIO_InitTypeDef structure.
77 (++) Analog mode is required when a pin is to be used as ADC channel
78 or DAC output.
79 (++) In case of external interrupt/event selection the "Mode" member from
80 GPIO_InitTypeDef structure select the type (interrupt or event) and
81 the corresponding trigger event (rising or falling or both).
82
83 (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
84 mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
85 HAL_NVIC_EnableIRQ().
86
87 (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
88
89 (#) To set/reset the level of a pin configured in output mode use
90 HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
91
92 (#) To set the level of several pins and reset level of several other pins in
93 same cycle, use HAL_GPIO_WriteMultipleStatePin().
94
95 (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
96
97 (#) During and just after reset, the alternate functions are not
98 active and the GPIO pins are configured in input pull-up mode (except JTAG
99 pins).
100
101 (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
102 (PB12 and PB13, respectively) when the LSE oscillator is off. The LSE has
103 priority over the GPIO function.
104
105 (#) The HSE oscillator pins OSC_IN/OSC_OUT are dedicated oscillator IOs and can
106 not be used as general purpose.
107
108 @endverbatim
109 ******************************************************************************
110 */
111
112 /* Includes ------------------------------------------------------------------*/
113 #include "stm32wb0x_hal.h"
114
115 /** @addtogroup STM32WB0x_HAL_Driver
116 * @{
117 */
118
119 /** @addtogroup GPIO
120 * @{
121 */
122 /** MISRA C:2012 deviation rule has been granted for following rules:
123 * Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of
124 * range of the shift operator in following API :
125 * HAL_GPIO_Init
126 * HAL_GPIO_DeInit
127 */
128
129 #ifdef HAL_GPIO_MODULE_ENABLED
130
131 /* Private typedef -----------------------------------------------------------*/
132 /* Private defines ------------------------------------------------------------*/
133 /** @defgroup GPIO_Private_Constants GPIO Private Constants
134 * @{
135 */
136 #define GPIO_NUMBER (16u)
137 /**
138 * @}
139 */
140
141 /* Private macros ------------------------------------------------------------*/
142 /* Private variables ---------------------------------------------------------*/
143 /* Private function prototypes -----------------------------------------------*/
144 /* Exported functions --------------------------------------------------------*/
145
146 /** @addtogroup GPIO_Exported_Functions
147 * @{
148 */
149
150 /** @addtogroup GPIO_Exported_Functions_Group1
151 * @brief Initialization and Configuration functions
152 *
153 @verbatim
154 ===============================================================================
155 ##### Initialization and de-initialization functions #####
156 ===============================================================================
157
158 @endverbatim
159 * @{
160 */
161
162 /**
163 * @brief Initialize the GPIOx peripheral according to the specified parameters in the GPIO_Init.
164 * @param GPIOx where x can be (A..B) to select the GPIO peripheral for STM32WB0x family
165 * @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains
166 * the configuration information for the specified GPIO peripheral.
167 * @retval None
168 */
HAL_GPIO_Init(GPIO_TypeDef * GPIOx,GPIO_InitTypeDef * GPIO_Init)169 void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
170 {
171 uint32_t position = 0x00u;
172 uint32_t iocurrent;
173 uint32_t temp;
174
175 /* Check the parameters */
176 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
177 assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
178 assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
179 assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
180
181 /* Configure the port pins */
182 while (((GPIO_Init->Pin) >> position) != 0x00u)
183 {
184 /* Get current io position */
185 iocurrent = (GPIO_Init->Pin) & (1uL << position);
186
187 if (iocurrent != 0x00u)
188 {
189 /*--------------------- GPIO Mode Configuration ------------------------*/
190 /* In case of Output or Alternate function mode selection */
191 if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF))
192 {
193 /* Check the Speed parameter */
194 assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
195 /* Configure the IO Speed */
196 temp = GPIOx->OSPEEDR;
197 temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
198 temp |= (GPIO_Init->Speed << (position * 2u));
199 GPIOx->OSPEEDR = temp;
200
201 /* Configure the IO Output Type */
202 temp = GPIOx->OTYPER;
203 temp &= ~(GPIO_OTYPER_OT0 << position) ;
204 temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
205 GPIOx->OTYPER = temp;
206 }
207
208 /* Activate the Pull-up or Pull down resistor for the current IO */
209 if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG)
210 {
211 temp = GPIOx->PUPDR;
212 temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
213 temp |= ((GPIO_Init->Pull) << (position * 2U));
214 GPIOx->PUPDR = temp;
215 }
216
217 /* In case of Alternate function mode selection */
218 if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
219 {
220 /* Check the Alternate function parameters */
221 assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
222 assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
223
224 /* Configure Alternate function mapped with the current IO */
225 temp = GPIOx->AFR[position >> 3u];
226 temp &= ~(0xFu << ((position & 0x07u) * 4u));
227 temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u));
228 GPIOx->AFR[position >> 3u] = temp;
229 }
230
231 /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
232 temp = GPIOx->MODER;
233 temp &= ~(GPIO_MODER_MODE0 << (position * 2u));
234 temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u));
235 GPIOx->MODER = temp;
236
237 /*--------------------- EXTI Mode Configuration ------------------------*/
238 /* Configure the External Interrupt or event for the current IO */
239 if ((GPIO_Init->Mode & EXTI_MODE) != 0x00u)
240 {
241
242 /* Edge/Level line configuration */
243 if ((GPIO_Init->Mode & DETECTION_TYPE) != 0x00u)
244 {
245 temp = SYSCFG->IO_DTR;
246 if (GPIOx == GPIOA)
247 {
248 temp &= ~(1 << position);
249 temp |= (1 << position);
250 }
251 else
252 {
253 temp &= ~((1 << position) << 16);
254 temp |= ((1 << position) << 16);
255 }
256 SYSCFG->IO_DTR = temp;
257 }
258
259 /* Edge selection configuration */
260 if ((GPIO_Init->Mode & EDGE_SELECTION) != 0x00u)
261 {
262 temp = SYSCFG->IO_IBER;
263
264 if (GPIOx == GPIOA)
265 {
266 temp &= ~(1 << position);
267 temp |= (1 << position);
268 }
269 else
270 {
271 temp &= ~((1 << position) << 16);
272 temp |= ((1 << position) << 16);
273 }
274 SYSCFG->IO_IBER= temp;
275 }
276
277 /* Trigger mode configuration */
278 if ((GPIO_Init->Mode & TRIGGER_MODE) != 0x00u)
279 {
280 temp = SYSCFG->IO_IEVR;
281
282 if (GPIOx == GPIOA)
283 {
284 temp &= ~(1 << position);
285 temp |= (1 << position);
286 }
287 else
288 {
289 temp &= ~((1 << position) << 16);
290 temp |= ((1 << position) << 16);
291 }
292 SYSCFG->IO_IEVR= temp;
293 }
294
295 /* Enable the specified EXTI interrupt line */
296 if ((GPIO_Init->Mode & EXTI_IT) == EXTI_IT)
297 {
298 temp = SYSCFG->IO_IER;
299
300 if (GPIOx == GPIOA)
301 {
302 temp &= ~(1 << position);
303 temp |= (1 << position);
304 }
305 else
306 {
307 temp &= ~((1 << position) << 16);
308 temp |= ((1 << position) << 16);
309 }
310 SYSCFG->IO_IER= temp;
311 }
312 }
313 }
314
315 position++;
316 }
317 }
318
319 /**
320 * @brief De-initialize the GPIOx peripheral registers to their default reset values.
321 * @param GPIOx where x can be (A..B) to select the GPIO peripheral for STM32WB0x family
322 * @param GPIO_Pin specifies the port bit to be written.
323 * This parameter can be one of GPIO_PIN_x where x can be (0..15).
324 * @retval None
325 */
HAL_GPIO_DeInit(GPIO_TypeDef * GPIOx,uint32_t GPIO_Pin)326 void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
327 {
328 uint32_t position = 0x00u;
329 uint32_t iocurrent;
330 uint32_t tmp;
331
332 /* Check the parameters */
333 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
334 assert_param(IS_GPIO_PIN(GPIO_Pin));
335
336 /* Configure the port pins */
337 while ((GPIO_Pin >> position) != 0x00u)
338 {
339 /* Get current io position */
340 iocurrent = (GPIO_Pin) & (1uL << position);
341
342 if (iocurrent != 0x00u)
343 {
344 /*------------------------- EXTI Mode Configuration --------------------*/
345 /* Clear the External Interrupt or Event for the current IO */
346
347 /* Disable the specified EXTI interrupt line */
348 tmp = SYSCFG->IO_IER;
349 if(GPIOx == GPIOA)
350 {
351 tmp = ~(1<<position);
352 }
353 else
354 {
355 tmp = ~((1<<position) << 16);
356 }
357 SYSCFG->IO_IER = tmp;
358
359 /* Clear EXTI line configuration */
360 tmp = SYSCFG->IO_DTR;
361 if(GPIOx == GPIOA)
362 {
363 tmp = ~(1<<position);
364 }
365 else
366 {
367 tmp = ~((1<<position) << 16);
368 }
369 SYSCFG->IO_DTR = tmp;
370
371 tmp = SYSCFG->IO_IBER;
372 if(GPIOx == GPIOA)
373 {
374 tmp = ~(1<<position);
375 }
376 else
377 {
378 tmp = ~((1<<position) << 16);
379 }
380 SYSCFG->IO_IBER = tmp;
381
382 /* Clear trigger mode configuration */
383 tmp = SYSCFG->IO_IEVR;
384 if(GPIOx == GPIOA)
385 {
386 tmp = ~(1<<position);
387 }
388 else
389 {
390 tmp = ~((1<<position) << 16);
391 }
392 SYSCFG->IO_IEVR = tmp;
393
394 /*------------------------- GPIO Mode Configuration --------------------*/
395 /* Configure IO in Analog Mode */
396 GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2u));
397
398 /* Configure the default Alternate Function in current IO */
399 GPIOx->AFR[position >> 3u] &= ~(0xFu << ((position & 0x07u) * 4u)) ;
400
401 /* Deactivate the Pull-up and Pull-down resistor for the current IO */
402 GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
403
404 /* Configure the default value IO Output Type */
405 GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ;
406
407 /* Configure the default value for IO Speed */
408 GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
409 }
410
411 position++;
412 }
413 }
414
415 /**
416 * @}
417 */
418
419 /** @addtogroup GPIO_Exported_Functions_Group2
420 * @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
421 *
422 @verbatim
423 ===============================================================================
424 ##### IO operation functions #####
425 ===============================================================================
426
427 @endverbatim
428 * @{
429 */
430
431 /**
432 * @brief Read the specified input port pin.
433 * @param GPIOx where x can be (A..B) to select the GPIO peripheral for STM32WB0x family
434 * @param GPIO_Pin specifies the port bit to read.
435 * This parameter can be GPIO_PIN_x where x can be (0..15).
436 * @retval The input port pin value.
437 */
HAL_GPIO_ReadPin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)438 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
439 {
440 GPIO_PinState bitstatus;
441
442 /* Check the parameters */
443 assert_param(IS_GPIO_PIN(GPIO_Pin));
444
445 if ((GPIOx->IDR & GPIO_Pin) != 0x00u)
446 {
447 bitstatus = GPIO_PIN_SET;
448 }
449 else
450 {
451 bitstatus = GPIO_PIN_RESET;
452 }
453 return bitstatus;
454 }
455
456 /**
457 * @brief Set or clear the selected data port bit.
458 * @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
459 * accesses. In this way, there is no risk of an IRQ occurring between
460 * the read and the modify access.
461 * @param GPIOx where x can be (A..B) to select the GPIO peripheral for STM32WB0x family
462 * @param GPIO_Pin specifies the port bit to be written.
463 * This parameter can be one of GPIO_PIN_x where x can be (0..15).
464 * @param PinState specifies the value to be written to the selected bit.
465 * This parameter can be one of the GPIO_PinState enum values:
466 * @arg GPIO_PIN_RESET: to clear the port pin
467 * @arg GPIO_PIN_SET: to set the port pin
468 * @retval None
469 */
HAL_GPIO_WritePin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin,GPIO_PinState PinState)470 void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
471 {
472 /* Check the parameters */
473 assert_param(IS_GPIO_PIN(GPIO_Pin));
474 assert_param(IS_GPIO_PIN_ACTION(PinState));
475
476 if (PinState != GPIO_PIN_RESET)
477 {
478 GPIOx->BSRR = (uint32_t)GPIO_Pin;
479 }
480 else
481 {
482 GPIOx->BRR = (uint32_t)GPIO_Pin;
483 }
484 }
485
486 /**
487 * @brief Set and clear several pins of a dedicated port in same cycle.
488 * @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
489 * accesses.
490 * @param GPIOx where x can be (A..F) to select the GPIO peripheral for STM32WLxx family
491 * @param PinReset specifies the port bits to be reset
492 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero.
493 * @param PinSet specifies the port bits to be set
494 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15) or zero.
495 * @note Both PinReset and PinSet combinations shall not get any common bit, else
496 * assert would be triggered.
497 * @note At least one of the two parameters used to set or reset shall be different from zero.
498 * @retval None
499 */
HAL_GPIO_WriteMultipleStatePin(GPIO_TypeDef * GPIOx,uint16_t PinReset,uint16_t PinSet)500 void HAL_GPIO_WriteMultipleStatePin(GPIO_TypeDef *GPIOx, uint16_t PinReset, uint16_t PinSet)
501 {
502 uint32_t tmp;
503
504 /* Check the parameters */
505 /* Make sure at least one parameter is different from zero and that there is no common pin */
506 assert_param(IS_GPIO_PIN((uint32_t)PinReset | (uint32_t)PinSet));
507 assert_param(IS_GPIO_COMMON_PIN(PinReset, PinSet));
508
509 tmp = (((uint32_t)PinReset << 16) | PinSet);
510 GPIOx->BSRR = tmp;
511 }
512
513 /**
514 * @brief Toggle the specified GPIO pin.
515 * @param GPIOx where x can be (A..B) to select the GPIO peripheral for STM32WB0x family
516 * @param GPIO_Pin specifies the pin to be toggled.
517 * @retval None
518 */
HAL_GPIO_TogglePin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)519 void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
520 {
521 uint32_t odr;
522
523 /* Check the parameters */
524 assert_param(IS_GPIO_PIN(GPIO_Pin));
525
526 /* get current Output Data Register value */
527 odr = GPIOx->ODR;
528
529 /* Set selected pins that were at low level, and reset ones that were high */
530 GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
531 }
532
533 /**
534 * @brief Lock GPIO Pins configuration registers.
535 * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
536 * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
537 * @note The configuration of the locked GPIO pins can no longer be modified
538 * until the next reset.
539 * @param GPIOx where x can be (A..B) to select the GPIO peripheral for STM32WB0x family
540 * @param GPIO_Pin specifies the port bits to be locked.
541 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
542 * @retval None
543 */
HAL_GPIO_LockPin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)544 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
545 {
546 __IO uint32_t tmp = GPIO_LCKR_LCKK;
547
548 /* Check the parameters */
549 assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
550 assert_param(IS_GPIO_PIN(GPIO_Pin));
551
552 /* Apply lock key write sequence */
553 tmp |= GPIO_Pin;
554 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
555 GPIOx->LCKR = tmp;
556 /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
557 GPIOx->LCKR = GPIO_Pin;
558 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
559 GPIOx->LCKR = tmp;
560 /* Read LCKK register. This read is mandatory to complete key lock sequence */
561 tmp = GPIOx->LCKR;
562
563 /* read again in order to confirm lock is active */
564 if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00u)
565 {
566 return HAL_OK;
567 }
568 else
569 {
570 return HAL_ERROR;
571 }
572 }
573
574 /**
575 * @brief Handle EXTI interrupt request.
576 * @param GPIOx where x can be (A..B) to select the GPIO peripheral
577 * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
578 * @retval None
579 */
HAL_GPIO_EXTI_IRQHandler(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)580 void HAL_GPIO_EXTI_IRQHandler(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
581 {
582 /* EXTI line interrupt detected */
583 if (__HAL_GPIO_EXTI_GET_IT(GPIOx, GPIO_Pin) != 0x00u)
584 {
585 __HAL_GPIO_EXTI_CLEAR_IT(GPIOx, GPIO_Pin);
586 HAL_GPIO_EXTI_Callback(GPIOx, GPIO_Pin);
587 }
588 }
589
590 /**
591 * @brief EXTI line detection callback.
592 * @param GPIOx where x can be (A..B) to select the GPIO peripheral
593 * @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
594 * @retval None
595 */
HAL_GPIO_EXTI_Callback(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)596 __weak void HAL_GPIO_EXTI_Callback(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
597 {
598 /* Prevent unused argument(s) compilation warning */
599 UNUSED(GPIO_Pin);
600
601 /* NOTE: This function should not be modified, when the callback is needed,
602 the HAL_GPIO_EXTI_Callback could be implemented in the user file
603 */
604 }
605
606 /**
607 * @}
608 */
609
610
611 /**
612 * @}
613 */
614
615 #endif /* HAL_GPIO_MODULE_ENABLED */
616 /**
617 * @}
618 */
619
620 /**
621 * @}
622 */
623