blob: fe54a0374fb5973f4cd3fdbf28ab83e4fb42b4b4 [file] [log] [blame]
Ali Labbeneaeda37f2020-01-28 14:50:48 +01001/**
2 ******************************************************************************
3 * @file stm32h7xx_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 *
rihab kouki9439ae72021-12-14 12:56:29 +010011 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2017 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 ******************************************************************************
Ali Labbeneaeda37f2020-01-28 14:50:48 +010022 @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 (CORE1 or CORE2 in case of dual core line )
31 (++) Event (CORE1 or CORE2 in case of dual core line )
32 (++) a combination of the previous
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
Ali Labbene3ba4eb32021-03-09 12:48:33 +010046 be selected through multiplexer.
Ali Labbeneaeda37f2020-01-28 14:50:48 +010047
Ali Labbene3ba4eb32021-03-09 12:48:33 +010048 (+) PendClearSource used to set the D3 Smart Run Domain autoamtic pend clear source.
Ali Labbeneaeda37f2020-01-28 14:50:48 +010049 It is applicable for line with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain).
50 Value can be one of the following:
Ali Labbene3ba4eb32021-03-09 12:48:33 +010051 (++) EXTI_D3_PENDCLR_SRC_NONE : no pend clear source is selected :
Ali Labbeneaeda37f2020-01-28 14:50:48 +010052 In this case corresponding bit of D2PMRx register is set to 0
53 (+++) On a configurable Line : the D3 domain wakeup signal is
54 automatically cleared after after the Delay + Rising Edge detect
55 (+++) On a direct Line : the D3 domain wakeup signal is
56 cleared after the direct event input signal is cleared
57
Ali Labbene3ba4eb32021-03-09 12:48:33 +010058 (++) EXTI_D3_PENDCLR_SRC_DMACH6 : no pend clear source is selected :
Ali Labbeneaeda37f2020-01-28 14:50:48 +010059 In this case corresponding bit of D2PMRx register is set to 1
60 and corresponding bits(2) of D3PCRxL/H is set to b00 :
61 DMA ch6 event selected as D3 domain pendclear source
62
Ali Labbene3ba4eb32021-03-09 12:48:33 +010063 (++) EXTI_D3_PENDCLR_SRC_DMACH7 : no pend clear source is selected :
Ali Labbeneaeda37f2020-01-28 14:50:48 +010064 In this case corresponding bit of D2PMRx register is set to 1
65 and corresponding bits(2) of D3PCRxL/H is set to b01 :
66 DMA ch7 event selected as D3 domain pendclear source
67
Ali Labbene3ba4eb32021-03-09 12:48:33 +010068 (++) EXTI_D3_PENDCLR_SRC_LPTIM4 : no pend clear source is selected :
Ali Labbeneaeda37f2020-01-28 14:50:48 +010069 In this case corresponding bit of D2PMRx register is set to 1
70 and corresponding bits(2) of D3PCRxL/H is set to b10 :
71 LPTIM4 out selected as D3 domain pendclear source
72
Ali Labbene3ba4eb32021-03-09 12:48:33 +010073 (++) EXTI_D3_PENDCLR_SRC_LPTIM5 : no pend clear source is selected :
Ali Labbeneaeda37f2020-01-28 14:50:48 +010074 In this case corresponding bit of D2PMRx register is set to 1
75 and corresponding bits(2) of D3PCRxL/H is set to b11 :
76 LPTIM5 out selected as D3 domain pendclear source
77
78
79 ##### How to use this driver #####
80 ==============================================================================
81 [..]
82
83 (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
84 (++) Choose the interrupt line number by setting "Line" member from
85 EXTI_ConfigTypeDef structure.
86 (++) Configure the interrupt and/or event mode using "Mode" member from
87 EXTI_ConfigTypeDef structure.
88 (++) For configurable lines, configure rising and/or falling trigger
89 "Trigger" member from EXTI_ConfigTypeDef structure.
90 (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
91 member from GPIO_InitTypeDef structure.
92 (++) For Exti lines with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain),
93 choose gpio D3 PendClearSource using PendClearSource
94 member from EXTI_PendClear_Source structure.
95
96 (#) Get current Exti configuration of a dedicated line using
97 HAL_EXTI_GetConfigLine().
98 (++) Provide exiting handle as parameter.
99 (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
100
Tasnimfec141c2024-03-19 09:13:06 +0100101 (#) Clear Exti configuration of a dedicated line using HAL_EXTI_ClearConfigLine().
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100102 (++) Provide exiting handle as parameter.
103
104 (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
105 (++) Provide exiting handle as first parameter.
106 (++) Provide which callback will be registered using one value from
107 EXTI_CallbackIDTypeDef.
108 (++) Provide callback function pointer.
109
110 (#) Get interrupt pending bit using HAL_EXTI_GetPending().
111
Tasnimfec141c2024-03-19 09:13:06 +0100112 (#) Clear interrupt pending bit using HAL_EXTI_ClearPending().
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100113
114 (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
115
116 @endverbatim
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100117 */
118
119/* Includes ------------------------------------------------------------------*/
120#include "stm32h7xx_hal.h"
121
122/** @addtogroup STM32H7xx_HAL_Driver
123 * @{
124 */
125
126/** @addtogroup EXTI
127 * @{
128 */
129
130#ifdef HAL_EXTI_MODULE_ENABLED
131
132/* Private typedef -----------------------------------------------------------*/
133/* Private defines ------------------------------------------------------------*/
134/** @defgroup EXTI_Private_Constants EXTI Private Constants
135 * @{
136 */
137#define EXTI_MODE_OFFSET 0x04U /* 0x10: offset between CPU IMR/EMR registers */
138#define EXTI_CONFIG_OFFSET 0x08U /* 0x20: offset between CPU Rising/Falling configuration registers */
139/**
140 * @}
141 */
142
143/* Private macros ------------------------------------------------------------*/
144/* Private variables ---------------------------------------------------------*/
145/* Private function prototypes -----------------------------------------------*/
146/* Exported functions --------------------------------------------------------*/
147
148/** @addtogroup EXTI_Exported_Functions
149 * @{
150 */
151
152/** @addtogroup EXTI_Exported_Functions_Group1
153 * @brief Configuration functions
154 *
155@verbatim
156 ===============================================================================
157 ##### Configuration functions #####
158 ===============================================================================
159
160@endverbatim
161 * @{
162 */
163
164/**
165 * @brief Set configuration of a dedicated Exti line.
166 * @param hexti Exti handle.
167 * @param pExtiConfig Pointer on EXTI configuration to be set.
168 * @retval HAL Status.
169 */
170HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
171{
172 __IO uint32_t *regaddr;
173 uint32_t regval;
174 uint32_t linepos;
175 uint32_t maskline;
176 uint32_t offset;
177 uint32_t pcrlinepos;
178
179 /* Check null pointer */
180 if ((hexti == NULL) || (pExtiConfig == NULL))
181 {
182 return HAL_ERROR;
183 }
184
185 /* Check the parameters */
186 assert_param(IS_EXTI_LINE(pExtiConfig->Line));
187 assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
188
189 /* Assign line number to handle */
190 hexti->Line = pExtiConfig->Line;
191
192 /* compute line register offset and line mask */
193 offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
194 linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
195 maskline = (1UL << linepos);
196
197 /* Configure triggers for configurable lines */
198 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
199 {
200 assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
201
202 /* Configure rising trigger */
203 regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
204 regval = *regaddr;
205
206 /* Mask or set line */
207 if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00U)
208 {
209 regval |= maskline;
210 }
211 else
212 {
213 regval &= ~maskline;
214 }
215
216 /* Store rising trigger mode */
217 *regaddr = regval;
218
219 /* Configure falling trigger */
220 regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
221 regval = *regaddr;
222
223 /* Mask or set line */
224 if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00U)
225 {
226 regval |= maskline;
227 }
228 else
229 {
230 regval &= ~maskline;
231 }
232
233 /* Store falling trigger mode */
234 *regaddr = regval;
235
236 /* Configure gpio port selection in case of gpio exti line */
237 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
238 {
239 assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
240 assert_param(IS_EXTI_GPIO_PIN(linepos));
241
242 regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
243 regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
244 regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
245 SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
246 }
247 }
248
249 /* Configure interrupt mode : read current mode */
250 regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
251 regval = *regaddr;
252
253 /* Mask or set line */
254 if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00U)
255 {
256 regval |= maskline;
257 }
258 else
259 {
260 regval &= ~maskline;
261 }
262
263 /* Store interrupt mode */
264 *regaddr = regval;
265
266 /* The event mode cannot be configured if the line does not support it */
267 assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
268
269 /* Configure event mode : read current mode */
270 regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
271 regval = *regaddr;
272
273 /* Mask or set line */
274 if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00U)
275 {
276 regval |= maskline;
277 }
278 else
279 {
280 regval &= ~maskline;
281 }
282
283 /* Store event mode */
284 *regaddr = regval;
285
286#if defined (DUAL_CORE)
287 /* Configure interrupt mode for Core2 : read current mode */
288 regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
289 regval = *regaddr;
290
291 /* Mask or set line */
292 if ((pExtiConfig->Mode & EXTI_MODE_CORE2_INTERRUPT) != 0x00U)
293 {
294 regval |= maskline;
295 }
296 else
297 {
298 regval &= ~maskline;
299 }
300
301 /* Store interrupt mode */
302 *regaddr = regval;
303
304 /* The event mode cannot be configured if the line does not support it */
305 assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != EXTI_MODE_CORE2_EVENT));
306
307 /* Configure event mode : read current mode */
308 regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
309 regval = *regaddr;
310
311 /* Mask or set line */
312 if ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != 0x00U)
313 {
314 regval |= maskline;
315 }
316 else
317 {
318 regval &= ~maskline;
319 }
320
321 /* Store event mode */
322 *regaddr = regval;
323#endif /* DUAL_CORE */
324
325 /* Configure the D3 PendClear source in case of Wakeup target is Any */
326 if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
327 {
328 assert_param(IS_EXTI_D3_PENDCLR_SRC(pExtiConfig->PendClearSource));
329
330 /*Calc the PMR register address for the given line */
331 regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
332 regval = *regaddr;
333
334 if(pExtiConfig->PendClearSource == EXTI_D3_PENDCLR_SRC_NONE)
335 {
336 /* Clear D3PMRx register for the given line */
337 regval &= ~maskline;
338 /* Store D3PMRx register value */
339 *regaddr = regval;
340 }
341 else
342 {
343 /* Set D3PMRx register to 1 for the given line */
344 regval |= maskline;
345 /* Store D3PMRx register value */
346 *regaddr = regval;
347
348 if(linepos < 16UL)
349 {
350 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
351 pcrlinepos = 1UL << linepos;
352 }
353 else
354 {
355 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
356 pcrlinepos = 1UL << (linepos - 16UL);
357 }
358
359 regval = (*regaddr & (~(pcrlinepos * pcrlinepos * 3UL))) | (pcrlinepos * pcrlinepos * (pExtiConfig->PendClearSource - 1UL));
360 *regaddr = regval;
361 }
362 }
363
364 return HAL_OK;
365}
366
367
368/**
369 * @brief Get configuration of a dedicated Exti line.
370 * @param hexti Exti handle.
371 * @param pExtiConfig Pointer on structure to store Exti configuration.
372 * @retval HAL Status.
373 */
374HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
375{
376 __IO uint32_t *regaddr;
377 uint32_t regval;
378 uint32_t linepos;
379 uint32_t maskline;
380 uint32_t offset;
381 uint32_t pcrlinepos;
382
383 /* Check null pointer */
384 if ((hexti == NULL) || (pExtiConfig == NULL))
385 {
386 return HAL_ERROR;
387 }
388
389 /* Check the parameter */
390 assert_param(IS_EXTI_LINE(hexti->Line));
391
392 /* Store handle line number to configuration structure */
393 pExtiConfig->Line = hexti->Line;
394
395 /* compute line register offset and line mask */
396 offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
397 linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
398 maskline = (1UL << linepos);
399
400 /* 1] Get core mode : interrupt */
401 regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
402 regval = *regaddr;
403
404 pExtiConfig->Mode = EXTI_MODE_NONE;
405
406 /* Check if selected line is enable */
407 if ((regval & maskline) != 0x00U)
408 {
409 pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
410 }
411
412 /* Get event mode */
413 regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
414 regval = *regaddr;
415
416 /* Check if selected line is enable */
417 if ((regval & maskline) != 0x00U)
418 {
419 pExtiConfig->Mode |= EXTI_MODE_EVENT;
420 }
421#if defined (DUAL_CORE)
422 regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
423 regval = *regaddr;
424
425 /* Check if selected line is enable */
426 if ((regval & maskline) != 0x00U)
427 {
428 pExtiConfig->Mode = EXTI_MODE_CORE2_INTERRUPT;
429 }
430
431 /* Get event mode */
432 regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
433 regval = *regaddr;
434
435 /* Check if selected line is enable */
436 if ((regval & maskline) != 0x00U)
437 {
438 pExtiConfig->Mode |= EXTI_MODE_CORE2_EVENT;
439 }
440#endif /*DUAL_CORE*/
441
rihab kouki9439ae72021-12-14 12:56:29 +0100442 /* Get default Trigger and GPIOSel configuration */
443 pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
444 pExtiConfig->GPIOSel = 0x00U;
445
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100446 /* 2] Get trigger for configurable lines : rising */
447 if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
448 {
449 regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
450 regval = *regaddr;
451
452 /* Check if configuration of selected line is enable */
453 if ((regval & maskline) != 0x00U)
454 {
455 pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
456 }
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100457
458 /* Get falling configuration */
459 regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
460 regval = *regaddr;
461
462 /* Check if configuration of selected line is enable */
463 if ((regval & maskline) != 0x00U)
464 {
465 pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
466 }
467
468 /* Get Gpio port selection for gpio lines */
469 if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
470 {
471 assert_param(IS_EXTI_GPIO_PIN(linepos));
472
473 regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
Eyab7163792022-12-08 09:25:51 +0100474 pExtiConfig->GPIOSel = (regval >> (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u))) & SYSCFG_EXTICR1_EXTI0;
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100475 }
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100476 }
rihab kouki9439ae72021-12-14 12:56:29 +0100477
478 /* Get default Pend Clear Source */
479 pExtiConfig->PendClearSource = EXTI_D3_PENDCLR_SRC_NONE;
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100480
481 /* 3] Get D3 Pend Clear source */
482 if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
483 {
484 regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
rihab kouki9439ae72021-12-14 12:56:29 +0100485 if(((*regaddr) & linepos) != 0UL)
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100486 {
487 /* if wakeup target is any and PMR set, the read pend clear source from D3PCRxL/H */
488 if(linepos < 16UL)
489 {
490 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
491 pcrlinepos = 1UL << linepos;
492 }
493 else
494 {
495 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
496 pcrlinepos = 1UL << (linepos - 16UL);
497 }
498
499 pExtiConfig->PendClearSource = 1UL + ((*regaddr & (pcrlinepos * pcrlinepos * 3UL)) / (pcrlinepos * pcrlinepos));
500 }
501 }
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100502
503 return HAL_OK;
504}
505
506
507/**
508 * @brief Clear whole configuration of a dedicated Exti line.
509 * @param hexti Exti handle.
510 * @retval HAL Status.
511 */
512HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
513{
514 __IO uint32_t *regaddr;
515 uint32_t regval;
516 uint32_t linepos;
517 uint32_t maskline;
518 uint32_t offset;
519 uint32_t pcrlinepos;
520
521 /* Check null pointer */
522 if (hexti == NULL)
523 {
524 return HAL_ERROR;
525 }
526
527 /* Check the parameter */
528 assert_param(IS_EXTI_LINE(hexti->Line));
529
530 /* compute line register offset and line mask */
531 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
532 linepos = (hexti->Line & EXTI_PIN_MASK);
533 maskline = (1UL << linepos);
534
535 /* 1] Clear interrupt mode */
536 regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
537 regval = (*regaddr & ~maskline);
538 *regaddr = regval;
539
540 /* 2] Clear event mode */
541 regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
542 regval = (*regaddr & ~maskline);
543 *regaddr = regval;
544
545#if defined (DUAL_CORE)
546 /* 1] Clear CM4 interrupt mode */
547 regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
548 regval = (*regaddr & ~maskline);
549 *regaddr = regval;
550
551 /* 2] Clear CM4 event mode */
552 regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
553 regval = (*regaddr & ~maskline);
554 *regaddr = regval;
555#endif /* DUAL_CORE */
556
557 /* 3] Clear triggers in case of configurable lines */
558 if ((hexti->Line & EXTI_CONFIG) != 0x00U)
559 {
560 regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
561 regval = (*regaddr & ~maskline);
562 *regaddr = regval;
563
564 regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
565 regval = (*regaddr & ~maskline);
566 *regaddr = regval;
567
568 /* Get Gpio port selection for gpio lines */
569 if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
570 {
571 assert_param(IS_EXTI_GPIO_PIN(linepos));
572
573 regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
574 regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03UL)));
575 SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
576 }
577 }
578
579 /* 4] Clear D3 Config lines */
580 if ((hexti->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
581 {
582 regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
583 *regaddr = (*regaddr & ~maskline);
584
585 if(linepos < 16UL)
586 {
587 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
588 pcrlinepos = 1UL << linepos;
589 }
590 else
591 {
592 regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
593 pcrlinepos = 1UL << (linepos - 16UL);
594 }
595
596 /*Clear D3 PendClear source */
597 *regaddr &= (~(pcrlinepos * pcrlinepos * 3UL));
598 }
599
600 return HAL_OK;
601}
602
603
604/**
605 * @brief Register callback for a dedicated Exti line.
606 * @param hexti Exti handle.
607 * @param CallbackID User callback identifier.
608 * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
609 * @param pPendingCbfn function pointer to be stored as callback.
610 * @retval HAL Status.
611 */
612HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
613{
614 HAL_StatusTypeDef status = HAL_OK;
615
616 /* Check null pointer */
617 if (hexti == NULL)
618 {
619 return HAL_ERROR;
620 }
621
622 switch (CallbackID)
623 {
624 case HAL_EXTI_COMMON_CB_ID:
625 hexti->PendingCallback = pPendingCbfn;
626 break;
627
628 default:
629 status = HAL_ERROR;
630 break;
631 }
632
633 return status;
634}
635
636
637/**
638 * @brief Store line number as handle private field.
639 * @param hexti Exti handle.
640 * @param ExtiLine Exti line number.
641 * This parameter can be from 0 to @ref EXTI_LINE_NB.
642 * @retval HAL Status.
643 */
644HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
645{
646 /* Check the parameters */
647 assert_param(IS_EXTI_LINE(ExtiLine));
648
649 /* Check null pointer */
650 if (hexti == NULL)
651 {
652 return HAL_ERROR;
653 }
654 else
655 {
656 /* Store line number as handle private field */
657 hexti->Line = ExtiLine;
658
659 return HAL_OK;
660 }
661}
662
663
664/**
665 * @}
666 */
667
668/** @addtogroup EXTI_Exported_Functions_Group2
669 * @brief EXTI IO functions.
670 *
671@verbatim
672 ===============================================================================
673 ##### IO operation functions #####
674 ===============================================================================
675
676@endverbatim
677 * @{
678 */
679
680/**
681 * @brief Handle EXTI interrupt request.
682 * @param hexti Exti handle.
683 * @retval none.
684 */
685void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
686{
687 __IO uint32_t *regaddr;
688 uint32_t regval;
689 uint32_t maskline;
690 uint32_t offset;
691
692 /* Compute line register offset and line mask */
693 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
694 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
695
696#if defined(DUAL_CORE)
697 if (HAL_GetCurrentCPUID() == CM7_CPUID)
698 {
699 /* Get pending register address */
700 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
701 }
702 else /* Cortex-M4*/
703 {
704 /* Get pending register address */
705 regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
706 }
707#else
708 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
709#endif /* DUAL_CORE */
710
711 /* Get pending bit */
712 regval = (*regaddr & maskline);
713
714 if (regval != 0x00U)
715 {
716 /* Clear pending bit */
717 *regaddr = maskline;
718
719 /* Call callback */
720 if (hexti->PendingCallback != NULL)
721 {
722 hexti->PendingCallback();
723 }
724 }
725}
726
727
728/**
729 * @brief Get interrupt pending bit of a dedicated line.
730 * @param hexti Exti handle.
731 * @param Edge Specify which pending edge as to be checked.
732 * This parameter can be one of the following values:
733 * @arg @ref EXTI_TRIGGER_RISING_FALLING
734 * This parameter is kept for compatibility with other series.
735 * @retval 1 if interrupt is pending else 0.
736 */
737uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
738{
739 __IO uint32_t *regaddr;
740 uint32_t regval;
741 uint32_t linepos;
742 uint32_t maskline;
743 uint32_t offset;
744
Tasnimfec141c2024-03-19 09:13:06 +0100745 /* Prevent unused argument(s) compilation warning */
746 UNUSED(Edge);
747
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100748 /* Check parameters */
749 assert_param(IS_EXTI_LINE(hexti->Line));
750 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
751 assert_param(IS_EXTI_PENDING_EDGE(Edge));
752
753 /* compute line register offset and line mask */
754 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
755 linepos = (hexti->Line & EXTI_PIN_MASK);
756 maskline = (1UL << linepos);
757
758#if defined(DUAL_CORE)
759 if (HAL_GetCurrentCPUID() == CM7_CPUID)
760 {
761 /* Get pending register address */
762 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
763 }
764 else /* Cortex-M4 */
765 {
766 /* Get pending register address */
767 regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
768 }
769#else
770 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
771#endif /* DUAL_CORE */
772
773 /* return 1 if bit is set else 0 */
774 regval = ((*regaddr & maskline) >> linepos);
775 return regval;
776}
777
778
779/**
780 * @brief Clear interrupt pending bit of a dedicated line.
781 * @param hexti Exti handle.
782 * @param Edge Specify which pending edge as to be clear.
783 * This parameter can be one of the following values:
784 * @arg @ref EXTI_TRIGGER_RISING_FALLING
785 * This parameter is kept for compatibility with other series.
786 * @retval None.
787 */
788void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
789{
790 __IO uint32_t *regaddr;
791 uint32_t maskline;
792 uint32_t offset;
793
Tasnimfec141c2024-03-19 09:13:06 +0100794 /* Prevent unused argument(s) compilation warning */
795 UNUSED(Edge);
796
Ali Labbeneaeda37f2020-01-28 14:50:48 +0100797 /* Check parameters */
798 assert_param(IS_EXTI_LINE(hexti->Line));
799 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
800 assert_param(IS_EXTI_PENDING_EDGE(Edge));
801
802 /* compute line register offset and line mask */
803 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
804 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
805
806#if defined(DUAL_CORE)
807 if (HAL_GetCurrentCPUID() == CM7_CPUID)
808 {
809 /* Get pending register address */
810 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
811 }
812 else /* Cortex-M4 */
813 {
814 /* Get pending register address */
815 regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
816 }
817#else
818 regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
819#endif /* DUAL_CORE */
820
821 /* Clear Pending bit */
822 *regaddr = maskline;
823}
824
825/**
826 * @brief Generate a software interrupt for a dedicated line.
827 * @param hexti Exti handle.
828 * @retval None.
829 */
830void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
831{
832 __IO uint32_t *regaddr;
833 uint32_t maskline;
834 uint32_t offset;
835
836 /* Check parameters */
837 assert_param(IS_EXTI_LINE(hexti->Line));
838 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
839
840 /* compute line register offset and line mask */
841 offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
842 maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
843
844 regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
845 *regaddr = maskline;
846}
847
848
849/**
850 * @}
851 */
852
853/**
854 * @}
855 */
856
857#endif /* HAL_EXTI_MODULE_ENABLED */
858/**
859 * @}
860 */
861
862/**
863 * @}
864 */
865