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   @verbatim
13   ==============================================================================
14                     ##### EXTI Peripheral features #####
15   ==============================================================================
16   [..]
17     (+) Each Exti line can be configured within this driver.
18 
19     (+) Exti line can be configured in 3 different modes
20         (++) Interrupt
21         (++) Event
22         (++) Both of them
23 
24     (+) Configurable Exti lines can be configured with 3 different triggers
25         (++) Rising
26         (++) Falling
27         (++) Both of them
28 
29     (+) When set in interrupt mode, configurable Exti lines have two different
30         interrupt pending registers which allow to distinguish which transition
31         occurs:
32         (++) Rising edge pending interrupt
33         (++) Falling
34 
35     (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
36         be selected through multiplexer.
37 
38                      ##### How to use this driver #####
39   ==============================================================================
40   [..]
41 
42     (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
43         (++) Choose the interrupt line number by setting "Line" member from
44              EXTI_ConfigTypeDef structure.
45         (++) Configure the interrupt and/or event mode using "Mode" member from
46              EXTI_ConfigTypeDef structure.
47         (++) For configurable lines, configure rising and/or falling trigger
48              "Trigger" member from EXTI_ConfigTypeDef structure.
49         (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
50              member from GPIO_InitTypeDef structure.
51 
52     (#) Get current Exti configuration of a dedicated line using
53         HAL_EXTI_GetConfigLine().
54         (++) Provide exiting handle as parameter.
55         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
56 
57     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
58         (++) Provide exiting handle as parameter.
59 
60     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
61         (++) Provide exiting handle as first parameter.
62         (++) Provide which callback will be registered using one value from
63              EXTI_CallbackIDTypeDef.
64         (++) Provide callback function pointer.
65 
66     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
67 
68     (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
69 
70     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
71 
72   @endverbatim
73   ******************************************************************************
74   * @attention
75   *
76   * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
77   * All rights reserved.</center></h2>
78   *
79   * This software component is licensed by ST under BSD 3-Clause license,
80   * the "License"; You may not use this file except in compliance with the
81   * License. You may obtain a copy of the License at:
82   *                        opensource.org/licenses/BSD-3-Clause
83   *
84   ******************************************************************************
85   */
86 
87 /* Includes ------------------------------------------------------------------*/
88 #include "stm32l5xx_hal.h"
89 
90 /** @addtogroup STM32L5xx_HAL_Driver
91   * @{
92   */
93 
94 /** @addtogroup EXTI
95   * @{
96   */
97 
98 #ifdef HAL_EXTI_MODULE_ENABLED
99 
100 /* Private typedef -----------------------------------------------------------*/
101 /* Private defines ------------------------------------------------------------*/
102 /** @defgroup EXTI_Private_Constants EXTI Private Constants
103   * @{
104   */
105 #define EXTI_MODE_OFFSET                    0x04U   /* byte offset between IMR/EMR registers */
106 #define EXTI_CONFIG_OFFSET                  0x08U   /* byte offset between Rising/Falling configuration registers */
107 #define EXTI_PRIVCFGR_OFFSET                0x04U   /* byte offset between PRIVCFGR1/PRIVCFGR2 registers */
108 #define EXTI_SECCFGR_OFFSET                 0x04U   /* byte offset between SECCFGR1/SECCFGR2 registers */
109 /**
110   * @}
111   */
112 
113 /* Private macros ------------------------------------------------------------*/
114 /* Private variables ---------------------------------------------------------*/
115 /* Private function prototypes -----------------------------------------------*/
116 /* Exported functions --------------------------------------------------------*/
117 
118 /** @addtogroup EXTI_Exported_Functions
119   * @{
120   */
121 
122 /** @addtogroup EXTI_Exported_Functions_Group1
123  *  @brief    Configuration functions
124  *
125 @verbatim
126  ===============================================================================
127               ##### Configuration functions #####
128  ===============================================================================
129 
130 @endverbatim
131   * @{
132   */
133 
134 /**
135   * @brief  Set configuration of a dedicated Exti line.
136   * @param  hexti Exti handle.
137   * @param  pExtiConfig Pointer on EXTI configuration to be set.
138   * @retval HAL Status.
139   */
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)140 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
141 {
142   __IO uint32_t *regaddr;
143   uint32_t regval;
144   uint32_t linepos;
145   uint32_t maskline;
146   uint32_t offset;
147 
148   /* Check null pointer */
149   if((hexti == NULL) || (pExtiConfig == NULL))
150   {
151     return HAL_ERROR;
152   }
153 
154   /* Check the parameters */
155   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
156   assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
157 
158   /* Assign line number to handle */
159   hexti->Line = pExtiConfig->Line;
160 
161   /* compute line register offset and line mask */
162   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
163   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
164   maskline = (1UL << linepos);
165 
166   /* Configure triggers for configurable lines */
167   if((pExtiConfig->Line & EXTI_CONFIG) != 0U)
168   {
169     assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
170 
171     /* Configure rising trigger */
172     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
173     regval = *regaddr;
174 
175     /* Mask or set line */
176     if((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0U)
177     {
178       regval |= maskline;
179     }
180     else
181     {
182       regval &= ~maskline;
183     }
184 
185     /* Store rising trigger mode */
186     *regaddr = regval;
187 
188     /* Configure falling trigger */
189     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
190     regval = *regaddr;
191 
192     /* Mask or set line */
193     if((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0U)
194     {
195       regval |= maskline;
196     }
197     else
198     {
199       regval &= ~maskline;
200     }
201 
202     /* Store falling trigger mode */
203     *regaddr = regval;
204 
205     /* Configure gpio port selection in case of gpio exti line */
206     if((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
207     {
208       assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
209       assert_param(IS_EXTI_GPIO_PIN(linepos));
210 
211       regval = EXTI->EXTICR[linepos >> 2U];
212       regval &= ~(0xFFU << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
213       regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
214       EXTI->EXTICR[linepos >> 2U] = regval;
215     }
216   }
217 
218   /* Configure interrupt mode : read current mode */
219   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
220   regval = *regaddr;
221 
222   /* Mask or set line */
223   if((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0U)
224   {
225     regval |= maskline;
226   }
227   else
228   {
229     regval &= ~maskline;
230   }
231 
232   /* Store interrupt mode */
233   *regaddr = regval;
234 
235   /* Configure event mode : read current mode */
236   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
237   regval = *regaddr;
238 
239   /* Mask or set line */
240   if((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0U)
241   {
242     regval |= maskline;
243   }
244   else
245   {
246     regval &= ~maskline;
247   }
248 
249   /* Store event mode */
250   *regaddr = regval;
251 
252   return HAL_OK;
253 }
254 
255 
256 /**
257   * @brief  Get configuration of a dedicated Exti line.
258   * @param  hexti Exti handle.
259   * @param  pExtiConfig Pointer on structure to store Exti configuration.
260   * @retval HAL Status.
261   */
HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)262 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
263 {
264   __IO uint32_t *regaddr;
265   uint32_t regval;
266   uint32_t linepos;
267   uint32_t maskline;
268   uint32_t offset;
269 
270   /* Check null pointer */
271   if((hexti == NULL) || (pExtiConfig == NULL))
272   {
273     return HAL_ERROR;
274   }
275 
276   /* Check the parameter */
277   assert_param(IS_EXTI_LINE(hexti->Line));
278 
279   /* Store handle line number to configiguration structure */
280   pExtiConfig->Line = hexti->Line;
281 
282   /* compute line register offset and line mask */
283   offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
284   linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
285   maskline = (1UL << linepos);
286 
287   /* 1] Get core mode : interrupt */
288   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
289   regval = *regaddr;
290 
291   /* Check if selected line is enable */
292   if((regval & maskline) != 0U)
293   {
294     pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
295   }
296   else
297   {
298     pExtiConfig->Mode = EXTI_MODE_NONE;
299   }
300 
301   /* Get event mode */
302   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
303   regval = *regaddr;
304 
305   /* Check if selected line is enable */
306   if((regval & maskline) != 0U)
307   {
308     pExtiConfig->Mode |= EXTI_MODE_EVENT;
309   }
310 
311   /* 2] Get trigger for configurable lines : rising */
312   if((pExtiConfig->Line & EXTI_CONFIG) != 0U)
313   {
314     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
315     regval = *regaddr;
316 
317     /* Check if configuration of selected line is enable */
318     if((regval & maskline) != 0U)
319     {
320       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
321     }
322     else
323     {
324       pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
325     }
326 
327     /* Get falling configuration */
328     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
329     regval = *regaddr;
330 
331     /* Check if configuration of selected line is enable */
332     if((regval & maskline) != 0U)
333     {
334       pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
335     }
336 
337     /* Get Gpio port selection for gpio lines */
338     if((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
339     {
340       assert_param(IS_EXTI_GPIO_PIN(linepos));
341 
342       regval = EXTI->EXTICR[linepos >> 2U];
343       pExtiConfig->GPIOSel = ((regval << (EXTI_EXTICR1_EXTI1_Pos * (3U - (linepos & 0x03U)))) >> 24U);
344     }
345     else
346     {
347       pExtiConfig->GPIOSel = 0U;
348     }
349   }
350   else
351   {
352     pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
353     pExtiConfig->GPIOSel = 0U;
354   }
355 
356   return HAL_OK;
357 }
358 
359 
360 /**
361   * @brief  Clear whole configuration of a dedicated Exti line.
362   * @param  hexti Exti handle.
363   * @retval HAL Status.
364   */
HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef * hexti)365 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
366 {
367   __IO uint32_t *regaddr;
368   uint32_t regval;
369   uint32_t linepos;
370   uint32_t maskline;
371   uint32_t offset;
372 
373   /* Check null pointer */
374   if(hexti == NULL)
375   {
376     return HAL_ERROR;
377   }
378 
379   /* Check the parameter */
380   assert_param(IS_EXTI_LINE(hexti->Line));
381 
382   /* compute line register offset and line mask */
383   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
384   linepos = (hexti->Line & EXTI_PIN_MASK);
385   maskline = (1UL << linepos);
386 
387   /* 1] Clear interrupt mode */
388   regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
389   regval = (*regaddr & ~maskline);
390   *regaddr = regval;
391 
392   /* 2] Clear event mode */
393   regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
394   regval = (*regaddr & ~maskline);
395   *regaddr = regval;
396 
397   /* 3] Clear triggers in case of configurable lines */
398   if((hexti->Line & EXTI_CONFIG) != 0U)
399   {
400     regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
401     regval = (*regaddr & ~maskline);
402     *regaddr = regval;
403 
404     regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
405     regval = (*regaddr & ~maskline);
406     *regaddr = regval;
407 
408     /* Get Gpio port selection for gpio lines */
409     if((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
410     {
411       assert_param(IS_EXTI_GPIO_PIN(linepos));
412 
413       regval = EXTI->EXTICR[linepos >> 2U];
414       regval &= ~(0xFFU << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
415       EXTI->EXTICR[linepos >> 2U] = regval;
416     }
417   }
418 
419   return HAL_OK;
420 }
421 
422 
423 /**
424   * @brief  Register callback for a dedicaated Exti line.
425   * @param  hexti Exti handle.
426   * @param  CallbackID User callback identifier.
427   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
428   * @param  pPendingCbfn function pointer to be stored as callback.
429   * @retval HAL Status.
430   */
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef * hexti,EXTI_CallbackIDTypeDef CallbackID,void (* pPendingCbfn)(void))431 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, 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 null pointer */
469   if(hexti == NULL)
470   {
471     return HAL_ERROR;
472   }
473 
474   /* Check parameters */
475   assert_param(IS_EXTI_LINE(ExtiLine));
476 
477   /* Store line number as handle private field */
478   hexti->Line = ExtiLine;
479 
480   return HAL_OK;
481 }
482 
483 
484 /**
485   * @}
486   */
487 
488 /** @addtogroup EXTI_Exported_Functions_Group2
489  *  @brief EXTI IO functions.
490  *
491 @verbatim
492  ===============================================================================
493                        ##### IO operation functions #####
494  ===============================================================================
495 
496 @endverbatim
497   * @{
498   */
499 
500 /**
501   * @brief  Handle EXTI interrupt request.
502   * @param  hexti Exti handle.
503   * @retval none.
504   */
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef * hexti)505 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
506 {
507   __IO uint32_t *regaddr;
508   uint32_t regval;
509   uint32_t maskline;
510   uint32_t offset;
511 
512   /* Compute line register offset and line mask */
513   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
514   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
515 
516   /* Get rising edge pending bit  */
517   regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
518   regval = (*regaddr & maskline);
519 
520   if(regval != 0U)
521   {
522     /* Clear pending bit */
523     *regaddr = maskline;
524 
525     /* Call rising callback */
526     if(hexti->RisingCallback != NULL)
527     {
528       hexti->RisingCallback();
529     }
530   }
531 
532   /* Get falling edge pending bit  */
533   regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
534   regval = (*regaddr & maskline);
535 
536   if(regval != 0U)
537   {
538     /* Clear pending bit */
539     *regaddr = maskline;
540 
541     /* Call rising callback */
542     if(hexti->FallingCallback != NULL)
543     {
544       hexti->FallingCallback();
545     }
546   }
547 }
548 
549 
550 /**
551   * @brief  Get interrupt pending bit of a dedicated line.
552   * @param  hexti Exti handle.
553   * @param  Edge Specify which pending edge as to be checked.
554   *         This parameter can be one of the following values:
555   *           @arg @ref EXTI_TRIGGER_RISING
556   *           @arg @ref EXTI_TRIGGER_FALLING
557   * @retval 1 if interrupt is pending else 0.
558   */
HAL_EXTI_GetPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)559 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
560 {
561   __IO uint32_t *regaddr;
562   uint32_t regval;
563   uint32_t linepos;
564   uint32_t maskline;
565   uint32_t offset;
566 
567   /* Check the parameters */
568   assert_param(IS_EXTI_LINE(hexti->Line));
569   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
570   assert_param(IS_EXTI_PENDING_EDGE(Edge));
571 
572   /* compute line register offset and line mask */
573   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
574   linepos = (hexti->Line & EXTI_PIN_MASK);
575   maskline = (1UL << linepos);
576 
577   if(Edge != EXTI_TRIGGER_RISING)
578   {
579     /* Get falling edge pending bit */
580     regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
581   }
582   else
583   {
584     /* Get rising edge pending bit */
585     regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
586   }
587 
588   /* return 1 if bit is set else 0 */
589   regval = ((*regaddr & maskline) >> linepos);
590   return regval;
591 }
592 
593 
594 /**
595   * @brief  Clear interrupt pending bit of a dedicated line.
596   * @param  hexti Exti handle.
597   * @param  Edge Specify which pending edge as to be clear.
598   *         This parameter can be one of the following values:
599   *           @arg @ref EXTI_TRIGGER_RISING
600   *           @arg @ref EXTI_TRIGGER_FALLING
601   * @retval None.
602   */
HAL_EXTI_ClearPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)603 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
604 {
605   __IO uint32_t *regaddr;
606   uint32_t maskline;
607   uint32_t offset;
608 
609   /* Check the parameters */
610   assert_param(IS_EXTI_LINE(hexti->Line));
611   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
612   assert_param(IS_EXTI_PENDING_EDGE(Edge));
613 
614   /* compute line register offset and line mask */
615   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
616   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
617 
618   if(Edge != EXTI_TRIGGER_RISING)
619   {
620     /* Get falling edge pending register address */
621     regaddr = (&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
622   }
623   else
624   {
625     /* Get falling edge pending register address */
626     regaddr = (&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
627   }
628 
629   /* Clear Pending bit */
630   *regaddr =  maskline;
631 }
632 
633 
634 /**
635   * @brief  Generate a software interrupt for a dedicated line.
636   * @param  hexti Exti handle.
637   * @retval None.
638   */
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef * hexti)639 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
640 {
641   __IO uint32_t *regaddr;
642   uint32_t maskline;
643   uint32_t offset;
644 
645   /* Check the parameters */
646   assert_param(IS_EXTI_LINE(hexti->Line));
647   assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
648 
649   /* compute line register offset and line mask */
650   offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
651   maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
652 
653   regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
654   *regaddr = maskline;
655 }
656 
657 
658 /**
659   * @}
660   */
661 
662 /** @defgroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions
663  *  @brief EXTI attributes management functions.
664  *
665 @verbatim
666  ===============================================================================
667                        ##### EXTI attributes functions #####
668  ===============================================================================
669 
670 @endverbatim
671   * @{
672   */
673 
674 /**
675   * @brief  Configure the EXTI line attribute(s).
676   * @note   Available attributes are to secure EXTI line and set EXT line as privileged.
677   *         Default state is not secure and unprivileged access allowed.
678   * @note   Secure and non-secure attributes can only be set from the secure
679   *         state when the system implements the security (TZEN=1).
680   * @note   Security and privilege attributes can be set independently.
681   * @param  ExtiLine Exti line number.
682   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
683   * @param  LineAttributes can be one or a combination of the following values:
684   *            @arg @ref EXTI_LINE_PRIV         Privileged-only access
685   *            @arg @ref EXTI_LINE_NPRIV        Privileged/Non-privileged access
686   *            @arg @ref EXTI_LINE_SEC          Secure-only access
687   *            @arg @ref EXTI_LINE_NSEC         Secure/Non-secure access
688   * @retval None
689   */
HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine,uint32_t LineAttributes)690 void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes)
691 {
692   __IO uint32_t *regaddr;
693   uint32_t regval;
694   uint32_t linepos;
695   uint32_t maskline;
696   uint32_t offset;
697 
698   /* Check the parameters */
699   assert_param(IS_EXTI_LINE(ExtiLine));
700   assert_param(IS_EXTI_LINE_ATTRIBUTES(LineAttributes));
701 
702   /* compute line register offset and line mask */
703   offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
704   linepos = (ExtiLine & EXTI_PIN_MASK);
705   maskline = (1UL << linepos);
706 
707   /* Configure privilege or non-privilege attributes */
708   regaddr = (&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
709   regval = *regaddr;
710 
711   /* Mask or set line */
712   if((LineAttributes & EXTI_LINE_PRIV) == EXTI_LINE_PRIV)
713   {
714     regval |= maskline;
715   }
716   else if((LineAttributes & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)
717   {
718     regval &= ~maskline;
719   }
720   else
721   {
722     /* do nothing */
723   }
724 
725   /* Store privilege or non-privilege attribute */
726   *regaddr = regval;
727 
728 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
729 
730   /* Configure secure or non-secure attributes */
731   regaddr = (&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 
751 #endif /* __ARM_FEATURE_CMSE */
752 }
753 
754 /**
755   * @brief  Get the EXTI line attribute(s).
756   * @note   Secure and non-secure attributes are only available from secure state
757   *         when the system implements the security (TZEN=1)
758   * @param  ExtiLine Exti line number.
759   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
760   * @param  pLineAttributes: pointer to return line attributes.
761   * @retval HAL Status.
762   */
HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine,uint32_t * pLineAttributes)763 HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes)
764 {
765   __IO uint32_t *regaddr;
766   uint32_t linepos;
767   uint32_t maskline;
768   uint32_t offset;
769   uint32_t attributes;
770 
771   /* Check null pointer */
772   if(pLineAttributes == NULL)
773   {
774     return HAL_ERROR;
775   }
776 
777   /* Check the parameters */
778   assert_param(IS_EXTI_LINE(ExtiLine));
779 
780   /* Compute line register offset and line mask */
781   offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
782   linepos = (ExtiLine & EXTI_PIN_MASK);
783   maskline = (1UL << linepos);
784 
785   /* Get privilege or non-privilege attribute */
786   regaddr = (&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
787 
788   if((*regaddr & maskline) != 0U)
789   {
790     attributes = EXTI_LINE_PRIV;
791   }
792   else
793   {
794     attributes = EXTI_LINE_NPRIV;
795   }
796 
797 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
798 
799   /* Get secure or non-secure attribute */
800   regaddr = (&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
801 
802   if((*regaddr & maskline) != 0U)
803   {
804     attributes |= EXTI_LINE_SEC;
805   }
806   else
807   {
808     attributes |= EXTI_LINE_NSEC;
809   }
810 
811 #endif /* __ARM_FEATURE_CMSE */
812 
813   /* return value */
814   *pLineAttributes = attributes;
815 
816   return HAL_OK;
817 }
818 
819 /**
820   * @}
821   */
822 
823 /**
824   * @}
825   */
826 
827 #endif /* HAL_EXTI_MODULE_ENABLED */
828 /**
829   * @}
830   */
831 
832 /**
833   * @}
834   */
835 
836 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
837