summaryrefslogtreecommitdiff
path: root/bootloader
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader')
-rw-r--r--bootloader/SOURCES1
-rw-r--r--bootloader/common.c3
-rw-r--r--bootloader/gigabeat-s.c155
3 files changed, 83 insertions, 76 deletions
diff --git a/bootloader/SOURCES b/bootloader/SOURCES
index d16c51690e..c56acb25ba 100644
--- a/bootloader/SOURCES
+++ b/bootloader/SOURCES
@@ -8,6 +8,7 @@ ipod.c
8gigabeat.c 8gigabeat.c
9#elif defined(GIGABEAT_S) 9#elif defined(GIGABEAT_S)
10gigabeat-s.c 10gigabeat-s.c
11show_logo.c
11../firmware/target/arm/imx31/mmu-imx31.c 12../firmware/target/arm/imx31/mmu-imx31.c
12#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \ 13#elif defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \
13 defined(SANSA_E200) || defined(SANSA_C200) || \ 14 defined(SANSA_E200) || defined(SANSA_C200) || \
diff --git a/bootloader/common.c b/bootloader/common.c
index 8c587edf51..8fb7cdef36 100644
--- a/bootloader/common.c
+++ b/bootloader/common.c
@@ -45,7 +45,8 @@
45 || defined(SAMSUNG_YH925) || defined(SAMSUNG_YH920) \ 45 || defined(SAMSUNG_YH925) || defined(SAMSUNG_YH920) \
46 || defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \ 46 || defined(SAMSUNG_YH820) || defined(PHILIPS_SA9200) \
47 || defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \ 47 || defined(PHILIPS_HDD1630) || defined(PHILIPS_HDD6330) \
48 || defined(ONDA_VX747) || defined(PBELL_VIBE500) 48 || defined(ONDA_VX747) || defined(PBELL_VIBE500) \
49 || defined(TOSHIBA_GIGABEAT_S)
49bool verbose = false; 50bool verbose = false;
50#else 51#else
51bool verbose = true; 52bool verbose = true;
diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c
index 77887f5d4b..06f675644c 100644
--- a/bootloader/gigabeat-s.c
+++ b/bootloader/gigabeat-s.c
@@ -30,6 +30,7 @@
30#include "dir.h" 30#include "dir.h"
31#include "disk.h" 31#include "disk.h"
32#include "common.h" 32#include "common.h"
33#include "power.h"
33#include "backlight.h" 34#include "backlight.h"
34#include "usb.h" 35#include "usb.h"
35#include "button.h" 36#include "button.h"
@@ -38,6 +39,9 @@
38#include "usb-target.h" 39#include "usb-target.h"
39#include "version.h" 40#include "version.h"
40 41
42/* Show the Rockbox logo - in show_logo.c */
43extern int show_logo(void);
44
41#define TAR_CHUNK 512 45#define TAR_CHUNK 512
42#define TAR_HEADER_SIZE 157 46#define TAR_HEADER_SIZE 157
43 47
@@ -51,67 +55,44 @@ static void * const load_buf = 0x00000000;
51static const size_t load_buf_size = 0x20000000 - 0x100000; 55static const size_t load_buf_size = 0x20000000 - 0x100000;
52static const void * const start_addr = 0x00000000; 56static const void * const start_addr = 0x00000000;
53 57
54static void show_splash(int timeout, const char *msg) 58/* Show a message + "Shutting down...", then power off the device */
59static void display_message_and_power_off(int timeout, const char *msg)
55{ 60{
56 backlight_on(); 61 verbose = true;
57 reset_screen(); 62 printf(msg);
58 lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, 63 printf("Shutting down...");
59 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
60 lcd_update();
61
62 sleep(timeout); 64 sleep(timeout);
65 power_off();
63} 66}
64 67
65static bool pause_if_button_pressed(bool pre_usb) 68static void check_battery_safe(void)
66{ 69{
67 while (1) 70 if (battery_level_safe())
68 { 71 return;
69 int button = button_read_device();
70
71 if (pre_usb && !usb_plugged())
72 return false;
73
74 /* Exit if no button or only select buttons that have other
75 * functions */
76 switch (button)
77 {
78 case USB_BL_INSTALL_MODE_BTN:
79 if (!pre_usb)
80 break; /* Only before USB detect */
81 case BUTTON_MENU: /* Settings reset */
82 case BUTTON_NONE: /* Nothing pressed */
83 return true;
84 }
85
86 sleep(HZ/5);
87 72
88 /* If the disk powers off, the firmware will lock at startup */ 73 display_message_and_power_off(HZ, "Battery low");
89 storage_spin();
90 }
91} 74}
92 75
93/* TODO: Handle charging while connected */ 76/* TODO: Handle charging while connected */
94static void handle_usb(void) 77static void handle_usb(int connect_timeout)
95{ 78{
79 long end_tick = 0;
96 int button; 80 int button;
97 81
98 /* Check if plugged and pause to look at messages. If the cable was pulled
99 * while waiting, proceed as if it never was plugged. */
100 if (!usb_plugged() || !pause_if_button_pressed(true))
101 return;
102
103 /** Enter USB mode **/
104
105 /* We need full button and backlight handling now */ 82 /* We need full button and backlight handling now */
106 backlight_init(); 83 backlight_init();
107 button_init(); 84 button_init();
85 backlight_on();
108 86
109 /* Start the USB driver */ 87 /* Start the USB driver */
110 usb_init(); 88 usb_init();
111 usb_start_monitoring(); 89 usb_start_monitoring();
112 90
113 /* Wait for threads to connect or cable is pulled */ 91 /* Wait for threads to connect or cable is pulled */
114 show_splash(HZ/2, "Waiting for USB"); 92 printf("USB: Connecting");
93
94 if (connect_timeout != TIMEOUT_BLOCK)
95 end_tick = current_tick + connect_timeout;
115 96
116 while (1) 97 while (1)
117 { 98 {
@@ -120,35 +101,47 @@ static void handle_usb(void)
120 if (button == SYS_USB_CONNECTED) 101 if (button == SYS_USB_CONNECTED)
121 break; /* Hit */ 102 break; /* Hit */
122 103
104 if (connect_timeout != TIMEOUT_BLOCK &&
105 TIME_AFTER(current_tick, end_tick))
106 {
107 /* Timed out waiting for the connect - will happen when connected
108 * to a charger through the USB port */
109 printf("USB: Timed out");
110 break;
111 }
112
123 if (!usb_plugged()) 113 if (!usb_plugged())
124 break; /* Cable pulled */ 114 break; /* Cable pulled */
125 } 115 }
126 116
127 if (button == SYS_USB_CONNECTED) 117 if (button == SYS_USB_CONNECTED)
128 { 118 {
119 /* Switch to verbose mode if not in it so that the status updates
120 * are shown */
121 verbose = true;
129 /* Got the message - wait for disconnect */ 122 /* Got the message - wait for disconnect */
130 show_splash(0, "Bootloader USB mode"); 123 printf("Bootloader USB mode");
131 124
132 usb_acknowledge(SYS_USB_CONNECTED_ACK); 125 usb_acknowledge(SYS_USB_CONNECTED_ACK);
133 126
134 while (1) 127 while (1)
135 { 128 {
136 button = button_get(true); 129 button = button_get_w_tmo(HZ/2);
137 if (button == SYS_USB_DISCONNECTED) 130 if (button == SYS_USB_DISCONNECTED)
138 break; 131 break;
132
133 check_battery_safe();
139 } 134 }
135
136 backlight_on();
137 /* Sleep a little to let the backlight ramp up */
138 sleep(HZ*5/4);
140 } 139 }
141 140
142 /* Put drivers initialized for USB connection into a known state */ 141 /* Put drivers initialized for USB connection into a known state */
143 backlight_on();
144 usb_close(); 142 usb_close();
145 button_close(); 143 button_close();
146 backlight_close(); 144 backlight_close();
147
148 /* Sleep a little to let the backlight ramp up */
149 sleep(HZ*5/4);
150
151 reset_screen();
152} 145}
153 146
154static void untar(int tar_fd) 147static void untar(int tar_fd)
@@ -265,6 +258,7 @@ static void handle_untar(void)
265 model[4] = 0; 258 model[4] = 0;
266 if (strcmp(model, "gigs") == 0) 259 if (strcmp(model, "gigs") == 0)
267 { 260 {
261 verbose = true;
268 printf("Found rockbox binary. Moving..."); 262 printf("Found rockbox binary. Moving...");
269 close(fd); 263 close(fd);
270 remove( BOOTDIR "/" BOOTFILE); 264 remove( BOOTDIR "/" BOOTFILE);
@@ -283,6 +277,7 @@ static void handle_untar(void)
283 tarstring[5] = 0; 277 tarstring[5] = 0;
284 if (strcmp(tarstring, "ustar") == 0) 278 if (strcmp(tarstring, "ustar") == 0)
285 { 279 {
280 verbose = true;
286 printf("Found tar file. Unarchiving..."); 281 printf("Found tar file. Unarchiving...");
287 lseek(fd, 0, SEEK_SET); 282 lseek(fd, 0, SEEK_SET);
288 untar(fd); 283 untar(fd);
@@ -300,14 +295,27 @@ static void handle_untar(void)
300/* Try to load the firmware and run it */ 295/* Try to load the firmware and run it */
301static void NORETURN_ATTR handle_firmware_load(void) 296static void NORETURN_ATTR handle_firmware_load(void)
302{ 297{
303 int rc = load_firmware(load_buf, BOOTFILE, 298 int rc = load_firmware(load_buf, BOOTFILE, load_buf_size);
304 load_buf_size);
305 299
306 if(rc < 0) 300 if(rc < 0)
307 error(EBOOTFILE, rc, true); 301 error(EBOOTFILE, rc, true);
308 302
309 /* Pause to look at messages */ 303 /* Pause to look at messages */
310 pause_if_button_pressed(false); 304 while (1)
305 {
306 int button = button_read_device();
307
308 /* Ignore settings reset */
309 if (button == BUTTON_NONE || button == BUTTON_MENU)
310 break;
311
312 sleep(HZ/5);
313
314 check_battery_safe();
315
316 /* If the disk powers off, the firmware will lock at startup */
317 storage_spin();
318 }
311 319
312 /* Put drivers into a known state */ 320 /* Put drivers into a known state */
313 button_close_device(); 321 button_close_device();
@@ -316,7 +324,7 @@ static void NORETURN_ATTR handle_firmware_load(void)
316 324
317 if (rc == EOK) 325 if (rc == EOK)
318 { 326 {
319 cpucache_invalidate(); 327 cpucache_commit_discard();
320 asm volatile ("bx %0": : "r"(start_addr)); 328 asm volatile ("bx %0": : "r"(start_addr));
321 } 329 }
322 330
@@ -325,58 +333,55 @@ static void NORETURN_ATTR handle_firmware_load(void)
325 core_idle(); 333 core_idle();
326} 334}
327 335
328static void check_battery(void)
329{
330 int batt = battery_adc_voltage();
331 printf("Battery: %d.%03d V", batt / 1000, batt % 1000);
332 /* TODO: warn on low battery or shut down */
333}
334
335void main(void) 336void main(void)
336{ 337{
337 int rc; 338 int rc;
338 339 int batt;
339 /* Flush and invalidate all caches (because vectors were written) */
340 cpucache_invalidate();
341 340
342 system_init(); 341 system_init();
343 kernel_init(); 342 kernel_init();
344 343
345 enable_interrupt(IRQ_FIQ_STATUS); 344 enable_interrupt(IRQ_FIQ_STATUS);
346 345
347 lcd_init_device(); 346 /* Keep button_device_init early to delay calls to button_read_device */
347 button_init_device();
348
349 lcd_init();
350 font_init();
351 show_logo();
348 lcd_clear_display(); 352 lcd_clear_display();
349 353
354 if (button_hold())
355 display_message_and_power_off(HZ, "Hold switch on");
356
357 if (button_read_device() != BUTTON_NONE)
358 verbose = true;
359
350 printf("Gigabeat S Rockbox Bootloader"); 360 printf("Gigabeat S Rockbox Bootloader");
351 printf("Version " RBVERSION); 361 printf("Version " RBVERSION);
352 362
353 /* Initialize KPP so we can poll the button states */
354 button_init_device();
355
356 adc_init(); 363 adc_init();
357 364 batt = battery_adc_voltage();
358 check_battery(); 365 printf("Battery: %d.%03d V", batt / 1000, batt % 1000);
366 check_battery_safe();
359 367
360 rc = storage_init(); 368 rc = storage_init();
361 if(rc) 369 if(rc)
362 {
363 reset_screen();
364 error(EATA, rc, true); 370 error(EATA, rc, true);
365 }
366 371
367 disk_init(); 372 disk_init();
368 373
369 rc = disk_mount_all(); 374 rc = disk_mount_all();
370 if (rc<=0) 375 if (rc <= 0)
371 {
372 error(EDISK, rc, true); 376 error(EDISK, rc, true);
373 }
374 377
375 printf("Init complete"); 378 printf("Init complete");
376 379
377 /* Do USB first since a tar or binary could be added to the MTP directory 380 /* Do USB first since a tar or binary could be added to the MTP directory
378 * at the time and we can untar or move after unplugging. */ 381 * at the time and we can untar or move after unplugging. */
379 handle_usb(); 382 if (usb_plugged())
383 handle_usb(HZ*2);
384
380 handle_untar(); 385 handle_untar();
381 handle_firmware_load(); /* No return */ 386 handle_firmware_load(); /* No return */
382} 387}