1 /**
2   ******************************************************************************
3   * @file    stm32mp1xx_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   ******************************************************************************
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 diffenrents
40         interrupt 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 throught multiplexer.
47 
48                      ##### How to use this driver #####
49   ==============================================================================
50   [..]
51 
52     (#) Configure the configurable EXTI line using HAL_EXTI_SetConfigLine().
53         NOTE: in addition HAL_EXTI_SetInterruptAndEventMask shall be used
54         to configure interrupt and events mask of this configurable line
55         (++) Choose the interrupt line number by setting "Line" member from
56              EXTI_ConfigTypeDef structure.
57         (++) Configure the interrupt and/or event mode using "Mode" member from
58              EXTI_ConfigTypeDef structure.
59         (++) For configurable lines, configure rising and/or falling trigger
60              "Trigger" member from EXTI_ConfigTypeDef structure.
61         (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
62              member from GPIO_InitTypeDef structure.
63 
64     (#) Get current Exti configuration of a dedicated line using
65         HAL_EXTI_GetConfigLine().
66         (++) Provide exiting handle as parameter.
67         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
68 
69     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
70         (++) Provide exiting handle as parameter.
71 
72     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
73         (++) Provide exiting handle as first parameter.
74         (++) Provide which callback will be registered using one value from
75              EXTI_CallbackIDTypeDef.
76         (++) Provide callback function pointer.
77 
78     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
79 
80     (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
81 
82     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
83 
84   @endverbatim
85   ******************************************************************************
86   */
87 
88 /* Includes ------------------------------------------------------------------*/
89 #include "stm32mp1xx_hal.h"
90 
91 /** @addtogroup STM32MP1xx_HAL_Driver
92   * @{
93   */
94 
95 /** @addtogroup EXTI
96   * @{
97   */
98 /** MISRA C:2012 deviation rule has been granted for following rule:
99   * Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out
100   * of bounds [0,3] in following API :
101   * HAL_EXTI_SetConfigLine
102   * HAL_EXTI_GetConfigLine
103   * HAL_EXTI_ClearConfigLine
104   */
105 
106 #ifdef HAL_EXTI_MODULE_ENABLED
107 
108 /* Private typedef -----------------------------------------------------------*/
109 /* Private defines ------------------------------------------------------------*/
110 /** @defgroup EXTI_Private_Constants EXTI Private Constants
111   * @{
112   */
113 #define EXTI_MODE_C1                        0x10u
114 #define EXTI_MODE_C2                        0x20u
115 #define EXTI_MODE_INTERRUPT                 0x01u
116 #define EXTI_MODE_EVENT                     0x02u
117 #define EXTI_MODE_OFFSET                    0x04u   /* 0x10: offset between CPU IMR/EMR registers */
118 #define EXTI_CONFIG_OFFSET                  0x08u   /* 0x20: offset between CPU Rising/Falling configuration registers */
119 /**
120   * @}
121   */
122 
123 /* Private macros ------------------------------------------------------------*/
124 /* Private variables ---------------------------------------------------------*/
125 /* Private function prototypes -----------------------------------------------*/
126 /* Exported functions --------------------------------------------------------*/
127 
128 /** @addtogroup EXTI_Exported_Functions
129   * @{
130   */
131 
132 /** @addtogroup EXTI_Exported_Functions_Group1
133  *  @brief    Configuration functions
134  *
135 @verbatim
136  ===============================================================================
137               ##### Configuration functions #####
138  ===============================================================================
139 
140 @endverbatim
141   * @{
142   */
143 
144 /**
145   * @brief  Set configuration except Interrupt and Event mask of a dedicated Exti line.
146   *         It is relevant only for configurable events.
147   * @param  hexti Exti handle.
148   * @param  pExtiConfig Pointer on EXTI configuration to be set.
149   * @retval HAL Status.
150   */
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)151 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
152 {
153   __IO uint32_t *regaddr;
154   uint32_t regval;
155   uint32_t linepos;
156   uint32_t maskline;
157   uint32_t offset;
158 
159   /* Check null pointer */
160   if ((hexti == NULL) || (pExtiConfig == NULL))
161   {
162     return HAL_ERROR;
163   }
164 
165   /* Check parameters */
166   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
167 
168   /* Assign line number to handle */
169   hexti->Line = pExtiConfig->Line;
170 
171   /* compute line register offset and line mask */
172   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
173   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
174   maskline = (1uL << linepos);
175 
176   /* Configure triggers for configurable lines */
177   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x0u)
178   {
179     assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
180 
181     /* Configure rising trigger */
182     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
183     regval = *regaddr;
184 
185     /* Mask or set line */
186     if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x0u)
187     {
188       regval |= maskline;
189     }
190     else
191     {
192       regval &= ~maskline;
193     }
194 
195     /* Store rising trigger mode */
196     *regaddr = regval;
197 
198     /* Configure falling trigger */
199     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
200     regval = *regaddr;
201 
202     /* Mask or set line */
203     if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x0u)
204     {
205       regval |= maskline;
206     }
207     else
208     {
209       regval &= ~maskline;
210     }
211 
212     /* Store falling trigger mode */
213     *regaddr = regval;
214 
215     /* Configure gpio port selection in case of gpio exti line */
216     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
217     {
218       assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
219       assert_param(IS_EXTI_GPIO_PIN(linepos));
220 
221       regval = EXTI->EXTICR[linepos >> 2u];
222       regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
223       regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
224       EXTI->EXTICR[linepos >> 2u] = regval;
225     }
226   }
227 
228 
229   /*Set Interrupt And Event Mask for Core 1 if configuration for Core 1 given into parameter mode */
230   if ((pExtiConfig->Mode & EXTI_MODE_C1) != 0x0u)
231   {
232     regaddr = (&EXTI->C1IMR1 + (EXTI_MODE_OFFSET * offset));
233 
234     regval = *regaddr;
235 
236     /* Mask or set line */
237     if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x0u)
238     {
239       regval |= maskline;
240     }
241     else
242     {
243       regval &= ~maskline;
244     }
245 
246     /* Store interrupt mode */
247     *regaddr = regval;
248   }
249 
250   /*Set Interrupt And Event Mask for Core 2 if configuration for Core 2 given into parameter mode  */
251   if ((pExtiConfig->Mode & EXTI_MODE_C2) != 0x0u)
252   {
253     regaddr = (&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
254 
255     regval = *regaddr;
256 
257     /* Mask or set line */
258     if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x0u)
259     {
260       regval |= maskline;
261     }
262     else
263     {
264       regval &= ~maskline;
265     }
266 
267     /* Store interrupt mode */
268     *regaddr = regval;
269 
270     /* The event mode cannot be configured if the line does not support it */
271     assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
272 
273     regaddr = (&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
274 
275     regval = *regaddr;
276 
277     /* Mask or set line */
278     if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x0u)
279     {
280       regval |= maskline;
281     }
282     else
283     {
284       regval &= ~maskline;
285     }
286 
287     /* Store event mode */
288     *regaddr = regval;
289   }
290 
291   return HAL_OK;
292 }
293 
294 
295 /**
296   * @brief  Get configuration of a dedicated Exti line.
297   * @param  hexti Exti handle.
298   * @param  pExtiConfig Pointer on structure to store Exti configuration.
299   * @retval HAL Status.
300   */
HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)301 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
302 {
303   __IO uint32_t *regaddr;
304   uint32_t regval;
305   uint32_t linepos;
306   uint32_t maskline;
307   uint32_t offset;
308 
309   /* Check null pointer */
310   if ((hexti == NULL) || (pExtiConfig == NULL))
311   {
312     return HAL_ERROR;
313   }
314 
315   /* Check the parameter */
316   assert_param(IS_EXTI_LINE(hexti->Line));
317 
318   /* Store handle line number to configiguration structure */
319   pExtiConfig->Line = hexti->Line;
320 
321   /* compute line register offset and line mask */
322   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
323   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
324   maskline = (1uL << linepos);
325 
326 
327   /* 1] Get core 1 mode : interrupt */
328   regaddr = (&EXTI->C1IMR1 + (EXTI_MODE_OFFSET * offset));
329   regval = *regaddr;
330 
331   /* Check if selected line is enable */
332   if ((regval & maskline) != 0x0u)
333   {
334     pExtiConfig->Mode = EXTI_MODE_C1_INTERRUPT;
335   }
336   else
337   {
338     pExtiConfig->Mode = EXTI_MODE_C1_NONE;
339   }
340 
341   /* Get core 2 mode : interrupt */
342   regaddr = (&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
343   regval = *regaddr;
344 
345   /* Check if selected line is enable */
346   if ((regval & maskline) != 0x0u)
347   {
348     pExtiConfig->Mode |= EXTI_MODE_C2_INTERRUPT;
349   }
350   else
351   {
352     pExtiConfig->Mode |= EXTI_MODE_C2_NONE;
353   }
354 
355   /* Get Core 2 mode : event */
356   regaddr = (&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
357   regval = *regaddr;
358 
359   /* Check if selected line is enable */
360   if ((regval & maskline) != 0x0u)
361   {
362     pExtiConfig->Mode |= EXTI_MODE_C2_EVENT;
363   }
364 
365   /* Get default Trigger and GPIOSel configuration */
366   pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
367   pExtiConfig->GPIOSel = 0x0u;
368 
369   /* 2] Get trigger for configurable lines : rising */
370   if ((pExtiConfig->Line & EXTI_CONFIG) != 0x0u)
371   {
372     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
373     regval = *regaddr;
374 
375     /* Check if configuration of selected line is enable */
376     if ((regval & maskline) != 0x0u)
377     {
378       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
379     }
380 
381     /* Get falling configuration */
382     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
383     regval = *regaddr;
384 
385     /* Check if configuration of selected line is enable */
386     if ((regval & maskline) != 0x0u)
387     {
388       pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
389     }
390 
391     /* Get Gpio port selection for gpio lines */
392     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
393     {
394       assert_param(IS_EXTI_GPIO_PIN(linepos));
395 
396       regval = EXTI->EXTICR[linepos >> 2u];
397       pExtiConfig->GPIOSel = ((regval << (EXTI_EXTICR1_EXTI1_Pos * (3uL - (linepos & 0x03u)))) >> 24);
398     }
399   }
400 
401   return HAL_OK;
402 }
403 
404 
405 /**
406   * @brief  Clear whole configuration of a dedicated Exti line.
407   * @param  hexti Exti handle.
408   * @retval HAL Status.
409   */
HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef * hexti)410 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
411 {
412   __IO uint32_t *regaddr;
413   uint32_t regval;
414   uint32_t linepos;
415   uint32_t maskline;
416   uint32_t offset;
417 
418   /* Check null pointer */
419   if (hexti == NULL)
420   {
421     return HAL_ERROR;
422   }
423 
424   /* Check the parameter */
425   assert_param(IS_EXTI_LINE(hexti->Line));
426 
427   /* compute line register offset and line mask */
428   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
429   linepos = (hexti->Line & EXTI_PIN_MASK);
430   maskline = (1uL << linepos);
431 
432   /* 1] Clear interrupt mode */
433   regaddr = (&EXTI->C1IMR1 + (EXTI_MODE_OFFSET * offset));
434   regval = (*regaddr & ~maskline);
435   *regaddr = regval;
436 
437   regaddr = (&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
438   regval = (*regaddr & ~maskline);
439   *regaddr = regval;
440 
441   /* 2] Clear event mode */
442   regaddr = (&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
443   regval = (*regaddr & ~maskline);
444   *regaddr = regval;
445 
446   /* 3] Clear triggers in case of configurable lines */
447   if ((hexti->Line & EXTI_CONFIG) != 0x0u)
448   {
449     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
450     regval = (*regaddr & ~maskline);
451     *regaddr = regval;
452 
453     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
454     regval = (*regaddr & ~maskline);
455     *regaddr = regval;
456 
457     /* Get Gpio port selection for gpio lines */
458     if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
459     {
460       assert_param(IS_EXTI_GPIO_PIN(linepos));
461 
462       regval = EXTI->EXTICR[linepos >> 2u];
463       regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
464       EXTI->EXTICR[linepos >> 2u] = regval;
465     }
466   }
467 
468   return HAL_OK;
469 }
470 
471 
472 /**
473   * @brief  Register callback for a dedicaated Exti line.
474   * @param  hexti Exti handle.
475   * @param  CallbackID User callback identifier.
476   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
477   * @param  pPendingCbfn function pointer to be stored as callback.
478   * @retval HAL Status.
479   */
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef * hexti,EXTI_CallbackIDTypeDef CallbackID,void (* pPendingCbfn)(void))480 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
481 {
482   HAL_StatusTypeDef status = HAL_OK;
483 
484   switch (CallbackID)
485   {
486     case  HAL_EXTI_COMMON_CB_ID:
487       hexti->RisingCallback = pPendingCbfn;
488       hexti->FallingCallback = pPendingCbfn;
489       break;
490 
491     case  HAL_EXTI_RISING_CB_ID:
492       hexti->RisingCallback = pPendingCbfn;
493       break;
494 
495     case  HAL_EXTI_FALLING_CB_ID:
496       hexti->FallingCallback = pPendingCbfn;
497       break;
498 
499     default:
500       status = HAL_ERROR;
501       break;
502   }
503 
504   return status;
505 }
506 
507 
508 /**
509   * @brief  Store line number as handle private field.
510   * @param  hexti Exti handle.
511   * @param  ExtiLine Exti line number.
512   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
513   * @retval HAL Status.
514   */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)515 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
516 {
517   /* Check the parameters */
518   assert_param(IS_EXTI_LINE(ExtiLine));
519 
520   /* Check null pointer */
521   if (hexti == NULL)
522   {
523     return HAL_ERROR;
524   }
525   else
526   {
527     /* Store line number as handle private field */
528     hexti->Line = ExtiLine;
529 
530     return HAL_OK;
531   }
532 }
533 
534 
535 /**
536   * @}
537   */
538 
539 /** @addtogroup EXTI_Exported_Functions_Group2
540  *  @brief EXTI IO functions.
541  *
542 @verbatim
543  ===============================================================================
544                        ##### IO operation functions #####
545  ===============================================================================
546 
547 @endverbatim
548   * @{
549   */
550 
551 /**
552   * @brief  Handle EXTI interrupt request.
553   * @param  hexti Exti handle.
554   * @retval none.
555   */
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef * hexti)556 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
557 {
558   __IO uint32_t *regaddr;
559   uint32_t regval;
560   uint32_t maskline;
561   uint32_t offset;
562 
563   /* Compute line register offset and line mask */
564   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
565   maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
566 
567   /* Get rising edge pending bit  */
568   regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
569   regval = (*regaddr & maskline);
570 
571   if (regval != 0x0u)
572   {
573     /* Clear pending bit */
574     *regaddr = maskline;
575 
576     /* Call rising callback */
577     if (hexti->RisingCallback != NULL)
578     {
579       hexti->RisingCallback();
580     }
581   }
582 
583   /* Get falling edge pending bit  */
584   regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
585   regval = (*regaddr & maskline);
586 
587   if (regval != 0x0u)
588   {
589     /* Clear pending bit */
590     *regaddr = maskline;
591 
592     /* Call rising callback */
593     if (hexti->FallingCallback != NULL)
594     {
595       hexti->FallingCallback();
596     }
597   }
598 }
599 
600 
601 /**
602   * @brief  Get interrupt pending bit of a dedicated line.
603   * @param  hexti Exti handle.
604   * @param  Edge Specify which pending edge as to be checked.
605   *         This parameter can be one of the following values:
606   *           @arg @ref EXTI_TRIGGER_RISING
607   *           @arg @ref EXTI_TRIGGER_FALLING
608   * @retval 1 if interrupt is pending else 0.
609   */
HAL_EXTI_GetPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)610 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
611 {
612   __IO uint32_t *regaddr;
613   uint32_t regval;
614   uint32_t linepos;
615   uint32_t maskline;
616   uint32_t offset;
617 
618   /* Check parameters */
619   assert_param(IS_EXTI_LINE(hexti->Line));
620   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
621   assert_param(IS_EXTI_PENDING_EDGE(Edge));
622 
623   /* compute line register offset and line mask */
624   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
625   linepos = (hexti->Line & EXTI_PIN_MASK);
626   maskline = (1uL << linepos);
627 
628   if (Edge != EXTI_TRIGGER_RISING)
629   {
630     /* Get falling edge pending bit */
631     regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
632   }
633   else
634   {
635     /* Get rising edge pending bit */
636     regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
637   }
638 
639   /* return 1 if bit is set else 0 */
640   regval = ((*regaddr & maskline) >> linepos);
641   return regval;
642 }
643 
644 
645 /**
646   * @brief  Clear interrupt pending bit of a dedicated line.
647   * @param  hexti Exti handle.
648   * @param  Edge Specify which pending edge as to be clear.
649   *         This parameter can be one of the following values:
650   *           @arg @ref EXTI_TRIGGER_RISING
651   *           @arg @ref EXTI_TRIGGER_FALLING
652   * @retval None.
653   */
HAL_EXTI_ClearPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)654 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
655 {
656   __IO uint32_t *regaddr;
657   uint32_t maskline;
658   uint32_t offset;
659 
660   /* Check parameters */
661   assert_param(IS_EXTI_LINE(hexti->Line));
662   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
663   assert_param(IS_EXTI_PENDING_EDGE(Edge));
664 
665   /* compute line register offset and line mask */
666   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
667   maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
668 
669   if (Edge != EXTI_TRIGGER_RISING)
670   {
671     /* Get falling edge pending register address */
672     regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
673   }
674   else
675   {
676     /* Get falling edge pending register address */
677     regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
678   }
679 
680   /* Clear Pending bit */
681   *regaddr =  maskline;
682 }
683 
684 
685 /**
686   * @brief  Generate a software interrupt for a dedicated line.
687   * @param  hexti Exti handle.
688   * @retval None.
689   */
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef * hexti)690 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
691 {
692   __IO uint32_t *regaddr;
693   uint32_t maskline;
694   uint32_t offset;
695 
696   /* Check parameters */
697   assert_param(IS_EXTI_LINE(hexti->Line));
698   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
699 
700   /* compute line register offset and line mask */
701   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
702   maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
703 
704   regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
705   *regaddr = maskline;
706 }
707 
708 
709 /**
710   * @}
711   */
712 
713 /**
714   * @}
715   */
716 
717 #endif /* HAL_EXTI_MODULE_ENABLED */
718 /**
719   * @}
720   */
721 
722 /**
723   * @}
724   */
725