grr.. typo
[Rockbox.git] / apps / main.c
blob7309d95df23120f1951ea5bcb13441458a6bf8cb
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 "disk.h"
23 #include "fat.h"
24 #include "lcd.h"
25 #include "rtc.h"
26 #include "debug.h"
27 #include "led.h"
28 #include "kernel.h"
29 #include "button.h"
30 #include "tree.h"
31 #include "filetypes.h"
32 #include "panic.h"
33 #include "menu.h"
34 #include "system.h"
35 #include "usb.h"
36 #include "powermgmt.h"
37 #include "adc.h"
38 #include "i2c.h"
39 #ifndef DEBUG
40 #include "serial.h"
41 #endif
42 #include "audio.h"
43 #include "mp3_playback.h"
44 #include "thread.h"
45 #include "settings.h"
46 #include "backlight.h"
47 #include "status.h"
48 #include "debug_menu.h"
49 #include "version.h"
50 #include "sprintf.h"
51 #include "font.h"
52 #include "language.h"
53 #include "gwps.h"
54 #include "playlist.h"
55 #include "buffer.h"
56 #include "rolo.h"
57 #include "screens.h"
58 #include "power.h"
59 #include "talk.h"
60 #include "plugin.h"
61 #include "misc.h"
62 #include "dircache.h"
63 #ifdef HAVE_TAGCACHE
64 #include "tagcache.h"
65 #include "tagtree.h"
66 #endif
67 #include "lang.h"
68 #include "string.h"
69 #include "splash.h"
70 #include "eeprom_settings.h"
71 #include "scrobbler.h"
72 #include "icon.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 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
87 #define SETTINGS_RESET BUTTON_A
88 #endif
90 #if CONFIG_TUNER
91 #include "radio.h"
92 #endif
93 #ifdef HAVE_MMC
94 #include "ata_mmc.h"
95 #endif
97 #ifdef HAVE_REMOTE_LCD
98 #include "lcd-remote.h"
99 #endif
101 #if CONFIG_USBOTG == USBOTG_ISP1362
102 #include "isp1362.h"
103 #endif
105 #if CONFIG_USBOTG == USBOTG_M5636
106 #include "m5636.h"
107 #endif
109 #include "cuesheet.h"
111 #ifdef SIMULATOR
112 #include "system-sdl.h"
113 #endif
115 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
117 const char appsversion[]=APPSVERSION;
119 static void init(void);
121 #ifdef SIMULATOR
122 void app_main(void)
123 #else
124 static void app_main(void)
125 #endif
127 int i;
128 init();
129 FOR_NB_SCREENS(i)
131 screens[i].clear_display();
132 screens[i].update();
134 tree_gui_init();
135 #ifdef HAVE_TOUCHPAD
136 touchpad_set_mode(TOUCHPAD_BUTTON);
137 #endif
138 root_menu();
141 static int init_dircache(bool preinit)
143 #ifdef HAVE_DIRCACHE
144 int result = 0;
145 bool clear = false;
147 if (preinit)
148 dircache_init();
150 if (!global_settings.dircache)
151 return 0;
153 # ifdef HAVE_EEPROM_SETTINGS
154 if (firmware_settings.initialized && firmware_settings.disk_clean
155 && preinit)
157 result = dircache_load();
159 if (result < 0)
161 firmware_settings.disk_clean = false;
162 if (global_status.dircache_size <= 0)
164 /* This will be in default language, settings are not
165 applied yet. Not really any easy way to fix that. */
166 gui_syncsplash(0, str(LANG_SCANNING_DISK));
167 clear = true;
170 dircache_build(global_status.dircache_size);
173 else
174 # endif
176 if (preinit)
177 return -1;
179 if (!dircache_is_enabled()
180 && !dircache_is_initializing())
182 if (global_status.dircache_size <= 0)
184 gui_syncsplash(0, str(LANG_SCANNING_DISK));
185 clear = true;
187 result = dircache_build(global_status.dircache_size);
190 if (result < 0)
192 /* Initialization of dircache failed. Manual action is
193 * necessary to enable dircache again.
195 gui_syncsplash(0, "Dircache failed, disabled. Result: %d", result);
196 global_settings.dircache = false;
201 if (clear)
203 backlight_on();
204 show_logo();
205 global_status.dircache_size = dircache_get_cache_size();
206 status_save();
209 return result;
210 #else
211 (void)preinit;
212 return 0;
213 #endif
216 #ifdef HAVE_TAGCACHE
217 static void init_tagcache(void)
219 bool clear = false;
221 tagcache_init();
223 while (!tagcache_is_initialized())
225 #ifdef HAVE_LCD_CHARCELLS
226 char buf[32];
227 #endif
228 int ret = tagcache_get_commit_step();
230 if (ret > 0)
232 #if CONFIG_CODEC == SWCODEC
233 /* hwcodec can't use voice here, as the database commit
234 * uses the audio buffer. */
235 static long talked_tick = 0;
236 if(global_settings.talk_menu
237 && (talked_tick == 0
238 || TIME_AFTER(current_tick, talked_tick+7*HZ)))
240 talked_tick = current_tick;
241 talk_id(LANG_TAGCACHE_INIT, false);
242 talk_number(ret, true);
243 talk_id(VOICE_OF, true);
244 talk_number(tagcache_get_max_commit_step(), true);
246 #endif
247 #ifdef HAVE_LCD_BITMAP
248 gui_syncsplash(0, "%s [%d/%d]",
249 str(LANG_TAGCACHE_INIT), ret,
250 tagcache_get_max_commit_step());
251 #else
252 lcd_double_height(false);
253 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
254 tagcache_get_max_commit_step());
255 lcd_puts(0, 1, buf);
256 lcd_update();
257 #endif
258 clear = true;
260 sleep(HZ/4);
262 tagtree_init();
264 if (clear)
266 backlight_on();
267 show_logo();
270 #endif
272 #ifdef SIMULATOR
274 static void init(void)
276 kernel_init();
277 buffer_init();
278 enable_irq();
279 lcd_init();
280 #ifdef HAVE_REMOTE_LCD
281 lcd_remote_init();
282 #endif
283 font_init();
284 show_logo();
285 button_init();
286 backlight_init();
287 lang_init();
288 #ifdef DEBUG
289 debug_init();
290 #endif
291 /* Must be done before any code uses the multi-screen APi */
292 screen_access_init();
293 gui_syncstatusbar_init(&statusbars);
294 ata_init();
295 settings_reset();
296 settings_load(SETTINGS_ALL);
297 gui_sync_wps_init();
298 settings_apply(true);
299 init_dircache(true);
300 init_dircache(false);
301 #ifdef HAVE_TAGCACHE
302 init_tagcache();
303 #endif
304 sleep(HZ/2);
305 tree_mem_init();
306 filetype_init();
307 playlist_init();
309 #if CONFIG_CODEC != SWCODEC
310 mp3_init( global_settings.volume,
311 global_settings.bass,
312 global_settings.treble,
313 global_settings.balance,
314 global_settings.loudness,
315 global_settings.avc,
316 global_settings.channel_config,
317 global_settings.stereo_width,
318 global_settings.mdb_strength,
319 global_settings.mdb_harmonics,
320 global_settings.mdb_center,
321 global_settings.mdb_shape,
322 global_settings.mdb_enable,
323 global_settings.superbass);
325 /* audio_init must to know the size of voice buffer so init voice first */
326 talk_init();
327 #endif /* CONFIG_CODEC != SWCODEC */
329 scrobbler_init();
330 cuesheet_init();
332 audio_init();
333 button_clear_queue(); /* Empty the keyboard buffer */
336 #else
338 static void init(void)
340 int rc;
341 bool mounted = false;
342 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
343 /* if nobody initialized ATA before, I consider this a cold start */
344 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
345 #endif
347 system_init();
348 kernel_init();
350 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
351 set_cpu_frequency(CPUFREQ_NORMAL);
352 #ifdef CPU_COLDFIRE
353 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
354 #endif
355 cpu_boost(true);
356 #endif
358 buffer_init();
360 settings_reset();
362 i2c_init();
364 power_init();
366 enable_irq();
367 #ifdef CPU_ARM
368 enable_fiq();
369 #endif
370 lcd_init();
371 #ifdef HAVE_REMOTE_LCD
372 lcd_remote_init();
373 #endif
374 font_init();
376 show_logo();
377 lang_init();
379 #ifdef DEBUG
380 debug_init();
381 #else
382 #if !defined(HAVE_FMADC) && !defined(HAVE_MMC)
383 serial_setup();
384 #endif
385 #endif
387 #if CONFIG_RTC
388 rtc_init();
389 #endif
390 #ifdef HAVE_RTC_RAM
391 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
392 #endif
394 adc_init();
396 usb_init();
397 #if CONFIG_USBOTG == USBOTG_ISP1362
398 isp1362_init();
399 #elif CONFIG_USBOTG == USBOTG_M5636
400 m5636_init();
401 #endif
403 backlight_init();
405 button_init();
407 powermgmt_init();
409 #if CONFIG_TUNER
410 radio_init();
411 #endif
413 /* Must be done before any code uses the multi-screen APi */
414 screen_access_init();
415 gui_syncstatusbar_init(&statusbars);
417 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
418 if (coldstart && charger_inserted()
419 && !global_settings.car_adapter_mode
420 #ifdef ATA_POWER_PLAYERSTYLE
421 && !ide_powered() /* relies on probing result from bootloader */
422 #endif
425 rc = charging_screen(); /* display a "charging" screen */
426 if (rc == 1) /* charger removed */
427 power_off();
428 /* "On" pressed or USB connected: proceed */
429 show_logo(); /* again, to provide better visual feedback */
431 #endif
433 rc = ata_init();
434 if(rc)
436 #ifdef HAVE_LCD_BITMAP
437 char str[32];
438 lcd_clear_display();
439 snprintf(str, 31, "ATA error: %d", rc);
440 lcd_puts(0, 1, str);
441 lcd_puts(0, 3, "Press ON to debug");
442 lcd_update();
443 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
444 dbg_ports();
445 #endif
446 panicf("ata: %d", rc);
449 #ifdef HAVE_EEPROM_SETTINGS
450 eeprom_settings_init();
451 #endif
453 usb_start_monitoring();
454 #ifndef HAVE_USBSTACK
455 while (usb_detect() == USB_INSERTED)
457 #ifdef HAVE_EEPROM_SETTINGS
458 firmware_settings.disk_clean = false;
459 #endif
460 /* enter USB mode early, before trying to mount */
461 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
462 #ifdef HAVE_MMC
463 if (!mmc_touched() ||
464 (mmc_remove_request() == SYS_HOTSWAP_EXTRACTED))
465 #endif
467 usb_screen();
468 mounted = true; /* mounting done @ end of USB mode */
470 #ifdef HAVE_USB_POWER
471 if (usb_powered()) /* avoid deadlock */
472 break;
473 #endif
475 #endif
477 if (!mounted)
479 rc = disk_mount_all();
480 if (rc<=0)
482 lcd_clear_display();
483 lcd_puts(0, 0, "No partition");
484 lcd_puts(0, 1, "found.");
485 #ifdef HAVE_LCD_BITMAP
486 lcd_puts(0, 2, "Insert USB cable");
487 lcd_puts(0, 3, "and fix it.");
488 #endif
489 lcd_update();
491 while(button_get(true) != SYS_USB_CONNECTED) {};
492 usb_screen();
493 system_reboot();
497 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
498 (CONFIG_KEYPAD == IRIVER_H10_PAD)
499 #ifdef SETTINGS_RESET
500 /* Reset settings if holding the reset button. (Rec on Archos,
501 A on Gigabeat) */
502 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
503 #else
504 /* Reset settings if the hold button is turned on */
505 if (button_hold())
506 #endif
508 gui_syncsplash(HZ*2, str(LANG_RESET_DONE_CLEAR));
509 settings_reset();
511 else
512 #endif
513 settings_load(SETTINGS_ALL);
515 if (init_dircache(true) < 0)
517 #ifdef HAVE_TAGCACHE
518 remove(TAGCACHE_STATEFILE);
519 #endif
522 gui_sync_wps_init();
523 settings_apply(true);
524 init_dircache(false);
525 #ifdef HAVE_TAGCACHE
526 init_tagcache();
527 #endif
529 #ifdef HAVE_EEPROM_SETTINGS
530 if (firmware_settings.initialized)
532 /* In case we crash. */
533 firmware_settings.disk_clean = false;
534 eeprom_settings_store();
536 #endif
537 status_init();
538 playlist_init();
539 tree_mem_init();
540 filetype_init();
541 scrobbler_init();
542 cuesheet_init();
544 #if CONFIG_CODEC != SWCODEC
545 /* No buffer allocation (see buffer.c) may take place after the call to
546 audio_init() since the mpeg thread takes the rest of the buffer space */
547 mp3_init( global_settings.volume,
548 global_settings.bass,
549 global_settings.treble,
550 global_settings.balance,
551 global_settings.loudness,
552 global_settings.avc,
553 global_settings.channel_config,
554 global_settings.stereo_width,
555 global_settings.mdb_strength,
556 global_settings.mdb_harmonics,
557 global_settings.mdb_center,
558 global_settings.mdb_shape,
559 global_settings.mdb_enable,
560 global_settings.superbass);
562 /* audio_init must to know the size of voice buffer so init voice first */
563 talk_init();
564 #endif /* CONFIG_CODEC != SWCODEC */
566 audio_init();
568 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
569 pcm_rec_init();
570 #endif
572 /* runtime database has to be initialized after audio_init() */
573 cpu_boost(false);
575 #ifdef AUTOROCK
577 int fd;
578 static const char filename[] = PLUGIN_APPS_DIR "/autostart.rock";
580 fd = open(filename, O_RDONLY);
581 if(fd >= 0) /* no complaint if it doesn't exist */
583 close(fd);
584 plugin_load((char*)filename, NULL); /* start if it does */
587 #endif /* #ifdef AUTOROCK */
589 #if CONFIG_CHARGING
590 car_adapter_mode_init();
591 #endif
594 #ifdef CPU_PP
595 void cop_main(void)
597 /* This is the entry point for the coprocessor
598 Anyone not running an upgraded bootloader will never reach this point,
599 so it should not be assumed that the coprocessor be usable even on
600 platforms which support it.
602 A kernel thread is initially setup on the coprocessor and immediately
603 destroyed for purposes of continuity. The cop sits idle until at least
604 one thread exists on it. */
606 /* 3G doesn't have Rolo or dual core support yet */
607 #if NUM_CORES > 1
608 system_init();
609 kernel_init();
610 /* This should never be reached */
611 #endif
612 while(1) {
613 COP_CTL = PROC_SLEEP;
616 #endif /* CPU_PP */
618 int main(void)
620 app_main();
622 while(1) {
623 #if (CONFIG_LED == LED_REAL)
624 led(true); sleep(HZ/10);
625 led(false); sleep(HZ/10);
626 #endif
628 return 0;
630 #endif