hdl_interrupt.c 15 KB

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