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