1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - SPI - demos
3 File: monkey.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-12-22#$
14 $Rev: 9714 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 #include "monkey.h"
19 #include <nitro/spi.h>
20 #include <nitro/spi/common/pm_common.h>
21 #include <nitro/spi/ARM9/pm.h>
22
23
24 /*---------------------------------------------------------------------------*
25 Internal Function Definitions
26 *---------------------------------------------------------------------------*/
27 static void MonkeyThread(void *arg);
28 static void MonkeySamplingAlarm(void *arg);
29 static void MonkeyMicCallback(MICResult result, void *arg);
30 static void MonkeyTpCallback(TPRequestCommand command, TPRequestResult result, u16 index);
31
32
33 /*---------------------------------------------------------------------------*
34 Internal Variable Definitions
35 *---------------------------------------------------------------------------*/
36 static MonkeyWork monkey;
37
38
39 /*---------------------------------------------------------------------------*
40 Name: MonkeyInit
41
42 Description: Starts the thread for SPI device sampling.
43
44 Arguments: None.
45
46 Returns: None.
47 *---------------------------------------------------------------------------*/
MonkeyInit(void)48 void MonkeyInit(void)
49 {
50 // Create a thread exclusively for sampling.
51 OS_InitMessageQueue(&(monkey.msg_q), monkey.msg_buf, MONKEY_MESSAGE_ARRAY_MAX);
52 OS_CreateThread(&(monkey.thread),
53 MonkeyThread,
54 0,
55 (void *)(monkey.stack + (MONKEY_STACK_SIZE / sizeof(u32))),
56 MONKEY_STACK_SIZE, MONKEY_THREAD_PRIORITY);
57 OS_WakeupThreadDirect(&(monkey.thread));
58 }
59
60 /*---------------------------------------------------------------------------*
61 Name: MonkeyGetNewTpData
62
63 Description: Gets the newest touch panel sampling data.
64 Does not consider whether the data has already been read once.
65
66 Arguments: num: Specifies the number of pieces of data to get.
67 array: Specifies the array that will get the data.
68 Data is stored starting at the beginning of the array with the newest data first.
69
70 Returns: None.
71 *---------------------------------------------------------------------------*/
MonkeyGetNewTpData(s32 num,TPData * array)72 void MonkeyGetNewTpData(s32 num, TPData *array)
73 {
74 s32 i;
75 s32 index;
76
77 index = (s32)(monkey.tpIndex);
78 for (i = 0; i < num; i++)
79 {
80 index = (index + (MONKEY_TP_ARRAY_MAX - 1)) % MONKEY_TP_ARRAY_MAX;
81 array[i] = monkey.tpBuf[index];
82 }
83 }
84
85 /*---------------------------------------------------------------------------*
86 Name: MonkeyGetNewMicData
87
88 Description: Gets the newest mic sampling data.
89 Does not consider whether the data has already been read once.
90
91 Arguments: num: Specifies the number of pieces of data to get
92 array: Specifies the array which will get the data.
93 Data is stored starting at the beginning of the array with the newest data first.
94
95 Returns: None.
96 *---------------------------------------------------------------------------*/
MonkeyGetNewMicData(s32 num,u16 * array)97 void MonkeyGetNewMicData(s32 num, u16 *array)
98 {
99 s32 i;
100 s32 index;
101
102 index = (s32)(monkey.micIndex);
103 for (i = 0; i < num; i++)
104 {
105 index = (index + (MONKEY_MIC_ARRAY_MAX - 1)) % MONKEY_MIC_ARRAY_MAX;
106 array[i] = monkey.micBuf[index];
107 }
108 }
109
110 /*---------------------------------------------------------------------------*
111 Name: MonkeyThread
112
113 Description: The thread that performs sampling.
114
115 Arguments: arg: Unused
116
117 Returns: None.
118 *---------------------------------------------------------------------------*/
MonkeyThread(void * arg)119 static void MonkeyThread(void *arg)
120 {
121 #pragma unused( arg )
122
123 OSMessage msg;
124
125 // Microphone API Initialization
126 {
127 MIC_Init();
128 monkey.micIndex = 0;
129
130 // Initialize PMIC
131 PM_Init();
132 // AMP on
133 (void)PM_SetAmp(PM_AMP_ON);
134 // Adjust AMP gain
135 (void)PM_SetAmpGain(PM_AMPGAIN_80);
136 }
137 // Touch Panel API Initialization.
138 {
139 TPCalibrateParam calibrate;
140
141 TP_Init();
142 if (TP_GetUserInfo(&calibrate))
143 {
144 TP_SetCalibrateParam(&calibrate);
145 }
146 else
147 {
148 OS_Panic("Can't find TP calibration data.");
149 }
150 TP_SetCallback(MonkeyTpCallback);
151 monkey.tpIndex = 0;
152 }
153
154 // Start the sampling timer
155 OS_CreateAlarm(&(monkey.alarm));
156 monkey.timerCount = 0;
157 OS_SetPeriodicAlarm(&(monkey.alarm),
158 OS_GetTick(),
159 (MONKEY_MIC_SPAN_TICK * MONKEY_SAMPLING_SPAN_LINE),
160 MonkeySamplingAlarm, NULL);
161
162 while (TRUE)
163 {
164 // Pause the thread until message is received
165 (void)OS_ReceiveMessage(&(monkey.msg_q), &msg, OS_MESSAGE_BLOCK);
166
167 // Touch panel sampling
168 if ((u32)msg == MONKEY_MESSAGE_TYPE_TP)
169 {
170 TP_RequestSamplingAsync();
171 }
172 // Mic sampling
173 else if ((u32)msg == MONKEY_MESSAGE_TYPE_MIC)
174 {
175 if (MIC_RESULT_SUCCESS != MIC_DoSamplingAsync(MIC_SAMPLING_TYPE_12BIT,
176 &(monkey.micBuf[monkey.micIndex]),
177 MonkeyMicCallback, NULL))
178 {
179 OS_Printf("Monkey: MIC request failure.\n");
180 }
181 }
182 }
183 }
184
185 /*---------------------------------------------------------------------------*
186 Name: MonkeySamplingAlarm
187
188 Description: Alarm handler that controls when to send messages to the thread.
189
190 Arguments: arg: Unused
191
192 Returns: None.
193 *---------------------------------------------------------------------------*/
194 /*---------------------------------------------------------------------------*
195 Periodic timer and sampling timing chart
196
197 -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
198 MIC >---- >---- >---- >---- >----
199 TP >-------- >-------- >--
200
201 *---------------------------------------------------------------------------*/
MonkeySamplingAlarm(void * arg)202 static void MonkeySamplingAlarm(void *arg)
203 {
204 #pragma unused( arg )
205
206 if (0 == (monkey.timerCount % 8))
207 {
208 (void)OS_SendMessage(&(monkey.msg_q), (void *)MONKEY_MESSAGE_TYPE_MIC, OS_MESSAGE_BLOCK);
209 }
210 else if (3 == (monkey.timerCount % 16))
211 {
212 (void)OS_SendMessage(&(monkey.msg_q), (void *)MONKEY_MESSAGE_TYPE_TP, OS_MESSAGE_BLOCK);
213 }
214
215 monkey.timerCount++;
216 }
217
218 /*---------------------------------------------------------------------------*
219 Name: MonkeyMicCallback
220
221 Description: Response callback function for mic sampling requests.
222 When sampling was completed without trouble, it advances the data storage destination buffer to the next position.
223
224
225 Arguments: result: Processing result corresponding to mic operation request
226 arg: Unused
227
228 Returns: None.
229 *---------------------------------------------------------------------------*/
MonkeyMicCallback(MICResult result,void * arg)230 static void MonkeyMicCallback(MICResult result, void *arg)
231 {
232 #pragma unused( arg )
233
234 if (result == MIC_RESULT_SUCCESS)
235 {
236 // Advance to the next data storage buffer position
237 monkey.micIndex = (u16)((monkey.micIndex + 1) % MONKEY_MIC_ARRAY_MAX);
238 }
239 else
240 {
241 // Fails because the sampling immediately before has not completed due to effects of sound
242 OS_Printf("Monkey: MIC request failure.\n");
243 }
244 }
245
246 /*---------------------------------------------------------------------------*
247 Name: MonkeyTpCallback
248
249 Description: Callback function that responds to the touch panel's sampling requests.
250 When sampling was completed without trouble, it advances the data storage destination buffer to the next position.
251
252
253 Arguments: command: Indicates the operation request command that the response responds to. Not used.
254 result: Processing result for the touch panel operation request.
255 index: Index for auto-sampling. Not used.
256
257 Returns: None.
258 *---------------------------------------------------------------------------*/
MonkeyTpCallback(TPRequestCommand command,TPRequestResult result,u16 index)259 static void MonkeyTpCallback(TPRequestCommand command, TPRequestResult result, u16 index)
260 {
261 #pragma unused( command , index )
262
263 if (result == TP_RESULT_SUCCESS)
264 {
265 // Convert raw sampling values to screen coordinates
266 (void)TP_GetCalibratedResult(&(monkey.tpBuf[monkey.tpIndex]));
267 // Advance to the next data storage buffer position
268 monkey.tpIndex = (u16)((monkey.tpIndex + 1) % MONKEY_TP_ARRAY_MAX);
269 }
270 else
271 {
272 // Fails because the sampling immediately before has not completed due to effects of sound
273 OS_Printf("Monkey: TP request failure.\n");
274 }
275 }
276
277 /*---------------------------------------------------------------------------*
278 End of file
279 *---------------------------------------------------------------------------*/
280