hdl_interrupt.c 15 KB

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