xref: /btstack/port/stm32-f4discovery-cc256x/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_exti.c (revision 225f4ba4fe806afeda1ee8519bb5f4a8ce540af2)
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_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   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *
11   @verbatim
12   ==============================================================================
13                     ##### EXTI Peripheral features #####
14   ==============================================================================
15   [..]
16     (+) Each Exti line can be configured within this driver.
17 
18     (+) Exti line can be configured in 3 different modes
19         (++) Interrupt
20         (++) Event
21         (++) Both of them
22 
23     (+) Configurable Exti lines can be configured with 3 different triggers
24         (++) Rising
25         (++) Falling
26         (++) Both of them
27 
28     (+) When set in interrupt mode, configurable Exti lines have two different
29         interrupts pending registers which allow to distinguish which transition
30         occurs:
31         (++) Rising edge pending interrupt
32         (++) Falling
33 
34     (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
35         be selected through multiplexer.
36 
37                      ##### How to use this driver #####
38   ==============================================================================
39   [..]
40 
41     (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
42         (++) Choose the interrupt line number by setting "Line" member from
43              EXTI_ConfigTypeDef structure.
44         (++) Configure the interrupt and/or event mode using "Mode" member from
45              EXTI_ConfigTypeDef structure.
46         (++) For configurable lines, configure rising and/or falling trigger
47              "Trigger" member from EXTI_ConfigTypeDef structure.
48 
49     (#) Get current Exti configuration of a dedicated line using
50         HAL_EXTI_GetConfigLine().
51         (++) Provide exiting handle as parameter.
52         (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
53 
54     (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
55         (++) Provide exiting handle as parameter.
56 
57     (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
58         (++) Provide exiting handle as first parameter.
59         (++) Provide which callback will be registered using one value from
60              EXTI_CallbackIDTypeDef.
61         (++) Provide callback function pointer.
62 
63     (#) Get interrupt pending bit using HAL_EXTI_GetPending().
64 
65     (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
66 
67     (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
68 
69   @endverbatim
70   ******************************************************************************
71   * @attention
72   *
73   * <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
74   * All rights reserved.</center></h2>
75   *
76   * This software component is licensed by ST under BSD 3-Clause license,
77   * the "License"; You may not use this file except in compliance with the
78   * License. You may obtain a copy of the License at:
79   *                        opensource.org/licenses/BSD-3-Clause
80   *
81   ******************************************************************************
82   */
83 
84 /* Includes ------------------------------------------------------------------*/
85 #include "stm32f4xx_hal.h"
86 
87 /** @addtogroup STM32F4xx_HAL_Driver
88   * @{
89   */
90 
91 /** @addtogroup EXTI
92   * @{
93   */
94 /** MISRA C:2012 deviation rule has been granted for following rule:
95   * Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out
96   * of bounds [0,3] in following API :
97   * HAL_EXTI_SetConfigLine
98   * HAL_EXTI_GetConfigLine
99   * HAL_EXTI_ClearConfigLine
100   */
101 
102 #ifdef HAL_EXTI_MODULE_ENABLED
103 
104 /* Private typedef -----------------------------------------------------------*/
105 /* Private defines -----------------------------------------------------------*/
106 /** @defgroup EXTI_Private_Constants EXTI Private Constants
107   * @{
108   */
109 
110 /**
111   * @}
112   */
113 
114 /* Private macros ------------------------------------------------------------*/
115 /* Private variables ---------------------------------------------------------*/
116 /* Private function prototypes -----------------------------------------------*/
117 /* Exported functions --------------------------------------------------------*/
118 
119 /** @addtogroup EXTI_Exported_Functions
120   * @{
121   */
122 
123 /** @addtogroup EXTI_Exported_Functions_Group1
124   *  @brief    Configuration functions
125   *
126 @verbatim
127  ===============================================================================
128               ##### Configuration functions #####
129  ===============================================================================
130 
131 @endverbatim
132   * @{
133   */
134 
135 /**
136   * @brief  Set configuration of a dedicated Exti line.
137   * @param  hexti Exti handle.
138   * @param  pExtiConfig Pointer on EXTI configuration to be set.
139   * @retval HAL Status.
140   */
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)141 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
142 {
143   uint32_t regval;
144 
145   /* Check null pointer */
146   if ((hexti == NULL) || (pExtiConfig == NULL))
147   {
148     return HAL_ERROR;
149   }
150 
151   /* Check parameters */
152   assert_param(IS_EXTI_LINE(pExtiConfig->Line));
153   assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
154   assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
155 
156   /* Assign line number to handle */
157   hexti->Line = pExtiConfig->Line;
158 
159   /* Clear EXTI line configuration */
160   EXTI->IMR &= ~pExtiConfig->Line;
161   EXTI->EMR &= ~pExtiConfig->Line;
162 
163   /* Select the Mode for the selected external interrupts */
164   regval = (uint32_t)EXTI_BASE;
165   regval += pExtiConfig->Mode;
166   *(__IO uint32_t *) regval |= pExtiConfig->Line;
167 
168   /* Clear Rising Falling edge configuration */
169   EXTI->RTSR &= ~pExtiConfig->Line;
170   EXTI->FTSR &= ~pExtiConfig->Line;
171 
172   /* Select the trigger for the selected external interrupts */
173   if (pExtiConfig->Trigger == EXTI_TRIGGER_RISING_FALLING)
174   {
175     /* Rising Falling edge */
176     EXTI->RTSR |= pExtiConfig->Line;
177     EXTI->FTSR |= pExtiConfig->Line;
178   }
179   else
180   {
181     regval = (uint32_t)EXTI_BASE;
182     regval += pExtiConfig->Trigger;
183     *(__IO uint32_t *) regval |= pExtiConfig->Line;
184   }
185   return HAL_OK;
186 }
187 
188 /**
189   * @brief  Get configuration of a dedicated Exti line.
190   * @param  hexti Exti handle.
191   * @param  pExtiConfig Pointer on structure to store Exti configuration.
192   * @retval HAL Status.
193   */
HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef * hexti,EXTI_ConfigTypeDef * pExtiConfig)194 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
195 {
196   /* Check null pointer */
197   if ((hexti == NULL) || (pExtiConfig == NULL))
198   {
199     return HAL_ERROR;
200   }
201 
202   /* Check the parameter */
203   assert_param(IS_EXTI_LINE(hexti->Line));
204 
205   /* Store handle line number to configuration structure */
206   pExtiConfig->Line = hexti->Line;
207 
208   /* Get EXTI mode to configiguration structure */
209   if ((EXTI->IMR & hexti->Line) == hexti->Line)
210   {
211     pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
212   }
213   else if ((EXTI->EMR & hexti->Line) == hexti->Line)
214   {
215     pExtiConfig->Mode = EXTI_MODE_EVENT;
216   }
217   else
218   {
219     /* No MODE selected */
220     pExtiConfig->Mode = 0x0Bu;
221   }
222 
223   /* Get EXTI Trigger to configiguration structure */
224   if ((EXTI->RTSR & hexti->Line) == hexti->Line)
225   {
226     if ((EXTI->FTSR & hexti->Line) == hexti->Line)
227     {
228       pExtiConfig->Trigger = EXTI_TRIGGER_RISING_FALLING;
229     }
230     else
231     {
232       pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
233     }
234   }
235   else if ((EXTI->FTSR & hexti->Line) == hexti->Line)
236   {
237     pExtiConfig->Trigger = EXTI_TRIGGER_FALLING;
238   }
239   else
240   {
241     /* No Trigger selected */
242     pExtiConfig->Trigger = 0x00u;
243   }
244 
245   return HAL_OK;
246 }
247 
248 /**
249   * @brief  Clear whole configuration of a dedicated Exti line.
250   * @param  hexti Exti handle.
251   * @retval HAL Status.
252   */
HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef * hexti)253 HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
254 {
255   /* Check null pointer */
256   if (hexti == NULL)
257   {
258     return HAL_ERROR;
259   }
260 
261   /* Check the parameter */
262   assert_param(IS_EXTI_LINE(hexti->Line));
263 
264   /* 1] Clear interrupt mode */
265   EXTI->IMR = (EXTI->IMR & ~hexti->Line);
266 
267   /* 2] Clear event mode */
268   EXTI->EMR = (EXTI->EMR & ~hexti->Line);
269 
270   /* 3] Clear triggers */
271   EXTI->RTSR = (EXTI->RTSR & ~hexti->Line);
272   EXTI->FTSR = (EXTI->FTSR & ~hexti->Line);
273 
274   return HAL_OK;
275 }
276 
277 /**
278   * @brief  Register callback for a dedicated Exti line.
279   * @param  hexti Exti handle.
280   * @param  CallbackID User callback identifier.
281   *         This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
282   * @param  pPendingCbfn function pointer to be stored as callback.
283   * @retval HAL Status.
284   */
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef * hexti,EXTI_CallbackIDTypeDef CallbackID,void (* pPendingCbfn)(void))285 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
286 {
287   HAL_StatusTypeDef status = HAL_OK;
288 
289   switch (CallbackID)
290   {
291     case  HAL_EXTI_COMMON_CB_ID:
292       hexti->RisingCallback = pPendingCbfn;
293       break;
294 
295     default:
296       status = HAL_ERROR;
297       break;
298   }
299 
300   return status;
301 }
302 
303 /**
304   * @brief  Store line number as handle private field.
305   * @param  hexti Exti handle.
306   * @param  ExtiLine Exti line number.
307   *         This parameter can be from 0 to @ref EXTI_LINE_NB.
308   * @retval HAL Status.
309   */
HAL_EXTI_GetHandle(EXTI_HandleTypeDef * hexti,uint32_t ExtiLine)310 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
311 {
312   /* Check the parameters */
313   assert_param(IS_EXTI_LINE(ExtiLine));
314 
315   /* Check null pointer */
316   if (hexti == NULL)
317   {
318     return HAL_ERROR;
319   }
320   else
321   {
322     /* Store line number as handle private field */
323     hexti->Line = ExtiLine;
324 
325     return HAL_OK;
326   }
327 }
328 
329 /**
330   * @}
331   */
332 
333 /** @addtogroup EXTI_Exported_Functions_Group2
334   *  @brief EXTI IO functions.
335   *
336 @verbatim
337  ===============================================================================
338                        ##### IO operation functions #####
339  ===============================================================================
340 
341 @endverbatim
342   * @{
343   */
344 
345 /**
346   * @brief  Handle EXTI interrupt request.
347   * @param  hexti Exti handle.
348   * @retval none.
349   */
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef * hexti)350 void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
351 {
352   if (EXTI->PR != 0x00u)
353   {
354     /* Clear pending bit */
355     EXTI->PR = hexti->Line;
356 
357     /* Call callback */
358     if (hexti->RisingCallback != NULL)
359     {
360       hexti->RisingCallback();
361     }
362   }
363 }
364 
365 /**
366   * @brief  Get interrupt pending bit of a dedicated line.
367   * @param  hexti Exti handle.
368   * @param  Edge Specify which pending edge as to be checked.
369   *         This parameter can be one of the following values:
370   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
371   *         This parameter is kept for compatibility with other series.
372   * @retval 1 if interrupt is pending else 0.
373   */
HAL_EXTI_GetPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)374 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
375 {
376   __IO uint32_t *regaddr;
377   uint32_t regval;
378 
379   /* Check parameters */
380   assert_param(IS_EXTI_LINE(hexti->Line));
381   assert_param(IS_EXTI_PENDING_EDGE(Edge));
382 
383   /* Get pending bit */
384   regaddr = &EXTI->PR;
385 
386   /* return 1 if bit is set else 0 */
387   regval = ((*regaddr & hexti->Line) >> POSITION_VAL(hexti->Line));
388 
389   return regval;
390 }
391 
392 /**
393   * @brief  Clear interrupt pending bit of a dedicated line.
394   * @param  hexti Exti handle.
395   * @param  Edge Specify which pending edge as to be clear.
396   *         This parameter can be one of the following values:
397   *           @arg @ref EXTI_TRIGGER_RISING_FALLING
398   *         This parameter is kept for compatibility with other series.
399   * @retval None.
400   */
HAL_EXTI_ClearPending(EXTI_HandleTypeDef * hexti,uint32_t Edge)401 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
402 {
403   /* Check parameters */
404   assert_param(IS_EXTI_LINE(hexti->Line));
405   assert_param(IS_EXTI_PENDING_EDGE(Edge));
406 
407   EXTI->PR =  hexti->Line;
408 }
409 
410 /**
411   * @brief  Generate a software interrupt for a dedicated line.
412   * @param  hexti Exti handle.
413   * @retval None.
414   */
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef * hexti)415 void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
416 {
417   /* Check parameters */
418   assert_param(IS_EXTI_LINE(hexti->Line));
419 
420   EXTI->SWIER = hexti->Line;
421 }
422 
423 /**
424   * @}
425   */
426 
427 /**
428   * @}
429   */
430 
431 #endif /* HAL_EXTI_MODULE_ENABLED */
432 /**
433   * @}
434   */
435 
436 /**
437   * @}
438   */
439 
440 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
441