fix Tab navigation in rbutil, and make it also look at other places for rbutil.ini.
[kugel-rb.git] / apps / main.c
blobe515c9ddd265e0aa17599fe98023997d00a8375c
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"
73 #include "icon.h"
75 #if (CONFIG_CODEC == SWCODEC)
76 #include "playback.h"
77 #include "pcmbuf.h"
78 #else
79 #define pcmbuf_init()
80 #endif
81 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
82 #include "pcm_record.h"
83 #endif
85 #ifdef BUTTON_REC
86 #define SETTINGS_RESET BUTTON_REC
87 #elif (CONFIG_KEYPAD == GIGABEAT_PAD)
88 #define SETTINGS_RESET BUTTON_A
89 #endif
91 #if CONFIG_TUNER
92 #include "radio.h"
93 #endif
94 #ifdef HAVE_MMC
95 #include "ata_mmc.h"
96 #endif
98 #ifdef HAVE_REMOTE_LCD
99 #include "lcd-remote.h"
100 #endif
102 #if CONFIG_USBOTG == USBOTG_ISP1362
103 #include "isp1362.h"
104 #endif
106 #if CONFIG_USBOTG == USBOTG_M5636
107 #include "m5636.h"
108 #endif
110 #include "cuesheet.h"
112 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
114 const char appsversion[]=APPSVERSION;
116 static void init(void);
118 #ifdef SIMULATOR
119 void app_main(void)
120 #else
121 static void app_main(void)
122 #endif
124 init();
125 browse_root();
128 static int init_dircache(bool preinit)
130 #ifdef HAVE_DIRCACHE
131 int result = 0;
132 bool clear = false;
134 if (preinit)
135 dircache_init();
137 if (!global_settings.dircache)
138 return 0;
140 # ifdef HAVE_EEPROM_SETTINGS
141 if (firmware_settings.initialized && firmware_settings.disk_clean
142 && preinit)
144 result = dircache_load();
146 if (result < 0)
148 firmware_settings.disk_clean = false;
149 if (global_status.dircache_size <= 0)
151 /* This will be in default language, settings are not
152 applied yet. Not really any easy way to fix that. */
153 gui_syncsplash(0, str(LANG_DIRCACHE_BUILDING));
154 clear = true;
157 dircache_build(global_status.dircache_size);
160 else
161 # endif
163 if (preinit)
164 return -1;
166 if (!dircache_is_enabled()
167 && !dircache_is_initializing())
169 if (global_status.dircache_size <= 0)
171 gui_syncsplash(0, str(LANG_DIRCACHE_BUILDING));
172 clear = true;
174 result = dircache_build(global_status.dircache_size);
177 if (result < 0)
179 /* Initialization of dircache failed. Manual action is
180 * necessary to enable dircache again.
182 gui_syncsplash(0, "Dircache failed, disabled. Result: %d", result);
183 global_settings.dircache = false;
188 if (clear)
190 backlight_on();
191 show_logo();
192 global_status.dircache_size = dircache_get_cache_size();
193 status_save();
196 return result;
197 #else
198 (void)preinit;
199 return 0;
200 #endif
203 #ifdef HAVE_TAGCACHE
204 static void init_tagcache(void)
206 bool clear = false;
208 tagcache_init();
210 while (!tagcache_is_initialized())
212 #ifdef HAVE_LCD_CHARCELLS
213 char buf[32];
214 #endif
215 int ret = tagcache_get_commit_step();
217 if (ret > 0)
219 #ifdef HAVE_LCD_BITMAP
220 gui_syncsplash(0, "%s [%d/%d]",
221 str(LANG_TAGCACHE_INIT), ret,
222 tagcache_get_max_commit_step());
223 #else
224 lcd_double_height(false);
225 snprintf(buf, sizeof(buf), " DB [%d/%d]", ret,
226 tagcache_get_max_commit_step());
227 lcd_puts(0, 1, buf);
228 lcd_update();
229 #endif
230 clear = true;
232 sleep(HZ/4);
234 tagtree_init();
236 if (clear)
238 backlight_on();
239 show_logo();
242 #endif
244 #ifdef SIMULATOR
246 static void init(void)
248 init_threads();
249 buffer_init();
250 lcd_init();
251 #ifdef HAVE_REMOTE_LCD
252 lcd_remote_init();
253 #endif
254 font_init();
255 show_logo();
256 button_init();
257 backlight_init();
258 lang_init();
259 #ifdef DEBUG
260 debug_init();
261 #endif
262 /* Must be done before any code uses the multi-screen APi */
263 screen_access_init();
264 gui_syncstatusbar_init(&statusbars);
265 settings_reset();
266 settings_load(SETTINGS_ALL);
267 gui_sync_wps_init();
268 settings_apply();
269 init_dircache(true);
270 init_dircache(false);
271 #ifdef HAVE_TAGCACHE
272 init_tagcache();
273 #endif
274 sleep(HZ/2);
275 tree_init();
276 filetype_init();
277 playlist_init();
279 #if CONFIG_CODEC != SWCODEC
280 mp3_init( global_settings.volume,
281 global_settings.bass,
282 global_settings.treble,
283 global_settings.balance,
284 global_settings.loudness,
285 global_settings.avc,
286 global_settings.channel_config,
287 global_settings.stereo_width,
288 global_settings.mdb_strength,
289 global_settings.mdb_harmonics,
290 global_settings.mdb_center,
291 global_settings.mdb_shape,
292 global_settings.mdb_enable,
293 global_settings.superbass);
295 /* audio_init must to know the size of voice buffer so init voice first */
296 talk_init();
297 #endif /* CONFIG_CODEC != SWCODEC */
299 scrobbler_init();
300 cuesheet_init();
302 audio_init();
303 button_clear_queue(); /* Empty the keyboard buffer */
306 #else
308 static void init(void)
310 int rc;
311 bool mounted = false;
312 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
313 /* if nobody initialized ATA before, I consider this a cold start */
314 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
315 #endif
316 #ifdef CPU_PP
317 COP_CTL = PROC_WAKE;
318 #endif
319 system_init();
320 kernel_init();
322 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
323 set_cpu_frequency(CPUFREQ_NORMAL);
324 #ifdef CPU_COLDFIRE
325 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
326 #endif
327 cpu_boost(true);
328 #endif
330 buffer_init();
332 settings_reset();
334 power_init();
336 set_irq_level(0);
337 lcd_init();
338 #ifdef HAVE_REMOTE_LCD
339 lcd_remote_init();
340 #endif
341 font_init();
343 show_logo();
344 lang_init();
346 #ifdef DEBUG
347 debug_init();
348 #else
349 #if !defined(HAVE_FMADC) && !defined(HAVE_MMC)
350 serial_setup();
351 #endif
352 #endif
354 i2c_init();
356 #if CONFIG_RTC
357 rtc_init();
358 #endif
359 #ifdef HAVE_RTC_RAM
360 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
361 #endif
363 adc_init();
365 usb_init();
366 #if CONFIG_USBOTG == USBOTG_ISP1362
367 isp1362_init();
368 #elif CONFIG_USBOTG == USBOTG_M5636
369 m5636_init();
370 #endif
372 backlight_init();
374 button_init();
376 powermgmt_init();
378 #if CONFIG_TUNER
379 radio_init();
380 #endif
382 /* Must be done before any code uses the multi-screen APi */
383 screen_access_init();
384 gui_syncstatusbar_init(&statusbars);
386 #if CONFIG_CHARGING && (CONFIG_CPU == SH7034)
387 if (coldstart && charger_inserted()
388 && !global_settings.car_adapter_mode
389 #ifdef ATA_POWER_PLAYERSTYLE
390 && !ide_powered() /* relies on probing result from bootloader */
391 #endif
394 rc = charging_screen(); /* display a "charging" screen */
395 if (rc == 1) /* charger removed */
396 power_off();
397 /* "On" pressed or USB connected: proceed */
398 show_logo(); /* again, to provide better visual feedback */
400 #endif
402 ata_idle_notify_init();
403 rc = ata_init();
404 if(rc)
406 #ifdef HAVE_LCD_BITMAP
407 char str[32];
408 lcd_clear_display();
409 snprintf(str, 31, "ATA error: %d", rc);
410 lcd_puts(0, 1, str);
411 lcd_puts(0, 3, "Press ON to debug");
412 lcd_update();
413 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
414 dbg_ports();
415 #endif
416 panicf("ata: %d", rc);
419 #ifdef HAVE_EEPROM_SETTINGS
420 eeprom_settings_init();
421 #endif
423 usb_start_monitoring();
424 while (usb_detect())
426 #ifdef HAVE_EEPROM_SETTINGS
427 firmware_settings.disk_clean = false;
428 #endif
429 /* enter USB mode early, before trying to mount */
430 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
431 #ifdef HAVE_MMC
432 if (!mmc_touched() || (mmc_remove_request() == SYS_MMC_EXTRACTED))
433 #endif
435 usb_screen();
436 mounted = true; /* mounting done @ end of USB mode */
438 #ifdef HAVE_USB_POWER
439 if (usb_powered()) /* avoid deadlock */
440 break;
441 #endif
444 if (!mounted)
446 rc = disk_mount_all();
447 if (rc<=0)
449 lcd_clear_display();
450 lcd_puts(0, 0, "No partition");
451 lcd_puts(0, 1, "found.");
452 #ifdef HAVE_LCD_BITMAP
453 lcd_puts(0, 2, "Insert USB cable");
454 lcd_puts(0, 3, "and fix it.");
455 #endif
456 lcd_update();
458 while(button_get(true) != SYS_USB_CONNECTED) {};
459 usb_screen();
460 system_reboot();
464 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) || \
465 (CONFIG_KEYPAD == IRIVER_H10_PAD)
466 #ifdef SETTINGS_RESET
467 /* Reset settings if holding the reset button. (Rec on Archos,
468 A on Gigabeat) */
469 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
470 #else
471 /* Reset settings if the hold button is turned on */
472 if (button_hold())
473 #endif
475 gui_syncsplash(HZ*2, str(LANG_RESET_DONE_CLEAR));
476 settings_reset();
478 else
479 #endif
480 settings_load(SETTINGS_ALL);
482 if (init_dircache(true) < 0)
484 #ifdef HAVE_TAGCACHE
485 remove(TAGCACHE_STATEFILE);
486 #endif
489 gui_sync_wps_init();
490 settings_apply();
491 init_dircache(false);
492 #ifdef HAVE_TAGCACHE
493 init_tagcache();
494 #endif
496 #ifdef HAVE_EEPROM_SETTINGS
497 if (firmware_settings.initialized)
499 /* In case we crash. */
500 firmware_settings.disk_clean = false;
501 eeprom_settings_store();
503 #endif
504 status_init();
505 playlist_init();
506 tree_init();
507 filetype_init();
508 scrobbler_init();
509 cuesheet_init();
511 #if CONFIG_CODEC != SWCODEC
512 /* No buffer allocation (see buffer.c) may take place after the call to
513 audio_init() since the mpeg thread takes the rest of the buffer space */
514 mp3_init( global_settings.volume,
515 global_settings.bass,
516 global_settings.treble,
517 global_settings.balance,
518 global_settings.loudness,
519 global_settings.avc,
520 global_settings.channel_config,
521 global_settings.stereo_width,
522 global_settings.mdb_strength,
523 global_settings.mdb_harmonics,
524 global_settings.mdb_center,
525 global_settings.mdb_shape,
526 global_settings.mdb_enable,
527 global_settings.superbass);
529 /* audio_init must to know the size of voice buffer so init voice first */
530 talk_init();
531 #endif /* CONFIG_CODEC != SWCODEC */
533 audio_init();
535 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
536 pcm_rec_init();
537 #endif
539 /* runtime database has to be initialized after audio_init() */
540 cpu_boost(false);
542 #ifdef AUTOROCK
544 int fd;
545 static const char filename[] = PLUGIN_DIR "/autostart.rock";
547 fd = open(filename, O_RDONLY);
548 if(fd >= 0) /* no complaint if it doesn't exist */
550 close(fd);
551 plugin_load((char*)filename, NULL); /* start if it does */
554 #endif /* #ifdef AUTOROCK */
556 #if CONFIG_CHARGING
557 car_adapter_mode_init();
558 #endif
561 #ifdef CPU_PP
562 void cop_main(void)
564 /* This is the entry point for the coprocessor
565 Anyone not running an upgraded bootloader will never reach this point,
566 so it should not be assumed that the coprocessor be usable even on
567 platforms which support it.
569 A kernel thread runs on the coprocessor which waits for other threads to be
570 added, and gracefully handles RoLo */
572 #if CONFIG_CPU == PP5002
573 /* 3G doesn't have Rolo or dual core support yet */
574 while(1) {
575 COP_CTL = PROC_SLEEP;
577 #else
578 extern volatile unsigned char cpu_message;
580 system_init();
581 kernel_init();
583 while(cpu_message != COP_REBOOT) {
584 sleep(HZ);
586 rolo_restart_cop();
587 #endif /* PP5002 */
589 #endif /* CPU_PP */
591 int main(void)
593 app_main();
595 while(1) {
596 #if (CONFIG_LED == LED_REAL)
597 led(true); sleep(HZ/10);
598 led(false); sleep(HZ/10);
599 #endif
601 return 0;
603 #endif