1 /**
2   ******************************************************************************
3   * @file    stm32n6xx_hal_exti.c
4   * @author  GPM 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) 2023 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         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 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 
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32n6xx_hal.h"
88 
89 /** @addtogroup STM32N6xx_HAL_Driver
90   * @{
91   */
92 
93 /** @addtogroup EXTI
94   * @{
95   */
96 
97 #ifdef HAL_EXTI_MODULE_ENABLED
98 
99 /* Private typedef -----------------------------------------------------------*/
100 /* Private defines ------------------------------------------------------------*/
101 /** @defgroup EXTI_Private_Constants EXTI Private Constants
102   * @{
103   */
104 #define EXTI_MODE_OFFSET                    0x04U   /* byte offset between IMRx/EMRx registers */
105 #define EXTI_CONFIG_OFFSET                  0x08U   /* byte offset between Rising/Falling configuration registers */
106 #define EXTI_PRIVCFGR_OFFSET                0x08U   /* byte offset between PRIVCFGRx/PRIVCFGRx registers */
107 #define EXTI_SECCFGR_OFFSET                 0x08U   /* byte offset between SECCFGRx/SECCFGRx registers */
108 /**
109   * @}
110   */
111 
112 /* Private macros ------------------------------------------------------------*/
113 /* Private variables ---------------------------------------------------------*/
114 /* Private function prototypes -----------------------------------------------*/
115 /* Exported functions --------------------------------------------------------*/
116 
117 /** @addtogroup EXTI_Exported_Functions
118   * @{
119   */
120 
121 /** @addtogroup EXTI_Exported_Functions_Group1
122   *  @brief    Configuration functions
123   *
124 @verbatim
125  ===============================================================================
126               ##### Configuration functions #####
127  ===============================================================================
128 
129 @endverbatim
130   * @{
131   */
132 
133 /**
134   * @brief  Set configuration of a dedicated Exti line.
135   * @param  hexti Exti handle.
136   * @param  pExtiConfig Pointer on EXTI configuration to be set.
137   * @retval HAL Status.
138   */
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef * hexti,const EXTI_ConfigTypeDef * pExtiConfig)139 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, const EXTI_ConfigTypeDef *pExtiConfig)
140 {
141   __IO uint32_t *regaddr;
142   uint32_t regval;
143   uint32_t linepos;
144   uint32_t maskline;
145   uint32_t offset;
146 
147   /* Check null pointer */
148   if ((hexti == NULL) || (pExtiConfig == NULL))
149   {
150     return HAL_ERROR;
151   }
152 
153   /* Check the parameters */
154   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
155   assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
156 
157   /* Assign line number to handle */
158   hexti->Line = pExtiConfig->Line;
159 
160   /* compute line register offset and line mask */
161   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
162   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
163   maskline = (1UL << linepos);
164 
165   /* Configure triggers for configurable lines */
166   if ((pExtiConfig->Line & EXTI_CONFIG) != 0U)
167   {
168     assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
169 
170     /* Configure rising trigger */
171     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
172     regval = *regaddr;
173 
174     /* Mask or set line */
175     if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0U)
176     {
177       regval |= maskline;
178     }
179     else
180     {
181       regval &= ~maskline;
182     }
183 
184     /* Store rising trigger mode */
185     *regaddr = regval;
186 
187     /* Configure falling trigger */
188     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
189     regval = *regaddr;
190 
191     /* Mask or set line */
192     if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0U)
193     {
194       regval |= maskline;
195     }
196     else
197     {
198       regval &= ~maskline;
199     }
200 
201     /* Store falling trigger mode */
202     *regaddr = regval;
203 
204     /* Configure gpio port selection in case of gpio exti line */
205     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
206     {
207       assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
208       assert_param(IS_EXTI_GPIO_PIN(linepos));
209 
210       regval = EXTI->EXTICR[(linepos >> 2U) & 0x03UL];
211       regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
212       regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
213       EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
214     }
215   }
216 
217   /* Configure interrupt mode : read current mode */
218   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
219   regval = *regaddr;
220 
221   /* Mask or set line */
222   if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0U)
223   {
224     regval |= maskline;
225   }
226   else
227   {
228     regval &= ~maskline;
229   }
230 
231   /* Store interrupt mode */
232   *regaddr = regval;
233 
234   /* Configure event mode : read current mode */
235   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
236   regval = *regaddr;
237 
238   /* Mask or set line */
239   if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0U)
240   {
241     regval |= maskline;
242   }
243   else
244   {
245     regval &= ~maskline;
246   }
247 
248   /* Store event mode */
249   *regaddr = regval;
250 
251   return HAL_OK;
252 }
253 
254 
255 /**
256   * @brief  Get configuration of a dedicated Exti line.
257   * @param  hexti Exti handle.
258   * @param  pExtiConfig Pointer on structure to store Exti configuration.
259   * @retval HAL Status.
260   */
HAL_EXTI_GetConfigLine(const EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)261 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(const EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
262 {
263   const __IO uint32_t *regaddr;
264   uint32_t regval;
265   uint32_t linepos;
266   uint32_t maskline;
267   uint32_t offset;
268 
269   /* Check null pointer */
270   if ((hexti == NULL) || (pExtiConfig == NULL))
271   {
272     return HAL_ERROR;
273   }
274 
275   /* Check the parameter */
276   assert_param(IS_EXTI_LINE(hexti->Line));
277 
278   /* Store handle line number to configuration structure */
279   pExtiConfig->Line = hexti->Line;
280 
281   /* compute line register offset and line mask */
282   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
283   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
284   maskline = (1UL << linepos);
285 
286   /* 1] Get core mode : interrupt */
287   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
288   regval = *regaddr;
289 
290   /* Check if selected line is enable */
291   if ((regval & maskline) != 0U)
292   {
293     pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
294   }
295   else
296   {
297     pExtiConfig->Mode = EXTI_MODE_NONE;
298   }
299 
300   /* Get event mode */
301   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
302   regval = *regaddr;
303 
304   /* Check if selected line is enable */
305   if ((regval & maskline) != 0U)
306   {
307     pExtiConfig->Mode |= EXTI_MODE_EVENT;
308   }
309 
310   /* 2] Get trigger for configurable lines : rising */
311   if ((pExtiConfig->Line & EXTI_CONFIG) != 0U)
312   {
313     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
314     regval = *regaddr;
315 
316     /* Check if configuration of selected line is enable */
317     if ((regval & maskline) != 0U)
318     {
319       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
320     }
321     else
322     {
323       pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
324     }
325 
326     /* Get falling configuration */
327     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
328     regval = *regaddr;
329 
330     /* Check if configuration of selected line is enable */
331     if ((regval & maskline) != 0U)
332     {
333       pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
334     }
335 
336     /* Get Gpio port selection for gpio lines */
337     if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
338     {
339       assert_param(IS_EXTI_GPIO_PIN(linepos));
340 
341       regval = EXTI->EXTICR[(linepos >> 2U) & 0x03UL];
342       pExtiConfig->GPIOSel = (regval >> (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & EXTI_EXTICR1_EXTI0;
343     }
344     else
345     {
346       pExtiConfig->GPIOSel = 0U;
347     }
348   }
349   else
350   {
351     pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
352     pExtiConfig->GPIOSel = 0U;
353   }
354 
355   return HAL_OK;
356 }
357 
358 
359 /**
360   * @brief  Clear whole configuration of a dedicated Exti line.
361   * @param  hexti Exti handle.
362   * @retval HAL Status.
363   */
HAL_EXTI_ClearConfigLine(const EXTI_HandleTypeDef * hexti)364 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(const EXTI_HandleTypeDef *hexti)
365 {
366   __IO uint32_t *regaddr;
367   uint32_t regval;
368   uint32_t linepos;
369   uint32_t maskline;
370   uint32_t offset;
371 
372   /* Check null pointer */
373   if (hexti == NULL)
374   {
375     return HAL_ERROR;
376   }
377 
378   /* Check the parameter */
379   assert_param(IS_EXTI_LINE(hexti->Line));
380 
381   /* compute line register offset and line mask */
382   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
383   linepos = (hexti->Line & EXTI_PIN_MASK);
384   maskline = (1UL << linepos);
385 
386   /* 1] Clear interrupt mode */
387   regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
388   regval = (*regaddr & ~maskline);
389   *regaddr = regval;
390 
391   /* 2] Clear event mode */
392   regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
393   regval = (*regaddr & ~maskline);
394   *regaddr = regval;
395 
396   /* 3] Clear triggers in case of configurable lines */
397   if ((hexti->Line & EXTI_CONFIG) != 0U)
398   {
399     regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
400     regval = (*regaddr & ~maskline);
401     *regaddr = regval;
402 
403     regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
404     regval = (*regaddr & ~maskline);
405     *regaddr = regval;
406 
407     /* Get Gpio port selection for gpio lines */
408     if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
409     {
410       assert_param(IS_EXTI_GPIO_PIN(linepos));
411 
412       regval = EXTI->EXTICR[(linepos >> 2U) & 0x03UL];
413       regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
414       EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
415     }
416   }
417 
418   return HAL_OK;
419 }
420 
421 
422 /**
423   * @brief  Register callback for a dedicated Exti line.
424   * @param  hexti Exti handle.
425   * @param  CallbackID User callback identifier.
426   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
427   * @param  pPendingCbfn function pointer to be stored as callback.
428   * @retval HAL Status.
429   */
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef * hexti,EXTI_CallbackIDTypeDef CallbackID,void (* pPendingCbfn)(void))430 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID,
431                                             void (*pPendingCbfn)(void))
432 {
433   HAL_StatusTypeDef status = HAL_OK;
434 
435   switch (CallbackID)
436   {
437     case  HAL_EXTI_COMMON_CB_ID:
438       hexti->RisingCallback = pPendingCbfn;
439       hexti->FallingCallback = pPendingCbfn;
440       break;
441 
442     case  HAL_EXTI_RISING_CB_ID:
443       hexti->RisingCallback = pPendingCbfn;
444       break;
445 
446     case  HAL_EXTI_FALLING_CB_ID:
447       hexti->FallingCallback = pPendingCbfn;
448       break;
449 
450     default:
451       status = HAL_ERROR;
452       break;
453   }
454 
455   return status;
456 }
457 
458 
459 /**
460   * @brief  Store line number as handle private field.
461   * @param  hexti Exti handle.
462   * @param  ExtiLine Exti line number.
463   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
464   * @retval HAL Status.
465   */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)466 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
467 {
468   /* Check the parameters */
469   assert_param(IS_EXTI_LINE(ExtiLine));
470 
471   /* Check null pointer */
472   if (hexti == NULL)
473   {
474     return HAL_ERROR;
475   }
476   else
477   {
478     /* Store line number as handle private field */
479     hexti->Line = ExtiLine;
480 
481     return HAL_OK;
482   }
483 }
484 
485 
486 /**
487   * @}
488   */
489 
490 /** @addtogroup EXTI_Exported_Functions_Group2
491   *  @brief EXTI IO functions.
492   *
493 @verbatim
494  ===============================================================================
495                        ##### IO operation functions #####
496  ===============================================================================
497 
498 @endverbatim
499   * @{
500   */
501 
502 /**
503   * @brief  Handle EXTI interrupt request.
504   * @param  hexti Exti handle.
505   * @retval none.
506   */
HAL_EXTI_IRQHandler(const EXTI_HandleTypeDef * hexti)507 void HAL_EXTI_IRQHandler(const EXTI_HandleTypeDef *hexti)
508 {
509   __IO uint32_t *regaddr;
510   uint32_t regval;
511   uint32_t maskline;
512   uint32_t offset;
513 
514   /* Compute line register offset and line mask */
515   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
516   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
517 
518   /* Get rising edge pending bit  */
519   regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
520   regval = (*regaddr & maskline);
521 
522   if (regval != 0U)
523   {
524     /* Clear pending bit */
525     *regaddr = maskline;
526 
527     /* Call rising callback */
528     if (hexti->RisingCallback != NULL)
529     {
530       hexti->RisingCallback();
531     }
532   }
533 
534   /* Get falling edge pending bit  */
535   regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
536   regval = (*regaddr & maskline);
537 
538   if (regval != 0U)
539   {
540     /* Clear pending bit */
541     *regaddr = maskline;
542 
543     /* Call falling callback */
544     if (hexti->FallingCallback != NULL)
545     {
546       hexti->FallingCallback();
547     }
548   }
549 }
550 
551 
552 /**
553   * @brief  Get interrupt pending bit of a dedicated line.
554   * @param  hexti Exti handle.
555   * @param  Edge Specify which pending edge as to be checked.
556   *         This parameter can be one of the following values:
557   *           @arg @ref EXTI_TRIGGER_RISING
558   *           @arg @ref EXTI_TRIGGER_FALLING
559   * @retval 1 if interrupt is pending else 0.
560   */
HAL_EXTI_GetPending(const EXTI_HandleTypeDef * hexti,uint32_t Edge)561 uint32_t HAL_EXTI_GetPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
562 {
563   const __IO uint32_t *regaddr;
564   uint32_t regval;
565   uint32_t linepos;
566   uint32_t maskline;
567   uint32_t offset;
568 
569   /* Check the parameters */
570   assert_param(IS_EXTI_LINE(hexti->Line));
571   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
572   assert_param(IS_EXTI_PENDING_EDGE(Edge));
573 
574   /* compute line register offset and line mask */
575   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
576   linepos = (hexti->Line & EXTI_PIN_MASK);
577   maskline = (1UL << linepos);
578 
579   if (Edge != EXTI_TRIGGER_RISING)
580   {
581     /* Get falling edge pending bit */
582     regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
583   }
584   else
585   {
586     /* Get rising edge pending bit */
587     regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
588   }
589 
590   /* return 1 if bit is set else 0 */
591   regval = ((*regaddr & maskline) >> linepos);
592   return regval;
593 }
594 
595 
596 /**
597   * @brief  Clear interrupt pending bit of a dedicated line.
598   * @param  hexti Exti handle.
599   * @param  Edge Specify which pending edge as to be clear.
600   *         This parameter can be one of the following values:
601   *           @arg @ref EXTI_TRIGGER_RISING
602   *           @arg @ref EXTI_TRIGGER_FALLING
603   * @retval None.
604   */
HAL_EXTI_ClearPending(const EXTI_HandleTypeDef * hexti,uint32_t Edge)605 void HAL_EXTI_ClearPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
606 {
607   __IO uint32_t *regaddr;
608   uint32_t maskline;
609   uint32_t offset;
610 
611   /* Check the parameters */
612   assert_param(IS_EXTI_LINE(hexti->Line));
613   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
614   assert_param(IS_EXTI_PENDING_EDGE(Edge));
615 
616   /* compute line register offset and line mask */
617   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
618   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
619 
620   if (Edge != EXTI_TRIGGER_RISING)
621   {
622     /* Get falling edge pending register address */
623     regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
624   }
625   else
626   {
627     /* Get rising edge pending register address */
628     regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
629   }
630 
631   /* Clear Pending bit */
632   *regaddr =  maskline;
633 }
634 
635 
636 /**
637   * @brief  Generate a software interrupt for a dedicated line.
638   * @param  hexti Exti handle.
639   * @retval None.
640   */
HAL_EXTI_GenerateSWI(const EXTI_HandleTypeDef * hexti)641 void HAL_EXTI_GenerateSWI(const EXTI_HandleTypeDef *hexti)
642 {
643   __IO uint32_t *regaddr;
644   uint32_t maskline;
645   uint32_t offset;
646 
647   /* Check the parameters */
648   assert_param(IS_EXTI_LINE(hexti->Line));
649   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
650 
651   /* compute line register offset and line mask */
652   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
653   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
654 
655   regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
656   *regaddr = maskline;
657 }
658 
659 /**
660   * @}
661   */
662 
663 /** @defgroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions
664   *  @brief EXTI attributes management functions.
665   *
666 @verbatim
667  ===============================================================================
668                        ##### EXTI attributes functions #####
669  ===============================================================================
670 
671 @endverbatim
672   * @{
673   */
674 
675 /**
676   * @brief  Configure the EXTI line attribute(s).
677   * @note   Available attributes are to secure EXTI line and set EXTI line as privileged.
678   *         Default state is not secure and unprivileged access allowed.
679   * @note   Set an EXTI line to secure is only available in secure and privilege
680   *         Set an EXTI line to privilege is only available in privilege
681   * @note   Security and privilege attributes can be set independently.
682   * @param  ExtiLine Exti line number.
683   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
684   * @param  LineAttributes can be one or a combination of the following values:
685   *            @arg @ref EXTI_LINE_PRIV         Privileged-only access
686   *            @arg @ref EXTI_LINE_NPRIV        Privileged/Non-privileged access
687   *            @arg @ref EXTI_LINE_SEC          Secure-only access
688   *            @arg @ref EXTI_LINE_NSEC         Secure/Non-secure access
689   * @retval None
690   */
HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine,uint32_t LineAttributes)691 void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes)
692 {
693   __IO uint32_t *regaddr;
694   uint32_t regval;
695   uint32_t linepos;
696   uint32_t maskline;
697   uint32_t offset;
698 
699   /* Check the parameters */
700   assert_param(IS_EXTI_LINE(ExtiLine));
701   assert_param(IS_EXTI_LINE_ATTRIBUTES(LineAttributes));
702 
703   /* compute line register offset and line mask */
704   offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
705   linepos = (ExtiLine & EXTI_PIN_MASK);
706   maskline = (1UL << linepos);
707 
708   /* Configure privilege or non-privilege attributes */
709   regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
710   regval = *regaddr;
711 
712   /* Mask or set line */
713   if ((LineAttributes & EXTI_LINE_PRIV) == EXTI_LINE_PRIV)
714   {
715     regval |= maskline;
716   }
717   else if ((LineAttributes & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)
718   {
719     regval &= ~maskline;
720   }
721   else
722   {
723     /* do nothing */
724   }
725 
726   /* Store privilege or non-privilege attribute */
727   *regaddr = regval;
728 
729 #if defined CPU_IN_SECURE_STATE
730   /* Configure secure or non-secure attributes */
731   regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
732   regval = *regaddr;
733 
734   /* Mask or set line */
735   if ((LineAttributes & EXTI_LINE_SEC) == EXTI_LINE_SEC)
736   {
737     regval |= maskline;
738   }
739   else if ((LineAttributes & EXTI_LINE_NSEC) == EXTI_LINE_NSEC)
740   {
741     regval &= ~maskline;
742   }
743   else
744   {
745     /* do nothing */
746   }
747 
748   /* Store secure or non-secure attribute */
749   *regaddr = regval;
750 #endif /* CPU_IN_SECURE_STATE */
751 
752 }
753 
754 /**
755   * @brief  Get the EXTI line attribute(s).
756   * @param  ExtiLine Exti line number.
757   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
758   * @param  pLineAttributes: pointer to return line attributes.
759   * @retval HAL Status.
760   */
HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine,uint32_t * pLineAttributes)761 HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes)
762 {
763   const __IO uint32_t *regaddr;
764   uint32_t linepos;
765   uint32_t maskline;
766   uint32_t offset;
767   uint32_t attributes;
768 
769   /* Check null pointer */
770   if (pLineAttributes == NULL)
771   {
772     return HAL_ERROR;
773   }
774 
775   /* Check the parameters */
776   assert_param(IS_EXTI_LINE(ExtiLine));
777 
778   /* Compute line register offset and line mask */
779   offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
780   linepos = (ExtiLine & EXTI_PIN_MASK);
781   maskline = (1UL << linepos);
782 
783   /* Get privilege or non-privilege attribute */
784   regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
785 
786   if ((*regaddr & maskline) != 0U)
787   {
788     attributes = EXTI_LINE_PRIV;
789   }
790   else
791   {
792     attributes = EXTI_LINE_NPRIV;
793   }
794 
795   /* Get secure or non-secure attribute */
796   regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
797 
798   if ((*regaddr & maskline) != 0U)
799   {
800     attributes |= EXTI_LINE_SEC;
801   }
802   else
803   {
804     attributes |= EXTI_LINE_NSEC;
805   }
806 
807   /* return value */
808   *pLineAttributes = attributes;
809 
810   return HAL_OK;
811 }
812 
813 #if defined(CPU_IN_SECURE_STATE)
814 /**
815   * @brief  Lock the secure and privilege configuration registers.
816   * @retval None
817   */
HAL_EXTI_LockAttributes(void)818 void HAL_EXTI_LockAttributes(void)
819 {
820   SET_BIT(EXTI->LOCKR, EXTI_LOCKR_LOCK);
821 }
822 
823 /**
824   * @brief  Return the secure and privilege configuration registers LOCK status
825   * @retval 1 if the secure and privilege configuration registers have been locked else 0.
826   */
HAL_EXTI_GetLockAttributes(void)827 uint32_t HAL_EXTI_GetLockAttributes(void)
828 {
829   return READ_BIT(EXTI->LOCKR, EXTI_LOCKR_LOCK);
830 }
831 
832 #endif /* CPU_IN_SECURE_STATE */
833 /**
834   * @}
835   */
836 
837 /**
838   * @}
839   */
840 
841 #endif /* HAL_EXTI_MODULE_ENABLED */
842 /**
843   * @}
844   */
845 
846 /**
847   * @}
848   */
849 
850