1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2011 by amaury Pouly
12 * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
13 * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
23 ****************************************************************************/
29 #include "gcc_extensions.h"
31 #include "backlight.h"
32 #include "button-target.h"
38 #include "power-imx233.h"
39 #include "system-target.h"
40 #include "fmradio_i2c.h"
42 #include "powermgmt.h"
46 extern char loadaddress
[];
47 extern char loadaddressend
[];
49 #ifdef HAVE_BOOTLOADER_USB_MODE
50 static void usb_mode(int connect_timeout
)
55 usb_start_monitoring();
57 /* Wait for threads to connect or cable is pulled */
58 printf("USB: Connecting");
60 long end_tick
= current_tick
+ connect_timeout
;
64 button
= button_get_w_tmo(HZ
/10);
66 if(button
== SYS_USB_CONNECTED
)
69 if(TIME_AFTER(current_tick
, end_tick
))
71 /* Timed out waiting for the connect - will happen when connected
72 * to a charger through the USB port */
73 printf("USB: Timed out");
77 if(usb_detect() == USB_EXTRACTED
)
78 break; /* Cable pulled */
81 if(button
== SYS_USB_CONNECTED
)
83 /* Got the message - wait for disconnect */
84 printf("Bootloader USB mode");
85 /* Enable power management to charge */
88 usb_acknowledge(SYS_USB_CONNECTED_ACK
);
92 button
= button_get_w_tmo(HZ
/2);
93 if(button
== SYS_USB_DISCONNECTED
)
95 struct imx233_powermgmt_info_t info
= imx233_powermgmt_get_info();
96 lcd_putsf(0, 7, "Charging status: %s",
97 info
.state
== CHARGE_STATE_DISABLED
? "disabled" :
98 info
.state
== CHARGE_STATE_ERROR
? "error" :
99 info
.state
== DISCHARGING
? "discharging" :
100 info
.state
== TRICKLE
? "trickle" :
101 info
.state
== TOPOFF
? "topoff" :
102 info
.state
== CHARGING
? "charging" : "<unknown>");
103 lcd_putsf(0, 8, "Battery: %d%%", battery_level());
108 /* Put drivers initialized for USB connection into a known state */
111 #else /* !HAVE_BOOTLOADER_USB_MODE */
112 static void usb_mode(int connect_timeout
)
114 (void) connect_timeout
;
116 #endif /* HAVE_BOOTLOADER_USB_MODE */
118 void main(uint32_t arg
, uint32_t addr
) NORETURN_ATTR
;
119 void main(uint32_t arg
, uint32_t addr
)
121 unsigned char* loadbuffer
;
123 void(*kernel_entry
)(void);
140 //button_debug_screen();
141 printf("Boot version: %s", RBVERSION
);
142 printf("arg=%x addr=%x", arg
, addr
);
143 printf("power up source: %x", __XTRACT(HW_POWER_STS
, PWRUP_SOURCE
));
145 #ifdef SANSA_FUZEPLUS
146 extern void imx233_mmc_disable_window(void);
147 if(arg
== 0xfee1dead)
149 printf("Disable MMC window.");
150 imx233_mmc_disable_window();
154 ret
= storage_init();
156 error(EATA
, ret
, true);
158 /* NOTE: allow disk_init and disk_mount_all to fail since we can do USB after.
159 * We need this order to determine the correct logical sector size */
160 while(!disk_init(IF_MV(0)))
161 printf("disk_init failed!");
163 if((ret
= disk_mount_all()) <= 0)
164 error(EDISK
, ret
, false);
166 if(usb_detect() == USB_INSERTED
)
169 printf("Loading firmware");
171 loadbuffer
= (unsigned char*)loadaddress
;
172 buffer_size
= (int)(loadaddressend
- loadaddress
);
174 while((ret
= load_firmware(loadbuffer
, BOOTFILE
, buffer_size
)) < 0)
176 error(EBOOTFILE
, ret
, true);
179 kernel_entry
= (void*) loadbuffer
;
181 disable_interrupt(IRQ_FIQ_STATUS
);
182 commit_discard_idcache();
184 printf("ERR: Failed to boot");