STM32L4xx_HAL_Driver  1.14.0
stm32l4xx_hal_exti.c
Go to the documentation of this file.
1 
86 /* Includes ------------------------------------------------------------------*/
87 #include "stm32l4xx_hal.h"
88 
104 #ifdef HAL_EXTI_MODULE_ENABLED
105 
106 /* Private typedef -----------------------------------------------------------*/
107 /* Private defines ------------------------------------------------------------*/
111 #define EXTI_MODE_OFFSET 0x08u /* 0x20: offset between MCU IMR/EMR registers */
112 #define EXTI_CONFIG_OFFSET 0x08u /* 0x20: offset between MCU Rising/Falling configuration registers */
113 
117 /* Private macros ------------------------------------------------------------*/
118 /* Private variables ---------------------------------------------------------*/
119 /* Private function prototypes -----------------------------------------------*/
120 /* Exported functions --------------------------------------------------------*/
121 
144 HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
145 {
146  __IO uint32_t *regaddr;
147  uint32_t regval;
148  uint32_t linepos;
149  uint32_t maskline;
150  uint32_t offset;
151 
152  /* Check null pointer */
153  if ((hexti == NULL) || (pExtiConfig == NULL))
154  {
155  return HAL_ERROR;
156  }
157 
158  /* Check parameters */
159  assert_param(IS_EXTI_LINE(pExtiConfig->Line));
160  assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
161 
162  /* Assign line number to handle */
163  hexti->Line = pExtiConfig->Line;
164 
165  /* Compute line register offset and line mask */
166  offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
167  linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
168  maskline = (1uL << linepos);
169 
170  /* Configure triggers for configurable lines */
171  if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
172  {
173  assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
174 
175  /* Configure rising trigger */
176  regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
177  regval = *regaddr;
178 
179  /* Mask or set line */
180  if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u)
181  {
182  regval |= maskline;
183  }
184  else
185  {
186  regval &= ~maskline;
187  }
188 
189  /* Store rising trigger mode */
190  *regaddr = regval;
191 
192  /* Configure falling trigger */
193  regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
194  regval = *regaddr;
195 
196  /* Mask or set line */
197  if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u)
198  {
199  regval |= maskline;
200  }
201  else
202  {
203  regval &= ~maskline;
204  }
205 
206  /* Store falling trigger mode */
207  *regaddr = regval;
208 
209  /* Configure gpio port selection in case of gpio exti line */
210  if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
211  {
212  assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
213  assert_param(IS_EXTI_GPIO_PIN(linepos));
214 
215  regval = SYSCFG->EXTICR[linepos >> 2u];
216  regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
217  regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
218  SYSCFG->EXTICR[linepos >> 2u] = regval;
219  }
220  }
221 
222  /* Configure interrupt mode : read current mode */
223  regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
224  regval = *regaddr;
225 
226  /* Mask or set line */
227  if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u)
228  {
229  regval |= maskline;
230  }
231  else
232  {
233  regval &= ~maskline;
234  }
235 
236  /* Store interrupt mode */
237  *regaddr = regval;
238 
239  /* The event mode cannot be configured if the line does not support it */
240  assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
241 
242  /* Configure event mode : read current mode */
243  regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
244  regval = *regaddr;
245 
246  /* Mask or set line */
247  if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u)
248  {
249  regval |= maskline;
250  }
251  else
252  {
253  regval &= ~maskline;
254  }
255 
256  /* Store event mode */
257  *regaddr = regval;
258 
259  return HAL_OK;
260 }
261 
262 
269 HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
270 {
271  __IO uint32_t *regaddr;
272  uint32_t regval;
273  uint32_t linepos;
274  uint32_t maskline;
275  uint32_t offset;
276 
277  /* Check null pointer */
278  if ((hexti == NULL) || (pExtiConfig == NULL))
279  {
280  return HAL_ERROR;
281  }
282 
283  /* Check the parameter */
284  assert_param(IS_EXTI_LINE(hexti->Line));
285 
286  /* Store handle line number to configuration structure */
287  pExtiConfig->Line = hexti->Line;
288 
289  /* Compute line register offset and line mask */
290  offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
291  linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
292  maskline = (1uL << linepos);
293 
294  /* 1] Get core mode : interrupt */
295  regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
296  regval = *regaddr;
297 
298  /* Check if selected line is enable */
299  if ((regval & maskline) != 0x00u)
300  {
301  pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
302  }
303  else
304  {
305  pExtiConfig->Mode = EXTI_MODE_NONE;
306  }
307 
308  /* Get event mode */
309  regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
310  regval = *regaddr;
311 
312  /* Check if selected line is enable */
313  if ((regval & maskline) != 0x00u)
314  {
315  pExtiConfig->Mode |= EXTI_MODE_EVENT;
316  }
317 
318  /* 2] Get trigger for configurable lines : rising */
319  if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
320  {
321  regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
322  regval = *regaddr;
323 
324  /* Check if configuration of selected line is enable */
325  if ((regval & maskline) != 0x00u)
326  {
327  pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
328  }
329  else
330  {
331  pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
332  }
333 
334  /* Get falling configuration */
335  regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
336  regval = *regaddr;
337 
338  /* Check if configuration of selected line is enable */
339  if ((regval & maskline) != 0x00u)
340  {
341  pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
342  }
343 
344  /* Get Gpio port selection for gpio lines */
345  if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
346  {
347  assert_param(IS_EXTI_GPIO_PIN(linepos));
348 
349  regval = SYSCFG->EXTICR[linepos >> 2u];
350  pExtiConfig->GPIOSel = ((regval << (SYSCFG_EXTICR1_EXTI1_Pos * (3uL - (linepos & 0x03u)))) >> 24);
351  }
352  else
353  {
354  pExtiConfig->GPIOSel = 0x00u;
355  }
356  }
357  else
358  {
359  pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
360  pExtiConfig->GPIOSel = 0x00u;
361  }
362 
363  return HAL_OK;
364 }
365 
366 
373 {
374  __IO uint32_t *regaddr;
375  uint32_t regval;
376  uint32_t linepos;
377  uint32_t maskline;
378  uint32_t offset;
379 
380  /* Check null pointer */
381  if (hexti == NULL)
382  {
383  return HAL_ERROR;
384  }
385 
386  /* Check the parameter */
387  assert_param(IS_EXTI_LINE(hexti->Line));
388 
389  /* compute line register offset and line mask */
390  offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
391  linepos = (hexti->Line & EXTI_PIN_MASK);
392  maskline = (1uL << linepos);
393 
394  /* 1] Clear interrupt mode */
395  regaddr = (&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
396  regval = (*regaddr & ~maskline);
397  *regaddr = regval;
398 
399  /* 2] Clear event mode */
400  regaddr = (&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
401  regval = (*regaddr & ~maskline);
402  *regaddr = regval;
403 
404  /* 3] Clear triggers in case of configurable lines */
405  if ((hexti->Line & EXTI_CONFIG) != 0x00u)
406  {
407  regaddr = (&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
408  regval = (*regaddr & ~maskline);
409  *regaddr = regval;
410 
411  regaddr = (&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
412  regval = (*regaddr & ~maskline);
413  *regaddr = regval;
414 
415  /* Get Gpio port selection for gpio lines */
416  if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
417  {
418  assert_param(IS_EXTI_GPIO_PIN(linepos));
419 
420  regval = SYSCFG->EXTICR[linepos >> 2u];
421  regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
422  SYSCFG->EXTICR[linepos >> 2u] = regval;
423  }
424  }
425 
426  return HAL_OK;
427 }
428 
429 
438 HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
439 {
440  HAL_StatusTypeDef status = HAL_OK;
441 
442  switch (CallbackID)
443  {
445  hexti->PendingCallback = pPendingCbfn;
446  break;
447 
448  default:
449  status = HAL_ERROR;
450  break;
451  }
452 
453  return status;
454 }
455 
456 
464 HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
465 {
466  /* Check the parameters */
467  assert_param(IS_EXTI_LINE(ExtiLine));
468 
469  /* Check null pointer */
470  if (hexti == NULL)
471  {
472  return HAL_ERROR;
473  }
474  else
475  {
476  /* Store line number as handle private field */
477  hexti->Line = ExtiLine;
478 
479  return HAL_OK;
480  }
481 }
482 
483 
506 {
507  __IO uint32_t *regaddr;
508  uint32_t regval;
509  uint32_t maskline;
510  uint32_t offset;
511 
512  /* Compute line register offset and line mask */
513  offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
514  maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
515 
516  /* Get pending bit */
517  regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
518  regval = (*regaddr & maskline);
519 
520  if (regval != 0x00u)
521  {
522  /* Clear pending bit */
523  *regaddr = maskline;
524 
525  /* Call callback */
526  if (hexti->PendingCallback != NULL)
527  {
528  hexti->PendingCallback();
529  }
530  }
531 }
532 
533 
543 uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
544 {
545  __IO uint32_t *regaddr;
546  uint32_t regval;
547  uint32_t linepos;
548  uint32_t maskline;
549  uint32_t offset;
550 
551  /* Check parameters */
552  assert_param(IS_EXTI_LINE(hexti->Line));
553  assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
554  assert_param(IS_EXTI_PENDING_EDGE(Edge));
555 
556  /* Compute line register offset and line mask */
557  offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
558  linepos = (hexti->Line & EXTI_PIN_MASK);
559  maskline = (1uL << linepos);
560 
561  /* Get pending bit */
562  regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
563 
564  /* return 1 if bit is set else 0 */
565  regval = ((*regaddr & maskline) >> linepos);
566  return regval;
567 }
568 
569 
579 void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
580 {
581  __IO uint32_t *regaddr;
582  uint32_t maskline;
583  uint32_t offset;
584 
585  /* Check parameters */
586  assert_param(IS_EXTI_LINE(hexti->Line));
587  assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
588  assert_param(IS_EXTI_PENDING_EDGE(Edge));
589 
590  /* compute line register offset and line mask */
591  offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
592  maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
593 
594  /* Get pending register address */
595  regaddr = (&EXTI->PR1 + (EXTI_CONFIG_OFFSET * offset));
596 
597  /* Clear Pending bit */
598  *regaddr = maskline;
599 }
600 
601 
608 {
609  __IO uint32_t *regaddr;
610  uint32_t maskline;
611  uint32_t offset;
612 
613  /* Check parameters */
614  assert_param(IS_EXTI_LINE(hexti->Line));
615  assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
616 
617  /* compute line register offset and line mask */
618  offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
619  maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
620 
621  regaddr = (&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
622  *regaddr = maskline;
623 }
624 
625 
634 #endif /* HAL_EXTI_MODULE_ENABLED */
635 
643 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
Clear interrupt pending bit of a dedicated line.
EXTI Handle structure definition.
HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
Get configuration of a dedicated Exti line.
This file contains all the functions prototypes for the HAL module driver.
HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
Set configuration of a dedicated Exti line.
void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
Handle EXTI interrupt request.
EXTI_CallbackIDTypeDef
return HAL_OK
void(* PendingCallback)(void)
uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
Get interrupt pending bit of a dedicated line.
EXTI Configuration structure definition.
HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void(*pPendingCbfn)(void))
Register callback for a dedicated Exti line.
HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
Clear whole configuration of a dedicated Exti line.
void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
Generate a software interrupt for a dedicated line.
HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
Store line number as handle private field.
assert_param(IS_RTC_WAKEUP_CLOCK(WakeUpClock))