1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - libraries - snd - common
3 File: snd_alarm.c
4
5 Copyright 2004-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/snd/common/alarm.h>
19
20 #include <nitro/pxi.h>
21 #include <nitro/snd/common/work.h>
22
23 /******************************************************************************
24 structure definition
25 ******************************************************************************/
26
27 #ifdef SDK_ARM9
28
29 typedef struct AlarmCallbackInfo
30 {
31 void (*func) (void *);
32 void *arg;
33 u8 id;
34 u8 pad;
35 u16 pad2;
36 }
37 AlarmCallbackInfo;
38
39 #endif
40
41 /******************************************************************************
42 static variable
43 ******************************************************************************/
44
45 #ifdef SDK_ARM9
46
47 static AlarmCallbackInfo sCallbackTable[SND_ALARM_NUM];
48
49 #endif
50
51 /******************************************************************************
52 static function declaration
53 ******************************************************************************/
54
55 #ifdef SDK_ARM7
56
57 static void AlarmHandler(void *arg);
58
59 #endif
60
61 /******************************************************************************
62 public function
63 ******************************************************************************/
64
65 #ifdef SDK_ARM9
66
SND_AlarmInit(void)67 void SND_AlarmInit(void)
68 {
69 int alarmNo;
70
71 for (alarmNo = 0; alarmNo < SND_ALARM_NUM; alarmNo++)
72 {
73 AlarmCallbackInfo *info;
74
75 info = &sCallbackTable[alarmNo];
76
77 info->func = NULL;
78 info->arg = NULL;
79 info->id = 0;
80 }
81 }
82
83 #else
84
SND_AlarmInit(void)85 void SND_AlarmInit(void)
86 {
87 int alarmNo;
88
89 for (alarmNo = 0; alarmNo < SND_ALARM_NUM; alarmNo++)
90 {
91 SNDi_Work.alarm[alarmNo].enable = FALSE;
92 SNDi_Work.alarm[alarmNo].id = 0;
93 }
94 }
95
SND_SetupAlarm(int alarmNo,OSTick tick,OSTick period,int id)96 void SND_SetupAlarm(int alarmNo, OSTick tick, OSTick period, int id)
97 {
98 SNDAlarm *alarm;
99
100 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
101 SDK_MINMAX_ASSERT(id, 0x00, 0xff);
102
103 alarm = &SNDi_Work.alarm[alarmNo];
104
105 if (alarm->enable)
106 {
107 OS_CancelAlarm(&alarm->alarm);
108 alarm->enable = FALSE;
109 }
110
111 alarm->setting.tick = tick;
112 alarm->setting.period = period;
113 alarm->id = (u8)id;
114 alarm->count = 0;
115 }
116
SND_StartAlarm(int alarmNo)117 void SND_StartAlarm(int alarmNo)
118 {
119 OSTick tick;
120 OSTick period;
121 SNDAlarm *alarm;
122 void *arg;
123
124 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
125
126 alarm = &SNDi_Work.alarm[alarmNo];
127
128 if (alarm->enable)
129 {
130 OS_CancelAlarm(&alarm->alarm);
131 alarm->enable = FALSE;
132 }
133
134 tick = alarm->setting.tick;
135 period = alarm->setting.period;
136 arg = (void *)((alarm->id << 8) | alarmNo);
137
138 OS_CreateAlarm(&alarm->alarm);
139
140 if (period == 0)
141 {
142 OS_SetAlarm(&alarm->alarm, tick, AlarmHandler, arg);
143 }
144 else
145 {
146 OS_SetPeriodicAlarm(&alarm->alarm, OS_GetTick() + tick, period, AlarmHandler, arg);
147 }
148
149 alarm->enable = TRUE;
150 }
151
SND_StopAlarm(int alarmNo)152 void SND_StopAlarm(int alarmNo)
153 {
154 SNDAlarm *alarm;
155
156 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
157
158 alarm = &SNDi_Work.alarm[alarmNo];
159
160 if (!alarm->enable)
161 return;
162
163 OS_CancelAlarm(&alarm->alarm);
164
165 alarm->id++;
166 alarm->enable = FALSE;
167 }
168 #endif
169
170 /******************************************************************************
171 static function
172 ******************************************************************************/
173
174 #ifdef SDK_ARM7
175
AlarmHandler(void * arg)176 static void AlarmHandler(void *arg)
177 {
178 u32 msg = (u32)arg;
179 u32 alarmNo = msg & 0xff;
180 u32 id = (msg >> 8) & 0xff;
181 SNDAlarm *alarm;
182
183 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
184
185 alarm = &SNDi_Work.alarm[alarmNo];
186 if ( id != alarm->id ) {
187 return;
188 }
189
190 if ( alarm->count < 0xff ) {
191 alarm->count++;
192 }
193
194 while (alarm->count > 0)
195 {
196 if (PXI_SendWordByFifo(PXI_FIFO_TAG_SOUND, msg, FALSE) < 0) {
197 break;
198 }
199 alarm->count--;
200 }
201 }
202
203 #endif
204
205 /******************************************************************************
206 private function
207 ******************************************************************************/
208
209 #ifdef SDK_ARM9
210
SNDi_IncAlarmId(int alarmNo)211 void SNDi_IncAlarmId(int alarmNo)
212 {
213 AlarmCallbackInfo *info;
214
215 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
216
217 info = &sCallbackTable[alarmNo];
218
219 info->id++;
220 }
221
SNDi_SetAlarmHandler(int alarmNo,SNDAlarmHandler handler,void * arg)222 u8 SNDi_SetAlarmHandler(int alarmNo, SNDAlarmHandler handler, void *arg)
223 {
224 AlarmCallbackInfo *info;
225
226 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
227
228 info = &sCallbackTable[alarmNo];
229
230 info->func = handler;
231 info->arg = arg;
232 info->id++;
233
234 return info->id;
235 }
236
SNDi_CallAlarmHandler(int msg)237 void SNDi_CallAlarmHandler(int msg)
238 {
239 AlarmCallbackInfo *info;
240 int alarmNo = msg & 0xff;
241 int id = (msg >> 8) & 0xff;
242
243 SDK_MINMAX_ASSERT(alarmNo, SND_ALARM_MIN, SND_ALARM_MAX);
244
245 info = &sCallbackTable[alarmNo];
246
247 if (id == info->id)
248 {
249 if (info->func != NULL)
250 {
251 info->func(info->arg);
252 }
253 }
254 }
255
256 #endif
257
258 /*====== End of snd_alarm.c ======*/
259