stm32h7xx_hal_exti.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. /**
  2. ******************************************************************************
  3. * @file stm32h7xx_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 General Purpose Input/Output (EXTI) peripheral:
  8. * + Initialization and de-initialization functions
  9. * + IO operation functions
  10. *
  11. ******************************************************************************
  12. * @attention
  13. *
  14. * Copyright (c) 2017 STMicroelectronics.
  15. * All rights reserved.
  16. *
  17. * This software is licensed under terms that can be found in the LICENSE file
  18. * in the root directory of this software component.
  19. * If no LICENSE file comes with this software, it is provided AS-IS.
  20. *
  21. ******************************************************************************
  22. @verbatim
  23. ==============================================================================
  24. ##### EXTI Peripheral features #####
  25. ==============================================================================
  26. [..]
  27. (+) Each Exti line can be configured within this driver.
  28. (+) Exti line can be configured in 3 different modes
  29. (++) Interrupt (CORE1 or CORE2 in case of dual core line )
  30. (++) Event (CORE1 or CORE2 in case of dual core line )
  31. (++) a combination of the previous
  32. (+) Configurable Exti lines can be configured with 3 different triggers
  33. (++) Rising
  34. (++) Falling
  35. (++) Both of them
  36. (+) When set in interrupt mode, configurable Exti lines have two diffenrents
  37. interrupt pending registers which allow to distinguish which transition
  38. occurs:
  39. (++) Rising edge pending interrupt
  40. (++) Falling
  41. (+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
  42. be selected through multiplexer.
  43. (+) PendClearSource used to set the D3 Smart Run Domain autoamtic pend clear source.
  44. It is applicable for line with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain).
  45. Value can be one of the following:
  46. (++) EXTI_D3_PENDCLR_SRC_NONE : no pend clear source is selected :
  47. In this case corresponding bit of D2PMRx register is set to 0
  48. (+++) On a configurable Line : the D3 domain wakeup signal is
  49. automatically cleared after after the Delay + Rising Edge detect
  50. (+++) On a direct Line : the D3 domain wakeup signal is
  51. cleared after the direct event input signal is cleared
  52. (++) EXTI_D3_PENDCLR_SRC_DMACH6 : no pend clear source is selected :
  53. In this case corresponding bit of D2PMRx register is set to 1
  54. and corresponding bits(2) of D3PCRxL/H is set to b00 :
  55. DMA ch6 event selected as D3 domain pendclear source
  56. (++) EXTI_D3_PENDCLR_SRC_DMACH7 : no pend clear source is selected :
  57. In this case corresponding bit of D2PMRx register is set to 1
  58. and corresponding bits(2) of D3PCRxL/H is set to b01 :
  59. DMA ch7 event selected as D3 domain pendclear source
  60. (++) EXTI_D3_PENDCLR_SRC_LPTIM4 : no pend clear source is selected :
  61. In this case corresponding bit of D2PMRx register is set to 1
  62. and corresponding bits(2) of D3PCRxL/H is set to b10 :
  63. LPTIM4 out selected as D3 domain pendclear source
  64. (++) EXTI_D3_PENDCLR_SRC_LPTIM5 : no pend clear source is selected :
  65. In this case corresponding bit of D2PMRx register is set to 1
  66. and corresponding bits(2) of D3PCRxL/H is set to b11 :
  67. LPTIM5 out selected as D3 domain pendclear source
  68. ##### How to use this driver #####
  69. ==============================================================================
  70. [..]
  71. (#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
  72. (++) Choose the interrupt line number by setting "Line" member from
  73. EXTI_ConfigTypeDef structure.
  74. (++) Configure the interrupt and/or event mode using "Mode" member from
  75. EXTI_ConfigTypeDef structure.
  76. (++) For configurable lines, configure rising and/or falling trigger
  77. "Trigger" member from EXTI_ConfigTypeDef structure.
  78. (++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
  79. member from GPIO_InitTypeDef structure.
  80. (++) For Exti lines with wkaeup target is Any (CPU1 , CPU2 and D3 smart run domain),
  81. choose gpio D3 PendClearSource using PendClearSource
  82. member from EXTI_PendClear_Source structure.
  83. (#) Get current Exti configuration of a dedicated line using
  84. HAL_EXTI_GetConfigLine().
  85. (++) Provide exiting handle as parameter.
  86. (++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
  87. (#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
  88. (++) Provide exiting handle as parameter.
  89. (#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
  90. (++) Provide exiting handle as first parameter.
  91. (++) Provide which callback will be registered using one value from
  92. EXTI_CallbackIDTypeDef.
  93. (++) Provide callback function pointer.
  94. (#) Get interrupt pending bit using HAL_EXTI_GetPending().
  95. (#) Clear interrupt pending bit using HAL_EXTI_GetPending().
  96. (#) Generate software interrupt using HAL_EXTI_GenerateSWI().
  97. @endverbatim
  98. */
  99. /* Includes ------------------------------------------------------------------*/
  100. #include "stm32h7xx_hal.h"
  101. /** @addtogroup STM32H7xx_HAL_Driver
  102. * @{
  103. */
  104. /** @addtogroup EXTI
  105. * @{
  106. */
  107. #ifdef HAL_EXTI_MODULE_ENABLED
  108. /* Private typedef -----------------------------------------------------------*/
  109. /* Private defines ------------------------------------------------------------*/
  110. /** @defgroup EXTI_Private_Constants EXTI Private Constants
  111. * @{
  112. */
  113. #define EXTI_MODE_OFFSET 0x04U /* 0x10: offset between CPU IMR/EMR registers */
  114. #define EXTI_CONFIG_OFFSET 0x08U /* 0x20: offset between CPU Rising/Falling configuration registers */
  115. /**
  116. * @}
  117. */
  118. /* Private macros ------------------------------------------------------------*/
  119. /* Private variables ---------------------------------------------------------*/
  120. /* Private function prototypes -----------------------------------------------*/
  121. /* Exported functions --------------------------------------------------------*/
  122. /** @addtogroup EXTI_Exported_Functions
  123. * @{
  124. */
  125. /** @addtogroup EXTI_Exported_Functions_Group1
  126. * @brief Configuration functions
  127. *
  128. @verbatim
  129. ===============================================================================
  130. ##### Configuration functions #####
  131. ===============================================================================
  132. @endverbatim
  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. */
  141. HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
  142. {
  143. __IO uint32_t *regaddr;
  144. uint32_t regval;
  145. uint32_t linepos;
  146. uint32_t maskline;
  147. uint32_t offset;
  148. uint32_t pcrlinepos;
  149. /* Check null pointer */
  150. if ((hexti == NULL) || (pExtiConfig == NULL))
  151. {
  152. return HAL_ERROR;
  153. }
  154. /* Check the parameters */
  155. assert_param(IS_EXTI_LINE(pExtiConfig->Line));
  156. assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
  157. /* Assign line number to handle */
  158. hexti->Line = pExtiConfig->Line;
  159. /* compute line register offset and line mask */
  160. offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  161. linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
  162. maskline = (1UL << linepos);
  163. /* Configure triggers for configurable lines */
  164. if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
  165. {
  166. assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
  167. /* Configure rising trigger */
  168. regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
  169. regval = *regaddr;
  170. /* Mask or set line */
  171. if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00U)
  172. {
  173. regval |= maskline;
  174. }
  175. else
  176. {
  177. regval &= ~maskline;
  178. }
  179. /* Store rising trigger mode */
  180. *regaddr = regval;
  181. /* Configure falling trigger */
  182. regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
  183. regval = *regaddr;
  184. /* Mask or set line */
  185. if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00U)
  186. {
  187. regval |= maskline;
  188. }
  189. else
  190. {
  191. regval &= ~maskline;
  192. }
  193. /* Store falling trigger mode */
  194. *regaddr = regval;
  195. /* Configure gpio port selection in case of gpio exti line */
  196. if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
  197. {
  198. assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
  199. assert_param(IS_EXTI_GPIO_PIN(linepos));
  200. regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
  201. regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
  202. regval |= (pExtiConfig->GPIOSel << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03U)));
  203. SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
  204. }
  205. }
  206. /* Configure interrupt mode : read current mode */
  207. regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
  208. regval = *regaddr;
  209. /* Mask or set line */
  210. if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00U)
  211. {
  212. regval |= maskline;
  213. }
  214. else
  215. {
  216. regval &= ~maskline;
  217. }
  218. /* Store interrupt mode */
  219. *regaddr = regval;
  220. /* The event mode cannot be configured if the line does not support it */
  221. assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_EVENT) != EXTI_MODE_EVENT));
  222. /* Configure event mode : read current mode */
  223. regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
  224. regval = *regaddr;
  225. /* Mask or set line */
  226. if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00U)
  227. {
  228. regval |= maskline;
  229. }
  230. else
  231. {
  232. regval &= ~maskline;
  233. }
  234. /* Store event mode */
  235. *regaddr = regval;
  236. #if defined (DUAL_CORE)
  237. /* Configure interrupt mode for Core2 : read current mode */
  238. regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
  239. regval = *regaddr;
  240. /* Mask or set line */
  241. if ((pExtiConfig->Mode & EXTI_MODE_CORE2_INTERRUPT) != 0x00U)
  242. {
  243. regval |= maskline;
  244. }
  245. else
  246. {
  247. regval &= ~maskline;
  248. }
  249. /* Store interrupt mode */
  250. *regaddr = regval;
  251. /* The event mode cannot be configured if the line does not support it */
  252. assert_param(((pExtiConfig->Line & EXTI_EVENT) == EXTI_EVENT) || ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != EXTI_MODE_CORE2_EVENT));
  253. /* Configure event mode : read current mode */
  254. regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
  255. regval = *regaddr;
  256. /* Mask or set line */
  257. if ((pExtiConfig->Mode & EXTI_MODE_CORE2_EVENT) != 0x00U)
  258. {
  259. regval |= maskline;
  260. }
  261. else
  262. {
  263. regval &= ~maskline;
  264. }
  265. /* Store event mode */
  266. *regaddr = regval;
  267. #endif /* DUAL_CORE */
  268. /* Configure the D3 PendClear source in case of Wakeup target is Any */
  269. if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
  270. {
  271. assert_param(IS_EXTI_D3_PENDCLR_SRC(pExtiConfig->PendClearSource));
  272. /*Calc the PMR register address for the given line */
  273. regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
  274. regval = *regaddr;
  275. if(pExtiConfig->PendClearSource == EXTI_D3_PENDCLR_SRC_NONE)
  276. {
  277. /* Clear D3PMRx register for the given line */
  278. regval &= ~maskline;
  279. /* Store D3PMRx register value */
  280. *regaddr = regval;
  281. }
  282. else
  283. {
  284. /* Set D3PMRx register to 1 for the given line */
  285. regval |= maskline;
  286. /* Store D3PMRx register value */
  287. *regaddr = regval;
  288. if(linepos < 16UL)
  289. {
  290. regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
  291. pcrlinepos = 1UL << linepos;
  292. }
  293. else
  294. {
  295. regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
  296. pcrlinepos = 1UL << (linepos - 16UL);
  297. }
  298. regval = (*regaddr & (~(pcrlinepos * pcrlinepos * 3UL))) | (pcrlinepos * pcrlinepos * (pExtiConfig->PendClearSource - 1UL));
  299. *regaddr = regval;
  300. }
  301. }
  302. return HAL_OK;
  303. }
  304. /**
  305. * @brief Get configuration of a dedicated Exti line.
  306. * @param hexti Exti handle.
  307. * @param pExtiConfig Pointer on structure to store Exti configuration.
  308. * @retval HAL Status.
  309. */
  310. HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
  311. {
  312. __IO uint32_t *regaddr;
  313. uint32_t regval;
  314. uint32_t linepos;
  315. uint32_t maskline;
  316. uint32_t offset;
  317. uint32_t pcrlinepos;
  318. /* Check null pointer */
  319. if ((hexti == NULL) || (pExtiConfig == NULL))
  320. {
  321. return HAL_ERROR;
  322. }
  323. /* Check the parameter */
  324. assert_param(IS_EXTI_LINE(hexti->Line));
  325. /* Store handle line number to configuration structure */
  326. pExtiConfig->Line = hexti->Line;
  327. /* compute line register offset and line mask */
  328. offset = ((pExtiConfig->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  329. linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
  330. maskline = (1UL << linepos);
  331. /* 1] Get core mode : interrupt */
  332. regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
  333. regval = *regaddr;
  334. pExtiConfig->Mode = EXTI_MODE_NONE;
  335. /* Check if selected line is enable */
  336. if ((regval & maskline) != 0x00U)
  337. {
  338. pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
  339. }
  340. /* Get event mode */
  341. regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
  342. regval = *regaddr;
  343. /* Check if selected line is enable */
  344. if ((regval & maskline) != 0x00U)
  345. {
  346. pExtiConfig->Mode |= EXTI_MODE_EVENT;
  347. }
  348. #if defined (DUAL_CORE)
  349. regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
  350. regval = *regaddr;
  351. /* Check if selected line is enable */
  352. if ((regval & maskline) != 0x00U)
  353. {
  354. pExtiConfig->Mode = EXTI_MODE_CORE2_INTERRUPT;
  355. }
  356. /* Get event mode */
  357. regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
  358. regval = *regaddr;
  359. /* Check if selected line is enable */
  360. if ((regval & maskline) != 0x00U)
  361. {
  362. pExtiConfig->Mode |= EXTI_MODE_CORE2_EVENT;
  363. }
  364. #endif /*DUAL_CORE*/
  365. /* Get default Trigger and GPIOSel configuration */
  366. pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
  367. pExtiConfig->GPIOSel = 0x00U;
  368. /* 2] Get trigger for configurable lines : rising */
  369. if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00U)
  370. {
  371. regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
  372. regval = *regaddr;
  373. /* Check if configuration of selected line is enable */
  374. if ((regval & maskline) != 0x00U)
  375. {
  376. pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
  377. }
  378. /* Get falling configuration */
  379. regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
  380. regval = *regaddr;
  381. /* Check if configuration of selected line is enable */
  382. if ((regval & maskline) != 0x00U)
  383. {
  384. pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
  385. }
  386. /* Get Gpio port selection for gpio lines */
  387. if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
  388. {
  389. assert_param(IS_EXTI_GPIO_PIN(linepos));
  390. regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
  391. pExtiConfig->GPIOSel = ((regval << (SYSCFG_EXTICR1_EXTI1_Pos * (3UL - (linepos & 0x03UL)))) >> 24U);
  392. }
  393. }
  394. /* Get default Pend Clear Source */
  395. pExtiConfig->PendClearSource = EXTI_D3_PENDCLR_SRC_NONE;
  396. /* 3] Get D3 Pend Clear source */
  397. if ((pExtiConfig->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
  398. {
  399. regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
  400. if(((*regaddr) & linepos) != 0UL)
  401. {
  402. /* if wakeup target is any and PMR set, the read pend clear source from D3PCRxL/H */
  403. if(linepos < 16UL)
  404. {
  405. regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
  406. pcrlinepos = 1UL << linepos;
  407. }
  408. else
  409. {
  410. regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
  411. pcrlinepos = 1UL << (linepos - 16UL);
  412. }
  413. pExtiConfig->PendClearSource = 1UL + ((*regaddr & (pcrlinepos * pcrlinepos * 3UL)) / (pcrlinepos * pcrlinepos));
  414. }
  415. }
  416. return HAL_OK;
  417. }
  418. /**
  419. * @brief Clear whole configuration of a dedicated Exti line.
  420. * @param hexti Exti handle.
  421. * @retval HAL Status.
  422. */
  423. HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
  424. {
  425. __IO uint32_t *regaddr;
  426. uint32_t regval;
  427. uint32_t linepos;
  428. uint32_t maskline;
  429. uint32_t offset;
  430. uint32_t pcrlinepos;
  431. /* Check null pointer */
  432. if (hexti == NULL)
  433. {
  434. return HAL_ERROR;
  435. }
  436. /* Check the parameter */
  437. assert_param(IS_EXTI_LINE(hexti->Line));
  438. /* compute line register offset and line mask */
  439. offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  440. linepos = (hexti->Line & EXTI_PIN_MASK);
  441. maskline = (1UL << linepos);
  442. /* 1] Clear interrupt mode */
  443. regaddr = (__IO uint32_t *)(&EXTI->IMR1 + (EXTI_MODE_OFFSET * offset));
  444. regval = (*regaddr & ~maskline);
  445. *regaddr = regval;
  446. /* 2] Clear event mode */
  447. regaddr = (__IO uint32_t *)(&EXTI->EMR1 + (EXTI_MODE_OFFSET * offset));
  448. regval = (*regaddr & ~maskline);
  449. *regaddr = regval;
  450. #if defined (DUAL_CORE)
  451. /* 1] Clear CM4 interrupt mode */
  452. regaddr = (__IO uint32_t *)(&EXTI->C2IMR1 + (EXTI_MODE_OFFSET * offset));
  453. regval = (*regaddr & ~maskline);
  454. *regaddr = regval;
  455. /* 2] Clear CM4 event mode */
  456. regaddr = (__IO uint32_t *)(&EXTI->C2EMR1 + (EXTI_MODE_OFFSET * offset));
  457. regval = (*regaddr & ~maskline);
  458. *regaddr = regval;
  459. #endif /* DUAL_CORE */
  460. /* 3] Clear triggers in case of configurable lines */
  461. if ((hexti->Line & EXTI_CONFIG) != 0x00U)
  462. {
  463. regaddr = (__IO uint32_t *)(&EXTI->RTSR1 + (EXTI_CONFIG_OFFSET * offset));
  464. regval = (*regaddr & ~maskline);
  465. *regaddr = regval;
  466. regaddr = (__IO uint32_t *)(&EXTI->FTSR1 + (EXTI_CONFIG_OFFSET * offset));
  467. regval = (*regaddr & ~maskline);
  468. *regaddr = regval;
  469. /* Get Gpio port selection for gpio lines */
  470. if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
  471. {
  472. assert_param(IS_EXTI_GPIO_PIN(linepos));
  473. regval = SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL];
  474. regval &= ~(SYSCFG_EXTICR1_EXTI0 << (SYSCFG_EXTICR1_EXTI1_Pos * (linepos & 0x03UL)));
  475. SYSCFG->EXTICR[(linepos >> 2U) & 0x03UL] = regval;
  476. }
  477. }
  478. /* 4] Clear D3 Config lines */
  479. if ((hexti->Line & EXTI_TARGET_MASK) == EXTI_TARGET_MSK_ALL)
  480. {
  481. regaddr = (__IO uint32_t *)(&EXTI->D3PMR1 + (EXTI_CONFIG_OFFSET * offset));
  482. *regaddr = (*regaddr & ~maskline);
  483. if(linepos < 16UL)
  484. {
  485. regaddr = (__IO uint32_t *)(&EXTI->D3PCR1L + (EXTI_CONFIG_OFFSET * offset));
  486. pcrlinepos = 1UL << linepos;
  487. }
  488. else
  489. {
  490. regaddr = (__IO uint32_t *)(&EXTI->D3PCR1H + (EXTI_CONFIG_OFFSET * offset));
  491. pcrlinepos = 1UL << (linepos - 16UL);
  492. }
  493. /*Clear D3 PendClear source */
  494. *regaddr &= (~(pcrlinepos * pcrlinepos * 3UL));
  495. }
  496. return HAL_OK;
  497. }
  498. /**
  499. * @brief Register callback for a dedicated Exti line.
  500. * @param hexti Exti handle.
  501. * @param CallbackID User callback identifier.
  502. * This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
  503. * @param pPendingCbfn function pointer to be stored as callback.
  504. * @retval HAL Status.
  505. */
  506. HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
  507. {
  508. HAL_StatusTypeDef status = HAL_OK;
  509. /* Check null pointer */
  510. if (hexti == NULL)
  511. {
  512. return HAL_ERROR;
  513. }
  514. switch (CallbackID)
  515. {
  516. case HAL_EXTI_COMMON_CB_ID:
  517. hexti->PendingCallback = pPendingCbfn;
  518. break;
  519. default:
  520. status = HAL_ERROR;
  521. break;
  522. }
  523. return status;
  524. }
  525. /**
  526. * @brief Store line number as handle private field.
  527. * @param hexti Exti handle.
  528. * @param ExtiLine Exti line number.
  529. * This parameter can be from 0 to @ref EXTI_LINE_NB.
  530. * @retval HAL Status.
  531. */
  532. HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
  533. {
  534. /* Check the parameters */
  535. assert_param(IS_EXTI_LINE(ExtiLine));
  536. /* Check null pointer */
  537. if (hexti == NULL)
  538. {
  539. return HAL_ERROR;
  540. }
  541. else
  542. {
  543. /* Store line number as handle private field */
  544. hexti->Line = ExtiLine;
  545. return HAL_OK;
  546. }
  547. }
  548. /**
  549. * @}
  550. */
  551. /** @addtogroup EXTI_Exported_Functions_Group2
  552. * @brief EXTI IO functions.
  553. *
  554. @verbatim
  555. ===============================================================================
  556. ##### IO operation functions #####
  557. ===============================================================================
  558. @endverbatim
  559. * @{
  560. */
  561. /**
  562. * @brief Handle EXTI interrupt request.
  563. * @param hexti Exti handle.
  564. * @retval none.
  565. */
  566. void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
  567. {
  568. __IO uint32_t *regaddr;
  569. uint32_t regval;
  570. uint32_t maskline;
  571. uint32_t offset;
  572. /* Compute line register offset and line mask */
  573. offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  574. maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
  575. #if defined(DUAL_CORE)
  576. if (HAL_GetCurrentCPUID() == CM7_CPUID)
  577. {
  578. /* Get pending register address */
  579. regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
  580. }
  581. else /* Cortex-M4*/
  582. {
  583. /* Get pending register address */
  584. regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
  585. }
  586. #else
  587. regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
  588. #endif /* DUAL_CORE */
  589. /* Get pending bit */
  590. regval = (*regaddr & maskline);
  591. if (regval != 0x00U)
  592. {
  593. /* Clear pending bit */
  594. *regaddr = maskline;
  595. /* Call callback */
  596. if (hexti->PendingCallback != NULL)
  597. {
  598. hexti->PendingCallback();
  599. }
  600. }
  601. }
  602. /**
  603. * @brief Get interrupt pending bit of a dedicated line.
  604. * @param hexti Exti handle.
  605. * @param Edge Specify which pending edge as to be checked.
  606. * This parameter can be one of the following values:
  607. * @arg @ref EXTI_TRIGGER_RISING_FALLING
  608. * This parameter is kept for compatibility with other series.
  609. * @retval 1 if interrupt is pending else 0.
  610. */
  611. uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
  612. {
  613. __IO uint32_t *regaddr;
  614. uint32_t regval;
  615. uint32_t linepos;
  616. uint32_t maskline;
  617. uint32_t offset;
  618. /* Check parameters */
  619. assert_param(IS_EXTI_LINE(hexti->Line));
  620. assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
  621. assert_param(IS_EXTI_PENDING_EDGE(Edge));
  622. /* compute line register offset and line mask */
  623. offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  624. linepos = (hexti->Line & EXTI_PIN_MASK);
  625. maskline = (1UL << linepos);
  626. #if defined(DUAL_CORE)
  627. if (HAL_GetCurrentCPUID() == CM7_CPUID)
  628. {
  629. /* Get pending register address */
  630. regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
  631. }
  632. else /* Cortex-M4 */
  633. {
  634. /* Get pending register address */
  635. regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
  636. }
  637. #else
  638. regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
  639. #endif /* DUAL_CORE */
  640. /* return 1 if bit is set else 0 */
  641. regval = ((*regaddr & maskline) >> linepos);
  642. return regval;
  643. }
  644. /**
  645. * @brief Clear interrupt pending bit of a dedicated line.
  646. * @param hexti Exti handle.
  647. * @param Edge Specify which pending edge as to be clear.
  648. * This parameter can be one of the following values:
  649. * @arg @ref EXTI_TRIGGER_RISING_FALLING
  650. * This parameter is kept for compatibility with other series.
  651. * @retval None.
  652. */
  653. void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
  654. {
  655. __IO uint32_t *regaddr;
  656. uint32_t maskline;
  657. uint32_t offset;
  658. /* Check parameters */
  659. assert_param(IS_EXTI_LINE(hexti->Line));
  660. assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
  661. assert_param(IS_EXTI_PENDING_EDGE(Edge));
  662. /* compute line register offset and line mask */
  663. offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  664. maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
  665. #if defined(DUAL_CORE)
  666. if (HAL_GetCurrentCPUID() == CM7_CPUID)
  667. {
  668. /* Get pending register address */
  669. regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
  670. }
  671. else /* Cortex-M4 */
  672. {
  673. /* Get pending register address */
  674. regaddr = (__IO uint32_t *)(&EXTI->C2PR1 + (EXTI_MODE_OFFSET * offset));
  675. }
  676. #else
  677. regaddr = (__IO uint32_t *)(&EXTI->PR1 + (EXTI_MODE_OFFSET * offset));
  678. #endif /* DUAL_CORE */
  679. /* Clear Pending bit */
  680. *regaddr = maskline;
  681. }
  682. /**
  683. * @brief Generate a software interrupt for a dedicated line.
  684. * @param hexti Exti handle.
  685. * @retval None.
  686. */
  687. void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
  688. {
  689. __IO uint32_t *regaddr;
  690. uint32_t maskline;
  691. uint32_t offset;
  692. /* Check parameters */
  693. assert_param(IS_EXTI_LINE(hexti->Line));
  694. assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
  695. /* compute line register offset and line mask */
  696. offset = ((hexti->Line & EXTI_REG_MASK) >> EXTI_REG_SHIFT);
  697. maskline = (1UL << (hexti->Line & EXTI_PIN_MASK));
  698. regaddr = (__IO uint32_t *)(&EXTI->SWIER1 + (EXTI_CONFIG_OFFSET * offset));
  699. *regaddr = maskline;
  700. }
  701. /**
  702. * @}
  703. */
  704. /**
  705. * @}
  706. */
  707. #endif /* HAL_EXTI_MODULE_ENABLED */
  708. /**
  709. * @}
  710. */
  711. /**
  712. * @}
  713. */