Merge maintenance-8.x.x fixes into master
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_exti.c
blob07825da4140b204a63e0bd957b93ee4dd13d51ca
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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 General Purpose Input/Output (EXTI) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
11 ******************************************************************************
12 * @attention
14 * Copyright (c) 2017 STMicroelectronics.
15 * All rights reserved.
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.
21 ******************************************************************************
22 @verbatim
23 ==============================================================================
24 ##### EXTI Peripheral features #####
25 ==============================================================================
26 [..]
27 (+) Each Exti line can be configured within this driver.
29 (+) Exti line can be configured in 3 different modes
30 (++) Interrupt (CORE1 or CORE2 in case of dual core line )
31 (++) Event (CORE1 or CORE2 in case of dual core line )
32 (++) a combination of the previous
34 (+) Configurable Exti lines can be configured with 3 different triggers
35 (++) Rising
36 (++) Falling
37 (++) Both of them
39 (+) When set in interrupt mode, configurable Exti lines have two diffenrents
40 interrupt pending registers which allow to distinguish which transition
41 occurs:
42 (++) Rising edge pending interrupt
43 (++) Falling
45 (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
46 be selected through multiplexer.
48 (+) PendClearSource used to set the D3 Smart Run Domain autoamtic pend clear source.
49 It is applicable for line with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain).
50 Value can be one of the following:
51 (++) EXTI_D3_PENDCLR_SRC_NONE : no pend clear source is selected :
52 In this case corresponding bit of D2PMRx register is set to 0
53 (+++) On a configurable Line : the D3 domain wakeup signal is
54 automatically cleared after after the Delay + Rising Edge detect
55 (+++) On a direct Line : the D3 domain wakeup signal is
56 cleared after the direct event input signal is cleared
58 (++) EXTI_D3_PENDCLR_SRC_DMACH6 : no pend clear source is selected :
59 In this case corresponding bit of D2PMRx register is set to 1
60 and corresponding bits(2) of D3PCRxL/H is set to b00 :
61 DMA ch6 event selected as D3 domain pendclear source
63 (++) EXTI_D3_PENDCLR_SRC_DMACH7 : no pend clear source is selected :
64 In this case corresponding bit of D2PMRx register is set to 1
65 and corresponding bits(2) of D3PCRxL/H is set to b01 :
66 DMA ch7 event selected as D3 domain pendclear source
68 (++) EXTI_D3_PENDCLR_SRC_LPTIM4 : no pend clear source is selected :
69 In this case corresponding bit of D2PMRx register is set to 1
70 and corresponding bits(2) of D3PCRxL/H is set to b10 :
71 LPTIM4 out selected as D3 domain pendclear source
73 (++) EXTI_D3_PENDCLR_SRC_LPTIM5 : no pend clear source is selected :
74 In this case corresponding bit of D2PMRx register is set to 1
75 and corresponding bits(2) of D3PCRxL/H is set to b11 :
76 LPTIM5 out selected as D3 domain pendclear source
79 ##### How to use this driver #####
80 ==============================================================================
81 [..]
83 (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
84 (++) Choose the interrupt line number by setting "Line" member from
85 EXTI_ConfigTypeDef structure.
86 (++) Configure the interrupt and/or event mode using "Mode" member from
87 EXTI_ConfigTypeDef structure.
88 (++) For configurable lines, configure rising and/or falling trigger
89 "Trigger" member from EXTI_ConfigTypeDef structure.
90 (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
91 member from GPIO_InitTypeDef structure.
92 (++) For Exti lines with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain),
93 choose gpio D3 PendClearSource using PendClearSource
94 member from EXTI_PendClear_Source structure.
96 (#) Get current Exti configuration of a dedicated line using
97 HAL_EXTI_GetConfigLine().
98 (++) Provide exiting handle as parameter.
99 (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
101 (#) Clear Exti configuration of a dedicated line using HAL_EXTI_ClearConfigLine().
102 (++) Provide exiting handle as parameter.
104 (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
105 (++) Provide exiting handle as first parameter.
106 (++) Provide which callback will be registered using one value from
107 EXTI_CallbackIDTypeDef.
108 (++) Provide callback function pointer.
110 (#) Get interrupt pending bit using HAL_EXTI_GetPending().
112 (#) Clear interrupt pending bit using HAL_EXTI_ClearPending().
114 (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
116 @endverbatim
119 /* Includes ------------------------------------------------------------------*/
120 #include "stm32h7xx_hal.h"
122 /** @addtogroup STM32H7xx_HAL_Driver
123 * @{
126 /** @addtogroup EXTI
127 * @{
130 #ifdef HAL_EXTI_MODULE_ENABLED
132 /* Private typedef -----------------------------------------------------------*/
133 /* Private defines ------------------------------------------------------------*/
134 /** @defgroup EXTI_Private_Constants EXTI Private Constants
135 * @{
137 #define EXTI_MODE_OFFSET 0x04U /* 0x10: offset between CPU IMR/EMR registers */
138 #define EXTI_CONFIG_OFFSET 0x08U /* 0x20: offset between CPU Rising/Falling configuration registers */
140 * @}
143 /* Private macros ------------------------------------------------------------*/
144 /* Private variables ---------------------------------------------------------*/
145 /* Private function prototypes -----------------------------------------------*/
146 /* Exported functions --------------------------------------------------------*/
148 /** @addtogroup EXTI_Exported_Functions
149 * @{
152 /** @addtogroup EXTI_Exported_Functions_Group1
153 * @brief Configuration functions
155 @verbatim
156 ===============================================================================
157 ##### Configuration functions #####
158 ===============================================================================
160 @endverbatim
161 * @{
165 * @brief Set configuration of a dedicated Exti line.
166 * @param hexti Exti handle.
167 * @param pExtiConfig Pointer on EXTI configuration to be set.
168 * @retval HAL Status.
170 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
172 __IO uint32_t *regaddr;
173 uint32_t regval;
174 uint32_t linepos;
175 uint32_t maskline;
176 uint32_t offset;
177 uint32_t pcrlinepos;
179 /* Check null pointer */
180 if ((hexti == NULL) || (pExtiConfig == NULL))
182 return HAL_ERROR;
185 /* Check the parameters */
186 assert_param(IS_EXTI_LINE(pExtiConfig->Line));
187 assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
189 /* Assign line number to handle */
190 hexti->Line = pExtiConfig->Line;
192 /* compute line register offset and line mask */
193 offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
194 linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
195 maskline = (1UL << linepos);
197 /* Configure triggers for configurable lines */
198 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
200 assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
202 /* Configure rising trigger */
203 regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
204 regval = *regaddr;
206 /* Mask or set line */
207 if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00U)
209 regval |= maskline;
211 else
213 regval &= ~maskline;
216 /* Store rising trigger mode */
217 *regaddr = regval;
219 /* Configure falling trigger */
220 regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
221 regval = *regaddr;
223 /* Mask or set line */
224 if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00U)
226 regval |= maskline;
228 else
230 regval &= ~maskline;
233 /* Store falling trigger mode */
234 *regaddr = regval;
236 /* Configure gpio port selection in case of gpio exti line */
237 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
239 assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
240 assert_param(IS_EXTI_GPIO_PIN(linepos));
242 regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
243 regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
244 regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
245 SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
249 /* Configure interrupt mode : read current mode */
250 regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
251 regval = *regaddr;
253 /* Mask or set line */
254 if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00U)
256 regval |= maskline;
258 else
260 regval &= ~maskline;
263 /* Store interrupt mode */
264 *regaddr = regval;
266 /* The event mode cannot be configured if the line does not support it */
267 assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
269 /* Configure event mode : read current mode */
270 regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
271 regval = *regaddr;
273 /* Mask or set line */
274 if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00U)
276 regval |= maskline;
278 else
280 regval &= ~maskline;
283 /* Store event mode */
284 *regaddr = regval;
286 #if defined (DUAL_CORE)
287 /* Configure interrupt mode for Core2 : read current mode */
288 regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
289 regval = *regaddr;
291 /* Mask or set line */
292 if ((pExtiConfig->Mode & EXTI_MODE_CORE2_INTERRUPT) != 0x00U)
294 regval |= maskline;
296 else
298 regval &= ~maskline;
301 /* Store interrupt mode */
302 *regaddr = regval;
304 /* The event mode cannot be configured if the line does not support it */
305 assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != EXTI_MODE_CORE2_EVENT));
307 /* Configure event mode : read current mode */
308 regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
309 regval = *regaddr;
311 /* Mask or set line */
312 if ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != 0x00U)
314 regval |= maskline;
316 else
318 regval &= ~maskline;
321 /* Store event mode */
322 *regaddr = regval;
323 #endif /* DUAL_CORE */
325 /* Configure the D3 PendClear source in case of Wakeup target is Any */
326 if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
328 assert_param(IS_EXTI_D3_PENDCLR_SRC(pExtiConfig->PendClearSource));
330 /*Calc the PMR register address for the given line */
331 regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
332 regval = *regaddr;
334 if(pExtiConfig->PendClearSource == EXTI_D3_PENDCLR_SRC_NONE)
336 /* Clear D3PMRx register for the given line */
337 regval &= ~maskline;
338 /* Store D3PMRx register value */
339 *regaddr = regval;
341 else
343 /* Set D3PMRx register to 1 for the given line */
344 regval |= maskline;
345 /* Store D3PMRx register value */
346 *regaddr = regval;
348 if(linepos < 16UL)
350 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
351 pcrlinepos = 1UL << linepos;
353 else
355 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
356 pcrlinepos = 1UL << (linepos - 16UL);
359 regval = (*regaddr & (~(pcrlinepos * pcrlinepos * 3UL))) | (pcrlinepos * pcrlinepos * (pExtiConfig->PendClearSource - 1UL));
360 *regaddr = regval;
364 return HAL_OK;
369 * @brief Get configuration of a dedicated Exti line.
370 * @param hexti Exti handle.
371 * @param pExtiConfig Pointer on structure to store Exti configuration.
372 * @retval HAL Status.
374 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
376 __IO uint32_t *regaddr;
377 uint32_t regval;
378 uint32_t linepos;
379 uint32_t maskline;
380 uint32_t offset;
381 uint32_t pcrlinepos;
383 /* Check null pointer */
384 if ((hexti == NULL) || (pExtiConfig == NULL))
386 return HAL_ERROR;
389 /* Check the parameter */
390 assert_param(IS_EXTI_LINE(hexti->Line));
392 /* Store handle line number to configuration structure */
393 pExtiConfig->Line = hexti->Line;
395 /* compute line register offset and line mask */
396 offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
397 linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
398 maskline = (1UL << linepos);
400 /* 1] Get core mode : interrupt */
401 regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
402 regval = *regaddr;
404 pExtiConfig->Mode = EXTI_MODE_NONE;
406 /* Check if selected line is enable */
407 if ((regval & maskline) != 0x00U)
409 pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
412 /* Get event mode */
413 regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
414 regval = *regaddr;
416 /* Check if selected line is enable */
417 if ((regval & maskline) != 0x00U)
419 pExtiConfig->Mode |= EXTI_MODE_EVENT;
421 #if defined (DUAL_CORE)
422 regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
423 regval = *regaddr;
425 /* Check if selected line is enable */
426 if ((regval & maskline) != 0x00U)
428 pExtiConfig->Mode = EXTI_MODE_CORE2_INTERRUPT;
431 /* Get event mode */
432 regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
433 regval = *regaddr;
435 /* Check if selected line is enable */
436 if ((regval & maskline) != 0x00U)
438 pExtiConfig->Mode |= EXTI_MODE_CORE2_EVENT;
440 #endif /*DUAL_CORE*/
442 /* Get default Trigger and GPIOSel configuration */
443 pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
444 pExtiConfig->GPIOSel = 0x00U;
446 /* 2] Get trigger for configurable lines : rising */
447 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
449 regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
450 regval = *regaddr;
452 /* Check if configuration of selected line is enable */
453 if ((regval & maskline) != 0x00U)
455 pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
458 /* Get falling configuration */
459 regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
460 regval = *regaddr;
462 /* Check if configuration of selected line is enable */
463 if ((regval & maskline) != 0x00U)
465 pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
468 /* Get Gpio port selection for gpio lines */
469 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
471 assert_param(IS_EXTI_GPIO_PIN(linepos));
473 regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
474 pExtiConfig->GPIOSel = (regval >> (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & SYSCFG_EXTICR1_EXTI0;
478 /* Get default Pend Clear Source */
479 pExtiConfig->PendClearSource = EXTI_D3_PENDCLR_SRC_NONE;
481 /* 3] Get D3 Pend Clear source */
482 if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
484 regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
485 if(((*regaddr) & linepos) != 0UL)
487 /* if wakeup target is any and PMR set, the read pend clear source from D3PCRxL/H */
488 if(linepos < 16UL)
490 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
491 pcrlinepos = 1UL << linepos;
493 else
495 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
496 pcrlinepos = 1UL << (linepos - 16UL);
499 pExtiConfig->PendClearSource = 1UL + ((*regaddr & (pcrlinepos * pcrlinepos * 3UL)) / (pcrlinepos * pcrlinepos));
503 return HAL_OK;
508 * @brief Clear whole configuration of a dedicated Exti line.
509 * @param hexti Exti handle.
510 * @retval HAL Status.
512 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(const EXTI_HandleTypeDef *hexti)
514 __IO uint32_t *regaddr;
515 uint32_t regval;
516 uint32_t linepos;
517 uint32_t maskline;
518 uint32_t offset;
519 uint32_t pcrlinepos;
521 /* Check null pointer */
522 if (hexti == NULL)
524 return HAL_ERROR;
527 /* Check the parameter */
528 assert_param(IS_EXTI_LINE(hexti->Line));
530 /* compute line register offset and line mask */
531 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
532 linepos = (hexti->Line & EXTI_PIN_MASK);
533 maskline = (1UL << linepos);
535 /* 1] Clear interrupt mode */
536 regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
537 regval = (*regaddr & ~maskline);
538 *regaddr = regval;
540 /* 2] Clear event mode */
541 regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
542 regval = (*regaddr & ~maskline);
543 *regaddr = regval;
545 #if defined (DUAL_CORE)
546 /* 1] Clear CM4 interrupt mode */
547 regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
548 regval = (*regaddr & ~maskline);
549 *regaddr = regval;
551 /* 2] Clear CM4 event mode */
552 regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
553 regval = (*regaddr & ~maskline);
554 *regaddr = regval;
555 #endif /* DUAL_CORE */
557 /* 3] Clear triggers in case of configurable lines */
558 if ((hexti->Line & EXTI_CONFIG) != 0x00U)
560 regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
561 regval = (*regaddr & ~maskline);
562 *regaddr = regval;
564 regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
565 regval = (*regaddr & ~maskline);
566 *regaddr = regval;
568 /* Get Gpio port selection for gpio lines */
569 if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
571 assert_param(IS_EXTI_GPIO_PIN(linepos));
573 regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
574 regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03UL)));
575 SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
579 /* 4] Clear D3 Config lines */
580 if ((hexti->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
582 regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
583 *regaddr = (*regaddr & ~maskline);
585 if(linepos < 16UL)
587 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
588 pcrlinepos = 1UL << linepos;
590 else
592 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
593 pcrlinepos = 1UL << (linepos - 16UL);
596 /*Clear D3 PendClear source */
597 *regaddr &= (~(pcrlinepos * pcrlinepos * 3UL));
600 return HAL_OK;
605 * @brief Register callback for a dedicated Exti line.
606 * @param hexti Exti handle.
607 * @param CallbackID User callback identifier.
608 * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
609 * @param pPendingCbfn function pointer to be stored as callback.
610 * @retval HAL Status.
612 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
614 HAL_StatusTypeDef status = HAL_OK;
616 /* Check null pointer */
617 if (hexti == NULL)
619 return HAL_ERROR;
622 switch (CallbackID)
624 case HAL_EXTI_COMMON_CB_ID:
625 hexti->PendingCallback = pPendingCbfn;
626 break;
628 default:
629 status = HAL_ERROR;
630 break;
633 return status;
638 * @brief Store line number as handle private field.
639 * @param hexti Exti handle.
640 * @param ExtiLine Exti line number.
641 * This parameter can be from 0 to @ref EXTI_LINE_NB.
642 * @retval HAL Status.
644 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
646 /* Check the parameters */
647 assert_param(IS_EXTI_LINE(ExtiLine));
649 /* Check null pointer */
650 if (hexti == NULL)
652 return HAL_ERROR;
654 else
656 /* Store line number as handle private field */
657 hexti->Line = ExtiLine;
659 return HAL_OK;
665 * @}
668 /** @addtogroup EXTI_Exported_Functions_Group2
669 * @brief EXTI IO functions.
671 @verbatim
672 ===============================================================================
673 ##### IO operation functions #####
674 ===============================================================================
676 @endverbatim
677 * @{
681 * @brief Handle EXTI interrupt request.
682 * @param hexti Exti handle.
683 * @retval none.
685 void HAL_EXTI_IRQHandler(const EXTI_HandleTypeDef *hexti)
687 __IO uint32_t *regaddr;
688 uint32_t regval;
689 uint32_t maskline;
690 uint32_t offset;
692 /* Compute line register offset and line mask */
693 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
694 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
696 #if defined(DUAL_CORE)
697 if (HAL_GetCurrentCPUID() == CM7_CPUID)
699 /* Get pending register address */
700 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
702 else /* Cortex-M4*/
704 /* Get pending register address */
705 regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
707 #else
708 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
709 #endif /* DUAL_CORE */
711 /* Get pending bit */
712 regval = (*regaddr & maskline);
714 if (regval != 0x00U)
716 /* Clear pending bit */
717 *regaddr = maskline;
719 /* Call callback */
720 if (hexti->PendingCallback != NULL)
722 hexti->PendingCallback();
729 * @brief Get interrupt pending bit of a dedicated line.
730 * @param hexti Exti handle.
731 * @param Edge Specify which pending edge as to be checked.
732 * This parameter can be one of the following values:
733 * @arg @ref EXTI_TRIGGER_RISING_FALLING
734 * This parameter is kept for compatibility with other series.
735 * @retval 1 if interrupt is pending else 0.
737 uint32_t HAL_EXTI_GetPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
739 const __IO uint32_t *regaddr;
740 uint32_t regval;
741 uint32_t linepos;
742 uint32_t maskline;
743 uint32_t offset;
745 /* Prevent unused argument(s) compilation warning */
746 UNUSED(Edge);
748 /* Check parameters */
749 assert_param(IS_EXTI_LINE(hexti->Line));
750 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
751 assert_param(IS_EXTI_PENDING_EDGE(Edge));
753 /* compute line register offset and line mask */
754 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
755 linepos = (hexti->Line & EXTI_PIN_MASK);
756 maskline = (1UL << linepos);
758 #if defined(DUAL_CORE)
759 if (HAL_GetCurrentCPUID() == CM7_CPUID)
761 /* Get pending register address */
762 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
764 else /* Cortex-M4 */
766 /* Get pending register address */
767 regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
769 #else
770 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
771 #endif /* DUAL_CORE */
773 /* return 1 if bit is set else 0 */
774 regval = ((*regaddr & maskline) >> linepos);
775 return regval;
780 * @brief Clear interrupt pending bit of a dedicated line.
781 * @param hexti Exti handle.
782 * @param Edge Specify which pending edge as to be clear.
783 * This parameter can be one of the following values:
784 * @arg @ref EXTI_TRIGGER_RISING_FALLING
785 * This parameter is kept for compatibility with other series.
786 * @retval None.
788 void HAL_EXTI_ClearPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
790 __IO uint32_t *regaddr;
791 uint32_t maskline;
792 uint32_t offset;
794 /* Prevent unused argument(s) compilation warning */
795 UNUSED(Edge);
797 /* Check parameters */
798 assert_param(IS_EXTI_LINE(hexti->Line));
799 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
800 assert_param(IS_EXTI_PENDING_EDGE(Edge));
802 /* compute line register offset and line mask */
803 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
804 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
806 #if defined(DUAL_CORE)
807 if (HAL_GetCurrentCPUID() == CM7_CPUID)
809 /* Get pending register address */
810 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
812 else /* Cortex-M4 */
814 /* Get pending register address */
815 regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
817 #else
818 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
819 #endif /* DUAL_CORE */
821 /* Clear Pending bit */
822 *regaddr = maskline;
826 * @brief Generate a software interrupt for a dedicated line.
827 * @param hexti Exti handle.
828 * @retval None.
830 void HAL_EXTI_GenerateSWI(const EXTI_HandleTypeDef *hexti)
832 __IO uint32_t *regaddr;
833 uint32_t maskline;
834 uint32_t offset;
836 /* Check parameters */
837 assert_param(IS_EXTI_LINE(hexti->Line));
838 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
840 /* compute line register offset and line mask */
841 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
842 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
844 regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
845 *regaddr = maskline;
850 * @}
854 * @}
857 #endif /* HAL_EXTI_MODULE_ENABLED */
859 * @}
863 * @}