Remove experimental check which should only be there if all PCM drivers do it. It...
[kugel-rb.git] / apps / main.c
blob24a89eca56b13542cec78174fd2ac7ea520a5bdf
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(VP_SB_ALLSCREENS);
142 add_event(GUI_EVENT_STATUSBAR_TOGGLE, false,
143 viewportmanager_statusbar_changed);
144 #ifdef HAVE_USBSTACK
145 /* All threads should be created and public queues registered by now */
146 usb_start_monitoring();
147 #endif
148 root_menu();
151 static int init_dircache(bool preinit)
153 #ifdef HAVE_DIRCACHE
154 int result = 0;
155 bool clear = false;
157 if (preinit)
158 dircache_init();
160 if (!global_settings.dircache)
161 return 0;
163 # ifdef HAVE_EEPROM_SETTINGS
164 if (firmware_settings.initialized && firmware_settings.disk_clean
165 && preinit)
167 result = dircache_load();
169 if (result < 0)
171 firmware_settings.disk_clean = false;
172 if (global_status.dircache_size <= 0)
174 /* This will be in default language, settings are not
175 applied yet. Not really any easy way to fix that. */
176 splash(0, str(LANG_SCANNING_DISK));
177 clear = true;
180 dircache_build(global_status.dircache_size);
183 else
184 # endif
186 if (preinit)
187 return -1;
189 if (!dircache_is_enabled()
190 && !dircache_is_initializing())
192 if (global_status.dircache_size <= 0)
194 splash(0, str(LANG_SCANNING_DISK));
195 clear = true;
197 result = dircache_build(global_status.dircache_size);
200 if (result < 0)
202 /* Initialization of dircache failed. Manual action is
203 * necessary to enable dircache again.
205 splashf(0, "Dircache failed, disabled. Result: %d", result);
206 global_settings.dircache = false;
211 if (clear)
213 backlight_on();
214 show_logo();
215 global_status.dircache_size = dircache_get_cache_size();
216 status_save();
219 return result;
220 #else
221 (void)preinit;
222 return 0;
223 #endif
226 #ifdef HAVE_TAGCACHE
227 static void init_tagcache(void)
229 bool clear = false;
231 tagcache_init();
233 while (!tagcache_is_initialized())
235 #ifdef HAVE_LCD_CHARCELLS
236 char buf[32];
237 #endif
238 int ret = tagcache_get_commit_step();
240 if (ret > 0)
242 #if CONFIG_CODEC == SWCODEC
243 /* hwcodec can't use voice here, as the database commit
244 * uses the audio buffer. */
245 static long talked_tick = 0;
246 if(global_settings.talk_menu
247 && (talked_tick == 0
248 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
250 talked_tick = current_tick;
251 talk_id(LANG_TAGCACHE_INIT, false);
252 talk_number(ret, true);
253 talk_id(VOICE_OF, true);
254 talk_number(tagcache_get_max_commit_step(), true);
256 #endif
257 #ifdef HAVE_LCD_BITMAP
258 splashf(0, "%s [%d/%d]",
259 str(LANG_TAGCACHE_INIT), ret,
260 tagcache_get_max_commit_step());
261 #else
262 lcd_double_height(false);
263 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
264 tagcache_get_max_commit_step());
265 lcd_puts(0, 1, buf);
266 lcd_update();
267 #endif
268 clear = true;
270 sleep(HZ/4);
272 tagtree_init();
274 if (clear)
276 backlight_on();
277 show_logo();
280 #endif
282 #ifdef SIMULATOR
284 static void init(void)
286 kernel_init();
287 buffer_init();
288 enable_irq();
289 lcd_init();
290 #ifdef HAVE_REMOTE_LCD
291 lcd_remote_init();
292 #endif
293 font_init();
294 show_logo();
295 button_init();
296 backlight_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();
341 audio_init();
342 button_clear_queue(); /* Empty the keyboard buffer */
345 #else
347 static void init(void)
349 int rc;
350 bool mounted = false;
351 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
352 /* if nobody initialized ATA before, I consider this a cold start */
353 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
354 #endif
356 system_init();
357 kernel_init();
359 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
360 set_cpu_frequency(CPUFREQ_NORMAL);
361 #ifdef CPU_COLDFIRE
362 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
363 #endif
364 cpu_boost(true);
365 #endif
367 buffer_init();
369 settings_reset();
371 i2c_init();
373 power_init();
375 enable_irq();
376 #ifdef CPU_ARM
377 enable_fiq();
378 #endif
379 lcd_init();
380 #ifdef HAVE_REMOTE_LCD
381 lcd_remote_init();
382 #endif
383 font_init();
385 show_logo();
386 lang_init();
388 #ifdef DEBUG
389 debug_init();
390 #else
391 #ifdef HAVE_SERIAL
392 serial_setup();
393 #endif
394 #endif
396 #if CONFIG_RTC
397 rtc_init();
398 #endif
399 #ifdef HAVE_RTC_RAM
400 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
401 #endif
403 adc_init();
405 usb_init();
406 #if CONFIG_USBOTG == USBOTG_ISP1362
407 isp1362_init();
408 #elif CONFIG_USBOTG == USBOTG_M5636
409 m5636_init();
410 #endif
412 backlight_init();
414 button_init();
416 powermgmt_init();
418 #if CONFIG_TUNER
419 radio_init();
420 #endif
422 /* Must be done before any code uses the multi-screen APi */
423 gui_syncstatusbar_init(&statusbars);
425 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
426 if (coldstart && charger_inserted()
427 && !global_settings.car_adapter_mode
428 #ifdef ATA_POWER_PLAYERSTYLE
429 && !ide_powered() /* relies on probing result from bootloader */
430 #endif
433 rc = charging_screen(); /* display a "charging" screen */
434 if (rc == 1) /* charger removed */
435 power_off();
436 /* "On" pressed or USB connected: proceed */
437 show_logo(); /* again, to provide better visual feedback */
439 #endif
441 rc = storage_init();
442 if(rc)
444 #ifdef HAVE_LCD_BITMAP
445 char str[32];
446 lcd_clear_display();
447 snprintf(str, 31, "ATA error: %d", rc);
448 lcd_puts(0, 1, str);
449 lcd_puts(0, 3, "Press ON to debug");
450 lcd_update();
451 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
452 dbg_ports();
453 #endif
454 panicf("ata: %d", rc);
457 #ifdef HAVE_EEPROM_SETTINGS
458 eeprom_settings_init();
459 #endif
461 #ifndef HAVE_USBSTACK
462 usb_start_monitoring();
463 while (usb_detect() == USB_INSERTED)
465 #ifdef HAVE_EEPROM_SETTINGS
466 firmware_settings.disk_clean = false;
467 #endif
468 /* enter USB mode early, before trying to mount */
469 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
470 #if (CONFIG_STORAGE & STORAGE_MMC)
471 if (!mmc_touched() ||
472 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
473 #endif
475 usb_screen();
476 mounted = true; /* mounting done @ end of USB mode */
478 #ifdef HAVE_USB_POWER
479 if (usb_powered()) /* avoid deadlock */
480 break;
481 #endif
483 #endif
485 if (!mounted)
487 rc = disk_mount_all();
488 if (rc<=0)
490 lcd_clear_display();
491 lcd_puts(0, 0, "No partition");
492 lcd_puts(0, 1, "found.");
493 #ifdef HAVE_LCD_BITMAP
494 lcd_puts(0, 2, "Insert USB cable");
495 lcd_puts(0, 3, "and fix it.");
496 #endif
497 lcd_update();
499 while(button_get(true) != SYS_USB_CONNECTED) {};
500 usb_screen();
501 system_reboot();
505 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
506 (CONFIG_KEYPAD == IRIVER_H10_PAD)
507 #ifdef SETTINGS_RESET
508 /* Reset settings if holding the reset button. (Rec on Archos,
509 A on Gigabeat) */
510 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
511 #else
512 /* Reset settings if the hold button is turned on */
513 if (button_hold())
514 #endif
516 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
517 settings_reset();
519 else
520 #endif
521 settings_load(SETTINGS_ALL);
523 if (init_dircache(true) < 0)
525 #ifdef HAVE_TAGCACHE
526 remove(TAGCACHE_STATEFILE);
527 #endif
530 gui_sync_wps_init();
531 settings_apply(true);
532 init_dircache(false);
533 #ifdef HAVE_TAGCACHE
534 init_tagcache();
535 #endif
537 #ifdef HAVE_EEPROM_SETTINGS
538 if (firmware_settings.initialized)
540 /* In case we crash. */
541 firmware_settings.disk_clean = false;
542 eeprom_settings_store();
544 #endif
545 status_init();
546 playlist_init();
547 tree_mem_init();
548 filetype_init();
549 scrobbler_init();
550 cuesheet_init();
552 #if CONFIG_CODEC != SWCODEC
553 /* No buffer allocation (see buffer.c) may take place after the call to
554 audio_init() since the mpeg thread takes the rest of the buffer space */
555 mp3_init( global_settings.volume,
556 global_settings.bass,
557 global_settings.treble,
558 global_settings.balance,
559 global_settings.loudness,
560 global_settings.avc,
561 global_settings.channel_config,
562 global_settings.stereo_width,
563 global_settings.mdb_strength,
564 global_settings.mdb_harmonics,
565 global_settings.mdb_center,
566 global_settings.mdb_shape,
567 global_settings.mdb_enable,
568 global_settings.superbass);
570 /* audio_init must to know the size of voice buffer so init voice first */
571 talk_init();
572 #endif /* CONFIG_CODEC != SWCODEC */
574 audio_init();
576 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
577 pcm_rec_init();
578 #endif
580 /* runtime database has to be initialized after audio_init() */
581 cpu_boost(false);
583 #ifdef AUTOROCK
585 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
587 if(file_exists(filename)) /* no complaint if it doesn't exist */
589 plugin_load((char*)filename, NULL); /* start if it does */
592 #endif /* #ifdef AUTOROCK */
594 #if CONFIG_CHARGING
595 car_adapter_mode_init();
596 #endif
597 #ifdef IPOD_ACCESSORY_PROTOCOL
598 iap_setup(global_settings.serial_bitrate);
599 #endif
600 #ifdef HAVE_ACCESSORY_SUPPLY
601 accessory_supply_set(global_settings.accessory_supply);
602 #endif
605 #ifdef CPU_PP
606 void cop_main(void)
608 /* This is the entry point for the coprocessor
609 Anyone not running an upgraded bootloader will never reach this point,
610 so it should not be assumed that the coprocessor be usable even on
611 platforms which support it.
613 A kernel thread is initially setup on the coprocessor and immediately
614 destroyed for purposes of continuity. The cop sits idle until at least
615 one thread exists on it. */
617 /* 3G doesn't have Rolo or dual core support yet */
618 #if NUM_CORES > 1
619 system_init();
620 kernel_init();
621 /* This should never be reached */
622 #endif
623 while(1) {
624 sleep_core(COP);
627 #endif /* CPU_PP */
629 int main(void)
631 app_main();
633 while(1) {
634 #if (CONFIG_LED == LED_REAL)
635 led(true); sleep(HZ/10);
636 led(false); sleep(HZ/10);
637 #endif
639 return 0;
641 #endif