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:: 2008-09-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
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 /*---------------------------------------------------------------------------*
125 Name: OS_GetTick
126
127 Description: get tick value
128
129 Arguments: None
130
131 Returns: tick value
132 *---------------------------------------------------------------------------*/
OS_GetTick(void)133 OSTick OS_GetTick(void)
134 {
135 vu16 countL;
136 vu64 countH;
137
138 OSIntrMode prev = OS_DisableInterrupts();
139 SDK_ASSERT(OSi_UseTick);
140
141 countL = *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4);
142 countH = OSi_TickCounter & 0xffffffffffffULL;
143
144 //---- check if timer interrupt bit is on
145 if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000))
146 {
147 countH++;
148 }
149
150 (void)OS_RestoreInterrupts(prev);
151
152 return (countH << 16) | countL;
153 }
154
155 //---- for profiler
156 #pragma profile off
OSi_GetTick_noProfile(void)157 u32 OSi_GetTick_noProfile(void)
158 {
159 vu16 countL;
160 vu16 countH;
161
162 OSIntrMode prev = OS_DisableInterrupts();
163 SDK_ASSERT(OSi_UseTick);
164
165 countL = *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4);
166 countH = (u16)OSi_TickCounter;
167
168 //---- check if timer interrupt bit is on
169 if (reg_OS_IF & OSi_TICK_IE_TIMER && !(countL & 0x8000))
170 {
171 countH++;
172 }
173
174 (void)OS_RestoreInterrupts(prev);
175
176 return (u32)(countH << 16) | countL;
177 }
178
179 #pragma profile reset
180
181 /*---------------------------------------------------------------------------*
182 Name: OS_GetTickLo
183
184 Description: get tick value (only u16 part)
185
186 Arguments: None
187
188 Returns: tick value (only u16 part)
189 *---------------------------------------------------------------------------*/
OS_GetTickLo(void)190 u16 OS_GetTickLo(void)
191 {
192 SDK_ASSERT(OSi_UseTick);
193 return *(REGType16 *)((u32)REG_TM0CNT_L_ADDR + OSi_TICK_TIMER * 4);
194 }
195
196 /*---------------------------------------------------------------------------*
197 Name: OS_SetTick
198
199 Description: set tick value
200
201 Arguments: count value of tick to be set
202
203 Returns: None
204 *---------------------------------------------------------------------------*/
OS_SetTick(OSTick count)205 void OS_SetTick(OSTick count)
206 {
207 OSIntrMode prev;
208
209 SDK_ASSERT(OSi_UseTick);
210 prev = OS_DisableInterrupts();
211
212 reg_OS_IF = OSi_TICK_IE_TIMER;
213
214 OSi_NeedResetTimer = TRUE;
215
216 OSi_TickCounter = (u64)(count >> 16);
217
218 OS_SetTimerControl(OSi_TICK_TIMER, 0);
219 OS_SetTimerCount((OSTimer)OSi_TICK_TIMER, (u16)(count & 0xffff));
220 OS_SetTimerControl(OSi_TICK_TIMER, (u16)OSi_TICK_TIMERCONTROL);
221
222 (void)OS_RestoreInterrupts(prev);
223 }
224