STM32H735xx HAL User Manual
stm32h7xx_hal_exti.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_exti.c
00004   * @author  MCD Application Team
00005   * @brief   EXTI HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the General Purpose Input/Output (EXTI) 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                     ##### EXTI Peripheral features #####
00025   ==============================================================================
00026   [..]
00027     (+) Each Exti line can be configured within this driver.
00028 
00029     (+) Exti line can be configured in 3 different modes
00030         (++) Interrupt (CORE1 or CORE2 in case of dual core line )
00031         (++) Event (CORE1 or CORE2 in case of dual core line )
00032         (++) a combination of the previous
00033 
00034     (+) Configurable Exti lines can be configured with 3 different triggers
00035         (++) Rising
00036         (++) Falling
00037         (++) Both of them
00038 
00039     (+) When set in interrupt mode, configurable Exti lines have two diffenrents
00040         interrupt pending registers which allow to distinguish which transition
00041         occurs:
00042         (++) Rising edge pending interrupt
00043         (++) Falling
00044 
00045     (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
00046         be selected through multiplexer.
00047 
00048     (+) PendClearSource used to set the D3 Smart Run Domain autoamtic pend clear source.
00049         It is applicable for line with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain).
00050         Value can be one of the following:
00051         (++)  EXTI_D3_PENDCLR_SRC_NONE : no pend clear source is selected :
00052               In this case corresponding bit of D2PMRx register is set to 0
00053                 (+++) On a configurable Line : the D3 domain wakeup signal is
00054                       automatically cleared after after the Delay + Rising Edge detect
00055                 (+++) On a direct Line : the D3 domain wakeup signal is
00056                       cleared after the direct event input signal is cleared
00057 
00058         (++)  EXTI_D3_PENDCLR_SRC_DMACH6 : no pend clear source is selected :
00059               In this case corresponding bit of D2PMRx register is set to 1
00060               and corresponding bits(2) of D3PCRxL/H is set to b00 :
00061                 DMA ch6 event selected as D3 domain pendclear source
00062 
00063         (++)  EXTI_D3_PENDCLR_SRC_DMACH7 : no pend clear source is selected :
00064               In this case corresponding bit of D2PMRx register is set to 1
00065               and corresponding bits(2) of D3PCRxL/H is set to b01 :
00066                 DMA ch7 event selected as D3 domain pendclear source
00067 
00068         (++)  EXTI_D3_PENDCLR_SRC_LPTIM4 : no pend clear source is selected :
00069               In this case corresponding bit of D2PMRx register is set to 1
00070               and corresponding bits(2) of D3PCRxL/H is set to b10 :
00071                 LPTIM4 out selected as D3 domain pendclear source
00072 
00073         (++)  EXTI_D3_PENDCLR_SRC_LPTIM5 : no pend clear source is selected :
00074               In this case corresponding bit of D2PMRx register is set to 1
00075               and corresponding bits(2) of D3PCRxL/H is set to b11 :
00076                 LPTIM5 out selected as D3 domain pendclear source
00077 
00078 
00079                      ##### How to use this driver #####
00080   ==============================================================================
00081   [..]
00082 
00083     (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
00084         (++) Choose the interrupt line number by setting "Line" member from
00085              EXTI_ConfigTypeDef structure.
00086         (++) Configure the interrupt and/or event mode using "Mode" member from
00087              EXTI_ConfigTypeDef structure.
00088         (++) For configurable lines, configure rising and/or falling trigger
00089              "Trigger" member from EXTI_ConfigTypeDef structure.
00090         (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
00091              member from GPIO_InitTypeDef structure.
00092         (++) For Exti lines with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain),
00093              choose gpio D3 PendClearSource using PendClearSource
00094              member from EXTI_PendClear_Source structure.
00095 
00096     (#) Get current Exti configuration of a dedicated line using
00097         HAL_EXTI_GetConfigLine().
00098         (++) Provide exiting handle as parameter.
00099         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
00100 
00101     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
00102         (++) Provide exiting handle as parameter.
00103 
00104     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
00105         (++) Provide exiting handle as first parameter.
00106         (++) Provide which callback will be registered using one value from
00107              EXTI_CallbackIDTypeDef.
00108         (++) Provide callback function pointer.
00109 
00110     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
00111 
00112     (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
00113 
00114     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
00115 
00116   @endverbatim
00117   */
00118 
00119 /* Includes ------------------------------------------------------------------*/
00120 #include "stm32h7xx_hal.h"
00121 
00122 /** @addtogroup STM32H7xx_HAL_Driver
00123   * @{
00124   */
00125 
00126 /** @addtogroup EXTI
00127   * @{
00128   */
00129 
00130 #ifdef HAL_EXTI_MODULE_ENABLED
00131 
00132 /* Private typedef -----------------------------------------------------------*/
00133 /* Private defines ------------------------------------------------------------*/
00134 /** @defgroup EXTI_Private_Constants EXTI Private Constants
00135   * @{
00136   */
00137 #define EXTI_MODE_OFFSET                    0x04U   /* 0x10: offset between CPU IMR/EMR registers */
00138 #define EXTI_CONFIG_OFFSET                  0x08U   /* 0x20: offset between CPU Rising/Falling configuration registers */
00139 /**
00140   * @}
00141   */
00142 
00143 /* Private macros ------------------------------------------------------------*/
00144 /* Private variables ---------------------------------------------------------*/
00145 /* Private function prototypes -----------------------------------------------*/
00146 /* Exported functions --------------------------------------------------------*/
00147 
00148 /** @addtogroup EXTI_Exported_Functions
00149   * @{
00150   */
00151 
00152 /** @addtogroup EXTI_Exported_Functions_Group1
00153  *  @brief    Configuration functions
00154  *
00155 @verbatim
00156  ===============================================================================
00157               ##### Configuration functions #####
00158  ===============================================================================
00159 
00160 @endverbatim
00161   * @{
00162   */
00163 
00164 /**
00165   * @brief  Set configuration of a dedicated Exti line.
00166   * @param  hexti Exti handle.
00167   * @param  pExtiConfig Pointer on EXTI configuration to be set.
00168   * @retval HAL Status.
00169   */
00170 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
00171 {
00172   __IO uint32_t *regaddr;
00173   uint32_t regval;
00174   uint32_t linepos;
00175   uint32_t maskline;
00176   uint32_t offset;
00177   uint32_t pcrlinepos;
00178 
00179   /* Check null pointer */
00180   if ((hexti == NULL) || (pExtiConfig == NULL))
00181   {
00182     return HAL_ERROR;
00183   }
00184 
00185   /* Check the parameters */
00186   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
00187   assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
00188 
00189   /* Assign line number to handle */
00190   hexti->Line = pExtiConfig->Line;
00191 
00192   /* compute line register offset and line mask */
00193   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00194   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
00195   maskline = (1UL << linepos);
00196 
00197   /* Configure triggers for configurable lines */
00198   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
00199   {
00200     assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
00201 
00202     /* Configure rising trigger */
00203     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
00204     regval = *regaddr;
00205 
00206     /* Mask or set line */
00207     if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00U)
00208     {
00209       regval |= maskline;
00210     }
00211     else
00212     {
00213       regval &= ~maskline;
00214     }
00215 
00216     /* Store rising trigger mode */
00217     *regaddr = regval;
00218 
00219     /* Configure falling trigger */
00220     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
00221     regval = *regaddr;
00222 
00223     /* Mask or set line */
00224     if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00U)
00225     {
00226       regval |= maskline;
00227     }
00228     else
00229     {
00230       regval &= ~maskline;
00231     }
00232 
00233     /* Store falling trigger mode */
00234     *regaddr = regval;
00235 
00236     /* Configure gpio port selection in case of gpio exti line */
00237     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
00238     {
00239       assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
00240       assert_param(IS_EXTI_GPIO_PIN(linepos));
00241 
00242       regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
00243       regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
00244       regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
00245       SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
00246     }
00247   }
00248 
00249   /* Configure interrupt mode : read current mode */
00250   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
00251   regval = *regaddr;
00252 
00253   /* Mask or set line */
00254   if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00U)
00255   {
00256     regval |= maskline;
00257   }
00258   else
00259   {
00260     regval &= ~maskline;
00261   }
00262 
00263   /* Store interrupt mode */
00264   *regaddr = regval;
00265 
00266   /* The event mode cannot be configured if the line does not support it */
00267   assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
00268 
00269   /* Configure event mode : read current mode */
00270   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
00271   regval = *regaddr;
00272 
00273   /* Mask or set line */
00274   if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00U)
00275   {
00276     regval |= maskline;
00277   }
00278   else
00279   {
00280     regval &= ~maskline;
00281   }
00282 
00283   /* Store event mode */
00284   *regaddr = regval;
00285 
00286 #if defined (DUAL_CORE)
00287   /* Configure interrupt mode for Core2 : read current mode */
00288   regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
00289   regval = *regaddr;
00290 
00291   /* Mask or set line */
00292   if ((pExtiConfig->Mode & EXTI_MODE_CORE2_INTERRUPT) != 0x00U)
00293   {
00294     regval |= maskline;
00295   }
00296   else
00297   {
00298     regval &= ~maskline;
00299   }
00300 
00301   /* Store interrupt mode */
00302   *regaddr = regval;
00303 
00304   /* The event mode cannot be configured if the line does not support it */
00305   assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != EXTI_MODE_CORE2_EVENT));
00306 
00307   /* Configure event mode : read current mode */
00308   regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
00309   regval = *regaddr;
00310 
00311   /* Mask or set line */
00312   if ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != 0x00U)
00313   {
00314     regval |= maskline;
00315   }
00316   else
00317   {
00318     regval &= ~maskline;
00319   }
00320 
00321   /* Store event mode */
00322   *regaddr = regval;
00323 #endif /* DUAL_CORE */
00324 
00325   /* Configure the D3 PendClear source in case of Wakeup target is Any */
00326   if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
00327   {
00328     assert_param(IS_EXTI_D3_PENDCLR_SRC(pExtiConfig->PendClearSource));
00329 
00330     /*Calc the PMR register address for the given line */
00331     regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
00332     regval = *regaddr;
00333 
00334     if(pExtiConfig->PendClearSource == EXTI_D3_PENDCLR_SRC_NONE)
00335     {
00336       /* Clear D3PMRx register for the given line */
00337       regval &= ~maskline;
00338       /* Store D3PMRx register value */
00339       *regaddr = regval;
00340     }
00341     else
00342     {
00343       /* Set D3PMRx register to 1 for the given line */
00344       regval |= maskline;
00345       /* Store D3PMRx register value */
00346       *regaddr = regval;
00347 
00348       if(linepos < 16UL)
00349       {
00350         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
00351         pcrlinepos = 1UL << linepos;
00352       }
00353       else
00354       {
00355         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
00356         pcrlinepos = 1UL << (linepos - 16UL);
00357       }
00358 
00359       regval = (*regaddr & (~(pcrlinepos * pcrlinepos * 3UL))) | (pcrlinepos * pcrlinepos * (pExtiConfig->PendClearSource - 1UL));
00360       *regaddr = regval;
00361     }
00362   }
00363 
00364   return HAL_OK;
00365 }
00366 
00367 
00368 /**
00369   * @brief  Get configuration of a dedicated Exti line.
00370   * @param  hexti Exti handle.
00371   * @param  pExtiConfig Pointer on structure to store Exti configuration.
00372   * @retval HAL Status.
00373   */
00374 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
00375 {
00376   __IO uint32_t *regaddr;
00377   uint32_t regval;
00378   uint32_t linepos;
00379   uint32_t maskline;
00380   uint32_t offset;
00381   uint32_t pcrlinepos;
00382 
00383   /* Check null pointer */
00384   if ((hexti == NULL) || (pExtiConfig == NULL))
00385   {
00386     return HAL_ERROR;
00387   }
00388 
00389   /* Check the parameter */
00390   assert_param(IS_EXTI_LINE(hexti->Line));
00391 
00392   /* Store handle line number to configuration structure */
00393   pExtiConfig->Line = hexti->Line;
00394 
00395   /* compute line register offset and line mask */
00396   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00397   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
00398   maskline = (1UL << linepos);
00399 
00400   /* 1] Get core mode : interrupt */
00401   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
00402   regval = *regaddr;
00403 
00404   pExtiConfig->Mode = EXTI_MODE_NONE;
00405 
00406   /* Check if selected line is enable */
00407   if ((regval & maskline) != 0x00U)
00408   {
00409     pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
00410   }
00411 
00412   /* Get event mode */
00413   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
00414   regval = *regaddr;
00415 
00416   /* Check if selected line is enable */
00417   if ((regval & maskline) != 0x00U)
00418   {
00419     pExtiConfig->Mode |= EXTI_MODE_EVENT;
00420   }
00421 #if defined (DUAL_CORE)
00422   regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
00423   regval = *regaddr;
00424 
00425   /* Check if selected line is enable */
00426   if ((regval & maskline) != 0x00U)
00427   {
00428     pExtiConfig->Mode = EXTI_MODE_CORE2_INTERRUPT;
00429   }
00430 
00431   /* Get event mode */
00432   regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
00433   regval = *regaddr;
00434 
00435   /* Check if selected line is enable */
00436   if ((regval & maskline) != 0x00U)
00437   {
00438     pExtiConfig->Mode |= EXTI_MODE_CORE2_EVENT;
00439   }
00440 #endif /*DUAL_CORE*/
00441 
00442   /* Get default Trigger and GPIOSel configuration */
00443   pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
00444   pExtiConfig->GPIOSel = 0x00U;
00445 
00446   /* 2] Get trigger for configurable lines : rising */
00447   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
00448   {
00449     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
00450     regval = *regaddr;
00451 
00452     /* Check if configuration of selected line is enable */
00453     if ((regval & maskline) != 0x00U)
00454     {
00455       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
00456     }
00457 
00458     /* Get falling configuration */
00459     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
00460     regval = *regaddr;
00461 
00462     /* Check if configuration of selected line is enable */
00463     if ((regval & maskline) != 0x00U)
00464     {
00465       pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
00466     }
00467 
00468     /* Get Gpio port selection for gpio lines */
00469     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
00470     {
00471       assert_param(IS_EXTI_GPIO_PIN(linepos));
00472 
00473       regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
00474       pExtiConfig->GPIOSel = ((regval << (SYSCFG_EXTICR1_EXTI1_Pos * (3UL - (linepos & 0x03UL)))) >> 24U);
00475     }
00476   }
00477 
00478   /* Get default Pend Clear Source */
00479   pExtiConfig->PendClearSource = EXTI_D3_PENDCLR_SRC_NONE;
00480 
00481   /* 3] Get D3 Pend Clear source */
00482   if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
00483   {
00484     regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
00485     if(((*regaddr) & linepos) != 0UL)
00486     {
00487       /* if wakeup target is any and PMR set, the read pend clear source from  D3PCRxL/H */
00488       if(linepos < 16UL)
00489       {
00490         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
00491         pcrlinepos = 1UL << linepos;
00492       }
00493       else
00494       {
00495         regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
00496         pcrlinepos = 1UL << (linepos - 16UL);
00497       }
00498 
00499       pExtiConfig->PendClearSource = 1UL + ((*regaddr & (pcrlinepos * pcrlinepos * 3UL)) / (pcrlinepos * pcrlinepos));
00500     }
00501   }
00502 
00503   return HAL_OK;
00504 }
00505 
00506 
00507 /**
00508   * @brief  Clear whole configuration of a dedicated Exti line.
00509   * @param  hexti Exti handle.
00510   * @retval HAL Status.
00511   */
00512 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
00513 {
00514   __IO uint32_t *regaddr;
00515   uint32_t regval;
00516   uint32_t linepos;
00517   uint32_t maskline;
00518   uint32_t offset;
00519   uint32_t pcrlinepos;
00520 
00521   /* Check null pointer */
00522   if (hexti == NULL)
00523   {
00524     return HAL_ERROR;
00525   }
00526 
00527   /* Check the parameter */
00528   assert_param(IS_EXTI_LINE(hexti->Line));
00529 
00530   /* compute line register offset and line mask */
00531   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00532   linepos = (hexti->Line & EXTI_PIN_MASK);
00533   maskline = (1UL << linepos);
00534 
00535   /* 1] Clear interrupt mode */
00536   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
00537   regval = (*regaddr & ~maskline);
00538   *regaddr = regval;
00539 
00540   /* 2] Clear event mode */
00541   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
00542   regval = (*regaddr & ~maskline);
00543   *regaddr = regval;
00544 
00545 #if defined (DUAL_CORE)
00546     /* 1] Clear CM4 interrupt mode */
00547   regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
00548   regval = (*regaddr & ~maskline);
00549   *regaddr = regval;
00550 
00551   /* 2] Clear CM4 event mode */
00552   regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
00553   regval = (*regaddr & ~maskline);
00554   *regaddr = regval;
00555 #endif /* DUAL_CORE */
00556 
00557   /* 3] Clear triggers in case of configurable lines */
00558   if ((hexti->Line & EXTI_CONFIG) != 0x00U)
00559   {
00560     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
00561     regval = (*regaddr & ~maskline);
00562     *regaddr = regval;
00563 
00564     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
00565     regval = (*regaddr & ~maskline);
00566     *regaddr = regval;
00567 
00568     /* Get Gpio port selection for gpio lines */
00569     if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
00570     {
00571       assert_param(IS_EXTI_GPIO_PIN(linepos));
00572 
00573       regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
00574       regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03UL)));
00575       SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
00576     }
00577   }
00578 
00579   /* 4] Clear D3 Config lines */
00580   if ((hexti->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
00581   {
00582     regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
00583     *regaddr = (*regaddr & ~maskline);
00584 
00585     if(linepos < 16UL)
00586     {
00587       regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
00588       pcrlinepos = 1UL << linepos;
00589     }
00590     else
00591     {
00592       regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
00593       pcrlinepos = 1UL << (linepos - 16UL);
00594     }
00595 
00596     /*Clear D3 PendClear source */
00597     *regaddr &= (~(pcrlinepos * pcrlinepos * 3UL));
00598   }
00599 
00600   return HAL_OK;
00601 }
00602 
00603 
00604 /**
00605   * @brief  Register callback for a dedicated Exti line.
00606   * @param  hexti Exti handle.
00607   * @param  CallbackID User callback identifier.
00608   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
00609   * @param  pPendingCbfn function pointer to be stored as callback.
00610   * @retval HAL Status.
00611   */
00612 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
00613 {
00614   HAL_StatusTypeDef status = HAL_OK;
00615 
00616   /* Check null pointer */
00617   if (hexti == NULL)
00618   {
00619     return HAL_ERROR;
00620   }
00621 
00622   switch (CallbackID)
00623   {
00624     case  HAL_EXTI_COMMON_CB_ID:
00625       hexti->PendingCallback = pPendingCbfn;
00626       break;
00627 
00628     default:
00629       status = HAL_ERROR;
00630       break;
00631   }
00632 
00633   return status;
00634 }
00635 
00636 
00637 /**
00638   * @brief  Store line number as handle private field.
00639   * @param  hexti Exti handle.
00640   * @param  ExtiLine Exti line number.
00641   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
00642   * @retval HAL Status.
00643   */
00644 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
00645 {
00646   /* Check the parameters */
00647   assert_param(IS_EXTI_LINE(ExtiLine));
00648 
00649   /* Check null pointer */
00650   if (hexti == NULL)
00651   {
00652     return HAL_ERROR;
00653   }
00654   else
00655   {
00656     /* Store line number as handle private field */
00657     hexti->Line = ExtiLine;
00658 
00659     return HAL_OK;
00660   }
00661 }
00662 
00663 
00664 /**
00665   * @}
00666   */
00667 
00668 /** @addtogroup EXTI_Exported_Functions_Group2
00669  *  @brief EXTI IO functions.
00670  *
00671 @verbatim
00672  ===============================================================================
00673                        ##### IO operation functions #####
00674  ===============================================================================
00675 
00676 @endverbatim
00677   * @{
00678   */
00679 
00680 /**
00681   * @brief  Handle EXTI interrupt request.
00682   * @param  hexti Exti handle.
00683   * @retval none.
00684   */
00685 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
00686 {
00687   __IO uint32_t *regaddr;
00688   uint32_t regval;
00689   uint32_t maskline;
00690   uint32_t offset;
00691 
00692   /* Compute line register offset and line mask */
00693   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00694   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
00695 
00696 #if defined(DUAL_CORE)
00697   if (HAL_GetCurrentCPUID() == CM7_CPUID)
00698   {
00699     /* Get pending register address */
00700     regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
00701   }
00702   else /* Cortex-M4*/
00703   {
00704     /* Get pending register address */
00705     regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
00706   }
00707 #else
00708   regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
00709 #endif /* DUAL_CORE */
00710 
00711   /* Get pending bit  */
00712   regval = (*regaddr & maskline);
00713 
00714   if (regval != 0x00U)
00715   {
00716     /* Clear pending bit */
00717     *regaddr = maskline;
00718 
00719     /* Call callback */
00720     if (hexti->PendingCallback != NULL)
00721     {
00722       hexti->PendingCallback();
00723     }
00724   }
00725 }
00726 
00727 
00728 /**
00729   * @brief  Get interrupt pending bit of a dedicated line.
00730   * @param  hexti Exti handle.
00731   * @param  Edge Specify which pending edge as to be checked.
00732   *         This parameter can be one of the following values:
00733   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
00734   *         This parameter is kept for compatibility with other series.
00735   * @retval 1 if interrupt is pending else 0.
00736   */
00737 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
00738 {
00739   __IO uint32_t *regaddr;
00740   uint32_t regval;
00741   uint32_t linepos;
00742   uint32_t maskline;
00743   uint32_t offset;
00744 
00745   /* Check parameters */
00746   assert_param(IS_EXTI_LINE(hexti->Line));
00747   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
00748   assert_param(IS_EXTI_PENDING_EDGE(Edge));
00749 
00750   /* compute line register offset and line mask */
00751   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00752   linepos = (hexti->Line & EXTI_PIN_MASK);
00753   maskline = (1UL << linepos);
00754 
00755 #if defined(DUAL_CORE)
00756   if (HAL_GetCurrentCPUID() == CM7_CPUID)
00757   {
00758     /* Get pending register address */
00759     regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
00760   }
00761   else /* Cortex-M4 */
00762   {
00763     /* Get pending register address */
00764     regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
00765   }
00766 #else
00767   regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
00768 #endif /* DUAL_CORE */
00769 
00770   /* return 1 if bit is set else 0 */
00771   regval = ((*regaddr & maskline) >> linepos);
00772   return regval;
00773 }
00774 
00775 
00776 /**
00777   * @brief  Clear interrupt pending bit of a dedicated line.
00778   * @param  hexti Exti handle.
00779   * @param  Edge Specify which pending edge as to be clear.
00780   *         This parameter can be one of the following values:
00781   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
00782   *         This parameter is kept for compatibility with other series.
00783   * @retval None.
00784   */
00785 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
00786 {
00787   __IO uint32_t *regaddr;
00788   uint32_t maskline;
00789   uint32_t offset;
00790 
00791   /* Check parameters */
00792   assert_param(IS_EXTI_LINE(hexti->Line));
00793   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
00794   assert_param(IS_EXTI_PENDING_EDGE(Edge));
00795 
00796   /* compute line register offset and line mask */
00797   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00798   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
00799 
00800 #if defined(DUAL_CORE)
00801   if (HAL_GetCurrentCPUID() == CM7_CPUID)
00802   {
00803     /* Get pending register address */
00804     regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
00805   }
00806   else /* Cortex-M4 */
00807   {
00808     /* Get pending register address */
00809     regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
00810   }
00811 #else
00812   regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
00813 #endif /* DUAL_CORE */
00814 
00815   /* Clear Pending bit */
00816   *regaddr =  maskline;
00817 }
00818 
00819 /**
00820   * @brief  Generate a software interrupt for a dedicated line.
00821   * @param  hexti Exti handle.
00822   * @retval None.
00823   */
00824 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
00825 {
00826   __IO uint32_t *regaddr;
00827   uint32_t maskline;
00828   uint32_t offset;
00829 
00830   /* Check parameters */
00831   assert_param(IS_EXTI_LINE(hexti->Line));
00832   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
00833 
00834   /* compute line register offset and line mask */
00835   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
00836   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
00837 
00838   regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
00839   *regaddr = maskline;
00840 }
00841 
00842 
00843 /**
00844   * @}
00845   */
00846 
00847 /**
00848   * @}
00849   */
00850 
00851 #endif /* HAL_EXTI_MODULE_ENABLED */
00852 /**
00853   * @}
00854   */
00855 
00856 /**
00857   * @}
00858   */
00859