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>© 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