1 /**
2 ******************************************************************************
3 * @file stm32h5xx_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 /* Includes ------------------------------------------------------------------*/
86 #include "stm32h5xx_hal.h"
87
88 /** @addtogroup STM32H5xx_HAL_Driver
89 * @{
90 */
91
92 /** @addtogroup EXTI
93 * @{
94 */
95
96 #ifdef HAL_EXTI_MODULE_ENABLED
97
98 /* Private typedef -----------------------------------------------------------*/
99 /* Private defines ------------------------------------------------------------*/
100 /** @defgroup EXTI_Private_Constants EXTI Private Constants
101 * @{
102 */
103 #define EXTI_MODE_OFFSET 0x04U /* 0x10: byte offset between: IMR1/EMR1 and IMR2/EMR2 registers */
104 #define EXTI_CONFIG_OFFSET 0x08U /* 0x20: byte offset between Rising1/Falling1 and Rising2/Falling2
105 configuration registers */
106 #define EXTI_PRIVCFGR_OFFSET 0x08U /* 0x20: byte offset between PRIVCFGR1 and PRIVCFGR2 registers */
107 #define EXTI_SECCFGR_OFFSET 0x08U /* 0x20: byte offset between SECCFGR1 and 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 __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 /* Get default Trigger and GPIOSel configuration */
317 pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
318 pExtiConfig->GPIOSel = 0x00u;
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 = (__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 }
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 = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
379 regval = (*regaddr & ~maskline);
380 *regaddr = regval;
381
382 /* 2] Clear event mode */
383 regaddr = (__IO uint32_t *)(&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 = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
391 regval = (*regaddr & ~maskline);
392 *regaddr = regval;
393
394 regaddr = (__IO uint32_t *)(&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) & 0x03UL];
404 regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
405 EXTI->EXTICR[(linepos >> 2U) & 0x03UL] = 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,
422 void (*pPendingCbfn)(void))
423 {
424 HAL_StatusTypeDef status = HAL_OK;
425
426 switch (CallbackID)
427 {
428 case HAL_EXTI_COMMON_CB_ID:
429 hexti->RisingCallback = pPendingCbfn;
430 hexti->FallingCallback = pPendingCbfn;
431 break;
432
433 case HAL_EXTI_RISING_CB_ID:
434 hexti->RisingCallback = pPendingCbfn;
435 break;
436
437 case HAL_EXTI_FALLING_CB_ID:
438 hexti->FallingCallback = pPendingCbfn;
439 break;
440
441 default:
442 status = HAL_ERROR;
443 break;
444 }
445
446 return status;
447 }
448
449
450 /**
451 * @brief Store line number as handle private field.
452 * @param hexti Exti handle.
453 * @param ExtiLine Exti line number.
454 * This parameter can be from 0 to @ref EXTI_LINE_NB.
455 * @retval HAL Status.
456 */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)457 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
458 {
459 /* Check the parameters */
460 assert_param(IS_EXTI_LINE(ExtiLine));
461
462 /* Check null pointer */
463 if (hexti == NULL)
464 {
465 return HAL_ERROR;
466 }
467 else
468 {
469 /* Store line number as handle private field */
470 hexti->Line = ExtiLine;
471
472 return HAL_OK;
473 }
474 }
475
476
477 /**
478 * @}
479 */
480
481 /** @addtogroup EXTI_Exported_Functions_Group2
482 * @brief EXTI IO functions.
483 *
484 @verbatim
485 ===============================================================================
486 ##### IO operation functions #####
487 ===============================================================================
488
489 @endverbatim
490 * @{
491 */
492
493 /**
494 * @brief Handle EXTI interrupt request.
495 * @param hexti Exti handle.
496 * @retval none.
497 */
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef * hexti)498 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
499 {
500 __IO uint32_t *regaddr;
501 uint32_t regval;
502 uint32_t maskline;
503 uint32_t offset;
504
505 /* Compute line register offset and line mask */
506 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
507 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
508
509 /* Get rising edge pending bit */
510 regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
511 regval = (*regaddr & maskline);
512
513 if (regval != 0U)
514 {
515 /* Clear pending bit */
516 *regaddr = maskline;
517
518 /* Call rising callback */
519 if (hexti->RisingCallback != NULL)
520 {
521 hexti->RisingCallback();
522 }
523 }
524
525 /* Get falling edge pending bit */
526 regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
527 regval = (*regaddr & maskline);
528
529 if (regval != 0U)
530 {
531 /* Clear pending bit */
532 *regaddr = maskline;
533
534 /* Call rising callback */
535 if (hexti->FallingCallback != NULL)
536 {
537 hexti->FallingCallback();
538 }
539 }
540 }
541
542
543 /**
544 * @brief Get interrupt pending bit of a dedicated line.
545 * @param hexti Exti handle.
546 * @param Edge Specify which pending edge as to be checked.
547 * This parameter can be one of the following values:
548 * @arg @ref EXTI_TRIGGER_RISING
549 * @arg @ref EXTI_TRIGGER_FALLING
550 * @retval 1 if interrupt is pending else 0.
551 */
HAL_EXTI_GetPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)552 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
553 {
554 __IO uint32_t *regaddr;
555 uint32_t regval;
556 uint32_t linepos;
557 uint32_t maskline;
558 uint32_t offset;
559
560 /* Check the parameters */
561 assert_param(IS_EXTI_LINE(hexti->Line));
562 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
563 assert_param(IS_EXTI_PENDING_EDGE(Edge));
564
565 /* compute line register offset and line mask */
566 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
567 linepos = (hexti->Line & EXTI_PIN_MASK);
568 maskline = (1UL << linepos);
569
570 if (Edge != EXTI_TRIGGER_RISING)
571 {
572 /* Get falling edge pending bit */
573 regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
574 }
575 else
576 {
577 /* Get rising edge pending bit */
578 regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
579 }
580
581 /* return 1 if bit is set else 0 */
582 regval = ((*regaddr & maskline) >> linepos);
583 return regval;
584 }
585
586
587 /**
588 * @brief Clear interrupt pending bit of a dedicated line.
589 * @param hexti Exti handle.
590 * @param Edge Specify which pending edge as to be clear.
591 * This parameter can be one of the following values:
592 * @arg @ref EXTI_TRIGGER_RISING
593 * @arg @ref EXTI_TRIGGER_FALLING
594 * @retval None.
595 */
HAL_EXTI_ClearPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)596 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
597 {
598 __IO uint32_t *regaddr;
599 uint32_t maskline;
600 uint32_t offset;
601
602 /* Check the parameters */
603 assert_param(IS_EXTI_LINE(hexti->Line));
604 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
605 assert_param(IS_EXTI_PENDING_EDGE(Edge));
606
607 /* compute line register offset and line mask */
608 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
609 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
610
611 if (Edge != EXTI_TRIGGER_RISING)
612 {
613 /* Get falling edge pending register address */
614 regaddr = (__IO uint32_t *)(&EXTI->FPR1 + (EXTI_CONFIG_OFFSET * offset));
615 }
616 else
617 {
618 /* Get falling edge pending register address */
619 regaddr = (__IO uint32_t *)(&EXTI->RPR1 + (EXTI_CONFIG_OFFSET * offset));
620 }
621
622 /* Clear Pending bit */
623 *regaddr = maskline;
624 }
625
626
627 /**
628 * @brief Generate a software interrupt for a dedicated line.
629 * @param hexti Exti handle.
630 * @retval None.
631 */
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef * hexti)632 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
633 {
634 __IO uint32_t *regaddr;
635 uint32_t maskline;
636 uint32_t offset;
637
638 /* Check the parameters */
639 assert_param(IS_EXTI_LINE(hexti->Line));
640 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
641
642 /* compute line register offset and line mask */
643 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
644 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
645
646 regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
647 *regaddr = maskline;
648 }
649
650
651 /**
652 * @}
653 */
654
655 /** @defgroup EXTI_Exported_Functions_Group3 EXTI line attributes management functions
656 * @brief EXTI attributes management functions.
657 *
658 @verbatim
659 ===============================================================================
660 ##### EXTI attributes functions #####
661 ===============================================================================
662
663 @endverbatim
664 * @{
665 */
666
667 /**
668 * @brief Configure the EXTI line attribute(s).
669 * @note Available attributes are to secure EXTI line and set EXT line as privileged.
670 * Default state is not secure and unprivileged access allowed.
671 * @note Secure and non-secure attributes can only be set from the secure
672 * state when the system implements the security (TZEN=1).
673 * @note Security and privilege attributes can be set independently.
674 * @param ExtiLine Exti line number.
675 * This parameter can be from 0 to @ref EXTI_LINE_NB.
676 * @param LineAttributes can be one or a combination of the following values:
677 * @arg @ref EXTI_LINE_PRIV Privileged-only access
678 * @arg @ref EXTI_LINE_NPRIV Privileged/Non-privileged access
679 * @arg @ref EXTI_LINE_SEC Secure-only access
680 * @arg @ref EXTI_LINE_NSEC Secure/Non-secure access
681 * @retval None
682 */
HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine,uint32_t LineAttributes)683 void HAL_EXTI_ConfigLineAttributes(uint32_t ExtiLine, uint32_t LineAttributes)
684 {
685 __IO uint32_t *regaddr;
686 uint32_t regval;
687 uint32_t linepos;
688 uint32_t maskline;
689 uint32_t offset;
690
691 /* Check the parameters */
692 assert_param(IS_EXTI_LINE(ExtiLine));
693 assert_param(IS_EXTI_LINE_ATTRIBUTES(LineAttributes));
694
695 /* compute line register offset and line mask */
696 offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
697 linepos = (ExtiLine & EXTI_PIN_MASK);
698 maskline = (1UL << linepos);
699
700 /* Configure privilege or non-privilege attributes */
701 regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
702 regval = *regaddr;
703
704 /* Mask or set line */
705 if ((LineAttributes & EXTI_LINE_PRIV) == EXTI_LINE_PRIV)
706 {
707 regval |= maskline;
708 }
709 else if ((LineAttributes & EXTI_LINE_NPRIV) == EXTI_LINE_NPRIV)
710 {
711 regval &= ~maskline;
712 }
713 else
714 {
715 /* do nothing */
716 }
717
718 /* Store privilege or non-privilege attribute */
719 *regaddr = regval;
720
721 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
722
723 /* Configure secure or non-secure attributes */
724 regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
725 regval = *regaddr;
726
727 /* Mask or set line */
728 if ((LineAttributes & EXTI_LINE_SEC) == EXTI_LINE_SEC)
729 {
730 regval |= maskline;
731 }
732 else if ((LineAttributes & EXTI_LINE_NSEC) == EXTI_LINE_NSEC)
733 {
734 regval &= ~maskline;
735 }
736 else
737 {
738 /* do nothing */
739 }
740
741 /* Store secure or non-secure attribute */
742 *regaddr = regval;
743
744 #endif /* __ARM_FEATURE_CMSE */
745 }
746
747 /**
748 * @brief Get the EXTI line attribute(s).
749 * @note Secure and non-secure attributes are only available from secure state
750 * when the system implements the security (TZEN=1)
751 * @param ExtiLine Exti line number.
752 * This parameter can be from 0 to @ref EXTI_LINE_NB.
753 * @param pLineAttributes: pointer to return line attributes.
754 * @retval HAL Status.
755 */
HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine,uint32_t * pLineAttributes)756 HAL_StatusTypeDef HAL_EXTI_GetConfigLineAttributes(uint32_t ExtiLine, uint32_t *pLineAttributes)
757 {
758 __IO uint32_t *regaddr;
759 uint32_t linepos;
760 uint32_t maskline;
761 uint32_t offset;
762 uint32_t attributes;
763
764 /* Check null pointer */
765 if (pLineAttributes == NULL)
766 {
767 return HAL_ERROR;
768 }
769
770 /* Check the parameters */
771 assert_param(IS_EXTI_LINE(ExtiLine));
772
773 /* Compute line register offset and line mask */
774 offset = ((ExtiLine & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
775 linepos = (ExtiLine & EXTI_PIN_MASK);
776 maskline = (1UL << linepos);
777
778 /* Get privilege or non-privilege attribute */
779 regaddr = (__IO uint32_t *)(&EXTI->PRIVCFGR1 + (EXTI_PRIVCFGR_OFFSET * offset));
780
781 if ((*regaddr & maskline) != 0U)
782 {
783 attributes = EXTI_LINE_PRIV;
784 }
785 else
786 {
787 attributes = EXTI_LINE_NPRIV;
788 }
789
790 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
791
792 /* Get secure or non-secure attribute */
793 regaddr = (__IO uint32_t *)(&EXTI->SECCFGR1 + (EXTI_SECCFGR_OFFSET * offset));
794
795 if ((*regaddr & maskline) != 0U)
796 {
797 attributes |= EXTI_LINE_SEC;
798 }
799 else
800 {
801 attributes |= EXTI_LINE_NSEC;
802 }
803
804 #endif /* __ARM_FEATURE_CMSE */
805
806 /* return value */
807 *pLineAttributes = attributes;
808
809 return HAL_OK;
810 }
811 #if defined (EXTI_LOCKR_LOCK)
812 #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
813 /**
814 * @brief Lock the global EXTI security and privilege configuration.
815 * @retval HAL Status.
816 */
HAL_EXTI_LockConfigAttributes(void)817 HAL_StatusTypeDef HAL_EXTI_LockConfigAttributes(void)
818 {
819 EXTI->LOCKR = EXTI_ATTRIBUTES_LOCKED;
820
821 return HAL_OK;
822 }
823
824 /**
825 * @brief Get the global EXTI security and privilege lock configuration.
826 * @param pLockState : Pointer to returned security and privilege configuration
827 * @retval HAL Status.
828 */
HAL_EXTI_GetLockConfigAttributes(uint32_t * const pLockState)829 HAL_StatusTypeDef HAL_EXTI_GetLockConfigAttributes(uint32_t *const pLockState)
830 {
831 uint32_t attributes;
832 __IO uint32_t *regaddr;
833
834 /* Check null pointer */
835 if (pLockState == NULL)
836 {
837 return HAL_ERROR;
838 }
839
840 /* Get security and privilege configuration */
841 regaddr = (__IO uint32_t *)(&EXTI->LOCKR);
842
843 if ((*regaddr & EXTI_LOCKR_LOCK) != 0U)
844 {
845 attributes = EXTI_ATTRIBUTES_LOCKED;
846 }
847 else
848 {
849 attributes = EXTI_ATTRIBUTES_UNLOCKED;
850 }
851
852 /* return value */
853 *pLockState = attributes;
854
855 return HAL_OK;
856 }
857 #endif /* defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) */
858 #endif /* defined (EXTI_LOCKR_LOCK) */
859 /**
860 * @}
861 */
862
863 /**
864 * @}
865 */
866
867 #endif /* HAL_EXTI_MODULE_ENABLED */
868 /**
869 * @}
870 */
871
872 /**
873 * @}
874 */
875