Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_gpio.c
0004   * @author  MCD Application Team
0005   * @brief   GPIO HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the General Purpose Input/Output (GPIO) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *
0011   ******************************************************************************
0012   * @attention
0013   *
0014   * Copyright (c) 2017 STMicroelectronics.
0015   * All rights reserved.
0016   *
0017   * This software is licensed under terms that can be found in the LICENSE file
0018   * in the root directory of this software component.
0019   * If no LICENSE file comes with this software, it is provided AS-IS.
0020   *
0021   ******************************************************************************
0022   @verbatim
0023   ==============================================================================
0024                     ##### GPIO Peripheral features #####
0025   ==============================================================================
0026   [..]
0027     (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
0028         configured by software in several modes:
0029         (++) Input mode
0030         (++) Analog mode
0031         (++) Output mode
0032         (++) Alternate function mode
0033         (++) External interrupt/event lines
0034 
0035     (+) During and just after reset, the alternate functions and external interrupt
0036         lines are not active and the I/O ports are configured in input floating mode.
0037 
0038     (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
0039         activated or not.
0040 
0041     (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull
0042         type and the IO speed can be selected depending on the VDD value.
0043 
0044     (+) The microcontroller IO pins are connected to onboard peripherals/modules through a
0045         multiplexer that allows only one peripheral alternate function (AF) connected
0046        to an IO pin at a time. In this way, there can be no conflict between peripherals
0047        sharing the same IO pin.
0048 
0049     (+) All ports have external interrupt/event capability. To use external interrupt
0050         lines, the port must be configured in input mode. All available GPIO pins are
0051         connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
0052 
0053   The external interrupt/event controller consists of up to 23 edge detectors
0054         (16 lines are connected to GPIO) for generating event/interrupt requests (each
0055         input line can be independently configured to select the type (interrupt or event)
0056         and the corresponding trigger event (rising or falling or both). Each line can
0057         also be masked independently.
0058 
0059                      ##### How to use this driver #####
0060   ==============================================================================
0061   [..]
0062     (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
0063 
0064     (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
0065         (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
0066         (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
0067              structure.
0068         (++) In case of Output or alternate function mode selection: the speed is
0069              configured through "Speed" member from GPIO_InitTypeDef structure.
0070         (++) In alternate mode is selection, the alternate function connected to the IO
0071              is configured through "Alternate" member from GPIO_InitTypeDef structure.
0072         (++) Analog mode is required when a pin is to be used as ADC channel
0073              or DAC output.
0074         (++) In case of external interrupt/event selection the "Mode" member from
0075              GPIO_InitTypeDef structure select the type (interrupt or event) and
0076              the corresponding trigger event (rising or falling or both).
0077 
0078     (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
0079         mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
0080         HAL_NVIC_EnableIRQ().
0081 
0082     (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
0083 
0084     (#) To set/reset the level of a pin configured in output mode use
0085         HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
0086 
0087    (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
0088 
0089 
0090     (#) During and just after reset, the alternate functions are not
0091         active and the GPIO pins are configured in input floating mode (except JTAG
0092         pins).
0093 
0094     (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
0095         (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
0096         priority over the GPIO function.
0097 
0098     (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
0099         general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
0100         The HSE has priority over the GPIO function.
0101 
0102   @endverbatim
0103   ******************************************************************************
0104   */
0105 
0106 /* Includes ------------------------------------------------------------------*/
0107 #include "stm32h7xx_hal.h"
0108 
0109 /** @addtogroup STM32H7xx_HAL_Driver
0110   * @{
0111   */
0112 
0113 /** @defgroup GPIO  GPIO
0114   * @ingroup RTEMSBSPsARMSTM32H7
0115   * @brief GPIO HAL module driver
0116   * @{
0117   */
0118 
0119 #ifdef HAL_GPIO_MODULE_ENABLED
0120 
0121 /* Private typedef -----------------------------------------------------------*/
0122 /* Private defines ------------------------------------------------------------*/
0123 /** @addtogroup GPIO_Private_Constants GPIO Private Constants
0124   * @{
0125   */
0126 
0127 #if defined(DUAL_CORE)
0128 #define EXTI_CPU1             (0x01000000U)
0129 #define EXTI_CPU2             (0x02000000U)
0130 #endif /*DUAL_CORE*/
0131 #define GPIO_NUMBER           (16U)
0132 /**
0133   * @}
0134   */
0135 /* Private macro -------------------------------------------------------------*/
0136 /* Private variables ---------------------------------------------------------*/
0137 /* Private function prototypes -----------------------------------------------*/
0138 /* Private functions ---------------------------------------------------------*/
0139 /* Exported functions --------------------------------------------------------*/
0140 /** @defgroup GPIO_Exported_Functions GPIO Exported Functions
0141   * @ingroup RTEMSBSPsARMSTM32H7
0142   * @{
0143   */
0144 
0145 /** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
0146   * @ingroup RTEMSBSPsARMSTM32H7
0147  *  @brief    Initialization and Configuration functions
0148  *
0149 @verbatim
0150  ===============================================================================
0151               ##### Initialization and de-initialization functions #####
0152  ===============================================================================
0153   [..]
0154     This section provides functions allowing to initialize and de-initialize the GPIOs
0155     to be ready for use.
0156 
0157 @endverbatim
0158   * @{
0159   */
0160 
0161 /**
0162   * @brief  Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
0163   * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
0164   * @param  GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
0165   *         the configuration information for the specified GPIO peripheral.
0166   * @retval None
0167   */
0168 void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
0169 {
0170   uint32_t position = 0x00U;
0171   uint32_t iocurrent;
0172   uint32_t temp;
0173   EXTI_Core_TypeDef *EXTI_CurrentCPU;
0174 
0175 #if defined(DUAL_CORE) && defined(CORE_CM4)
0176   EXTI_CurrentCPU = EXTI_D2; /* EXTI for CM4 CPU */
0177 #else
0178   EXTI_CurrentCPU = EXTI_D1; /* EXTI for CM7 CPU */
0179 #endif
0180 
0181   /* Check the parameters */
0182   assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
0183   assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
0184   assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
0185 
0186   /* Configure the port pins */
0187   while (((GPIO_Init->Pin) >> position) != 0x00U)
0188   {
0189     /* Get current io position */
0190     iocurrent = (GPIO_Init->Pin) & (1UL << position);
0191 
0192     if (iocurrent != 0x00U)
0193     {
0194       /*--------------------- GPIO Mode Configuration ------------------------*/
0195       /* In case of Output or Alternate function mode selection */
0196       if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF))
0197       {
0198         /* Check the Speed parameter */
0199         assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
0200 
0201         /* Configure the IO Speed */
0202         temp = GPIOx->OSPEEDR;
0203         temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U));
0204         temp |= (GPIO_Init->Speed << (position * 2U));
0205         GPIOx->OSPEEDR = temp;
0206 
0207         /* Configure the IO Output Type */
0208         temp = GPIOx->OTYPER;
0209         temp &= ~(GPIO_OTYPER_OT0 << position) ;
0210         temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
0211         GPIOx->OTYPER = temp;
0212       }
0213 
0214       if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG)
0215       {
0216        /* Check the Pull parameter */
0217        assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
0218 
0219       /* Activate the Pull-up or Pull down resistor for the current IO */
0220       temp = GPIOx->PUPDR;
0221       temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
0222       temp |= ((GPIO_Init->Pull) << (position * 2U));
0223       GPIOx->PUPDR = temp;
0224       }
0225 
0226       /* In case of Alternate function mode selection */
0227       if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
0228       {
0229         /* Check the Alternate function parameters */
0230         assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
0231         assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
0232 
0233         /* Configure Alternate function mapped with the current IO */
0234         temp = GPIOx->AFR[position >> 3U];
0235         temp &= ~(0xFU << ((position & 0x07U) * 4U));
0236         temp |= ((GPIO_Init->Alternate) << ((position & 0x07U) * 4U));
0237         GPIOx->AFR[position >> 3U] = temp;
0238       }
0239 
0240       /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
0241       temp = GPIOx->MODER;
0242       temp &= ~(GPIO_MODER_MODE0 << (position * 2U));
0243       temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U));
0244       GPIOx->MODER = temp;
0245 
0246       /*--------------------- EXTI Mode Configuration ------------------------*/
0247       /* Configure the External Interrupt or event for the current IO */
0248       if ((GPIO_Init->Mode & EXTI_MODE) != 0x00U)
0249       {
0250         /* Enable SYSCFG Clock */
0251         __HAL_RCC_SYSCFG_CLK_ENABLE();
0252 
0253         temp = SYSCFG->EXTICR[position >> 2U];
0254         temp &= ~(0x0FUL << (4U * (position & 0x03U)));
0255         temp |= (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U)));
0256         SYSCFG->EXTICR[position >> 2U] = temp;
0257 
0258         /* Clear Rising Falling edge configuration */
0259         temp = EXTI->RTSR1;
0260         temp &= ~(iocurrent);
0261         if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00U)
0262         {
0263           temp |= iocurrent;
0264         }
0265         EXTI->RTSR1 = temp;
0266 
0267         temp = EXTI->FTSR1;
0268         temp &= ~(iocurrent);
0269         if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00U)
0270         {
0271           temp |= iocurrent;
0272         }
0273         EXTI->FTSR1 = temp;
0274 
0275         temp = EXTI_CurrentCPU->EMR1;
0276         temp &= ~(iocurrent);
0277         if ((GPIO_Init->Mode & EXTI_EVT) != 0x00U)
0278         {
0279           temp |= iocurrent;
0280         }
0281         EXTI_CurrentCPU->EMR1 = temp;
0282 
0283         /* Clear EXTI line configuration */
0284         temp = EXTI_CurrentCPU->IMR1;
0285         temp &= ~(iocurrent);
0286         if ((GPIO_Init->Mode & EXTI_IT) != 0x00U)
0287         {
0288           temp |= iocurrent;
0289         }
0290         EXTI_CurrentCPU->IMR1 = temp;
0291       }
0292     }
0293 
0294     position++;
0295   }
0296 }
0297 
0298 /**
0299   * @brief  De-initializes the GPIOx peripheral registers to their default reset values.
0300   * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
0301   * @param  GPIO_Pin: specifies the port bit to be written.
0302   *          This parameter can be one of GPIO_PIN_x where x can be (0..15).
0303   * @retval None
0304   */
0305 void HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin)
0306 {
0307   uint32_t position = 0x00U;
0308   uint32_t iocurrent;
0309   uint32_t tmp;
0310   EXTI_Core_TypeDef *EXTI_CurrentCPU;
0311 
0312 #if defined(DUAL_CORE) && defined(CORE_CM4)
0313   EXTI_CurrentCPU = EXTI_D2; /* EXTI for CM4 CPU */
0314 #else
0315   EXTI_CurrentCPU = EXTI_D1; /* EXTI for CM7 CPU */
0316 #endif
0317 
0318   /* Check the parameters */
0319   assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
0320   assert_param(IS_GPIO_PIN(GPIO_Pin));
0321 
0322   /* Configure the port pins */
0323   while ((GPIO_Pin >> position) != 0x00U)
0324   {
0325     /* Get current io position */
0326     iocurrent = GPIO_Pin & (1UL << position) ;
0327 
0328     if (iocurrent != 0x00U)
0329     {
0330       /*------------------------- EXTI Mode Configuration --------------------*/
0331       /* Clear the External Interrupt or Event for the current IO */
0332       tmp = SYSCFG->EXTICR[position >> 2U];
0333       tmp &= (0x0FUL << (4U * (position & 0x03U)));
0334       if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))))
0335       {
0336         /* Clear EXTI line configuration for Current CPU */
0337         EXTI_CurrentCPU->IMR1 &= ~(iocurrent);
0338         EXTI_CurrentCPU->EMR1 &= ~(iocurrent);
0339 
0340         /* Clear Rising Falling edge configuration */
0341         EXTI->FTSR1 &= ~(iocurrent);
0342         EXTI->RTSR1 &= ~(iocurrent);
0343 
0344         tmp = 0x0FUL << (4U * (position & 0x03U));
0345         SYSCFG->EXTICR[position >> 2U] &= ~tmp;
0346       }
0347 
0348       /*------------------------- GPIO Mode Configuration --------------------*/
0349       /* Configure IO in Analog Mode */
0350       GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2U));
0351 
0352       /* Configure the default Alternate Function in current IO */
0353       GPIOx->AFR[position >> 3U] &= ~(0xFU << ((position & 0x07U) * 4U)) ;
0354 
0355       /* Deactivate the Pull-up and Pull-down resistor for the current IO */
0356       GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
0357 
0358       /* Configure the default value IO Output Type */
0359       GPIOx->OTYPER  &= ~(GPIO_OTYPER_OT0 << position) ;
0360 
0361       /* Configure the default value for IO Speed */
0362       GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U));
0363     }
0364 
0365     position++;
0366   }
0367 }
0368 
0369 /**
0370   * @}
0371   */
0372 
0373 /** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
0374   * @ingroup RTEMSBSPsARMSTM32H7
0375  *  @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
0376  *
0377 @verbatim
0378  ===============================================================================
0379                        ##### IO operation functions #####
0380  ===============================================================================
0381 
0382 @endverbatim
0383   * @{
0384   */
0385 
0386 /**
0387   * @brief  Reads the specified input port pin.
0388   * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
0389   * @param  GPIO_Pin: specifies the port bit to read.
0390   *         This parameter can be GPIO_PIN_x where x can be (0..15).
0391   * @retval The input port pin value.
0392   */
0393 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
0394 {
0395   GPIO_PinState bitstatus;
0396 
0397   /* Check the parameters */
0398   assert_param(IS_GPIO_PIN(GPIO_Pin));
0399 
0400   if ((GPIOx->IDR & GPIO_Pin) != 0x00U)
0401   {
0402     bitstatus = GPIO_PIN_SET;
0403   }
0404   else
0405   {
0406     bitstatus = GPIO_PIN_RESET;
0407   }
0408   return bitstatus;
0409 }
0410 
0411 /**
0412   * @brief  Sets or clears the selected data port bit.
0413   *
0414   * @note   This function uses GPIOx_BSRR register to allow atomic read/modify
0415   *         accesses. In this way, there is no risk of an IRQ occurring between
0416   *         the read and the modify access.
0417   *
0418   * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
0419   * @param  GPIO_Pin: specifies the port bit to be written.
0420   *          This parameter can be one of GPIO_PIN_x where x can be (0..15).
0421   * @param  PinState: specifies the value to be written to the selected bit.
0422   *          This parameter can be one of the GPIO_PinState enum values:
0423   *            @arg GPIO_PIN_RESET: to clear the port pin
0424   *            @arg GPIO_PIN_SET: to set the port pin
0425   * @retval None
0426   */
0427 void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
0428 {
0429   /* Check the parameters */
0430   assert_param(IS_GPIO_PIN(GPIO_Pin));
0431   assert_param(IS_GPIO_PIN_ACTION(PinState));
0432 
0433   if (PinState != GPIO_PIN_RESET)
0434   {
0435     GPIOx->BSRR = GPIO_Pin;
0436   }
0437   else
0438   {
0439     GPIOx->BSRR = (uint32_t)GPIO_Pin << GPIO_NUMBER;
0440   }
0441 }
0442 
0443 /**
0444   * @brief  Toggles the specified GPIO pins.
0445   * @param  GPIOx: Where x can be (A..K) to select the GPIO peripheral.
0446   * @param  GPIO_Pin: Specifies the pins to be toggled.
0447   * @retval None
0448   */
0449 void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
0450 {
0451   uint32_t odr;
0452 
0453   /* Check the parameters */
0454   assert_param(IS_GPIO_PIN(GPIO_Pin));
0455 
0456   /* get current Output Data Register value */
0457   odr = GPIOx->ODR;
0458 
0459   /* Set selected pins that were at low level, and reset ones that were high */
0460   GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
0461 }
0462 
0463 /**
0464   * @brief  Locks GPIO Pins configuration registers.
0465   * @note   The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
0466   *         GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
0467   * @note   The configuration of the locked GPIO pins can no longer be modified
0468   *         until the next reset.
0469   * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32H7 family
0470   * @param  GPIO_Pin: specifies the port bit to be locked.
0471   *         This parameter can be any combination of GPIO_PIN_x where x can be (0..15).
0472   * @retval None
0473   */
0474 HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
0475 {
0476   __IO uint32_t tmp = GPIO_LCKR_LCKK;
0477 
0478   /* Check the parameters */
0479   assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
0480   assert_param(IS_GPIO_PIN(GPIO_Pin));
0481 
0482   /* Apply lock key write sequence */
0483   tmp |= GPIO_Pin;
0484   /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
0485   GPIOx->LCKR = tmp;
0486   /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
0487   GPIOx->LCKR = GPIO_Pin;
0488   /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
0489   GPIOx->LCKR = tmp;
0490   /* Read LCKK register. This read is mandatory to complete key lock sequence*/
0491   tmp = GPIOx->LCKR;
0492 
0493   /* read again in order to confirm lock is active */
0494   if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00U)
0495   {
0496     return HAL_OK;
0497   }
0498   else
0499   {
0500     return HAL_ERROR;
0501   }
0502 }
0503 
0504 /**
0505   * @brief  Handle EXTI interrupt request.
0506   * @param  GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
0507   * @retval None
0508   */
0509 void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
0510 {
0511 #if defined(DUAL_CORE) && defined(CORE_CM4)
0512   if (__HAL_GPIO_EXTID2_GET_IT(GPIO_Pin) != 0x00U)
0513   {
0514     __HAL_GPIO_EXTID2_CLEAR_IT(GPIO_Pin);
0515     HAL_GPIO_EXTI_Callback(GPIO_Pin);
0516   }
0517 #else
0518   /* EXTI line interrupt detected */
0519   if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00U)
0520   {
0521     __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
0522     HAL_GPIO_EXTI_Callback(GPIO_Pin);
0523   }
0524 #endif
0525 }
0526 
0527 /**
0528   * @brief  EXTI line detection callback.
0529   * @param  GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
0530   * @retval None
0531   */
0532 __weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
0533 {
0534   /* Prevent unused argument(s) compilation warning */
0535   UNUSED(GPIO_Pin);
0536 
0537   /* NOTE: This function Should not be modified, when the callback is needed,
0538            the HAL_GPIO_EXTI_Callback could be implemented in the user file
0539    */
0540 }
0541 
0542 /**
0543   * @}
0544   */
0545 
0546 
0547 /**
0548   * @}
0549   */
0550 
0551 #endif /* HAL_GPIO_MODULE_ENABLED */
0552 /**
0553   * @}
0554   */
0555 
0556 /**
0557   * @}
0558   */
0559