X5: Assembler optimised remote LCD update. Speedup: 3 times @11MHz, 3.3 times @45MHz...
[Rockbox.git] / apps / main.c
blob90bd13ee320b7a99fddee0b0f97e4fba528c6778
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 by 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 "panic.h"
32 #include "menu.h"
33 #include "system.h"
34 #include "usb.h"
35 #include "powermgmt.h"
36 #include "adc.h"
37 #include "i2c.h"
38 #ifndef DEBUG
39 #include "serial.h"
40 #endif
41 #include "audio.h"
42 #include "mp3_playback.h"
43 #include "thread.h"
44 #include "settings.h"
45 #include "backlight.h"
46 #include "status.h"
47 #include "debug_menu.h"
48 #include "version.h"
49 #include "sprintf.h"
50 #include "font.h"
51 #include "language.h"
52 #include "gwps.h"
53 #include "playlist.h"
54 #include "buffer.h"
55 #include "rolo.h"
56 #include "screens.h"
57 #include "power.h"
58 #include "talk.h"
59 #include "plugin.h"
60 #include "misc.h"
61 #include "database.h"
62 #include "dircache.h"
63 #include "tagcache.h"
64 #include "tagtree.h"
65 #include "lang.h"
66 #include "string.h"
67 #include "splash.h"
68 #include "eeprom_settings.h"
70 #if (CONFIG_CODEC == SWCODEC)
71 #include "playback.h"
72 #include "pcmbuf.h"
73 #else
74 #define pcmbuf_init()
75 #endif
76 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
77 #include "pcm_record.h"
78 #define SETTINGS_RESET BUTTON_REC
79 #endif
81 #ifdef CONFIG_TUNER
82 #include "radio.h"
83 #endif
84 #ifdef HAVE_MMC
85 #include "ata_mmc.h"
86 #endif
88 #ifdef HAVE_REMOTE_LCD
89 #include "lcd-remote.h"
90 #endif
92 #if CONFIG_USBOTG == USBOTG_ISP1362
93 #include "isp1362.h"
94 #endif
96 #if CONFIG_USBOTG == USBOTG_M5636
97 #include "m5636.h"
98 #endif
100 /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
102 const char appsversion[]=APPSVERSION;
104 void init(void);
106 void app_main(void)
108 init();
109 browse_root();
112 int init_dircache(bool preinit)
114 #ifdef HAVE_DIRCACHE
115 int result = 0;
116 bool clear = false;
118 if (preinit)
119 dircache_init();
121 if (global_settings.dircache)
123 # ifdef HAVE_EEPROM_SETTINGS
124 if (firmware_settings.initialized && firmware_settings.disk_clean
125 && preinit)
127 result = dircache_load(DIRCACHE_FILE);
128 remove(DIRCACHE_FILE);
129 if (result < 0)
131 firmware_settings.disk_clean = false;
132 if (global_settings.dircache_size >= 0)
133 dircache_build(global_settings.dircache_size);
136 return result;
138 # endif
140 if (preinit)
141 return -1;
143 if (!dircache_is_enabled()
144 && !dircache_is_initializing())
146 if (global_settings.dircache_size <= 0)
148 gui_syncsplash(0, true, str(LANG_DIRCACHE_BUILDING));
149 clear = true;
151 result = dircache_build(global_settings.dircache_size);
154 if (result < 0)
155 gui_syncsplash(0, true, "Failed! Result: %d", result);
157 if (clear)
159 backlight_on();
160 show_logo();
164 return result;
165 #else
166 (void)preinit;
167 return 0;
168 #endif
171 void init_tagcache(void)
173 bool clear = false;
175 tagcache_init();
177 while (!tagcache_is_initialized())
179 #ifdef HAVE_LCD_CHARCELLS
180 char buf[32];
181 #endif
182 int ret = tagcache_get_commit_step();
184 if (ret > 0)
186 #ifdef HAVE_LCD_BITMAP
187 gui_syncsplash(0, true, "%s [%d/%d]",
188 str(LANG_TAGCACHE_INIT), ret, TAG_COUNT);
189 #else
190 lcd_double_height(false);
191 snprintf(buf, sizeof(buf), " TC [%d/%d]", ret, TAG_COUNT);
192 lcd_puts(0, 1, buf);
193 #endif
194 clear = true;
196 sleep(HZ/4);
198 tagtree_init();
200 if (clear)
202 backlight_on();
203 show_logo();
207 #ifdef SIMULATOR
209 void init(void)
211 init_threads();
212 buffer_init();
213 lcd_init();
214 #ifdef HAVE_REMOTE_LCD
215 lcd_remote_init();
216 #endif
217 font_init();
218 show_logo();
219 button_init();
220 backlight_init();
221 lang_init();
222 /* Must be done before any code uses the multi-screen APi */
223 screen_access_init();
224 gui_syncstatusbar_init(&statusbars);
225 settings_reset();
226 settings_calc_config_sector();
227 settings_load(SETTINGS_ALL);
228 gui_sync_wps_init();
229 settings_apply();
230 init_dircache(true);
231 init_dircache(false);
232 init_tagcache();
233 sleep(HZ/2);
234 tree_init();
235 playlist_init();
236 mp3_init( global_settings.volume,
237 global_settings.bass,
238 global_settings.treble,
239 global_settings.balance,
240 global_settings.loudness,
241 global_settings.avc,
242 global_settings.channel_config,
243 global_settings.stereo_width,
244 global_settings.mdb_strength,
245 global_settings.mdb_harmonics,
246 global_settings.mdb_center,
247 global_settings.mdb_shape,
248 global_settings.mdb_enable,
249 global_settings.superbass);
251 #if CONFIG_CODEC == SWCODEC
252 audio_preinit();
253 #endif
255 /* audio_init must to know the size of voice buffer so init voice first */
256 #if CONFIG_CODEC == SWCODEC
257 talk_init();
258 #endif
260 audio_init();
261 button_clear_queue(); /* Empty the keyboard buffer */
264 #else
266 void init(void)
268 int rc;
269 bool mounted = false;
270 #if defined(CONFIG_CHARGING) && (CONFIG_CPU == SH7034)
271 /* if nobody initialized ATA before, I consider this a cold start */
272 bool coldstart = (PACR2 & 0x4000) != 0; /* starting from Flash */
273 #endif
274 system_init();
275 kernel_init();
277 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
278 set_cpu_frequency(CPUFREQ_NORMAL);
279 cpu_boost(true);
280 #endif
282 buffer_init();
284 settings_reset();
286 power_init();
288 set_irq_level(0);
289 lcd_init();
290 #ifdef HAVE_REMOTE_LCD
291 lcd_remote_init();
292 #endif
293 font_init();
294 show_logo();
295 lang_init();
297 #ifdef DEBUG
298 debug_init();
299 #else
300 #ifndef HAVE_MMC /* FIXME: This is also necessary for debug builds
301 * (do debug builds on the Ondio make sense?) */
302 serial_setup();
303 #endif
304 #endif
306 i2c_init();
308 #ifdef CONFIG_RTC
309 rtc_init();
310 #endif
311 #ifdef HAVE_RTC_RAM
312 settings_load(SETTINGS_RTC); /* early load parts of global_settings */
313 #endif
315 adc_init();
317 usb_init();
318 #if CONFIG_USBOTG == USBOTG_ISP1362
319 isp1362_init();
320 #elif CONFIG_USBOTG == USBOTG_M5636
321 m5636_init();
322 #endif
324 backlight_init();
326 button_init();
328 powermgmt_init();
330 #if CONFIG_CODEC == SWCODEC
331 audio_preinit();
332 #endif
334 #ifdef CONFIG_TUNER
335 radio_init();
336 #endif
338 /* Must be done before any code uses the multi-screen APi */
339 screen_access_init();
340 gui_syncstatusbar_init(&statusbars);
342 #if defined(CONFIG_CHARGING) && (CONFIG_CPU == SH7034)
343 if (coldstart && charger_inserted()
344 && !global_settings.car_adapter_mode
345 #ifdef ATA_POWER_PLAYERSTYLE
346 && !ide_powered() /* relies on probing result from bootloader */
347 #endif
350 rc = charging_screen(); /* display a "charging" screen */
351 if (rc == 1) /* charger removed */
352 power_off();
353 /* "On" pressed or USB connected: proceed */
354 show_logo(); /* again, to provide better visual feedback */
356 #endif
358 rc = ata_init();
359 if(rc)
361 #ifdef HAVE_LCD_BITMAP
362 char str[32];
363 lcd_clear_display();
364 snprintf(str, 31, "ATA error: %d", rc);
365 lcd_puts(0, 1, str);
366 lcd_puts(0, 3, "Press ON to debug");
367 lcd_update();
368 while(!(button_get(true) & BUTTON_REL)); /*DO NOT CHANGE TO ACTION SYSTEM */
369 dbg_ports();
370 #endif
371 panicf("ata: %d", rc);
374 #ifdef HAVE_EEPROM_SETTINGS
375 eeprom_settings_init();
376 #endif
378 usb_start_monitoring();
379 while (usb_detect())
381 #ifdef HAVE_EEPROM_SETTINGS
382 firmware_settings.disk_clean = false;
383 #endif
384 /* enter USB mode early, before trying to mount */
385 if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED)
386 #ifdef HAVE_MMC
387 if (!mmc_touched() || (mmc_remove_request() == SYS_MMC_EXTRACTED))
388 #endif
390 usb_screen();
391 mounted = true; /* mounting done @ end of USB mode */
393 #ifdef HAVE_USB_POWER
394 if (usb_powered()) /* avoid deadlock */
395 break;
396 #endif
399 if (!mounted)
401 rc = disk_mount_all();
402 if (rc<=0)
404 lcd_clear_display();
405 lcd_puts(0, 0, "No partition");
406 lcd_puts(0, 1, "found.");
407 #ifdef HAVE_LCD_BITMAP
408 lcd_puts(0, 2, "Insert USB cable");
409 lcd_puts(0, 3, "and fix it.");
410 lcd_update();
411 #endif
412 while(button_get(true) != SYS_USB_CONNECTED) {};
413 usb_screen();
414 system_reboot();
418 settings_calc_config_sector();
420 #if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD)
421 #ifdef SETTINGS_RESET
422 /* Reset settings if holding the rec button. */
423 if ((button_status() & SETTINGS_RESET) == SETTINGS_RESET)
424 #else
425 /* Reset settings if the hold button is turned on */
426 if (button_hold())
427 #endif
429 gui_syncsplash(HZ*2, true, str(LANG_RESET_DONE_CLEAR));
430 settings_reset();
432 else
433 #endif
434 settings_load(SETTINGS_ALL);
437 if (init_dircache(true) < 0)
439 remove(TAGCACHE_STATEFILE);
442 gui_sync_wps_init();
443 settings_apply();
444 init_dircache(false);
445 init_tagcache();
447 #ifdef HAVE_EEPROM_SETTINGS
448 if (firmware_settings.initialized)
450 /* In case we crash. */
451 firmware_settings.disk_clean = false;
452 eeprom_settings_store();
454 #endif
455 status_init();
456 playlist_init();
457 tree_init();
459 /* No buffer allocation (see buffer.c) may take place after the call to
460 audio_init() since the mpeg thread takes the rest of the buffer space */
461 mp3_init( global_settings.volume,
462 global_settings.bass,
463 global_settings.treble,
464 global_settings.balance,
465 global_settings.loudness,
466 global_settings.avc,
467 global_settings.channel_config,
468 global_settings.stereo_width,
469 global_settings.mdb_strength,
470 global_settings.mdb_harmonics,
471 global_settings.mdb_center,
472 global_settings.mdb_shape,
473 global_settings.mdb_enable,
474 global_settings.superbass);
476 /* audio_init must to know the size of voice buffer so init voice first */
477 talk_init();
479 audio_init();
480 #if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
481 pcm_rec_init();
482 #endif
484 /* runtime database has to be initialized after audio_init() */
485 cpu_boost(false);
487 #ifdef AUTOROCK
489 int fd;
490 static const char filename[] = PLUGIN_DIR "/autostart.rock";
492 fd = open(filename, O_RDONLY);
493 if(fd >= 0) /* no complaint if it doesn't exist */
495 close(fd);
496 plugin_load((char*)filename, NULL); /* start if it does */
499 #endif /* #ifdef AUTOROCK */
501 #ifdef CONFIG_CHARGING
502 car_adapter_mode_init();
503 #endif
506 #ifdef CPU_PP
507 void cop_main(void)
509 /* This is the entry point for the coprocessor
510 Anyone not running an upgraded bootloader will never reach this point,
511 so it should not be assumed that the coprocessor be usable even on
512 platforms which support it.
514 At present all we do is send the COP to sleep if anything wakes it. */
515 while(1) {
516 COP_CTL = PROC_SLEEP;
519 #endif
521 int main(void)
523 app_main();
525 while(1) {
526 #if CONFIG_LED == LED_REAL
527 led(true); sleep(HZ/10);
528 led(false); sleep(HZ/10);
529 #endif
531 return 0;
533 #endif