Back to home page

LXR

 
 

    


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

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_exti.c
0004   * @author  MCD Application Team
0005   * @brief   EXTI HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the General Purpose Input/Output (EXTI) 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                     ##### EXTI Peripheral features #####
0025   ==============================================================================
0026   [..]
0027     (+) Each Exti line can be configured within this driver.
0028 
0029     (+) Exti line can be configured in 3 different modes
0030         (++) Interrupt (CORE1 or CORE2 in case of dual core line )
0031         (++) Event (CORE1 or CORE2 in case of dual core line )
0032         (++) a combination of the previous
0033 
0034     (+) Configurable Exti lines can be configured with 3 different triggers
0035         (++) Rising
0036         (++) Falling
0037         (++) Both of them
0038 
0039     (+) When set in interrupt mode, configurable Exti lines have two diffenrents
0040         interrupt pending registers which allow to distinguish which transition
0041         occurs:
0042         (++) Rising edge pending interrupt
0043         (++) Falling
0044 
0045     (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
0046         be selected through multiplexer.
0047 
0048     (+) PendClearSource used to set the D3 Smart Run Domain autoamtic pend clear source.
0049         It is applicable for line with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain).
0050         Value can be one of the following:
0051         (++)  EXTI_D3_PENDCLR_SRC_NONE : no pend clear source is selected :
0052               In this case corresponding bit of D2PMRx register is set to 0
0053                 (+++) On a configurable Line : the D3 domain wakeup signal is
0054                       automatically cleared after after the Delay + Rising Edge detect
0055                 (+++) On a direct Line : the D3 domain wakeup signal is
0056                       cleared after the direct event input signal is cleared
0057 
0058         (++)  EXTI_D3_PENDCLR_SRC_DMACH6 : no pend clear source is selected :
0059               In this case corresponding bit of D2PMRx register is set to 1
0060               and corresponding bits(2) of D3PCRxL/H is set to b00 :
0061                 DMA ch6 event selected as D3 domain pendclear source
0062 
0063         (++)  EXTI_D3_PENDCLR_SRC_DMACH7 : no pend clear source is selected :
0064               In this case corresponding bit of D2PMRx register is set to 1
0065               and corresponding bits(2) of D3PCRxL/H is set to b01 :
0066                 DMA ch7 event selected as D3 domain pendclear source
0067 
0068         (++)  EXTI_D3_PENDCLR_SRC_LPTIM4 : no pend clear source is selected :
0069               In this case corresponding bit of D2PMRx register is set to 1
0070               and corresponding bits(2) of D3PCRxL/H is set to b10 :
0071                 LPTIM4 out selected as D3 domain pendclear source
0072 
0073         (++)  EXTI_D3_PENDCLR_SRC_LPTIM5 : no pend clear source is selected :
0074               In this case corresponding bit of D2PMRx register is set to 1
0075               and corresponding bits(2) of D3PCRxL/H is set to b11 :
0076                 LPTIM5 out selected as D3 domain pendclear source
0077 
0078 
0079                      ##### How to use this driver #####
0080   ==============================================================================
0081   [..]
0082 
0083     (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
0084         (++) Choose the interrupt line number by setting "Line" member from
0085              EXTI_ConfigTypeDef structure.
0086         (++) Configure the interrupt and/or event mode using "Mode" member from
0087              EXTI_ConfigTypeDef structure.
0088         (++) For configurable lines, configure rising and/or falling trigger
0089              "Trigger" member from EXTI_ConfigTypeDef structure.
0090         (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
0091              member from GPIO_InitTypeDef structure.
0092         (++) For Exti lines with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain),
0093              choose gpio D3 PendClearSource using PendClearSource
0094              member from EXTI_PendClear_Source structure.
0095 
0096     (#) Get current Exti configuration of a dedicated line using
0097         HAL_EXTI_GetConfigLine().
0098         (++) Provide exiting handle as parameter.
0099         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
0100 
0101     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_ClearConfigLine().
0102         (++) Provide exiting handle as parameter.
0103 
0104     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
0105         (++) Provide exiting handle as first parameter.
0106         (++) Provide which callback will be registered using one value from
0107              EXTI_CallbackIDTypeDef.
0108         (++) Provide callback function pointer.
0109 
0110     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
0111 
0112     (#) Clear interrupt pending bit using HAL_EXTI_ClearPending().
0113 
0114     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
0115 
0116   @endverbatim
0117   */
0118 
0119 /* Includes ------------------------------------------------------------------*/
0120 #include "stm32h7xx_hal.h"
0121 
0122 /** @addtogroup STM32H7xx_HAL_Driver
0123   * @{
0124   */
0125 
0126 /** @addtogroup EXTI
0127   * @{
0128   */
0129 
0130 #ifdef HAL_EXTI_MODULE_ENABLED
0131 
0132 /* Private typedef -----------------------------------------------------------*/
0133 /* Private defines ------------------------------------------------------------*/
0134 /** @defgroup EXTI_Private_Constants EXTI Private Constants
0135   * @ingroup RTEMSBSPsARMSTM32H7
0136   * @{
0137   */
0138 #define EXTI_MODE_OFFSET                    0x04U   /* 0x10: offset between CPU IMR/EMR registers */
0139 #define EXTI_CONFIG_OFFSET                  0x08U   /* 0x20: offset between CPU Rising/Falling configuration registers */
0140 /**
0141   * @}
0142   */
0143 
0144 /* Private macros ------------------------------------------------------------*/
0145 /* Private variables ---------------------------------------------------------*/
0146 /* Private function prototypes -----------------------------------------------*/
0147 /* Exported functions --------------------------------------------------------*/
0148 
0149 /** @addtogroup EXTI_Exported_Functions
0150   * @{
0151   */
0152 
0153 /** @addtogroup EXTI_Exported_Functions_Group1
0154  *  @brief    Configuration functions
0155  *
0156 @verbatim
0157  ===============================================================================
0158               ##### Configuration functions #####
0159  ===============================================================================
0160 
0161 @endverbatim
0162   * @{
0163   */
0164 
0165 /**
0166   * @brief  Set configuration of a dedicated Exti line.
0167   * @param  hexti Exti handle.
0168   * @param  pExtiConfig Pointer on EXTI configuration to be set.
0169   * @retval HAL Status.
0170   */
0171 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
0172 {
0173   __IO uint32_t *regaddr;
0174   uint32_t regval;
0175   uint32_t linepos;
0176   uint32_t maskline;
0177   uint32_t offset;
0178   uint32_t pcrlinepos;
0179 
0180   /* Check null pointer */
0181   if ((hexti == NULL) || (pExtiConfig == NULL))
0182   {
0183     return HAL_ERROR;
0184   }
0185 
0186   /* Check the parameters */
0187   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
0188   assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
0189 
0190   /* Assign line number to handle */
0191   hexti->Line = pExtiConfig->Line;
0192 
0193   /* compute line register offset and line mask */
0194   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0195   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
0196   maskline = (1UL << linepos);
0197 
0198   /* Configure triggers for configurable lines */
0199   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
0200   {
0201     assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
0202 
0203     /* Configure rising trigger */
0204     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
0205     regval = *regaddr;
0206 
0207     /* Mask or set line */
0208     if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00U)
0209     {
0210       regval |= maskline;
0211     }
0212     else
0213     {
0214       regval &= ~maskline;
0215     }
0216 
0217     /* Store rising trigger mode */
0218     *regaddr = regval;
0219 
0220     /* Configure falling trigger */
0221     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
0222     regval = *regaddr;
0223 
0224     /* Mask or set line */
0225     if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00U)
0226     {
0227       regval |= maskline;
0228     }
0229     else
0230     {
0231       regval &= ~maskline;
0232     }
0233 
0234     /* Store falling trigger mode */
0235     *regaddr = regval;
0236 
0237     /* Configure gpio port selection in case of gpio exti line */
0238     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
0239     {
0240       assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
0241       assert_param(IS_EXTI_GPIO_PIN(linepos));
0242 
0243       regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
0244       regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
0245       regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
0246       SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
0247     }
0248   }
0249 
0250   /* Configure interrupt mode : read current mode */
0251   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
0252   regval = *regaddr;
0253 
0254   /* Mask or set line */
0255   if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00U)
0256   {
0257     regval |= maskline;
0258   }
0259   else
0260   {
0261     regval &= ~maskline;
0262   }
0263 
0264   /* Store interrupt mode */
0265   *regaddr = regval;
0266 
0267   /* The event mode cannot be configured if the line does not support it */
0268   assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
0269 
0270   /* Configure event mode : read current mode */
0271   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
0272   regval = *regaddr;
0273 
0274   /* Mask or set line */
0275   if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00U)
0276   {
0277     regval |= maskline;
0278   }
0279   else
0280   {
0281     regval &= ~maskline;
0282   }
0283 
0284   /* Store event mode */
0285   *regaddr = regval;
0286 
0287 #if defined (DUAL_CORE)
0288   /* Configure interrupt mode for Core2 : read current mode */
0289   regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
0290   regval = *regaddr;
0291 
0292   /* Mask or set line */
0293   if ((pExtiConfig->Mode & EXTI_MODE_CORE2_INTERRUPT) != 0x00U)
0294   {
0295     regval |= maskline;
0296   }
0297   else
0298   {
0299     regval &= ~maskline;
0300   }
0301 
0302   /* Store interrupt mode */
0303   *regaddr = regval;
0304 
0305   /* The event mode cannot be configured if the line does not support it */
0306   assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != EXTI_MODE_CORE2_EVENT));
0307 
0308   /* Configure event mode : read current mode */
0309   regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
0310   regval = *regaddr;
0311 
0312   /* Mask or set line */
0313   if ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != 0x00U)
0314   {
0315     regval |= maskline;
0316   }
0317   else
0318   {
0319     regval &= ~maskline;
0320   }
0321 
0322   /* Store event mode */
0323   *regaddr = regval;
0324 #endif /* DUAL_CORE */
0325 
0326   /* Configure the D3 PendClear source in case of Wakeup target is Any */
0327   if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
0328   {
0329     assert_param(IS_EXTI_D3_PENDCLR_SRC(pExtiConfig->PendClearSource));
0330 
0331     /*Calc the PMR register address for the given line */
0332     regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
0333     regval = *regaddr;
0334 
0335     if(pExtiConfig->PendClearSource == EXTI_D3_PENDCLR_SRC_NONE)
0336     {
0337       /* Clear D3PMRx register for the given line */
0338       regval &= ~maskline;
0339       /* Store D3PMRx register value */
0340       *regaddr = regval;
0341     }
0342     else
0343     {
0344       /* Set D3PMRx register to 1 for the given line */
0345       regval |= maskline;
0346       /* Store D3PMRx register value */
0347       *regaddr = regval;
0348 
0349       if(linepos < 16UL)
0350       {
0351         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
0352         pcrlinepos = 1UL << linepos;
0353       }
0354       else
0355       {
0356         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
0357         pcrlinepos = 1UL << (linepos - 16UL);
0358       }
0359 
0360       regval = (*regaddr & (~(pcrlinepos * pcrlinepos * 3UL))) | (pcrlinepos * pcrlinepos * (pExtiConfig->PendClearSource - 1UL));
0361       *regaddr = regval;
0362     }
0363   }
0364 
0365   return HAL_OK;
0366 }
0367 
0368 
0369 /**
0370   * @brief  Get configuration of a dedicated Exti line.
0371   * @param  hexti Exti handle.
0372   * @param  pExtiConfig Pointer on structure to store Exti configuration.
0373   * @retval HAL Status.
0374   */
0375 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
0376 {
0377   __IO uint32_t *regaddr;
0378   uint32_t regval;
0379   uint32_t linepos;
0380   uint32_t maskline;
0381   uint32_t offset;
0382   uint32_t pcrlinepos;
0383 
0384   /* Check null pointer */
0385   if ((hexti == NULL) || (pExtiConfig == NULL))
0386   {
0387     return HAL_ERROR;
0388   }
0389 
0390   /* Check the parameter */
0391   assert_param(IS_EXTI_LINE(hexti->Line));
0392 
0393   /* Store handle line number to configuration structure */
0394   pExtiConfig->Line = hexti->Line;
0395 
0396   /* compute line register offset and line mask */
0397   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0398   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
0399   maskline = (1UL << linepos);
0400 
0401   /* 1] Get core mode : interrupt */
0402   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
0403   regval = *regaddr;
0404 
0405   pExtiConfig->Mode = EXTI_MODE_NONE;
0406 
0407   /* Check if selected line is enable */
0408   if ((regval & maskline) != 0x00U)
0409   {
0410     pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
0411   }
0412 
0413   /* Get event mode */
0414   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
0415   regval = *regaddr;
0416 
0417   /* Check if selected line is enable */
0418   if ((regval & maskline) != 0x00U)
0419   {
0420     pExtiConfig->Mode |= EXTI_MODE_EVENT;
0421   }
0422 #if defined (DUAL_CORE)
0423   regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
0424   regval = *regaddr;
0425 
0426   /* Check if selected line is enable */
0427   if ((regval & maskline) != 0x00U)
0428   {
0429     pExtiConfig->Mode = EXTI_MODE_CORE2_INTERRUPT;
0430   }
0431 
0432   /* Get event mode */
0433   regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
0434   regval = *regaddr;
0435 
0436   /* Check if selected line is enable */
0437   if ((regval & maskline) != 0x00U)
0438   {
0439     pExtiConfig->Mode |= EXTI_MODE_CORE2_EVENT;
0440   }
0441 #endif /*DUAL_CORE*/
0442 
0443   /* Get default Trigger and GPIOSel configuration */
0444   pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
0445   pExtiConfig->GPIOSel = 0x00U;
0446 
0447   /* 2] Get trigger for configurable lines : rising */
0448   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
0449   {
0450     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
0451     regval = *regaddr;
0452 
0453     /* Check if configuration of selected line is enable */
0454     if ((regval & maskline) != 0x00U)
0455     {
0456       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
0457     }
0458 
0459     /* Get falling configuration */
0460     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
0461     regval = *regaddr;
0462 
0463     /* Check if configuration of selected line is enable */
0464     if ((regval & maskline) != 0x00U)
0465     {
0466       pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
0467     }
0468 
0469     /* Get Gpio port selection for gpio lines */
0470     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
0471     {
0472       assert_param(IS_EXTI_GPIO_PIN(linepos));
0473 
0474       regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
0475       pExtiConfig->GPIOSel = (regval >> (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & SYSCFG_EXTICR1_EXTI0;
0476     }
0477   }
0478 
0479   /* Get default Pend Clear Source */
0480   pExtiConfig->PendClearSource = EXTI_D3_PENDCLR_SRC_NONE;
0481 
0482   /* 3] Get D3 Pend Clear source */
0483   if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
0484   {
0485     regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
0486     if(((*regaddr) & linepos) != 0UL)
0487     {
0488       /* if wakeup target is any and PMR set, the read pend clear source from  D3PCRxL/H */
0489       if(linepos < 16UL)
0490       {
0491         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
0492         pcrlinepos = 1UL << linepos;
0493       }
0494       else
0495       {
0496         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
0497         pcrlinepos = 1UL << (linepos - 16UL);
0498       }
0499 
0500       pExtiConfig->PendClearSource = 1UL + ((*regaddr & (pcrlinepos * pcrlinepos * 3UL)) / (pcrlinepos * pcrlinepos));
0501     }
0502   }
0503 
0504   return HAL_OK;
0505 }
0506 
0507 
0508 /**
0509   * @brief  Clear whole configuration of a dedicated Exti line.
0510   * @param  hexti Exti handle.
0511   * @retval HAL Status.
0512   */
0513 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
0514 {
0515   __IO uint32_t *regaddr;
0516   uint32_t regval;
0517   uint32_t linepos;
0518   uint32_t maskline;
0519   uint32_t offset;
0520   uint32_t pcrlinepos;
0521 
0522   /* Check null pointer */
0523   if (hexti == NULL)
0524   {
0525     return HAL_ERROR;
0526   }
0527 
0528   /* Check the parameter */
0529   assert_param(IS_EXTI_LINE(hexti->Line));
0530 
0531   /* compute line register offset and line mask */
0532   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0533   linepos = (hexti->Line & EXTI_PIN_MASK);
0534   maskline = (1UL << linepos);
0535 
0536   /* 1] Clear interrupt mode */
0537   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
0538   regval = (*regaddr & ~maskline);
0539   *regaddr = regval;
0540 
0541   /* 2] Clear event mode */
0542   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
0543   regval = (*regaddr & ~maskline);
0544   *regaddr = regval;
0545 
0546 #if defined (DUAL_CORE)
0547     /* 1] Clear CM4 interrupt mode */
0548   regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
0549   regval = (*regaddr & ~maskline);
0550   *regaddr = regval;
0551 
0552   /* 2] Clear CM4 event mode */
0553   regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
0554   regval = (*regaddr & ~maskline);
0555   *regaddr = regval;
0556 #endif /* DUAL_CORE */
0557 
0558   /* 3] Clear triggers in case of configurable lines */
0559   if ((hexti->Line & EXTI_CONFIG) != 0x00U)
0560   {
0561     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
0562     regval = (*regaddr & ~maskline);
0563     *regaddr = regval;
0564 
0565     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
0566     regval = (*regaddr & ~maskline);
0567     *regaddr = regval;
0568 
0569     /* Get Gpio port selection for gpio lines */
0570     if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
0571     {
0572       assert_param(IS_EXTI_GPIO_PIN(linepos));
0573 
0574       regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
0575       regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03UL)));
0576       SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
0577     }
0578   }
0579 
0580   /* 4] Clear D3 Config lines */
0581   if ((hexti->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
0582   {
0583     regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
0584     *regaddr = (*regaddr & ~maskline);
0585 
0586     if(linepos < 16UL)
0587     {
0588       regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
0589       pcrlinepos = 1UL << linepos;
0590     }
0591     else
0592     {
0593       regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
0594       pcrlinepos = 1UL << (linepos - 16UL);
0595     }
0596 
0597     /*Clear D3 PendClear source */
0598     *regaddr &= (~(pcrlinepos * pcrlinepos * 3UL));
0599   }
0600 
0601   return HAL_OK;
0602 }
0603 
0604 
0605 /**
0606   * @brief  Register callback for a dedicated Exti line.
0607   * @param  hexti Exti handle.
0608   * @param  CallbackID User callback identifier.
0609   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
0610   * @param  pPendingCbfn function pointer to be stored as callback.
0611   * @retval HAL Status.
0612   */
0613 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
0614 {
0615   HAL_StatusTypeDef status = HAL_OK;
0616 
0617   /* Check null pointer */
0618   if (hexti == NULL)
0619   {
0620     return HAL_ERROR;
0621   }
0622 
0623   switch (CallbackID)
0624   {
0625     case  HAL_EXTI_COMMON_CB_ID:
0626       hexti->PendingCallback = pPendingCbfn;
0627       break;
0628 
0629     default:
0630       status = HAL_ERROR;
0631       break;
0632   }
0633 
0634   return status;
0635 }
0636 
0637 
0638 /**
0639   * @brief  Store line number as handle private field.
0640   * @param  hexti Exti handle.
0641   * @param  ExtiLine Exti line number.
0642   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
0643   * @retval HAL Status.
0644   */
0645 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
0646 {
0647   /* Check the parameters */
0648   assert_param(IS_EXTI_LINE(ExtiLine));
0649 
0650   /* Check null pointer */
0651   if (hexti == NULL)
0652   {
0653     return HAL_ERROR;
0654   }
0655   else
0656   {
0657     /* Store line number as handle private field */
0658     hexti->Line = ExtiLine;
0659 
0660     return HAL_OK;
0661   }
0662 }
0663 
0664 
0665 /**
0666   * @}
0667   */
0668 
0669 /** @addtogroup EXTI_Exported_Functions_Group2
0670  *  @brief EXTI IO functions.
0671  *
0672 @verbatim
0673  ===============================================================================
0674                        ##### IO operation functions #####
0675  ===============================================================================
0676 
0677 @endverbatim
0678   * @{
0679   */
0680 
0681 /**
0682   * @brief  Handle EXTI interrupt request.
0683   * @param  hexti Exti handle.
0684   * @retval none.
0685   */
0686 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
0687 {
0688   __IO uint32_t *regaddr;
0689   uint32_t regval;
0690   uint32_t maskline;
0691   uint32_t offset;
0692 
0693   /* Compute line register offset and line mask */
0694   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0695   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
0696 
0697 #if defined(DUAL_CORE)
0698   if (HAL_GetCurrentCPUID() == CM7_CPUID)
0699   {
0700     /* Get pending register address */
0701     regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
0702   }
0703   else /* Cortex-M4*/
0704   {
0705     /* Get pending register address */
0706     regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
0707   }
0708 #else
0709   regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
0710 #endif /* DUAL_CORE */
0711 
0712   /* Get pending bit  */
0713   regval = (*regaddr & maskline);
0714 
0715   if (regval != 0x00U)
0716   {
0717     /* Clear pending bit */
0718     *regaddr = maskline;
0719 
0720     /* Call callback */
0721     if (hexti->PendingCallback != NULL)
0722     {
0723       hexti->PendingCallback();
0724     }
0725   }
0726 }
0727 
0728 
0729 /**
0730   * @brief  Get interrupt pending bit of a dedicated line.
0731   * @param  hexti Exti handle.
0732   * @param  Edge Specify which pending edge as to be checked.
0733   *         This parameter can be one of the following values:
0734   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
0735   *         This parameter is kept for compatibility with other series.
0736   * @retval 1 if interrupt is pending else 0.
0737   */
0738 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
0739 {
0740   __IO uint32_t *regaddr;
0741   uint32_t regval;
0742   uint32_t linepos;
0743   uint32_t maskline;
0744   uint32_t offset;
0745 
0746   /* Prevent unused argument(s) compilation warning */
0747   UNUSED(Edge);
0748 
0749   /* Check parameters */
0750   assert_param(IS_EXTI_LINE(hexti->Line));
0751   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
0752   assert_param(IS_EXTI_PENDING_EDGE(Edge));
0753 
0754   /* compute line register offset and line mask */
0755   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0756   linepos = (hexti->Line & EXTI_PIN_MASK);
0757   maskline = (1UL << linepos);
0758 
0759 #if defined(DUAL_CORE)
0760   if (HAL_GetCurrentCPUID() == CM7_CPUID)
0761   {
0762     /* Get pending register address */
0763     regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
0764   }
0765   else /* Cortex-M4 */
0766   {
0767     /* Get pending register address */
0768     regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
0769   }
0770 #else
0771   regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
0772 #endif /* DUAL_CORE */
0773 
0774   /* return 1 if bit is set else 0 */
0775   regval = ((*regaddr & maskline) >> linepos);
0776   return regval;
0777 }
0778 
0779 
0780 /**
0781   * @brief  Clear interrupt pending bit of a dedicated line.
0782   * @param  hexti Exti handle.
0783   * @param  Edge Specify which pending edge as to be clear.
0784   *         This parameter can be one of the following values:
0785   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
0786   *         This parameter is kept for compatibility with other series.
0787   * @retval None.
0788   */
0789 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
0790 {
0791   __IO uint32_t *regaddr;
0792   uint32_t maskline;
0793   uint32_t offset;
0794 
0795   /* Prevent unused argument(s) compilation warning */
0796   UNUSED(Edge);
0797 
0798   /* Check parameters */
0799   assert_param(IS_EXTI_LINE(hexti->Line));
0800   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
0801   assert_param(IS_EXTI_PENDING_EDGE(Edge));
0802 
0803   /* compute line register offset and line mask */
0804   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0805   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
0806 
0807 #if defined(DUAL_CORE)
0808   if (HAL_GetCurrentCPUID() == CM7_CPUID)
0809   {
0810     /* Get pending register address */
0811     regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
0812   }
0813   else /* Cortex-M4 */
0814   {
0815     /* Get pending register address */
0816     regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
0817   }
0818 #else
0819   regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
0820 #endif /* DUAL_CORE */
0821 
0822   /* Clear Pending bit */
0823   *regaddr =  maskline;
0824 }
0825 
0826 /**
0827   * @brief  Generate a software interrupt for a dedicated line.
0828   * @param  hexti Exti handle.
0829   * @retval None.
0830   */
0831 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
0832 {
0833   __IO uint32_t *regaddr;
0834   uint32_t maskline;
0835   uint32_t offset;
0836 
0837   /* Check parameters */
0838   assert_param(IS_EXTI_LINE(hexti->Line));
0839   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
0840 
0841   /* compute line register offset and line mask */
0842   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
0843   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
0844 
0845   regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
0846   *regaddr = maskline;
0847 }
0848 
0849 
0850 /**
0851   * @}
0852   */
0853 
0854 /**
0855   * @}
0856   */
0857 
0858 #endif /* HAL_EXTI_MODULE_ENABLED */
0859 /**
0860   * @}
0861   */
0862 
0863 /**
0864   * @}
0865   */
0866