diff options
Diffstat (limited to 'bootloader/fiiom3k.c')
-rw-r--r-- | bootloader/fiiom3k.c | 105 |
1 files changed, 87 insertions, 18 deletions
diff --git a/bootloader/fiiom3k.c b/bootloader/fiiom3k.c index 93010e86d2..9f169755ae 100644 --- a/bootloader/fiiom3k.c +++ b/bootloader/fiiom3k.c | |||
@@ -24,13 +24,17 @@ | |||
24 | #include "i2c.h" | 24 | #include "i2c.h" |
25 | #include "power.h" | 25 | #include "power.h" |
26 | #include "lcd.h" | 26 | #include "lcd.h" |
27 | #include "font.h" | ||
27 | #include "backlight.h" | 28 | #include "backlight.h" |
29 | #include "backlight-target.h" | ||
28 | #include "button.h" | 30 | #include "button.h" |
29 | #include "storage.h" | 31 | #include "storage.h" |
30 | #include "file_internal.h" | 32 | #include "file_internal.h" |
31 | #include "disk.h" | 33 | #include "disk.h" |
34 | #include "usb.h" | ||
32 | #include "rb-loader.h" | 35 | #include "rb-loader.h" |
33 | #include "loader_strerror.h" | 36 | #include "loader_strerror.h" |
37 | #include "version.h" | ||
34 | 38 | ||
35 | /* Load address where the binary needs to be placed */ | 39 | /* Load address where the binary needs to be placed */ |
36 | extern unsigned char loadaddress[]; | 40 | extern unsigned char loadaddress[]; |
@@ -53,20 +57,67 @@ void exec(void* dst, const void* src, int bytes) | |||
53 | __builtin_unreachable(); | 57 | __builtin_unreachable(); |
54 | } | 58 | } |
55 | 59 | ||
56 | static void error(const char* msg) | 60 | static bool lcd_inited = false; |
61 | static bool usb_inited = false; | ||
62 | |||
63 | static void init_lcd(void) | ||
57 | { | 64 | { |
58 | /* Initialization of the LCD/buttons only if needed */ | 65 | if(lcd_inited) |
66 | return; | ||
67 | |||
59 | lcd_init(); | 68 | lcd_init(); |
69 | font_init(); | ||
70 | lcd_setfont(FONT_SYSFIXED); | ||
71 | |||
72 | /* Clear screen before turning backlight on, otherwise we might | ||
73 | * display random garbage on the screen */ | ||
74 | lcd_clear_display(); | ||
75 | lcd_update(); | ||
76 | |||
60 | backlight_init(); | 77 | backlight_init(); |
61 | button_init(); | ||
62 | 78 | ||
79 | lcd_inited = true; | ||
80 | } | ||
81 | |||
82 | static void do_splash2(int delay, const char* msg, const char* msg2) | ||
83 | { | ||
84 | init_lcd(); | ||
63 | lcd_clear_display(); | 85 | lcd_clear_display(); |
64 | lcd_puts(0, 0, msg); | 86 | lcd_putsxy((LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, |
65 | lcd_puts(0, 2, "Press POWER to power off"); | 87 | (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); |
88 | if(msg2) { | ||
89 | lcd_putsxy((LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg2))) / 2, | ||
90 | (LCD_HEIGHT + 2*SYSFONT_HEIGHT) / 2, msg2); | ||
91 | } | ||
92 | |||
93 | lcd_putsxy((LCD_WIDTH - (SYSFONT_WIDTH * strlen(rbversion))) / 2, | ||
94 | (LCD_HEIGHT - SYSFONT_HEIGHT), rbversion); | ||
66 | lcd_update(); | 95 | lcd_update(); |
96 | sleep(delay); | ||
97 | } | ||
67 | 98 | ||
68 | while(button_get(true) != BUTTON_POWER); | 99 | static void do_splash(int delay, const char* msg) |
69 | power_off(); | 100 | { |
101 | do_splash2(delay, msg, NULL); | ||
102 | } | ||
103 | |||
104 | static void do_usb(void) | ||
105 | { | ||
106 | if(!usb_inited) { | ||
107 | usb_init(); | ||
108 | usb_start_monitoring(); | ||
109 | usb_inited = true; | ||
110 | } | ||
111 | |||
112 | do_splash(0, "Waiting for USB"); | ||
113 | |||
114 | while(button_get(true) != SYS_USB_CONNECTED); | ||
115 | do_splash(0, "USB mode"); | ||
116 | |||
117 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
118 | while(button_get(true) != SYS_USB_DISCONNECTED); | ||
119 | |||
120 | do_splash(3*HZ, "USB disconnected"); | ||
70 | } | 121 | } |
71 | 122 | ||
72 | void main(void) | 123 | void main(void) |
@@ -75,22 +126,40 @@ void main(void) | |||
75 | kernel_init(); | 126 | kernel_init(); |
76 | i2c_init(); | 127 | i2c_init(); |
77 | power_init(); | 128 | power_init(); |
129 | button_init(); | ||
78 | enable_irq(); | 130 | enable_irq(); |
79 | 131 | ||
80 | if(storage_init() < 0) | 132 | if(storage_init() < 0) { |
81 | error("Storage initialization failed"); | 133 | do_splash(3*HZ, "Failed to init storage"); |
134 | power_off(); | ||
135 | } | ||
82 | 136 | ||
83 | filesystem_init(); | 137 | filesystem_init(); |
84 | 138 | ||
85 | if(!storage_present(0)) | 139 | int loadsize = 0; |
86 | error("No SD card present"); | 140 | do { |
87 | 141 | if(!storage_present(0)) { | |
88 | if(disk_mount_all() <= 0) | 142 | do_splash(HZ, "Insert SD card"); |
89 | error("Unable to mount filesystem"); | 143 | continue; |
90 | 144 | } | |
91 | int loadsize = load_firmware(loadbuffer, BOOTFILE, MAX_LOAD_SIZE); | 145 | |
92 | if(loadsize <= 0) | 146 | if(disk_mount_all() <= 0) { |
93 | error(loader_strerror(loadsize)); | 147 | do_splash(5*HZ, "Cannot mount filesystem"); |
148 | do_usb(); | ||
149 | continue; | ||
150 | } | ||
151 | |||
152 | loadsize = load_firmware(loadbuffer, BOOTFILE, MAX_LOAD_SIZE); | ||
153 | if(loadsize <= 0) { | ||
154 | do_splash2(5*HZ, "Error loading Rockbox", | ||
155 | loader_strerror(loadsize)); | ||
156 | do_usb(); | ||
157 | continue; | ||
158 | } | ||
159 | } while(loadsize <= 0); | ||
160 | |||
161 | if(lcd_inited) | ||
162 | backlight_hw_off(); | ||
94 | 163 | ||
95 | disable_irq(); | 164 | disable_irq(); |
96 | 165 | ||