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  * 2012-02-21   onelife     Initial creation for EFM32
9  */
10 
11 /***************************************************************************//**
12  * @addtogroup efm32
13  * @{
14  ******************************************************************************/
15 
16 /* Includes ------------------------------------------------------------------*/
17 #include "board.h"
18 #include "drv_emu.h"
19 
20 /* Private typedef -----------------------------------------------------------*/
21 /* Private define ------------------------------------------------------------*/
22 /* Private macro -------------------------------------------------------------*/
23 #ifdef EFM32_EMU_DEBUG
24 #define emu_debug(format,args...)           rt_kprintf(format, ##args)
25 #else
26 #define emu_debug(format,args...)
27 #endif
28 
29 /* Private variables ---------------------------------------------------------*/
30 struct efm32_emu_task   emu_task;
31 
32 /***************************************************************************//**
33 * @brief
34 *   Register SPI device
35 *
36 * @details
37 *
38 * @note
39 *
40 * @param[in] device
41 *   Pointer to device descriptor
42 *
43 * @param[in] name
44 *   Device name
45 *
46 * @param[in] flag
47 *   Configuration flags
48 *
49 * @param[in] spi
50 *   Pointer to SPI device descriptor
51 *
52 * @return
53 *   Error code
54 ******************************************************************************/
emu_task_main_loop(void * parameter)55 void emu_task_main_loop(void *parameter)
56 {
57     struct efm32_emu_task *emu_task = (struct efm32_emu_task *)parameter;
58 
59     while(1)
60     {
61         if (emu_task->em2.value == EMU_TASK_EM2_TOKEN_NUMBER)
62         {
63             if (emu_task->em3.value == EMU_TASK_EM3_TOKEN_NUMBER)
64             {
65                 if (emu_task->em4.value == EMU_TASK_EM4_TOKEN_NUMBER)
66                 {
67                     EMU_EnterEM4();
68                 }
69                 else
70                 {
71                     EMU_EnterEM3(RT_TRUE);
72                 }
73             }
74             else
75             {
76                 EMU_EnterEM2(RT_TRUE);
77             }
78         }
79         else
80         {
81             EMU_EnterEM1();
82         }
83     }
84 }
85 
86 #define OS_TIMER_LIST_EMPTY     (0x00000001)
87 #define OS_TIMER_LIST_NOT_EMPTY (0x00000002)
88 
emu_event_send(rt_uint32_t event)89 void emu_event_send(rt_uint32_t event)
90 {
91     switch (event)
92     {
93     case OS_TIMER_LIST_EMPTY:
94 //        SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk;
95         break;
96     case OS_TIMER_LIST_NOT_EMPTY:
97 //        SysTick->CTRL |= SysTick_CTRL_CLKSOURCE_Msk;
98         break;
99     }
100 }
101 
emu_is_emu(struct rt_thread * thread)102 rt_bool_t emu_is_emu(struct rt_thread *thread)
103 {
104     return (thread == &emu_task.thread);
105 }
106 
emu_all_disable(void)107 void emu_all_disable(void)
108 {
109     if (rt_sem_take(&emu_task.em4, RT_WAITING_NO) != RT_EOK)
110     {
111         RT_ASSERT(0);
112     }
113     if (rt_sem_take(&emu_task.em3, RT_WAITING_NO) != RT_EOK)
114     {
115         RT_ASSERT(0);
116     }
117     if (rt_sem_take(&emu_task.em2, RT_WAITING_NO) != RT_EOK)
118     {
119         RT_ASSERT(0);
120     }
121 }
122 
emu_em2_disable(void)123 void emu_em2_disable(void)
124 {
125     if (rt_sem_take(&emu_task.em2, RT_WAITING_NO) != RT_EOK)
126     {
127         RT_ASSERT(0);
128     }
129 }
130 
emu_em2_enable(void)131 void emu_em2_enable(void)
132 {
133     if (rt_sem_release(&emu_task.em2) != RT_EOK)
134     {
135         RT_ASSERT(0);
136     }
137 }
138 
emu_em3_disable(void)139 void emu_em3_disable(void)
140 {
141     if (rt_sem_take(&emu_task.em3, RT_WAITING_NO) != RT_EOK)
142     {
143         RT_ASSERT(0);
144     }
145 }
146 
emu_em3_enable(void)147 void emu_em3_enable(void)
148 {
149     if (rt_sem_release(&emu_task.em3) != RT_EOK)
150     {
151         RT_ASSERT(0);
152     }
153 }
154 
emu_em4_disable(void)155 void emu_em4_disable(void)
156 {
157     if (rt_sem_take(&emu_task.em4, RT_WAITING_NO) != RT_EOK)
158     {
159         RT_ASSERT(0);
160     }
161 }
162 
emu_em4_enable(void)163 void emu_em4_enable(void)
164 {
165     if (rt_sem_release(&emu_task.em4) != RT_EOK)
166     {
167         RT_ASSERT(0);
168     }
169 }
170 
171 /***************************************************************************//**
172  * @brief
173  *  Initialize EMU module related hardware
174  *
175  * @details
176  *
177  * @note
178  *
179  ******************************************************************************/
efm32_emu_init(void)180 void efm32_emu_init(void)
181 {
182     do
183     {
184         /* init token */
185         if (rt_sem_init(
186             &emu_task.em2,
187             "EM2",
188             EMU_TASK_EM2_TOKEN_NUMBER,
189             RT_IPC_FLAG_FIFO) != RT_EOK)
190         {
191             break;
192         }
193         if (rt_sem_init(
194             &emu_task.em3,
195             "EM3",
196             EMU_TASK_EM3_TOKEN_NUMBER,
197             RT_IPC_FLAG_FIFO) != RT_EOK)
198         {
199             break;
200         }
201         if (rt_sem_init(
202             &emu_task.em4,
203             "EM4",
204             EMU_TASK_EM4_TOKEN_NUMBER,
205             RT_IPC_FLAG_FIFO) != RT_EOK)
206         {
207             break;
208         }
209 
210         /* init thread */
211         if (rt_thread_init(
212             &emu_task.thread,
213             "EMU",
214             emu_task_main_loop, (void *)&emu_task,
215             (void *)&emu_task.stack, sizeof(emu_task.stack),
216             RT_THREAD_PRIORITY_MAX - 2, RT_TICK_PER_SECOND) != RT_EOK)
217         {
218             break;
219         }
220 
221         /* startup */
222         if (rt_thread_startup(&emu_task.thread) != RT_EOK)
223         {
224             break;
225         }
226     } while (0);
227 
228     rt_kprintf("EMU err: init failed!\n");
229 }
230 
231 /*******************************************************************************
232  *  Export to FINSH
233  ******************************************************************************/
234 #ifdef RT_USING_FINSH
235 #include <finsh.h>
236 
list_emu(void)237 void list_emu(void)
238 {
239     rt_kprintf(" --------- EMU Status ---------\n");
240     rt_kprintf(" em2 token used %d\n",
241         EMU_TASK_EM2_TOKEN_NUMBER - emu_task.em2.value);
242     rt_kprintf(" em3 token used %d\n",
243         EMU_TASK_EM3_TOKEN_NUMBER - emu_task.em3.value);
244     rt_kprintf(" em4 token used %d\n",
245         EMU_TASK_EM4_TOKEN_NUMBER - emu_task.em4.value);
246 }
247 FINSH_FUNCTION_EXPORT(list_emu, list the EMU status)
248 #endif
249 
250 /***************************************************************************//**
251  * @}
252  ******************************************************************************/
253