Fixed m200v4 red build.
[kugel-rb.git] / apps / main.c
blob45e6c77801366875a403f4fe16f43efee10ff795
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 root_menu();
144 static int init_dircache(bool preinit)
146 #ifdef HAVE_DIRCACHE
147 int result = 0;
148 bool clear = false;
150 if (preinit)
151 dircache_init();
153 if (!global_settings.dircache)
154 return 0;
156 # ifdef HAVE_EEPROM_SETTINGS
157 if (firmware_settings.initialized && firmware_settings.disk_clean
158 && preinit)
160 result = dircache_load();
162 if (result < 0)
164 firmware_settings.disk_clean = false;
165 if (global_status.dircache_size <= 0)
167 /* This will be in default language, settings are not
168 applied yet. Not really any easy way to fix that. */
169 splash(0, str(LANG_SCANNING_DISK));
170 clear = true;
173 dircache_build(global_status.dircache_size);
176 else
177 # endif
179 if (preinit)
180 return -1;
182 if (!dircache_is_enabled()
183 && !dircache_is_initializing())
185 if (global_status.dircache_size <= 0)
187 splash(0, str(LANG_SCANNING_DISK));
188 clear = true;
190 result = dircache_build(global_status.dircache_size);
193 if (result < 0)
195 /* Initialization of dircache failed. Manual action is
196 * necessary to enable dircache again.
198 splashf(0, "Dircache failed, disabled. Result: %d", result);
199 global_settings.dircache = false;
204 if (clear)
206 backlight_on();
207 show_logo();
208 global_status.dircache_size = dircache_get_cache_size();
209 status_save();
212 return result;
213 #else
214 (void)preinit;
215 return 0;
216 #endif
219 #ifdef HAVE_TAGCACHE
220 static void init_tagcache(void)
222 bool clear = false;
224 tagcache_init();
226 while (!tagcache_is_initialized())
228 #ifdef HAVE_LCD_CHARCELLS
229 char buf[32];
230 #endif
231 int ret = tagcache_get_commit_step();
233 if (ret > 0)
235 #if CONFIG_CODEC == SWCODEC
236 /* hwcodec can't use voice here, as the database commit
237 * uses the audio buffer. */
238 static long talked_tick = 0;
239 if(global_settings.talk_menu
240 && (talked_tick == 0
241 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
243 talked_tick = current_tick;
244 talk_id(LANG_TAGCACHE_INIT, false);
245 talk_number(ret, true);
246 talk_id(VOICE_OF, true);
247 talk_number(tagcache_get_max_commit_step(), true);
249 #endif
250 #ifdef HAVE_LCD_BITMAP
251 splashf(0, "%s [%d/%d]",
252 str(LANG_TAGCACHE_INIT), ret,
253 tagcache_get_max_commit_step());
254 #else
255 lcd_double_height(false);
256 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
257 tagcache_get_max_commit_step());
258 lcd_puts(0, 1, buf);
259 lcd_update();
260 #endif
261 clear = true;
263 sleep(HZ/4);
265 tagtree_init();
267 if (clear)
269 backlight_on();
270 show_logo();
273 #endif
275 #ifdef SIMULATOR
277 static void init(void)
279 kernel_init();
280 buffer_init();
281 enable_irq();
282 lcd_init();
283 #ifdef HAVE_REMOTE_LCD
284 lcd_remote_init();
285 #endif
286 font_init();
287 show_logo();
288 button_init();
289 backlight_init();
290 lang_init();
291 #ifdef DEBUG
292 debug_init();
293 #endif
294 /* Must be done before any code uses the multi-screen APi */
295 gui_syncstatusbar_init(&statusbars);
296 storage_init();
297 settings_reset();
298 settings_load(SETTINGS_ALL);
299 gui_sync_wps_init();
300 settings_apply(true);
301 init_dircache(true);
302 init_dircache(false);
303 #ifdef HAVE_TAGCACHE
304 init_tagcache();
305 #endif
306 sleep(HZ/2);
307 tree_mem_init();
308 filetype_init();
309 playlist_init();
311 #if CONFIG_CODEC != SWCODEC
312 mp3_init( global_settings.volume,
313 global_settings.bass,
314 global_settings.treble,
315 global_settings.balance,
316 global_settings.loudness,
317 global_settings.avc,
318 global_settings.channel_config,
319 global_settings.stereo_width,
320 global_settings.mdb_strength,
321 global_settings.mdb_harmonics,
322 global_settings.mdb_center,
323 global_settings.mdb_shape,
324 global_settings.mdb_enable,
325 global_settings.superbass);
327 /* audio_init must to know the size of voice buffer so init voice first */
328 talk_init();
329 #endif /* CONFIG_CODEC != SWCODEC */
331 scrobbler_init();
332 cuesheet_init();
334 audio_init();
335 button_clear_queue(); /* Empty the keyboard buffer */
338 #else
340 static void init(void)
342 int rc;
343 bool mounted = false;
344 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
345 /* if nobody initialized ATA before, I consider this a cold start */
346 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
347 #endif
349 system_init();
350 kernel_init();
352 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
353 set_cpu_frequency(CPUFREQ_NORMAL);
354 #ifdef CPU_COLDFIRE
355 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
356 #endif
357 cpu_boost(true);
358 #endif
360 buffer_init();
362 settings_reset();
364 i2c_init();
366 power_init();
368 enable_irq();
369 #ifdef CPU_ARM
370 enable_fiq();
371 #endif
372 lcd_init();
373 #ifdef HAVE_REMOTE_LCD
374 lcd_remote_init();
375 #endif
376 font_init();
378 show_logo();
379 lang_init();
381 #ifdef DEBUG
382 debug_init();
383 #else
384 #if !defined(HAVE_FMADC) && !(CONFIG_STORAGE & STORAGE_MMC)
385 serial_setup();
386 #endif
387 #endif
389 #if CONFIG_RTC
390 rtc_init();
391 #endif
392 #ifdef HAVE_RTC_RAM
393 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
394 #endif
396 adc_init();
398 usb_init();
399 #if CONFIG_USBOTG == USBOTG_ISP1362
400 isp1362_init();
401 #elif CONFIG_USBOTG == USBOTG_M5636
402 m5636_init();
403 #endif
405 backlight_init();
407 button_init();
409 powermgmt_init();
411 #if CONFIG_TUNER
412 radio_init();
413 #endif
415 /* Must be done before any code uses the multi-screen APi */
416 gui_syncstatusbar_init(&statusbars);
418 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
419 if (coldstart && charger_inserted()
420 && !global_settings.car_adapter_mode
421 #ifdef ATA_POWER_PLAYERSTYLE
422 && !ide_powered() /* relies on probing result from bootloader */
423 #endif
426 rc = charging_screen(); /* display a "charging" screen */
427 if (rc == 1) /* charger removed */
428 power_off();
429 /* "On" pressed or USB connected: proceed */
430 show_logo(); /* again, to provide better visual feedback */
432 #endif
434 rc = storage_init();
435 if(rc)
437 #ifdef HAVE_LCD_BITMAP
438 char str[32];
439 lcd_clear_display();
440 snprintf(str, 31, "ATA error: %d", rc);
441 lcd_puts(0, 1, str);
442 lcd_puts(0, 3, "Press ON to debug");
443 lcd_update();
444 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
445 dbg_ports();
446 #endif
447 panicf("ata: %d", rc);
450 #ifdef HAVE_EEPROM_SETTINGS
451 eeprom_settings_init();
452 #endif
454 usb_start_monitoring();
455 #ifndef HAVE_USBSTACK
456 while (usb_detect() == USB_INSERTED)
458 #ifdef HAVE_EEPROM_SETTINGS
459 firmware_settings.disk_clean = false;
460 #endif
461 /* enter USB mode early, before trying to mount */
462 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
463 #if (CONFIG_STORAGE & STORAGE_MMC)
464 if (!mmc_touched() ||
465 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
466 #endif
468 usb_screen();
469 mounted = true; /* mounting done @ end of USB mode */
471 #ifdef HAVE_USB_POWER
472 if (usb_powered()) /* avoid deadlock */
473 break;
474 #endif
476 #endif
478 if (!mounted)
480 rc = disk_mount_all();
481 if (rc<=0)
483 lcd_clear_display();
484 lcd_puts(0, 0, "No partition");
485 lcd_puts(0, 1, "found.");
486 #ifdef HAVE_LCD_BITMAP
487 lcd_puts(0, 2, "Insert USB cable");
488 lcd_puts(0, 3, "and fix it.");
489 #endif
490 lcd_update();
492 while(button_get(true) != SYS_USB_CONNECTED) {};
493 usb_screen();
494 system_reboot();
498 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
499 (CONFIG_KEYPAD == IRIVER_H10_PAD)
500 #ifdef SETTINGS_RESET
501 /* Reset settings if holding the reset button. (Rec on Archos,
502 A on Gigabeat) */
503 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
504 #else
505 /* Reset settings if the hold button is turned on */
506 if (button_hold())
507 #endif
509 splash(HZ*2, str(LANG_RESET_DONE_CLEAR));
510 settings_reset();
512 else
513 #endif
514 settings_load(SETTINGS_ALL);
516 if (init_dircache(true) < 0)
518 #ifdef HAVE_TAGCACHE
519 remove(TAGCACHE_STATEFILE);
520 #endif
523 gui_sync_wps_init();
524 settings_apply(true);
525 init_dircache(false);
526 #ifdef HAVE_TAGCACHE
527 init_tagcache();
528 #endif
530 #ifdef HAVE_EEPROM_SETTINGS
531 if (firmware_settings.initialized)
533 /* In case we crash. */
534 firmware_settings.disk_clean = false;
535 eeprom_settings_store();
537 #endif
538 status_init();
539 playlist_init();
540 tree_mem_init();
541 filetype_init();
542 scrobbler_init();
543 cuesheet_init();
545 #if CONFIG_CODEC != SWCODEC
546 /* No buffer allocation (see buffer.c) may take place after the call to
547 audio_init() since the mpeg thread takes the rest of the buffer space */
548 mp3_init( global_settings.volume,
549 global_settings.bass,
550 global_settings.treble,
551 global_settings.balance,
552 global_settings.loudness,
553 global_settings.avc,
554 global_settings.channel_config,
555 global_settings.stereo_width,
556 global_settings.mdb_strength,
557 global_settings.mdb_harmonics,
558 global_settings.mdb_center,
559 global_settings.mdb_shape,
560 global_settings.mdb_enable,
561 global_settings.superbass);
563 /* audio_init must to know the size of voice buffer so init voice first */
564 talk_init();
565 #endif /* CONFIG_CODEC != SWCODEC */
567 audio_init();
569 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
570 pcm_rec_init();
571 #endif
573 /* runtime database has to be initialized after audio_init() */
574 cpu_boost(false);
576 #ifdef AUTOROCK
578 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
580 if(file_exists(filename)) /* no complaint if it doesn't exist */
582 plugin_load((char*)filename, NULL); /* start if it does */
585 #endif /* #ifdef AUTOROCK */
587 #if CONFIG_CHARGING
588 car_adapter_mode_init();
589 #endif
590 #ifdef IPOD_ACCESSORY_PROTOCOL
591 iap_setup(global_settings.serial_bitrate);
592 #endif
593 #ifdef HAVE_ACCESSORY_SUPPLY
594 accessory_supply_set(global_settings.accessory_supply);
595 #endif
598 #ifdef CPU_PP
599 void cop_main(void)
601 /* This is the entry point for the coprocessor
602 Anyone not running an upgraded bootloader will never reach this point,
603 so it should not be assumed that the coprocessor be usable even on
604 platforms which support it.
606 A kernel thread is initially setup on the coprocessor and immediately
607 destroyed for purposes of continuity. The cop sits idle until at least
608 one thread exists on it. */
610 /* 3G doesn't have Rolo or dual core support yet */
611 #if NUM_CORES > 1
612 system_init();
613 kernel_init();
614 /* This should never be reached */
615 #endif
616 while(1) {
617 sleep_core(COP);
620 #endif /* CPU_PP */
622 int main(void)
624 app_main();
626 while(1) {
627 #if (CONFIG_LED == LED_REAL)
628 led(true); sleep(HZ/10);
629 led(false); sleep(HZ/10);
630 #endif
632 return 0;
634 #endif