1 /*
2  * Copyright (c) 2006-2022, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date         Author      Notes
8  * 2010-12-29   onelife     Initial creation for EFM32
9  * 2011-07-12   onelife     Disable interrupts in GPIO handler
10  * 2011-12-09   onelife     Add giant gecko support
11  * 2011-12-09   onelife     Add UART module support
12  * 2011-12-09   onelife     Add LEUART module support
13  * 2011-12-27   onelife     Utilize "XXX_PRESENT" and "XXX_COUNT"
14  */
15 
16 /* Includes ------------------------------------------------------------------*/
17 #include "board.h"
18 #include "hdl_interrupt.h"
19 
20 /***************************************************************************//**
21  * @addtogroup efm32
22  * @{
23  ******************************************************************************/
24 
25 /* Private typedef -----------------------------------------------------------*/
26 /* Private define ------------------------------------------------------------*/
27 /* Private macro -------------------------------------------------------------*/
28 #ifdef RT_IRQHDL_DEBUG
29 #define hdl_debug(format,args...)           rt_kprintf(format, ##args)
30 #else
31 #define hdl_debug(format,args...)
32 #endif
33 
34 /* Private variables ---------------------------------------------------------*/
35 efm32_irq_hook_t dmaCbTable[DMA_CHAN_COUNT * 2] = {RT_NULL};
36 efm32_irq_hook_t timerCbTable[TIMER_COUNT]      = {RT_NULL};
37 #if defined(LETIMER_PRESENT)
38 efm32_irq_hook_t letimerCbTable[LETIMER_COUNT]  = {RT_NULL};
39 #endif
40 efm32_irq_hook_t rtcCbTable[RTC_COUNT]          = {RT_NULL};
41 efm32_irq_hook_t gpioCbTable[16]                = {RT_NULL};
42 efm32_irq_hook_t acmpCbTable[ACMP_COUNT]        = {RT_NULL};
43 #if defined(USART_PRESENT)
44  #if defined(UART_PRESENT)
45 efm32_irq_hook_t usartCbTable[USART_COUNT * 2 + UART_COUNT * 2] = {RT_NULL};
46  #else
47 efm32_irq_hook_t usartCbTable[USART_COUNT * 2]  = {RT_NULL};
48  #endif
49 #endif
50 #if defined(LEUART_PRESENT)
51 efm32_irq_hook_t leuartCbTable[LEUART_COUNT]    = {RT_NULL};
52 #endif
53 #if defined(I2C_PRESENT)
54 efm32_irq_hook_t iicCbTable[I2C_COUNT]          = {RT_NULL};
55 #endif
56 
57 /* Private function prototypes -----------------------------------------------*/
58 /* Private functions ---------------------------------------------------------*/
59 
60 /***************************************************************************//**
61  * @brief
62  *  NMI exception handler
63  *
64  * @details
65  *
66  * @note
67  ******************************************************************************/
NMI_Handler(void)68 void NMI_Handler(void)
69 {
70     hdl_debug("[NMI_Handler: NOP]\n");
71 }
72 
73 /***************************************************************************//**
74  * @brief
75  *  Memory manage exception handler
76  *
77  * @details
78  *
79  * @note
80  ******************************************************************************/
MemManage_Handler(void)81 void MemManage_Handler(void)
82 {
83     hdl_debug("[MemManage_Handler: infinite loop]\n");
84     while (1);
85 }
86 
87 /***************************************************************************//**
88  * @brief
89  *  Bus fault exception handler
90  *
91  * @details
92  *
93  * @note
94  ******************************************************************************/
BusFault_Handler(void)95 void BusFault_Handler(void)
96 {
97     hdl_debug("[BusFault_Handler: infinite loop]\n");
98     while (1);
99 }
100 
101 /***************************************************************************//**
102  * @brief
103  *  Usage fault exception handler
104  *
105  * @details
106  *
107  * @note
108  ******************************************************************************/
UsageFault_Handler(void)109 void UsageFault_Handler(void)
110 {
111     hdl_debug("[UsageFault_Handler: infinite loop]\n");
112     while (1);
113 }
114 
115 /***************************************************************************//**
116  * @brief
117  *  Supervisor call exception handler
118  *
119  * @details
120  *
121  * @note
122  ******************************************************************************/
SVC_Handler(void)123 void SVC_Handler(void)
124 {
125     hdl_debug("[SVC_Handler: NOP]\n");
126 }
127 
128 /***************************************************************************//**
129  * @brief
130  *   Debug monitor exception handler
131  *
132  * @details
133  *
134  * @note
135  ******************************************************************************/
DebugMon_Handler(void)136 void DebugMon_Handler(void)
137 {
138     hdl_debug("[DebugMon_Handler: NOP]\n");
139 }
140 
141 /***************************************************************************//**
142  * @brief
143  *  System tick timer interrupt handler
144  *
145  * @details
146  *
147  * @note
148  *
149  ******************************************************************************/
SysTick_Handler(void)150 void SysTick_Handler(void)
151 {
152     /* enter interrupt */
153     rt_interrupt_enter();
154 
155     rt_tick_increase();
156 
157     /* leave interrupt */
158     rt_interrupt_leave();
159 }
160 
161 /*******************************************************************************
162  *                 STM32F10x Peripherals Interrupt Handlers
163  *  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the
164  *  available peripheral interrupt handler's name please refer to the startup
165  *  file (startup_stm32f10x_xx.s).
166 /******************************************************************************/
167 
168 /***************************************************************************//**
169  * @brief
170  *  Common DMA interrupt handler
171  *
172  * @details
173  *
174  * @note
175  *
176  ******************************************************************************/
DMA_IRQHandler_All(rt_uint32_t channel,rt_bool_t primary,void * user)177 void DMA_IRQHandler_All(rt_uint32_t channel, rt_bool_t primary, void *user)
178 {
179     /* enter interrupt */
180     rt_interrupt_enter();
181 
182     /* invoke callback function */
183     if (dmaCbTable[channel].cbFunc != RT_NULL)
184     {
185         (dmaCbTable[channel].cbFunc)(dmaCbTable[channel].userPtr);
186     }
187 
188     /* leave interrupt */
189     rt_interrupt_leave();
190 }
191 
192 /***************************************************************************//**
193  * @brief
194  *  Common Timer0 interrupt handler
195  *
196  * @details
197  *  This function handles Timer0 counter overflow interrupt request
198  *
199  * @note
200  *
201  ******************************************************************************/
TIMER0_IRQHandler(void)202 void TIMER0_IRQHandler(void)
203 {
204     if (TIMER0->IF & TIMER_IF_OF)
205     {
206         /* invoke callback function */
207         if (timerCbTable[0].cbFunc != RT_NULL)
208         {
209             (timerCbTable[0].cbFunc)(timerCbTable[0].userPtr);
210         }
211 
212         /* clear interrupt */
213         BITBAND_Peripheral(&(TIMER0->IFC), _TIMER_IF_OF_SHIFT, 0x1UL);
214     }
215 }
216 
217 
218 /***************************************************************************//**
219  * @brief
220  *  Common Timer1 interrupt handler
221  *
222  * @details
223  *  This function handles Timer1 counter overflow interrupt request
224  *
225  * @note
226  *
227  ******************************************************************************/
TIMER1_IRQHandler(void)228 void TIMER1_IRQHandler(void)
229 {
230     if (TIMER1->IF & TIMER_IF_OF)
231     {
232         /* invoke callback function */
233         if (timerCbTable[1].cbFunc != RT_NULL)
234         {
235             (timerCbTable[1].cbFunc)(timerCbTable[1].userPtr);
236         }
237 
238         /* clear interrupt */
239         BITBAND_Peripheral(&(TIMER1->IFC), _TIMER_IF_OF_SHIFT, 0x1UL);
240     }
241 }
242 
243 /***************************************************************************//**
244  * @brief
245  *  Common Timer2 interrupt handler
246  *
247  * @details
248  *  This function handles Timer2 counter overflow interrupt request
249  *
250  * @note
251  *
252  ******************************************************************************/
TIMER2_IRQHandler(void)253 void TIMER2_IRQHandler(void)
254 {
255     if (TIMER2->IF & TIMER_IF_OF)
256     {
257         /* invoke callback function */
258         if (timerCbTable[2].cbFunc != RT_NULL)
259         {
260             (timerCbTable[2].cbFunc)(timerCbTable[2].userPtr);
261         }
262 
263         /* clear interrupt */
264         BITBAND_Peripheral(&(TIMER2->IFC), _TIMER_IF_OF_SHIFT, 0x1UL);
265     }
266 }
267 
268 #if defined(LETIMER_PRESENT)
269 /***************************************************************************//**
270  * @brief
271  *  Common Low Energy Timer0 interrupt handler
272  *
273  * @details
274  *  This function handles Timer0 counter overflow interrupt request
275  *
276  * @note
277  *
278  ******************************************************************************/
LETIMER0_IRQHandler(void)279 void LETIMER0_IRQHandler(void)
280 {
281     if (LETIMER0->IF & LETIMER_IF_UF)
282     {
283         /* enter interrupt */
284         rt_interrupt_enter();
285 
286         rt_tick_increase();
287 
288         /* leave interrupt */
289         rt_interrupt_leave();
290 
291         /* invoke callback function */
292 /*      if (letimerCbTable[0].cbFunc != RT_NULL)
293         {
294             (letimerCbTable[0].cbFunc)(letimerCbTable[0].userPtr);
295         }
296 */
297         /* clear interrupt */
298         BITBAND_Peripheral(&(LETIMER0->IFC), _LETIMER_IF_UF_SHIFT, 0x1UL);
299     }
300 }
301 #endif
302 
303 /***************************************************************************//**
304  * @brief
305  *  Common RTC interrupt handler
306  *
307  * @details
308  *  This function handles RTC counter overflow interrupt request
309  *
310  * @note
311  *
312  ******************************************************************************/
RTC_IRQHandler(void)313 void RTC_IRQHandler(void)
314 {
315     /* enter interrupt */
316     rt_interrupt_enter();
317 
318     if (RTC->IF & RTC_IF_OF)
319     {
320         /* invoke callback function */
321         if (rtcCbTable[0].cbFunc != RT_NULL)
322         {
323             (rtcCbTable[0].cbFunc)(rtcCbTable[0].userPtr);
324         }
325     }
326 
327     /* leave interrupt */
328     rt_interrupt_leave();
329 }
330 
331 /***************************************************************************//**
332  * @brief
333  *  Common even number GPIO interrupt handler
334  *
335  * @details
336  *
337  * @note
338  *
339  ******************************************************************************/
GPIO_EVEN_IRQHandler(void)340 void GPIO_EVEN_IRQHandler(void)
341 {
342     rt_uint16_t flag, n;
343     rt_base_t level;
344 
345     /* Disable interrupt */
346     level = rt_hw_interrupt_disable();
347     /* Enter ISR */
348     rt_interrupt_enter();
349 
350      /* invoke callback function */
351     flag = (rt_uint16_t)(GPIO->IF & 0xFFFF);
352     for ( n = 0; flag > 0; flag = flag >> 2, n = n + 2)
353     {
354         if ((flag & 0x0001) && (gpioCbTable[n].cbFunc != RT_NULL))
355         {
356             (gpioCbTable[n].cbFunc)(gpioCbTable[n].userPtr);
357         }
358     }
359 
360     /* clear interrupt */
361     GPIO->IFC = 0x5555UL;
362 
363     /* Leave ISR */
364     rt_interrupt_leave();
365     /* Enable interrupt */
366     rt_hw_interrupt_enable(level);
367 }
368 
369 /***************************************************************************//**
370  * @brief
371  *  Common odd number GPIO interrupt handler
372  *
373  * @details
374  *
375  * @note
376  *
377  ******************************************************************************/
GPIO_ODD_IRQHandler(void)378 void GPIO_ODD_IRQHandler(void)
379 {
380     rt_uint16_t flag, n;
381     rt_base_t level;
382 
383     /* Disable interrupt */
384     level = rt_hw_interrupt_disable();
385     /* Enter ISR */
386     rt_interrupt_enter();
387 
388      /* invoke callback function */
389     flag = (rt_uint16_t)(GPIO->IF & 0xFFFF) >> 1;
390     for ( n = 1; flag > 0; flag = flag >> 2, n = n + 2)
391     {
392         if ((flag & 0x0001) && (gpioCbTable[n].cbFunc != RT_NULL))
393         {
394             (gpioCbTable[n].cbFunc)(gpioCbTable[n].userPtr);
395         }
396     }
397 
398     /* clear interrupt */
399     GPIO->IFC = 0xAAAAUL;
400 
401     /* Leave ISR */
402     rt_interrupt_leave();
403     /* Enable interrupt */
404     rt_hw_interrupt_enable(level);
405 }
406 
407 /***************************************************************************//**
408  * @brief
409  *  Common ACMP interrupt handler
410  *
411  * @details
412  *  This function handles ACMP edge trigger interrupt request
413  *
414  * @note
415  *
416  ******************************************************************************/
ACMP0_IRQHandler(void)417 void ACMP0_IRQHandler(void)
418 {
419     /* enter interrupt */
420     rt_interrupt_enter();
421 
422     if (ACMP0->IF & ACMP_IF_EDGE)
423     {
424         /* invoke callback function */
425         if (acmpCbTable[0].cbFunc != RT_NULL)
426         {
427             (acmpCbTable[0].cbFunc)(acmpCbTable[0].userPtr);
428         }
429 
430         /* clear interrupt */
431         BITBAND_Peripheral(&(ACMP0->IFC), _ACMP_IF_EDGE_SHIFT, 0x1UL);
432     }
433 
434     if (ACMP1->IF & ACMP_IF_EDGE)
435     {
436         /* invoke callback function */
437         if (acmpCbTable[1].cbFunc != RT_NULL)
438         {
439             (acmpCbTable[1].cbFunc)(acmpCbTable[1].userPtr);
440         }
441 
442         /* clear interrupt */
443         BITBAND_Peripheral(&(ACMP1->IFC), _ACMP_IF_EDGE_SHIFT, 0x1UL);
444     }
445 
446     /* leave interrupt */
447     rt_interrupt_leave();
448 }
449 
450 #if defined(USART_PRESENT)
451 /***************************************************************************//**
452  * @brief
453  *  Common USART0 TX interrupt handler
454  *
455  * @details
456  *  This function handles USART0 TX complete interrupt request
457  *
458  * @note
459  *
460  ******************************************************************************/
USART0_TX_IRQHandler(void)461 void USART0_TX_IRQHandler(void)
462 {
463     /* enter interrupt */
464     rt_interrupt_enter();
465 
466     if (USART0->IF & USART_IF_TXC)
467     {
468         /* invoke callback function */
469         if (usartCbTable[0].cbFunc != RT_NULL)
470         {
471             (usartCbTable[0].cbFunc)(usartCbTable[0].userPtr);
472         }
473 
474         /* clear interrupt */
475         BITBAND_Peripheral(&(USART0->IFC), _USART_IF_TXC_SHIFT, 0x1UL);
476     }
477 
478     /* leave interrupt */
479     rt_interrupt_leave();
480 }
481 
482 /***************************************************************************//**
483  * @brief
484  *  Common USART0 RX interrupt handler
485  *
486  * @details
487  *  This function handles USART0 RX data valid interrupt request
488  *
489  * @note
490  *
491  ******************************************************************************/
USART0_RX_IRQHandler(void)492 void USART0_RX_IRQHandler(void)
493 {
494     if (USART0->IF & USART_IF_RXDATAV)
495     {
496         /* invoke callback function */
497         if (usartCbTable[1].cbFunc != RT_NULL)
498         {
499             (usartCbTable[1].cbFunc)(usartCbTable[1].userPtr);
500         }
501     }
502 }
503 #endif
504 
505 #if (defined(USART_PRESENT) && (USART_COUNT > 1))
506 /***************************************************************************//**
507  * @brief
508  *  Common USART1 TX interrupt handler
509  *
510  * @details
511  *  This function handles USART1 TX complete interrupt request
512  *
513  * @note
514  *
515  ******************************************************************************/
USART1_TX_IRQHandler(void)516 void USART1_TX_IRQHandler(void)
517 {
518     /* enter interrupt */
519     rt_interrupt_enter();
520 
521     if (USART1->IF & USART_IF_TXC)
522     {
523         /* invoke callback function */
524         if (usartCbTable[2].cbFunc != RT_NULL)
525         {
526             (usartCbTable[2].cbFunc)(usartCbTable[2].userPtr);
527         }
528 
529         /* clear interrupt */
530         BITBAND_Peripheral(&(USART1->IFC), _USART_IF_TXC_SHIFT, 0x1UL);
531     }
532 
533     /* leave interrupt */
534     rt_interrupt_leave();
535 }
536 
537 /***************************************************************************//**
538  * @brief
539  *  Common USART1 RX interrupt handler
540  *
541  * @details
542  *  This function handles USART1 RX data valid interrupt request
543  *
544  * @note
545  *
546  ******************************************************************************/
USART1_RX_IRQHandler(void)547 void USART1_RX_IRQHandler(void)
548 {
549     if (USART1->IF & USART_IF_RXDATAV)
550     {
551         /* invoke callback function */
552         if (usartCbTable[3].cbFunc != RT_NULL)
553         {
554             (usartCbTable[3].cbFunc)(usartCbTable[3].userPtr);
555         }
556     }
557 }
558 #endif
559 
560 #if (defined(USART_PRESENT) && (USART_COUNT > 2))
561 /***************************************************************************//**
562  * @brief
563  *  Common USART2 TX interrupt handler
564  *
565  * @details
566  *  This function handles USART2 TX complete interrupt request
567  *
568  * @note
569  *
570  ******************************************************************************/
USART2_TX_IRQHandler(void)571 void USART2_TX_IRQHandler(void)
572 {
573     /* enter interrupt */
574     rt_interrupt_enter();
575 
576     if (USART2->IF & USART_IF_TXC)
577     {
578         /* invoke callback function */
579         if (usartCbTable[4].cbFunc != RT_NULL)
580         {
581             (usartCbTable[4].cbFunc)(usartCbTable[4].userPtr);
582         }
583 
584         /* clear interrupt */
585         BITBAND_Peripheral(&(USART2->IFC), _USART_IF_TXC_SHIFT, 0x1UL);
586     }
587 
588     /* leave interrupt */
589     rt_interrupt_leave();
590 }
591 
592 /***************************************************************************//**
593  * @brief
594  *  Common USART2 RX interrupt handler
595  *
596  * @details
597  *  This function handles USART2 RX data valid interrupt request
598  *
599  * @note
600  *
601  ******************************************************************************/
USART2_RX_IRQHandler(void)602 void USART2_RX_IRQHandler(void)
603 {
604     if (USART2->IF & USART_IF_RXDATAV)
605     {
606         /* invoke callback function */
607         if (usartCbTable[5].cbFunc != RT_NULL)
608         {
609             (usartCbTable[5].cbFunc)(usartCbTable[5].userPtr);
610         }
611     }
612 }
613 #endif
614 
615 #if defined(UART_PRESENT)
616 /***************************************************************************//**
617  * @brief
618  *  Common UART0 TX interrupt handler
619  *
620  * @details
621  *  This function handles UART0 TX complete interrupt request
622  *
623  * @note
624  *
625  ******************************************************************************/
UART0_TX_IRQHandler(void)626 void UART0_TX_IRQHandler(void)
627 {
628     /* enter interrupt */
629     rt_interrupt_enter();
630 
631     if (UART0->IF & UART_IF_TXC)
632     {
633         /* invoke callback function */
634         if (usartCbTable[USART_COUNT * 2].cbFunc != RT_NULL)
635         {
636             (usartCbTable[USART_COUNT * 2].cbFunc)(usartCbTable[USART_COUNT * 2].userPtr);
637         }
638 
639         /* clear interrupt */
640         BITBAND_Peripheral(&(UART0->IFC), _UART_IF_TXC_SHIFT, 0x1UL);
641     }
642 
643     /* leave interrupt */
644     rt_interrupt_leave();
645 }
646 
647 /***************************************************************************//**
648  * @brief
649  *  Common UART0 RX interrupt handler
650  *
651  * @details
652  *  This function handles UART0 RX data valid interrupt request
653  *
654  * @note
655  *
656  ******************************************************************************/
UART0_RX_IRQHandler(void)657 void UART0_RX_IRQHandler(void)
658 {
659     if (UART0->IF & UART_IF_RXDATAV)
660     {
661         /* invoke callback function */
662         if (usartCbTable[USART_COUNT * 2 + 1].cbFunc != RT_NULL)
663         {
664             (usartCbTable[USART_COUNT * 2 + 1].cbFunc)(usartCbTable[USART_COUNT * 2 + 1].userPtr);
665         }
666     }
667 }
668 #endif
669 
670 #if (defined(UART_PRESENT) && (UART_COUNT > 1))
671 /***************************************************************************//**
672  * @brief
673  *  Common UART1 TX interrupt handler
674  *
675  * @details
676  *  This function handles UART1 TX complete interrupt request
677  *
678  * @note
679  *
680  ******************************************************************************/
UART1_TX_IRQHandler(void)681 void UART1_TX_IRQHandler(void)
682 {
683     /* enter interrupt */
684     rt_interrupt_enter();
685 
686     if (UART1->IF & UART_IF_TXC)
687     {
688         /* invoke callback function */
689         if (usartCbTable[USART_COUNT * 2 + 2].cbFunc != RT_NULL)
690         {
691             (usartCbTable[USART_COUNT * 2 + 2].cbFunc)(usartCbTable[USART_COUNT * 2 + 2].userPtr);
692         }
693 
694         /* clear interrupt */
695         BITBAND_Peripheral(&(UART1->IFC), _UART_IF_TXC_SHIFT, 0x1UL);
696     }
697 
698     /* leave interrupt */
699     rt_interrupt_leave();
700 }
701 
702 /***************************************************************************//**
703  * @brief
704  *  Common UART1 RX interrupt handler
705  *
706  * @details
707  *  This function handles UART1 RX data valid interrupt request
708  *
709  * @note
710  *
711  ******************************************************************************/
UART1_RX_IRQHandler(void)712 void UART1_RX_IRQHandler(void)
713 {
714     if (UART1->IF & UART_IF_RXDATAV)
715     {
716         /* invoke callback function */
717         if (usartCbTable[USART_COUNT * 2 + 3].cbFunc != RT_NULL)
718         {
719             (usartCbTable[USART_COUNT * 2 + 3].cbFunc)(usartCbTable[USART_COUNT * 2 + 3].userPtr);
720         }
721     }
722 }
723 #endif
724 
725 #if defined(LEUART_PRESENT)
726 /***************************************************************************//**
727  * @brief
728  *  Common LEUART0 interrupt handler
729  *
730  * @details
731  *  This function handles LEUART0 interrupt request
732  *
733  * @note
734  *
735  ******************************************************************************/
LEUART0_IRQHandler(void)736 void LEUART0_IRQHandler(void)
737 {
738     if (LEUART0->IF & LEUART_IF_RXDATAV)
739     {
740         /* invoke callback function */
741         if (leuartCbTable[0].cbFunc != RT_NULL)
742         {
743             (leuartCbTable[0].cbFunc)(leuartCbTable[0].userPtr);
744         }
745     }
746 }
747 #endif
748 
749 #if (defined(LEUART_PRESENT) && (LEUART_COUNT > 1))
750 /***************************************************************************//**
751  * @brief
752  *  Common LEUART1 interrupt handler
753  *
754  * @details
755  *  This function handles LEUART1 interrupt request
756  *
757  * @note
758  *
759  ******************************************************************************/
LEUART1_IRQHandler(void)760 void LEUART1_IRQHandler(void)
761 {
762     if (LEUART1->IF & LEUART_IF_RXDATAV)
763     {
764         /* invoke callback function */
765         if (leuartCbTable[1].cbFunc != RT_NULL)
766         {
767             (leuartCbTable[1].cbFunc)(leuartCbTable[1].userPtr);
768         }
769     }
770 }
771 #endif
772 
773 #if defined(I2C_PRESENT)
774 /***************************************************************************//**
775  * @brief
776  *  Common IIC0 interrupt handler
777  *
778  * @details
779  *  This function handles IIC0 slave mode interrupt requests
780  *
781  * @note
782  *
783  ******************************************************************************/
I2C0_IRQHandler(void)784 void I2C0_IRQHandler(void)
785 {
786     if ((I2C0->IF & I2C_IF_ADDR) || \
787         (I2C0->IF & I2C_IF_RXDATAV) || \
788         (I2C0->IF & I2C_IF_SSTOP))
789     {
790         /* invoke callback function */
791         if (iicCbTable[0].cbFunc != RT_NULL)
792         {
793             (iicCbTable[0].cbFunc)(iicCbTable[0].userPtr);
794         }
795     }
796 
797     I2C_IntClear(I2C0, I2C_IFC_ADDR | I2C_IFC_SSTOP);
798 }
799 #endif
800 
801 /***************************************************************************//**
802  * @brief
803  *  EFM32 common interrupt handlers register function
804  *
805  * @details
806  *
807  * @note
808  *
809  ******************************************************************************/
efm32_irq_hook_register(efm32_irq_hook_init_t * hook)810 void efm32_irq_hook_register(efm32_irq_hook_init_t *hook)
811 {
812     switch (hook->type)
813     {
814     case efm32_irq_type_dma:
815         dmaCbTable[hook->unit].cbFunc = hook->cbFunc;
816         dmaCbTable[hook->unit].userPtr = hook->userPtr;
817         break;
818 
819     case efm32_irq_type_rtc:
820         rtcCbTable[hook->unit].cbFunc = hook->cbFunc;
821         rtcCbTable[hook->unit].userPtr = hook->userPtr;
822         break;
823 
824     case efm32_irq_type_timer:
825         timerCbTable[hook->unit].cbFunc = hook->cbFunc;
826         timerCbTable[hook->unit].userPtr = hook->userPtr;
827         break;
828 
829     case efm32_irq_type_letimer:
830         letimerCbTable[hook->unit].cbFunc = hook->cbFunc;
831         letimerCbTable[hook->unit].userPtr = hook->userPtr;
832         break;
833 
834     case efm32_irq_type_gpio:
835         gpioCbTable[hook->unit].cbFunc = hook->cbFunc;
836         gpioCbTable[hook->unit].userPtr = hook->userPtr;
837         break;
838 
839     case efm32_irq_type_acmp:
840         acmpCbTable[hook->unit].cbFunc = hook->cbFunc;
841         acmpCbTable[hook->unit].userPtr = hook->userPtr;
842         break;
843 #if defined(USART_PRESENT)
844     case efm32_irq_type_usart:
845         usartCbTable[hook->unit].cbFunc = hook->cbFunc;
846         usartCbTable[hook->unit].userPtr = hook->userPtr;
847         break;
848 #endif
849 #if defined(LEUART_PRESENT)
850     case efm32_irq_type_leuart:
851         leuartCbTable[hook->unit].cbFunc = hook->cbFunc;
852         leuartCbTable[hook->unit].userPtr = hook->userPtr;
853         break;
854 #endif
855 #if defined(I2C_PRESENT)
856     case efm32_irq_type_iic:
857         iicCbTable[hook->unit].cbFunc = hook->cbFunc;
858         iicCbTable[hook->unit].userPtr = hook->userPtr;
859         break;
860 #endif
861     default:
862         break;
863     }
864 
865     hdl_debug("Hook Registered: type: %s, unit: %x, cbFunc: %x, userPtr: %x\n", \
866         hook->type, hook->unit, hook->cbFunc, hook->userPtr);
867 }
868 
869 /***************************************************************************//**
870  * @}
871  ******************************************************************************/
872