/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2005 by Jörg Hohensohn aka [IDC]Dragon * * This is "Bootbox", a minimalistic loader, rescue firmware for just * booting into a full features one. Aside from that it does charging * and USB mode, to enable copying the desired firmware. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "config.h" #include #include #include "cpu.h" #include "system.h" #include "lcd.h" #include "kernel.h" #include "thread.h" #include "storage.h" #include "disk.h" #include "font.h" #include "adc.h" #include "button.h" #include "panic.h" #include "power.h" #include "file.h" #include "buffer.h" #include "rolo.h" #include "usb.h" #include "powermgmt.h" static void usb_screen(void) { lcd_clear_display(); lcd_puts(0, 0, "USB mode"); lcd_update(); usb_acknowledge(SYS_USB_CONNECTED_ACK); while(usb_wait_for_disconnect_w_tmo(&button_queue, HZ)) { } } static void show_logo(void) { lcd_clear_display(); lcd_puts(0, 0, "Rockbox"); lcd_puts(0, 1, "Rescue boot"); lcd_update(); } #if CONFIG_CHARGING static void charging_screen(void) { unsigned int button; const char* msg; ide_power_enable(false); /* power down the disk, else would be spinning */ lcd_clear_display(); do { #ifdef ARCHOS_RECORDER if (charge_state == CHARGING) msg = "charging"; else if (charge_state == TOPOFF) msg = "topoff charge"; else if (charge_state == TRICKLE) msg = "trickle charge"; else msg = "not charging"; #else msg = "charging"; #endif lcd_puts(0, 0, msg); { char buf[32]; int battv = battery_voltage(); snprintf(buf, sizeof(buf), "%d.%02dV %d%%", battv / 1000, (battv % 1000) / 10, battery_level()); lcd_puts(0, 1, buf); } lcd_update(); button = button_get_w_tmo(HZ/2); #ifdef BUTTON_ON if (button == (BUTTON_ON | BUTTON_REL)) #else if (button == (BUTTON_RIGHT | BUTTON_REL)) #endif break; /* start */ else { if (usb_detect() == USB_INSERTED) break; else if (!charger_inserted()) power_off(); /* charger removed: power down */ } } while (1); } #endif /* CONFIG_CHARGING */ /* prompt user to plug USB and fix a problem */ static void prompt_usb(const char* msg1, const char* msg2) { int button; lcd_clear_display(); lcd_puts(0, 0, msg1); lcd_puts(0, 1, msg2); #ifdef HAVE_LCD_BITMAP lcd_puts(0, 2, "Insert USB cable"); lcd_puts(0, 3, "and fix it."); #endif lcd_update(); do { button = button_get(true); if (button == SYS_POWEROFF) { power_off(); } } while (button != SYS_USB_CONNECTED); usb_screen(); system_reboot(); } void main(void) { int rc; power_init(); system_init(); kernel_init(); buffer_init(); lcd_init(); show_logo(); enable_irq(); adc_init(); usb_init(); button_init(); powermgmt_init(); #if CONFIG_CHARGING && (CONFIG_CPU == SH7034) if (charger_inserted() #ifdef ATA_POWER_PLAYERSTYLE && !ide_powered() /* relies on probing result from bootloader */ #endif ) { charging_screen(); /* display a "charging" screen */ show_logo(); /* again, to provide better visual feedback */ } #endif rc = storage_init(); if(rc) { #ifdef HAVE_LCD_BITMAP char str[32]; lcd_clear_display(); snprintf(str, 31, "ATA error: %d", rc); lcd_puts(0, 1, str); lcd_update(); while(!(button_get(true) & BUTTON_REL)); #endif panicf("storage: %d", rc); } usb_start_monitoring(); while (usb_detect() == USB_INSERTED) { /* enter USB mode early, before trying to mount */ if (button_get_w_tmo(HZ/10) == SYS_USB_CONNECTED) { usb_screen(); } } rc = disk_mount_all(); if (rc<=0) { prompt_usb("No partition", "found."); } { // rolo the firmware static const char filename[] = "/" BOOTFILE; rolo_load((char*)filename); /* won't return if started */ prompt_usb("No firmware", filename); } } /* These functions are present in the firmware library, but we reimplement them here because the originals do a lot more than we want */ void audio_stop(void) { } int audio_status(void) { return 0; } void audio_stop_recording(void) { } void mp3_shutdown(void) { }