hdl_interrupt.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. /***************************************************************************//**
  2. * @file hdl_interrupt.c
  3. * @brief USART driver of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2011, RT-Thread Development Team
  5. * @author onelife
  6. * @version 0.4 beta
  7. *******************************************************************************
  8. * @section License
  9. * The license and distribution terms for this file may be found in the file
  10. * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE
  11. *******************************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2010-12-29 onelife Initial creation for EFM32
  15. * 2011-07-12 onelife Disable interrupts in GPIO handler
  16. ******************************************************************************/
  17. /* Includes ------------------------------------------------------------------*/
  18. #include "board.h"
  19. #include "hdl_interrupt.h"
  20. /***************************************************************************//**
  21. * @addtogroup efm32
  22. * @{
  23. ******************************************************************************/
  24. /* Private typedef -----------------------------------------------------------*/
  25. /* Private define ------------------------------------------------------------*/
  26. /* Private macro -------------------------------------------------------------*/
  27. #ifdef RT_IRQHDL_DEBUG
  28. #define hdl_debug(format,args...) rt_kprintf(format, ##args)
  29. #else
  30. #define hdl_debug(format,args...)
  31. #endif
  32. /* Private variables ---------------------------------------------------------*/
  33. efm32_irq_hook_t dmaCbTable[DMA_CHAN_COUNT * 2] = {RT_NULL};
  34. efm32_irq_hook_t timerCbTable[TIMER_COUNT] = {RT_NULL};
  35. efm32_irq_hook_t rtcCbTable[RTC_COUNT] = {RT_NULL};
  36. efm32_irq_hook_t gpioCbTable[16] = {RT_NULL};
  37. efm32_irq_hook_t acmpCbTable[ACMP_COUNT] = {RT_NULL};
  38. efm32_irq_hook_t usartCbTable[USART_COUNT * 2] = {RT_NULL};
  39. efm32_irq_hook_t iicCbTable[I2C_COUNT] = {RT_NULL};
  40. /* Private function prototypes -----------------------------------------------*/
  41. /* Private functions ---------------------------------------------------------*/
  42. /***************************************************************************//**
  43. * @brief
  44. * NMI exception handler
  45. *
  46. * @details
  47. *
  48. * @note
  49. ******************************************************************************/
  50. void NMI_Handler(void)
  51. {
  52. hdl_debug("[NMI_Handler: NOP]\n");
  53. }
  54. /***************************************************************************//**
  55. * @brief
  56. * Memory manage exception handler
  57. *
  58. * @details
  59. *
  60. * @note
  61. ******************************************************************************/
  62. void MemManage_Handler(void)
  63. {
  64. hdl_debug("[MemManage_Handler: infinite loop]\n");
  65. while (1);
  66. }
  67. /***************************************************************************//**
  68. * @brief
  69. * Bus fault exception handler
  70. *
  71. * @details
  72. *
  73. * @note
  74. ******************************************************************************/
  75. void BusFault_Handler(void)
  76. {
  77. hdl_debug("[BusFault_Handler: infinite loop]\n");
  78. while (1);
  79. }
  80. /***************************************************************************//**
  81. * @brief
  82. * Usage fault exception handler
  83. *
  84. * @details
  85. *
  86. * @note
  87. ******************************************************************************/
  88. void UsageFault_Handler(void)
  89. {
  90. hdl_debug("[UsageFault_Handler: infinite loop]\n");
  91. while (1);
  92. }
  93. /***************************************************************************//**
  94. * @brief
  95. * Supervisor call exception handler
  96. *
  97. * @details
  98. *
  99. * @note
  100. ******************************************************************************/
  101. void SVC_Handler(void)
  102. {
  103. hdl_debug("[SVC_Handler: NOP]\n");
  104. }
  105. /***************************************************************************//**
  106. * @brief
  107. * Debug monitor exception handler
  108. *
  109. * @details
  110. *
  111. * @note
  112. ******************************************************************************/
  113. void DebugMon_Handler(void)
  114. {
  115. hdl_debug("[DebugMon_Handler: NOP]\n");
  116. }
  117. /***************************************************************************//**
  118. * @brief
  119. * System tick timer interrupt handler
  120. *
  121. * @details
  122. *
  123. * @note
  124. *
  125. ******************************************************************************/
  126. void SysTick_Handler(void)
  127. {
  128. /* enter interrupt */
  129. rt_interrupt_enter();
  130. rt_tick_increase();
  131. /* leave interrupt */
  132. rt_interrupt_leave();
  133. }
  134. /*******************************************************************************
  135. * STM32F10x Peripherals Interrupt Handlers
  136. * Add here the Interrupt Handler for the used peripheral(s) (PPP), for the
  137. * available peripheral interrupt handler's name please refer to the startup
  138. * file (startup_stm32f10x_xx.s).
  139. /******************************************************************************/
  140. /***************************************************************************//**
  141. * @brief
  142. * Common DMA interrupt handler
  143. *
  144. * @details
  145. *
  146. * @note
  147. *
  148. ******************************************************************************/
  149. void DMA_IRQHandler_All(unsigned int channel, bool primary, void *user)
  150. {
  151. /* enter interrupt */
  152. rt_interrupt_enter();
  153. /* invoke callback function */
  154. if (dmaCbTable[channel].cbFunc != RT_NULL)
  155. {
  156. (dmaCbTable[channel].cbFunc)(dmaCbTable[channel].userPtr);
  157. }
  158. /* leave interrupt */
  159. rt_interrupt_leave();
  160. }
  161. /***************************************************************************//**
  162. * @brief
  163. * Common Timer1 interrupt handler
  164. *
  165. * @details
  166. * This function handles Timer1 counter overflow interrupt request
  167. *
  168. * @note
  169. *
  170. ******************************************************************************/
  171. void TIMER1_IRQHandler(void)
  172. {
  173. if (TIMER1->IF & TIMER_IF_OF)
  174. {
  175. /* invoke callback function */
  176. if (timerCbTable[1].cbFunc != RT_NULL)
  177. {
  178. (timerCbTable[1].cbFunc)(timerCbTable[1].userPtr);
  179. }
  180. /* clear interrupt */
  181. BITBAND_Peripheral(&(TIMER1->IFC), _TIMER_IF_OF_SHIFT, 0x1UL);
  182. }
  183. }
  184. /***************************************************************************//**
  185. * @brief
  186. * Common Timer2 interrupt handler
  187. *
  188. * @details
  189. * This function handles Timer2 counter overflow interrupt request
  190. *
  191. * @note
  192. *
  193. ******************************************************************************/
  194. void TIMER2_IRQHandler(void)
  195. {
  196. if (TIMER2->IF & TIMER_IF_OF)
  197. {
  198. /* invoke callback function */
  199. if (timerCbTable[2].cbFunc != RT_NULL)
  200. {
  201. (timerCbTable[2].cbFunc)(timerCbTable[2].userPtr);
  202. }
  203. /* clear interrupt */
  204. BITBAND_Peripheral(&(TIMER2->IFC), _TIMER_IF_OF_SHIFT, 0x1UL);
  205. }
  206. }
  207. /***************************************************************************//**
  208. * @brief
  209. * Common RTC interrupt handler
  210. *
  211. * @details
  212. * This function handles RTC counter overflow interrupt request
  213. *
  214. * @note
  215. *
  216. ******************************************************************************/
  217. void RTC_IRQHandler(void)
  218. {
  219. /* enter interrupt */
  220. rt_interrupt_enter();
  221. if (RTC->IF & RTC_IF_OF)
  222. {
  223. /* invoke callback function */
  224. if (rtcCbTable[0].cbFunc != RT_NULL)
  225. {
  226. (rtcCbTable[0].cbFunc)(rtcCbTable[0].userPtr);
  227. }
  228. }
  229. /* leave interrupt */
  230. rt_interrupt_leave();
  231. }
  232. /***************************************************************************//**
  233. * @brief
  234. * Common even number GPIO interrupt handler
  235. *
  236. * @details
  237. *
  238. * @note
  239. *
  240. ******************************************************************************/
  241. void GPIO_EVEN_IRQHandler(void)
  242. {
  243. rt_uint16_t flag, n;
  244. rt_base_t level;
  245. /* Disable interrupt */
  246. level = rt_hw_interrupt_disable();
  247. /* Enter ISR */
  248. rt_interrupt_enter();
  249. /* invoke callback function */
  250. flag = (rt_uint16_t)(GPIO->IF & 0xFFFF);
  251. for ( n = 0; flag > 0; flag = flag >> 2, n = n + 2)
  252. {
  253. if ((flag & 0x0001) && (gpioCbTable[n].cbFunc != RT_NULL))
  254. {
  255. (gpioCbTable[n].cbFunc)(gpioCbTable[n].userPtr);
  256. }
  257. }
  258. /* clear interrupt */
  259. GPIO->IFC = 0x5555UL;
  260. /* Leave ISR */
  261. rt_interrupt_leave();
  262. /* Enable interrupt */
  263. rt_hw_interrupt_enable(level);
  264. }
  265. /***************************************************************************//**
  266. * @brief
  267. * Common odd number GPIO interrupt handler
  268. *
  269. * @details
  270. *
  271. * @note
  272. *
  273. ******************************************************************************/
  274. void GPIO_ODD_IRQHandler(void)
  275. {
  276. rt_uint16_t flag, n;
  277. rt_base_t level;
  278. /* Disable interrupt */
  279. level = rt_hw_interrupt_disable();
  280. /* Enter ISR */
  281. rt_interrupt_enter();
  282. /* invoke callback function */
  283. flag = (rt_uint16_t)(GPIO->IF & 0xFFFF) >> 1;
  284. for ( n = 1; flag > 0; flag = flag >> 2, n = n + 2)
  285. {
  286. if ((flag & 0x0001) && (gpioCbTable[n].cbFunc != RT_NULL))
  287. {
  288. (gpioCbTable[n].cbFunc)(gpioCbTable[n].userPtr);
  289. }
  290. }
  291. /* clear interrupt */
  292. GPIO->IFC = 0xAAAAUL;
  293. /* Leave ISR */
  294. rt_interrupt_leave();
  295. /* Enable interrupt */
  296. rt_hw_interrupt_enable(level);
  297. }
  298. /***************************************************************************//**
  299. * @brief
  300. * Common ACMP interrupt handler
  301. *
  302. * @details
  303. * This function handles ACMP edge trigger interrupt request
  304. *
  305. * @note
  306. *
  307. ******************************************************************************/
  308. void ACMP0_IRQHandler(void)
  309. {
  310. /* enter interrupt */
  311. rt_interrupt_enter();
  312. if (ACMP0->IF & ACMP_IF_EDGE)
  313. {
  314. /* invoke callback function */
  315. if (acmpCbTable[0].cbFunc != RT_NULL)
  316. {
  317. (acmpCbTable[0].cbFunc)(acmpCbTable[0].userPtr);
  318. }
  319. /* clear interrupt */
  320. BITBAND_Peripheral(&(ACMP0->IFC), _ACMP_IF_EDGE_SHIFT, 0x1UL);
  321. }
  322. if (ACMP1->IF & ACMP_IF_EDGE)
  323. {
  324. /* invoke callback function */
  325. if (acmpCbTable[1].cbFunc != RT_NULL)
  326. {
  327. (acmpCbTable[1].cbFunc)(acmpCbTable[1].userPtr);
  328. }
  329. /* clear interrupt */
  330. BITBAND_Peripheral(&(ACMP1->IFC), _ACMP_IF_EDGE_SHIFT, 0x1UL);
  331. }
  332. /* leave interrupt */
  333. rt_interrupt_leave();
  334. }
  335. /***************************************************************************//**
  336. * @brief
  337. * Common USART0 TX interrupt handler
  338. *
  339. * @details
  340. * This function handles USART0 TX complete interrupt request
  341. *
  342. * @note
  343. *
  344. ******************************************************************************/
  345. void USART0_TX_IRQHandler(void)
  346. {
  347. /* enter interrupt */
  348. rt_interrupt_enter();
  349. if (USART0->IF & USART_IF_TXC)
  350. {
  351. /* invoke callback function */
  352. if (usartCbTable[0].cbFunc != RT_NULL)
  353. {
  354. (usartCbTable[0].cbFunc)(usartCbTable[0].userPtr);
  355. }
  356. /* clear interrupt */
  357. BITBAND_Peripheral(&(USART0->IFC), _USART_IF_TXC_SHIFT, 0x1UL);
  358. }
  359. /* leave interrupt */
  360. rt_interrupt_leave();
  361. }
  362. /***************************************************************************//**
  363. * @brief
  364. * Common USART0 RX interrupt handler
  365. *
  366. * @details
  367. * This function handles USART0 RX data valid interrupt request
  368. *
  369. * @note
  370. *
  371. ******************************************************************************/
  372. void USART0_RX_IRQHandler(void)
  373. {
  374. if (USART0->IF & USART_IF_RXDATAV)
  375. {
  376. /* invoke callback function */
  377. if (usartCbTable[1].cbFunc != RT_NULL)
  378. {
  379. (usartCbTable[1].cbFunc)(usartCbTable[1].userPtr);
  380. }
  381. }
  382. }
  383. /***************************************************************************//**
  384. * @brief
  385. * Common USART1 TX interrupt handler
  386. *
  387. * @details
  388. * This function handles USART1 TX complete interrupt request
  389. *
  390. * @note
  391. *
  392. ******************************************************************************/
  393. void USART1_TX_IRQHandler(void)
  394. {
  395. /* enter interrupt */
  396. rt_interrupt_enter();
  397. if (USART1->IF & USART_IF_TXC)
  398. {
  399. /* invoke callback function */
  400. if (usartCbTable[2].cbFunc != RT_NULL)
  401. {
  402. (usartCbTable[2].cbFunc)(usartCbTable[2].userPtr);
  403. }
  404. /* clear interrupt */
  405. BITBAND_Peripheral(&(USART1->IFC), _USART_IF_TXC_SHIFT, 0x1UL);
  406. }
  407. /* leave interrupt */
  408. rt_interrupt_leave();
  409. }
  410. /***************************************************************************//**
  411. * @brief
  412. * Common USART1 RX interrupt handler
  413. *
  414. * @details
  415. * This function handles USART1 RX data valid interrupt request
  416. *
  417. * @note
  418. *
  419. ******************************************************************************/
  420. void USART1_RX_IRQHandler(void)
  421. {
  422. if (USART1->IF & USART_IF_RXDATAV)
  423. {
  424. /* invoke callback function */
  425. if (usartCbTable[3].cbFunc != RT_NULL)
  426. {
  427. (usartCbTable[3].cbFunc)(usartCbTable[3].userPtr);
  428. }
  429. }
  430. }
  431. /***************************************************************************//**
  432. * @brief
  433. * Common USART2 TX interrupt handler
  434. *
  435. * @details
  436. * This function handles USART2 TX complete interrupt request
  437. *
  438. * @note
  439. *
  440. ******************************************************************************/
  441. void USART2_TX_IRQHandler(void)
  442. {
  443. /* enter interrupt */
  444. rt_interrupt_enter();
  445. if (USART2->IF & USART_IF_TXC)
  446. {
  447. /* invoke callback function */
  448. if (usartCbTable[4].cbFunc != RT_NULL)
  449. {
  450. (usartCbTable[4].cbFunc)(usartCbTable[4].userPtr);
  451. }
  452. /* clear interrupt */
  453. BITBAND_Peripheral(&(USART2->IFC), _USART_IF_TXC_SHIFT, 0x1UL);
  454. }
  455. /* leave interrupt */
  456. rt_interrupt_leave();
  457. }
  458. /***************************************************************************//**
  459. * @brief
  460. * Common USART2 RX interrupt handler
  461. *
  462. * @details
  463. * This function handles USART2 RX data valid interrupt request
  464. *
  465. * @note
  466. *
  467. ******************************************************************************/
  468. void USART2_RX_IRQHandler(void)
  469. {
  470. if (USART2->IF & USART_IF_RXDATAV)
  471. {
  472. /* invoke callback function */
  473. if (usartCbTable[5].cbFunc != RT_NULL)
  474. {
  475. (usartCbTable[5].cbFunc)(usartCbTable[5].userPtr);
  476. }
  477. }
  478. }
  479. /***************************************************************************//**
  480. * @brief
  481. * Common IIC0 interrupt handler
  482. *
  483. * @details
  484. * This function handles IIC0 slave mode interrupt requests
  485. *
  486. * @note
  487. *
  488. ******************************************************************************/
  489. void I2C0_IRQHandler(void)
  490. {
  491. if ((I2C0->IF & I2C_IF_ADDR) || \
  492. (I2C0->IF & I2C_IF_RXDATAV) || \
  493. (I2C0->IF & I2C_IF_SSTOP))
  494. {
  495. /* invoke callback function */
  496. if (iicCbTable[0].cbFunc != RT_NULL)
  497. {
  498. (iicCbTable[0].cbFunc)(iicCbTable[0].userPtr);
  499. }
  500. }
  501. I2C_IntClear(I2C0, I2C_IFC_ADDR | I2C_IFC_SSTOP);
  502. }
  503. /***************************************************************************//**
  504. * @brief
  505. * EFM32 common interrupt handlers register function
  506. *
  507. * @details
  508. *
  509. * @note
  510. *
  511. ******************************************************************************/
  512. void efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
  513. {
  514. switch (hook->type)
  515. {
  516. case efm32_irq_type_dma:
  517. dmaCbTable[hook->unit].cbFunc = hook->cbFunc;
  518. dmaCbTable[hook->unit].userPtr = hook->userPtr;
  519. break;
  520. case efm32_irq_type_rtc:
  521. rtcCbTable[hook->unit].cbFunc = hook->cbFunc;
  522. rtcCbTable[hook->unit].userPtr = hook->userPtr;
  523. break;
  524. case efm32_irq_type_timer:
  525. timerCbTable[hook->unit].cbFunc = hook->cbFunc;
  526. timerCbTable[hook->unit].userPtr = hook->userPtr;
  527. break;
  528. case efm32_irq_type_gpio:
  529. gpioCbTable[hook->unit].cbFunc = hook->cbFunc;
  530. gpioCbTable[hook->unit].userPtr = hook->userPtr;
  531. break;
  532. case efm32_irq_type_acmp:
  533. acmpCbTable[hook->unit].cbFunc = hook->cbFunc;
  534. acmpCbTable[hook->unit].userPtr = hook->userPtr;
  535. break;
  536. case efm32_irq_type_usart:
  537. usartCbTable[hook->unit].cbFunc = hook->cbFunc;
  538. usartCbTable[hook->unit].userPtr = hook->userPtr;
  539. break;
  540. case efm32_irq_type_iic:
  541. iicCbTable[hook->unit].cbFunc = hook->cbFunc;
  542. iicCbTable[hook->unit].userPtr = hook->userPtr;
  543. break;
  544. default:
  545. break;
  546. }
  547. hdl_debug("Hook Registered: type: %s, unit: %x, cbFunc: %x, userPtr: %x\n", \
  548. hook->type, hook->unit, hook->cbFunc, hook->userPtr);
  549. }
  550. /***************************************************************************//**
  551. * @}
  552. ******************************************************************************/