1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS
3 File: os_timer.c
4
5 Copyright 2003-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Date:: 2008-09-17#$
14 $Rev: 8556 $
15 $Author: okubata_ryoma $
16
17 *---------------------------------------------------------------------------*/
18 #include <nitro/os.h>
19
20
21 //----------------------------------------------------------------------
22 #define OSi_TM_E_MASK REG_OS_TM0CNT_H_E_MASK
23 #define OSi_TM_I_MASK REG_OS_TM0CNT_H_I_MASK
24 #define OSi_TM_CH_MASK REG_OS_TM1CNT_H_CH_MASK
25
26 #define OSi_TIMER_MASK(preScale) ((u16)(OSi_TM_E_MASK | OSi_TM_I_MASK | (preScale)))
27 #define OSi_CASCADE_MASK ((u16)(OSi_TM_E_MASK | OSi_TM_I_MASK | OSi_TM_CH_MASK))
28
29 //---- if OS reserved each timer, bit=1 (LSB is TIMER0)
30 static u16 OSi_TimerReserved = 0;
31
32 u16 OSi_IsTimerReserved(int timerNum);
33 void OSi_SetTimerReserved(int timerNum);
34 void OSi_UnsetTimerReserved(int timerNum);
35
36 static void OS_StopTimerAndUnsetHandler(OSTimer id);
37 static void OSi_TimerIntr0(void);
38 static void OSi_TimerIntr1(void);
39 static void OSi_TimerIntr2(void);
40
41 static void (*OSi_IntrTable[])(void) = { OSi_TimerIntr0, OSi_TimerIntr1, OSi_TimerIntr2 };
42 static OSIrqMask OSi_MaskTable[] = { OS_IE_TIMER0, OS_IE_TIMER1, OS_IE_TIMER2 };
43
44 //================================================================================
45 /*---------------------------------------------------------------------------*
46 Name: OSi_IsTimerReserved
47
48 Description: check if specified timer is reserved for OS
49
50 Arguments: timerNum : timerNo (0-3)
51
52 Returns: non-0 if reserved
53 *---------------------------------------------------------------------------*/
OSi_IsTimerReserved(int timerNum)54 u16 OSi_IsTimerReserved(int timerNum)
55 {
56 return (u16)(OSi_TimerReserved & (1 << timerNum));
57 }
58
59 /*---------------------------------------------------------------------------*
60 Name: OSi_SetTimerReserved
61
62 Description: set specified timer to reserved for OS
63
64 Arguments: timerNum : timerNo (0-3)
65
66 Returns: None.
67 *---------------------------------------------------------------------------*/
OSi_SetTimerReserved(int timerNum)68 void OSi_SetTimerReserved(int timerNum)
69 {
70 OSi_TimerReserved |= (1 << timerNum);
71 }
72
73 /*---------------------------------------------------------------------------*
74 Name: OSi_UnsetTimerReserved
75
76 Description: unset specified timer to reserved for OS
77
78 Arguments: timerNum : timerNo (0-3)
79
80 Returns: None.
81 *---------------------------------------------------------------------------*/
OSi_UnsetTimerReserved(int timerNum)82 void OSi_UnsetTimerReserved(int timerNum)
83 {
84 OSi_TimerReserved &= ~(1 << timerNum);
85 }
86
87 //================================================================================
88 /*---------------------------------------------------------------------------*
89 Name: OS_StartTimer / OS_StartTimer32 / OS_StartTimer48 /OS_StartTimer64
90
91 Description: set timer(s) and start
92
93 Arguments: id timerNo
94 count count value to be set to timer
95 preScale preScale
96
97 Returns: None
98 *---------------------------------------------------------------------------*/
99 // use 1 timer, 16bit counter, timer<id> interrupt occurs by overflow
100 //
OS_StartTimer(OSTimer id,u16 count,OSTimerPrescaler preScale)101 void OS_StartTimer(OSTimer id, u16 count, OSTimerPrescaler preScale)
102 {
103 SDK_ASSERT(OS_TIMER_0 <= id && id <= OS_TIMER_3);
104 SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
105 //---- check if system reserved
106 SDK_ASSERT(!OSi_IsTimerReserved(id));
107
108 //---- set a count register
109 OS_SetTimerCount(id, (u16)~count);
110
111 //---- set a control register
112 OS_SetTimerControl(id, OSi_TIMER_MASK(preScale));
113 }
114 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
115 // use 2 timers, 32bit counter, timer<id+1> interrupt occurs by overflow
116 //
OS_StartTimer32(OSTimer32 id,u32 count,OSTimerPrescaler preScale)117 void OS_StartTimer32(OSTimer32 id, u32 count, OSTimerPrescaler preScale)
118 {
119 SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23);
120 SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
121 //---- check if system reserved
122 SDK_ASSERT(!OSi_IsTimerReserved(id));
123 SDK_ASSERT(!OSi_IsTimerReserved(id + 1));
124
125 //---- set count registers
126 OS_SetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff));
127 OS_SetTimerCount((OSTimer)id, (u16)(~count & 0xffff));
128
129 //---- set a timer interrupt handler
130 OS_SetIrqFunction(OSi_MaskTable[(int)id], OSi_IntrTable[(int)id]);
131
132 //---- set control registers
133 OS_SetTimerControl((OSTimer)((int)id + 1), OSi_CASCADE_MASK );
134 OS_SetTimerControl((OSTimer)id, OSi_TIMER_MASK(preScale));
135 }
136 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
137 // use 3 timers, 48bit counter, timer<id+2> interrupt occurs by overflow
138 //
OS_StartTimer48(OSTimer48 id,u64 count,OSTimerPrescaler preScale)139 void OS_StartTimer48(OSTimer48 id, u64 count, OSTimerPrescaler preScale)
140 {
141 SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123);
142 SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
143 //---- check if system reserved
144 SDK_ASSERT(!OSi_IsTimerReserved(id));
145 SDK_ASSERT(!OSi_IsTimerReserved(id + 1));
146 SDK_ASSERT(!OSi_IsTimerReserved(id + 2));
147
148 //---- set count registers
149 OS_SetTimerCount((OSTimer)((int)id + 2), (u16)((~count >> 32) & 0xffff));
150 OS_SetTimerCount((OSTimer)((int)id + 1), (u16)((~count >> 16) & 0xffff));
151 OS_SetTimerCount((OSTimer)id, (u16)(~count & 0xffff));
152
153 //---- set timer interrupt handlers
154 OS_SetIrqFunction(OSi_MaskTable[(int)id+1], OSi_IntrTable[(int)id+1]);
155 OS_SetIrqFunction(OSi_MaskTable[(int)id], OSi_IntrTable[(int)id]);
156
157 //---- set control registers
158 OS_SetTimerControl((OSTimer)((int)id + 2), OSi_CASCADE_MASK );
159 OS_SetTimerControl((OSTimer)((int)id + 1), OSi_CASCADE_MASK );
160 OS_SetTimerControl((OSTimer)id, OSi_TIMER_MASK(preScale));
161 }
162 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
163 // use all 4 timers, 64bit counter, timer3 interrupt occurs by overflow
164 //
OS_StartTimer64(u64 count,OSTimerPrescaler preScale)165 void OS_StartTimer64(u64 count, OSTimerPrescaler preScale)
166 {
167 SDK_ASSERT(OS_TIMER_PRESCALER_1 <= preScale && preScale <= OS_TIMER_PRESCALER_1024);
168 //---- check if system reserved
169 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_0));
170 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_1));
171 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_2));
172 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_3));
173
174 //---- set count registers
175 OS_SetTimerCount(OS_TIMER_3, (u16)((~count >> 48) & 0xffff));
176 OS_SetTimerCount(OS_TIMER_2, (u16)((~count >> 32) & 0xffff));
177 OS_SetTimerCount(OS_TIMER_1, (u16)((~count >> 16) & 0xffff));
178 OS_SetTimerCount(OS_TIMER_0, (u16)(~count & 0xffff));
179
180 //---- set timer interrupt handlers
181 OS_SetIrqFunction(OS_IE_TIMER2, OSi_TimerIntr2);
182 OS_SetIrqFunction(OS_IE_TIMER1, OSi_TimerIntr1);
183 OS_SetIrqFunction(OS_IE_TIMER0, OSi_TimerIntr0);
184
185 //---- set control registers
186 OS_SetTimerControl(OS_TIMER_3, OSi_CASCADE_MASK );
187 OS_SetTimerControl(OS_TIMER_2, OSi_CASCADE_MASK );
188 OS_SetTimerControl(OS_TIMER_1, OSi_CASCADE_MASK );
189 OS_SetTimerControl(OS_TIMER_0, OSi_TIMER_MASK(preScale));
190 }
191
192 /*---------------------------------------------------------------------------*
193 Name: OS_StopTimer / OS_StopTimer32 / OS_StopTimer48 / OS_StopTimer64
194
195 Description: stop timer(s)
196
197 Arguments: id timerNo
198
199 Returns: None
200 *---------------------------------------------------------------------------*/
201 // stop a timer
202 //
OS_StopTimer(OSTimer id)203 void OS_StopTimer(OSTimer id)
204 {
205 SDK_ASSERT(OS_TIMER_0 <= id && id <= OS_TIMER_3);
206 //---- check if system reserved
207 SDK_ASSERT(!OSi_IsTimerReserved(id));
208
209 OS_SetTimerControl(id, 0);
210 }
211
OS_StopTimerAndUnsetHandler(OSTimer id)212 static void OS_StopTimerAndUnsetHandler(OSTimer id)
213 {
214 OS_SetIrqFunction(OSi_MaskTable[(int)id], NULL);
215 OS_StopTimer(id);
216 }
217 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
218 // stop 2 timers
219 //
OS_StopTimer32(OSTimer32 id)220 void OS_StopTimer32(OSTimer32 id)
221 {
222 SDK_ASSERT(OS_TIMER32_01 <= id && id <= OS_TIMER32_23);
223 //---- check if system reserved
224 SDK_ASSERT(!OSi_IsTimerReserved(id));
225 SDK_ASSERT(!OSi_IsTimerReserved(id + 1));
226
227 //---- clear timer setting
228 OS_StopTimerAndUnsetHandler((OSTimer)id);
229 OS_StopTimer((OSTimer)((int)id + 1));
230 }
231 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
232 // stop 3 timers
233 //
OS_StopTimer48(OSTimer48 id)234 void OS_StopTimer48(OSTimer48 id)
235 {
236 SDK_ASSERT(OS_TIMER48_012 <= id && id <= OS_TIMER48_123);
237 //---- check if system reserved
238 SDK_ASSERT(!OSi_IsTimerReserved(id));
239 SDK_ASSERT(!OSi_IsTimerReserved(id + 1));
240 SDK_ASSERT(!OSi_IsTimerReserved(id + 2));
241
242 //---- clear timer setting
243 OS_StopTimerAndUnsetHandler((OSTimer)id);
244 OS_StopTimerAndUnsetHandler((OSTimer)((int)id + 1));
245 OS_StopTimer((OSTimer)((int)id + 2));
246 }
247 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
248 // stop all 4 timers
249 //
OS_StopTimer64(void)250 void OS_StopTimer64(void)
251 {
252 //---- check if system reserved
253 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_0));
254 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_1));
255 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_2));
256 SDK_ASSERT(!OSi_IsTimerReserved(OS_TIMER_3));
257
258 //---- clear timer setting
259 OS_StopTimerAndUnsetHandler(OS_TIMER_0);
260 OS_StopTimerAndUnsetHandler(OS_TIMER_1);
261 OS_StopTimerAndUnsetHandler(OS_TIMER_2);
262 OS_StopTimer(OS_TIMER_3);
263 }
264
265 /*---------------------------------------------------------------------------*
266 Name: OSi_TimerIntr0 / OSi_TimerIntr1 / OSi_TimerIntr2
267
268 Description: timer 0/1/2 interrupt handler
269
270 Arguments: None
271
272 Returns: None
273 *---------------------------------------------------------------------------*/
OSi_TimerIntr0()274 static void OSi_TimerIntr0()
275 {
276 OS_SetTimerCount( OS_TIMER_0, 0 );
277 }
278 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSi_TimerIntr1()279 static void OSi_TimerIntr1()
280 {
281 OS_SetTimerCount( OS_TIMER_1, 0 );
282 }
283 //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSi_TimerIntr2()284 static void OSi_TimerIntr2()
285 {
286 OS_SetTimerCount( OS_TIMER_2, 0 );
287 }
288