STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_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 Extended Interrupts and events controller (EXTI) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * 00011 ****************************************************************************** 00012 * @attention 00013 * 00014 * Copyright (c) 2018 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 00031 (++) Event 00032 (++) Both of them 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 different 00040 interrupts 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 ##### How to use this driver ##### 00049 ============================================================================== 00050 [..] 00051 00052 (#) Configure the EXTI line using HAL_EXTI_SetConfigLine(). 00053 (++) Choose the interrupt line number by setting "Line" member from 00054 EXTI_ConfigTypeDef structure. 00055 (++) Configure the interrupt and/or event mode using "Mode" member from 00056 EXTI_ConfigTypeDef structure. 00057 (++) For configurable lines, configure rising and/or falling trigger 00058 "Trigger" member from EXTI_ConfigTypeDef structure. 00059 (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel" 00060 member from GPIO_InitTypeDef structure. 00061 00062 (#) Get current Exti configuration of a dedicated line using 00063 HAL_EXTI_GetConfigLine(). 00064 (++) Provide exiting handle as parameter. 00065 (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter. 00066 00067 (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine(). 00068 (++) Provide exiting handle as parameter. 00069 00070 (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback(). 00071 (++) Provide exiting handle as first parameter. 00072 (++) Provide which callback will be registered using one value from 00073 EXTI_CallbackIDTypeDef. 00074 (++) Provide callback function pointer. 00075 00076 (#) Get interrupt pending bit using HAL_EXTI_GetPending(). 00077 00078 (#) Clear interrupt pending bit using HAL_EXTI_GetPending(). 00079 00080 (#) Generate software interrupt using HAL_EXTI_GenerateSWI(). 00081 00082 @endverbatim 00083 */ 00084 00085 /* Includes ------------------------------------------------------------------*/ 00086 #include "stm32l4xx_hal.h" 00087 00088 /** @addtogroup STM32L4xx_HAL_Driver 00089 * @{ 00090 */ 00091 00092 /** @addtogroup EXTI 00093 * @{ 00094 */ 00095 /** MISRA C:2012 deviation rule has been granted for following rule: 00096 * Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out 00097 * of bounds [0,3] in following API : 00098 * HAL_EXTI_SetConfigLine 00099 * HAL_EXTI_GetConfigLine 00100 * HAL_EXTI_ClearConfigLine 00101 */ 00102 00103 #ifdef HAL_EXTI_MODULE_ENABLED 00104 00105 /* Private typedef -----------------------------------------------------------*/ 00106 /* Private defines ------------------------------------------------------------*/ 00107 /** @defgroup EXTI_Private_Constants EXTI Private Constants 00108 * @{ 00109 */ 00110 #define EXTI_MODE_OFFSET 0x08u /* 0x20: offset between MCU IMR/EMR registers */ 00111 #define EXTI_CONFIG_OFFSET 0x08u /* 0x20: offset between MCU Rising/Falling configuration registers */ 00112 /** 00113 * @} 00114 */ 00115 00116 /* Private macros ------------------------------------------------------------*/ 00117 /* Private variables ---------------------------------------------------------*/ 00118 /* Private function prototypes -----------------------------------------------*/ 00119 /* Exported functions --------------------------------------------------------*/ 00120 00121 /** @addtogroup EXTI_Exported_Functions 00122 * @{ 00123 */ 00124 00125 /** @addtogroup EXTI_Exported_Functions_Group1 00126 * @brief Configuration functions 00127 * 00128 @verbatim 00129 =============================================================================== 00130 ##### Configuration functions ##### 00131 =============================================================================== 00132 00133 @endverbatim 00134 * @{ 00135 */ 00136 00137 /** 00138 * @brief Set configuration of a dedicated Exti line. 00139 * @param hexti Exti handle. 00140 * @param pExtiConfig Pointer on EXTI configuration to be set. 00141 * @retval HAL Status. 00142 */ 00143 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) 00144 { 00145 __IO uint32_t *regaddr; 00146 uint32_t regval; 00147 uint32_t linepos; 00148 uint32_t maskline; 00149 uint32_t offset; 00150 00151 /* Check null pointer */ 00152 if ((hexti == NULL) || (pExtiConfig == NULL)) 00153 { 00154 return HAL_ERROR; 00155 } 00156 00157 /* Check parameters */ 00158 assert_param(IS_EXTI_LINE(pExtiConfig->Line)); 00159 assert_param(IS_EXTI_MODE(pExtiConfig->Mode)); 00160 00161 /* Assign line number to handle */ 00162 hexti->Line = pExtiConfig->Line; 00163 00164 /* Compute line register offset and line mask */ 00165 offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00166 linepos = (pExtiConfig->Line & EXTI_PIN_MASK); 00167 maskline = (1uL << linepos); 00168 00169 /* Configure triggers for configurable lines */ 00170 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) 00171 { 00172 assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger)); 00173 00174 /* Configure rising trigger */ 00175 regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); 00176 regval = *regaddr; 00177 00178 /* Mask or set line */ 00179 if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u) 00180 { 00181 regval |= maskline; 00182 } 00183 else 00184 { 00185 regval &= ~maskline; 00186 } 00187 00188 /* Store rising trigger mode */ 00189 *regaddr = regval; 00190 00191 /* Configure falling trigger */ 00192 regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset)); 00193 regval = *regaddr; 00194 00195 /* Mask or set line */ 00196 if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u) 00197 { 00198 regval |= maskline; 00199 } 00200 else 00201 { 00202 regval &= ~maskline; 00203 } 00204 00205 /* Store falling trigger mode */ 00206 *regaddr = regval; 00207 00208 /* Configure gpio port selection in case of gpio exti line */ 00209 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) 00210 { 00211 assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel)); 00212 assert_param(IS_EXTI_GPIO_PIN(linepos)); 00213 00214 regval = SYSCFG->EXTICR[linepos >> 2u]; 00215 regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 00216 regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 00217 SYSCFG->EXTICR[linepos >> 2u] = regval; 00218 } 00219 } 00220 00221 /* Configure interrupt mode : read current mode */ 00222 regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset)); 00223 regval = *regaddr; 00224 00225 /* Mask or set line */ 00226 if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u) 00227 { 00228 regval |= maskline; 00229 } 00230 else 00231 { 00232 regval &= ~maskline; 00233 } 00234 00235 /* Store interrupt mode */ 00236 *regaddr = regval; 00237 00238 /* The event mode cannot be configured if the line does not support it */ 00239 assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT)); 00240 00241 /* Configure event mode : read current mode */ 00242 regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset)); 00243 regval = *regaddr; 00244 00245 /* Mask or set line */ 00246 if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u) 00247 { 00248 regval |= maskline; 00249 } 00250 else 00251 { 00252 regval &= ~maskline; 00253 } 00254 00255 /* Store event mode */ 00256 *regaddr = regval; 00257 00258 return HAL_OK; 00259 } 00260 00261 00262 /** 00263 * @brief Get configuration of a dedicated Exti line. 00264 * @param hexti Exti handle. 00265 * @param pExtiConfig Pointer on structure to store Exti configuration. 00266 * @retval HAL Status. 00267 */ 00268 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) 00269 { 00270 __IO uint32_t *regaddr; 00271 uint32_t regval; 00272 uint32_t linepos; 00273 uint32_t maskline; 00274 uint32_t offset; 00275 00276 /* Check null pointer */ 00277 if ((hexti == NULL) || (pExtiConfig == NULL)) 00278 { 00279 return HAL_ERROR; 00280 } 00281 00282 /* Check the parameter */ 00283 assert_param(IS_EXTI_LINE(hexti->Line)); 00284 00285 /* Store handle line number to configuration structure */ 00286 pExtiConfig->Line = hexti->Line; 00287 00288 /* Compute line register offset and line mask */ 00289 offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00290 linepos = (pExtiConfig->Line & EXTI_PIN_MASK); 00291 maskline = (1uL << linepos); 00292 00293 /* 1] Get core mode : interrupt */ 00294 regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset)); 00295 regval = *regaddr; 00296 00297 /* Check if selected line is enable */ 00298 if ((regval & maskline) != 0x00u) 00299 { 00300 pExtiConfig->Mode = EXTI_MODE_INTERRUPT; 00301 } 00302 else 00303 { 00304 pExtiConfig->Mode = EXTI_MODE_NONE; 00305 } 00306 00307 /* Get event mode */ 00308 regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset)); 00309 regval = *regaddr; 00310 00311 /* Check if selected line is enable */ 00312 if ((regval & maskline) != 0x00u) 00313 { 00314 pExtiConfig->Mode |= EXTI_MODE_EVENT; 00315 } 00316 00317 /* Get default Trigger and GPIOSel configuration */ 00318 pExtiConfig->Trigger = EXTI_TRIGGER_NONE; 00319 pExtiConfig->GPIOSel = 0x00u; 00320 00321 /* 2] Get trigger for configurable lines : rising */ 00322 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) 00323 { 00324 regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); 00325 regval = *regaddr; 00326 00327 /* Check if configuration of selected line is enable */ 00328 if ((regval & maskline) != 0x00u) 00329 { 00330 pExtiConfig->Trigger = EXTI_TRIGGER_RISING; 00331 } 00332 00333 /* Get falling configuration */ 00334 regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset)); 00335 regval = *regaddr; 00336 00337 /* Check if configuration of selected line is enable */ 00338 if ((regval & maskline) != 0x00u) 00339 { 00340 pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING; 00341 } 00342 00343 /* Get Gpio port selection for gpio lines */ 00344 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) 00345 { 00346 assert_param(IS_EXTI_GPIO_PIN(linepos)); 00347 00348 regval = SYSCFG->EXTICR[linepos >> 2u]; 00349 pExtiConfig->GPIOSel = ((regval << (SYSCFG_EXTICR1_EXTI1_Pos * (3uL - (linepos & 0x03u)))) >> 24); 00350 } 00351 } 00352 00353 return HAL_OK; 00354 } 00355 00356 00357 /** 00358 * @brief Clear whole configuration of a dedicated Exti line. 00359 * @param hexti Exti handle. 00360 * @retval HAL Status. 00361 */ 00362 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti) 00363 { 00364 __IO uint32_t *regaddr; 00365 uint32_t regval; 00366 uint32_t linepos; 00367 uint32_t maskline; 00368 uint32_t offset; 00369 00370 /* Check null pointer */ 00371 if (hexti == NULL) 00372 { 00373 return HAL_ERROR; 00374 } 00375 00376 /* Check the parameter */ 00377 assert_param(IS_EXTI_LINE(hexti->Line)); 00378 00379 /* compute line register offset and line mask */ 00380 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00381 linepos = (hexti->Line & EXTI_PIN_MASK); 00382 maskline = (1uL << linepos); 00383 00384 /* 1] Clear interrupt mode */ 00385 regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset)); 00386 regval = (*regaddr & ~maskline); 00387 *regaddr = regval; 00388 00389 /* 2] Clear event mode */ 00390 regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset)); 00391 regval = (*regaddr & ~maskline); 00392 *regaddr = regval; 00393 00394 /* 3] Clear triggers in case of configurable lines */ 00395 if ((hexti->Line & EXTI_CONFIG) != 0x00u) 00396 { 00397 regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset)); 00398 regval = (*regaddr & ~maskline); 00399 *regaddr = regval; 00400 00401 regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset)); 00402 regval = (*regaddr & ~maskline); 00403 *regaddr = regval; 00404 00405 /* Get Gpio port selection for gpio lines */ 00406 if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO) 00407 { 00408 assert_param(IS_EXTI_GPIO_PIN(linepos)); 00409 00410 regval = SYSCFG->EXTICR[linepos >> 2u]; 00411 regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 00412 SYSCFG->EXTICR[linepos >> 2u] = regval; 00413 } 00414 } 00415 00416 return HAL_OK; 00417 } 00418 00419 00420 /** 00421 * @brief Register callback for a dedicated Exti line. 00422 * @param hexti Exti handle. 00423 * @param CallbackID User callback identifier. 00424 * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values. 00425 * @param pPendingCbfn function pointer to be stored as callback. 00426 * @retval HAL Status. 00427 */ 00428 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void)) 00429 { 00430 HAL_StatusTypeDef status = HAL_OK; 00431 00432 switch (CallbackID) 00433 { 00434 case HAL_EXTI_COMMON_CB_ID: 00435 hexti->PendingCallback = pPendingCbfn; 00436 break; 00437 00438 default: 00439 status = HAL_ERROR; 00440 break; 00441 } 00442 00443 return status; 00444 } 00445 00446 00447 /** 00448 * @brief Store line number as handle private field. 00449 * @param hexti Exti handle. 00450 * @param ExtiLine Exti line number. 00451 * This parameter can be from 0 to @ref EXTI_LINE_NB. 00452 * @retval HAL Status. 00453 */ 00454 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine) 00455 { 00456 /* Check the parameters */ 00457 assert_param(IS_EXTI_LINE(ExtiLine)); 00458 00459 /* Check null pointer */ 00460 if (hexti == NULL) 00461 { 00462 return HAL_ERROR; 00463 } 00464 else 00465 { 00466 /* Store line number as handle private field */ 00467 hexti->Line = ExtiLine; 00468 00469 return HAL_OK; 00470 } 00471 } 00472 00473 00474 /** 00475 * @} 00476 */ 00477 00478 /** @addtogroup EXTI_Exported_Functions_Group2 00479 * @brief EXTI IO functions. 00480 * 00481 @verbatim 00482 =============================================================================== 00483 ##### IO operation functions ##### 00484 =============================================================================== 00485 00486 @endverbatim 00487 * @{ 00488 */ 00489 00490 /** 00491 * @brief Handle EXTI interrupt request. 00492 * @param hexti Exti handle. 00493 * @retval none. 00494 */ 00495 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti) 00496 { 00497 __IO uint32_t *regaddr; 00498 uint32_t regval; 00499 uint32_t maskline; 00500 uint32_t offset; 00501 00502 /* Compute line register offset and line mask */ 00503 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00504 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 00505 00506 /* Get pending bit */ 00507 regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset)); 00508 regval = (*regaddr & maskline); 00509 00510 if (regval != 0x00u) 00511 { 00512 /* Clear pending bit */ 00513 *regaddr = maskline; 00514 00515 /* Call callback */ 00516 if (hexti->PendingCallback != NULL) 00517 { 00518 hexti->PendingCallback(); 00519 } 00520 } 00521 } 00522 00523 00524 /** 00525 * @brief Get interrupt pending bit of a dedicated line. 00526 * @param hexti Exti handle. 00527 * @param Edge Specify which pending edge as to be checked. 00528 * This parameter can be one of the following values: 00529 * @arg @ref EXTI_TRIGGER_RISING_FALLING 00530 * This parameter is kept for compatibility with other series. 00531 * @retval 1 if interrupt is pending else 0. 00532 */ 00533 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) 00534 { 00535 __IO uint32_t *regaddr; 00536 uint32_t regval; 00537 uint32_t linepos; 00538 uint32_t maskline; 00539 uint32_t offset; 00540 00541 /* Check parameters */ 00542 assert_param(IS_EXTI_LINE(hexti->Line)); 00543 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 00544 assert_param(IS_EXTI_PENDING_EDGE(Edge)); 00545 00546 /* Compute line register offset and line mask */ 00547 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00548 linepos = (hexti->Line & EXTI_PIN_MASK); 00549 maskline = (1uL << linepos); 00550 00551 /* Get pending bit */ 00552 regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset)); 00553 00554 /* return 1 if bit is set else 0 */ 00555 regval = ((*regaddr & maskline) >> linepos); 00556 return regval; 00557 } 00558 00559 00560 /** 00561 * @brief Clear interrupt pending bit of a dedicated line. 00562 * @param hexti Exti handle. 00563 * @param Edge Specify which pending edge as to be clear. 00564 * This parameter can be one of the following values: 00565 * @arg @ref EXTI_TRIGGER_RISING_FALLING 00566 * This parameter is kept for compatibility with other series. 00567 * @retval None. 00568 */ 00569 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) 00570 { 00571 __IO uint32_t *regaddr; 00572 uint32_t maskline; 00573 uint32_t offset; 00574 00575 /* Check parameters */ 00576 assert_param(IS_EXTI_LINE(hexti->Line)); 00577 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 00578 assert_param(IS_EXTI_PENDING_EDGE(Edge)); 00579 00580 /* compute line register offset and line mask */ 00581 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00582 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 00583 00584 /* Get pending register address */ 00585 regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset)); 00586 00587 /* Clear Pending bit */ 00588 *regaddr = maskline; 00589 } 00590 00591 00592 /** 00593 * @brief Generate a software interrupt for a dedicated line. 00594 * @param hexti Exti handle. 00595 * @retval None. 00596 */ 00597 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti) 00598 { 00599 __IO uint32_t *regaddr; 00600 uint32_t maskline; 00601 uint32_t offset; 00602 00603 /* Check parameters */ 00604 assert_param(IS_EXTI_LINE(hexti->Line)); 00605 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 00606 00607 /* compute line register offset and line mask */ 00608 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT); 00609 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 00610 00611 regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset)); 00612 *regaddr = maskline; 00613 } 00614 00615 00616 /** 00617 * @} 00618 */ 00619 00620 /** 00621 * @} 00622 */ 00623 00624 #endif /* HAL_EXTI_MODULE_ENABLED */ 00625 /** 00626 * @} 00627 */ 00628 00629 /** 00630 * @} 00631 */ 00632