1 /**
2 ******************************************************************************
3 * @file stm32wbaxx_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) 2022 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 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_GetConfigLine().
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_GetPending().
79
80 (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
81
82 @endverbatim
83 ******************************************************************************
84 */
85
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32wbaxx_hal.h"
88
89 /** @addtogroup STM32WBAxx_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 = (__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(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)261 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(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 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 = (__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_EXTI1_Pos;
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 dedicaated 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, void (*pPendingCbfn)(void))
431 {
432 HAL_StatusTypeDef status = HAL_OK;
433
434 switch (CallbackID)
435 {
436 case HAL_EXTI_COMMON_CB_ID:
437 hexti->RisingCallback = pPendingCbfn;
438 hexti->FallingCallback = pPendingCbfn;
439 break;
440
441 case HAL_EXTI_RISING_CB_ID:
442 hexti->RisingCallback = pPendingCbfn;
443 break;
444
445 case HAL_EXTI_FALLING_CB_ID:
446 hexti->FallingCallback = pPendingCbfn;
447 break;
448
449 default:
450 status = HAL_ERROR;
451 break;
452 }
453
454 return status;
455 }
456
457
458 /**
459 * @brief Store line number as handle private field.
460 * @param hexti Exti handle.
461 * @param ExtiLine Exti line number.
462 * This parameter can be from 0 to @ref EXTI_LINE_NB.
463 * @retval HAL Status.
464 */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)465 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
466 {
467 /* Check the parameters */
468 assert_param(IS_EXTI_LINE(ExtiLine));
469
470 /* Check null pointer */
471 if (hexti == NULL)
472 {
473 return HAL_ERROR;
474 }
475 else
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(const EXTI_HandleTypeDef * hexti)505 void HAL_EXTI_IRQHandler(const 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 = (__IO uint32_t *)(&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 = (__IO uint32_t *)(&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(const EXTI_HandleTypeDef * hexti,uint32_t Edge)559 uint32_t HAL_EXTI_GetPending(const EXTI_HandleTypeDef *hexti, uint32_t Edge)
560 {
561 const __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 = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
581 }
582 else
583 {
584 /* Get rising edge pending bit */
585 regaddr = (__IO uint32_t *)(&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(const EXTI_HandleTypeDef * hexti,uint32_t Edge)603 void HAL_EXTI_ClearPending(const 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 = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
622 }
623 else
624 {
625 /* Get falling edge pending register address */
626 regaddr = (__IO uint32_t *)(&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(const EXTI_HandleTypeDef * hexti)639 void HAL_EXTI_GenerateSWI(const 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 = (__IO uint32_t *)(&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 #if defined(EXTI_SECCFGR1_SEC0)
675 /**
676 * @brief Configure the EXTI line attribute(s).
677 * @note Available attributes are to secure EXTI line and set EXT line as privileged.
678 * Default state is not secure and unprivileged access allowed.
679 * @note Secure and non-secure attributes can only be set from the secure
680 * state when the system implements the security (TZEN=1).
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 (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
730
731 /* Configure secure or non-secure attributes */
732 regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
733 regval = *regaddr;
734
735 /* Mask or set line */
736 if ((LineAttributes & EXTI_LINE_SEC) == EXTI_LINE_SEC)
737 {
738 regval |= maskline;
739 }
740 else if ((LineAttributes & EXTI_LINE_NSEC) == EXTI_LINE_NSEC)
741 {
742 regval &= ~maskline;
743 }
744 else
745 {
746 /* do nothing */
747 }
748
749 /* Store secure or non-secure attribute */
750 *regaddr = regval;
751
752 #endif /* __ARM_FEATURE_CMSE */
753 }
754
755 /**
756 * @brief Get the EXTI line attribute(s).
757 * @note Secure and non-secure attributes are only available from secure state
758 * when the system implements the security (TZEN=1)
759 * @param ExtiLine Exti line number.
760 * This parameter can be from 0 to @ref EXTI_LINE_NB.
761 * @param pLineAttributes: pointer to return line attributes.
762 * @retval HAL Status.
763 */
HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine,uint32_t * pLineAttributes)764 HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes)
765 {
766 const __IO uint32_t *regaddr;
767 uint32_t linepos;
768 uint32_t maskline;
769 uint32_t offset;
770 uint32_t attributes;
771
772 /* Check null pointer */
773 if (pLineAttributes == NULL)
774 {
775 return HAL_ERROR;
776 }
777
778 /* Check the parameters */
779 assert_param(IS_EXTI_LINE(ExtiLine));
780
781 /* Compute line register offset and line mask */
782 offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
783 linepos = (ExtiLine & EXTI_PIN_MASK);
784 maskline = (1UL << linepos);
785
786 /* Get privilege or non-privilege attribute */
787 regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
788
789 if ((*regaddr & maskline) != 0U)
790 {
791 attributes = EXTI_LINE_PRIV;
792 }
793 else
794 {
795 attributes = EXTI_LINE_NPRIV;
796 }
797
798 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
799
800 /* Get secure or non-secure attribute */
801 regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
802
803 if ((*regaddr & maskline) != 0U)
804 {
805 attributes |= EXTI_LINE_SEC;
806 }
807 else
808 {
809 attributes |= EXTI_LINE_NSEC;
810 }
811
812 #endif /* __ARM_FEATURE_CMSE */
813
814 /* return value */
815 *pLineAttributes = attributes;
816
817 return HAL_OK;
818 }
819 #endif /* #if defined(EXTI_SECCFGR1_SEC0) */
820
821 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
822 /**
823 * @brief Lock the secure and privilege configuration registers.
824 * @retval None
825 */
HAL_EXTI_LockAttributes(void)826 void HAL_EXTI_LockAttributes(void)
827 {
828 SET_BIT(EXTI->LOCKR, EXTI_LOCKR_LOCK);
829 }
830
831 /**
832 * @brief Return the secure and privilege configuration registers LOCK status
833 * @retval 1 if the secure and privilege configuration registers have been locked else 0.
834 */
HAL_EXTI_GetLockAttributes(void)835 uint32_t HAL_EXTI_GetLockAttributes(void)
836 {
837 return READ_BIT(EXTI->LOCKR, EXTI_LOCKR_LOCK);
838 }
839 #endif /* __ARM_FEATURE_CMSE */
840
841 /**
842 * @}
843 */
844
845 /**
846 * @}
847 */
848
849 #endif /* HAL_EXTI_MODULE_ENABLED */
850 /**
851 * @}
852 */
853
854 /**
855 * @}
856 */
857
858