fix m200v4 simulator.
[kugel-rb.git] / apps / main.c
blob4e66a851f16d0f623c0ef3abc38cd616b495dc00
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 "gwps.h"
56 #include "playlist.h"
57 #include "buffer.h"
58 #include "rolo.h"
59 #include "screens.h"
60 #include "power.h"
61 #include "talk.h"
62 #include "plugin.h"
63 #include "misc.h"
64 #include "dircache.h"
65 #ifdef HAVE_TAGCACHE
66 #include "tagcache.h"
67 #include "tagtree.h"
68 #endif
69 #include "lang.h"
70 #include "string.h"
71 #include "splash.h"
72 #include "eeprom_settings.h"
73 #include "scrobbler.h"
74 #include "icon.h"
76 #ifdef IPOD_ACCESSORY_PROTOCOL
77 #include "iap.h"
78 #endif
80 #if (CONFIG_CODEC == SWCODEC)
81 #include "playback.h"
82 #endif
83 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
84 #include "pcm_record.h"
85 #endif
87 #ifdef BUTTON_REC
88 #define SETTINGS_RESET BUTTON_REC
89 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
90 #define SETTINGS_RESET BUTTON_A
91 #endif
93 #if CONFIG_TUNER
94 #include "radio.h"
95 #endif
96 #if (CONFIG_STORAGE & STORAGE_MMC)
97 #include "ata_mmc.h"
98 #endif
100 #ifdef HAVE_REMOTE_LCD
101 #include "lcd-remote.h"
102 #endif
104 #if CONFIG_USBOTG == USBOTG_ISP1362
105 #include "isp1362.h"
106 #endif
108 #if CONFIG_USBOTG == USBOTG_M5636
109 #include "m5636.h"
110 #endif
112 #include "cuesheet.h"
114 #ifdef SIMULATOR
115 #include "system-sdl.h"
116 #endif
118 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
120 const char appsversion[]=APPSVERSION;
122 static void init(void);
124 #ifdef SIMULATOR
125 void app_main(void)
126 #else
127 static void app_main(void)
128 #endif
130 int i;
131 init();
132 FOR_NB_SCREENS(i)
134 screens[i].clear_display();
135 screens[i].update();
137 tree_gui_init();
138 #ifdef HAVE_TOUCHSCREEN
139 touchscreen_set_mode(TOUCHSCREEN_BUTTON);
140 #endif
141 viewportmanager_set_statusbar(true);
142 add_event(GUI_EVENT_STATUSBAR_TOGGLE, false,
143 viewportmanager_statusbar_changed);
144 root_menu();
147 static int init_dircache(bool preinit)
149 #ifdef HAVE_DIRCACHE
150 int result = 0;
151 bool clear = false;
153 if (preinit)
154 dircache_init();
156 if (!global_settings.dircache)
157 return 0;
159 # ifdef HAVE_EEPROM_SETTINGS
160 if (firmware_settings.initialized && firmware_settings.disk_clean
161 && preinit)
163 result = dircache_load();
165 if (result < 0)
167 firmware_settings.disk_clean = false;
168 if (global_status.dircache_size <= 0)
170 /* This will be in default language, settings are not
171 applied yet. Not really any easy way to fix that. */
172 splash(0, str(LANG_SCANNING_DISK));
173 clear = true;
176 dircache_build(global_status.dircache_size);
179 else
180 # endif
182 if (preinit)
183 return -1;
185 if (!dircache_is_enabled()
186 && !dircache_is_initializing())
188 if (global_status.dircache_size <= 0)
190 splash(0, str(LANG_SCANNING_DISK));
191 clear = true;
193 result = dircache_build(global_status.dircache_size);
196 if (result < 0)
198 /* Initialization of dircache failed. Manual action is
199 * necessary to enable dircache again.
201 splashf(0, "Dircache failed, disabled. Result: %d", result);
202 global_settings.dircache = false;
207 if (clear)
209 backlight_on();
210 show_logo();
211 global_status.dircache_size = dircache_get_cache_size();
212 status_save();
215 return result;
216 #else
217 (void)preinit;
218 return 0;
219 #endif
222 #ifdef HAVE_TAGCACHE
223 static void init_tagcache(void)
225 bool clear = false;
227 tagcache_init();
229 while (!tagcache_is_initialized())
231 #ifdef HAVE_LCD_CHARCELLS
232 char buf[32];
233 #endif
234 int ret = tagcache_get_commit_step();
236 if (ret > 0)
238 #if CONFIG_CODEC == SWCODEC
239 /* hwcodec can't use voice here, as the database commit
240 * uses the audio buffer. */
241 static long talked_tick = 0;
242 if(global_settings.talk_menu
243 && (talked_tick == 0
244 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
246 talked_tick = current_tick;
247 talk_id(LANG_TAGCACHE_INIT, false);
248 talk_number(ret, true);
249 talk_id(VOICE_OF, true);
250 talk_number(tagcache_get_max_commit_step(), true);
252 #endif
253 #ifdef HAVE_LCD_BITMAP
254 splashf(0, "%s [%d/%d]",
255 str(LANG_TAGCACHE_INIT), ret,
256 tagcache_get_max_commit_step());
257 #else
258 lcd_double_height(false);
259 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
260 tagcache_get_max_commit_step());
261 lcd_puts(0, 1, buf);
262 lcd_update();
263 #endif
264 clear = true;
266 sleep(HZ/4);
268 tagtree_init();
270 if (clear)
272 backlight_on();
273 show_logo();
276 #endif
278 #ifdef SIMULATOR
280 static void init(void)
282 kernel_init();
283 buffer_init();
284 enable_irq();
285 lcd_init();
286 #ifdef HAVE_REMOTE_LCD
287 lcd_remote_init();
288 #endif
289 font_init();
290 show_logo();
291 button_init();
292 backlight_init();
293 lang_init();
294 #ifdef DEBUG
295 debug_init();
296 #endif
297 /* Must be done before any code uses the multi-screen APi */
298 gui_syncstatusbar_init(&statusbars);
299 storage_init();
300 settings_reset();
301 settings_load(SETTINGS_ALL);
302 gui_sync_wps_init();
303 settings_apply(true);
304 init_dircache(true);
305 init_dircache(false);
306 #ifdef HAVE_TAGCACHE
307 init_tagcache();
308 #endif
309 sleep(HZ/2);
310 tree_mem_init();
311 filetype_init();
312 playlist_init();
314 #if CONFIG_CODEC != SWCODEC
315 mp3_init( global_settings.volume,
316 global_settings.bass,
317 global_settings.treble,
318 global_settings.balance,
319 global_settings.loudness,
320 global_settings.avc,
321 global_settings.channel_config,
322 global_settings.stereo_width,
323 global_settings.mdb_strength,
324 global_settings.mdb_harmonics,
325 global_settings.mdb_center,
326 global_settings.mdb_shape,
327 global_settings.mdb_enable,
328 global_settings.superbass);
330 /* audio_init must to know the size of voice buffer so init voice first */
331 talk_init();
332 #endif /* CONFIG_CODEC != SWCODEC */
334 scrobbler_init();
335 cuesheet_init();
337 audio_init();
338 button_clear_queue(); /* Empty the keyboard buffer */
341 #else
343 static void init(void)
345 int rc;
346 bool mounted = false;
347 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
348 /* if nobody initialized ATA before, I consider this a cold start */
349 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
350 #endif
352 system_init();
353 kernel_init();
355 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
356 set_cpu_frequency(CPUFREQ_NORMAL);
357 #ifdef CPU_COLDFIRE
358 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
359 #endif
360 cpu_boost(true);
361 #endif
363 buffer_init();
365 settings_reset();
367 i2c_init();
369 power_init();
371 enable_irq();
372 #ifdef CPU_ARM
373 enable_fiq();
374 #endif
375 lcd_init();
376 #ifdef HAVE_REMOTE_LCD
377 lcd_remote_init();
378 #endif
379 font_init();
381 show_logo();
382 lang_init();
384 #ifdef DEBUG
385 debug_init();
386 #else
387 #if !defined(HAVE_FMADC) && !(CONFIG_STORAGE & STORAGE_MMC)
388 serial_setup();
389 #endif
390 #endif
392 #if CONFIG_RTC
393 rtc_init();
394 #endif
395 #ifdef HAVE_RTC_RAM
396 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
397 #endif
399 adc_init();
401 usb_init();
402 #if CONFIG_USBOTG == USBOTG_ISP1362
403 isp1362_init();
404 #elif CONFIG_USBOTG == USBOTG_M5636
405 m5636_init();
406 #endif
408 backlight_init();
410 button_init();
412 powermgmt_init();
414 #if CONFIG_TUNER
415 radio_init();
416 #endif
418 /* Must be done before any code uses the multi-screen APi */
419 gui_syncstatusbar_init(&statusbars);
421 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
422 if (coldstart && charger_inserted()
423 && !global_settings.car_adapter_mode
424 #ifdef ATA_POWER_PLAYERSTYLE
425 && !ide_powered() /* relies on probing result from bootloader */
426 #endif
429 rc = charging_screen(); /* display a "charging" screen */
430 if (rc == 1) /* charger removed */
431 power_off();
432 /* "On" pressed or USB connected: proceed */
433 show_logo(); /* again, to provide better visual feedback */
435 #endif
437 rc = storage_init();
438 if(rc)
440 #ifdef HAVE_LCD_BITMAP
441 char str[32];
442 lcd_clear_display();
443 snprintf(str, 31, "ATA error: %d", rc);
444 lcd_puts(0, 1, str);
445 lcd_puts(0, 3, "Press ON to debug");
446 lcd_update();
447 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
448 dbg_ports();
449 #endif
450 panicf("ata: %d", rc);
453 #ifdef HAVE_EEPROM_SETTINGS
454 eeprom_settings_init();
455 #endif
457 usb_start_monitoring();
458 #ifndef HAVE_USBSTACK
459 while (usb_detect() == USB_INSERTED)
461 #ifdef HAVE_EEPROM_SETTINGS
462 firmware_settings.disk_clean = false;
463 #endif
464 /* enter USB mode early, before trying to mount */
465 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
466 #if (CONFIG_STORAGE & STORAGE_MMC)
467 if (!mmc_touched() ||
468 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
469 #endif
471 usb_screen();
472 mounted = true; /* mounting done @ end of USB mode */
474 #ifdef HAVE_USB_POWER
475 if (usb_powered()) /* avoid deadlock */
476 break;
477 #endif
479 #endif
481 if (!mounted)
483 rc = disk_mount_all();
484 if (rc<=0)
486 lcd_clear_display();
487 lcd_puts(0, 0, "No partition");
488 lcd_puts(0, 1, "found.");
489 #ifdef HAVE_LCD_BITMAP
490 lcd_puts(0, 2, "Insert USB cable");
491 lcd_puts(0, 3, "and fix it.");
492 #endif
493 lcd_update();
495 while(button_get(true) != SYS_USB_CONNECTED) {};
496 usb_screen();
497 system_reboot();
501 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
502 (CONFIG_KEYPAD == IRIVER_H10_PAD)
503 #ifdef SETTINGS_RESET
504 /* Reset settings if holding the reset button. (Rec on Archos,
505 A on Gigabeat) */
506 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
507 #else
508 /* Reset settings if the hold button is turned on */
509 if (button_hold())
510 #endif
512 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
513 settings_reset();
515 else
516 #endif
517 settings_load(SETTINGS_ALL);
519 if (init_dircache(true) < 0)
521 #ifdef HAVE_TAGCACHE
522 remove(TAGCACHE_STATEFILE);
523 #endif
526 gui_sync_wps_init();
527 settings_apply(true);
528 init_dircache(false);
529 #ifdef HAVE_TAGCACHE
530 init_tagcache();
531 #endif
533 #ifdef HAVE_EEPROM_SETTINGS
534 if (firmware_settings.initialized)
536 /* In case we crash. */
537 firmware_settings.disk_clean = false;
538 eeprom_settings_store();
540 #endif
541 status_init();
542 playlist_init();
543 tree_mem_init();
544 filetype_init();
545 scrobbler_init();
546 cuesheet_init();
548 #if CONFIG_CODEC != SWCODEC
549 /* No buffer allocation (see buffer.c) may take place after the call to
550 audio_init() since the mpeg thread takes the rest of the buffer space */
551 mp3_init( global_settings.volume,
552 global_settings.bass,
553 global_settings.treble,
554 global_settings.balance,
555 global_settings.loudness,
556 global_settings.avc,
557 global_settings.channel_config,
558 global_settings.stereo_width,
559 global_settings.mdb_strength,
560 global_settings.mdb_harmonics,
561 global_settings.mdb_center,
562 global_settings.mdb_shape,
563 global_settings.mdb_enable,
564 global_settings.superbass);
566 /* audio_init must to know the size of voice buffer so init voice first */
567 talk_init();
568 #endif /* CONFIG_CODEC != SWCODEC */
570 audio_init();
572 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
573 pcm_rec_init();
574 #endif
576 /* runtime database has to be initialized after audio_init() */
577 cpu_boost(false);
579 #ifdef AUTOROCK
581 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
583 if(file_exists(filename)) /* no complaint if it doesn't exist */
585 plugin_load((char*)filename, NULL); /* start if it does */
588 #endif /* #ifdef AUTOROCK */
590 #if CONFIG_CHARGING
591 car_adapter_mode_init();
592 #endif
593 #ifdef IPOD_ACCESSORY_PROTOCOL
594 iap_setup(global_settings.serial_bitrate);
595 #endif
596 #ifdef HAVE_ACCESSORY_SUPPLY
597 accessory_supply_set(global_settings.accessory_supply);
598 #endif
601 #ifdef CPU_PP
602 void cop_main(void)
604 /* This is the entry point for the coprocessor
605 Anyone not running an upgraded bootloader will never reach this point,
606 so it should not be assumed that the coprocessor be usable even on
607 platforms which support it.
609 A kernel thread is initially setup on the coprocessor and immediately
610 destroyed for purposes of continuity. The cop sits idle until at least
611 one thread exists on it. */
613 /* 3G doesn't have Rolo or dual core support yet */
614 #if NUM_CORES > 1
615 system_init();
616 kernel_init();
617 /* This should never be reached */
618 #endif
619 while(1) {
620 sleep_core(COP);
623 #endif /* CPU_PP */
625 int main(void)
627 app_main();
629 while(1) {
630 #if (CONFIG_LED == LED_REAL)
631 led(true); sleep(HZ/10);
632 led(false); sleep(HZ/10);
633 #endif
635 return 0;
637 #endif