firmware-nucleo/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c (15048B)
1 /** 2 ****************************************************************************** 3 * @file stm32f1xx_hal_exti.c 4 * @author MCD Application Team 5 * @brief EXTI HAL module driver. 6 * This file provides firmware functions to manage the following 7 * functionalities of the Extended Interrupts and events controller (EXTI) peripheral: 8 * + Initialization and de-initialization functions 9 * + IO operation functions 10 * 11 ****************************************************************************** 12 * @attention 13 * 14 * Copyright (c) 2019 STMicroelectronics. 15 * All rights reserved. 16 * 17 * This software is licensed under terms that can be found in the LICENSE file 18 * in the root directory of this software component. 19 * If no LICENSE file comes with this software, it is provided AS-IS. 20 * 21 ****************************************************************************** 22 @verbatim 23 ============================================================================== 24 ##### EXTI Peripheral features ##### 25 ============================================================================== 26 [..] 27 (+) Each Exti line can be configured within this driver. 28 29 (+) Exti line can be configured in 3 different modes 30 (++) Interrupt 31 (++) Event 32 (++) Both of them 33 34 (+) Configurable Exti lines can be configured with 3 different triggers 35 (++) Rising 36 (++) Falling 37 (++) Both of them 38 39 (+) When set in interrupt mode, configurable Exti lines have two different 40 interrupts pending registers which allow to distinguish which transition 41 occurs: 42 (++) Rising edge pending interrupt 43 (++) Falling 44 45 (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can 46 be selected through multiplexer. 47 48 ##### How to use this driver ##### 49 ============================================================================== 50 [..] 51 52 (#) Configure the EXTI line using HAL_EXTI_SetConfigLine(). 53 (++) Choose the interrupt line number by setting "Line" member from 54 EXTI_ConfigTypeDef structure. 55 (++) Configure the interrupt and/or event mode using "Mode" member from 56 EXTI_ConfigTypeDef structure. 57 (++) For configurable lines, configure rising and/or falling trigger 58 "Trigger" member from EXTI_ConfigTypeDef structure. 59 (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel" 60 member from GPIO_InitTypeDef structure. 61 62 (#) Get current Exti configuration of a dedicated line using 63 HAL_EXTI_GetConfigLine(). 64 (++) Provide exiting handle as parameter. 65 (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter. 66 67 (#) Clear Exti configuration of a dedicated line using HAL_EXTI_ClearConfigLine(). 68 (++) Provide exiting handle as parameter. 69 70 (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback(). 71 (++) Provide exiting handle as first parameter. 72 (++) Provide which callback will be registered using one value from 73 EXTI_CallbackIDTypeDef. 74 (++) Provide callback function pointer. 75 76 (#) Get interrupt pending bit using HAL_EXTI_GetPending(). 77 78 (#) Clear interrupt pending bit using HAL_EXTI_ClearPending(). 79 80 (#) Generate software interrupt using HAL_EXTI_GenerateSWI(). 81 82 @endverbatim 83 */ 84 85 /* Includes ------------------------------------------------------------------*/ 86 #include "stm32f1xx_hal.h" 87 88 /** @addtogroup STM32F1xx_HAL_Driver 89 * @{ 90 */ 91 92 /** @addtogroup EXTI 93 * @{ 94 */ 95 /** MISRA C:2012 deviation rule has been granted for following rule: 96 * Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out 97 * of bounds [0,3] in following API : 98 * HAL_EXTI_SetConfigLine 99 * HAL_EXTI_GetConfigLine 100 * HAL_EXTI_ClearConfigLine 101 */ 102 103 #ifdef HAL_EXTI_MODULE_ENABLED 104 105 /* Private typedef -----------------------------------------------------------*/ 106 /* Private defines -----------------------------------------------------------*/ 107 /** @defgroup EXTI_Private_Constants EXTI Private Constants 108 * @{ 109 */ 110 111 /** 112 * @} 113 */ 114 115 /* Private macros ------------------------------------------------------------*/ 116 /* Private variables ---------------------------------------------------------*/ 117 /* Private function prototypes -----------------------------------------------*/ 118 /* Exported functions --------------------------------------------------------*/ 119 120 /** @addtogroup EXTI_Exported_Functions 121 * @{ 122 */ 123 124 /** @addtogroup EXTI_Exported_Functions_Group1 125 * @brief Configuration functions 126 * 127 @verbatim 128 =============================================================================== 129 ##### Configuration functions ##### 130 =============================================================================== 131 132 @endverbatim 133 * @{ 134 */ 135 136 /** 137 * @brief Set configuration of a dedicated Exti line. 138 * @param hexti Exti handle. 139 * @param pExtiConfig Pointer on EXTI configuration to be set. 140 * @retval HAL Status. 141 */ 142 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) 143 { 144 uint32_t regval; 145 uint32_t linepos; 146 uint32_t maskline; 147 148 /* Check null pointer */ 149 if ((hexti == NULL) || (pExtiConfig == NULL)) 150 { 151 return HAL_ERROR; 152 } 153 154 /* Check parameters */ 155 assert_param(IS_EXTI_LINE(pExtiConfig->Line)); 156 assert_param(IS_EXTI_MODE(pExtiConfig->Mode)); 157 158 /* Assign line number to handle */ 159 hexti->Line = pExtiConfig->Line; 160 161 /* Compute line mask */ 162 linepos = (pExtiConfig->Line & EXTI_PIN_MASK); 163 maskline = (1uL << linepos); 164 165 /* Configure triggers for configurable lines */ 166 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) 167 { 168 assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger)); 169 170 /* Configure rising trigger */ 171 /* Mask or set line */ 172 if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u) 173 { 174 EXTI->RTSR |= maskline; 175 } 176 else 177 { 178 EXTI->RTSR &= ~maskline; 179 } 180 181 /* Configure falling trigger */ 182 /* Mask or set line */ 183 if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u) 184 { 185 EXTI->FTSR |= maskline; 186 } 187 else 188 { 189 EXTI->FTSR &= ~maskline; 190 } 191 192 193 /* Configure gpio port selection in case of gpio exti line */ 194 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) 195 { 196 assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel)); 197 assert_param(IS_EXTI_GPIO_PIN(linepos)); 198 199 regval = AFIO->EXTICR[linepos >> 2u]; 200 regval &= ~(AFIO_EXTICR1_EXTI0 << (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 201 regval |= (pExtiConfig->GPIOSel << (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 202 AFIO->EXTICR[linepos >> 2u] = regval; 203 } 204 } 205 206 /* Configure interrupt mode : read current mode */ 207 /* Mask or set line */ 208 if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u) 209 { 210 EXTI->IMR |= maskline; 211 } 212 else 213 { 214 EXTI->IMR &= ~maskline; 215 } 216 217 /* Configure event mode : read current mode */ 218 /* Mask or set line */ 219 if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u) 220 { 221 EXTI->EMR |= maskline; 222 } 223 else 224 { 225 EXTI->EMR &= ~maskline; 226 } 227 228 return HAL_OK; 229 } 230 231 /** 232 * @brief Get configuration of a dedicated Exti line. 233 * @param hexti Exti handle. 234 * @param pExtiConfig Pointer on structure to store Exti configuration. 235 * @retval HAL Status. 236 */ 237 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig) 238 { 239 uint32_t regval; 240 uint32_t linepos; 241 uint32_t maskline; 242 243 /* Check null pointer */ 244 if ((hexti == NULL) || (pExtiConfig == NULL)) 245 { 246 return HAL_ERROR; 247 } 248 249 /* Check the parameter */ 250 assert_param(IS_EXTI_LINE(hexti->Line)); 251 252 /* Store handle line number to configuration structure */ 253 pExtiConfig->Line = hexti->Line; 254 255 /* Compute line mask */ 256 linepos = (pExtiConfig->Line & EXTI_PIN_MASK); 257 maskline = (1uL << linepos); 258 259 /* 1] Get core mode : interrupt */ 260 261 /* Check if selected line is enable */ 262 if ((EXTI->IMR & maskline) != 0x00u) 263 { 264 pExtiConfig->Mode = EXTI_MODE_INTERRUPT; 265 } 266 else 267 { 268 pExtiConfig->Mode = EXTI_MODE_NONE; 269 } 270 271 /* Get event mode */ 272 /* Check if selected line is enable */ 273 if ((EXTI->EMR & maskline) != 0x00u) 274 { 275 pExtiConfig->Mode |= EXTI_MODE_EVENT; 276 } 277 278 /* Get default Trigger and GPIOSel configuration */ 279 pExtiConfig->Trigger = EXTI_TRIGGER_NONE; 280 pExtiConfig->GPIOSel = 0x00u; 281 282 /* 2] Get trigger for configurable lines : rising */ 283 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) 284 { 285 /* Check if configuration of selected line is enable */ 286 if ((EXTI->RTSR & maskline) != 0x00u) 287 { 288 pExtiConfig->Trigger = EXTI_TRIGGER_RISING; 289 } 290 291 /* Get falling configuration */ 292 /* Check if configuration of selected line is enable */ 293 if ((EXTI->FTSR & maskline) != 0x00u) 294 { 295 pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING; 296 } 297 298 /* Get Gpio port selection for gpio lines */ 299 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) 300 { 301 assert_param(IS_EXTI_GPIO_PIN(linepos)); 302 303 regval = AFIO->EXTICR[linepos >> 2u]; 304 pExtiConfig->GPIOSel = (regval >> (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & AFIO_EXTICR1_EXTI0; 305 } 306 } 307 308 return HAL_OK; 309 } 310 311 /** 312 * @brief Clear whole configuration of a dedicated Exti line. 313 * @param hexti Exti handle. 314 * @retval HAL Status. 315 */ 316 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti) 317 { 318 uint32_t regval; 319 uint32_t linepos; 320 uint32_t maskline; 321 322 /* Check null pointer */ 323 if (hexti == NULL) 324 { 325 return HAL_ERROR; 326 } 327 328 /* Check the parameter */ 329 assert_param(IS_EXTI_LINE(hexti->Line)); 330 331 /* compute line mask */ 332 linepos = (hexti->Line & EXTI_PIN_MASK); 333 maskline = (1uL << linepos); 334 335 /* 1] Clear interrupt mode */ 336 EXTI->IMR = (EXTI->IMR & ~maskline); 337 338 /* 2] Clear event mode */ 339 EXTI->EMR = (EXTI->EMR & ~maskline); 340 341 /* 3] Clear triggers in case of configurable lines */ 342 if ((hexti->Line & EXTI_CONFIG) != 0x00u) 343 { 344 EXTI->RTSR = (EXTI->RTSR & ~maskline); 345 EXTI->FTSR = (EXTI->FTSR & ~maskline); 346 347 /* Get Gpio port selection for gpio lines */ 348 if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO) 349 { 350 assert_param(IS_EXTI_GPIO_PIN(linepos)); 351 352 regval = AFIO->EXTICR[linepos >> 2u]; 353 regval &= ~(AFIO_EXTICR1_EXTI0 << (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 354 AFIO->EXTICR[linepos >> 2u] = regval; 355 } 356 } 357 358 return HAL_OK; 359 } 360 361 /** 362 * @brief Register callback for a dedicated Exti line. 363 * @param hexti Exti handle. 364 * @param CallbackID User callback identifier. 365 * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values. 366 * @param pPendingCbfn function pointer to be stored as callback. 367 * @retval HAL Status. 368 */ 369 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void)) 370 { 371 HAL_StatusTypeDef status = HAL_OK; 372 373 switch (CallbackID) 374 { 375 case HAL_EXTI_COMMON_CB_ID: 376 hexti->PendingCallback = pPendingCbfn; 377 break; 378 379 default: 380 status = HAL_ERROR; 381 break; 382 } 383 384 return status; 385 } 386 387 /** 388 * @brief Store line number as handle private field. 389 * @param hexti Exti handle. 390 * @param ExtiLine Exti line number. 391 * This parameter can be from 0 to @ref EXTI_LINE_NB. 392 * @retval HAL Status. 393 */ 394 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine) 395 { 396 /* Check the parameters */ 397 assert_param(IS_EXTI_LINE(ExtiLine)); 398 399 /* Check null pointer */ 400 if (hexti == NULL) 401 { 402 return HAL_ERROR; 403 } 404 else 405 { 406 /* Store line number as handle private field */ 407 hexti->Line = ExtiLine; 408 409 return HAL_OK; 410 } 411 } 412 413 /** 414 * @} 415 */ 416 417 /** @addtogroup EXTI_Exported_Functions_Group2 418 * @brief EXTI IO functions. 419 * 420 @verbatim 421 =============================================================================== 422 ##### IO operation functions ##### 423 =============================================================================== 424 425 @endverbatim 426 * @{ 427 */ 428 429 /** 430 * @brief Handle EXTI interrupt request. 431 * @param hexti Exti handle. 432 * @retval none. 433 */ 434 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti) 435 { 436 uint32_t regval; 437 uint32_t maskline; 438 439 /* Compute line mask */ 440 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 441 442 /* Get pending bit */ 443 regval = (EXTI->PR & maskline); 444 if (regval != 0x00u) 445 { 446 /* Clear pending bit */ 447 EXTI->PR = maskline; 448 449 /* Call callback */ 450 if (hexti->PendingCallback != NULL) 451 { 452 hexti->PendingCallback(); 453 } 454 } 455 } 456 457 /** 458 * @brief Get interrupt pending bit of a dedicated line. 459 * @param hexti Exti handle. 460 * @param Edge Specify which pending edge as to be checked. 461 * This parameter can be one of the following values: 462 * @arg @ref EXTI_TRIGGER_RISING_FALLING 463 * This parameter is kept for compatibility with other series. 464 * @retval 1 if interrupt is pending else 0. 465 */ 466 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) 467 { 468 uint32_t regval; 469 uint32_t maskline; 470 uint32_t linepos; 471 472 /* Check parameters */ 473 assert_param(IS_EXTI_LINE(hexti->Line)); 474 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 475 assert_param(IS_EXTI_PENDING_EDGE(Edge)); 476 477 /* Prevent unused argument compilation warning */ 478 UNUSED(Edge); 479 480 /* Compute line mask */ 481 linepos = (hexti->Line & EXTI_PIN_MASK); 482 maskline = (1uL << linepos); 483 484 /* return 1 if bit is set else 0 */ 485 regval = ((EXTI->PR & maskline) >> linepos); 486 return regval; 487 } 488 489 /** 490 * @brief Clear interrupt pending bit of a dedicated line. 491 * @param hexti Exti handle. 492 * @param Edge Specify which pending edge as to be clear. 493 * This parameter can be one of the following values: 494 * @arg @ref EXTI_TRIGGER_RISING_FALLING 495 * This parameter is kept for compatibility with other series. 496 * @retval None. 497 */ 498 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) 499 { 500 uint32_t maskline; 501 502 /* Check parameters */ 503 assert_param(IS_EXTI_LINE(hexti->Line)); 504 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 505 assert_param(IS_EXTI_PENDING_EDGE(Edge)); 506 507 /* Prevent unused argument compilation warning */ 508 UNUSED(Edge); 509 510 /* Compute line mask */ 511 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 512 513 /* Clear Pending bit */ 514 EXTI->PR = maskline; 515 } 516 517 /** 518 * @brief Generate a software interrupt for a dedicated line. 519 * @param hexti Exti handle. 520 * @retval None. 521 */ 522 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti) 523 { 524 uint32_t maskline; 525 526 /* Check parameters */ 527 assert_param(IS_EXTI_LINE(hexti->Line)); 528 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 529 530 /* Compute line mask */ 531 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 532 533 /* Generate Software interrupt */ 534 EXTI->SWIER = maskline; 535 } 536 537 /** 538 * @} 539 */ 540 541 /** 542 * @} 543 */ 544 545 #endif /* HAL_EXTI_MODULE_ENABLED */ 546 /** 547 * @} 548 */ 549 550 /** 551 * @} 552 */ 553
