1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_hal_exti.c
4   * @author  MCD Application Team
5   * @brief   EXTI HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Extended Interrupts and event controller
8   *          (EXTI) peripheral:
9   *           + Initialization and de-initialization functions
10   *           + IO operation functions
11   *
12   ******************************************************************************
13   * @attention
14   *
15   * Copyright (c) 2019 STMicroelectronics.
16   * All rights reserved.
17   *
18   * This software is licensed under terms that can be found in the LICENSE file
19   * in the root directory of this software component.
20   * If no LICENSE file comes with this software, it is provided AS-IS.
21   *
22   ******************************************************************************
23   @verbatim
24   ==============================================================================
25                     ##### EXTI Peripheral features #####
26   ==============================================================================
27   [..]
28     (+) Each Exti line can be configured within this driver.
29 
30     (+) Exti line can be configured in 3 different modes
31         (++) Interrupt
32         (++) Event
33         (++) Both of them
34 
35     (+) Configurable Exti lines can be configured with 3 different triggers
36         (++) Rising
37         (++) Falling
38         (++) Both of them
39 
40     (+) When set in interrupt mode, configurable Exti lines have two different
41         interrupt pending registers which allow to distinguish which transition
42         occurs:
43         (++) Rising edge pending interrupt
44         (++) Falling
45 
46     (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
47         be selected through multiplexer.
48 
49                      ##### How to use this driver #####
50   ==============================================================================
51   [..]
52 
53     (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
54         (++) Choose the interrupt line number by setting "Line" member from
55              EXTI_ConfigTypeDef structure.
56         (++) Configure the interrupt and/or event mode using "Mode" member from
57              EXTI_ConfigTypeDef structure.
58         (++) For configurable lines, configure rising and/or falling trigger
59              "Trigger" member from EXTI_ConfigTypeDef structure.
60         (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
61              member from GPIO_InitTypeDef structure.
62 
63     (#) Get current Exti configuration of a dedicated line using
64         HAL_EXTI_GetConfigLine().
65         (++) Provide exiting handle as parameter.
66         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
67 
68     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
69         (++) Provide exiting handle as parameter.
70 
71     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
72         (++) Provide exiting handle as first parameter.
73         (++) Provide which callback will be registered using one value from
74              EXTI_CallbackIDTypeDef.
75         (++) Provide callback function pointer.
76 
77     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
78 
79     (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
80 
81     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
82 
83   @endverbatim
84   */
85 
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32l5xx_hal.h"
88 
89 /** @addtogroup STM32L5xx_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 IMR/EMR registers */
105 #define EXTI_CONFIG_OFFSET                  0x08U   /* byte offset between Rising/Falling configuration registers */
106 #define EXTI_PRIVCFGR_OFFSET                0x04U   /* byte offset between PRIVCFGR1/PRIVCFGR2 registers */
107 #define EXTI_SECCFGR_OFFSET                 0x04U   /* byte offset between SECCFGR1/SECCFGR2 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,EXTI_ConfigTypeDef * pExtiConfig)139 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, 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 = (&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 = (&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];
211       regval &= ~(0xFFU << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
212       regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
213       EXTI->EXTICR[linepos >> 2U] = regval;
214     }
215   }
216 
217   /* Configure interrupt mode : read current mode */
218   regaddr = (&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 = (&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(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)261 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
262 {
263   __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 configiguration 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 = (&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 = (&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   /* Get default Trigger and GPIOSel configuration */
311   pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
312   pExtiConfig->GPIOSel = 0x00u;
313 
314   /* 2] Get trigger for configurable lines : rising */
315   if((pExtiConfig->Line & EXTI_CONFIG) != 0U)
316   {
317     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
318     regval = *regaddr;
319 
320     /* Check if configuration of selected line is enable */
321     if((regval & maskline) != 0U)
322     {
323       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
324     }
325 
326     /* Get falling configuration */
327     regaddr = (&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];
342       pExtiConfig->GPIOSel = (regval >> (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & EXTI_EXTICR1_EXTI0;
343     }
344   }
345 
346   return HAL_OK;
347 }
348 
349 
350 /**
351   * @brief  Clear whole configuration of a dedicated Exti line.
352   * @param  hexti Exti handle.
353   * @retval HAL Status.
354   */
HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef * hexti)355 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
356 {
357   __IO uint32_t *regaddr;
358   uint32_t regval;
359   uint32_t linepos;
360   uint32_t maskline;
361   uint32_t offset;
362 
363   /* Check null pointer */
364   if(hexti == NULL)
365   {
366     return HAL_ERROR;
367   }
368 
369   /* Check the parameter */
370   assert_param(IS_EXTI_LINE(hexti->Line));
371 
372   /* compute line register offset and line mask */
373   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
374   linepos = (hexti->Line & EXTI_PIN_MASK);
375   maskline = (1UL << linepos);
376 
377   /* 1] Clear interrupt mode */
378   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
379   regval = (*regaddr & ~maskline);
380   *regaddr = regval;
381 
382   /* 2] Clear event mode */
383   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
384   regval = (*regaddr & ~maskline);
385   *regaddr = regval;
386 
387   /* 3] Clear triggers in case of configurable lines */
388   if((hexti->Line & EXTI_CONFIG) != 0U)
389   {
390     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
391     regval = (*regaddr & ~maskline);
392     *regaddr = regval;
393 
394     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
395     regval = (*regaddr & ~maskline);
396     *regaddr = regval;
397 
398     /* Get Gpio port selection for gpio lines */
399     if((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
400     {
401       assert_param(IS_EXTI_GPIO_PIN(linepos));
402 
403       regval = EXTI->EXTICR[linepos >> 2U];
404       regval &= ~(0xFFU << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
405       EXTI->EXTICR[linepos >> 2U] = regval;
406     }
407   }
408 
409   return HAL_OK;
410 }
411 
412 
413 /**
414   * @brief  Register callback for a dedicaated Exti line.
415   * @param  hexti Exti handle.
416   * @param  CallbackID User callback identifier.
417   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
418   * @param  pPendingCbfn function pointer to be stored as callback.
419   * @retval HAL Status.
420   */
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef * hexti,EXTI_CallbackIDTypeDef CallbackID,void (* pPendingCbfn)(void))421 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
422 {
423   HAL_StatusTypeDef status = HAL_OK;
424 
425   switch (CallbackID)
426   {
427     case  HAL_EXTI_COMMON_CB_ID:
428       hexti->RisingCallback = pPendingCbfn;
429       hexti->FallingCallback = pPendingCbfn;
430       break;
431 
432     case  HAL_EXTI_RISING_CB_ID:
433       hexti->RisingCallback = pPendingCbfn;
434       break;
435 
436     case  HAL_EXTI_FALLING_CB_ID:
437       hexti->FallingCallback = pPendingCbfn;
438       break;
439 
440     default:
441       status = HAL_ERROR;
442       break;
443   }
444 
445   return status;
446 }
447 
448 
449 /**
450   * @brief  Store line number as handle private field.
451   * @param  hexti Exti handle.
452   * @param  ExtiLine Exti line number.
453   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
454   * @retval HAL Status.
455   */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)456 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
457 {
458   /* Check null pointer */
459   if(hexti == NULL)
460   {
461     return HAL_ERROR;
462   }
463 
464   /* Check parameters */
465   assert_param(IS_EXTI_LINE(ExtiLine));
466 
467   /* Store line number as handle private field */
468   hexti->Line = ExtiLine;
469 
470   return HAL_OK;
471 }
472 
473 
474 /**
475   * @}
476   */
477 
478 /** @addtogroup EXTI_Exported_Functions_Group2
479  *  @brief EXTI IO functions.
480  *
481 @verbatim
482  ===============================================================================
483                        ##### IO operation functions #####
484  ===============================================================================
485 
486 @endverbatim
487   * @{
488   */
489 
490 /**
491   * @brief  Handle EXTI interrupt request.
492   * @param  hexti Exti handle.
493   * @retval none.
494   */
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef * hexti)495 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
496 {
497   __IO uint32_t *regaddr;
498   uint32_t regval;
499   uint32_t maskline;
500   uint32_t offset;
501 
502   /* Compute line register offset and line mask */
503   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
504   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
505 
506   /* Get rising edge pending bit  */
507   regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
508   regval = (*regaddr & maskline);
509 
510   if(regval != 0U)
511   {
512     /* Clear pending bit */
513     *regaddr = maskline;
514 
515     /* Call rising callback */
516     if(hexti->RisingCallback != NULL)
517     {
518       hexti->RisingCallback();
519     }
520   }
521 
522   /* Get falling edge pending bit  */
523   regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
524   regval = (*regaddr & maskline);
525 
526   if(regval != 0U)
527   {
528     /* Clear pending bit */
529     *regaddr = maskline;
530 
531     /* Call rising callback */
532     if(hexti->FallingCallback != NULL)
533     {
534       hexti->FallingCallback();
535     }
536   }
537 }
538 
539 
540 /**
541   * @brief  Get interrupt pending bit of a dedicated line.
542   * @param  hexti Exti handle.
543   * @param  Edge Specify which pending edge as to be checked.
544   *         This parameter can be one of the following values:
545   *           @arg @ref EXTI_TRIGGER_RISING
546   *           @arg @ref EXTI_TRIGGER_FALLING
547   * @retval 1 if interrupt is pending else 0.
548   */
HAL_EXTI_GetPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)549 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
550 {
551   __IO uint32_t *regaddr;
552   uint32_t regval;
553   uint32_t linepos;
554   uint32_t maskline;
555   uint32_t offset;
556 
557   /* Check the parameters */
558   assert_param(IS_EXTI_LINE(hexti->Line));
559   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
560   assert_param(IS_EXTI_PENDING_EDGE(Edge));
561 
562   /* compute line register offset and line mask */
563   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
564   linepos = (hexti->Line & EXTI_PIN_MASK);
565   maskline = (1UL << linepos);
566 
567   if(Edge != EXTI_TRIGGER_RISING)
568   {
569     /* Get falling edge pending bit */
570     regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
571   }
572   else
573   {
574     /* Get rising edge pending bit */
575     regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
576   }
577 
578   /* return 1 if bit is set else 0 */
579   regval = ((*regaddr & maskline) >> linepos);
580   return regval;
581 }
582 
583 
584 /**
585   * @brief  Clear interrupt pending bit of a dedicated line.
586   * @param  hexti Exti handle.
587   * @param  Edge Specify which pending edge as to be clear.
588   *         This parameter can be one of the following values:
589   *           @arg @ref EXTI_TRIGGER_RISING
590   *           @arg @ref EXTI_TRIGGER_FALLING
591   * @retval None.
592   */
HAL_EXTI_ClearPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)593 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
594 {
595   __IO uint32_t *regaddr;
596   uint32_t maskline;
597   uint32_t offset;
598 
599   /* Check the parameters */
600   assert_param(IS_EXTI_LINE(hexti->Line));
601   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
602   assert_param(IS_EXTI_PENDING_EDGE(Edge));
603 
604   /* compute line register offset and line mask */
605   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
606   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
607 
608   if(Edge != EXTI_TRIGGER_RISING)
609   {
610     /* Get falling edge pending register address */
611     regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
612   }
613   else
614   {
615     /* Get falling edge pending register address */
616     regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
617   }
618 
619   /* Clear Pending bit */
620   *regaddr =  maskline;
621 }
622 
623 
624 /**
625   * @brief  Generate a software interrupt for a dedicated line.
626   * @param  hexti Exti handle.
627   * @retval None.
628   */
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef * hexti)629 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
630 {
631   __IO uint32_t *regaddr;
632   uint32_t maskline;
633   uint32_t offset;
634 
635   /* Check the parameters */
636   assert_param(IS_EXTI_LINE(hexti->Line));
637   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
638 
639   /* compute line register offset and line mask */
640   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
641   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
642 
643   regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
644   *regaddr = maskline;
645 }
646 
647 
648 /**
649   * @}
650   */
651 
652 /** @defgroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions
653  *  @brief EXTI attributes management functions.
654  *
655 @verbatim
656  ===============================================================================
657                        ##### EXTI attributes functions #####
658  ===============================================================================
659 
660 @endverbatim
661   * @{
662   */
663 
664 /**
665   * @brief  Configure the EXTI line attribute(s).
666   * @note   Available attributes are to secure EXTI line and set EXT line as privileged.
667   *         Default state is not secure and unprivileged access allowed.
668   * @note   Secure and non-secure attributes can only be set from the secure
669   *         state when the system implements the security (TZEN=1).
670   * @note   Security and privilege attributes can be set independently.
671   * @param  ExtiLine Exti line number.
672   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
673   * @param  LineAttributes can be one or a combination of the following values:
674   *            @arg @ref EXTI_LINE_PRIV         Privileged-only access
675   *            @arg @ref EXTI_LINE_NPRIV        Privileged/Non-privileged access
676   *            @arg @ref EXTI_LINE_SEC          Secure-only access
677   *            @arg @ref EXTI_LINE_NSEC         Secure/Non-secure access
678   * @retval None
679   */
HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine,uint32_t LineAttributes)680 void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes)
681 {
682   __IO uint32_t *regaddr;
683   uint32_t regval;
684   uint32_t linepos;
685   uint32_t maskline;
686   uint32_t offset;
687 
688   /* Check the parameters */
689   assert_param(IS_EXTI_LINE(ExtiLine));
690   assert_param(IS_EXTI_LINE_ATTRIBUTES(LineAttributes));
691 
692   /* compute line register offset and line mask */
693   offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
694   linepos = (ExtiLine & EXTI_PIN_MASK);
695   maskline = (1UL << linepos);
696 
697   /* Configure privilege or non-privilege attributes */
698   regaddr = (&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
699   regval = *regaddr;
700 
701   /* Mask or set line */
702   if((LineAttributes & EXTI_LINE_PRIV) == EXTI_LINE_PRIV)
703   {
704     regval |= maskline;
705   }
706   else if((LineAttributes & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)
707   {
708     regval &= ~maskline;
709   }
710   else
711   {
712     /* do nothing */
713   }
714 
715   /* Store privilege or non-privilege attribute */
716   *regaddr = regval;
717 
718 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
719 
720   /* Configure secure or non-secure attributes */
721   regaddr = (&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
722   regval = *regaddr;
723 
724   /* Mask or set line */
725   if((LineAttributes & EXTI_LINE_SEC) == EXTI_LINE_SEC)
726   {
727     regval |= maskline;
728   }
729   else if((LineAttributes & EXTI_LINE_NSEC) == EXTI_LINE_NSEC)
730   {
731     regval &= ~maskline;
732   }
733   else
734   {
735     /* do nothing */
736   }
737 
738   /* Store secure or non-secure attribute */
739   *regaddr = regval;
740 
741 #endif /* __ARM_FEATURE_CMSE */
742 }
743 
744 /**
745   * @brief  Get the EXTI line attribute(s).
746   * @note   Secure and non-secure attributes are only available from secure state
747   *         when the system implements the security (TZEN=1)
748   * @param  ExtiLine Exti line number.
749   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
750   * @param  pLineAttributes: pointer to return line attributes.
751   * @retval HAL Status.
752   */
HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine,uint32_t * pLineAttributes)753 HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes)
754 {
755   __IO uint32_t *regaddr;
756   uint32_t linepos;
757   uint32_t maskline;
758   uint32_t offset;
759   uint32_t attributes;
760 
761   /* Check null pointer */
762   if(pLineAttributes == NULL)
763   {
764     return HAL_ERROR;
765   }
766 
767   /* Check the parameters */
768   assert_param(IS_EXTI_LINE(ExtiLine));
769 
770   /* Compute line register offset and line mask */
771   offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
772   linepos = (ExtiLine & EXTI_PIN_MASK);
773   maskline = (1UL << linepos);
774 
775   /* Get privilege or non-privilege attribute */
776   regaddr = (&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
777 
778   if((*regaddr & maskline) != 0U)
779   {
780     attributes = EXTI_LINE_PRIV;
781   }
782   else
783   {
784     attributes = EXTI_LINE_NPRIV;
785   }
786 
787 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
788 
789   /* Get secure or non-secure attribute */
790   regaddr = (&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
791 
792   if((*regaddr & maskline) != 0U)
793   {
794     attributes |= EXTI_LINE_SEC;
795   }
796   else
797   {
798     attributes |= EXTI_LINE_NSEC;
799   }
800 
801 #endif /* __ARM_FEATURE_CMSE */
802 
803   /* return value */
804   *pLineAttributes = attributes;
805 
806   return HAL_OK;
807 }
808 
809 /**
810   * @}
811   */
812 
813 /**
814   * @}
815   */
816 
817 #endif /* HAL_EXTI_MODULE_ENABLED */
818 /**
819   * @}
820   */
821 
822 /**
823   * @}
824   */
825