STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_gpio.c 00004 * @author MCD Application Team 00005 * @brief GPIO HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the General Purpose Input/Output (GPIO) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * 00011 ****************************************************************************** 00012 * @attention 00013 * 00014 * Copyright (c) 2017 STMicroelectronics. 00015 * All rights reserved. 00016 * 00017 * This software is licensed under terms that can be found in the LICENSE file 00018 * in the root directory of this software component. 00019 * If no LICENSE file comes with this software, it is provided AS-IS. 00020 * 00021 ****************************************************************************** 00022 @verbatim 00023 ============================================================================== 00024 ##### GPIO Peripheral features ##### 00025 ============================================================================== 00026 [..] 00027 (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually 00028 configured by software in several modes: 00029 (++) Input mode 00030 (++) Analog mode 00031 (++) Output mode 00032 (++) Alternate function mode 00033 (++) External interrupt/event lines 00034 00035 (+) During and just after reset, the alternate functions and external interrupt 00036 lines are not active and the I/O ports are configured in input floating mode. 00037 00038 (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be 00039 activated or not. 00040 00041 (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull 00042 type and the IO speed can be selected depending on the VDD value. 00043 00044 (+) The microcontroller IO pins are connected to onboard peripherals/modules through a 00045 multiplexer that allows only one peripheral alternate function (AF) connected 00046 to an IO pin at a time. In this way, there can be no conflict between peripherals 00047 sharing the same IO pin. 00048 00049 (+) All ports have external interrupt/event capability. To use external interrupt 00050 lines, the port must be configured in input mode. All available GPIO pins are 00051 connected to the 16 external interrupt/event lines from EXTI0 to EXTI15. 00052 00053 The external interrupt/event controller consists of up to 23 edge detectors 00054 (16 lines are connected to GPIO) for generating event/interrupt requests (each 00055 input line can be independently configured to select the type (interrupt or event) 00056 and the corresponding trigger event (rising or falling or both). Each line can 00057 also be masked independently. 00058 00059 ##### How to use this driver ##### 00060 ============================================================================== 00061 [..] 00062 (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE(). 00063 00064 (#) Configure the GPIO pin(s) using HAL_GPIO_Init(). 00065 (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure 00066 (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef 00067 structure. 00068 (++) In case of Output or alternate function mode selection: the speed is 00069 configured through "Speed" member from GPIO_InitTypeDef structure. 00070 (++) In alternate mode is selection, the alternate function connected to the IO 00071 is configured through "Alternate" member from GPIO_InitTypeDef structure. 00072 (++) Analog mode is required when a pin is to be used as ADC channel 00073 or DAC output. 00074 (++) In case of external interrupt/event selection the "Mode" member from 00075 GPIO_InitTypeDef structure select the type (interrupt or event) and 00076 the corresponding trigger event (rising or falling or both). 00077 00078 (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority 00079 mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using 00080 HAL_NVIC_EnableIRQ(). 00081 00082 (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin(). 00083 00084 (#) To set/reset the level of a pin configured in output mode use 00085 HAL_GPIO_WritePin()/HAL_GPIO_TogglePin(). 00086 00087 (#) To lock pin configuration until next reset use HAL_GPIO_LockPin(). 00088 00089 00090 (#) During and just after reset, the alternate functions are not 00091 active and the GPIO pins are configured in input floating mode (except JTAG 00092 pins). 00093 00094 (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose 00095 (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has 00096 priority over the GPIO function. 00097 00098 (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as 00099 general purpose PH0 and PH1, respectively, when the HSE oscillator is off. 00100 The HSE has priority over the GPIO function. 00101 00102 @endverbatim 00103 ****************************************************************************** 00104 */ 00105 00106 /* Includes ------------------------------------------------------------------*/ 00107 #include "stm32h7xx_hal.h" 00108 00109 /** @addtogroup STM32H7xx_HAL_Driver 00110 * @{ 00111 */ 00112 00113 /** @defgroup GPIO GPIO 00114 * @brief GPIO HAL module driver 00115 * @{ 00116 */ 00117 00118 #ifdef HAL_GPIO_MODULE_ENABLED 00119 00120 /* Private typedef -----------------------------------------------------------*/ 00121 /* Private defines ------------------------------------------------------------*/ 00122 /** @addtogroup GPIO_Private_Constants GPIO Private Constants 00123 * @{ 00124 */ 00125 00126 #if defined(DUAL_CORE) 00127 #define EXTI_CPU1 (0x01000000U) 00128 #define EXTI_CPU2 (0x02000000U) 00129 #endif /*DUAL_CORE*/ 00130 #define GPIO_NUMBER (16U) 00131 /** 00132 * @} 00133 */ 00134 /* Private macro -------------------------------------------------------------*/ 00135 /* Private variables ---------------------------------------------------------*/ 00136 /* Private function prototypes -----------------------------------------------*/ 00137 /* Private functions ---------------------------------------------------------*/ 00138 /* Exported functions --------------------------------------------------------*/ 00139 /** @defgroup GPIO_Exported_Functions GPIO Exported Functions 00140 * @{ 00141 */ 00142 00143 /** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions 00144 * @brief Initialization and Configuration functions 00145 * 00146 @verbatim 00147 =============================================================================== 00148 ##### Initialization and de-initialization functions ##### 00149 =============================================================================== 00150 [..] 00151 This section provides functions allowing to initialize and de-initialize the GPIOs 00152 to be ready for use. 00153 00154 @endverbatim 00155 * @{ 00156 */ 00157 00158 /** 00159 * @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init. 00160 * @param GPIOx: where x can be (A..K) to select the GPIO peripheral. 00161 * @param GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains 00162 * the configuration information for the specified GPIO peripheral. 00163 * @retval None 00164 */ 00165 void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init) 00166 { 00167 uint32_t position = 0x00U; 00168 uint32_t iocurrent; 00169 uint32_t temp; 00170 EXTI_Core_TypeDef *EXTI_CurrentCPU; 00171 00172 #if defined(DUAL_CORE) && defined(CORE_CM4) 00173 EXTI_CurrentCPU = EXTI_D2; /* EXTI for CM4 CPU */ 00174 #else 00175 EXTI_CurrentCPU = EXTI_D1; /* EXTI for CM7 CPU */ 00176 #endif 00177 00178 /* Check the parameters */ 00179 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); 00180 assert_param(IS_GPIO_PIN(GPIO_Init->Pin)); 00181 assert_param(IS_GPIO_MODE(GPIO_Init->Mode)); 00182 00183 /* Configure the port pins */ 00184 while (((GPIO_Init->Pin) >> position) != 0x00U) 00185 { 00186 /* Get current io position */ 00187 iocurrent = (GPIO_Init->Pin) & (1UL << position); 00188 00189 if (iocurrent != 0x00U) 00190 { 00191 /*--------------------- GPIO Mode Configuration ------------------------*/ 00192 /* In case of Output or Alternate function mode selection */ 00193 if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)) 00194 { 00195 /* Check the Speed parameter */ 00196 assert_param(IS_GPIO_SPEED(GPIO_Init->Speed)); 00197 00198 /* Configure the IO Speed */ 00199 temp = GPIOx->OSPEEDR; 00200 temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U)); 00201 temp |= (GPIO_Init->Speed << (position * 2U)); 00202 GPIOx->OSPEEDR = temp; 00203 00204 /* Configure the IO Output Type */ 00205 temp = GPIOx->OTYPER; 00206 temp &= ~(GPIO_OTYPER_OT0 << position) ; 00207 temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position); 00208 GPIOx->OTYPER = temp; 00209 } 00210 00211 if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG) 00212 { 00213 /* Check the Pull parameter */ 00214 assert_param(IS_GPIO_PULL(GPIO_Init->Pull)); 00215 00216 /* Activate the Pull-up or Pull down resistor for the current IO */ 00217 temp = GPIOx->PUPDR; 00218 temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U)); 00219 temp |= ((GPIO_Init->Pull) << (position * 2U)); 00220 GPIOx->PUPDR = temp; 00221 } 00222 00223 /* In case of Alternate function mode selection */ 00224 if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF) 00225 { 00226 /* Check the Alternate function parameters */ 00227 assert_param(IS_GPIO_AF_INSTANCE(GPIOx)); 00228 assert_param(IS_GPIO_AF(GPIO_Init->Alternate)); 00229 00230 /* Configure Alternate function mapped with the current IO */ 00231 temp = GPIOx->AFR[position >> 3U]; 00232 temp &= ~(0xFU << ((position & 0x07U) * 4U)); 00233 temp |= ((GPIO_Init->Alternate) << ((position & 0x07U) * 4U)); 00234 GPIOx->AFR[position >> 3U] = temp; 00235 } 00236 00237 /* Configure IO Direction mode (Input, Output, Alternate or Analog) */ 00238 temp = GPIOx->MODER; 00239 temp &= ~(GPIO_MODER_MODE0 << (position * 2U)); 00240 temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U)); 00241 GPIOx->MODER = temp; 00242 00243 /*--------------------- EXTI Mode Configuration ------------------------*/ 00244 /* Configure the External Interrupt or event for the current IO */ 00245 if ((GPIO_Init->Mode & EXTI_MODE) != 0x00U) 00246 { 00247 /* Enable SYSCFG Clock */ 00248 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00249 00250 temp = SYSCFG->EXTICR[position >> 2U]; 00251 temp &= ~(0x0FUL << (4U * (position & 0x03U))); 00252 temp |= (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))); 00253 SYSCFG->EXTICR[position >> 2U] = temp; 00254 00255 /* Clear Rising Falling edge configuration */ 00256 temp = EXTI->RTSR1; 00257 temp &= ~(iocurrent); 00258 if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00U) 00259 { 00260 temp |= iocurrent; 00261 } 00262 EXTI->RTSR1 = temp; 00263 00264 temp = EXTI->FTSR1; 00265 temp &= ~(iocurrent); 00266 if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00U) 00267 { 00268 temp |= iocurrent; 00269 } 00270 EXTI->FTSR1 = temp; 00271 00272 temp = EXTI_CurrentCPU->EMR1; 00273 temp &= ~(iocurrent); 00274 if ((GPIO_Init->Mode & EXTI_EVT) != 0x00U) 00275 { 00276 temp |= iocurrent; 00277 } 00278 EXTI_CurrentCPU->EMR1 = temp; 00279 00280 /* Clear EXTI line configuration */ 00281 temp = EXTI_CurrentCPU->IMR1; 00282 temp &= ~(iocurrent); 00283 if ((GPIO_Init->Mode & EXTI_IT) != 0x00U) 00284 { 00285 temp |= iocurrent; 00286 } 00287 EXTI_CurrentCPU->IMR1 = temp; 00288 } 00289 } 00290 00291 position++; 00292 } 00293 } 00294 00295 /** 00296 * @brief De-initializes the GPIOx peripheral registers to their default reset values. 00297 * @param GPIOx: where x can be (A..K) to select the GPIO peripheral. 00298 * @param GPIO_Pin: specifies the port bit to be written. 00299 * This parameter can be one of GPIO_PIN_x where x can be (0..15). 00300 * @retval None 00301 */ 00302 void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin) 00303 { 00304 uint32_t position = 0x00U; 00305 uint32_t iocurrent; 00306 uint32_t tmp; 00307 EXTI_Core_TypeDef *EXTI_CurrentCPU; 00308 00309 #if defined(DUAL_CORE) && defined(CORE_CM4) 00310 EXTI_CurrentCPU = EXTI_D2; /* EXTI for CM4 CPU */ 00311 #else 00312 EXTI_CurrentCPU = EXTI_D1; /* EXTI for CM7 CPU */ 00313 #endif 00314 00315 /* Check the parameters */ 00316 assert_param(IS_GPIO_ALL_INSTANCE(GPIOx)); 00317 assert_param(IS_GPIO_PIN(GPIO_Pin)); 00318 00319 /* Configure the port pins */ 00320 while ((GPIO_Pin >> position) != 0x00U) 00321 { 00322 /* Get current io position */ 00323 iocurrent = GPIO_Pin & (1UL << position) ; 00324 00325 if (iocurrent != 0x00U) 00326 { 00327 /*------------------------- EXTI Mode Configuration --------------------*/ 00328 /* Clear the External Interrupt or Event for the current IO */ 00329 tmp = SYSCFG->EXTICR[position >> 2U]; 00330 tmp &= (0x0FUL << (4U * (position & 0x03U))); 00331 if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U)))) 00332 { 00333 /* Clear EXTI line configuration for Current CPU */ 00334 EXTI_CurrentCPU->IMR1 &= ~(iocurrent); 00335 EXTI_CurrentCPU->EMR1 &= ~(iocurrent); 00336 00337 /* Clear Rising Falling edge configuration */ 00338 EXTI->FTSR1 &= ~(iocurrent); 00339 EXTI->RTSR1 &= ~(iocurrent); 00340 00341 tmp = 0x0FUL << (4U * (position & 0x03U)); 00342 SYSCFG->EXTICR[position >> 2U] &= ~tmp; 00343 } 00344 00345 /*------------------------- GPIO Mode Configuration --------------------*/ 00346 /* Configure IO in Analog Mode */ 00347 GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2U)); 00348 00349 /* Configure the default Alternate Function in current IO */ 00350 GPIOx->AFR[position >> 3U] &= ~(0xFU << ((position & 0x07U) * 4U)) ; 00351 00352 /* Deactivate the Pull-up and Pull-down resistor for the current IO */ 00353 GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2U)); 00354 00355 /* Configure the default value IO Output Type */ 00356 GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ; 00357 00358 /* Configure the default value for IO Speed */ 00359 GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U)); 00360 } 00361 00362 position++; 00363 } 00364 } 00365 00366 /** 00367 * @} 00368 */ 00369 00370 /** @defgroup GPIO_Exported_Functions_Group2 IO operation functions 00371 * @brief GPIO Read, Write, Toggle, Lock and EXTI management functions. 00372 * 00373 @verbatim 00374 =============================================================================== 00375 ##### IO operation functions ##### 00376 =============================================================================== 00377 00378 @endverbatim 00379 * @{ 00380 */ 00381 00382 /** 00383 * @brief Reads the specified input port pin. 00384 * @param GPIOx: where x can be (A..K) to select the GPIO peripheral. 00385 * @param GPIO_Pin: specifies the port bit to read. 00386 * This parameter can be GPIO_PIN_x where x can be (0..15). 00387 * @retval The input port pin value. 00388 */ 00389 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 00390 { 00391 GPIO_PinState bitstatus; 00392 00393 /* Check the parameters */ 00394 assert_param(IS_GPIO_PIN(GPIO_Pin)); 00395 00396 if ((GPIOx->IDR & GPIO_Pin) != 0x00U) 00397 { 00398 bitstatus = GPIO_PIN_SET; 00399 } 00400 else 00401 { 00402 bitstatus = GPIO_PIN_RESET; 00403 } 00404 return bitstatus; 00405 } 00406 00407 /** 00408 * @brief Sets or clears the selected data port bit. 00409 * 00410 * @note This function uses GPIOx_BSRR register to allow atomic read/modify 00411 * accesses. In this way, there is no risk of an IRQ occurring between 00412 * the read and the modify access. 00413 * 00414 * @param GPIOx: where x can be (A..K) to select the GPIO peripheral. 00415 * @param GPIO_Pin: specifies the port bit to be written. 00416 * This parameter can be one of GPIO_PIN_x where x can be (0..15). 00417 * @param PinState: specifies the value to be written to the selected bit. 00418 * This parameter can be one of the GPIO_PinState enum values: 00419 * @arg GPIO_PIN_RESET: to clear the port pin 00420 * @arg GPIO_PIN_SET: to set the port pin 00421 * @retval None 00422 */ 00423 void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState) 00424 { 00425 /* Check the parameters */ 00426 assert_param(IS_GPIO_PIN(GPIO_Pin)); 00427 assert_param(IS_GPIO_PIN_ACTION(PinState)); 00428 00429 if (PinState != GPIO_PIN_RESET) 00430 { 00431 GPIOx->BSRR = GPIO_Pin; 00432 } 00433 else 00434 { 00435 GPIOx->BSRR = (uint32_t)GPIO_Pin << GPIO_NUMBER; 00436 } 00437 } 00438 00439 /** 00440 * @brief Toggles the specified GPIO pins. 00441 * @param GPIOx: Where x can be (A..K) to select the GPIO peripheral. 00442 * @param GPIO_Pin: Specifies the pins to be toggled. 00443 * @retval None 00444 */ 00445 void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 00446 { 00447 uint32_t odr; 00448 00449 /* Check the parameters */ 00450 assert_param(IS_GPIO_PIN(GPIO_Pin)); 00451 00452 /* get current Output Data Register value */ 00453 odr = GPIOx->ODR; 00454 00455 /* Set selected pins that were at low level, and reset ones that were high */ 00456 GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin); 00457 } 00458 00459 /** 00460 * @brief Locks GPIO Pins configuration registers. 00461 * @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, 00462 * GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH. 00463 * @note The configuration of the locked GPIO pins can no longer be modified 00464 * until the next reset. 00465 * @param GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32H7 family 00466 * @param GPIO_Pin: specifies the port bit to be locked. 00467 * This parameter can be any combination of GPIO_PIN_x where x can be (0..15). 00468 * @retval None 00469 */ 00470 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) 00471 { 00472 __IO uint32_t tmp = GPIO_LCKR_LCKK; 00473 00474 /* Check the parameters */ 00475 assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx)); 00476 assert_param(IS_GPIO_PIN(GPIO_Pin)); 00477 00478 /* Apply lock key write sequence */ 00479 tmp |= GPIO_Pin; 00480 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ 00481 GPIOx->LCKR = tmp; 00482 /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */ 00483 GPIOx->LCKR = GPIO_Pin; 00484 /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */ 00485 GPIOx->LCKR = tmp; 00486 /* Read LCKK register. This read is mandatory to complete key lock sequence*/ 00487 tmp = GPIOx->LCKR; 00488 00489 /* read again in order to confirm lock is active */ 00490 if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00U) 00491 { 00492 return HAL_OK; 00493 } 00494 else 00495 { 00496 return HAL_ERROR; 00497 } 00498 } 00499 00500 /** 00501 * @brief Handle EXTI interrupt request. 00502 * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line. 00503 * @retval None 00504 */ 00505 void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) 00506 { 00507 #if defined(DUAL_CORE) && defined(CORE_CM4) 00508 if (__HAL_GPIO_EXTID2_GET_IT(GPIO_Pin) != 0x00U) 00509 { 00510 __HAL_GPIO_EXTID2_CLEAR_IT(GPIO_Pin); 00511 HAL_GPIO_EXTI_Callback(GPIO_Pin); 00512 } 00513 #else 00514 /* EXTI line interrupt detected */ 00515 if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00U) 00516 { 00517 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin); 00518 HAL_GPIO_EXTI_Callback(GPIO_Pin); 00519 } 00520 #endif 00521 } 00522 00523 /** 00524 * @brief EXTI line detection callback. 00525 * @param GPIO_Pin: Specifies the port pin connected to corresponding EXTI line. 00526 * @retval None 00527 */ 00528 __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 00529 { 00530 /* Prevent unused argument(s) compilation warning */ 00531 UNUSED(GPIO_Pin); 00532 00533 /* NOTE: This function Should not be modified, when the callback is needed, 00534 the HAL_GPIO_EXTI_Callback could be implemented in the user file 00535 */ 00536 } 00537 00538 /** 00539 * @} 00540 */ 00541 00542 00543 /** 00544 * @} 00545 */ 00546 00547 #endif /* HAL_GPIO_MODULE_ENABLED */ 00548 /** 00549 * @} 00550 */ 00551 00552 /** 00553 * @} 00554 */ 00555