STM32H735xx HAL User Manual
|
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