Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c (15224B)
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, 143 EXTI_ConfigTypeDef *pExtiConfig) 144 { 145 uint32_t regval; 146 uint32_t linepos; 147 uint32_t maskline; 148 149 /* Check null pointer */ 150 if ((hexti == NULL) || (pExtiConfig == NULL)) { 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 assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger)); 168 169 /* Configure rising trigger */ 170 /* Mask or set line */ 171 if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u) { 172 EXTI->RTSR |= maskline; 173 } else { 174 EXTI->RTSR &= ~maskline; 175 } 176 177 /* Configure falling trigger */ 178 /* Mask or set line */ 179 if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u) { 180 EXTI->FTSR |= maskline; 181 } else { 182 EXTI->FTSR &= ~maskline; 183 } 184 185 /* Configure gpio port selection in case of gpio exti line */ 186 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) { 187 assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel)); 188 assert_param(IS_EXTI_GPIO_PIN(linepos)); 189 190 regval = AFIO->EXTICR[linepos >> 2u]; 191 regval &= ~(AFIO_EXTICR1_EXTI0 192 << (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 193 regval |= (pExtiConfig->GPIOSel 194 << (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 195 AFIO->EXTICR[linepos >> 2u] = regval; 196 } 197 } 198 199 /* Configure interrupt mode : read current mode */ 200 /* Mask or set line */ 201 if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u) { 202 EXTI->IMR |= maskline; 203 } else { 204 EXTI->IMR &= ~maskline; 205 } 206 207 /* Configure event mode : read current mode */ 208 /* Mask or set line */ 209 if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u) { 210 EXTI->EMR |= maskline; 211 } else { 212 EXTI->EMR &= ~maskline; 213 } 214 215 return HAL_OK; 216 } 217 218 /** 219 * @brief Get configuration of a dedicated Exti line. 220 * @param hexti Exti handle. 221 * @param pExtiConfig Pointer on structure to store Exti configuration. 222 * @retval HAL Status. 223 */ 224 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, 225 EXTI_ConfigTypeDef *pExtiConfig) 226 { 227 uint32_t regval; 228 uint32_t linepos; 229 uint32_t maskline; 230 231 /* Check null pointer */ 232 if ((hexti == NULL) || (pExtiConfig == NULL)) { 233 return HAL_ERROR; 234 } 235 236 /* Check the parameter */ 237 assert_param(IS_EXTI_LINE(hexti->Line)); 238 239 /* Store handle line number to configuration structure */ 240 pExtiConfig->Line = hexti->Line; 241 242 /* Compute line mask */ 243 linepos = (pExtiConfig->Line & EXTI_PIN_MASK); 244 maskline = (1uL << linepos); 245 246 /* 1] Get core mode : interrupt */ 247 248 /* Check if selected line is enable */ 249 if ((EXTI->IMR & maskline) != 0x00u) { 250 pExtiConfig->Mode = EXTI_MODE_INTERRUPT; 251 } else { 252 pExtiConfig->Mode = EXTI_MODE_NONE; 253 } 254 255 /* Get event mode */ 256 /* Check if selected line is enable */ 257 if ((EXTI->EMR & maskline) != 0x00u) { 258 pExtiConfig->Mode |= EXTI_MODE_EVENT; 259 } 260 261 /* Get default Trigger and GPIOSel configuration */ 262 pExtiConfig->Trigger = EXTI_TRIGGER_NONE; 263 pExtiConfig->GPIOSel = 0x00u; 264 265 /* 2] Get trigger for configurable lines : rising */ 266 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u) { 267 /* Check if configuration of selected line is enable */ 268 if ((EXTI->RTSR & maskline) != 0x00u) { 269 pExtiConfig->Trigger = EXTI_TRIGGER_RISING; 270 } 271 272 /* Get falling configuration */ 273 /* Check if configuration of selected line is enable */ 274 if ((EXTI->FTSR & maskline) != 0x00u) { 275 pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING; 276 } 277 278 /* Get Gpio port selection for gpio lines */ 279 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO) { 280 assert_param(IS_EXTI_GPIO_PIN(linepos)); 281 282 regval = AFIO->EXTICR[linepos >> 2u]; 283 pExtiConfig->GPIOSel = (regval 284 >> (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) 285 & AFIO_EXTICR1_EXTI0; 286 } 287 } 288 289 return HAL_OK; 290 } 291 292 /** 293 * @brief Clear whole configuration of a dedicated Exti line. 294 * @param hexti Exti handle. 295 * @retval HAL Status. 296 */ 297 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti) 298 { 299 uint32_t regval; 300 uint32_t linepos; 301 uint32_t maskline; 302 303 /* Check null pointer */ 304 if (hexti == NULL) { 305 return HAL_ERROR; 306 } 307 308 /* Check the parameter */ 309 assert_param(IS_EXTI_LINE(hexti->Line)); 310 311 /* compute line mask */ 312 linepos = (hexti->Line & EXTI_PIN_MASK); 313 maskline = (1uL << linepos); 314 315 /* 1] Clear interrupt mode */ 316 EXTI->IMR = (EXTI->IMR & ~maskline); 317 318 /* 2] Clear event mode */ 319 EXTI->EMR = (EXTI->EMR & ~maskline); 320 321 /* 3] Clear triggers in case of configurable lines */ 322 if ((hexti->Line & EXTI_CONFIG) != 0x00u) { 323 EXTI->RTSR = (EXTI->RTSR & ~maskline); 324 EXTI->FTSR = (EXTI->FTSR & ~maskline); 325 326 /* Get Gpio port selection for gpio lines */ 327 if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO) { 328 assert_param(IS_EXTI_GPIO_PIN(linepos)); 329 330 regval = AFIO->EXTICR[linepos >> 2u]; 331 regval &= ~(AFIO_EXTICR1_EXTI0 332 << (AFIO_EXTICR1_EXTI1_Pos * (linepos & 0x03u))); 333 AFIO->EXTICR[linepos >> 2u] = regval; 334 } 335 } 336 337 return HAL_OK; 338 } 339 340 /** 341 * @brief Register callback for a dedicated Exti line. 342 * @param hexti Exti handle. 343 * @param CallbackID User callback identifier. 344 * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values. 345 * @param pPendingCbfn function pointer to be stored as callback. 346 * @retval HAL Status. 347 */ 348 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, 349 EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void)) 350 { 351 HAL_StatusTypeDef status = HAL_OK; 352 353 switch (CallbackID) { 354 case HAL_EXTI_COMMON_CB_ID: 355 hexti->PendingCallback = pPendingCbfn; 356 break; 357 358 default: 359 status = HAL_ERROR; 360 break; 361 } 362 363 return status; 364 } 365 366 /** 367 * @brief Store line number as handle private field. 368 * @param hexti Exti handle. 369 * @param ExtiLine Exti line number. 370 * This parameter can be from 0 to @ref EXTI_LINE_NB. 371 * @retval HAL Status. 372 */ 373 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, 374 uint32_t ExtiLine) 375 { 376 /* Check the parameters */ 377 assert_param(IS_EXTI_LINE(ExtiLine)); 378 379 /* Check null pointer */ 380 if (hexti == NULL) { 381 return HAL_ERROR; 382 } else { 383 /* Store line number as handle private field */ 384 hexti->Line = ExtiLine; 385 386 return HAL_OK; 387 } 388 } 389 390 /** 391 * @} 392 */ 393 394 /** @addtogroup EXTI_Exported_Functions_Group2 395 * @brief EXTI IO functions. 396 * 397 @verbatim 398 =============================================================================== 399 ##### IO operation functions ##### 400 =============================================================================== 401 402 @endverbatim 403 * @{ 404 */ 405 406 /** 407 * @brief Handle EXTI interrupt request. 408 * @param hexti Exti handle. 409 * @retval none. 410 */ 411 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti) 412 { 413 uint32_t regval; 414 uint32_t maskline; 415 416 /* Compute line mask */ 417 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 418 419 /* Get pending bit */ 420 regval = (EXTI->PR & maskline); 421 if (regval != 0x00u) { 422 /* Clear pending bit */ 423 EXTI->PR = maskline; 424 425 /* Call callback */ 426 if (hexti->PendingCallback != NULL) { 427 hexti->PendingCallback(); 428 } 429 } 430 } 431 432 /** 433 * @brief Get interrupt pending bit of a dedicated line. 434 * @param hexti Exti handle. 435 * @param Edge Specify which pending edge as to be checked. 436 * This parameter can be one of the following values: 437 * @arg @ref EXTI_TRIGGER_RISING_FALLING 438 * This parameter is kept for compatibility with other series. 439 * @retval 1 if interrupt is pending else 0. 440 */ 441 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) 442 { 443 uint32_t regval; 444 uint32_t maskline; 445 uint32_t linepos; 446 447 /* Check parameters */ 448 assert_param(IS_EXTI_LINE(hexti->Line)); 449 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 450 assert_param(IS_EXTI_PENDING_EDGE(Edge)); 451 452 /* Prevent unused argument compilation warning */ 453 UNUSED(Edge); 454 455 /* Compute line mask */ 456 linepos = (hexti->Line & EXTI_PIN_MASK); 457 maskline = (1uL << linepos); 458 459 /* return 1 if bit is set else 0 */ 460 regval = ((EXTI->PR & maskline) >> linepos); 461 return regval; 462 } 463 464 /** 465 * @brief Clear interrupt pending bit of a dedicated line. 466 * @param hexti Exti handle. 467 * @param Edge Specify which pending edge as to be clear. 468 * This parameter can be one of the following values: 469 * @arg @ref EXTI_TRIGGER_RISING_FALLING 470 * This parameter is kept for compatibility with other series. 471 * @retval None. 472 */ 473 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge) 474 { 475 uint32_t maskline; 476 477 /* Check parameters */ 478 assert_param(IS_EXTI_LINE(hexti->Line)); 479 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 480 assert_param(IS_EXTI_PENDING_EDGE(Edge)); 481 482 /* Prevent unused argument compilation warning */ 483 UNUSED(Edge); 484 485 /* Compute line mask */ 486 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 487 488 /* Clear Pending bit */ 489 EXTI->PR = maskline; 490 } 491 492 /** 493 * @brief Generate a software interrupt for a dedicated line. 494 * @param hexti Exti handle. 495 * @retval None. 496 */ 497 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti) 498 { 499 uint32_t maskline; 500 501 /* Check parameters */ 502 assert_param(IS_EXTI_LINE(hexti->Line)); 503 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line)); 504 505 /* Compute line mask */ 506 maskline = (1uL << (hexti->Line & EXTI_PIN_MASK)); 507 508 /* Generate Software interrupt */ 509 EXTI->SWIER = maskline; 510 } 511 512 /** 513 * @} 514 */ 515 516 /** 517 * @} 518 */ 519 520 #endif /* HAL_EXTI_MODULE_ENABLED */ 521 /** 522 * @} 523 */ 524 525 /** 526 * @} 527 */ 528
