usb_keypad_mode shouldn't depend on SIMULATOR
[kugel-rb.git] / apps / main.c
blob27641abe2dc53a683d42cb88b1d0952513b9a4cb
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "config.h"
23 #include "storage.h"
24 #include "disk.h"
25 #include "fat.h"
26 #include "lcd.h"
27 #include "rtc.h"
28 #include "debug.h"
29 #include "led.h"
30 #include "kernel.h"
31 #include "button.h"
32 #include "tree.h"
33 #include "filetypes.h"
34 #include "panic.h"
35 #include "menu.h"
36 #include "system.h"
37 #include "usb.h"
38 #include "powermgmt.h"
39 #include "adc.h"
40 #include "i2c.h"
41 #ifndef DEBUG
42 #include "serial.h"
43 #endif
44 #include "audio.h"
45 #include "mp3_playback.h"
46 #include "thread.h"
47 #include "settings.h"
48 #include "backlight.h"
49 #include "status.h"
50 #include "debug_menu.h"
51 #include "version.h"
52 #include "sprintf.h"
53 #include "font.h"
54 #include "language.h"
55 #include "wps.h"
56 #include "playlist.h"
57 #include "buffer.h"
58 #include "rolo.h"
59 #include "screens.h"
60 #include "usb_screen.h"
61 #include "power.h"
62 #include "talk.h"
63 #include "plugin.h"
64 #include "misc.h"
65 #include "dircache.h"
66 #ifdef HAVE_TAGCACHE
67 #include "tagcache.h"
68 #include "tagtree.h"
69 #endif
70 #include "lang.h"
71 #include "string.h"
72 #include "splash.h"
73 #include "eeprom_settings.h"
74 #include "scrobbler.h"
75 #include "icon.h"
76 #include "viewport.h"
77 #include "statusbar-skinned.h"
79 #ifdef IPOD_ACCESSORY_PROTOCOL
80 #include "iap.h"
81 #endif
83 #if (CONFIG_CODEC == SWCODEC)
84 #include "playback.h"
85 #include "tdspeed.h"
86 #endif
87 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
88 #include "pcm_record.h"
89 #endif
91 #ifdef BUTTON_REC
92 #define SETTINGS_RESET BUTTON_REC
93 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
94 #define SETTINGS_RESET BUTTON_A
95 #endif
97 #if CONFIG_TUNER
98 #include "radio.h"
99 #endif
100 #if (CONFIG_STORAGE & STORAGE_MMC)
101 #include "ata_mmc.h"
102 #endif
104 #ifdef HAVE_REMOTE_LCD
105 #include "lcd-remote.h"
106 #endif
108 #if CONFIG_USBOTG == USBOTG_ISP1362
109 #include "isp1362.h"
110 #endif
112 #if CONFIG_USBOTG == USBOTG_M5636
113 #include "m5636.h"
114 #endif
116 #ifdef SIMULATOR
117 #include "sim_tasks.h"
118 #include "system-sdl.h"
119 #endif
121 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
123 const char appsversion[]=APPSVERSION;
125 static void init(void);
127 #ifdef SIMULATOR
128 void app_main(void)
129 #else
130 static void app_main(void)
131 #endif
133 int i;
134 init();
135 FOR_NB_SCREENS(i)
137 screens[i].clear_display();
138 screens[i].update();
140 #ifdef HAVE_LCD_BITMAP
141 list_init();
142 #endif
143 tree_gui_init();
144 viewportmanager_init();
145 #ifdef HAVE_USBSTACK
146 /* All threads should be created and public queues registered by now */
147 usb_start_monitoring();
148 #endif
150 #ifdef AUTOROCK
152 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
154 if(file_exists(filename)) /* no complaint if it doesn't exist */
156 plugin_load((char*)filename, NULL); /* start if it does */
159 #endif /* #ifdef AUTOROCK */
161 root_menu();
164 static int init_dircache(bool preinit)
166 #ifdef HAVE_DIRCACHE
167 int result = 0;
168 bool clear = false;
170 if (preinit)
171 dircache_init();
173 if (!global_settings.dircache)
174 return 0;
176 # ifdef HAVE_EEPROM_SETTINGS
177 if (firmware_settings.initialized && firmware_settings.disk_clean
178 && preinit)
180 result = dircache_load();
182 if (result < 0)
184 firmware_settings.disk_clean = false;
185 if (global_status.dircache_size <= 0)
187 /* This will be in default language, settings are not
188 applied yet. Not really any easy way to fix that. */
189 splash(0, str(LANG_SCANNING_DISK));
190 clear = true;
193 dircache_build(global_status.dircache_size);
196 else
197 # endif
199 if (preinit)
200 return -1;
202 if (!dircache_is_enabled()
203 && !dircache_is_initializing())
205 if (global_status.dircache_size <= 0)
207 splash(0, str(LANG_SCANNING_DISK));
208 clear = true;
210 result = dircache_build(global_status.dircache_size);
213 if (result < 0)
215 /* Initialization of dircache failed. Manual action is
216 * necessary to enable dircache again.
218 splashf(0, "Dircache failed, disabled. Result: %d", result);
219 global_settings.dircache = false;
223 if (clear)
225 backlight_on();
226 show_logo();
227 global_status.dircache_size = dircache_get_cache_size();
228 status_save();
231 return result;
232 #else
233 (void)preinit;
234 return 0;
235 #endif
238 #ifdef HAVE_TAGCACHE
239 static void init_tagcache(void)
241 bool clear = false;
243 tagcache_init();
245 while (!tagcache_is_initialized())
247 int ret = tagcache_get_commit_step();
249 if (ret > 0)
251 #if CONFIG_CODEC == SWCODEC
252 /* hwcodec can't use voice here, as the database commit
253 * uses the audio buffer. */
254 static long talked_tick = 0;
255 if(global_settings.talk_menu
256 && (talked_tick == 0
257 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
259 talked_tick = current_tick;
260 talk_id(LANG_TAGCACHE_INIT, false);
261 talk_number(ret, true);
262 talk_id(VOICE_OF, true);
263 talk_number(tagcache_get_max_commit_step(), true);
265 #endif
266 #ifdef HAVE_LCD_BITMAP
267 if (lang_is_rtl())
269 splashf(0, "[%d/%d] %s", ret, tagcache_get_max_commit_step(),
270 str(LANG_TAGCACHE_INIT));
272 else
274 splashf(0, "%s [%d/%d]", str(LANG_TAGCACHE_INIT), ret,
275 tagcache_get_max_commit_step());
277 #else
278 lcd_double_height(false);
279 lcd_putsf(0, 1, " DB [%d/%d]", ret,
280 tagcache_get_max_commit_step());
281 lcd_update();
282 #endif
283 clear = true;
285 sleep(HZ/4);
287 tagtree_init();
289 if (clear)
291 backlight_on();
292 show_logo();
295 #endif
297 #ifdef SIMULATOR
299 static void init(void)
301 kernel_init();
302 buffer_init();
303 enable_irq();
304 lcd_init();
305 #ifdef HAVE_REMOTE_LCD
306 lcd_remote_init();
307 #endif
308 font_init();
309 show_logo();
310 button_init();
311 backlight_init();
312 sim_tasks_init();
313 lang_init(core_language_builtin, language_strings,
314 LANG_LAST_INDEX_IN_ARRAY);
315 #ifdef DEBUG
316 debug_init();
317 #endif
318 /* Must be done before any code uses the multi-screen API */
319 gui_syncstatusbar_init(&statusbars);
320 storage_init();
321 settings_reset();
322 settings_load(SETTINGS_ALL);
323 gui_sync_wps_init();
324 sb_skin_init();
325 settings_apply(true);
326 init_dircache(true);
327 init_dircache(false);
328 #ifdef HAVE_TAGCACHE
329 init_tagcache();
330 #endif
331 sleep(HZ/2);
332 tree_mem_init();
333 filetype_init();
334 playlist_init();
336 #if CONFIG_CODEC != SWCODEC
337 mp3_init( global_settings.volume,
338 global_settings.bass,
339 global_settings.treble,
340 global_settings.balance,
341 global_settings.loudness,
342 global_settings.avc,
343 global_settings.channel_config,
344 global_settings.stereo_width,
345 global_settings.mdb_strength,
346 global_settings.mdb_harmonics,
347 global_settings.mdb_center,
348 global_settings.mdb_shape,
349 global_settings.mdb_enable,
350 global_settings.superbass);
352 /* audio_init must to know the size of voice buffer so init voice first */
353 talk_init();
354 #endif /* CONFIG_CODEC != SWCODEC */
356 scrobbler_init();
357 #if CONFIG_CODEC == SWCODEC
358 tdspeed_init();
359 #endif /* CONFIG_CODEC == SWCODEC */
361 audio_init();
362 button_clear_queue(); /* Empty the keyboard buffer */
365 #else
367 static void init(void)
369 int rc;
370 bool mounted = false;
371 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
372 /* if nobody initialized ATA before, I consider this a cold start */
373 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
374 #endif
376 system_init();
377 kernel_init();
379 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
380 set_cpu_frequency(CPUFREQ_NORMAL);
381 #ifdef CPU_COLDFIRE
382 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
383 #endif
384 cpu_boost(true);
385 #endif
387 buffer_init();
389 settings_reset();
391 i2c_init();
393 power_init();
395 enable_irq();
396 #ifdef CPU_ARM
397 enable_fiq();
398 #endif
399 lcd_init();
400 #ifdef HAVE_REMOTE_LCD
401 lcd_remote_init();
402 #endif
403 font_init();
405 show_logo();
406 lang_init(core_language_builtin, language_strings,
407 LANG_LAST_INDEX_IN_ARRAY);
409 #ifdef DEBUG
410 debug_init();
411 #else
412 #ifdef HAVE_SERIAL
413 serial_setup();
414 #endif
415 #endif
417 #if CONFIG_RTC
418 rtc_init();
419 #endif
420 #ifdef HAVE_RTC_RAM
421 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
422 #endif
424 adc_init();
426 usb_init();
427 #if CONFIG_USBOTG == USBOTG_ISP1362
428 isp1362_init();
429 #elif CONFIG_USBOTG == USBOTG_M5636
430 m5636_init();
431 #endif
433 backlight_init();
435 button_init();
437 powermgmt_init();
439 #if CONFIG_TUNER
440 radio_init();
441 #endif
443 /* Must be done before any code uses the multi-screen API */
444 gui_syncstatusbar_init(&statusbars);
446 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
447 /* charger_inserted() can't be used here because power_thread()
448 hasn't checked power_input_status() yet */
449 if (coldstart && (power_input_status() & POWER_INPUT_MAIN_CHARGER)
450 && !global_settings.car_adapter_mode
451 #ifdef ATA_POWER_PLAYERSTYLE
452 && !ide_powered() /* relies on probing result from bootloader */
453 #endif
456 rc = charging_screen(); /* display a "charging" screen */
457 if (rc == 1) /* charger removed */
458 power_off();
459 /* "On" pressed or USB connected: proceed */
460 show_logo(); /* again, to provide better visual feedback */
462 #endif
464 rc = storage_init();
465 if(rc)
467 #ifdef HAVE_LCD_BITMAP
468 lcd_clear_display();
469 lcd_putsf(0, 1, "ATA error: %d", rc);
470 lcd_puts(0, 3, "Press ON to debug");
471 lcd_update();
472 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
473 dbg_ports();
474 #endif
475 panicf("ata: %d", rc);
478 #ifdef HAVE_EEPROM_SETTINGS
479 eeprom_settings_init();
480 #endif
482 #ifndef HAVE_USBSTACK
483 usb_start_monitoring();
484 while (usb_detect() == USB_INSERTED)
486 #ifdef HAVE_EEPROM_SETTINGS
487 firmware_settings.disk_clean = false;
488 #endif
489 /* enter USB mode early, before trying to mount */
490 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
491 #if (CONFIG_STORAGE & STORAGE_MMC)
492 if (!mmc_touched() ||
493 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
494 #endif
496 gui_usb_screen_run();
497 mounted = true; /* mounting done @ end of USB mode */
499 #ifdef HAVE_USB_POWER
500 if (usb_powered()) /* avoid deadlock */
501 break;
502 #endif
504 #endif
506 if (!mounted)
508 rc = disk_mount_all();
509 if (rc<=0)
511 lcd_clear_display();
512 lcd_puts(0, 0, "No partition");
513 lcd_puts(0, 1, "found.");
514 #ifdef HAVE_LCD_BITMAP
515 lcd_puts(0, 2, "Insert USB cable");
516 lcd_puts(0, 3, "and fix it.");
517 #endif
518 lcd_update();
520 while(button_get(true) != SYS_USB_CONNECTED) {};
521 gui_usb_screen_run();
522 system_reboot();
526 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
527 (CONFIG_KEYPAD == IRIVER_H10_PAD)
528 #ifdef SETTINGS_RESET
529 /* Reset settings if holding the reset button. (Rec on Archos,
530 A on Gigabeat) */
531 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
532 #else
533 /* Reset settings if the hold button is turned on */
534 if (button_hold())
535 #endif
537 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
538 settings_reset();
540 else
541 #endif
542 settings_load(SETTINGS_ALL);
544 if (init_dircache(true) < 0)
546 #ifdef HAVE_TAGCACHE
547 remove(TAGCACHE_STATEFILE);
548 #endif
551 gui_sync_wps_init();
552 sb_skin_init();
553 settings_apply(true);
554 init_dircache(false);
555 #ifdef HAVE_TAGCACHE
556 init_tagcache();
557 #endif
559 #ifdef HAVE_EEPROM_SETTINGS
560 if (firmware_settings.initialized)
562 /* In case we crash. */
563 firmware_settings.disk_clean = false;
564 eeprom_settings_store();
566 #endif
567 playlist_init();
568 tree_mem_init();
569 filetype_init();
570 scrobbler_init();
571 #if CONFIG_CODEC == SWCODEC
572 tdspeed_init();
573 #endif /* CONFIG_CODEC == SWCODEC */
575 #if CONFIG_CODEC != SWCODEC
576 /* No buffer allocation (see buffer.c) may take place after the call to
577 audio_init() since the mpeg thread takes the rest of the buffer space */
578 mp3_init( global_settings.volume,
579 global_settings.bass,
580 global_settings.treble,
581 global_settings.balance,
582 global_settings.loudness,
583 global_settings.avc,
584 global_settings.channel_config,
585 global_settings.stereo_width,
586 global_settings.mdb_strength,
587 global_settings.mdb_harmonics,
588 global_settings.mdb_center,
589 global_settings.mdb_shape,
590 global_settings.mdb_enable,
591 global_settings.superbass);
593 /* audio_init must to know the size of voice buffer so init voice first */
594 talk_init();
595 #endif /* CONFIG_CODEC != SWCODEC */
597 audio_init();
599 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
600 pcm_rec_init();
601 #endif
603 /* runtime database has to be initialized after audio_init() */
604 cpu_boost(false);
606 #if CONFIG_CHARGING
607 car_adapter_mode_init();
608 #endif
609 #ifdef IPOD_ACCESSORY_PROTOCOL
610 iap_setup(global_settings.serial_bitrate);
611 #endif
612 #ifdef HAVE_ACCESSORY_SUPPLY
613 accessory_supply_set(global_settings.accessory_supply);
614 #endif
617 #ifdef CPU_PP
618 void cop_main(void)
620 /* This is the entry point for the coprocessor
621 Anyone not running an upgraded bootloader will never reach this point,
622 so it should not be assumed that the coprocessor be usable even on
623 platforms which support it.
625 A kernel thread is initially setup on the coprocessor and immediately
626 destroyed for purposes of continuity. The cop sits idle until at least
627 one thread exists on it. */
629 /* 3G doesn't have Rolo or dual core support yet */
630 #if NUM_CORES > 1
631 system_init();
632 kernel_init();
633 /* This should never be reached */
634 #endif
635 while(1) {
636 sleep_core(COP);
639 #endif /* CPU_PP */
641 int main(void)
643 app_main();
645 while(1) {
646 #if (CONFIG_LED == LED_REAL)
647 led(true); sleep(HZ/10);
648 led(false); sleep(HZ/10);
649 #endif
651 return 0;
653 #endif