You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

878 lines
26 KiB

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