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