From 15a0a3c263b308cd3aa35f6a196f3468a641ba50 Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Sun, 28 Nov 2010 23:10:09 +0000 Subject: Rename bootloader file for MPIO players as it supports both HD200 and HD300. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28700 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/SOURCES | 2 +- bootloader/mpio_hd200.c | 499 ----------------------------------------- bootloader/mpio_hd200_hd300.c | 502 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 503 insertions(+), 500 deletions(-) delete mode 100644 bootloader/mpio_hd200.c create mode 100644 bootloader/mpio_hd200_hd300.c (limited to 'bootloader') diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 97ed449..d16c516 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES @@ -64,5 +64,5 @@ show_logo.c main-pp.c show_logo.c #elif defined(MPIO_HD200) || defined(MPIO_HD300) -mpio_hd200.c +mpio_hd200_hd300.c #endif diff --git a/bootloader/mpio_hd200.c b/bootloader/mpio_hd200.c deleted file mode 100644 index dd4510a..0000000 --- a/bootloader/mpio_hd200.c +++ /dev/null @@ -1,499 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Marcin Bukat - * - * 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 "inttypes.h" -#include "string.h" -#include "cpu.h" -#include "system.h" -#include "lcd.h" -#include "kernel.h" -#include "thread.h" -#include "storage.h" -#include "usb.h" -#include "disk.h" -#include "font.h" -#include "adc.h" -#include "backlight.h" -#include "backlight-target.h" -#include "button.h" -#include "panic.h" -#include "power.h" -#include "powermgmt.h" -#include "file.h" - -#include "common.h" -#include "version.h" - -#include - -/* Maximum allowed firmware image size. 10MB is more than enough */ -#define MAX_LOADSIZE (10*1024*1024) - -#define DRAM_START 0x31000000 - -#define BOOTMENU_TIMEOUT (10*HZ) -#define BOOTMENU_OPTIONS 3 - -#define EVENT_NONE 0x00 -#define EVENT_ON 0x01 -#define EVENT_AC 0x02 -#define EVENT_USB 0x04 - -/* From common.c */ -extern int line; -static const char *bootmenu_options[] = { - "Boot rockbox", - "Boot MPIO firmware", - "Shutdown" -}; - -enum option_t { - rockbox, - mpio_firmware, - shutdown -}; - -int usb_screen(void) -{ - return 0; -} - -static inline bool _charger_inserted(void) -{ - return (GPIO1_READ & (1<<14)) ? false : true; -} - -static inline bool _battery_full(void) -{ - return (GPIO_READ & (1<<30)) ? true : false; -} - -/* Reset the cookie for the crt0 crash check */ -static inline void __reset_cookie(void) -{ - asm(" move.l #0,%d0"); - asm(" move.l %d0,0x10017ffc"); -} - -static void start_rockbox(void) -{ - adc_close(); - asm(" move.w #0x2700,%sr"); - __reset_cookie(); - asm(" move.l %0,%%d0" :: "i"(DRAM_START)); - asm(" movec.l %d0,%vbr"); - asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START)); - asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4))); - asm(" jmp (%a0)"); -} - -static void start_mpio_firmware(void) -{ - asm(" move.w #0x2700,%sr"); - __reset_cookie(); - asm(" movec.l %d0,%vbr"); - asm(" move.l 0,%sp"); - asm(" jmp 8"); -} - -static void __shutdown(void) -{ - if (_charger_inserted()) - /* if AC power do nothing */ - return; - - /* We need to gracefully spin down the disk to prevent clicks. */ - if (ide_powered()) - { - /* Make sure ATA has been initialized. */ - storage_init(); - - /* And put the disk into sleep immediately. */ - storage_sleepnow(); - } - - /* Backlight OFF */ - _backlight_off(); - __reset_cookie(); - - power_off(); -} - -/* Print the battery voltage (and a warning message). */ -static void check_battery(void) -{ - - int battery_voltage, batt_int, batt_frac; - - battery_voltage = battery_adc_voltage(); - batt_int = battery_voltage / 1000; - batt_frac = (battery_voltage % 1000) / 10; - - printf("Battery: %d.%02dV", batt_int, batt_frac); - - if (battery_voltage <= 3500) - { - printf("WARNING! BATTERY LOW!!"); - sleep(HZ*2); - } - -} - - -static void lcd_putstring_centered(const char *string) -{ - int w,h; - font_getstringsize(string, &w, &h, FONT_SYSFIXED); - lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, string); -} - -static void rb_boot(void) -{ - int rc; - - /* boost to speedup rb image loading */ - cpu_boost(true); - - rc = storage_init(); - if(rc) - { - printf("ATA error: %d", rc); - sleep(HZ*5); - return; - } - - disk_init(); - - rc = disk_mount_all(); - if (rc<=0) - { - printf("No partition found"); - sleep(HZ*5); - return; - } - - printf("Loading firmware"); - - rc = load_firmware((unsigned char *)DRAM_START, - BOOTFILE, MAX_LOADSIZE); - - if (rc < EOK) - { - printf("Error!"); - printf("Can't load " BOOTFILE ": "); - printf("Result: %s", strerror(rc)); - sleep(HZ*5); - return; - } - - cpu_boost(false); - start_rockbox(); -} - -static void bootmenu(void) -{ - enum option_t i; - enum option_t option = rockbox; - int button; - const char select[] = "->"; - long start_tick = current_tick; - - /* backbone of menu */ - /* run the loader */ - printf("Rockbox boot loader"); - printf("Ver: " RBVERSION); - - check_battery(); - - printf(""); - printf("========================="); - - line += BOOTMENU_OPTIONS+2; /* skip lines */ - - printf("========================="); - printf(""); - printf(" [FF] [REW] to move "); - printf(" [PLAY] to confirm "); - - /* content of menu and keys handling */ - while (TIME_BEFORE(current_tick,start_tick + BOOTMENU_TIMEOUT)) - { - /* Draw the menu. */ - line = 6; /* move below header */ - - for (i=0;i rockbox) - option--; - else - option = shutdown; - break; - - case BUTTON_FF: -#ifdef MPIO_HD200 - case BUTTON_RC_FF: -#endif - if (option < shutdown) - option++; - else - option = rockbox; - break; - - case BUTTON_PLAY: -#ifdef MPIO_HD200 - case BUTTON_RC_PLAY: - case (BUTTON_PLAY|BUTTON_REC): -#endif - reset_screen(); - - switch (option) - { - case rockbox: - rb_boot(); - break; - - case mpio_firmware: - start_mpio_firmware(); - break; - - default: - return; - break; - } - } -} -/* timeout */ -} - -void main(void) -{ - /* messages */ - const char usb_connect_msg[] = "Bootloader USB mode"; - const char charging_msg[] = "Charging..."; - const char complete_msg[] = "Charging complete"; - - /* helper variable for messages */ - bool blink_toggle = false; - - int button; - unsigned int event = EVENT_NONE; - unsigned int last_event = EVENT_NONE; - - /* this is default mode after power_init() */ - bool high_current_charging = true; - - /* setup GPIOs related to power functions */ - power_init(); - - system_init(); - kernel_init(); - - /* run at 45MHz */ - set_cpu_frequency(CPUFREQ_NORMAL); - - /* IRQs are needed by button driver */ - enable_irq(); - - lcd_init(); - - /* only lowlevel functions no queue init */ - _backlight_init(); - _backlight_hw_on(); - - /* setup font system*/ - font_init(); - lcd_setfont(FONT_SYSFIXED); - - /* buttons reading init*/ - adc_init(); - button_init(); - - usb_init(); - cpu_idle_mode(true); - - /* Handle wakeup event. Possibilities are: - * ON button (PLAY) - * USB insert - * AC charger plug - */ - - while(1) - { - /* read buttons */ - event = EVENT_NONE; - button = button_get_w_tmo(HZ); - - if ( (button & BUTTON_PLAY) -#ifdef MPIO_HD200 - || (button & BUTTON_RC_PLAY) -#endif - ) - event |= EVENT_ON; - - if ( usb_detect() == USB_INSERTED ) - event |= EVENT_USB; - - if ( _charger_inserted() ) - event |= EVENT_AC; - - reset_screen(); - switch (event) - { - case EVENT_ON: - case (EVENT_ON | EVENT_AC): - /* hold is handled in button driver */ - cpu_idle_mode(false); - ide_power_enable(true); - - if (button == (BUTTON_PLAY|BUTTON_REC)) - bootmenu(); - else - rb_boot(); - - break; - - case EVENT_AC: - /* AC plug in */ - if (!(last_event & EVENT_AC)) - { - /* reset charging circuit */ - and_l(~(1<<23), &GPIO_ENABLE); - } - - /* USB unplug */ - if (last_event & EVENT_USB) - { - usb_enable(false); - sleep(HZ); - ide_power_enable(false); - sleep(HZ); - } - - if(!_battery_full()) - { - if (blink_toggle) - lcd_putstring_centered(charging_msg); - - blink_toggle = !blink_toggle; - } - else /* end of charge condition */ - { - /* put LTC1733 into shutdown mode */ - or_l((1<<23), &GPIO_ENABLE); - - if (high_current_charging) - { - /* switch to low current mode */ - and_l(~(1<<15), &GPIO_OUT); - - /* reset charging circuit */ - and_l(~(1<<23), &GPIO_ENABLE); - - high_current_charging = false; - } - else - { - lcd_putstring_centered(complete_msg); - } - } - check_battery(); - break; - - case EVENT_USB: - case (EVENT_USB | EVENT_AC): - /* AC plug in while in USB mode */ - if (!(last_event & EVENT_AC)) - { - /* reset charger circuit */ - and_l(~(1<<23), &GPIO_ENABLE); - } - - /* USB plug in */ - if (!(last_event & EVENT_USB)) - { - /* init USB */ - ide_power_enable(true); - sleep(HZ/20); - usb_enable(true); - } - - /* display blinking USB indicator */ - line = 0; - - if (blink_toggle) - lcd_putstring_centered(usb_connect_msg); - - check_battery(); - blink_toggle = !blink_toggle; - storage_spin(); - break; - - default: - /* USB unplug */ - if (last_event & EVENT_USB) - { - /* disable USB */ - usb_enable(false); - sleep(HZ); - ide_power_enable(false); - sleep(HZ); - } - - /* spurious wakeup ?*/ - __shutdown(); - break; - } - lcd_update(); - last_event = event; - } - -} - -/* These functions are present in the firmware library, but we reimplement - them here because the originals do a lot more than we want */ -void screen_dump(void) -{ -} diff --git a/bootloader/mpio_hd200_hd300.c b/bootloader/mpio_hd200_hd300.c new file mode 100644 index 0000000..7d6c608 --- /dev/null +++ b/bootloader/mpio_hd200_hd300.c @@ -0,0 +1,502 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Marcin Bukat + * + * 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 "inttypes.h" +#include "string.h" +#include "cpu.h" +#include "system.h" +#include "lcd.h" +#include "kernel.h" +#include "thread.h" +#include "storage.h" +#include "usb.h" +#include "disk.h" +#include "font.h" +#include "adc.h" +#include "backlight.h" +#include "backlight-target.h" +#include "button.h" +#include "panic.h" +#include "power.h" +#include "powermgmt.h" +#include "file.h" + +#include "common.h" +#include "version.h" + +#include + +/* Maximum allowed firmware image size. 10MB is more than enough */ +#define MAX_LOADSIZE (10*1024*1024) + +#define DRAM_START 0x31000000 + +#define BOOTMENU_TIMEOUT (10*HZ) +#define BOOTMENU_OPTIONS 3 + +#define EVENT_NONE 0x00 +#define EVENT_ON 0x01 +#define EVENT_AC 0x02 +#define EVENT_USB 0x04 + +/* From common.c */ +extern int line; +static const char *bootmenu_options[] = { + "Boot rockbox", + "Boot MPIO firmware", + "Shutdown" +}; + +enum option_t { + rockbox, + mpio_firmware, + shutdown +}; + +int usb_screen(void) +{ + return 0; +} + +static inline bool _charger_inserted(void) +{ + return (GPIO1_READ & (1<<14)) ? false : true; +} + +static inline bool _battery_full(void) +{ + return (GPIO_READ & (1<<30)) ? true : false; +} + +/* Reset the cookie for the crt0 crash check */ +static inline void __reset_cookie(void) +{ + asm(" move.l #0,%d0"); + asm(" move.l %d0,0x10017ffc"); +} + +static void start_rockbox(void) +{ + adc_close(); + asm(" move.w #0x2700,%sr"); + __reset_cookie(); + asm(" move.l %0,%%d0" :: "i"(DRAM_START)); + asm(" movec.l %d0,%vbr"); + asm(" move.l %0,%%sp" :: "m"(*(int *)DRAM_START)); + asm(" move.l %0,%%a0" :: "m"(*(int *)(DRAM_START+4))); + asm(" jmp (%a0)"); +} + +static void start_mpio_firmware(void) +{ + asm(" move.w #0x2700,%sr"); + __reset_cookie(); + asm(" movec.l %d0,%vbr"); + asm(" move.l 0,%sp"); + asm(" jmp 8"); +} + +static void __shutdown(void) +{ + if (_charger_inserted()) + /* if AC power do nothing */ + return; + + /* We need to gracefully spin down the disk to prevent clicks. */ + if (ide_powered()) + { + /* Make sure ATA has been initialized. */ + storage_init(); + + /* And put the disk into sleep immediately. */ + storage_sleepnow(); + } + + /* Backlight OFF */ + _backlight_off(); + __reset_cookie(); + + power_off(); +} + +/* Print the battery voltage (and a warning message). */ +static void check_battery(void) +{ + + int battery_voltage, batt_int, batt_frac; + + battery_voltage = battery_adc_voltage(); + batt_int = battery_voltage / 1000; + batt_frac = (battery_voltage % 1000) / 10; + + printf("Battery: %d.%02dV", batt_int, batt_frac); + + if (battery_voltage <= 3500) + { + printf("WARNING! BATTERY LOW!!"); + sleep(HZ*2); + } + +} + + +static void lcd_putstring_centered(const char *string) +{ + int w,h; + font_getstringsize(string, &w, &h, FONT_SYSFIXED); + lcd_putsxy((LCD_WIDTH-w)/2, (LCD_HEIGHT-h)/2, string); +} + +static void rb_boot(void) +{ + int rc; + + /* boost to speedup rb image loading */ + cpu_boost(true); + + printf("Rockbox boot loader"); + printf("Version " RBVERSION); + + rc = storage_init(); + if(rc) + { + printf("ATA error: %d", rc); + sleep(HZ*5); + return; + } + + disk_init(); + + rc = disk_mount_all(); + if (rc<=0) + { + printf("No partition found"); + sleep(HZ*5); + return; + } + + printf("Loading firmware"); + + rc = load_firmware((unsigned char *)DRAM_START, + BOOTFILE, MAX_LOADSIZE); + + if (rc < EOK) + { + printf("Error!"); + printf("Can't load " BOOTFILE ": "); + printf("Result: %s", strerror(rc)); + sleep(HZ*5); + return; + } + + cpu_boost(false); + start_rockbox(); +} + +static void bootmenu(void) +{ + enum option_t i; + enum option_t option = rockbox; + int button; + const char select[] = "->"; + long start_tick = current_tick; + + /* backbone of menu */ + /* run the loader */ + printf("Rockbox boot loader"); + printf("Ver: " RBVERSION); + + check_battery(); + + printf(""); + printf("========================="); + + line += BOOTMENU_OPTIONS+2; /* skip lines */ + + printf("========================="); + printf(""); + printf(" [FF] [REW] to move "); + printf(" [PLAY] to confirm "); + + /* content of menu and keys handling */ + while (TIME_BEFORE(current_tick,start_tick + BOOTMENU_TIMEOUT)) + { + /* Draw the menu. */ + line = 6; /* move below header */ + + for (i=0;i rockbox) + option--; + else + option = shutdown; + break; + + case BUTTON_FF: +#ifdef MPIO_HD200 + case BUTTON_RC_FF: +#endif + if (option < shutdown) + option++; + else + option = rockbox; + break; + + case BUTTON_PLAY: +#ifdef MPIO_HD200 + case BUTTON_RC_PLAY: + case (BUTTON_PLAY|BUTTON_REC): +#endif + reset_screen(); + + switch (option) + { + case rockbox: + rb_boot(); + break; + + case mpio_firmware: + start_mpio_firmware(); + break; + + default: + return; + break; + } + } +} +/* timeout */ +} + +void main(void) +{ + /* messages */ + const char usb_connect_msg[] = "Bootloader USB mode"; + const char charging_msg[] = "Charging..."; + const char complete_msg[] = "Charging complete"; + + /* helper variable for messages */ + bool blink_toggle = false; + + int button; + unsigned int event = EVENT_NONE; + unsigned int last_event = EVENT_NONE; + + /* this is default mode after power_init() */ + bool high_current_charging = true; + + /* setup GPIOs related to power functions */ + power_init(); + + system_init(); + kernel_init(); + + /* run at 45MHz */ + set_cpu_frequency(CPUFREQ_NORMAL); + + /* IRQs are needed by button driver */ + enable_irq(); + + lcd_init(); + + /* only lowlevel functions no queue init */ + _backlight_init(); + _backlight_hw_on(); + + /* setup font system*/ + font_init(); + lcd_setfont(FONT_SYSFIXED); + + /* buttons reading init*/ + adc_init(); + button_init(); + + usb_init(); + cpu_idle_mode(true); + + /* Handle wakeup event. Possibilities are: + * ON button (PLAY) + * USB insert + * AC charger plug + */ + + while(1) + { + /* read buttons */ + event = EVENT_NONE; + button = button_get_w_tmo(HZ); + + if ( (button & BUTTON_PLAY) +#ifdef MPIO_HD200 + || (button & BUTTON_RC_PLAY) +#endif + ) + event |= EVENT_ON; + + if ( usb_detect() == USB_INSERTED ) + event |= EVENT_USB; + + if ( _charger_inserted() ) + event |= EVENT_AC; + + reset_screen(); + switch (event) + { + case EVENT_ON: + case (EVENT_ON | EVENT_AC): + /* hold is handled in button driver */ + cpu_idle_mode(false); + ide_power_enable(true); + + if (button == (BUTTON_PLAY|BUTTON_REC)) + bootmenu(); + else + rb_boot(); + + break; + + case EVENT_AC: + /* AC plug in */ + if (!(last_event & EVENT_AC)) + { + /* reset charging circuit */ + and_l(~(1<<23), &GPIO_ENABLE); + } + + /* USB unplug */ + if (last_event & EVENT_USB) + { + usb_enable(false); + sleep(HZ); + ide_power_enable(false); + sleep(HZ); + } + + if(!_battery_full()) + { + if (blink_toggle) + lcd_putstring_centered(charging_msg); + + blink_toggle = !blink_toggle; + } + else /* end of charge condition */ + { + /* put LTC1733 into shutdown mode */ + or_l((1<<23), &GPIO_ENABLE); + + if (high_current_charging) + { + /* switch to low current mode */ + and_l(~(1<<15), &GPIO_OUT); + + /* reset charging circuit */ + and_l(~(1<<23), &GPIO_ENABLE); + + high_current_charging = false; + } + else + { + lcd_putstring_centered(complete_msg); + } + } + check_battery(); + break; + + case EVENT_USB: + case (EVENT_USB | EVENT_AC): + /* AC plug in while in USB mode */ + if (!(last_event & EVENT_AC)) + { + /* reset charger circuit */ + and_l(~(1<<23), &GPIO_ENABLE); + } + + /* USB plug in */ + if (!(last_event & EVENT_USB)) + { + /* init USB */ + ide_power_enable(true); + sleep(HZ/20); + usb_enable(true); + } + + /* display blinking USB indicator */ + line = 0; + + if (blink_toggle) + lcd_putstring_centered(usb_connect_msg); + + check_battery(); + blink_toggle = !blink_toggle; + storage_spin(); + break; + + default: + /* USB unplug */ + if (last_event & EVENT_USB) + { + /* disable USB */ + usb_enable(false); + sleep(HZ); + ide_power_enable(false); + sleep(HZ); + } + + /* spurious wakeup ?*/ + __shutdown(); + break; + } + lcd_update(); + last_event = event; + } + +} + +/* These functions are present in the firmware library, but we reimplement + them here because the originals do a lot more than we want */ +void screen_dump(void) +{ +} -- cgit v1.1