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