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