1 /**
2 ******************************************************************************
3 * @file stm32u5xx_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) 2021 STMicroelectronics.
14 * All rights reserved.
15 *
16 * This software component is licensed by ST under BSD 3-Clause license,
17 * the "License"; You may not use this file except in compliance with the
18 * License. You may obtain a copy of the License at:
19 * opensource.org/licenses/BSD-3-Clause
20 *
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### GPIO Peripheral features #####
25 ==============================================================================
26 [..]
27 (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
28 configured by software in several modes:
29 (++) Input mode
30 (++) Analog mode
31 (++) Output mode
32 (++) Alternate function mode
33 (++) External interrupt/event lines
34
35 (+) During and just after reset, the alternate functions and external interrupt
36 lines are not active and the I/O ports are configured in input floating mode.
37
38 (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
39 activated or not.
40
41 (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull
42 type and the IO speed can be selected depending on the VDD value.
43
44 (+) The microcontroller IO pins are connected to onboard peripherals/modules through a
45 multiplexer that allows only one peripheral alternate function (AF) connected
46 to an IO pin at a time. In this way, there can be no conflict between peripherals
47 sharing the same IO pin.
48
49 (+) All ports have external interrupt/event capability. To use external interrupt
50 lines, the port must be configured in input mode. All available GPIO pins are
51 connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
52
53 (+) The external interrupt/event controller consists of up to 39 edge detectors
54 (16 lines are connected to GPIO) for generating event/interrupt requests (each
55 input line can be independently configured to select the type (interrupt or event)
56 and the corresponding trigger event (rising or falling or both). Each line can
57 also be masked independently.
58
59 ##### How to use this driver #####
60 ==============================================================================
61 [..]
62 (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
63
64 (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
65 (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
66 (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
67 structure.
68 (++) In case of Output or alternate function mode selection: the speed is
69 configured through "Speed" member from GPIO_InitTypeDef structure.
70 (++) In alternate mode is selection, the alternate function connected to the IO
71 is configured through "Alternate" member from GPIO_InitTypeDef structure.
72 (++) Analog mode is required when a pin is to be used as ADC channel
73 or DAC output.
74 (++) In case of external interrupt/event selection the "Mode" member from
75 GPIO_InitTypeDef structure select the type (interrupt or event) and
76 the corresponding trigger event (rising or falling or both).
77
78 (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
79 mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
80 HAL_NVIC_EnableIRQ().
81
82 (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
83
84 (#) To set/reset the level of a pin configured in output mode use
85 HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
86
87 (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
88
89 (#) During and just after reset, the alternate functions are not
90 active and the GPIO pins are configured in input floating mode (except JTAG
91 pins).
92
93 (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
94 (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
95 priority over the GPIO function.
96
97 (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
98 general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
99 The HSE has priority over the GPIO function.
100
101 @endverbatim
102 ******************************************************************************
103 */
104
105 /* Includes ------------------------------------------------------------------*/
106 #include "stm32u5xx_hal.h"
107
108 /** @addtogroup STM32U5xx_HAL_Driver
109 * @{
110 */
111
112 /** @addtogroup GPIO
113 * @{
114 */
115
116 #ifdef HAL_GPIO_MODULE_ENABLED
117
118 /* Private typedef -----------------------------------------------------------*/
119 /* Private defines -----------------------------------------------------------*/
120 /** @defgroup GPIO_Private_Defines GPIO Private Defines
121 * @{
122 */
123 #define GPIO_MODE (0x00000003U)
124 #define EXTI_MODE (0x10000000U)
125 #define GPIO_MODE_IT (0x00010000U)
126 #define GPIO_MODE_EVT (0x00020000U)
127 #define RISING_EDGE (0x00100000U)
128 #define FALLING_EDGE (0x00200000U)
129 #define GPIO_OUTPUT_TYPE (0x00000010U)
130 #define GPIO_NUMBER (16U)
131
132 /**
133 * @}
134 */
135
136 /* Private macros ------------------------------------------------------------*/
137 /* Private variables ---------------------------------------------------------*/
138 /** @defgroup GPIO_Private_Variables GPIO Private Variables
139 * @{
140 */
141
142 /* LPGPIO Mapping */
143 static const LPGPIO_MapTypeDef LPGPIO_Map[GPIO_NUMBER] =
144 {
145 /* LPGPIO Pins Port Pin */
146 /* Pin 0:*/ {GPIOA, 1},
147 /* Pin 1:*/ {GPIOA, 3},
148 /* Pin 2:*/ {GPIOA, 6},
149 /* Pin 3:*/ {GPIOB, 1},
150 /* Pin 4:*/ {GPIOB, 10},
151 /* Pin 5:*/ {GPIOC, 2},
152 /* Pin 6:*/ {GPIOD, 13},
153 /* Pin 7:*/ {GPIOD, 2},
154 /* Pin 8:*/ {GPIOC, 10},
155 /* Pin 9:*/ {GPIOB, 0},
156 /* Pin 10:*/ {GPIOC, 12},
157 /* Pin 11:*/ {GPIOB, 3},
158 /* Pin 12:*/ {GPIOB, 4},
159 /* Pin 13:*/ {GPIOE, 0},
160 /* Pin 14:*/ {GPIOE, 2},
161 /* Pin 15:*/ {GPIOE, 3},
162 };
163
164 /**
165 * @}
166 */
167
168 /* Private function prototypes -----------------------------------------------*/
169 /* Exported functions --------------------------------------------------------*/
170
171 /** @addtogroup GPIO_Exported_Functions
172 * @{
173 */
174
175 /** @defgroup GPIO_Exported_Functions_Group1 Initialization/de-initialization functions
176 * @brief Initialization and Configuration functions
177 *
178 @verbatim
179 ===============================================================================
180 ##### Initialization and de-initialization functions #####
181 ===============================================================================
182
183 @endverbatim
184 * @{
185 */
186
187 /**
188 * @brief Initialize the GPIOx/LPGPIOx peripheral according to the specified parameters in the pGPIO_Init.
189 * @note If GPIOx/LPGPIOx peripheral pin is used in EXTI_MODE and the pin is secure in case
190 * the system implements the security (TZEN=1), it is up to the secure application to
191 * insure that the corresponding EXTI line is set secure.
192 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the corresponding
193 * peripheral for STM32U5 family
194 * @param pGPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
195 * the configuration information for the specified GPIO peripheral.
196 * @retval None
197 */
HAL_GPIO_Init(GPIO_TypeDef * GPIOx,const GPIO_InitTypeDef * pGPIO_Init)198 void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, const GPIO_InitTypeDef *pGPIO_Init)
199 {
200 uint32_t tmp;
201 uint32_t iocurrent;
202 uint32_t pin_position;
203 uint32_t position = 0U;
204 GPIO_TypeDef *p_gpio;
205
206 /* Check the parameters */
207 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
208 assert_param(IS_GPIO_PIN(pGPIO_Init->Pin));
209 assert_param(IS_GPIO_MODE(pGPIO_Init->Mode));
210
211 /* Save GPIO port address */
212 p_gpio = GPIOx;
213
214 /* Configure the port pins */
215 while (((pGPIO_Init->Pin) >> position) != 0U)
216 {
217 /* Get current io position */
218 iocurrent = (pGPIO_Init->Pin) & (1UL << position);
219
220 /* Save Pin Position */
221 pin_position = position;
222
223 if (iocurrent != 0U)
224 {
225 /*--------------------- GPIO Mode Configuration ------------------------*/
226 /* In case of Alternate function mode selection */
227 if (GPIOx == LPGPIO1)
228 {
229 /* MODER configuration */
230 tmp = GPIOx->MODER;
231 tmp &= ~(LPGPIO_MODER_MOD0 << position);
232 tmp |= ((pGPIO_Init->Mode & GPIO_MODE_OUTPUT_PP) << position);
233 GPIOx->MODER = tmp;
234
235 /* Save GPIO Port and pin index */
236 p_gpio = LPGPIO_Map[position].GPIO_PORT;
237 pin_position = LPGPIO_Map[position].Pin_Pos;
238
239 /* Configure Alternate function mapped with the current IO */
240 tmp = p_gpio->AFR[(pin_position) >> 3U];
241 tmp &= ~(0x0FUL << (((pin_position) & 0x07U) * 4U));
242 tmp |= ((GPIO_AF11_LPGPIO & 0x0FUL) << (((pin_position) & 0x07U) * 4U));
243 p_gpio->AFR[(pin_position) >> 3U] = tmp;
244
245 /* Configure IO Direction mode (Alternate) */
246 tmp = p_gpio->MODER;
247 tmp &= ~(GPIO_MODER_MODE0 << (pin_position * 2U));
248 tmp |= ((GPIO_MODE_AF_PP & 0x0FUL) << (pin_position * 2U));
249 p_gpio->MODER = tmp;
250 }
251 else if ((pGPIO_Init->Mode == GPIO_MODE_AF_PP) || (pGPIO_Init->Mode == GPIO_MODE_AF_OD))
252 {
253 /* Check the parameters */
254 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
255 assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
256 assert_param(IS_GPIO_AF(pGPIO_Init->Alternate));
257
258 /* Configure Alternate function mapped with the current IO */
259 tmp = GPIOx->AFR[position >> 3U];
260 tmp &= ~(0x0FUL << ((position & 0x07U) * 4U));
261 tmp |= ((pGPIO_Init->Alternate & 0x0FUL) << ((position & 0x07U) * 4U));
262 GPIOx->AFR[position >> 3U] = tmp;
263
264 /* Configure IO Direction mode (Alternate) */
265 tmp = p_gpio->MODER;
266 tmp &= ~(GPIO_MODER_MODE0 << (pin_position * 2U));
267 tmp |= ((pGPIO_Init->Mode & GPIO_MODE) << (pin_position * 2U));
268 p_gpio->MODER = tmp;
269 }
270 else
271 {
272 /* Check the parameters */
273 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
274
275 /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
276 tmp = p_gpio->MODER;
277 tmp &= ~(GPIO_MODER_MODE0 << (pin_position * 2U));
278 tmp |= ((pGPIO_Init->Mode & GPIO_MODE) << (pin_position * 2U));
279 p_gpio->MODER = tmp;
280 }
281
282 /* In case of Output or Alternate function mode selection */
283 if ((pGPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (pGPIO_Init->Mode == GPIO_MODE_AF_PP) ||
284 (pGPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (pGPIO_Init->Mode == GPIO_MODE_AF_OD))
285 {
286 /* Check the Speed parameter */
287 assert_param(IS_GPIO_SPEED(pGPIO_Init->Speed));
288
289 /* Configure the IO Speed */
290 tmp = p_gpio->OSPEEDR;
291 tmp &= ~(GPIO_OSPEEDR_OSPEED0 << (pin_position * 2U));
292 tmp |= (pGPIO_Init->Speed << (pin_position * 2U));
293 p_gpio->OSPEEDR = tmp;
294
295 /* Configure the IO Output Type */
296 tmp = p_gpio->OTYPER;
297 tmp &= ~(GPIO_OTYPER_OT0 << pin_position);
298 tmp |= (((pGPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4U) << pin_position);
299 p_gpio->OTYPER = tmp;
300 }
301
302 if (pGPIO_Init->Mode != GPIO_MODE_ANALOG)
303 {
304 /* Check the Pull parameters */
305 assert_param(IS_GPIO_PULL(pGPIO_Init->Pull));
306
307 /* Activate the Pull-up or Pull down resistor for the current IO */
308 tmp = p_gpio->PUPDR;
309 tmp &= ~(GPIO_PUPDR_PUPD0 << (pin_position * 2U));
310 tmp |= ((pGPIO_Init->Pull) << (pin_position * 2U));
311 p_gpio->PUPDR = tmp;
312 }
313
314 /*--------------------- EXTI Mode Configuration ------------------------*/
315 /* Configure the External Interrupt or event for the current IO */
316 if ((pGPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
317 {
318 tmp = EXTI->EXTICR[position >> 2U];
319 tmp &= ~((0x0FUL) << (8U * (position & 0x03U)));
320 tmp |= (GPIO_GET_INDEX(GPIOx) << (8U * (position & 0x03U)));
321 EXTI->EXTICR[position >> 2U] = tmp;
322
323 /* Clear EXTI line configuration */
324 tmp = EXTI->IMR1;
325 tmp &= ~((uint32_t)iocurrent);
326 if ((pGPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
327 {
328 tmp |= iocurrent;
329 }
330 EXTI->IMR1 = tmp;
331
332 tmp = EXTI->EMR1;
333 tmp &= ~((uint32_t)iocurrent);
334 if ((pGPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
335 {
336 tmp |= iocurrent;
337 }
338 EXTI->EMR1 = tmp;
339
340 /* Clear Rising Falling edge configuration */
341 tmp = EXTI->RTSR1;
342 tmp &= ~((uint32_t)iocurrent);
343 if ((pGPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
344 {
345 tmp |= iocurrent;
346 }
347 EXTI->RTSR1 = tmp;
348
349 tmp = EXTI->FTSR1;
350 tmp &= ~((uint32_t)iocurrent);
351 if ((pGPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
352 {
353 tmp |= iocurrent;
354 }
355 EXTI->FTSR1 = tmp;
356 }
357 }
358 position++;
359 }
360 }
361
362 /**
363 * @brief De-initialize the GPIOx peripheral registers to their default reset values.
364 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
365 * peripheral for STM32U5 family
366 * @param GPIO_Pin: specifies the port bit to be written.
367 * This parameter can be one of GPIO_PIN_x where x can be (0..15).
368 * @retval None
369 */
HAL_GPIO_DeInit(GPIO_TypeDef * GPIOx,uint32_t GPIO_Pin)370 void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
371 {
372 uint32_t tmp;
373 uint32_t iocurrent;
374 uint32_t pin_position;
375 uint32_t position = 0U;
376 GPIO_TypeDef *p_gpio;
377
378 /* Check the parameters */
379 assert_param(IS_GPIO_PIN(GPIO_Pin));
380
381 /* Save GPIO port address */
382 p_gpio = GPIOx;
383
384 /* Configure the port pins */
385 while ((GPIO_Pin >> position) != 0U)
386 {
387 /* Get current io position */
388 iocurrent = (GPIO_Pin) & (1UL << position);
389
390 /*Save Pin Position */
391 pin_position = position;
392
393 if (iocurrent != 0U)
394 {
395 /* In case of LPGPIO port selected */
396 if (GPIOx == LPGPIO1)
397 {
398 /* Configure LP/IO in Input Mode */
399 p_gpio = LPGPIO_Map[pin_position].GPIO_PORT;
400 pin_position = LPGPIO_Map[position].Pin_Pos;
401 LPGPIO1->MODER &= ~(1U << pin_position);
402 }
403 else
404 {
405 /* Check the parameters */
406 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
407
408 /*------------------------- EXTI Mode Configuration --------------------*/
409 /* Clear the External Interrupt or Event for the current IO */
410 tmp = EXTI->EXTICR[position >> 2U];
411 tmp &= ((0x0FUL) << (8U * (position & 0x03U)));
412 if (tmp == (GPIO_GET_INDEX(GPIOx) << (8U * (position & 0x03U))))
413 {
414 /* Clear EXTI line configuration */
415 EXTI->IMR1 &= ~(iocurrent);
416 EXTI->EMR1 &= ~(iocurrent);
417
418 /* Clear Rising Falling edge configuration */
419 EXTI->RTSR1 &= ~(iocurrent);
420 EXTI->FTSR1 &= ~(iocurrent);
421
422 tmp = (0x0FUL) << (8U * (position & 0x03U));
423 EXTI->EXTICR[position >> 2U] &= ~tmp;
424 }
425 }
426
427 /*------------------------- GPIO Mode Configuration --------------------*/
428 /* Configure IO in Analog Mode */
429 p_gpio->MODER |= (GPIO_MODER_MODE0 << (pin_position * 2U));
430
431 /* Configure the default Alternate Function in current IO */
432 p_gpio->AFR[pin_position >> 3U] &= ~(0x0FUL << ((pin_position & 0x07U) * 4U));
433
434 /* Configure the default value for IO Speed */
435 p_gpio->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (pin_position * 2U));
436
437 /* Configure the default value IO Output Type */
438 p_gpio->OTYPER &= ~(GPIO_OTYPER_OT0 << pin_position);
439
440 /* Deactivate the Pull-up and Pull-down resistor for the current IO */
441 p_gpio->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (pin_position * 2U));
442 }
443
444 position++;
445 }
446 }
447
448 /**
449 * @}
450 */
451
452 /** @addtogroup GPIO_Exported_Functions_Group2
453 * @brief GPIO/LPGPIO Read, Write, Toggle, Lock and EXTI management functions.
454 *
455 @verbatim
456 ===============================================================================
457 ##### IO operation functions #####
458 ===============================================================================
459
460 @endverbatim
461 * @{
462 */
463
464 /**
465 * @brief Read the specified input port pin.
466 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
467 * peripheral for STM32U5 family
468 * @param GPIO_Pin: specifies the port bit to read.
469 * This parameter can be GPIO_PIN_x where x can be (0..15).
470 * @retval The input port pin value.
471 */
HAL_GPIO_ReadPin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)472 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
473 {
474 GPIO_PinState bitstatus;
475
476 /* Check the parameters */
477 assert_param(IS_GPIO_PIN(GPIO_Pin));
478
479 if ((GPIOx->IDR & GPIO_Pin) != 0U)
480 {
481 bitstatus = GPIO_PIN_SET;
482 }
483 else
484 {
485 bitstatus = GPIO_PIN_RESET;
486 }
487
488 return bitstatus;
489 }
490
491 /**
492 * @brief Set or clear the selected data port bit.
493 * @note This function uses GPIOx_BSRR/LPGPIOx_BSRR and GPIOx_BRR/LPGPIOx_BRR registers to allow atomic read/modify
494 * accesses. In this way, there is no risk of an IRQ occurring between
495 * the read and the modify access.
496 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
497 * peripheral for STM32U5 family
498 * @param GPIO_Pin: specifies the port bit to be written.
499 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
500 * @param PinState: specifies the value to be written to the selected bit.
501 * This parameter can be one of the GPIO_PinState enum values:
502 * @arg GPIO_PIN_RESET: to clear the port pin
503 * @arg GPIO_PIN_SET: to set the port pin
504 * @retval None
505 */
HAL_GPIO_WritePin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin,GPIO_PinState PinState)506 void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
507 {
508 /* Check the parameters */
509 assert_param(IS_GPIO_PIN(GPIO_Pin));
510 assert_param(IS_GPIO_PIN_ACTION(PinState));
511
512 if (PinState != GPIO_PIN_RESET)
513 {
514 GPIOx->BSRR = (uint32_t)GPIO_Pin;
515 }
516 else
517 {
518 GPIOx->BRR = (uint32_t)GPIO_Pin;
519 }
520 }
521
522 /**
523 * @brief Toggle the specified GPIO pin.
524 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
525 * peripheral for STM32U5 family
526 * @param GPIO_Pin specifies the pin to be toggled.
527 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
528 * @retval None
529 */
HAL_GPIO_TogglePin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)530 void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
531 {
532 uint32_t odr;
533
534 /* Check the parameters */
535 assert_param(IS_GPIO_PIN(GPIO_Pin));
536
537 /* get current Output Data Register value */
538 odr = GPIOx->ODR;
539
540 /* Set selected pins that were at low level, and reset ones that were high */
541 GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
542 }
543
544 /**
545 * @brief Lock GPIO Pins configuration registers.
546 * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
547 * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
548 * @note The configuration of the locked GPIO pins can no longer be modified
549 * until the next reset.
550 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
551 * peripheral for STM32U5 family
552 * @param GPIO_Pin: specifies the port bits to be locked.
553 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
554 * @retval None
555 */
HAL_GPIO_LockPin(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)556 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
557 {
558 uint32_t iocurrent;
559 uint32_t pin_locked;
560 uint32_t pin_position;
561 uint32_t position = 0U;
562 GPIO_TypeDef *p_gpio;
563 __IO uint32_t tmp = GPIO_LCKR_LCKK;
564
565 /* Check the parameters */
566 assert_param(IS_GPIO_PIN(GPIO_Pin));
567
568 /* Save GPIO port address */
569 p_gpio = GPIOx;
570
571 /* Configure the port pins */
572 while ((GPIO_Pin >> position) != 0U)
573 {
574 /* Get current io position */
575 iocurrent = GPIO_Pin & (1UL << position);
576
577 if (iocurrent != 0U)
578 {
579
580 /* In case of LPGPIO Port */
581 if (GPIOx == LPGPIO1)
582 {
583 /* Save GPIO Port and pin index */
584 p_gpio = LPGPIO_Map[position].GPIO_PORT;
585 pin_position = (1UL << (LPGPIO_Map[position].Pin_Pos));
586
587 /* Save gpio pin locked */
588 pin_locked = p_gpio->LCKR;
589
590 /* Apply lock key write sequence */
591 tmp |= (pin_locked | pin_position);
592 }
593 else
594 {
595 /* Check the parameters */
596 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
597
598 /* Save GPIO Pin pos*/
599 pin_position = (1UL << position);
600
601 /* Save gpio pin locked */
602 pin_locked = p_gpio->LCKR;
603
604 /* Apply lock key write sequence */
605 tmp |= (pin_locked | pin_position);
606 }
607
608 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
609 p_gpio->LCKR = tmp;
610 /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
611 p_gpio->LCKR = pin_position;
612 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
613 p_gpio->LCKR = tmp;
614 /* Read LCKK register. This read is mandatory to complete key lock sequence */
615 tmp = p_gpio->LCKR;
616
617 /* read again in order to confirm lock is active */
618 if ((p_gpio->LCKR & GPIO_LCKR_LCKK) != GPIO_LCKR_LCKK)
619 {
620 return HAL_ERROR;
621 }
622 }
623 position++;
624 }
625 return HAL_OK;
626 }
627
628 /**
629 * @brief Enable speed optimization for several pin of dedicated port.
630 * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding
631 * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must
632 * be kept at reset value.
633 * @note It must be used only if the I/O supply voltage is below 2.7 V.
634 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
635 * peripheral for STM32U5 family
636 * @param GPIO_Pin: specifies the port bit to be written.
637 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
638 * @retval None
639 */
HAL_GPIO_EnableHighSPeedLowVoltage(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)640 void HAL_GPIO_EnableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
641 {
642 uint32_t iocurrent;
643 uint32_t pin_position;
644 uint32_t position = 0U;
645 GPIO_TypeDef *p_gpio;
646
647 /* Check the parameters */
648 assert_param(IS_GPIO_PIN(GPIO_Pin));
649
650 /* Save GPIO port address */
651 p_gpio = GPIOx;
652
653 /* Configure the port pins */
654 while ((GPIO_Pin >> position) != 0U)
655 {
656 /* Get current io position */
657 iocurrent = GPIO_Pin & (1UL << position);
658
659 if (iocurrent != 0U)
660 {
661 /* In case of LPGPIO Port */
662 if (GPIOx == LPGPIO1)
663 {
664 /* Get GPIO pin position */
665 position = POSITION_VAL(GPIO_Pin);
666
667 /* Save GPIO Port and pin index */
668 p_gpio = LPGPIO_Map[position].GPIO_PORT;
669 pin_position = (1UL << (LPGPIO_Map[position].Pin_Pos));
670 }
671 else
672 {
673 /* Check the parameters */
674 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
675
676 /* Save GPIO pin pos */
677 pin_position = (1UL << position);
678 }
679 /* Set HSLVR gpio pin */
680 SET_BIT(p_gpio->HSLVR, pin_position);
681 }
682 position++;
683 }
684 }
685
686 /**
687 * @brief Disable speed optimization for several pin of dedicated port.
688 * @note Not all I/Os support the HSLV mode. Refer to the I/O structure in the corresponding
689 * datasheet for the list of I/Os supporting this feature. Other I/Os HSLV configuration must
690 * be kept at reset value.
691 * @note It must be used only if the I/O supply voltage is below 2.7 V.
692 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
693 * peripheral for STM32U5 family
694 * @param GPIO_Pin: specifies the port bit to be written.
695 * This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
696 * @retval None
697 */
HAL_GPIO_DisableHighSPeedLowVoltage(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin)698 void HAL_GPIO_DisableHighSPeedLowVoltage(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
699 {
700 uint32_t iocurrent;
701 uint32_t pin_position;
702 uint32_t position = 0U;
703 GPIO_TypeDef *p_gpio;
704
705 /* Check the parameters */
706 assert_param(IS_GPIO_PIN(GPIO_Pin));
707
708 /* Save GPIO port address */
709 p_gpio = GPIOx;
710
711 /* Configure the port pins */
712 while ((GPIO_Pin >> position) != 0U)
713 {
714 /* Get current io position */
715 iocurrent = GPIO_Pin & (1UL << position);
716
717 if (iocurrent != 0U)
718 {
719 /* In case of LPGPIO Port */
720 if (GPIOx == LPGPIO1)
721 {
722 /* Get GPIO pin position */
723 position = POSITION_VAL(GPIO_Pin);
724
725 /* Save GPIO Port and pin index */
726 p_gpio = LPGPIO_Map[position].GPIO_PORT;
727 pin_position = (1UL << (LPGPIO_Map[position].Pin_Pos));
728 }
729 else
730 {
731 /* Check the parameters */
732 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
733
734 /* Save GPIO pin pos */
735 pin_position = (1UL << position);
736 }
737 /* Clear HSLVR gpio pin */
738 CLEAR_BIT(p_gpio->HSLVR, pin_position);
739 }
740 position++;
741 }
742 }
743
744 /**
745 * @brief Handle EXTI interrupt request.
746 * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
747 * @retval None
748 */
HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)749 void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
750 {
751 /* EXTI line interrupt detected */
752 if (__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_Pin) != 0U)
753 {
754 __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_Pin);
755 HAL_GPIO_EXTI_Rising_Callback(GPIO_Pin);
756 }
757
758 if (__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_Pin) != 0U)
759 {
760 __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_Pin);
761 HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);
762 }
763 }
764
765 /**
766 * @brief EXTI line rising detection callback.
767 * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
768 * @retval None
769 */
HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)770 __weak void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
771 {
772 /* Prevent unused argument(s) compilation warning */
773 UNUSED(GPIO_Pin);
774
775 /* NOTE: This function should not be modified, when the callback is needed,
776 the HAL_GPIO_EXTI_Rising_Callback could be implemented in the user file
777 */
778 }
779
780 /**
781 * @brief EXTI line falling detection callback.
782 * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
783 * @retval None
784 */
HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)785 __weak void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
786 {
787 /* Prevent unused argument(s) compilation warning */
788 UNUSED(GPIO_Pin);
789
790 /* NOTE: This function should not be modified, when the callback is needed,
791 the HAL_GPIO_EXTI_Falling_Callback could be implemented in the user file
792 */
793 }
794
795 /**
796 * @}
797 */
798
799 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
800
801 /** @defgroup GPIO_Exported_Functions_Group3 IO attributes management functions
802 * @brief GPIO attributes management functions.
803 *
804 @verbatim
805 ===============================================================================
806 ##### IO attributes functions #####
807 ===============================================================================
808
809 @endverbatim
810 * @{
811 */
812
813 /**
814 * @brief Configure the GPIO pins attributes.
815 * @note Available attributes are to secure GPIO pin(s), so this function is
816 * only available in secure
817 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
818 * peripheral for STM32U5 family
819 * @param GPIO_Pin: specifies the pin(s) to configure the secure attribute
820 * @param PinAttributes: specifies the pin(s) to be set in secure mode, other being set non secured.
821 * @retval None
822 */
HAL_GPIO_ConfigPinAttributes(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin,uint32_t PinAttributes)823 void HAL_GPIO_ConfigPinAttributes(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t PinAttributes)
824 {
825 uint32_t iocurrent;
826 uint32_t pin_position;
827 uint32_t position = 0U;
828 GPIO_TypeDef *p_gpio;
829
830 /* Check the parameters */
831 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
832 assert_param(IS_GPIO_PIN(GPIO_Pin));
833 assert_param(IS_GPIO_PIN_ATTRIBUTES(PinAttributes));
834
835 /* Save GPIO port address */
836 p_gpio = GPIOx;
837
838 /* Configure the port pins */
839 while ((GPIO_Pin >> position) != 0U)
840 {
841 /* Get current io position */
842 iocurrent = GPIO_Pin & (1UL << position);
843
844 /* Save pin position */
845 pin_position = position;
846
847 if (iocurrent != 0U)
848 {
849 /* In case of LPGPIO Port */
850 if (GPIOx == LPGPIO1)
851 {
852 /* Save GPIO Port and pin index */
853 p_gpio = LPGPIO_Map[position].GPIO_PORT;
854 pin_position = LPGPIO_Map[position].Pin_Pos;
855 }
856 else
857 {
858 /* Check the parameters */
859 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
860 }
861
862 /* Configure the IO secure attribute */
863 MODIFY_REG(p_gpio->SECCFGR, (GPIO_SECCFGR_SEC0 << pin_position), (PinAttributes << pin_position));
864 }
865 position++;
866 }
867 }
868
869 /**
870 * @brief Get the GPIO pins attributes.
871 * @note Available attributes are to secure GPIO pin(s), so this function is
872 * only available in secure
873 * @param GPIOx or LPGPIOx: where x can be (A..I) for the GPIO and (1) for LPGPIO to select the the corresponding
874 * peripheral for STM32U5 family
875 * @param GPIO_Pin: specifies the single pin to get the secure attribute from
876 * @param pPinAttributes: pointer to return the pin attributes.
877 * @retval HAL Status.
878 */
HAL_GPIO_GetConfigPinAttributes(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin,uint32_t * pPinAttributes)879 HAL_StatusTypeDef HAL_GPIO_GetConfigPinAttributes(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint32_t *pPinAttributes)
880 {
881 uint32_t iocurrent;
882 uint32_t pin_position;
883 uint32_t position = 0U;
884 GPIO_TypeDef *p_gpio;
885
886 /* Check the parameters */
887 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
888 assert_param(IS_GPIO_PIN(GPIO_Pin) && (GPIO_Pin != GPIO_PIN_ALL));
889
890 /* Check null pointer */
891 if (pPinAttributes == NULL)
892 {
893 return HAL_ERROR;
894 }
895
896 /* Get secure attribute of the port pin */
897 while ((GPIO_Pin >> position) != 0U)
898 {
899 /* Get current io position */
900 iocurrent = GPIO_Pin & (1UL << position);
901
902 if (iocurrent != 0U)
903 {
904 /* In case of LPGPIO Port */
905 if (GPIOx == LPGPIO1)
906 {
907 /* Save GPIO Port and pin index */
908 p_gpio = LPGPIO_Map[position].GPIO_PORT;
909 pin_position = LPGPIO_Map[position].Pin_Pos;
910 }
911 else
912 {
913 /* Check the parameters */
914 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
915
916 /* Save GPIO port address */
917 p_gpio = GPIOx;
918
919 pin_position = (1UL << position);
920 }
921
922 /* Get the IO secure attribute */
923 if ((p_gpio->SECCFGR & (GPIO_SECCFGR_SEC0 << pin_position)) != 0U)
924 {
925 *pPinAttributes = GPIO_PIN_SEC;
926 }
927 else
928 {
929 *pPinAttributes = GPIO_PIN_NSEC;
930 }
931
932 break;
933 }
934 position++;
935 }
936
937 return HAL_OK;
938 }
939
940 /**
941 * @}
942 */
943
944 #endif /* __ARM_FEATURE_CMSE */
945
946
947 /**
948 * @}
949 */
950
951 #endif /* HAL_GPIO_MODULE_ENABLED */
952 /**
953 * @}
954 */
955
956 /**
957 * @}
958 */
959