1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS - demos - entropy-1
3 File: main.c
4
5 Copyright 2005-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.h>
19
20 #include "DEMO.h"
21 #include "wmscan.h"
22
23
24 /*---------------------------------------------------------------------------*/
25 /* Variables */
26
27 static u8 randomSeed[20];
28 static u8 micData[1024] ATTRIBUTE_ALIGN(32);
29 static MICAutoParam micAutoParam;
30 static volatile BOOL bufferFullFlag;
31 static u8 wmBuffer[WM_SYSTEM_BUF_SIZE] ATTRIBUTE_ALIGN(32);
32
33
34 /*---------------------------------------------------------------------------*/
35 /* Functions */
36
37 static void ChurnRandomSeed(void);
38 static u32 GetRandomNumber(void);
39 static void MicFullCallback(MICResult result, void *arg);
40
41 /*---------------------------------------------------------------------------*
42 Name: NitroMain
43
44 Description: Main.
45
46 Arguments: None.
47
48 Returns: None.
49 *---------------------------------------------------------------------------*/
NitroMain()50 void NitroMain()
51 {
52 OS_Init();
53
54 // Increase the randomness of the data returned by OS_GetLowEntropyData function by starting Tick
55 OS_InitTick();
56 OS_InitAlarm();
57
58 // Touch panel initialization
59 {
60 TPCalibrateParam calibrate;
61 TP_Init();
62 // Get CalibrateParameter from FlashMemory
63 if (!TP_GetUserInfo(&calibrate))
64 {
65 OS_TPanic("FATAL ERROR: can't read UserOwnerInfo\n");
66 }
67 TP_SetCalibrateParam(&calibrate);
68 }
69
70 (void)OS_EnableIrq();
71 (void)OS_EnableInterrupts();
72
73 DEMOInitCommon();
74 DEMOInitVRAM();
75 DEMOInitDisplayBitmap();
76 DEMOHookConsole();
77 DEMOStartDisplay();
78
79 // Initialize mic and start auto-sampling
80 {
81 MICResult result = MIC_RESULT_ILLEGAL_STATUS;
82 MIC_Init();
83 (void)PM_SetAmp(PM_AMP_ON);
84
85 micAutoParam.type = MIC_SAMPLING_TYPE_8BIT;
86 micAutoParam.buffer = (void *)micData;
87 micAutoParam.size = sizeof(micData);
88 micAutoParam.rate = MIC_SAMPLING_RATE_8K;
89 micAutoParam.loop_enable = TRUE;
90 micAutoParam.full_callback = MicFullCallback;
91
92 bufferFullFlag = FALSE;
93 if (!OS_IsRunOnTwl())
94 {
95 result = MIC_StartAutoSampling(&micAutoParam);
96 }
97 #ifdef SDK_TWL
98 else
99 {
100 SNDEXFrequency freq;
101 SNDEX_Init();
102 if (SNDEX_GetI2SFrequency(&freq) != SNDEX_RESULT_SUCCESS)
103 {
104 OS_TWarning("failed to check I2C-master frequency.\n");
105 result = MIC_RESULT_ILLEGAL_STATUS;
106 }
107 else
108 {
109 micAutoParam.rate = (freq == SNDEX_FREQUENCY_32730) ? MIC_SAMPLING_RATE_8180 : MIC_SAMPLING_RATE_11900;
110 result = MIC_StartLimitedSampling(&micAutoParam);
111 }
112 }
113 #endif // SDK_TWL
114 if (result != MIC_RESULT_SUCCESS)
115 {
116 bufferFullFlag = TRUE;
117 OS_TPanic("MIC_StartAutoSampling failed. result = %d\n", result);
118 }
119 }
120
121 // Initialize wireless communication.
122 // Because the OS_GetLowEntropyData function also returns data based on the reception strength history
123 // this demo starts wireless communication and searches for a parent.
124 if (!WS_Initialize(wmBuffer, 3))
125 {
126 OS_TPanic("WS_Initialize failed.\n");
127 }
128 WS_TurnOnPictoCatch();
129 {
130 const u8 mac[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
131
132 // Wait for initialization to complete
133 while (WS_GetSystemState() != WS_SYSSTATE_IDLE)
134 {
135 }
136 // Start search for parent
137 if (!WS_StartScan(NULL, mac, TRUE))
138 {
139 OS_TPanic("WS_StartScan failed.\n");
140 }
141 }
142
143 // Initialize random number seed using mic sampling result
144 while (bufferFullFlag == FALSE)
145 {
146 // Wait until mic sampling goes through the buffer
147 ;
148 }
149 MATH_CalcSHA1(randomSeed, micData, sizeof(micData));
150
151 // Use the OS_GetLowEntropyData function to randomize the random number seed
152 ChurnRandomSeed();
153
154 // Main loop
155 while (1)
156 {
157 int i;
158 int j;
159 int y;
160 TPData raw_point;
161 u32 data[OS_LOW_ENTROPY_DATA_SIZE / sizeof(u32)];
162
163 DEMO_DrawFlip();
164 // Wait for V-Blank interrupt
165 OS_WaitVBlankIntr();
166
167 (void)TP_RequestRawSampling(&raw_point);
168
169 // Display result of OS_GetLowEntropyData on screen every 2ms
170 y = 0;
171 for (j = 0; j < 6; j++)
172 {
173 if (j != 0)
174 {
175 OS_Sleep(2);
176 }
177 OS_GetLowEntropyData(data);
178 for (i = 0; i < OS_LOW_ENTROPY_DATA_SIZE / sizeof(u32); i++)
179 {
180 char tmp[32 + 1];
181 int x;
182 for (x = 0; x < 32; ++x)
183 {
184 tmp[x] = (char)('0' + ((data[i] >> (31 - x)) & 1));
185 }
186 tmp[x] = '\0';
187 DEMOPutString(0, y, "%s", tmp);
188 y += 1;
189 }
190 }
191
192 if ((OS_GetVBlankCount() % 16) == 0)
193 {
194 // Use the OS_GetLowEntropyData function every 16 frames to randomize the random number seed
195 //
196 ChurnRandomSeed();
197 }
198
199 // Display the random number
200 OS_TPrintf("%08x\n", GetRandomNumber());
201 }
202 }
203
204 //--------------------------------------------------------------------------------
205 // Example of changing the random number seed based on the OS_GetLowEntropyData function
206 //
ChurnRandomSeed(void)207 void ChurnRandomSeed(void)
208 {
209 u32 data[OS_LOW_ENTROPY_DATA_SIZE / sizeof(u32)];
210 MATHSHA1Context context;
211
212 OS_GetLowEntropyData(data);
213 MATH_SHA1Init(&context);
214 MATH_SHA1Update(&context, randomSeed, sizeof(randomSeed));
215 MATH_SHA1Update(&context, data, sizeof(data));
216 MATH_SHA1GetHash(&context, randomSeed);
217 }
218
219 //--------------------------------------------------------------------------------
220 // Example of getting random number from random number seed (Not thread-safe)
221 //
GetRandomNumber(void)222 u32 GetRandomNumber(void)
223 {
224 static u32 count = 0;
225 u32 randomData[20 / sizeof(u32)];
226 MATHSHA1Context context;
227
228 MATH_SHA1Init(&context);
229 MATH_SHA1Update(&context, randomSeed, sizeof(randomSeed));
230 MATH_SHA1Update(&context, &count, sizeof(count));
231 MATH_SHA1GetHash(&context, randomData);
232 count++;
233
234 // Although you can use the entire randomData as a random number,
235 // you can also remove any part of randomData and use it as a random number.
236 return randomData[0];
237 }
238
239 //--------------------------------------------------------------------------------
240 // Auto-sampling buffer callback
241 //
MicFullCallback(MICResult result,void * arg)242 void MicFullCallback(MICResult result, void *arg)
243 {
244 #pragma unused(result)
245 #pragma unused(arg)
246 bufferFullFlag = TRUE;
247 }
248
249 /*====== End of main.c ======*/
250