|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of the License "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // UI menu file |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 */ |
|
21 |
|
22 #include <e32const.h> |
|
23 #include <e32const_private.h> |
|
24 #include <e32std.h> |
|
25 #include <e32std_private.h> |
|
26 #include <e32svr.h> |
|
27 #include <e32cons.h> |
|
28 #include <f32file.h> |
|
29 #include <hal.h> |
|
30 #include <u32hal.h> |
|
31 #include "bootloader_variantconfig.h" |
|
32 #include <nkern/nk_trace.h> |
|
33 #include <e32twin.h> |
|
34 |
|
35 #define FILE_ID 0x01 |
|
36 #include "bootldr.h" |
|
37 #include <d32comm.h> |
|
38 |
|
39 // Console screen |
|
40 RConsole TheConsole; |
|
41 RThread TheKeyThread; |
|
42 |
|
43 |
|
44 //////////////////////////////////////////////////////// |
|
45 void menu_displayfn(); |
|
46 LOCAL_C void menu_processkey(TConsoleKey&); |
|
47 void autoload_displayfn(); |
|
48 LOCAL_C void autoload_processkey(TConsoleKey &aKey); |
|
49 |
|
50 struct display_process |
|
51 { |
|
52 void (*iDisplayFn)(); |
|
53 void (*iProcessKey)(TConsoleKey&); |
|
54 }; |
|
55 |
|
56 display_process screens[] = |
|
57 { |
|
58 {autoload_displayfn, autoload_processkey}, |
|
59 {menu_displayfn, menu_processkey} |
|
60 }; |
|
61 |
|
62 #define SCREEN_AUTOLOAD 0 |
|
63 #define SCREEN_MENU 1 |
|
64 display_process* gCurrentScreen = &screens[SCREEN_AUTOLOAD]; |
|
65 TBool gScreenUpdate; // Controls whether to redraw the screen |
|
66 |
|
67 void mainmenu_usbboot(TUint32, TUint32) |
|
68 { |
|
69 // Turn off raw mode so app receives key events |
|
70 TheConsole.Control(_L("-Raw")); |
|
71 if(StartUSBMS() == EFalse) |
|
72 { |
|
73 // Didn't manage to start |
|
74 TheConsole.Control(_L("+Raw")); |
|
75 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
76 TheConsole.Write(_L("Insert MMC card first!!")); |
|
77 TheConsole.SetCursorPosAbs(TPoint(0,16)); |
|
78 TheConsole.Write(_L("Card required for USB boot")); |
|
79 TheConsole.SetCursorPosAbs(TPoint(0,17)); |
|
80 TheConsole.Write(_L("mode")); |
|
81 } |
|
82 return; |
|
83 } |
|
84 |
|
85 void mainmenu_serial(TUint32 aPort, TUint32 aBaud) |
|
86 { |
|
87 TBps baudRate; |
|
88 |
|
89 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
90 TBuf<64> outBuf; |
|
91 |
|
92 switch (aBaud) |
|
93 { |
|
94 case 115200: baudRate = EBps115200; break; |
|
95 case 230400: baudRate = EBps230400; break; |
|
96 default: |
|
97 outBuf.AppendFormat(_L("Invalid Baud Rate (COM%d,%d)"), aPort, aBaud); |
|
98 TheConsole.Write(outBuf); |
|
99 return; |
|
100 } |
|
101 outBuf.AppendFormat(_L("Setting COM%d baud %d"), aPort, aBaud); |
|
102 TheConsole.Write(outBuf); |
|
103 |
|
104 SerialDownloadPort = aPort; |
|
105 SerialBaud = baudRate; |
|
106 WriteConfig(); |
|
107 Restart(KtRestartReasonHardRestart); |
|
108 } |
|
109 |
|
110 #ifdef __SUPPORT_FLASH_REPRO__ |
|
111 void mainmenu_bootnor(TUint32, TUint32) |
|
112 { |
|
113 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
114 TheConsole.Write(_L("Attempting to boot from")); |
|
115 TheConsole.SetCursorPosAbs(TPoint(0,16)); |
|
116 TheConsole.Write(_L("onboard NOR flash...")); |
|
117 // This will restart the board very quickly - pause a second to let the LCD |
|
118 // controler display the message |
|
119 User::After(10000); |
|
120 Restart(KtRestartReasonBootRestart | KtRestartReasonNORImage); |
|
121 } |
|
122 #endif |
|
123 |
|
124 #ifdef __SUPPORT_MEMORY_TEST__ |
|
125 void mainmenu_memtest(TUint32, TUint32) |
|
126 { |
|
127 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
128 TheConsole.Write(_L("Starting Memory Test")); |
|
129 TheConsole.SetCursorPosAbs(TPoint(0,16)); |
|
130 TheConsole.Write(_L("screen will decay...")); |
|
131 // This will restart the board very quickly - pause a second to let the LCD |
|
132 // controler display the message |
|
133 User::After(10000); |
|
134 Restart(KtRestartCustomRestartMemCheck); |
|
135 } |
|
136 #endif |
|
137 |
|
138 #ifdef __SUPPORT_FLASH_NAND__ |
|
139 void mainmenu_bootnand(TUint32, TUint32) |
|
140 { |
|
141 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
142 TheConsole.Write(_L("Attempting to boot from")); |
|
143 TheConsole.SetCursorPosAbs(TPoint(0,16)); |
|
144 TheConsole.Write(_L("onboard NAND flash...")); |
|
145 // This will restart the board very quickly - pause a moment to let the LCD |
|
146 // controler display the message |
|
147 User::After(10000); |
|
148 Restart(KtRestartReasonBootRestart | KtRestartReasonNANDImage); |
|
149 } |
|
150 #endif |
|
151 |
|
152 #ifdef __SUPPORT_FLASH_ONENAND__ |
|
153 LOCAL_C void mainmenu_bootonenand(TUint32, TUint32) |
|
154 { |
|
155 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
156 TheConsole.Write(_L("Attempting to boot from")); |
|
157 TheConsole.SetCursorPosAbs(TPoint(0,16)); |
|
158 TheConsole.Write(_L("onboard OneNAND flash...")); |
|
159 // This will restart the board very quickly - pause a moment to let the LCD |
|
160 // controller display the message |
|
161 User::After(10000); |
|
162 Restart(KtRestartReasonBootRestart | KtRestartReasonONENANDImage); |
|
163 } |
|
164 #endif |
|
165 |
|
166 #ifdef __USE_EMBEDDED_MMC_SD__ |
|
167 LOCAL_C void mainmenu_bootmmc(TUint32, TUint32) |
|
168 { |
|
169 TheConsole.SetCursorPosAbs(TPoint(0,15)); |
|
170 TheConsole.Write(_L("Attempting to boot from")); |
|
171 TheConsole.SetCursorPosAbs(TPoint(0,16)); |
|
172 TheConsole.Write(_L("Embedded MMC...")); |
|
173 // This will restart the board very quickly - pause a moment to let the LCD |
|
174 // controller display the message |
|
175 User::After(10000); |
|
176 Restart(KtRestartReasonBootRestart | KtRestartReasonMMCSDImage); |
|
177 } |
|
178 #endif |
|
179 |
|
180 // Example of switching screens |
|
181 // |
|
182 // void mainmenu_gotoautoload() |
|
183 // { |
|
184 // // Change screen |
|
185 // gCurrentScreen = &screens[SCREEN_AUTOLOAD]; |
|
186 // gScreenUpdate=ETrue; |
|
187 // } |
|
188 |
|
189 struct menu_item |
|
190 { |
|
191 TPtrC iTitle; |
|
192 void (*iFn)(TUint32, TUint32); |
|
193 TUint32 iParam1; |
|
194 TUint32 iParam2; |
|
195 }; |
|
196 |
|
197 menu_item mainmenu[] = |
|
198 { |
|
199 // {_L("Autoload mode"), mainmenu_gotoautoload}, |
|
200 #ifdef __USE_USBMS__ |
|
201 {_L("USB Mass Storage mode"), mainmenu_usbboot, 0, 0}, |
|
202 #endif |
|
203 #ifdef __SUPPORT_COM0_115200__ |
|
204 {_L("COM0 @ 115200"), mainmenu_serial, 0, 115200}, |
|
205 #endif |
|
206 #ifdef __SUPPORT_COM0_230400__ |
|
207 {_L("COM0 @ 230400"), mainmenu_serial, 0, 230400}, |
|
208 #endif |
|
209 #ifdef __SUPPORT_COM1_115200__ |
|
210 {_L("COM1 @ 115200"), mainmenu_serial, 1, 115200}, |
|
211 #endif |
|
212 #ifdef __SUPPORT_COM1_230400__ |
|
213 {_L("COM1 @ 230400"), mainmenu_serial, 1, 230400}, |
|
214 #endif |
|
215 #ifdef __SUPPORT_COM2_115200__ |
|
216 {_L("COM2 @ 115200"), mainmenu_serial, 2, 115200}, |
|
217 #endif |
|
218 #ifdef __SUPPORT_COM2_230400__ |
|
219 {_L("COM2 @ 230400"), mainmenu_serial, 2, 230400}, |
|
220 #endif |
|
221 #ifdef __SUPPORT_COM3_115200__ |
|
222 {_L("COM3 @ 115200"), mainmenu_serial, 3, 115200}, |
|
223 #endif |
|
224 #ifdef __SUPPORT_COM3_230400__ |
|
225 {_L("COM3 @ 230400"), mainmenu_serial, 3, 230400}, |
|
226 #endif |
|
227 #ifdef __SUPPORT_COM7_115200__ |
|
228 {_L("COM7 @ 115200"), mainmenu_serial, 7, 115200}, |
|
229 #endif |
|
230 |
|
231 #ifdef __SUPPORT_FLASH_REPRO__ |
|
232 {_L("Try boot NOR flash"), mainmenu_bootnor, 0, 0}, |
|
233 #endif |
|
234 #ifdef __SUPPORT_FLASH_NAND__ |
|
235 {_L("Try boot NAND flash"), mainmenu_bootnand, 0, 0}, |
|
236 #endif |
|
237 #ifdef __SUPPORT_FLASH_ONENAND__ |
|
238 {_L("Try boot OneNAND flash"), mainmenu_bootonenand, 0, 0}, |
|
239 #endif |
|
240 #ifdef __USE_EMBEDDED_MMC_SD__ |
|
241 {_L("Try boot Embedded MMC"), mainmenu_bootmmc, 0, 0}, |
|
242 #endif |
|
243 #ifdef __SUPPORT_MEMORY_TEST__ |
|
244 {_L("Run Memory Test"), mainmenu_memtest, 0, 0}, |
|
245 #endif |
|
246 {_L("The End"), NULL}, // DO NOT REMOVE - array terminator |
|
247 }; |
|
248 |
|
249 TInt mainmenu_items=0; // The number of items in the menu is set up when the menu is drawn |
|
250 TInt mainmenu_idx=0; |
|
251 |
|
252 // autoload screen functions |
|
253 void autoload_displayfn() |
|
254 { |
|
255 TheConsole.ClearScreen(); |
|
256 TheConsole.SetCursorPosAbs(TPoint(0,0)); |
|
257 TheConsole.SetTitle(_L("AUTOLOAD")); |
|
258 TheConsole.Write(_L("AUTOLOADING on Serial.....")); |
|
259 } |
|
260 |
|
261 void autoload_processkey(TConsoleKey &aKey) |
|
262 { |
|
263 TUint code = aKey.Code(); |
|
264 if (aKey.Type() == 0x3) // key down |
|
265 { |
|
266 if ((code == 0x3)||(code == 0x4)) // Direction key enter, or Esc |
|
267 { |
|
268 // Change to menu mode |
|
269 gCurrentScreen = &screens[SCREEN_MENU]; |
|
270 gScreenUpdate=ETrue; |
|
271 } |
|
272 } |
|
273 } |
|
274 |
|
275 // main menu screen functions |
|
276 void menu_displayfn() |
|
277 { |
|
278 TheConsole.ClearScreen(); |
|
279 TheConsole.SetTitle(_L("Bootloader menu")); |
|
280 mainmenu_items=0; |
|
281 for (TInt i=0; mainmenu[i].iFn!=NULL ; i++) |
|
282 { |
|
283 TheConsole.SetCursorPosAbs(TPoint(0,i+1)); |
|
284 if (mainmenu_idx==i) |
|
285 TheConsole.Write(_L("==> ")); |
|
286 else |
|
287 TheConsole.Write(_L(" ")); |
|
288 |
|
289 TBuf<0x2> buf; |
|
290 buf.AppendNum(i); |
|
291 TheConsole.Write(buf); |
|
292 TheConsole.Write(_L(".")); |
|
293 |
|
294 TheConsole.Write(mainmenu[i].iTitle); |
|
295 mainmenu_items++; |
|
296 } |
|
297 TheConsole.SetCursorPosAbs(TPoint(0,14)); |
|
298 TheConsole.Write(_L("============================")); |
|
299 } |
|
300 |
|
301 void menu_processkey(TConsoleKey &aKey) |
|
302 { |
|
303 |
|
304 TUint code=aKey.Code(); |
|
305 TUint type=aKey.Type(); |
|
306 if (type == 0x3) // key down |
|
307 { |
|
308 if (code == 0x3) // Direction key enter |
|
309 { |
|
310 mainmenu[mainmenu_idx].iFn(mainmenu[mainmenu_idx].iParam1, mainmenu[mainmenu_idx].iParam2); |
|
311 } |
|
312 else if (code == 0x11) // Direction key down (portrait) |
|
313 { |
|
314 if (++mainmenu_idx == mainmenu_items) |
|
315 mainmenu_idx=0; |
|
316 gScreenUpdate=ETrue; |
|
317 } |
|
318 else if (code == 0x10) // Direction key up (portrait) |
|
319 { |
|
320 if (--mainmenu_idx<0) |
|
321 mainmenu_idx=mainmenu_items-1; |
|
322 gScreenUpdate=ETrue; |
|
323 } |
|
324 else if ((code >= 0x30) && (code <= 0x39)) |
|
325 { |
|
326 // If a number is entered, select the relevant menu option |
|
327 TUint num=code-0x30; |
|
328 if (num < TUint(mainmenu_items)) |
|
329 { |
|
330 // coverity[overrun-local] |
|
331 // Coverity doesn't consider the comparison against mainmenu_items |
|
332 mainmenu[num].iFn(mainmenu[num].iParam1, mainmenu[num].iParam2); |
|
333 } |
|
334 } |
|
335 } |
|
336 } |
|
337 |
|
338 // Generic key press processor |
|
339 void keystate_processor(TConsoleKey &aKey) |
|
340 { |
|
341 gScreenUpdate=EFalse; |
|
342 gCurrentScreen->iProcessKey(aKey); |
|
343 |
|
344 if (gScreenUpdate) |
|
345 gCurrentScreen->iDisplayFn(); |
|
346 } |
|
347 |
|
348 TInt KeyThreadFn(TAny*) |
|
349 { |
|
350 // Create a console window |
|
351 TheConsole.Init(_L(""),TSize(KConsFullScreen,KConsFullScreen)); |
|
352 // Suppress cursor, stop any resizing, ensure that we get RAW events from |
|
353 // the console which means people can't dick with the screen |
|
354 TheConsole.Control(_L("-Cursor -Aresize +Raw")); |
|
355 |
|
356 while(1) |
|
357 { |
|
358 TConsoleKey key; |
|
359 TheConsole.Read(key); |
|
360 //RDebug::Print(_L("code 0x%x\n"), key.Code()); |
|
361 //RDebug::Print(_L("type 0x%x\n"), key.Type()); |
|
362 //RDebug::Print(_L("mods 0x%x\n"), key.Modifiers()); |
|
363 keystate_processor(key); |
|
364 } |
|
365 } |
|
366 |
|
367 ////////////////////////////////////////////////////////////////////////////// |
|
368 // |
|
369 // Application entry point |
|
370 // |
|
371 ////////////////////////////////////////////////////////////////////////////// |
|
372 GLDEF_C void StartMenu() |
|
373 { |
|
374 TInt r = KErrUnknown; |
|
375 |
|
376 // Create thread for console and key events |
|
377 r = TheKeyThread.Create(_L("keythread"),KeyThreadFn,KDefaultStackSize,0x200,0x200,(TAny*)NULL,EOwnerProcess); |
|
378 if (r != KErrNone) |
|
379 { |
|
380 RDebug::Print(_L("FAULT: thread create %d\r\n"),r); |
|
381 BOOT_FAULT(); |
|
382 } |
|
383 TheKeyThread.Resume(); |
|
384 |
|
385 // Pause slightly to let the console draw before continuing |
|
386 User::After(100000); |
|
387 } |
|
388 |
|
389 GLDEF_C void EnableMenu() |
|
390 { |
|
391 // RDebug::Print(_L("Enable\r\n")); |
|
392 // Touching TheConsole is not allowed from this context |
|
393 // TheConsole.Control(_L("+Raw")); |
|
394 } |
|
395 |
|
396 GLDEF_C void DisableMenu() |
|
397 { |
|
398 // RDebug::Print(_L("Disable\r\n")); |
|
399 // Touching TheConsole is not allowed from this context |
|
400 // TheConsole.Control(_L("-Raw")); |
|
401 } |