1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS
3 File: os_tick.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:: 2009-06-15#$
14 $Rev: 10752 $
15 $Author: terui $
16 *---------------------------------------------------------------------------*/
17 #include <nitro/os.h>
18
19 //----------------------------------------------------------------------
20 //---- timer control setting for tick
21 #define OSi_TICK_TIMERCONTROL ( REG_OS_TM0CNT_H_E_MASK | REG_OS_TM0CNT_H_I_MASK | OS_TIMER_PRESCALER_64 )
22
23 //---- timer number tick uses
24 #define OSi_TICK_TIMER OS_TIMER_0
25
26 //---- timer interrupt mask (must be same number with OSi_TICK_TIMER)
27 #define OSi_TICK_IE_TIMER OS_IE_TIMER0
28
29 //---- flag for initialization tick
30 static u16 OSi_UseTick = FALSE;
31
32 //---- tick counter
33 vu64 OSi_TickCounter;
34
35 //---- flag for need to re-set timer
36 BOOL OSi_NeedResetTimer = FALSE;
37
38
39 extern u16 OSi_IsTimerReserved(int timerNum);
40 extern void OSi_SetTimerReserved(int timerNum);
41
42 static void OSi_CountUpTick(void);
43 u32 OSi_GetTick_noProfile(void);
44
45
46 /*---------------------------------------------------------------------------*
47 Name: OS_InitTick
48
49 Description: initialize 'tick system'
50
51 Arguments: None
52
53 Returns: None
54 *---------------------------------------------------------------------------*/
OS_InitTick(void)55 void OS_InitTick(void)
56 {
57 if (!OSi_UseTick)
58 {
59 OSi_UseTick = TRUE;
60
61 //---- OS reserves OSi_TICK_TIMER timer
62 SDK_ASSERT(!OSi_IsTimerReserved(OSi_TICK_TIMER));
63 OSi_SetTimerReserved(OSi_TICK_TIMER);
64
65 //---- setting timer
66 OSi_TickCounter = 0;
67 OS_SetTimerControl(OSi_TICK_TIMER, 0);
68 OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)0);
69 OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
70
71 //---- set interrupt callback
72 OS_SetIrqFunction(OSi_TICK_IE_TIMER, OSi_CountUpTick);
73
74 //---- enable timer interrupt
75 (void)OS_EnableIrqMask(OSi_TICK_IE_TIMER);
76
77 //---- need to reset
78 OSi_NeedResetTimer = FALSE;
79 }
80 }
81
82 /*---------------------------------------------------------------------------*
83 Name: OS_IsTickAvailable
84
85 Description: check tick system is available
86
87 Arguments: None
88
89 Returns: if available, TRUE.
90 *---------------------------------------------------------------------------*/
OS_IsTickAvailable(void)91 BOOL OS_IsTickAvailable(void)
92 {
93 return OSi_UseTick;
94 }
95
96
97 /*---------------------------------------------------------------------------*
98 Name: OSi_CountUpTick
99
100 Description: timer interrupt handle.
101
102 Arguments: None
103
104 Returns: None
105 *---------------------------------------------------------------------------*/
OSi_CountUpTick(void)106 static void OSi_CountUpTick(void)
107 {
108 OSi_TickCounter++;
109
110 //---- setting for timer
111 if (OSi_NeedResetTimer)
112 {
113 OS_SetTimerControl(OSi_TICK_TIMER, 0);
114 OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)0);
115 OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
116
117 OSi_NeedResetTimer = FALSE;
118 }
119
120 //---- reset callback
121 OSi_EnterTimerCallback(OSi_TICK_TIMER, (void (*)(void *))OSi_CountUpTick, 0);
122 }
123
124 #ifdef SDK_ARM7
125 #ifdef SDK_TWL
126 extern u32 MIC_GetDelayIF(void);
127 #endif
128 #endif
129 /*---------------------------------------------------------------------------*
130 Name: OS_GetTick
131
132 Description: get tick value
133
134 Arguments: None
135
136 Returns: tick value
137 *---------------------------------------------------------------------------*/
OS_GetTick(void)138 OSTick OS_GetTick(void)
139 {
140 vu16 countL;
141 vu64 countH;
142
143 OSIntrMode prev = OS_DisableInterrupts();
144 SDK_ASSERT(OSi_UseTick);
145
146 countL = *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4);
147 countH = OSi_TickCounter & 0xffffffffffffULL;
148
149 //---- check if timer interrupt bit is on
150 #ifdef SDK_ARM7
151 #ifdef SDK_TWL
152 if (((reg_OS_IF | MIC_GetDelayIF()) & OSi_TICK_IE_TIMER) && !(countL & 0x8000))
153 #else
154 if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000))
155 #endif
156 #else
157 if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000))
158 #endif
159 {
160 countH++;
161 }
162
163 (void)OS_RestoreInterrupts(prev);
164
165 return (countH << 16) | countL;
166 }
167
168 //---- for profiler
169 #pragma profile off
OSi_GetTick_noProfile(void)170 u32 OSi_GetTick_noProfile(void)
171 {
172 vu16 countL;
173 vu16 countH;
174
175 OSIntrMode prev = OS_DisableInterrupts();
176 SDK_ASSERT(OSi_UseTick);
177
178 countL = *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4);
179 countH = (u16)OSi_TickCounter;
180
181 //---- check if timer interrupt bit is on
182 if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000))
183 {
184 countH++;
185 }
186
187 (void)OS_RestoreInterrupts(prev);
188
189 return (u32)(countH << 16) | countL;
190 }
191
192 #pragma profile reset
193
194 /*---------------------------------------------------------------------------*
195 Name: OS_GetTickLo
196
197 Description: get tick value (only u16 part)
198
199 Arguments: None
200
201 Returns: tick value (only u16 part)
202 *---------------------------------------------------------------------------*/
OS_GetTickLo(void)203 u16 OS_GetTickLo(void)
204 {
205 SDK_ASSERT(OSi_UseTick);
206 return *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4);
207 }
208
209 /*---------------------------------------------------------------------------*
210 Name: OS_SetTick
211
212 Description: set tick value
213
214 Arguments: count value of tick to be set
215
216 Returns: None
217 *---------------------------------------------------------------------------*/
OS_SetTick(OSTick count)218 void OS_SetTick(OSTick count)
219 {
220 OSIntrMode prev;
221
222 SDK_ASSERT(OSi_UseTick);
223 prev = OS_DisableInterrupts();
224
225 reg_OS_IF = OSi_TICK_IE_TIMER;
226
227 OSi_NeedResetTimer = TRUE;
228
229 OSi_TickCounter = (u64)(count >> 16);
230
231 OS_SetTimerControl(OSi_TICK_TIMER, 0);
232 OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)(count & 0xffff));
233 OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
234
235 (void)OS_RestoreInterrupts(prev);
236 }
237