2 ******************************************************************************
3 * @file stm32g4xx_hal_exti.c
4 * @author MCD Application Team
5 * @brief EXTI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Extended Interrupts and events controller (EXTI) peripheral:
8 * functionalities of the General Purpose Input/Output (EXTI) peripheral:
9 * + Initialization and de-initialization functions
10 * + IO operation functions
13 ==============================================================================
14 ##### EXTI Peripheral features #####
15 ==============================================================================
17 (+) Each Exti line can be configured within this driver.
19 (+) Exti line can be configured in 3 different modes
24 (+) Configurable Exti lines can be configured with 3 different triggers
29 (+) When set in interrupt mode, configurable Exti lines have two different
30 interrupt pending registers which allow to distinguish which transition
32 (++) Rising edge pending interrupt
35 (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
36 be selected through multiplexer.
38 ##### How to use this driver #####
39 ==============================================================================
42 (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
43 (++) Choose the interrupt line number by setting "Line" member from
44 EXTI_ConfigTypeDef structure.
45 (++) Configure the interrupt and/or event mode using "Mode" member from
46 EXTI_ConfigTypeDef structure.
47 (++) For configurable lines, configure rising and/or falling trigger
48 "Trigger" member from EXTI_ConfigTypeDef structure.
49 (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
50 member from GPIO_InitTypeDef structure.
52 (#) Get current Exti configuration of a dedicated line using
53 HAL_EXTI_GetConfigLine().
54 (++) Provide exiting handle as parameter.
55 (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
57 (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
58 (++) Provide exiting handle as parameter.
60 (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
61 (++) Provide exiting handle as first parameter.
62 (++) Provide which callback will be registered using one value from
63 EXTI_CallbackIDTypeDef.
64 (++) Provide callback function pointer.
66 (#) Get interrupt pending bit using HAL_EXTI_GetPending().
68 (#) Clear interrupt pending bit using HAL_EXTI_ClearPending().
70 (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
73 ******************************************************************************
76 * <h2><center>© Copyright (c) 2018 STMicroelectronics.
77 * All rights reserved.</center></h2>
79 * This software component is licensed by ST under BSD 3-Clause license,
80 * the "License"; You may not use this file except in compliance with the
81 * License. You may obtain a copy of the License at:
82 * opensource.org/licenses/BSD-3-Clause
84 ******************************************************************************
87 /* Includes ------------------------------------------------------------------*/
88 #include "stm32g4xx_hal.h"
90 /** @addtogroup STM32G4xx_HAL_Driver
97 /** MISRA C:2012 deviation rule has been granted for following rule:
98 * Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out
99 * of bounds [0,3] in following API :
100 * HAL_EXTI_SetConfigLine
101 * HAL_EXTI_GetConfigLine
102 * HAL_EXTI_ClearConfigLine
105 #ifdef HAL_EXTI_MODULE_ENABLED
107 /* Private typedef -----------------------------------------------------------*/
108 /* Private defines ------------------------------------------------------------*/
109 /** @defgroup EXTI_Private_Constants EXTI Private Constants
112 #define EXTI_MODE_OFFSET 0x08U /* 0x20: offset between MCU IMR/EMR registers */
113 #define EXTI_CONFIG_OFFSET 0x08U /* 0x20: offset between MCU Rising/Falling configuration registers */
118 /* Private macros ------------------------------------------------------------*/
119 /* Private variables ---------------------------------------------------------*/
120 /* Private function prototypes -----------------------------------------------*/
121 /* Exported functions --------------------------------------------------------*/
123 /** @addtogroup EXTI_Exported_Functions
127 /** @addtogroup EXTI_Exported_Functions_Group1
128 * @brief Configuration functions
131 ===============================================================================
132 ##### Configuration functions #####
133 ===============================================================================
140 * @brief Set configuration of a dedicated Exti line.
141 * @param hexti Exti handle.
142 * @param pExtiConfig Pointer on EXTI configuration to be set.
143 * @retval HAL Status.
145 HAL_StatusTypeDef
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef
*hexti
, EXTI_ConfigTypeDef
*pExtiConfig
)
147 __IO
uint32_t *regaddr
;
153 /* Check null pointer */
154 if ((hexti
== NULL
) || (pExtiConfig
== NULL
))
159 /* Check parameters */
160 assert_param(IS_EXTI_LINE(pExtiConfig
->Line
));
161 assert_param(IS_EXTI_MODE(pExtiConfig
->Mode
));
163 /* Assign line number to handle */
164 hexti
->Line
= pExtiConfig
->Line
;
166 /* Compute line register offset */
167 offset
= ((pExtiConfig
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
168 /* Compute line position */
169 linepos
= (pExtiConfig
->Line
& EXTI_PIN_MASK
);
170 /* Compute line mask */
171 maskline
= (1uL << linepos
);
173 /* Configure triggers for configurable lines */
174 if ((pExtiConfig
->Line
& EXTI_CONFIG
) != 0x00u
)
176 assert_param(IS_EXTI_TRIGGER(pExtiConfig
->Trigger
));
178 /* Configure rising trigger */
179 regaddr
= (&EXTI
->RTSR1
+ (EXTI_CONFIG_OFFSET
* offset
));
182 /* Mask or set line */
183 if ((pExtiConfig
->Trigger
& EXTI_TRIGGER_RISING
) != 0x00u
)
192 /* Store rising trigger mode */
195 /* Configure falling trigger */
196 regaddr
= (&EXTI
->FTSR1
+ (EXTI_CONFIG_OFFSET
* offset
));
199 /* Mask or set line */
200 if ((pExtiConfig
->Trigger
& EXTI_TRIGGER_FALLING
) != 0x00u
)
209 /* Store falling trigger mode */
212 /* Configure gpio port selection in case of gpio exti line */
213 if ((pExtiConfig
->Line
& EXTI_GPIO
) == EXTI_GPIO
)
215 assert_param(IS_EXTI_GPIO_PORT(pExtiConfig
->GPIOSel
));
216 assert_param(IS_EXTI_GPIO_PIN(linepos
));
218 regval
= SYSCFG
->EXTICR
[linepos
>> 2u];
219 regval
&= ~(SYSCFG_EXTICR1_EXTI0
<< (SYSCFG_EXTICR1_EXTI1_Pos
* (linepos
& 0x03u
)));
220 regval
|= (pExtiConfig
->GPIOSel
<< (SYSCFG_EXTICR1_EXTI1_Pos
* (linepos
& 0x03u
)));
221 SYSCFG
->EXTICR
[linepos
>> 2u] = regval
;
225 /* Configure interrupt mode : read current mode */
226 regaddr
= (&EXTI
->IMR1
+ (EXTI_MODE_OFFSET
* offset
));
229 /* Mask or set line */
230 if ((pExtiConfig
->Mode
& EXTI_MODE_INTERRUPT
) != 0x00u
)
239 /* Store interrupt mode */
242 /* Configure event mode : read current mode */
243 regaddr
= (&EXTI
->EMR1
+ (EXTI_MODE_OFFSET
* offset
));
246 /* Mask or set line */
247 if ((pExtiConfig
->Mode
& EXTI_MODE_EVENT
) != 0x00u
)
256 /* Store event mode */
264 * @brief Get configuration of a dedicated Exti line.
265 * @param hexti Exti handle.
266 * @param pExtiConfig Pointer on structure to store Exti configuration.
267 * @retval HAL Status.
269 HAL_StatusTypeDef
HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef
*hexti
, EXTI_ConfigTypeDef
*pExtiConfig
)
271 __IO
uint32_t *regaddr
;
277 /* Check null pointer */
278 if ((hexti
== NULL
) || (pExtiConfig
== NULL
))
283 /* Check the parameter */
284 assert_param(IS_EXTI_LINE(hexti
->Line
));
286 /* Store handle line number to configuration structure */
287 pExtiConfig
->Line
= hexti
->Line
;
289 /* Compute line register offset and line mask */
290 offset
= ((pExtiConfig
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
291 /* Compute line position */
292 linepos
= (pExtiConfig
->Line
& EXTI_PIN_MASK
);
294 maskline
= (1uL << linepos
);
296 /* 1] Get core mode : interrupt */
297 regaddr
= (&EXTI
->IMR1
+ (EXTI_MODE_OFFSET
* offset
));
300 /* Check if selected line is enable */
301 if ((regval
& maskline
) != 0x00u
)
303 pExtiConfig
->Mode
= EXTI_MODE_INTERRUPT
;
307 pExtiConfig
->Mode
= EXTI_MODE_NONE
;
311 regaddr
= (&EXTI
->EMR1
+ (EXTI_MODE_OFFSET
* offset
));
314 /* Check if selected line is enable */
315 if ((regval
& maskline
) != 0x00u
)
317 pExtiConfig
->Mode
|= EXTI_MODE_EVENT
;
320 /* 2] Get trigger for configurable lines : rising */
321 if ((pExtiConfig
->Line
& EXTI_CONFIG
) != 0x00u
)
323 regaddr
= (&EXTI
->RTSR1
+ (EXTI_CONFIG_OFFSET
* offset
));
326 /* Check if configuration of selected line is enable */
327 if ((regval
& maskline
) != 0x00u
)
329 pExtiConfig
->Trigger
= EXTI_TRIGGER_RISING
;
333 pExtiConfig
->Trigger
= EXTI_TRIGGER_NONE
;
336 /* Get falling configuration */
337 regaddr
= (&EXTI
->FTSR1
+ (EXTI_CONFIG_OFFSET
* offset
));
340 /* Check if configuration of selected line is enable */
341 if ((regval
& maskline
) != 0x00u
)
343 pExtiConfig
->Trigger
|= EXTI_TRIGGER_FALLING
;
346 /* Get Gpio port selection for gpio lines */
347 if ((pExtiConfig
->Line
& EXTI_GPIO
) == EXTI_GPIO
)
349 assert_param(IS_EXTI_GPIO_PIN(linepos
));
351 regval
= SYSCFG
->EXTICR
[linepos
>> 2u];
352 pExtiConfig
->GPIOSel
= ((regval
>> (SYSCFG_EXTICR1_EXTI1_Pos
* ((linepos
& 0x03u
)))));
356 pExtiConfig
->GPIOSel
= 0x00u
;
361 pExtiConfig
->Trigger
= EXTI_TRIGGER_NONE
;
362 pExtiConfig
->GPIOSel
= 0x00u
;
370 * @brief Clear whole configuration of a dedicated Exti line.
371 * @param hexti Exti handle.
372 * @retval HAL Status.
374 HAL_StatusTypeDef
HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef
*hexti
)
376 __IO
uint32_t *regaddr
;
382 /* Check null pointer */
388 /* Check the parameter */
389 assert_param(IS_EXTI_LINE(hexti
->Line
));
391 /* compute line register offset and line mask */
392 offset
= ((hexti
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
393 /* compute line position */
394 linepos
= (hexti
->Line
& EXTI_PIN_MASK
);
395 /* compute line mask */
396 maskline
= (1uL << linepos
);
398 /* 1] Clear interrupt mode */
399 regaddr
= (&EXTI
->IMR1
+ (EXTI_MODE_OFFSET
* offset
));
400 regval
= (*regaddr
& ~maskline
);
403 /* 2] Clear event mode */
404 regaddr
= (&EXTI
->EMR1
+ (EXTI_MODE_OFFSET
* offset
));
405 regval
= (*regaddr
& ~maskline
);
408 /* 3] Clear triggers in case of configurable lines */
409 if ((hexti
->Line
& EXTI_CONFIG
) != 0x00u
)
411 regaddr
= (&EXTI
->RTSR1
+ (EXTI_CONFIG_OFFSET
* offset
));
412 regval
= (*regaddr
& ~maskline
);
415 regaddr
= (&EXTI
->FTSR1
+ (EXTI_CONFIG_OFFSET
* offset
));
416 regval
= (*regaddr
& ~maskline
);
419 /* Get Gpio port selection for gpio lines */
420 if ((hexti
->Line
& EXTI_GPIO
) == EXTI_GPIO
)
422 assert_param(IS_EXTI_GPIO_PIN(linepos
));
424 regval
= SYSCFG
->EXTICR
[linepos
>> 2u];
425 regval
&= ~(SYSCFG_EXTICR1_EXTI0
<< (SYSCFG_EXTICR1_EXTI1_Pos
* (linepos
& 0x03u
)));
426 SYSCFG
->EXTICR
[linepos
>> 2u] = regval
;
435 * @brief Register callback for a dedicated Exti line.
436 * @param hexti Exti handle.
437 * @param CallbackID User callback identifier.
438 * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
439 * @param pPendingCbfn function pointer to be stored as callback.
440 * @retval HAL Status.
442 HAL_StatusTypeDef
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef
*hexti
, EXTI_CallbackIDTypeDef CallbackID
, void (*pPendingCbfn
)(void))
444 HAL_StatusTypeDef status
= HAL_OK
;
446 /* Check the parameters */
447 assert_param(IS_EXTI_CB(CallbackID
));
451 /* set common callback */
452 case HAL_EXTI_COMMON_CB_ID
:
453 hexti
->PendingCallback
= pPendingCbfn
;
457 hexti
->PendingCallback
= NULL
;
467 * @brief Store line number as handle private field.
468 * @param hexti Exti handle.
469 * @param ExtiLine Exti line number.
470 * This parameter can be from 0 to @ref EXTI_LINE_NB.
471 * @retval HAL Status.
473 HAL_StatusTypeDef
HAL_EXTI_GetHandle(EXTI_HandleTypeDef
*hexti
, uint32_t ExtiLine
)
475 /* Check the parameters */
476 assert_param(IS_EXTI_LINE(ExtiLine
));
478 /* Check null pointer */
485 /* Store line number as handle private field */
486 hexti
->Line
= ExtiLine
;
497 /** @addtogroup EXTI_Exported_Functions_Group2
498 * @brief EXTI IO functions.
501 ===============================================================================
502 ##### IO operation functions #####
503 ===============================================================================
510 * @brief Handle EXTI interrupt request.
511 * @param hexti Exti handle.
514 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef
*hexti
)
516 __IO
uint32_t *regaddr
;
521 /* Compute line register offset */
522 offset
= ((hexti
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
523 /* compute line mask */
524 maskline
= (1uL << (hexti
->Line
& EXTI_PIN_MASK
));
526 /* Get pending bit */
527 regaddr
= (&EXTI
->PR1
+ (EXTI_CONFIG_OFFSET
* offset
));
528 regval
= (*regaddr
& maskline
);
532 /* Clear pending bit */
535 /* Call pending callback */
536 if (hexti
->PendingCallback
!= NULL
)
538 hexti
->PendingCallback();
544 * @brief Get interrupt pending bit of a dedicated line.
545 * @param hexti Exti handle.
547 * @retval 1 if interrupt is pending else 0.
549 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef
*hexti
, uint32_t Edge
)
551 __IO
uint32_t *regaddr
;
557 /* Check parameters */
558 assert_param(IS_EXTI_LINE(hexti
->Line
));
559 assert_param(IS_EXTI_CONFIG_LINE(hexti
->Line
));
562 /* Compute line register offset */
563 offset
= ((hexti
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
564 /* Compute line position */
565 linepos
= (hexti
->Line
& EXTI_PIN_MASK
);
566 /* Compute line mask */
567 maskline
= (1uL << linepos
);
569 /* Get pending bit */
570 regaddr
= (&EXTI
->PR1
+ (EXTI_CONFIG_OFFSET
* offset
));
572 /* return 1 if bit is set else 0 */
573 regval
= ((*regaddr
& maskline
) >> linepos
);
579 * @brief Clear interrupt pending bit of a dedicated line.
580 * @param hexti Exti handle.
584 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef
*hexti
, uint32_t Edge
)
586 __IO
uint32_t *regaddr
;
590 /* Check parameters */
591 assert_param(IS_EXTI_LINE(hexti
->Line
));
592 assert_param(IS_EXTI_CONFIG_LINE(hexti
->Line
));
595 /* Compute line register offset */
596 offset
= ((hexti
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
597 /* Compute line mask */
598 maskline
= (1uL << (hexti
->Line
& EXTI_PIN_MASK
));
600 /* Get pending register address */
601 regaddr
= (&EXTI
->PR1
+ (EXTI_CONFIG_OFFSET
* offset
));
603 /* Clear Pending bit */
609 * @brief Generate a software interrupt for a dedicated line.
610 * @param hexti Exti handle.
613 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef
*hexti
)
615 __IO
uint32_t *regaddr
;
619 /* Check parameter */
620 assert_param(IS_EXTI_LINE(hexti
->Line
));
621 assert_param(IS_EXTI_CONFIG_LINE(hexti
->Line
));
623 /* compute line register offset */
624 offset
= ((hexti
->Line
& EXTI_REG_MASK
) >> EXTI_REG_SHIFT
);
625 /* compute line mask */
626 maskline
= (1uL << (hexti
->Line
& EXTI_PIN_MASK
));
628 regaddr
= (&EXTI
->SWIER1
+ (EXTI_CONFIG_OFFSET
* offset
));
641 #endif /* HAL_EXTI_MODULE_ENABLED */
650 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/