STM32H735xx HAL User Manual
stm32h7xx_hal_gpio.c
Go to the documentation of this file.
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