Flyspray: FS#10326
[kugel-rb.git] / apps / main.c
bloba7c8bef6c08649b1a533cf603261dce8c642bb40
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 #include "tdspeed.h"
83 #endif
84 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
85 #include "pcm_record.h"
86 #endif
88 #ifdef BUTTON_REC
89 #define SETTINGS_RESET BUTTON_REC
90 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
91 #define SETTINGS_RESET BUTTON_A
92 #endif
94 #if CONFIG_TUNER
95 #include "radio.h"
96 #endif
97 #if (CONFIG_STORAGE & STORAGE_MMC)
98 #include "ata_mmc.h"
99 #endif
101 #ifdef HAVE_REMOTE_LCD
102 #include "lcd-remote.h"
103 #endif
105 #if CONFIG_USBOTG == USBOTG_ISP1362
106 #include "isp1362.h"
107 #endif
109 #if CONFIG_USBOTG == USBOTG_M5636
110 #include "m5636.h"
111 #endif
113 #include "cuesheet.h"
115 #ifdef SIMULATOR
116 #include "sim_tasks.h"
117 #include "system-sdl.h"
118 #endif
120 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
122 const char appsversion[]=APPSVERSION;
124 static void init(void);
126 #ifdef SIMULATOR
127 void app_main(void)
128 #else
129 static void app_main(void)
130 #endif
132 int i;
133 init();
134 FOR_NB_SCREENS(i)
136 screens[i].clear_display();
137 screens[i].update();
139 tree_gui_init();
140 viewportmanager_set_statusbar(VP_SB_ALLSCREENS);
141 add_event(GUI_EVENT_STATUSBAR_TOGGLE, false,
142 viewportmanager_statusbar_changed);
143 #ifdef HAVE_USBSTACK
144 /* All threads should be created and public queues registered by now */
145 usb_start_monitoring();
146 #endif
147 root_menu();
150 static int init_dircache(bool preinit)
152 #ifdef HAVE_DIRCACHE
153 int result = 0;
154 bool clear = false;
156 if (preinit)
157 dircache_init();
159 if (!global_settings.dircache)
160 return 0;
162 # ifdef HAVE_EEPROM_SETTINGS
163 if (firmware_settings.initialized && firmware_settings.disk_clean
164 && preinit)
166 result = dircache_load();
168 if (result < 0)
170 firmware_settings.disk_clean = false;
171 if (global_status.dircache_size <= 0)
173 /* This will be in default language, settings are not
174 applied yet. Not really any easy way to fix that. */
175 splash(0, str(LANG_SCANNING_DISK));
176 clear = true;
179 dircache_build(global_status.dircache_size);
182 else
183 # endif
185 if (preinit)
186 return -1;
188 if (!dircache_is_enabled()
189 && !dircache_is_initializing())
191 if (global_status.dircache_size <= 0)
193 splash(0, str(LANG_SCANNING_DISK));
194 clear = true;
196 result = dircache_build(global_status.dircache_size);
199 if (result < 0)
201 /* Initialization of dircache failed. Manual action is
202 * necessary to enable dircache again.
204 splashf(0, "Dircache failed, disabled. Result: %d", result);
205 global_settings.dircache = false;
210 if (clear)
212 backlight_on();
213 show_logo();
214 global_status.dircache_size = dircache_get_cache_size();
215 status_save();
218 return result;
219 #else
220 (void)preinit;
221 return 0;
222 #endif
225 #ifdef HAVE_TAGCACHE
226 static void init_tagcache(void)
228 bool clear = false;
230 tagcache_init();
232 while (!tagcache_is_initialized())
234 #ifdef HAVE_LCD_CHARCELLS
235 char buf[32];
236 #endif
237 int ret = tagcache_get_commit_step();
239 if (ret > 0)
241 #if CONFIG_CODEC == SWCODEC
242 /* hwcodec can't use voice here, as the database commit
243 * uses the audio buffer. */
244 static long talked_tick = 0;
245 if(global_settings.talk_menu
246 && (talked_tick == 0
247 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
249 talked_tick = current_tick;
250 talk_id(LANG_TAGCACHE_INIT, false);
251 talk_number(ret, true);
252 talk_id(VOICE_OF, true);
253 talk_number(tagcache_get_max_commit_step(), true);
255 #endif
256 #ifdef HAVE_LCD_BITMAP
257 splashf(0, "%s [%d/%d]",
258 str(LANG_TAGCACHE_INIT), ret,
259 tagcache_get_max_commit_step());
260 #else
261 lcd_double_height(false);
262 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
263 tagcache_get_max_commit_step());
264 lcd_puts(0, 1, buf);
265 lcd_update();
266 #endif
267 clear = true;
269 sleep(HZ/4);
271 tagtree_init();
273 if (clear)
275 backlight_on();
276 show_logo();
279 #endif
281 #ifdef SIMULATOR
283 static void init(void)
285 kernel_init();
286 buffer_init();
287 enable_irq();
288 lcd_init();
289 #ifdef HAVE_REMOTE_LCD
290 lcd_remote_init();
291 #endif
292 font_init();
293 show_logo();
294 button_init();
295 backlight_init();
296 sim_tasks_init();
297 lang_init();
298 #ifdef DEBUG
299 debug_init();
300 #endif
301 /* Must be done before any code uses the multi-screen APi */
302 gui_syncstatusbar_init(&statusbars);
303 storage_init();
304 settings_reset();
305 settings_load(SETTINGS_ALL);
306 gui_sync_wps_init();
307 settings_apply(true);
308 init_dircache(true);
309 init_dircache(false);
310 #ifdef HAVE_TAGCACHE
311 init_tagcache();
312 #endif
313 sleep(HZ/2);
314 tree_mem_init();
315 filetype_init();
316 playlist_init();
318 #if CONFIG_CODEC != SWCODEC
319 mp3_init( global_settings.volume,
320 global_settings.bass,
321 global_settings.treble,
322 global_settings.balance,
323 global_settings.loudness,
324 global_settings.avc,
325 global_settings.channel_config,
326 global_settings.stereo_width,
327 global_settings.mdb_strength,
328 global_settings.mdb_harmonics,
329 global_settings.mdb_center,
330 global_settings.mdb_shape,
331 global_settings.mdb_enable,
332 global_settings.superbass);
334 /* audio_init must to know the size of voice buffer so init voice first */
335 talk_init();
336 #endif /* CONFIG_CODEC != SWCODEC */
338 scrobbler_init();
339 cuesheet_init();
340 #if CONFIG_CODEC == SWCODEC
341 tdspeed_init();
342 #endif /* CONFIG_CODEC == SWCODEC */
344 audio_init();
345 button_clear_queue(); /* Empty the keyboard buffer */
348 #else
350 static void init(void)
352 int rc;
353 bool mounted = false;
354 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
355 /* if nobody initialized ATA before, I consider this a cold start */
356 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
357 #endif
359 system_init();
360 kernel_init();
362 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
363 set_cpu_frequency(CPUFREQ_NORMAL);
364 #ifdef CPU_COLDFIRE
365 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
366 #endif
367 cpu_boost(true);
368 #endif
370 buffer_init();
372 settings_reset();
374 i2c_init();
376 power_init();
378 enable_irq();
379 #ifdef CPU_ARM
380 enable_fiq();
381 #endif
382 lcd_init();
383 #ifdef HAVE_REMOTE_LCD
384 lcd_remote_init();
385 #endif
386 font_init();
388 show_logo();
389 lang_init();
391 #ifdef DEBUG
392 debug_init();
393 #else
394 #ifdef HAVE_SERIAL
395 serial_setup();
396 #endif
397 #endif
399 #if CONFIG_RTC
400 rtc_init();
401 #endif
402 #ifdef HAVE_RTC_RAM
403 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
404 #endif
406 adc_init();
408 usb_init();
409 #if CONFIG_USBOTG == USBOTG_ISP1362
410 isp1362_init();
411 #elif CONFIG_USBOTG == USBOTG_M5636
412 m5636_init();
413 #endif
415 backlight_init();
417 button_init();
419 powermgmt_init();
421 #if CONFIG_TUNER
422 radio_init();
423 #endif
425 /* Must be done before any code uses the multi-screen APi */
426 gui_syncstatusbar_init(&statusbars);
428 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
429 /* charger_inserted() can't be used here because power_thread()
430 hasn't checked power_input_status() yet */
431 if (coldstart && (power_input_status() & POWER_INPUT_MAIN_CHARGER)
432 && !global_settings.car_adapter_mode
433 #ifdef ATA_POWER_PLAYERSTYLE
434 && !ide_powered() /* relies on probing result from bootloader */
435 #endif
438 rc = charging_screen(); /* display a "charging" screen */
439 if (rc == 1) /* charger removed */
440 power_off();
441 /* "On" pressed or USB connected: proceed */
442 show_logo(); /* again, to provide better visual feedback */
444 #endif
446 rc = storage_init();
447 if(rc)
449 #ifdef HAVE_LCD_BITMAP
450 char str[32];
451 lcd_clear_display();
452 snprintf(str, 31, "ATA error: %d", rc);
453 lcd_puts(0, 1, str);
454 lcd_puts(0, 3, "Press ON to debug");
455 lcd_update();
456 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
457 dbg_ports();
458 #endif
459 panicf("ata: %d", rc);
462 #ifdef HAVE_EEPROM_SETTINGS
463 eeprom_settings_init();
464 #endif
466 #ifndef HAVE_USBSTACK
467 usb_start_monitoring();
468 while (usb_detect() == USB_INSERTED)
470 #ifdef HAVE_EEPROM_SETTINGS
471 firmware_settings.disk_clean = false;
472 #endif
473 /* enter USB mode early, before trying to mount */
474 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
475 #if (CONFIG_STORAGE & STORAGE_MMC)
476 if (!mmc_touched() ||
477 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
478 #endif
480 usb_screen();
481 mounted = true; /* mounting done @ end of USB mode */
483 #ifdef HAVE_USB_POWER
484 if (usb_powered()) /* avoid deadlock */
485 break;
486 #endif
488 #endif
490 if (!mounted)
492 rc = disk_mount_all();
493 if (rc<=0)
495 lcd_clear_display();
496 lcd_puts(0, 0, "No partition");
497 lcd_puts(0, 1, "found.");
498 #ifdef HAVE_LCD_BITMAP
499 lcd_puts(0, 2, "Insert USB cable");
500 lcd_puts(0, 3, "and fix it.");
501 #endif
502 lcd_update();
504 while(button_get(true) != SYS_USB_CONNECTED) {};
505 usb_screen();
506 system_reboot();
510 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
511 (CONFIG_KEYPAD == IRIVER_H10_PAD)
512 #ifdef SETTINGS_RESET
513 /* Reset settings if holding the reset button. (Rec on Archos,
514 A on Gigabeat) */
515 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
516 #else
517 /* Reset settings if the hold button is turned on */
518 if (button_hold())
519 #endif
521 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
522 settings_reset();
524 else
525 #endif
526 settings_load(SETTINGS_ALL);
528 if (init_dircache(true) < 0)
530 #ifdef HAVE_TAGCACHE
531 remove(TAGCACHE_STATEFILE);
532 #endif
535 gui_sync_wps_init();
536 settings_apply(true);
537 init_dircache(false);
538 #ifdef HAVE_TAGCACHE
539 init_tagcache();
540 #endif
542 #ifdef HAVE_EEPROM_SETTINGS
543 if (firmware_settings.initialized)
545 /* In case we crash. */
546 firmware_settings.disk_clean = false;
547 eeprom_settings_store();
549 #endif
550 status_init();
551 playlist_init();
552 tree_mem_init();
553 filetype_init();
554 scrobbler_init();
555 cuesheet_init();
556 #if CONFIG_CODEC == SWCODEC
557 tdspeed_init();
558 #endif /* CONFIG_CODEC == SWCODEC */
560 #if CONFIG_CODEC != SWCODEC
561 /* No buffer allocation (see buffer.c) may take place after the call to
562 audio_init() since the mpeg thread takes the rest of the buffer space */
563 mp3_init( global_settings.volume,
564 global_settings.bass,
565 global_settings.treble,
566 global_settings.balance,
567 global_settings.loudness,
568 global_settings.avc,
569 global_settings.channel_config,
570 global_settings.stereo_width,
571 global_settings.mdb_strength,
572 global_settings.mdb_harmonics,
573 global_settings.mdb_center,
574 global_settings.mdb_shape,
575 global_settings.mdb_enable,
576 global_settings.superbass);
578 /* audio_init must to know the size of voice buffer so init voice first */
579 talk_init();
580 #endif /* CONFIG_CODEC != SWCODEC */
582 audio_init();
584 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
585 pcm_rec_init();
586 #endif
588 /* runtime database has to be initialized after audio_init() */
589 cpu_boost(false);
591 #ifdef AUTOROCK
593 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
595 if(file_exists(filename)) /* no complaint if it doesn't exist */
597 plugin_load((char*)filename, NULL); /* start if it does */
600 #endif /* #ifdef AUTOROCK */
602 #if CONFIG_CHARGING
603 car_adapter_mode_init();
604 #endif
605 #ifdef IPOD_ACCESSORY_PROTOCOL
606 iap_setup(global_settings.serial_bitrate);
607 #endif
608 #ifdef HAVE_ACCESSORY_SUPPLY
609 accessory_supply_set(global_settings.accessory_supply);
610 #endif
613 #ifdef CPU_PP
614 void cop_main(void)
616 /* This is the entry point for the coprocessor
617 Anyone not running an upgraded bootloader will never reach this point,
618 so it should not be assumed that the coprocessor be usable even on
619 platforms which support it.
621 A kernel thread is initially setup on the coprocessor and immediately
622 destroyed for purposes of continuity. The cop sits idle until at least
623 one thread exists on it. */
625 /* 3G doesn't have Rolo or dual core support yet */
626 #if NUM_CORES > 1
627 system_init();
628 kernel_init();
629 /* This should never be reached */
630 #endif
631 while(1) {
632 sleep_core(COP);
635 #endif /* CPU_PP */
637 int main(void)
639 app_main();
641 while(1) {
642 #if (CONFIG_LED == LED_REAL)
643 led(true); sleep(HZ/10);
644 led(false); sleep(HZ/10);
645 #endif
647 return 0;
649 #endif