1 /**
2   ******************************************************************************
3   * @file    stm32wlxx_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
10   ******************************************************************************
11   * @attention
12   *
13   * Copyright (c) 2020 STMicroelectronics.
14   * All rights reserved.
15   *
16   * This software is licensed under terms that can be found in the LICENSE file
17   * in the root directory of this software component.
18   * If no LICENSE file comes with this software, it is provided AS-IS.
19   *
20   ******************************************************************************
21   @verbatim
22   ==============================================================================
23                     ##### EXTI Peripheral features #####
24   ==============================================================================
25   [..]
26     (+) Each Exti line can be configured within this driver.
27 
28     (+) Exti line can be configured in 3 different modes
29         (++) Interrupt
30         (++) Event
31         (++) Both of them
32 
33     (+) Configurable Exti lines can be configured with 3 different triggers
34         (++) Rising
35         (++) Falling
36         (++) Both of them
37 
38     (+) When set in interrupt mode, configurable Exti lines have two diffenrents
39         interrupt pending registers which allow to distinguish which transition
40         occurs:
41         (++) Rising edge pending interrupt
42         (++) Falling
43 
44     (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
45         be selected through multiplexer.
46 
47                      ##### How to use this driver #####
48   ==============================================================================
49   [..]
50 
51     (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
52         (++) Choose the interrupt line number by setting "Line" member from
53              EXTI_ConfigTypeDef structure.
54         (++) Configure the interrupt and/or event mode using "Mode" member from
55              EXTI_ConfigTypeDef structure.
56         (++) For configurable lines, configure rising and/or falling trigger
57              "Trigger" member from EXTI_ConfigTypeDef structure.
58         (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
59              member from GPIO_InitTypeDef structure.
60 
61     (#) Get current Exti configuration of a dedicated line using
62         HAL_EXTI_GetConfigLine().
63         (++) Provide exiting handle as parameter.
64         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
65 
66     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
67         (++) Provide exiting handle as parameter.
68 
69     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
70         (++) Provide exiting handle as first parameter.
71         (++) Provide which callback will be registered using one value from
72              EXTI_CallbackIDTypeDef.
73         (++) Provide callback function pointer.
74 
75     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
76 
77     (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
78 
79     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
80 
81   @endverbatim
82   ******************************************************************************
83   */
84 
85 /* Includes ------------------------------------------------------------------*/
86 #include "stm32wlxx_hal.h"
87 
88 /** @addtogroup STM32WLxx_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 #define EXTI_MODE_OFFSET                    0x04u  /* 0x10: offset between CPU IMR/EMR registers */
111 #define EXTI_CONFIG_OFFSET                  0x08u  /* 0x20: offset between CPU Rising/Falling configuration registers */
112 /**
113   * @}
114   */
115 
116 /* Private macros ------------------------------------------------------------*/
117 /* Private variables ---------------------------------------------------------*/
118 /* Private function prototypes -----------------------------------------------*/
119 /* Exported functions --------------------------------------------------------*/
120 
121 /** @addtogroup EXTI_Exported_Functions
122   * @{
123   */
124 
125 /** @addtogroup EXTI_Exported_Functions_Group1
126   *  @brief    Configuration functions
127   *
128 @verbatim
129  ===============================================================================
130               ##### Configuration functions #####
131  ===============================================================================
132 
133 @endverbatim
134   * @{
135   */
136 
137 /**
138   * @brief  Set configuration of a dedicated Exti line.
139   * @param  hexti Exti handle.
140   * @param  pExtiConfig Pointer on EXTI configuration to be set.
141   * @retval HAL Status.
142   */
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)143 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
144 {
145   __IO uint32_t *regaddr;
146   uint32_t regval;
147   uint32_t linepos;
148   uint32_t maskline;
149   uint32_t offset;
150 
151   /* Check null pointer */
152   if ((hexti == NULL) || (pExtiConfig == NULL))
153   {
154     return HAL_ERROR;
155   }
156 
157   /* Check parameters */
158   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
159   assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
160 
161   /* Assign line number to handle */
162   hexti->Line = pExtiConfig->Line;
163 
164   /* compute line register offset and line mask */
165   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
166   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
167   maskline = (1uL << linepos);
168 
169   /* Configure triggers for configurable lines */
170   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
171   {
172     assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
173 
174     /* Configure rising trigger */
175     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
176     regval = *regaddr;
177 
178     /* Mask or set line */
179     if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u)
180     {
181       regval |= maskline;
182     }
183     else
184     {
185       regval &= ~maskline;
186     }
187 
188     /* Store rising trigger mode */
189     *regaddr = regval;
190 
191     /* Configure falling trigger */
192     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
193     regval = *regaddr;
194 
195     /* Mask or set line */
196     if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u)
197     {
198       regval |= maskline;
199     }
200     else
201     {
202       regval &= ~maskline;
203     }
204 
205     /* Store falling trigger mode */
206     *regaddr = regval;
207 
208     /* Configure gpio port selection in case of gpio exti line */
209     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
210     {
211       assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
212       assert_param(IS_EXTI_GPIO_PIN(linepos));
213 
214       regval = SYSCFG->EXTICR[linepos >> 2u];
215       regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
216       regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
217       SYSCFG->EXTICR[linepos >> 2u] = regval;
218     }
219   }
220 
221   /* Configure interrupt mode : read current mode */
222 #if defined(DUAL_CORE) && defined(CORE_CM0PLUS)
223   regaddr = (&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
224 #else
225   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
226 #endif /* DUAL_CORE && CORE_CM0PLUS */
227   regval = *regaddr;
228 
229   /* Mask or set line */
230   if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u)
231   {
232     regval |= maskline;
233   }
234   else
235   {
236     regval &= ~maskline;
237   }
238 
239   /* Store interrupt mode */
240   *regaddr = regval;
241 
242   /* Configure event mode : read current mode */
243 #if defined(DUAL_CORE) && defined(CORE_CM0PLUS)
244   regaddr = (&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
245 #else
246   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
247 #endif /* DUAL_CORE && CORE_CM0PLUS */
248   regval = *regaddr;
249 
250   /* Mask or set line */
251   if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u)
252   {
253     /* The event mode cannot be configured if the line does not support it */
254     assert_param(IS_EXTI_EVENT_PRESENT(pExtiConfig->Line));
255     regval |= maskline;
256   }
257   else
258   {
259     regval &= ~maskline;
260   }
261 
262   /* Store event mode */
263   *regaddr = regval;
264 
265   return HAL_OK;
266 }
267 
268 
269 /**
270   * @brief  Get configuration of a dedicated Exti line.
271   * @param  hexti Exti handle.
272   * @param  pExtiConfig Pointer on structure to store Exti configuration.
273   * @retval HAL Status.
274   */
HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)275 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
276 {
277   __IO uint32_t *regaddr;
278   uint32_t regval;
279   uint32_t linepos;
280   uint32_t maskline;
281   uint32_t offset;
282 
283   /* Check null pointer */
284   if ((hexti == NULL) || (pExtiConfig == NULL))
285   {
286     return HAL_ERROR;
287   }
288 
289   /* Check the parameter */
290   assert_param(IS_EXTI_LINE(hexti->Line));
291 
292   /* Store handle line number to configuration structure */
293   pExtiConfig->Line = hexti->Line;
294 
295   /* compute line register offset and line mask */
296   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
297   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
298   maskline = (1uL << linepos);
299 
300   /* 1] Get core mode : interrupt */
301 #if defined(DUAL_CORE) && defined(CORE_CM0PLUS)
302   regaddr = (&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
303 #else
304   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
305 #endif /* DUAL_CORE && CORE_CM0PLUS */
306   regval = *regaddr;
307 
308   /* Check if selected line is enable */
309   if ((regval & maskline) != 0x00u)
310   {
311     pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
312   }
313   else
314   {
315     pExtiConfig->Mode = EXTI_MODE_NONE;
316   }
317 
318   /* Get event mode */
319 #if defined(DUAL_CORE) && defined(CORE_CM0PLUS)
320   regaddr = (&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
321 #else
322   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
323 #endif /* DUAL_CORE && CORE_CM0PLUS */
324   regval = *regaddr;
325 
326   /* Check if selected line is enable */
327   if ((regval & maskline) != 0x00u)
328   {
329     pExtiConfig->Mode |= EXTI_MODE_EVENT;
330   }
331 
332   /* Get default Trigger and GPIOSel configuration */
333   pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
334   pExtiConfig->GPIOSel = 0x00u;
335 
336   /* 2] Get trigger for configurable lines : rising */
337   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
338   {
339     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
340     regval = *regaddr;
341 
342     /* Check if configuration of selected line is enable */
343     if ((regval & maskline) != 0x00u)
344     {
345       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
346     }
347 
348     /* Get falling configuration */
349     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
350     regval = *regaddr;
351 
352     /* Check if configuration of selected line is enable */
353     if ((regval & maskline) != 0x00u)
354     {
355       pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
356     }
357 
358     /* Get Gpio port selection for gpio lines */
359     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
360     {
361       regval = SYSCFG->EXTICR[linepos >> 2u];
362       pExtiConfig->GPIOSel = (regval >> (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & SYSCFG_EXTICR1_EXTI0;
363     }
364   }
365 
366   return HAL_OK;
367 }
368 
369 
370 /**
371   * @brief  Clear whole configuration of a dedicated Exti line.
372   * @param  hexti Exti handle.
373   * @retval HAL Status.
374   */
HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef * hexti)375 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
376 {
377   __IO uint32_t *regaddr;
378   uint32_t regval;
379   uint32_t linepos;
380   uint32_t maskline;
381   uint32_t offset;
382 
383   /* Check null pointer */
384   if (hexti == NULL)
385   {
386     return HAL_ERROR;
387   }
388 
389   /* Check the parameter */
390   assert_param(IS_EXTI_LINE(hexti->Line));
391 
392   /* compute line register offset and line mask */
393   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
394   linepos = (hexti->Line & EXTI_PIN_MASK);
395   maskline = (1uL << linepos);
396 
397   /* 1] Clear interrupt mode */
398 #if defined(DUAL_CORE) && defined(CORE_CM0PLUS)
399   regaddr = (&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
400 #else
401   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
402 #endif /* DUAL_CORE && CORE_CM0PLUS */
403   regval = (*regaddr & ~maskline);
404   *regaddr = regval;
405 
406   /* 2] Clear event mode */
407 #if defined(DUAL_CORE) && defined(CORE_CM0PLUS)
408   regaddr = (&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
409 #else
410   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
411 #endif /* DUAL_CORE && CORE_CM0PLUS */
412   regval = (*regaddr & ~maskline);
413   *regaddr = regval;
414 
415   /* 3] Clear triggers in case of configurable lines */
416   if ((hexti->Line & EXTI_CONFIG) != 0x00u)
417   {
418     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
419     regval = (*regaddr & ~maskline);
420     *regaddr = regval;
421 
422     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
423     regval = (*regaddr & ~maskline);
424     *regaddr = regval;
425 
426     /* Get Gpio port selection for gpio lines */
427     if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
428     {
429       regval = SYSCFG->EXTICR[linepos >> 2u];
430       regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
431       SYSCFG->EXTICR[linepos >> 2u] = regval;
432     }
433   }
434 
435   return HAL_OK;
436 }
437 
438 
439 /**
440   * @brief  Register callback for a dedicaated Exti line.
441   * @param  hexti Exti handle.
442   * @param  CallbackID User callback identifier.
443   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
444   * @param  pPendingCbfn function pointer to be stored as callback.
445   * @retval HAL Status.
446   */
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef * hexti,EXTI_CallbackIDTypeDef CallbackID,void (* pPendingCbfn)(void))447 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
448 {
449   HAL_StatusTypeDef status = HAL_OK;
450 
451   switch (CallbackID)
452   {
453     case  HAL_EXTI_COMMON_CB_ID:
454       hexti->PendingCallback = pPendingCbfn;
455       break;
456 
457     default:
458       status = HAL_ERROR;
459       break;
460   }
461 
462   return status;
463 }
464 
465 
466 /**
467   * @brief  Store line number as handle private field.
468   * @param  hexti Exti handle.
469   * @param  ExtiLine Exti line number.
470   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
471   * @retval HAL Status.
472   */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)473 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
474 {
475   /* Check the parameters */
476   assert_param(IS_EXTI_LINE(ExtiLine));
477 
478   /* Check null pointer */
479   if (hexti == NULL)
480   {
481     return HAL_ERROR;
482   }
483   else
484   {
485     /* Store line number as handle private field */
486     hexti->Line = ExtiLine;
487 
488     return HAL_OK;
489   }
490 }
491 
492 
493 /**
494   * @}
495   */
496 
497 /** @addtogroup EXTI_Exported_Functions_Group2
498   *  @brief EXTI IO functions.
499   *
500 @verbatim
501  ===============================================================================
502                        ##### IO operation functions #####
503  ===============================================================================
504 
505 @endverbatim
506   * @{
507   */
508 
509 /**
510   * @brief  Handle EXTI interrupt request.
511   * @param  hexti Exti handle.
512   * @retval none.
513   */
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef * hexti)514 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
515 {
516   __IO uint32_t *regaddr;
517   uint32_t regval;
518   uint32_t maskline;
519   uint32_t offset;
520 
521   /* Compute line register offset and line mask */
522   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
523   maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
524 
525   /* Get pending bit  */
526   regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
527   regval = (*regaddr & maskline);
528 
529   if (regval != 0x00u)
530   {
531     /* Clear pending bit */
532     *regaddr = maskline;
533 
534     /* Call callback */
535     if (hexti->PendingCallback != NULL)
536     {
537       hexti->PendingCallback();
538     }
539   }
540 }
541 
542 
543 /**
544   * @brief  Get interrupt pending bit of a dedicated line.
545   * @param  hexti Exti handle.
546   * @param  Edge Specify which pending edge as to be checked.
547   *         This parameter can be one of the following values:
548   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
549   *         This parameter is kept for compatibility with other series.
550   * @retval 1 if interrupt is pending else 0.
551   */
HAL_EXTI_GetPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)552 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
553 {
554   __IO uint32_t *regaddr;
555   uint32_t regval;
556   uint32_t linepos;
557   uint32_t maskline;
558   uint32_t offset;
559 
560   /* Check parameters */
561   assert_param(IS_EXTI_LINE(hexti->Line));
562   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
563   assert_param(IS_EXTI_PENDING_EDGE(Edge));
564 
565   /* compute line register offset and line mask */
566   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
567   linepos = (hexti->Line & EXTI_PIN_MASK);
568   maskline = (1uL << linepos);
569 
570   /* Get pending bit */
571   regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
572 
573   /* return 1 if bit is set else 0 */
574   regval = ((*regaddr & maskline) >> linepos);
575   return regval;
576 }
577 
578 
579 /**
580   * @brief  Clear interrupt pending bit of a dedicated line.
581   * @param  hexti Exti handle.
582   * @param  Edge Specify which pending edge as to be clear.
583   *         This parameter can be one of the following values:
584   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
585   *         This parameter is kept for compatibility with other series.
586   * @retval None.
587   */
HAL_EXTI_ClearPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)588 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
589 {
590   __IO uint32_t *regaddr;
591   uint32_t maskline;
592   uint32_t offset;
593 
594   /* Check parameters */
595   assert_param(IS_EXTI_LINE(hexti->Line));
596   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
597   assert_param(IS_EXTI_PENDING_EDGE(Edge));
598 
599   /* compute line register offset and line mask */
600   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
601   maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
602 
603   /* Get pending register address */
604   regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
605 
606   /* Clear Pending bit */
607   *regaddr =  maskline;
608 }
609 
610 /**
611   * @brief  Generate a software interrupt for a dedicated line.
612   * @param  hexti Exti handle.
613   * @retval None.
614   */
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef * hexti)615 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
616 {
617   __IO uint32_t *regaddr;
618   uint32_t maskline;
619   uint32_t offset;
620 
621   /* Check parameters */
622   assert_param(IS_EXTI_LINE(hexti->Line));
623   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
624 
625   /* compute line register offset and line mask */
626   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
627   maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
628 
629   regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
630   *regaddr = maskline;
631 }
632 
633 
634 /**
635   * @}
636   */
637 
638 /**
639   * @}
640   */
641 
642 #endif /* HAL_EXTI_MODULE_ENABLED */
643 /**
644   * @}
645   */
646 
647 /**
648   * @}
649   */
650