1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - libraries - snd - common
3 File: snd_main.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/main.h>
19
20 #include <nitro/os.h>
21 #include <nitro/snd/common/global.h>
22 #include <nitro/snd/common/exchannel.h>
23 #include <nitro/snd/common/seq.h>
24 #include <nitro/snd/common/alarm.h>
25 #include <nitro/snd/common/command.h>
26 #include <nitro/snd/common/util.h>
27 #include <nitro/snd/common/work.h>
28
29 #ifdef SDK_TWL
30 #ifdef SDK_ARM7
31 #include <twl/snd/ARM7/sndex_api.h>
32 #endif
33 #endif
34
35 /******************************************************************************
36 Macro definitions
37 ******************************************************************************/
38
39 #ifdef SDK_ARM7
40
41 #define SND_THREAD_STACK_SIZE 1024
42 #define SND_THREAD_MESSAGE_BUFSIZE 8
43
44 #define SND_ALARM_COUNT_P1 0x10000
45
46 #endif /* SDK_ARM7 */
47
48 /******************************************************************************
49 Static variables
50 ******************************************************************************/
51
52 #ifdef SDK_ARM9
53
54 static OSMutex sSndMutex;
55
56 #else /* SDK_ARM7 */
57
58 static OSThread sndThread;
59 static u64 sndStack[SND_THREAD_STACK_SIZE / sizeof(u64)];
60 static OSAlarm sndAlarm;
61 static OSMessageQueue sndMesgQueue;
62 static OSMessage sndMesgBuffer[SND_THREAD_MESSAGE_BUFSIZE];
63
64 #endif /* SDK_ARM9 */
65
66
67 /******************************************************************************
68 Static function declarations
69 ******************************************************************************/
70
71 #ifdef SDK_ARM7
72
73 static void SndThread(void *arg);
74 static void SndAlarmCallback(void *arg);
75
76 #endif /* SDK_ARM7 */
77
78 /******************************************************************************
79 Public functions
80 ******************************************************************************/
81
82 #ifdef SDK_ARM9
83
84 /*---------------------------------------------------------------------------*
85 Name: SND_Init
86
87 Description: Initializes sound library.
88
89 Arguments: None.
90
91 Returns: None.
92 *---------------------------------------------------------------------------*/
SND_Init(void)93 void SND_Init(void)
94 {
95 {
96 static BOOL initialized = FALSE;
97 if (initialized)
98 return;
99 initialized = TRUE;
100 }
101
102 OS_InitMutex(&sSndMutex);
103 SND_CommandInit();
104 SND_AlarmInit();
105 }
106
107 #else /* SDK_ARM7 */
108
109 /*---------------------------------------------------------------------------*
110 Name: SND_Init
111
112 Description: Initializes sound and starts the sound thread.
113
114 Arguments: threadPrio - Thread priority.
115
116 Returns: None.
117 *---------------------------------------------------------------------------*/
SND_Init(u32 threadPrio)118 void SND_Init(u32 threadPrio)
119 {
120 {
121 static BOOL initialized = FALSE;
122 if (initialized)
123 return;
124 initialized = TRUE;
125 }
126
127 SND_CommandInit();
128
129 SND_CreateThread(threadPrio);
130 }
131
132 /*---------------------------------------------------------------------------*
133 Name: SND_CreateThread
134
135 Description: Starts the sound thread.
136
137 Arguments: threadPrio - Thread priority.
138
139 Returns: None.
140 *---------------------------------------------------------------------------*/
SND_CreateThread(u32 threadPrio)141 void SND_CreateThread(u32 threadPrio)
142 {
143 OS_CreateThread(&sndThread,
144 SndThread,
145 NULL,
146 sndStack + SND_THREAD_STACK_SIZE / sizeof(u64),
147 SND_THREAD_STACK_SIZE, threadPrio);
148 OS_WakeupThreadDirect(&sndThread);
149 }
150
151 /*---------------------------------------------------------------------------*
152 Name: SND_SetThreadPriority
153
154 Description: Configures the priority of the sound thread.
155
156 Arguments: prio - Thread priority.
157
158 Returns: Whether it was successful or not.
159 *---------------------------------------------------------------------------*/
SND_SetThreadPriority(u32 prio)160 BOOL SND_SetThreadPriority(u32 prio)
161 {
162 return OS_SetThreadPriority(&sndThread, prio);
163 }
164
165 /*---------------------------------------------------------------------------*
166 Name: SND_InitIntervalTimer
167
168 Description: Initializes the interval timer.
169
170 Arguments: None.
171
172 Returns: None.
173 *---------------------------------------------------------------------------*/
SND_InitIntervalTimer(void)174 void SND_InitIntervalTimer(void)
175 {
176 OS_InitMessageQueue(&sndMesgQueue, sndMesgBuffer, SND_THREAD_MESSAGE_BUFSIZE);
177
178 OS_CreateAlarm(&sndAlarm);
179 }
180
181 /*---------------------------------------------------------------------------*
182 Name: SND_StartIntervalTimer
183
184 Description: Starts the interval timer.
185
186 Arguments: None.
187
188 Returns: None.
189 *---------------------------------------------------------------------------*/
SND_StartIntervalTimer(void)190 void SND_StartIntervalTimer(void)
191 {
192 OS_SetPeriodicAlarm(&sndAlarm,
193 OS_GetTick() + SND_ALARM_COUNT_P1,
194 SND_PROC_INTERVAL, &SndAlarmCallback, NULL);
195 }
196
197 /*---------------------------------------------------------------------------*
198 Name: SND_StopIntervalTimer
199
200 Description: Stops the interval timer.
201
202 Arguments: None.
203
204 Returns: None.
205 *---------------------------------------------------------------------------*/
SND_StopIntervalTimer(void)206 void SND_StopIntervalTimer(void)
207 {
208 OS_CancelAlarm(&sndAlarm);
209 }
210
211 /*---------------------------------------------------------------------------*
212 Name: SND_WaitForIntervalTimer
213
214 Description: Waits for the interval timer.
215
216 Arguments: None.
217
218 Returns: Returns a message.
219 *---------------------------------------------------------------------------*/
SND_WaitForIntervalTimer(void)220 OSMessage SND_WaitForIntervalTimer(void)
221 {
222 OSMessage message;
223
224 (void)OS_ReceiveMessage(&sndMesgQueue, &message, OS_MESSAGE_BLOCK);
225
226 return message;
227 }
228
229 /*---------------------------------------------------------------------------*
230 Name: SND_SendWakeupMessage
231
232 Description: Sends a message to wake up the sound thread.
233
234 Arguments: None.
235
236 Returns: Flag expressing whether or not the message was successfully sent.
237 *---------------------------------------------------------------------------*/
SND_SendWakeupMessage(void)238 BOOL SND_SendWakeupMessage(void)
239 {
240 return OS_SendMessage(&sndMesgQueue, (OSMessage)SND_MESSAGE_WAKEUP_THREAD, OS_MESSAGE_NOBLOCK);
241 }
242
243 #endif /* SDK_ARM7 */
244
245 /******************************************************************************
246 Private function
247 ******************************************************************************/
248
249 /*---------------------------------------------------------------------------*
250 Name: SNDi_LockMutex
251
252 Description: Locks the sound mutex.
253
254 Arguments: None.
255
256 Returns: None.
257 *---------------------------------------------------------------------------*/
SNDi_LockMutex(void)258 void SNDi_LockMutex(void)
259 {
260 #ifdef SDK_ARM9
261 OS_LockMutex(&sSndMutex);
262 #endif
263 }
264
265 /*---------------------------------------------------------------------------*
266 Name: SNDi_UnlockMutex
267
268 Description: Unlocks the sound mutex.
269
270 Arguments: None.
271
272 Returns: None.
273 *---------------------------------------------------------------------------*/
SNDi_UnlockMutex(void)274 void SNDi_UnlockMutex(void)
275 {
276 #ifdef SDK_ARM9
277 OS_UnlockMutex(&sSndMutex);
278 #endif
279 }
280
281 /******************************************************************************
282 Static functions
283 ******************************************************************************/
284
285 #ifdef SDK_ARM7
286
287 /*---------------------------------------------------------------------------*
288 Name: SndAlarmCallback
289
290 Description: Callback called in the alarm cycle.
291
292 Arguments: arg: User data (unused)
293
294 Returns: None.
295 *---------------------------------------------------------------------------*/
SndAlarmCallback(void *)296 static void SndAlarmCallback(void * /*arg */ )
297 {
298 if (!OS_SendMessage(&sndMesgQueue, (OSMessage)SND_MESSAGE_PERIODIC, OS_MESSAGE_NOBLOCK))
299 {
300 OS_PutString("Failed sound alarm OS_SendMessage\n");
301 }
302 }
303
304 /*---------------------------------------------------------------------------*
305 Name: SndThread
306
307 Description: Sound thread function.
308
309 Arguments: arg: User data (unused)
310
311 Returns: None.
312 *---------------------------------------------------------------------------*/
SndThread(void *)313 static void SndThread(void * /*arg */ )
314 {
315 #ifdef SDK_TWL
316 if (OS_IsRunOnTwl() == TRUE)
317 {
318 /* Initialize I2S-related settings */
319 SDNEXi_InitializeSMIX();
320 }
321 /* Power supply to the sound circuit */
322 reg_SND_POWCNT |= REG_SND_POWCNT_SPE_MASK;
323 #endif
324
325 SND_InitIntervalTimer();
326 SND_ExChannelInit();
327 SND_SeqInit();
328 SND_AlarmInit();
329 SND_Enable();
330 SND_SetOutputSelector(SND_OUTPUT_MIXER,
331 SND_OUTPUT_MIXER, SND_CHANNEL_OUT_MIXER, SND_CHANNEL_OUT_MIXER);
332 SND_SetMasterVolume(SND_MASTER_VOLUME_MAX);
333
334 SND_StartIntervalTimer();
335
336 while (1)
337 {
338 OSMessage message;
339 BOOL doPeriodicProc = FALSE;
340
341 //-----------------------------------------------------------------------------
342 // Wait interval timer
343
344 message = SND_WaitForIntervalTimer();
345
346 switch ((u32)message)
347 {
348 case SND_MESSAGE_PERIODIC:
349 doPeriodicProc = TRUE;
350 break;
351 case SND_MESSAGE_WAKEUP_THREAD:
352 break;
353 }
354
355 //-----------------------------------------------------------------------------
356 // Update registers
357
358 SND_UpdateExChannel();
359
360 //-----------------------------------------------------------------------------
361 // ARM9 command proc
362
363 SND_CommandProc();
364
365 //-----------------------------------------------------------------------------
366 // Framework
367
368 SND_SeqMain(doPeriodicProc);
369 SND_ExChannelMain(doPeriodicProc);
370
371 SND_UpdateSharedWork();
372
373 (void)SND_CalcRandom();
374 }
375
376 SND_Disable();
377 SND_StopIntervalTimer();
378 }
379
380 #endif /* SDK_ARM7 */
381
382 /*====== End of snd_main.c ======*/
383