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