Revert change 13001, since it causes the metadata to be re-read for partially buffere...
[kugel-rb.git] / apps / main.c
blob3145f3693bea4c0d31e62445dca10d65085127b1
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "config.h"
21 #include "ata.h"
22 #include "ata_idle_notify.h"
23 #include "disk.h"
24 #include "fat.h"
25 #include "lcd.h"
26 #include "rtc.h"
27 #include "debug.h"
28 #include "led.h"
29 #include "kernel.h"
30 #include "button.h"
31 #include "tree.h"
32 #include "filetypes.h"
33 #include "panic.h"
34 #include "menu.h"
35 #include "system.h"
36 #include "usb.h"
37 #include "powermgmt.h"
38 #include "adc.h"
39 #include "i2c.h"
40 #ifndef DEBUG
41 #include "serial.h"
42 #endif
43 #include "audio.h"
44 #include "mp3_playback.h"
45 #include "thread.h"
46 #include "settings.h"
47 #include "backlight.h"
48 #include "status.h"
49 #include "debug_menu.h"
50 #include "version.h"
51 #include "sprintf.h"
52 #include "font.h"
53 #include "language.h"
54 #include "gwps.h"
55 #include "playlist.h"
56 #include "buffer.h"
57 #include "rolo.h"
58 #include "screens.h"
59 #include "power.h"
60 #include "talk.h"
61 #include "plugin.h"
62 #include "misc.h"
63 #include "dircache.h"
64 #ifdef HAVE_TAGCACHE
65 #include "tagcache.h"
66 #include "tagtree.h"
67 #endif
68 #include "lang.h"
69 #include "string.h"
70 #include "splash.h"
71 #include "eeprom_settings.h"
72 #include "scrobbler.h"
74 #if (CONFIG_CODEC == SWCODEC)
75 #include "playback.h"
76 #include "pcmbuf.h"
77 #else
78 #define pcmbuf_init()
79 #endif
80 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
81 #include "pcm_record.h"
82 #endif
84 #ifdef BUTTON_REC
85 #define SETTINGS_RESET BUTTON_REC
86 #endif
88 #if CONFIG_TUNER
89 #include "radio.h"
90 #endif
91 #ifdef HAVE_MMC
92 #include "ata_mmc.h"
93 #endif
95 #ifdef HAVE_REMOTE_LCD
96 #include "lcd-remote.h"
97 #endif
99 #if CONFIG_USBOTG == USBOTG_ISP1362
100 #include "isp1362.h"
101 #endif
103 #if CONFIG_USBOTG == USBOTG_M5636
104 #include "m5636.h"
105 #endif
107 #include "cuesheet.h"
109 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
111 const char appsversion[]=APPSVERSION;
113 static void init(void);
115 #ifdef SIMULATOR
116 void app_main(void)
117 #else
118 static void app_main(void)
119 #endif
121 init();
122 browse_root();
125 static int init_dircache(bool preinit)
127 #ifdef HAVE_DIRCACHE
128 int result = 0;
129 bool clear = false;
131 if (preinit)
132 dircache_init();
134 if (!global_settings.dircache)
135 return 0;
137 # ifdef HAVE_EEPROM_SETTINGS
138 if (firmware_settings.initialized && firmware_settings.disk_clean
139 && preinit)
141 result = dircache_load();
143 if (result < 0)
145 firmware_settings.disk_clean = false;
146 if (global_status.dircache_size <= 0)
148 /* This will be in default language, settings are not
149 applied yet. Not really any easy way to fix that. */
150 gui_syncsplash(0, str(LANG_DIRCACHE_BUILDING));
151 clear = true;
154 dircache_build(global_status.dircache_size);
157 else
158 # endif
160 if (preinit)
161 return -1;
163 if (!dircache_is_enabled()
164 && !dircache_is_initializing())
166 if (global_status.dircache_size <= 0)
168 gui_syncsplash(0, str(LANG_DIRCACHE_BUILDING));
169 clear = true;
171 result = dircache_build(global_status.dircache_size);
174 if (result < 0)
176 /* Initialization of dircache failed. Manual action is
177 * necessary to enable dircache again.
179 gui_syncsplash(0, "Dircache failed, disabled. Result: %d", result);
180 global_settings.dircache = false;
185 if (clear)
187 backlight_on();
188 show_logo();
189 global_status.dircache_size = dircache_get_cache_size();
190 status_save();
193 return result;
194 #else
195 (void)preinit;
196 return 0;
197 #endif
200 #ifdef HAVE_TAGCACHE
201 static void init_tagcache(void)
203 bool clear = false;
205 tagcache_init();
207 while (!tagcache_is_initialized())
209 #ifdef HAVE_LCD_CHARCELLS
210 char buf[32];
211 #endif
212 int ret = tagcache_get_commit_step();
214 if (ret > 0)
216 #ifdef HAVE_LCD_BITMAP
217 gui_syncsplash(0, "%s [%d/%d]",
218 str(LANG_TAGCACHE_INIT), ret,
219 tagcache_get_max_commit_step());
220 #else
221 lcd_double_height(false);
222 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
223 tagcache_get_max_commit_step());
224 lcd_puts(0, 1, buf);
225 #endif
226 clear = true;
228 sleep(HZ/4);
230 tagtree_init();
232 if (clear)
234 backlight_on();
235 show_logo();
238 #endif
240 #ifdef SIMULATOR
242 static void init(void)
244 init_threads();
245 buffer_init();
246 lcd_init();
247 #ifdef HAVE_REMOTE_LCD
248 lcd_remote_init();
249 #endif
250 font_init();
251 show_logo();
252 button_init();
253 backlight_init();
254 lang_init();
255 /* Must be done before any code uses the multi-screen APi */
256 screen_access_init();
257 gui_syncstatusbar_init(&statusbars);
258 settings_reset();
259 settings_load(SETTINGS_ALL);
260 gui_sync_wps_init();
261 settings_apply();
262 init_dircache(true);
263 init_dircache(false);
264 #ifdef HAVE_TAGCACHE
265 init_tagcache();
266 #endif
267 sleep(HZ/2);
268 tree_init();
269 filetype_init();
270 playlist_init();
272 #if CONFIG_CODEC != SWCODEC
273 mp3_init( global_settings.volume,
274 global_settings.bass,
275 global_settings.treble,
276 global_settings.balance,
277 global_settings.loudness,
278 global_settings.avc,
279 global_settings.channel_config,
280 global_settings.stereo_width,
281 global_settings.mdb_strength,
282 global_settings.mdb_harmonics,
283 global_settings.mdb_center,
284 global_settings.mdb_shape,
285 global_settings.mdb_enable,
286 global_settings.superbass);
288 /* audio_init must to know the size of voice buffer so init voice first */
289 talk_init();
290 #endif /* CONFIG_CODEC != SWCODEC */
292 scrobbler_init();
293 cuesheet_init();
295 audio_init();
296 button_clear_queue(); /* Empty the keyboard buffer */
299 #else
301 static void init(void)
303 int rc;
304 bool mounted = false;
305 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
306 /* if nobody initialized ATA before, I consider this a cold start */
307 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
308 #endif
309 #ifdef CPU_PP
310 COP_CTL = PROC_WAKE;
311 #endif
312 system_init();
313 kernel_init();
315 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
316 set_cpu_frequency(CPUFREQ_NORMAL);
317 #ifdef CPU_COLDFIRE
318 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
319 #endif
320 cpu_boost(true);
321 #endif
323 buffer_init();
325 settings_reset();
327 power_init();
329 set_irq_level(0);
330 lcd_init();
331 #ifdef HAVE_REMOTE_LCD
332 lcd_remote_init();
333 #endif
334 font_init();
336 #if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR)
337 show_logo();
338 #else
339 sleep(1); /* Weird. We crash w/o this tiny delay. */
340 #endif
341 lang_init();
343 #ifdef DEBUG
344 debug_init();
345 #else
346 #if !defined(HAVE_FMADC) && !defined(HAVE_MMC)
347 serial_setup();
348 #endif
349 #endif
351 i2c_init();
353 #if CONFIG_RTC
354 rtc_init();
355 #endif
356 #ifdef HAVE_RTC_RAM
357 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
358 #endif
360 adc_init();
362 usb_init();
363 #if CONFIG_USBOTG == USBOTG_ISP1362
364 isp1362_init();
365 #elif CONFIG_USBOTG == USBOTG_M5636
366 m5636_init();
367 #endif
369 backlight_init();
371 button_init();
373 powermgmt_init();
375 #if CONFIG_TUNER
376 radio_init();
377 #endif
379 /* Must be done before any code uses the multi-screen APi */
380 screen_access_init();
381 gui_syncstatusbar_init(&statusbars);
383 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
384 if (coldstart && charger_inserted()
385 && !global_settings.car_adapter_mode
386 #ifdef ATA_POWER_PLAYERSTYLE
387 && !ide_powered() /* relies on probing result from bootloader */
388 #endif
391 rc = charging_screen(); /* display a "charging" screen */
392 if (rc == 1) /* charger removed */
393 power_off();
394 /* "On" pressed or USB connected: proceed */
395 show_logo(); /* again, to provide better visual feedback */
397 #endif
399 ata_idle_notify_init();
400 rc = ata_init();
401 if(rc)
403 #ifdef HAVE_LCD_BITMAP
404 char str[32];
405 lcd_clear_display();
406 snprintf(str, 31, "ATA error: %d", rc);
407 lcd_puts(0, 1, str);
408 lcd_puts(0, 3, "Press ON to debug");
409 lcd_update();
410 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
411 dbg_ports();
412 #endif
413 panicf("ata: %d", rc);
416 #ifdef HAVE_EEPROM_SETTINGS
417 eeprom_settings_init();
418 #endif
420 usb_start_monitoring();
421 while (usb_detect())
423 #ifdef HAVE_EEPROM_SETTINGS
424 firmware_settings.disk_clean = false;
425 #endif
426 /* enter USB mode early, before trying to mount */
427 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
428 #ifdef HAVE_MMC
429 if (!mmc_touched() || (mmc_remove_request() == SYS_MMC_EXTRACTED))
430 #endif
432 usb_screen();
433 mounted = true; /* mounting done @ end of USB mode */
435 #ifdef HAVE_USB_POWER
436 if (usb_powered()) /* avoid deadlock */
437 break;
438 #endif
441 if (!mounted)
443 rc = disk_mount_all();
444 if (rc<=0)
446 lcd_clear_display();
447 lcd_puts(0, 0, "No partition");
448 lcd_puts(0, 1, "found.");
449 #ifdef HAVE_LCD_BITMAP
450 lcd_puts(0, 2, "Insert USB cable");
451 lcd_puts(0, 3, "and fix it.");
452 #endif
453 lcd_update();
455 while(button_get(true) != SYS_USB_CONNECTED) {};
456 usb_screen();
457 system_reboot();
461 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
462 (CONFIG_KEYPAD == IRIVER_H10_PAD) || (CONFIG_KEYPAD == GIGABEAT_PAD)
463 #ifdef SETTINGS_RESET
464 /* Reset settings if holding the rec button. */
465 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
466 #else
467 /* Reset settings if the hold button is turned on */
468 if (button_hold())
469 #endif
471 gui_syncsplash(HZ*2, str(LANG_RESET_DONE_CLEAR));
472 settings_reset();
474 else
475 #endif
476 settings_load(SETTINGS_ALL);
478 if (init_dircache(true) < 0)
480 #ifdef HAVE_TAGCACHE
481 remove(TAGCACHE_STATEFILE);
482 #endif
485 gui_sync_wps_init();
486 settings_apply();
487 init_dircache(false);
488 #ifdef HAVE_TAGCACHE
489 init_tagcache();
490 #endif
492 #ifdef HAVE_EEPROM_SETTINGS
493 if (firmware_settings.initialized)
495 /* In case we crash. */
496 firmware_settings.disk_clean = false;
497 eeprom_settings_store();
499 #endif
500 status_init();
501 playlist_init();
502 tree_init();
503 filetype_init();
504 scrobbler_init();
505 cuesheet_init();
507 #if CONFIG_CODEC != SWCODEC
508 /* No buffer allocation (see buffer.c) may take place after the call to
509 audio_init() since the mpeg thread takes the rest of the buffer space */
510 mp3_init( global_settings.volume,
511 global_settings.bass,
512 global_settings.treble,
513 global_settings.balance,
514 global_settings.loudness,
515 global_settings.avc,
516 global_settings.channel_config,
517 global_settings.stereo_width,
518 global_settings.mdb_strength,
519 global_settings.mdb_harmonics,
520 global_settings.mdb_center,
521 global_settings.mdb_shape,
522 global_settings.mdb_enable,
523 global_settings.superbass);
525 /* audio_init must to know the size of voice buffer so init voice first */
526 talk_init();
527 #endif /* CONFIG_CODEC != SWCODEC */
529 audio_init();
531 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
532 pcm_rec_init();
533 #endif
535 /* runtime database has to be initialized after audio_init() */
536 cpu_boost(false);
538 #ifdef AUTOROCK
540 int fd;
541 static const char filename[] = PLUGIN_DIR "/autostart.rock";
543 fd = open(filename, O_RDONLY);
544 if(fd >= 0) /* no complaint if it doesn't exist */
546 close(fd);
547 plugin_load((char*)filename, NULL); /* start if it does */
550 #endif /* #ifdef AUTOROCK */
552 #if CONFIG_CHARGING
553 car_adapter_mode_init();
554 #endif
557 #ifdef CPU_PP
558 void cop_main(void)
560 /* This is the entry point for the coprocessor
561 Anyone not running an upgraded bootloader will never reach this point,
562 so it should not be assumed that the coprocessor be usable even on
563 platforms which support it.
565 A kernel thread runs on the coprocessor which waits for other threads to be
566 added, and gracefully handles RoLo */
568 #if CONFIG_CPU == PP5002
569 /* 3G doesn't have Rolo or dual core support yet */
570 while(1) {
571 COP_CTL = PROC_SLEEP;
573 #else
574 extern volatile unsigned char cpu_message;
576 system_init();
577 kernel_init();
579 while(cpu_message != COP_REBOOT) {
580 sleep(HZ);
582 rolo_restart_cop();
583 #endif /* PP5002 */
585 #endif /* CPU_PP */
587 int main(void)
589 app_main();
591 while(1) {
592 #if (CONFIG_LED == LED_REAL)
593 led(true); sleep(HZ/10);
594 led(false); sleep(HZ/10);
595 #endif
597 return 0;
599 #endif