blob: 51b751cbf9ffda1cd784b36bf79c4c5610979fee [file] [log] [blame]
Barry Wardell84b509d2007-01-28 18:42:11 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: main.c 11997 2007-01-13 09:08:18Z miipekk $
9 *
10 * Copyright (C) 2005 by Linus Nielsen Feltzing
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "lcd.h"
20#include "lcd-remote.h"
21#include "font.h"
22#include "system.h"
23#include <stdarg.h>
24#include <stdio.h>
Dave Chapman4d25bff2007-03-05 23:56:28 +000025#include <stdbool.h>
Barry Wardell84b509d2007-01-28 18:42:11 +000026#include "cpu.h"
27#include "common.h"
Barry Wardell23709982007-03-12 22:12:20 +000028#include "power.h"
29#include "kernel.h"
Barry Wardell84b509d2007-01-28 18:42:11 +000030
Dave Chapman4d25bff2007-03-05 23:56:28 +000031/* TODO: Other bootloaders need to be adjusted to set this variable to true
Barry Wardell23709982007-03-12 22:12:20 +000032 on a button press - currently only the ipod, H10 and Sansa versions do. */
33#if defined(IPOD_ARCH) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \
34 defined(SANSA_E200)
Dave Chapman4d25bff2007-03-05 23:56:28 +000035bool verbose = false;
36#else
37bool verbose = true;
38#endif
39
Barry Wardell84b509d2007-01-28 18:42:11 +000040int line = 0;
41#ifdef HAVE_REMOTE_LCD
42int remote_line = 0;
43#endif
44
45char printfbuf[256];
46
47void reset_screen(void)
48{
49 lcd_clear_display();
50 line = 0;
51#ifdef HAVE_REMOTE_LCD
52 lcd_remote_clear_display();
53 remote_line = 0;
54#endif
55}
56
57void printf(const char *format, ...)
58{
59 int len;
60 unsigned char *ptr;
61 va_list ap;
62 va_start(ap, format);
63
64 ptr = printfbuf;
65 len = vsnprintf(ptr, sizeof(printfbuf), format, ap);
66 va_end(ap);
67
68 lcd_puts(0, line++, ptr);
Dave Chapman4d25bff2007-03-05 23:56:28 +000069 if (verbose)
70 lcd_update();
Barry Wardell84b509d2007-01-28 18:42:11 +000071 if(line >= LCD_HEIGHT/SYSFONT_HEIGHT)
72 line = 0;
73#ifdef HAVE_REMOTE_LCD
74 lcd_remote_puts(0, remote_line++, ptr);
Dave Chapman4d25bff2007-03-05 23:56:28 +000075 if (verbose)
76 lcd_remote_update();
Barry Wardell84b509d2007-01-28 18:42:11 +000077 if(remote_line >= LCD_REMOTE_HEIGHT/SYSFONT_HEIGHT)
78 remote_line = 0;
79#endif
80}
81
82char *strerror(int error)
83{
84 switch(error)
85 {
86 case EOK:
87 return "OK";
88 case EFILE_NOT_FOUND:
89 return "File not found";
90 case EREAD_CHKSUM_FAILED:
91 return "Read failed (chksum)";
92 case EREAD_MODEL_FAILED:
93 return "Read failed (model)";
94 case EREAD_IMAGE_FAILED:
95 return "Read failed (image)";
96 case EBAD_CHKSUM:
97 return "Bad checksum";
98 case EFILE_TOO_BIG:
99 return "File too big";
Barry Wardell14ed3ca2007-03-16 14:28:00 +0000100 case EINVALID_FORMAT:
101 return "Invalid file format";
Barry Wardell84b509d2007-01-28 18:42:11 +0000102 default:
103 return "Unknown";
104 }
105}
106
Barry Wardell23709982007-03-12 22:12:20 +0000107void error(int errortype, int error)
108{
109 switch(errortype)
110 {
111 case EATA:
112 printf("ATA error: %d", error);
113 break;
114
115 case EDISK:
116 printf("No partition found");
117 break;
118
119 case EBOOTFILE:
120 printf(strerror(error));
121 break;
122 }
123
124 lcd_update();
125 sleep(5*HZ);
126 power_off();
127}
128
Barry Wardell84b509d2007-01-28 18:42:11 +0000129/* Load firmware image in a format created by tools/scramble */
130int load_firmware(unsigned char* buf, char* firmware, int buffer_size)
131{
132 int fd;
133 int rc;
134 int len;
135 unsigned long chksum;
136 char model[5];
137 unsigned long sum;
138 int i;
139 char filename[MAX_PATH];
140
141 snprintf(filename,sizeof(filename),"/.rockbox/%s",firmware);
142 fd = open(filename, O_RDONLY);
143 if(fd < 0)
144 {
145 snprintf(filename,sizeof(filename),"/%s",firmware);
146 fd = open(filename, O_RDONLY);
147 if(fd < 0)
148 return EFILE_NOT_FOUND;
149 }
150
151 len = filesize(fd) - 8;
152
153 printf("Length: %x", len);
154
155 if (len > buffer_size)
156 return EFILE_TOO_BIG;
157
158 lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET);
159
160 rc = read(fd, &chksum, 4);
161 chksum=betoh32(chksum); /* Rockbox checksums are big-endian */
162 if(rc < 4)
163 return EREAD_CHKSUM_FAILED;
164
165 printf("Checksum: %x", chksum);
166
167 rc = read(fd, model, 4);
168 if(rc < 4)
169 return EREAD_MODEL_FAILED;
170
171 model[4] = 0;
172
173 printf("Model name: %s", model);
174 printf("Loading %s", firmware);
175
176 lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);
177
178 rc = read(fd, buf, len);
179 if(rc < len)
180 return EREAD_IMAGE_FAILED;
181
182 close(fd);
183
184 sum = MODEL_NUMBER;
185
186 for(i = 0;i < len;i++) {
187 sum += buf[i];
188 }
189
190 printf("Sum: %x", sum);
191
192 if(sum != chksum)
193 return EBAD_CHKSUM;
194
Linus Nielsen Feltzing46597c92007-02-22 15:09:49 +0000195 return EOK;
Barry Wardell84b509d2007-01-28 18:42:11 +0000196}
197
198/* Load raw binary image. */
199int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size)
200{
201 int fd;
202 int rc;
203 int len;
204 char filename[MAX_PATH];
205
206 snprintf(filename,sizeof(filename),"%s",firmware);
207 fd = open(filename, O_RDONLY);
208 if(fd < 0)
209 {
210 return EFILE_NOT_FOUND;
211 }
212
213 len = filesize(fd);
214
215 if (len > buffer_size)
216 return EFILE_TOO_BIG;
217
218 rc = read(fd, buf, len);
219 if(rc < len)
220 return EREAD_IMAGE_FAILED;
221
222 close(fd);
223 return len;
224}
225
226/* These functions are present in the firmware library, but we reimplement
227 them here because the originals do a lot more than we want */
228void reset_poweroff_timer(void)
229{
230}
231
232int dbg_ports(void)
233{
234 return 0;
235}
236
237void mpeg_stop(void)
238{
239}
240
241void sys_poweroff(void)
242{
243}