Merge pull request #11189 from klutvott123/move-telemetry-displayport-init
[betaflight.git] / lib / main / STM32G4 / Drivers / STM32G4xx_HAL_Driver / Src / stm32g4xx_hal_exti.c
blob0ef77dc0b9febac045f0e5833806bb1291cd2d8f
1 /**
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
12 @verbatim
13 ==============================================================================
14 ##### EXTI Peripheral features #####
15 ==============================================================================
16 [..]
17 (+) Each Exti line can be configured within this driver.
19 (+) Exti line can be configured in 3 different modes
20 (++) Interrupt
21 (++) Event
22 (++) Both of them
24 (+) Configurable Exti lines can be configured with 3 different triggers
25 (++) Rising
26 (++) Falling
27 (++) Both of them
29 (+) When set in interrupt mode, configurable Exti lines have two different
30 interrupt pending registers which allow to distinguish which transition
31 occurs:
32 (++) Rising edge pending interrupt
33 (++) Falling
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 ==============================================================================
40 [..]
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().
72 @endverbatim
73 ******************************************************************************
74 * @attention
76 * <h2><center>&copy; 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
91 * @{
94 /** @addtogroup EXTI
95 * @{
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
110 * @{
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 */
115 * @}
118 /* Private macros ------------------------------------------------------------*/
119 /* Private variables ---------------------------------------------------------*/
120 /* Private function prototypes -----------------------------------------------*/
121 /* Exported functions --------------------------------------------------------*/
123 /** @addtogroup EXTI_Exported_Functions
124 * @{
127 /** @addtogroup EXTI_Exported_Functions_Group1
128 * @brief Configuration functions
130 @verbatim
131 ===============================================================================
132 ##### Configuration functions #####
133 ===============================================================================
135 @endverbatim
136 * @{
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;
148 uint32_t regval;
149 uint32_t linepos;
150 uint32_t maskline;
151 uint32_t offset;
153 /* Check null pointer */
154 if ((hexti == NULL) || (pExtiConfig == NULL))
156 return HAL_ERROR;
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));
180 regval = *regaddr;
182 /* Mask or set line */
183 if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u)
185 regval |= maskline;
187 else
189 regval &= ~maskline;
192 /* Store rising trigger mode */
193 *regaddr = regval;
195 /* Configure falling trigger */
196 regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
197 regval = *regaddr;
199 /* Mask or set line */
200 if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u)
202 regval |= maskline;
204 else
206 regval &= ~maskline;
209 /* Store falling trigger mode */
210 *regaddr = regval;
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));
227 regval = *regaddr;
229 /* Mask or set line */
230 if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u)
232 regval |= maskline;
234 else
236 regval &= ~maskline;
239 /* Store interrupt mode */
240 *regaddr = regval;
242 /* Configure event mode : read current mode */
243 regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
244 regval = *regaddr;
246 /* Mask or set line */
247 if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u)
249 regval |= maskline;
251 else
253 regval &= ~maskline;
256 /* Store event mode */
257 *regaddr = regval;
259 return HAL_OK;
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;
272 uint32_t regval;
273 uint32_t linepos;
274 uint32_t maskline;
275 uint32_t offset;
277 /* Check null pointer */
278 if ((hexti == NULL) || (pExtiConfig == NULL))
280 return HAL_ERROR;
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);
293 /* Compute mask */
294 maskline = (1uL << linepos);
296 /* 1] Get core mode : interrupt */
297 regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
298 regval = *regaddr;
300 /* Check if selected line is enable */
301 if ((regval & maskline) != 0x00u)
303 pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
305 else
307 pExtiConfig->Mode = EXTI_MODE_NONE;
310 /* Get event mode */
311 regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
312 regval = *regaddr;
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));
324 regval = *regaddr;
326 /* Check if configuration of selected line is enable */
327 if ((regval & maskline) != 0x00u)
329 pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
331 else
333 pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
336 /* Get falling configuration */
337 regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
338 regval = *regaddr;
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)))));
354 else
356 pExtiConfig->GPIOSel = 0x00u;
359 else
361 pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
362 pExtiConfig->GPIOSel = 0x00u;
365 return HAL_OK;
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;
377 uint32_t regval;
378 uint32_t linepos;
379 uint32_t maskline;
380 uint32_t offset;
382 /* Check null pointer */
383 if (hexti == NULL)
385 return HAL_ERROR;
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);
401 *regaddr = regval;
403 /* 2] Clear event mode */
404 regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
405 regval = (*regaddr & ~maskline);
406 *regaddr = regval;
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);
413 *regaddr = regval;
415 regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
416 regval = (*regaddr & ~maskline);
417 *regaddr = regval;
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;
430 return HAL_OK;
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));
449 switch (CallbackID)
451 /* set common callback */
452 case HAL_EXTI_COMMON_CB_ID:
453 hexti->PendingCallback = pPendingCbfn;
454 break;
456 default:
457 hexti->PendingCallback = NULL;
458 status = HAL_ERROR;
459 break;
462 return status;
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 */
479 if (hexti == NULL)
481 return HAL_ERROR;
483 else
485 /* Store line number as handle private field */
486 hexti->Line = ExtiLine;
488 return HAL_OK;
494 * @}
497 /** @addtogroup EXTI_Exported_Functions_Group2
498 * @brief EXTI IO functions.
500 @verbatim
501 ===============================================================================
502 ##### IO operation functions #####
503 ===============================================================================
505 @endverbatim
506 * @{
510 * @brief Handle EXTI interrupt request.
511 * @param hexti Exti handle.
512 * @retval none.
514 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
516 __IO uint32_t *regaddr;
517 uint32_t regval;
518 uint32_t maskline;
519 uint32_t offset;
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);
530 if (regval != 0x00u)
532 /* Clear pending bit */
533 *regaddr = maskline;
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.
546 * @param Edge unused
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;
552 uint32_t regval;
553 uint32_t linepos;
554 uint32_t maskline;
555 uint32_t offset;
557 /* Check parameters */
558 assert_param(IS_EXTI_LINE(hexti->Line));
559 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
560 UNUSED(Edge);
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);
574 return regval;
579 * @brief Clear interrupt pending bit of a dedicated line.
580 * @param hexti Exti handle.
581 * @param Edge unused
582 * @retval None.
584 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
586 __IO uint32_t *regaddr;
587 uint32_t maskline;
588 uint32_t offset;
590 /* Check parameters */
591 assert_param(IS_EXTI_LINE(hexti->Line));
592 assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
593 UNUSED(Edge);
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 */
604 *regaddr = maskline;
609 * @brief Generate a software interrupt for a dedicated line.
610 * @param hexti Exti handle.
611 * @retval None.
613 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
615 __IO uint32_t *regaddr;
616 uint32_t maskline;
617 uint32_t offset;
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));
629 *regaddr = maskline;
634 * @}
638 * @}
641 #endif /* HAL_EXTI_MODULE_ENABLED */
643 * @}
647 * @}
650 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/