summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2003-11-30 11:37:43 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2003-11-30 11:37:43 +0000
commit6a4e4c87c24455e18bbd77565cb3e993ee350618 (patch)
tree6f2ceac4da97aa63ff8deef939bd3cc2d56d3466
parent014c4fa1f8d56850cfd504a90221c293e4a158f6 (diff)
downloadrockbox-6a4e4c87c24455e18bbd77565cb3e993ee350618.tar.gz
rockbox-6a4e4c87c24455e18bbd77565cb3e993ee350618.zip
source code for all my flash stuff, now finally in cvs
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4083 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--flash/README8
-rw-r--r--flash/bootloader/Makefile78
-rw-r--r--flash/bootloader/README4
-rw-r--r--flash/bootloader/bootloader.c480
-rw-r--r--flash/bootloader/bootloader.h111
-rw-r--r--flash/bootloader/bootloader.lds34
-rw-r--r--flash/bootloader/no_rom.lds62
-rw-r--r--flash/extract/README5
-rw-r--r--flash/extract/extract.c140
-rw-r--r--flash/extract/extract.dsp100
-rw-r--r--flash/make_firmware/README14
-rw-r--r--flash/make_firmware/make_firmware.c338
-rw-r--r--flash/make_firmware/make_firmware.dsp96
-rw-r--r--flash/minimon/Makefile53
-rw-r--r--flash/minimon/README6
-rw-r--r--flash/minimon/minimon.c156
-rw-r--r--flash/minimon/minimon.h24
-rw-r--r--flash/minimon/minimon.lds60
-rw-r--r--flash/uart_boot/README8
-rw-r--r--flash/uart_boot/client.c738
-rw-r--r--flash/uart_boot/client.h21
-rw-r--r--flash/uart_boot/flash.c77
-rw-r--r--flash/uart_boot/flash.h9
-rw-r--r--flash/uart_boot/minimon.h23
-rw-r--r--flash/uart_boot/scalar_types.h44
-rw-r--r--flash/uart_boot/uart.h56
-rw-r--r--flash/uart_boot/uart_boot.c337
-rw-r--r--flash/uart_boot/uart_boot.dsp130
-rw-r--r--flash/uart_boot/uart_win.c138
29 files changed, 3349 insertions, 1 deletions
diff --git a/flash/README b/flash/README
index 304360caba..9f77dd502f 100644
--- a/flash/README
+++ b/flash/README
@@ -1 +1,7 @@
1Readme 1(c) 2003 by Jörg Hohensohn
2
3Sourcecode for the flash "infrastructure"
4Please bear in mind that these are powerful tools, don't fool with them!
5
6For most up-to-date info about flashing see:
7http://rockbox.haxx.se/docs/flash.html
diff --git a/flash/bootloader/Makefile b/flash/bootloader/Makefile
new file mode 100644
index 0000000000..ae56cf9425
--- /dev/null
+++ b/flash/bootloader/Makefile
@@ -0,0 +1,78 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10CC = sh-elf-gcc
11LD = sh-elf-ld
12AR = sh-elf-ar
13AS = sh-elf-as
14OC = sh-elf-objcopy
15
16FIRMWARE := ../../firmware
17TOOLSDIR=../../tools
18
19TARGET = bootloader
20LDS := $(TARGET).lds
21
22
23ifndef PLATFORM
24not_configured:
25 @echo "No platform given."
26 @echo "Use make PLATFORM=PLAYER|RECORDER|RECORDER|FM {NO_ROM=1}"
27##else
28##configured:
29## @echo "Building bootloader for platform "$(PLATFORM)
30endif
31
32
33INCLUDES= -I$(FIRMWARE)/export -I. -I$(OBJDIR)
34DEFINES= -DPLATFORM_$(PLATFORM)
35
36OBJDIR := .
37
38CFLAGS = -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns $(INCLUDES) $(DEFINES)
39AFLAGS += -small -relax
40
41
42ifdef DEBUG
43 DEFINES := -DDEBUG
44 CFLAGS += -g
45endif
46
47SRC := $(wildcard *.c)
48
49OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
50
51ifdef NO_ROM
52LINKFILE = $(OBJDIR)/no_rom.lds
53ORIGIN = 0
54DEFINES += -DNO_ROM
55else
56LINKFILE = $(OBJDIR)/$(TARGET).lds
57ORIGIN = FFFF500
58endif
59
60$(OBJDIR)/$(TARGET).bin : $(OBJDIR)/$(TARGET).elf
61 $(OC) -O binary $(OBJDIR)/$(TARGET).elf $(OBJDIR)/$(TARGET).bin
62 $(TOOLSDIR)/sh2d $(OBJDIR)/$(TARGET).bin -o $(ORIGIN) > $(OBJDIR)/$(TARGET).asm
63ifndef NO_ROM
64 $(TOOLSDIR)/scramble $(OBJDIR)/$(TARGET).bin $(OBJDIR)/$(TARGET).ajz
65endif
66
67$(OBJDIR)/$(TARGET).elf : $(OBJS)
68 $(CC) -Os -nostdlib -o $(OBJDIR)/$(TARGET).elf -L$(OBJDIR) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/$(TARGET).map
69
70
71clean:
72 -rm -f \
73 $(OBJS) \
74 $(OBJDIR)/$(TARGET).asm \
75 $(OBJDIR)/$(TARGET).bin \
76 $(OBJDIR)/$(TARGET).ajz \
77 $(OBJDIR)/$(TARGET).elf \
78 $(OBJDIR)/$(TARGET).map
diff --git a/flash/bootloader/README b/flash/bootloader/README
new file mode 100644
index 0000000000..16c27d9876
--- /dev/null
+++ b/flash/bootloader/README
@@ -0,0 +1,4 @@
1(c) 2003 by Jörg Hohensohn
2
3This is the source code for the flash bootloader.
4It give the dual boot feature, decompresses one of two software images.
diff --git a/flash/bootloader/bootloader.c b/flash/bootloader/bootloader.c
new file mode 100644
index 0000000000..7179bbef95
--- /dev/null
+++ b/flash/bootloader/bootloader.c
@@ -0,0 +1,480 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 by Jörg Hohensohn
11 *
12 * Second-level bootloader, with dual-boot feature by holding F1/Menu
13 * This is the image being descrambled and executed by the boot ROM.
14 * It's task is to copy Rockbox from Flash to DRAM.
15 * The image(s) in flash may optionally be compressed with UCL 2e
16 *
17 * All files in this archive are subject to the GNU General Public License.
18 * See the file COPYING in the source tree root for full license agreement.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "sh7034.h"
26#include "bootloader.h"
27
28
29#ifdef NO_ROM
30// start with the vector table
31UINT32 vectors[] __attribute__ ((section (".vectors"))) =
32{
33 (UINT32)_main, // entry point, the copy routine
34 (UINT32)(end_stack - 1), // initial stack pointer
35 FLASH_BASE + 0x200, // source of image in flash
36 (UINT32)total_size, // size of image
37 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
38 0x03020080 // mask and version (just as a suggestion)
39};
40#else
41// our binary has to start with a vector to the entry point
42tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
43#endif
44
45#ifdef NO_ROM // some code which is only needed for the romless variant
46void _main(void)
47{
48 UINT32* pSrc;
49 UINT32* pDest;
50 UINT32* pEnd;
51/*
52 asm volatile ("ldc %0,sr" : : "r"(0xF0)); // disable interrupts
53 asm volatile ("mov.l @%0,r15" : : "r"(4)); // load stack
54 asm volatile ("ldc %0,vbr" : : "r"(0)); // load vector base
55*/
56 // copy everything to IRAM and continue there
57 pSrc = begin_iramcopy;
58 pDest = begin_text;
59 pEnd = pDest + (begin_stack - begin_text);
60
61 do
62 {
63 *pDest++ = *pSrc++;
64 }
65 while (pDest < pEnd);
66
67 main(); // jump to the real main()
68}
69
70
71void BootInit(void)
72{
73 // inits from the boot ROM, whether they make sense or not
74 PBDR &= 0xFFBF; // LED off (0x131E)
75 PBCR2 = 0; // all GPIO
76 PBIOR |= 0x40; // LED output
77 PBIOR &= 0xFFF1; // LCD lines input
78
79 // init DRAM like the boot ROM does
80 PACR2 &= 0xFFFB;
81 PACR2 |= 0x0008;
82 CASCR = 0xAF;
83 BCR |= 0x8000;
84 WCR1 &= 0xFDFD;
85 DCR = 0x0E00;
86 RCR = 0x5AB0;
87 RTCOR = 0x9605;
88 RTCSR = 0xA518;
89}
90#endif // #ifdef NO_ROM
91
92
93int main(void)
94{
95 int nButton;
96
97 PlatformInit(); // model-specific inits
98
99 nButton = ButtonPressed();
100
101 if (nButton == 3)
102 { // F3 means start monitor
103 MiniMon();
104 }
105 else
106 {
107 tImage* pImage;
108 pImage = GetStartImage(nButton); // which image
109 DecompressStart(pImage); // move into place and start it
110 }
111
112 return 0; // I guess we won't return ;-)
113}
114
115
116// init code that is specific to certain platform
117void PlatformInit(void)
118{
119#ifdef NO_ROM
120 BootInit(); // if not started by boot ROM, we need to init what it did
121#endif
122
123#if defined PLATFORM_PLAYER
124 BRR1 = 0x0019; // 14400 Baud for monitor
125 if (FW_VERSION > 451) // "new" Player?
126 {
127 PBDR &= ~0x10; // set PB4 to 0 to power-up the harddisk early
128 PBIOR |= 0x10; // make PB4 an output
129 }
130#elif defined PLATFORM_RECORDER
131 BRR1 = 0x0002; // 115200 Baud for monitor
132 if (ReadADC(7) > 0x100) // charger plugged?
133 { // switch off the HD, else a flat battery may not start
134 PACR2 &= 0xFBFF; // GPIO for PA5
135 PAIOR |= 0x20; // make PA5 an output (low by default)
136 }
137#elif defined PLATFORM_FM
138 BRR1 = 0x0002; // 115200 Baud for monitor
139 PBDR |= 0x20; // set PB5 to keep power (fixes the ON-holding problem)
140 PBIOR |= 0x20; // make PB5 an output
141 if (ReadADC(0) < 0x1FF) // charger plugged?
142 {
143 // how do we switch this off?
144 }
145#endif
146
147 // platform-independent inits
148 DCR |= 0x1000; // enable burst mode on DRAM
149 BCR |= 0x2000; // activate Warp mode (simultaneous internal and external mem access)
150}
151
152
153// Thinned out version of the UCL 2e decompression sourcecode
154// Original (C) Markus F.X.J Oberhumer under GNU GPL license
155#define GETBIT(bb, src, ilen) \
156 (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
157
158int ucl_nrv2e_decompress_8(
159 const UINT8 *src, UINT8 *dst, UINT32* dst_len)
160{
161 UINT32 bb = 0;
162 unsigned ilen = 0, olen = 0, last_m_off = 1;
163
164 for (;;)
165 {
166 unsigned m_off, m_len;
167
168 while (GETBIT(bb,src,ilen))
169 {
170 dst[olen++] = src[ilen++];
171 }
172 m_off = 1;
173 for (;;)
174 {
175 m_off = m_off*2 + GETBIT(bb,src,ilen);
176 if (GETBIT(bb,src,ilen)) break;
177 m_off = (m_off-1)*2 + GETBIT(bb,src,ilen);
178 }
179 if (m_off == 2)
180 {
181 m_off = last_m_off;
182 m_len = GETBIT(bb,src,ilen);
183 }
184 else
185 {
186 m_off = (m_off-3)*256 + src[ilen++];
187 if (m_off == 0xffffffff)
188 break;
189 m_len = (m_off ^ 0xffffffff) & 1;
190 m_off >>= 1;
191 last_m_off = ++m_off;
192 }
193 if (m_len)
194 m_len = 1 + GETBIT(bb,src,ilen);
195 else if (GETBIT(bb,src,ilen))
196 m_len = 3 + GETBIT(bb,src,ilen);
197 else
198 {
199 m_len++;
200 do {
201 m_len = m_len*2 + GETBIT(bb,src,ilen);
202 } while (!GETBIT(bb,src,ilen));
203 m_len += 3;
204 }
205 m_len += (m_off > 0x500);
206 {
207 const UINT8 *m_pos;
208 m_pos = dst + olen - m_off;
209 dst[olen++] = *m_pos++;
210 do dst[olen++] = *m_pos++; while (--m_len > 0);
211 }
212 }
213 *dst_len = olen;
214
215 return ilen;
216}
217
218
219// move the image into place and start it
220void DecompressStart(tImage* pImage)
221{
222 UINT32* pSrc;
223 UINT32* pDest;
224
225 pSrc = pImage->image;
226 pDest = pImage->pDestination;
227
228 if (pSrc != pDest) // if not linked to that flash address
229 {
230 if (pImage->flags & IF_UCL_2E)
231 { // UCL compressed, algorithm 2e
232 UINT32 dst_len; // dummy
233 ucl_nrv2e_decompress_8((UINT8*)pSrc, (UINT8*)pDest, &dst_len);
234 }
235 else
236 { // uncompressed, copy it
237 UINT32 size = pImage->size;
238 UINT32* pEnd;
239 size = (size + 3) / 4; // round up to 32bit-words
240 pEnd = pDest + size;
241
242 do
243 {
244 *pDest++ = *pSrc++;
245 }
246 while (pDest < pEnd);
247 }
248 }
249
250 pImage->pExecute();
251}
252
253
254int ReadADC(int channel)
255{
256 // after channel 3, the ports wrap and get re-used
257 volatile UINT16* pResult = (UINT16*)(ADDRAH_ADDR + 2 * (channel & 0x03));
258 int timeout = 266; // conversion takes 266 clock cycles
259
260 ADCSR = 0x20 | channel; // start single conversion
261 while (((ADCSR & 0x80) == 0) && (--timeout)); // 6 instructions per round
262
263 return (timeout == 0) ? -1 : *pResult>>6;
264}
265
266
267// This function is platform-dependent,
268// until I figure out how to distinguish at runtime.
269int ButtonPressed(void) // return 1,2,3 for F1,F2,F3, 0 if none pressed
270{
271 int value = ReadADC(CHANNEL);
272
273 if (value >= F1_LOWER && value <= F1_UPPER) // in range
274 return 1;
275 else if (value >= F2_LOWER && value <= F2_UPPER) // in range
276 return 2;
277 else if (value >= F3_LOWER && value <= F3_UPPER) // in range
278 return 3;
279
280 return 0;
281}
282
283
284// Determine the image to be started
285tImage* GetStartImage(int nPreferred)
286{
287 tImage* pImage1;
288 tImage* pImage2 = NULL; // default to not present
289 UINT32 pos;
290 UINT32* pFlash = (UINT32*)FLASH_BASE;
291
292 // determine the first image position
293 pos = pFlash[2] + pFlash[3]; // position + size of the bootloader = after it
294 pos = (pos + 3) & ~3; // be shure it's 32 bit aligned
295
296 pImage1 = (tImage*)pos;
297
298 if (pImage1->size != 0)
299 { // check for second image
300 pos = (UINT32)(&pImage1->image) + pImage1->size;
301 pImage2 = (tImage*)pos;
302
303 // does it make sense? (not in FF or 00 erazed space)
304 if (pImage2->pDestination == (void*)0xFFFFFFFF
305 || pImage2->size == 0xFFFFFFFF
306 || pImage2->pExecute == (void*)0xFFFFFFFF
307 || pImage2->flags == 0xFFFFFFFF
308 || pImage2->pDestination == NULL) // size, execute and flags can legally be 0
309 {
310 pImage2 = NULL; // invalidate
311 }
312 }
313
314 if (pImage2 == NULL || nPreferred == 1)
315 { // no second image or overridden: return the first
316 return pImage1;
317 }
318
319 return pImage2; // return second image
320}
321
322// diagnostic functions
323
324void SetLed(BOOL bOn)
325{
326 if (bOn)
327 PBDR |= 0x40;
328 else
329 PBDR &= ~0x40;
330}
331
332
333void UartInit(void)
334{
335 PBIOR &= 0xFBFF; // input: RXD1 remote pin
336 PBCR1 |= 0x00A0; // set PB3+PB2 to UART
337 PBCR1 &= 0xFFAF; // clear bits 6, 4 -> UART
338 SMR1 = 0x0000; // async format 8N1, baud generator input is CPU clock
339 SCR1 = 0x0030; // transmit+receive enable
340 PBCR1 &= 0x00FF; // set bit 12...15 as GPIO
341 SSR1 &= 0x00BF; // clear bit 6 (RDRF, receive data register full)
342}
343
344
345UINT8 UartRead(void)
346{
347 UINT8 byte;
348 while (!(SSR1 & SCI_RDRF)); // wait for char to be available
349 byte = RDR1;
350 SSR1 &= ~SCI_RDRF;
351 return byte;
352}
353
354
355void UartWrite(UINT8 byte)
356{
357 while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty
358 TDR1 = byte;
359 SSR1 &= ~SCI_TDRE;
360}
361
362
363// include the mini monitor as a rescue feature, started with F3
364void MiniMon(void)
365{
366 UINT8 cmd;
367 UINT32 addr;
368 UINT32 size;
369 UINT32 content;
370 volatile UINT8* paddr = NULL;
371 volatile UINT8* pflash = NULL; // flash base address
372
373 UartInit();
374
375 while (1)
376 {
377 cmd = UartRead();
378 switch (cmd)
379 {
380 case BAUDRATE:
381 content = UartRead();
382 UartWrite(cmd); // acknowledge by returning the command value
383 while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate
384 BRR1 = content;
385 break;
386
387 case ADDRESS:
388 addr = (UartRead() << 24) | (UartRead() << 16) | (UartRead() << 8) | UartRead();
389 paddr = (UINT8*)addr;
390 pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align
391 UartWrite(cmd); // acknowledge by returning the command value
392 break;
393
394 case BYTE_READ:
395 content = *paddr++;
396 UartWrite(content); // the content is the ack
397 break;
398
399 case BYTE_WRITE:
400 content = UartRead();
401 *paddr++ = content;
402 UartWrite(cmd); // acknowledge by returning the command value
403 break;
404
405 case BYTE_READ16:
406 size = 16;
407 while (size--)
408 {
409 content = *paddr++;
410 UartWrite(content); // the content is the ack
411 }
412 break;
413
414 case BYTE_WRITE16:
415 size = 16;
416 while (size--)
417 {
418 content = UartRead();
419 *paddr++ = content;
420 }
421 UartWrite(cmd); // acknowledge by returning the command value
422 break;
423
424 case BYTE_FLASH:
425 content = UartRead();
426 pflash[0x5555] = 0xAA; // set flash to command mode
427 pflash[0x2AAA] = 0x55;
428 pflash[0x5555] = 0xA0; // byte program command
429 *paddr++ = content;
430 UartWrite(cmd); // acknowledge by returning the command value
431 break;
432
433 case BYTE_FLASH16:
434 size = 16;
435 while (size--)
436 {
437 content = UartRead();
438 pflash[0x5555] = 0xAA; // set flash to command mode
439 pflash[0x2AAA] = 0x55;
440 pflash[0x5555] = 0xA0; // byte program command
441 *paddr++ = content;
442 }
443 UartWrite(cmd); // acknowledge by returning the command value
444 break;
445
446 case HALFWORD_READ:
447 content = *(UINT16*)paddr;
448 paddr += 2;
449 UartWrite(content >> 8); // highbyte
450 UartWrite(content & 0xFF); // lowbyte
451 break;
452
453 case HALFWORD_WRITE:
454 content = UartRead() << 8 | UartRead();
455 *(UINT16*)paddr = content;
456 paddr += 2;
457 UartWrite(cmd); // acknowledge by returning the command value
458 break;
459
460 case EXECUTE:
461 {
462 tpFunc pFunc = (tpFunc)paddr;
463 pFunc();
464 UartWrite(cmd); // acknowledge by returning the command value
465 }
466 break;
467
468 case VERSION:
469 UartWrite(1); // return our version number
470 break;
471
472 default:
473 {
474 SetLed(TRUE);
475 UartWrite(~cmd); // error acknowledge
476 }
477
478 } // case
479 } // while (1)
480}
diff --git a/flash/bootloader/bootloader.h b/flash/bootloader/bootloader.h
new file mode 100644
index 0000000000..eee61c4809
--- /dev/null
+++ b/flash/bootloader/bootloader.h
@@ -0,0 +1,111 @@
1#ifndef NULL
2#define NULL ((void*)0)
3#endif
4
5#define TRUE 1
6#define FALSE 0
7
8// scalar types
9typedef unsigned char UINT8;
10typedef unsigned short UINT16;
11typedef unsigned long UINT32;
12typedef int BOOL;
13
14typedef void(*tpFunc)(void); // type for execute
15typedef int(*tpMain)(void); // type for start vector to main()
16
17
18// structure of an image in the flash
19typedef struct
20{
21 UINT32* pDestination; // address to copy it to
22 UINT32 size; // how many bytes of payload (to the next header)
23 tpFunc pExecute; // entry point
24 UINT32 flags; // uncompressed or compressed
25 // end of header, now comes the payload
26 UINT32 image[]; // the binary image starts here
27 // after the payload, the next header may follow, all 0xFF if none
28} tImage;
29
30// flags valid for image header
31#define IF_NONE 0x00000000
32#define IF_UCL_2E 0x00000001 // image is compressed with UCL, algorithm 2e
33
34
35// resolve platform dependency of F1 button check
36#if defined PLATFORM_PLAYER
37#define CHANNEL 1
38#define F1_LOWER 0 // this is the "Menu" key
39#define F1_UPPER 384
40#define F2_LOWER 1024 // not present
41#define F2_UPPER 1024
42#define F3_LOWER 1024
43#define F3_UPPER 1024
44#elif defined PLATFORM_RECORDER
45#define CHANNEL 4
46#define F1_LOWER 250
47#define F1_UPPER 499
48#define F2_LOWER 500
49#define F2_UPPER 699
50#define F3_LOWER 900
51#define F3_UPPER 1023
52#elif defined PLATFORM_FM
53#define CHANNEL 4
54#define F1_LOWER 150
55#define F1_UPPER 384
56#define F2_LOWER 385
57#define F2_UPPER 544
58#define F3_LOWER 700
59#define F3_UPPER 1023
60#else
61#error ("No platform given!")
62#endif
63
64#define FLASH_BASE 0x02000000 // start of the flash memory
65#define FW_VERSION *(unsigned short*)(FLASH_BASE + 0xFE) // firmware version
66
67
68// prototypes
69void _main(void) __attribute__ ((section (".startup")));
70int main(void);
71void PlatformInit(void);
72void DramInit(void);
73int ucl_nrv2e_decompress_8(const UINT8 *src, UINT8 *dst, UINT32* dst_len);
74void DecompressStart(tImage* pImage);
75int ReadADC(int channel);
76int ButtonPressed(void);
77tImage* GetStartImage(int nPreferred);
78// test functions
79void SetLed(BOOL bOn);
80void UartInit(void);
81UINT8 UartRead(void);
82void UartWrite(UINT8 byte);
83void MiniMon(void);
84
85
86// minimon commands
87#define BAUDRATE 0x00 // followed by BRR value; response: command byte
88#define ADDRESS 0x01 // followed by 4 bytes address; response: command byte
89#define BYTE_READ 0x02 // response: 1 byte content
90#define BYTE_WRITE 0x03 // followed by 1 byte content; response: command byte
91#define BYTE_READ16 0x04 // response: 16 bytes content
92#define BYTE_WRITE16 0x05 // followed by 16 bytes; response: command byte
93#define BYTE_FLASH 0x06 // followed by 1 byte content; response: command byte
94#define BYTE_FLASH16 0x07 // followed by 16 bytes; response: command byte
95#define HALFWORD_READ 0x08 // response: 2 byte content
96#define HALFWORD_WRITE 0x09 // followed by 2 byte content; response: command byte
97#define EXECUTE 0x0A // response: command byte if call returns
98#define VERSION 0x0B // response: version
99
100
101// linker symbols
102extern UINT32 begin_text[];
103extern UINT32 end_text[];
104extern UINT32 begin_data[];
105extern UINT32 end_data[];
106extern UINT32 begin_bss[];
107extern UINT32 end_bss[];
108extern UINT32 begin_stack[];
109extern UINT32 end_stack[];
110extern UINT32 begin_iramcopy[];
111extern UINT32 total_size[];
diff --git a/flash/bootloader/bootloader.lds b/flash/bootloader/bootloader.lds
new file mode 100644
index 0000000000..143d83bdc7
--- /dev/null
+++ b/flash/bootloader/bootloader.lds
@@ -0,0 +1,34 @@
1OUTPUT_FORMAT(elf32-sh)
2INPUT(bootloader.o)
3
4MEMORY
5{
6 /* the boot ROM uses IRAM at 400-430, stay away and start at 500 */
7 IRAM : ORIGIN = 0x0FFFF500, LENGTH = 0xA00
8 /* and leave some room for stack at the end */
9}
10
11SECTIONS
12{
13 .startvector :
14 {
15 *(.startvector)
16 . = ALIGN(0x4);
17 } > IRAM
18
19 .text :
20 {
21 *(.text)
22 . = ALIGN(0x4);
23 } > IRAM
24
25 .data :
26 {
27 *(.data)
28 } > IRAM
29
30 .bss :
31 {
32 *(.bss)
33 } > IRAM
34}
diff --git a/flash/bootloader/no_rom.lds b/flash/bootloader/no_rom.lds
new file mode 100644
index 0000000000..e65e7fdd3c
--- /dev/null
+++ b/flash/bootloader/no_rom.lds
@@ -0,0 +1,62 @@
1/* This is for the variant without boot ROM,
2 where the flash ROM is mirrored to address zero */
3
4OUTPUT_FORMAT(elf32-sh)
5INPUT(bootloader.o)
6
7MEMORY
8{
9 IRAM : ORIGIN = 0x0FFFF000, LENGTH = 0x1000
10 FLASH : ORIGIN = 0x00000000, LENGTH = 0x40000
11}
12
13SECTIONS
14{
15 .vectors :
16 {
17 *(.vectors)
18 . = ALIGN(0x200);
19 } > FLASH
20
21 .startup :
22 {
23 *(.startup)
24 . = ALIGN(0x4);
25 _begin_iramcopy = .;
26 } > FLASH
27
28 .text : AT ( _begin_iramcopy )
29 {
30 _begin_text = .;
31 *(.text)
32 . = ALIGN(0x4);
33 _end_text = .;
34 } > IRAM
35
36 .data : AT ( _end_text )
37 {
38 _begin_data = .;
39 *(.data)
40 . = ALIGN(0x4);
41 _end_data = .;
42 } > IRAM
43
44 .bss : AT ( _end_data )
45 {
46 _begin_bss = .;
47 *(.bss)
48 . = ALIGN(0x4);
49 _end_bss = .;
50 } > IRAM
51
52 .stack :
53 {
54 _begin_stack = .;
55 *(.stack)
56 . = ALIGN(0x1000);
57 _end_stack = .;
58 } > IRAM
59
60 /* size of the program (without vectors) */
61 _total_size = SIZEOF(.startup) + SIZEOF(.text) + SIZEOF(.data);
62}
diff --git a/flash/extract/README b/flash/extract/README
new file mode 100644
index 0000000000..b66443aa34
--- /dev/null
+++ b/flash/extract/README
@@ -0,0 +1,5 @@
1(c) 2003 by Jörg Hohensohn
2
3This tool extracts the firmware image out of an original Archos ROM dump,
4like created with the Rockbox debug->dump feature.
5The extracted image can then be used to compose a dual-boot firmware.
diff --git a/flash/extract/extract.c b/flash/extract/extract.c
new file mode 100644
index 0000000000..31e223a546
--- /dev/null
+++ b/flash/extract/extract.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 by Jörg Hohensohn
11 *
12 * Tool to extract the scrambled image out of an Archos flash ROM dump
13 *
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <memory.h>
25
26#define UINT8 unsigned char
27#define UINT16 unsigned short
28#define UINT32 unsigned long
29
30#define IMAGE_HEADER 0x6000 // a 32 byte header in front of the software image
31#define IMAGE_START 0x6020 // software image position in Flash
32
33
34// place a 32 bit value into memory, big endian
35void Write32(UINT8* pByte, UINT32 value)
36{
37 pByte[0] = (UINT8)(value >> 24);
38 pByte[1] = (UINT8)(value >> 16);
39 pByte[2] = (UINT8)(value >> 8);
40 pByte[3] = (UINT8)(value);
41}
42
43
44// read a 32 bit value from memory, big endian
45UINT32 Read32(UINT8* pByte)
46{
47 UINT32 value = 0;
48
49 value |= (UINT32)pByte[0] << 24;
50 value |= (UINT32)pByte[1] << 16;
51 value |= (UINT32)pByte[2] << 8;
52 value |= (UINT32)pByte[3];
53
54 return value;
55}
56
57
58// entry point
59int main(int argc, char* argv[])
60{
61 FILE* pInFile;
62 FILE* pOutFile;
63 UINT8 aHeader[6];
64 UINT8 aImage[256*1024];
65 UINT32 i;
66 UINT32 uiSize, uiStart;
67 UINT16 usChecksum = 0;
68
69 if (argc < 2)
70 {
71 printf("Extract the software image out of an original Archos Flash ROM dump.\n");
72 printf("Result is a scrambled file, use the descramble tool to get the binary,\n");
73 printf(" always without the -fm option, even if processing an FM software.\n\n");
74 printf("Usage: extract <flash dump file> <output file>\n");
75 printf("Example: extract internal_rom_2000000-203FFFF.bin archos.ajz\n");
76 exit(0);
77 }
78
79 pInFile = fopen(argv[1], "rb");
80 if (pInFile == NULL)
81 {
82 printf("Error opening input file %s\n", argv[1]);
83 exit(1);
84 }
85
86 if (fread(aImage, 1, sizeof(aImage), pInFile) != sizeof(aImage))
87 {
88 printf("Error reading input file %s, must be 256kB in size.\n", argv[1]);
89 fclose(pInFile);
90 exit(2);
91 }
92 fclose(pInFile);
93
94 // find out about the type
95 uiStart = Read32(aImage + 8);
96 uiSize = Read32(aImage + 12); // booted ROM image
97 if (uiStart == 0x02000100 && uiSize > 20000)
98 { // Player has no loader, starts directly with the image
99 uiStart = 0x0100;
100 }
101 else
102 { // Recorder / FM / V2 Recorder
103 uiStart = IMAGE_START;
104 uiSize = Read32(aImage + IMAGE_HEADER + 4); // size record of header
105 }
106
107 // sanity check
108 if (uiSize > sizeof(aImage) - uiStart || uiSize < 40000)
109 {
110 printf("Error: Impossible image size &d bytes.\n", uiSize);
111 exit(3);
112 }
113
114 // generate checksum
115 for (i=0; i<uiSize; i++)
116 usChecksum += aImage[uiStart + i];
117
118 // make header
119 Write32(aHeader + 2, usChecksum); // checksum in 5th and 6th byte
120 Write32(aHeader, uiSize); // size in first 4 bytes
121
122 pOutFile = fopen(argv[2], "wb");
123 if (pOutFile == NULL)
124 {
125 printf("Error opening output file %s\n", argv[2]);
126 exit(4);
127 }
128
129 if (fwrite(aHeader, 1, sizeof(aHeader), pOutFile) != sizeof(aHeader)
130 || fwrite(aImage + uiStart, 1, uiSize, pOutFile) != uiSize)
131 {
132 printf("Write error\n");
133 fclose(pOutFile);
134 exit(5);
135 }
136
137 fclose(pOutFile);
138
139 return 0;
140} \ No newline at end of file
diff --git a/flash/extract/extract.dsp b/flash/extract/extract.dsp
new file mode 100644
index 0000000000..e10281a829
--- /dev/null
+++ b/flash/extract/extract.dsp
@@ -0,0 +1,100 @@
1# Microsoft Developer Studio Project File - Name="extract" - Package Owner=<4>
2# Microsoft Developer Studio Generated Build File, Format Version 6.00
3# ** DO NOT EDIT **
4
5# TARGTYPE "Win32 (x86) Console Application" 0x0103
6
7CFG=extract - Win32 Debug
8!MESSAGE This is not a valid makefile. To build this project using NMAKE,
9!MESSAGE use the Export Makefile command and run
10!MESSAGE
11!MESSAGE NMAKE /f "extract.mak".
12!MESSAGE
13!MESSAGE You can specify a configuration when running NMAKE
14!MESSAGE by defining the macro CFG on the command line. For example:
15!MESSAGE
16!MESSAGE NMAKE /f "extract.mak" CFG="extract - Win32 Debug"
17!MESSAGE
18!MESSAGE Possible choices for configuration are:
19!MESSAGE
20!MESSAGE "extract - Win32 Release" (based on "Win32 (x86) Console Application")
21!MESSAGE "extract - Win32 Debug" (based on "Win32 (x86) Console Application")
22!MESSAGE
23
24# Begin Project
25# PROP AllowPerConfigDependencies 0
26# PROP Scc_ProjName ""
27# PROP Scc_LocalPath ""
28CPP=cl.exe
29RSC=rc.exe
30
31!IF "$(CFG)" == "extract - Win32 Release"
32
33# PROP BASE Use_MFC 0
34# PROP BASE Use_Debug_Libraries 0
35# PROP BASE Output_Dir "Release"
36# PROP BASE Intermediate_Dir "Release"
37# PROP BASE Target_Dir ""
38# PROP Use_MFC 0
39# PROP Use_Debug_Libraries 0
40# PROP Output_Dir "Release"
41# PROP Intermediate_Dir "Release"
42# PROP Target_Dir ""
43# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
44# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
45# ADD BASE RSC /l 0x407 /d "NDEBUG"
46# ADD RSC /l 0x407 /d "NDEBUG"
47BSC32=bscmake.exe
48# ADD BASE BSC32 /nologo
49# ADD BSC32 /nologo
50LINK32=link.exe
51# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
52# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
53
54!ELSEIF "$(CFG)" == "extract - Win32 Debug"
55
56# PROP BASE Use_MFC 0
57# PROP BASE Use_Debug_Libraries 1
58# PROP BASE Output_Dir "Debug"
59# PROP BASE Intermediate_Dir "Debug"
60# PROP BASE Target_Dir ""
61# PROP Use_MFC 0
62# PROP Use_Debug_Libraries 1
63# PROP Output_Dir "Debug"
64# PROP Intermediate_Dir "Debug"
65# PROP Target_Dir ""
66# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
67# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
68# ADD BASE RSC /l 0x407 /d "_DEBUG"
69# ADD RSC /l 0x407 /d "_DEBUG"
70BSC32=bscmake.exe
71# ADD BASE BSC32 /nologo
72# ADD BSC32 /nologo
73LINK32=link.exe
74# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
75# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
76
77!ENDIF
78
79# Begin Target
80
81# Name "extract - Win32 Release"
82# Name "extract - Win32 Debug"
83# Begin Group "Source Files"
84
85# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
86# Begin Source File
87
88SOURCE=.\extract.c
89# End Source File
90# End Group
91# Begin Group "Header Files"
92
93# PROP Default_Filter "h;hpp;hxx;hm;inl"
94# End Group
95# Begin Group "Resource Files"
96
97# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
98# End Group
99# End Target
100# End Project
diff --git a/flash/make_firmware/README b/flash/make_firmware/README
new file mode 100644
index 0000000000..7110610284
--- /dev/null
+++ b/flash/make_firmware/README
@@ -0,0 +1,14 @@
1(c) 2003 by Jörg Hohensohn
2
3This tool composes a firmware file, out of:
41. Template for the first Flash page
52. Bootloader
63. Archos image
74. Rockbox image
8
9Use with extreme caution, the components have to match!
10The aspects are:
11- Model (Player, Recorder, FM, V2)
12- boot type (standard boot ROM or ROMless)
13
14Such a firmware file can then be programmed with "firmware_flash.rock".
diff --git a/flash/make_firmware/make_firmware.c b/flash/make_firmware/make_firmware.c
new file mode 100644
index 0000000000..220db4e5f1
--- /dev/null
+++ b/flash/make_firmware/make_firmware.c
@@ -0,0 +1,338 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2003 by Jörg Hohensohn
11 *
12 * Autoring tool for the firmware image to be programmed into Flash ROM
13 * It composes the flash content with header, bootloader and image(s)
14 *
15 * All files in this archive are subject to the GNU General Public License.
16 * See the file COPYING in the source tree root for full license agreement.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <memory.h>
27#include <string.h>
28
29#define UINT8 unsigned char
30#define UINT16 unsigned short
31#define UINT32 unsigned long
32#define BOOL int
33#define TRUE 1
34#define FALSE 0
35
36// size of one flash sector, the granularity with which it can be erased
37#define SECTORSIZE 4096
38
39#define BOOTLOAD_DEST 0x0FFFF500 // for the "normal" one
40#define BOOTLOAD_SCR 0x02000100
41#define ROCKBOX_DEST 0x09000000
42#define ROCKBOX_EXEC 0x09000200
43
44
45// place a 32 bit value into memory, big endian
46void Write32(UINT8* pByte, UINT32 value)
47{
48 pByte[0] = (UINT8)(value >> 24);
49 pByte[1] = (UINT8)(value >> 16);
50 pByte[2] = (UINT8)(value >> 8);
51 pByte[3] = (UINT8)(value);
52}
53
54
55// read a 32 bit value from memory, big endian
56UINT32 Read32(UINT8* pByte)
57{
58 UINT32 value = 0;
59
60 value |= (UINT32)pByte[0] << 24;
61 value |= (UINT32)pByte[1] << 16;
62 value |= (UINT32)pByte[2] << 8;
63 value |= (UINT32)pByte[3];
64
65 return value;
66}
67
68
69UINT32 CalcCRC32 (const UINT8* buf, UINT32 len)
70{
71 static const UINT32 crc_table[256] =
72 { // CRC32 lookup table for polynomial 0x04C11DB7
73 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B,
74 0x1A864DB2, 0x1E475005, 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
75 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, 0x4C11DB70, 0x48D0C6C7,
76 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75,
77 0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3,
78 0x709F7B7A, 0x745E66CD, 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039,
79 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, 0xBE2B5B58, 0xBAEA46EF,
80 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D,
81 0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, 0xC7361B4C, 0xC3F706FB,
82 0xCEB42022, 0xCA753D95, 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1,
83 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, 0x34867077, 0x30476DC0,
84 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072,
85 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x018AEB13, 0x054BF6A4,
86 0x0808D07D, 0x0CC9CDCA, 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE,
87 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, 0x5E9F46BF, 0x5A5E5B08,
88 0x571D7DD1, 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA,
89 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, 0xBB60ADFC,
90 0xB6238B25, 0xB2E29692, 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6,
91 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A, 0xE0B41DE7, 0xE4750050,
92 0xE9362689, 0xEDF73B3E, 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2,
93 0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34,
94 0xDC3ABDED, 0xD8FBA05A, 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637,
95 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, 0x4F040D56, 0x4BC510E1,
96 0x46863638, 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53,
97 0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5,
98 0x3F9B762C, 0x3B5A6B9B, 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF,
99 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, 0xF12F560E, 0xF5EE4BB9,
100 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B,
101 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD,
102 0xCDA1F604, 0xC960EBB3, 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7,
103 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, 0x9B3660C6, 0x9FF77D71,
104 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3,
105 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2,
106 0x470CDD2B, 0x43CDC09C, 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8,
107 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24, 0x119B4BE9, 0x155A565E,
108 0x18197087, 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC,
109 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A,
110 0x2D15EBE3, 0x29D4F654, 0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0,
111 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C, 0xE3A1CBC1, 0xE760D676,
112 0xEA23F0AF, 0xEEE2ED18, 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4,
113 0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662,
114 0x933EB0BB, 0x97FFAD0C, 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668,
115 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4
116 };
117 UINT32 i;
118 UINT32 crc = 0xffffffff;
119
120 for (i = 0; i < len; i++)
121 crc = (crc << 8) ^ crc_table[((crc >> 24) ^ *buf++) & 0xFF];
122
123 return crc;
124}
125
126
127UINT32 PlaceImage(char* filename, UINT32 pos, UINT8* pFirmware, UINT32 limit)
128{
129 UINT32 size, read;
130 FILE* pFile;
131 UINT32 align;
132 UINT32 flags;
133
134 // magic file header for compressed files
135 static const UINT8 magic[8] = { 0x00,0xe9,0x55,0x43,0x4c,0xff,0x01,0x1a };
136 UINT8 ucl_header[26];
137
138 pFile = fopen(filename, "rb"); // open the current image
139 if (pFile == NULL)
140 {
141 printf("Image file %s not found!\n", filename);
142 exit(5);
143 }
144
145 fseek(pFile, 0, SEEK_END);
146 size = ftell(pFile);
147 fseek(pFile, 0, SEEK_SET);
148
149 // determine if compressed
150 flags = 0x00000000; // default: flags for uncompressed
151 fread(ucl_header, 1, sizeof(ucl_header), pFile);
152 if (memcmp(magic, ucl_header, sizeof(magic)) == 0)
153 {
154 if (ucl_header[12] != 0x2E) // check algorithm
155 {
156 printf("UCL compressed files must use algorithm 2e, not %d\n", ucl_header[12]);
157 printf("Generate with: uclpack --best --2e rockbox.bin %s\n", filename);
158 exit(6);
159 }
160
161 size = Read32(ucl_header + 22); // compressed size
162 if (Read32(ucl_header + 18) > size) // compare with uncompressed size
163 { // normal case
164 flags = 0x00000001; // flags for UCL compressed
165 }
166 }
167 else
168 {
169 fseek(pFile, 0, SEEK_SET); // go back
170 }
171
172 if (pos + 16 + size > limit) // enough space for all that?
173 {
174 printf("Exceeding maximum image size %d\n", limit);
175 exit(7);
176 }
177
178 // write header
179 align = (pos + 16 + size + SECTORSIZE-1) & ~(SECTORSIZE-1); // round up to next flash sector
180 Write32(pFirmware + pos, ROCKBOX_DEST); // load address
181 Write32(pFirmware + pos + 4, align - (pos + 16)); // image size
182 Write32(pFirmware + pos + 8, ROCKBOX_EXEC); // execution address
183 Write32(pFirmware + pos + 12, flags); // compressed or not
184 pos += 16;
185
186 // load image
187 read = fread(pFirmware + pos, 1, size, pFile);
188 if (read != size)
189 {
190 printf("Read error, expecting %d bytes, got only %d\n", size, read);
191 exit(8);
192 }
193 fclose (pFile);
194
195 pos += size;
196
197 return pos;
198}
199
200
201int main(int argc, char* argv[])
202{
203 static UINT8 aFirmware[512*1024]; // maximum with exchanged chip
204 FILE* pFile;
205 UINT32 size; // size of loaded item
206 UINT32 pos; // current position in firmware
207 UINT32 crc32; // checksum of "payload"
208 BOOL hasBootRom; // flag if regular boot ROM or directly starts from flash
209 UINT32 template_F8, template_FC; // my platform ID, mask and version
210
211 int i;
212
213 if (argc <= 4)
214 {
215 printf("Usage:\n");
216 printf("make_firmware <output> <template.bin> <bootloader.ajz> <image1.ucl> {image2.ucl}\n");
217 printf("<template.bin> is the original firmware from your box\n");
218 printf("<bootloader.ajz> is the scrambled bootloader\n");
219 printf("<image1.ucl> is the first image, compressed (recommended) or uncompressed\n");
220 printf("<image1.ucl> is the second image, compressed (recommended) or uncompressed\n");
221 printf("More images may follow, but keep the flash size in mind!\n");
222 printf("Compression must be UCL, algorithm 2e.\n");
223 printf("Generated with: uclpack --best --2e rockbox.bin imageN.ucl\n");
224 exit(0);
225 }
226
227 memset(aFirmware, 0xFF, sizeof(aFirmware));
228
229 /******* process template *******/
230
231 pFile = fopen(argv[2], "rb"); // open the template
232 if (pFile == NULL)
233 {
234 printf("Template file %s not found!\n", argv[2]);
235 exit(1);
236 }
237 size = fread(aFirmware, 1, 256, pFile); // need only the header
238 fclose(pFile);
239 if (size < 256) // need at least the firmware header
240 {
241 printf("Template file %s too small, need at least the header!\n", argv[2]);
242 exit(2);
243 }
244
245 if (strncmp(aFirmware, "ARCH", 4) == 0)
246 {
247 hasBootRom = TRUE;
248 pos = 256; // place bootloader after this "boot block"
249 }
250 else if (Read32(aFirmware) == 0x0200)
251 {
252 hasBootRom = FALSE;
253 pos = 0; // directly start with the bootloader
254 template_F8 = Read32(aFirmware + 0xF8); // my platform ID and future info
255 template_FC = Read32(aFirmware + 0xFC); // use mask+version from template
256 }
257 else
258 {
259 printf("Template file %s invalid!\n", argv[2]);
260 exit(3);
261 }
262
263 /******* process bootloader *******/
264
265 pFile = fopen(argv[3], "rb"); // open the bootloader
266 if (pFile == NULL)
267 {
268 printf("Bootloader file %s not found!\n", argv[3]);
269 exit(4);
270 }
271 if (hasBootRom && fseek(pFile, 6, SEEK_SET)) // skip the ajz header
272 {
273 printf("Bootloader file %s too short!\n", argv[3]);
274 exit(5);
275 }
276
277 // place bootloader after header
278 size = fread(aFirmware + pos, 1, sizeof(aFirmware) - pos, pFile);
279 fclose(pFile);
280
281 if (hasBootRom)
282 {
283 Write32(aFirmware + 4, BOOTLOAD_DEST); // boot code destination address
284
285 for (i=0x08; i<=0x28; i+=8)
286 {
287 Write32(aFirmware + i, BOOTLOAD_SCR); // boot code source address
288 Write32(aFirmware + i + 4, size); // boot code size
289 }
290 }
291 else
292 {
293 Write32(aFirmware + 0xF8, template_F8); // values from template
294 Write32(aFirmware + 0xFC, template_FC); // mask and version
295 }
296
297 size = (size + 3) & ~3; // make shure it's 32 bit aligned
298 pos += size; // prepare position for first image
299
300 /******* process images *******/
301 for (i = 4; i < argc; i++)
302 {
303 pos = PlaceImage(argv[i], pos, aFirmware, sizeof(aFirmware));
304
305 if (i < argc-1)
306 { // not the last: round up to next flash sector
307 pos = (pos + SECTORSIZE-1) & ~(SECTORSIZE-1);
308 }
309 }
310
311
312 /******* append CRC32 checksum *******/
313 crc32 = CalcCRC32(aFirmware, pos);
314 Write32(aFirmware + pos, crc32);
315 pos += sizeof(crc32); // 4 bytes
316
317
318 /******* save result to output file *******/
319
320 pFile = fopen(argv[1], "wb"); // open the output file
321 if (pFile == NULL)
322 {
323 printf("Output file %s cannot be created!\n", argv[1]);
324 exit(9);
325 }
326 size = fwrite(aFirmware, 1, pos, pFile);
327 fclose(pFile);
328
329 if (size != pos)
330 {
331 printf("Error writing %d bytes to output file %s!\n", pos, argv[1]);
332 exit(10);
333 }
334
335 printf("Firmware file generated with %d bytes.\n", pos);
336
337 return 0;
338}
diff --git a/flash/make_firmware/make_firmware.dsp b/flash/make_firmware/make_firmware.dsp
new file mode 100644
index 0000000000..54a6f53671
--- /dev/null
+++ b/flash/make_firmware/make_firmware.dsp
@@ -0,0 +1,96 @@
1# Microsoft Developer Studio Project File - Name="make_firmware" - Package Owner=<4>
2# Microsoft Developer Studio Generated Build File, Format Version 6.00
3# ** DO NOT EDIT **
4
5# TARGTYPE "Win32 (x86) Console Application" 0x0103
6
7CFG=make_firmware - Win32 Debug
8!MESSAGE This is not a valid makefile. To build this project using NMAKE,
9!MESSAGE use the Export Makefile command and run
10!MESSAGE
11!MESSAGE NMAKE /f "make_firmware.mak".
12!MESSAGE
13!MESSAGE You can specify a configuration when running NMAKE
14!MESSAGE by defining the macro CFG on the command line. For example:
15!MESSAGE
16!MESSAGE NMAKE /f "make_firmware.mak" CFG="make_firmware - Win32 Debug"
17!MESSAGE
18!MESSAGE Possible choices for configuration are:
19!MESSAGE
20!MESSAGE "make_firmware - Win32 Release" (based on "Win32 (x86) Console Application")
21!MESSAGE "make_firmware - Win32 Debug" (based on "Win32 (x86) Console Application")
22!MESSAGE
23
24# Begin Project
25# PROP AllowPerConfigDependencies 0
26# PROP Scc_ProjName ""
27# PROP Scc_LocalPath ""
28CPP=cl.exe
29RSC=rc.exe
30
31!IF "$(CFG)" == "make_firmware - Win32 Release"
32
33# PROP BASE Use_MFC 0
34# PROP BASE Use_Debug_Libraries 0
35# PROP BASE Output_Dir "Release"
36# PROP BASE Intermediate_Dir "Release"
37# PROP BASE Target_Dir ""
38# PROP Use_MFC 0
39# PROP Use_Debug_Libraries 0
40# PROP Output_Dir "Release"
41# PROP Intermediate_Dir "Release"
42# PROP Target_Dir ""
43# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
44# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX"stdafx.h" /FD /c
45# ADD BASE RSC /l 0x407 /d "NDEBUG"
46# ADD RSC /l 0x407 /d "NDEBUG"
47BSC32=bscmake.exe
48# ADD BASE BSC32 /nologo
49# ADD BSC32 /nologo
50LINK32=link.exe
51# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
52# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
53
54!ELSEIF "$(CFG)" == "make_firmware - Win32 Debug"
55
56# PROP BASE Use_MFC 0
57# PROP BASE Use_Debug_Libraries 1
58# PROP BASE Output_Dir "Debug"
59# PROP BASE Intermediate_Dir "Debug"
60# PROP BASE Target_Dir ""
61# PROP Use_MFC 0
62# PROP Use_Debug_Libraries 1
63# PROP Output_Dir "Debug"
64# PROP Intermediate_Dir "Debug"
65# PROP Target_Dir ""
66# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
67# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX"stdafx.h" /FD /GZ /c
68# ADD BASE RSC /l 0x407 /d "_DEBUG"
69# ADD RSC /l 0x407 /d "_DEBUG"
70BSC32=bscmake.exe
71# ADD BASE BSC32 /nologo
72# ADD BSC32 /nologo
73LINK32=link.exe
74# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
75# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
76
77!ENDIF
78
79# Begin Target
80
81# Name "make_firmware - Win32 Release"
82# Name "make_firmware - Win32 Debug"
83# Begin Group "Source Files"
84
85# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
86# Begin Source File
87
88SOURCE=.\make_firmware.c
89# End Source File
90# End Group
91# Begin Group "Header Files"
92
93# PROP Default_Filter "h;hpp;hxx;hm;inl"
94# End Group
95# End Target
96# End Project
diff --git a/flash/minimon/Makefile b/flash/minimon/Makefile
new file mode 100644
index 0000000000..57ae13e940
--- /dev/null
+++ b/flash/minimon/Makefile
@@ -0,0 +1,53 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10CC = sh-elf-gcc
11LD = sh-elf-ld
12AR = sh-elf-ar
13AS = sh-elf-as
14OC = sh-elf-objcopy
15
16FIRMWARE := ../../firmware
17TOOLSDIR=../../tools
18
19TARGET = minimon
20LDS := $(TARGET).lds
21
22INCLUDES= -I$(FIRMWARE)/export -I. -I$(OBJDIR)
23OBJDIR := .
24
25CFLAGS = -fpic -O -W -Wall -m1 -nostdlib -ffreestanding -Wstrict-prototypes -fomit-frame-pointer -fschedule-insns $(INCLUDES) $(DEFINES)
26AFLAGS += -small -relax
27
28
29ifdef DEBUG
30 DEFINES := -DDEBUG
31 CFLAGS += -g
32endif
33
34SRC := $(wildcard *.c)
35
36OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
37
38LINKFILE = $(OBJDIR)/$(TARGET).lds
39
40
41$(OBJDIR)/$(TARGET).bin : $(OBJDIR)/$(TARGET).elf
42 $(OC) -O binary $(OBJDIR)/$(TARGET).elf $(OBJDIR)/$(TARGET).bin
43 $(TOOLSDIR)/sh2d $(OBJDIR)/$(TARGET).bin -o 0900000 > $(OBJDIR)/$(TARGET).asm
44
45$(OBJDIR)/$(TARGET).elf : $(OBJS)
46 $(CC) -Os -nostdlib -o $(OBJDIR)/$(TARGET).elf -L$(OBJDIR) -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/$(TARGET).map
47
48
49clean:
50 -rm -f $(OBJS) $(OBJDIR)/$(TARGET).asm \
51 $(OBJDIR)/$(TARGET).bin \
52 $(OBJDIR)/$(TARGET).elf \
53 $(OBJDIR)/$(TARGET).map
diff --git a/flash/minimon/README b/flash/minimon/README
new file mode 100644
index 0000000000..b80edd9689
--- /dev/null
+++ b/flash/minimon/README
@@ -0,0 +1,6 @@
1(c) 2003 by Jörg Hohensohn
2
3MiniMon is the tiny but powerful-enough piece of code that can be loaded
4with the UART boot mod.
5It allows to read and write memory, flash program, execute code.
6This is suitable to reflash the box, load Rockbox or the gdb stub, etc.
diff --git a/flash/minimon/minimon.c b/flash/minimon/minimon.c
new file mode 100644
index 0000000000..e7981f2d09
--- /dev/null
+++ b/flash/minimon/minimon.c
@@ -0,0 +1,156 @@
1// minimalistic monitor
2// to be loaded with the UART boot feature
3// capable of reading and writing bytes, commanded by UART
4
5#include "sh7034.h"
6#include "minimon.h"
7
8// scalar types
9typedef unsigned char UINT8;
10typedef unsigned short UINT16;
11typedef unsigned long UINT32;
12
13typedef void(*tpFunc)(void); // type for exec
14typedef int(*tpMain)(void); // type for start vector to main()
15
16
17// prototypes
18int main(void);
19
20// our binary has to start with a vector to the entry point
21tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
22
23
24UINT8 uart_read(void)
25{
26 UINT8 byte;
27 while (!(SSR1 & SCI_RDRF)); // wait for char to be available
28 byte = RDR1;
29 SSR1 &= ~SCI_RDRF;
30 return byte;
31}
32
33
34void uart_write(UINT8 byte)
35{
36 while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty
37 TDR1 = byte;
38 SSR1 &= ~SCI_TDRE;
39}
40
41
42int main(void)
43{
44 UINT8 cmd;
45 UINT32 addr;
46 UINT32 size;
47 UINT32 content;
48 volatile UINT8* paddr = 0;
49 volatile UINT8* pflash; // flash base address
50
51 while (1)
52 {
53 cmd = uart_read();
54 switch (cmd)
55 {
56 case BAUDRATE:
57 content = uart_read();
58 uart_write(cmd); // acknowledge by returning the command value
59 while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate
60 BRR1 = content;
61 break;
62
63 case ADDRESS:
64 addr = (uart_read() << 24) | (uart_read() << 16) | (uart_read() << 8) | uart_read();
65 paddr = (UINT8*)addr;
66 pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align
67 uart_write(cmd); // acknowledge by returning the command value
68 break;
69
70 case BYTE_READ:
71 content = *paddr++;
72 uart_write(content); // the content is the ack
73 break;
74
75 case BYTE_WRITE:
76 content = uart_read();
77 *paddr++ = content;
78 uart_write(cmd); // acknowledge by returning the command value
79 break;
80
81 case BYTE_READ16:
82 size = 16;
83 while (size--)
84 {
85 content = *paddr++;
86 uart_write(content); // the content is the ack
87 }
88 break;
89
90 case BYTE_WRITE16:
91 size = 16;
92 while (size--)
93 {
94 content = uart_read();
95 *paddr++ = content;
96 }
97 uart_write(cmd); // acknowledge by returning the command value
98 break;
99
100 case BYTE_FLASH:
101 content = uart_read();
102 pflash[0x5555] = 0xAA; // set flash to command mode
103 pflash[0x2AAA] = 0x55;
104 pflash[0x5555] = 0xA0; // byte program command
105 *paddr++ = content;
106 uart_write(cmd); // acknowledge by returning the command value
107 break;
108
109 case BYTE_FLASH16:
110 size = 16;
111 while (size--)
112 {
113 content = uart_read();
114 pflash[0x5555] = 0xAA; // set flash to command mode
115 pflash[0x2AAA] = 0x55;
116 pflash[0x5555] = 0xA0; // byte program command
117 *paddr++ = content;
118 }
119 uart_write(cmd); // acknowledge by returning the command value
120 break;
121
122 case HALFWORD_READ:
123 content = *(UINT16*)paddr;
124 paddr += 2;
125 uart_write(content >> 8); // highbyte
126 uart_write(content & 0xFF); // lowbyte
127 break;
128
129 case HALFWORD_WRITE:
130 content = uart_read() << 8 | uart_read();
131 *(UINT16*)paddr = content;
132 paddr += 2;
133 uart_write(cmd); // acknowledge by returning the command value
134 break;
135
136 case EXECUTE:
137 {
138 tpFunc pFunc = (tpFunc)paddr;
139 pFunc();
140 uart_write(cmd); // acknowledge by returning the command value
141 }
142 break;
143
144
145 default:
146 {
147 volatile UINT16* pPortB = (UINT16*)0x05FFFFC2;
148 *pPortB |= 1 << 6; // bit 6 is red LED on
149 uart_write(~cmd); // error acknowledge
150 }
151
152 } // case
153 }
154
155 return 0;
156}
diff --git a/flash/minimon/minimon.h b/flash/minimon/minimon.h
new file mode 100644
index 0000000000..b6e9805ecf
--- /dev/null
+++ b/flash/minimon/minimon.h
@@ -0,0 +1,24 @@
1#ifndef _MINIMON_H
2#define _MINIMON_H
3
4
5// Commands
6// all multibyte values (address, halfwords) are passed as big endian
7// (most significant of the bytes first)
8
9// set the address (all read/write commands will auto-increment it)
10#define BAUDRATE 0x00 // followed by BRR value; response: command byte
11#define ADDRESS 0x01 // followed by 4 bytes address; response: command byte
12#define BYTE_READ 0x02 // response: 1 byte content
13#define BYTE_WRITE 0x03 // followed by 1 byte content; response: command byte
14#define BYTE_READ16 0x04 // response: 16 bytes content
15#define BYTE_WRITE16 0x05 // followed by 16 bytes; response: command byte
16#define BYTE_FLASH 0x06 // followed by 1 byte content; response: command byte
17#define BYTE_FLASH16 0x07 // followed by 16 bytes; response: command byte
18#define HALFWORD_READ 0x08 // response: 2 byte content
19#define HALFWORD_WRITE 0x09 // followed by 2 byte content; response: command byte
20#define EXECUTE 0x0A // response: command byte if call returns
21#define VERSION 0x0B // response: version
22
23
24#endif // _MINIMON_H
diff --git a/flash/minimon/minimon.lds b/flash/minimon/minimon.lds
new file mode 100644
index 0000000000..dbdbdc3faa
--- /dev/null
+++ b/flash/minimon/minimon.lds
@@ -0,0 +1,60 @@
1OUTPUT_FORMAT(elf32-sh)
2INPUT(minimon.o)
3
4MEMORY
5{
6 DRAM : ORIGIN = 0x09000000, LENGTH = 0x200000
7}
8
9SECTIONS
10{
11 .startvector :
12 {
13 *(.startvector)
14 . = ALIGN(0x4);
15 } > DRAM
16
17 .got :
18 {
19 *(.got)
20 } > DRAM
21
22 .got.plt :
23 {
24 *(.got.plt)
25 } > DRAM
26
27 .rela.got :
28 {
29 *(.rela.got)
30 } > DRAM
31
32 .text :
33 {
34 . = ALIGN(0x200);
35 *(.entry)
36 *(.text)
37 . = ALIGN(0x4);
38 } > DRAM
39
40 .data :
41 {
42 *(.data)
43 } > DRAM
44
45 .rodata :
46 {
47 *(.rodata)
48 . = ALIGN(0x4);
49 } > DRAM
50
51 .bss :
52 {
53 *(.bss)
54 } > DRAM
55
56 .stack :
57 {
58 *(.stack)
59 } > DRAM
60}
diff --git a/flash/uart_boot/README b/flash/uart_boot/README
new file mode 100644
index 0000000000..edfa20c121
--- /dev/null
+++ b/flash/uart_boot/README
@@ -0,0 +1,8 @@
1(c) 2003 by Jörg Hohensohn
2
3This is the client side for MiniMon, a command line program that communicates with it.
4It can be used to reflash a box from ground up, load a program like gdb stub or Rockbox,
5and other diagnostics.
6
7Current implementation is for Windows, but with a different UART implementation
8it should work for other platforms (Linux) as well.
diff --git a/flash/uart_boot/client.c b/flash/uart_boot/client.c
new file mode 100644
index 0000000000..a98edc60cb
--- /dev/null
+++ b/flash/uart_boot/client.c
@@ -0,0 +1,738 @@
1// client.cpp : functions for monitor download and communication.
2//
3
4#include <stdio.h>
5#include <stdlib.h>
6#include "scalar_types.h" // (U)INT8/16/32
7#include "Uart.h" // platform abstraction for UART
8#include "minimon.h" // protocol of my little monitor
9
10// do the baudrate configuration for the Player
11int ConfigFirstlevelPlayer (tUartHandle serial_handle)
12{
13 UINT32 result_nbr;
14
15 if(!UartConfig(serial_handle, 4800, eMARKPARITY, eTWOSTOPBITS, 8))
16 {
17 UINT32 dwErr = GET_LAST_ERR();
18 printf("Error %d setting up COM params for baudrate byte\n", dwErr);
19 exit(1);
20 }
21
22 // this will read as 0x19 when viewed with 2300 baud like the player does
23 result_nbr = UartWrite(serial_handle, (UINT8*)"\x86\xC0", 2);
24 if (result_nbr != 2)
25 {
26 UINT32 dwErr = GET_LAST_ERR();
27 printf("Error %d setting up COM params for baudrate byte\n", dwErr);
28 }
29
30 SLEEP(100); // wait for the chars to be sent, is there a better way?
31
32 // the read 0x19 means 14423 baud with 12 MHz
33 if(!UartConfig(serial_handle, 14400, eNOPARITY, eONESTOPBIT, 8))
34 {
35 printf("Error setting up COM params for 1st level loader\n");
36 exit(1);
37 }
38
39 return 0;
40}
41
42
43// do the baudrate configuration for the Recoder/FM
44int ConfigFirstlevelRecorder (tUartHandle serial_handle)
45{
46 UINT32 result_nbr;
47
48 if(!UartConfig(serial_handle, 4800, eNOPARITY, eTWOSTOPBITS, 8))
49 {
50 UINT32 dwErr = GET_LAST_ERR();
51 printf("Error %d setting up COM params for baudrate byte\n", dwErr);
52 exit(1);
53 }
54
55 // this will read as 0x08 when viewed with 2120 baud like the recorder does
56 result_nbr = UartWrite(serial_handle, (UINT8*)"\x00\x00", 2);
57 if(result_nbr != 2)
58 {
59 printf("Error transmitting baudrate byte\n");
60 exit(1);
61 }
62
63 SLEEP(100); // wait for the chars to be sent, is there a better way?
64
65 // the read 0x08 means 38400 baud with 11.0592 MHz
66 if(!UartConfig(serial_handle, 38400, eNOPARITY, eONESTOPBIT, 8))
67 {
68 UINT32 dwErr = GET_LAST_ERR();
69 printf("Error %d setting up COM params for 1st level loader\n", dwErr);
70 exit(1);
71 }
72
73 return 0;
74}
75
76
77// transfer a byte for the monitor download, with or without acknowledge
78int DownloadByte(tUartHandle serial_handle, unsigned char byte, bool bAck)
79{
80 unsigned char received;
81 bool bRecorder = true; // false for player
82
83 while (1)
84 {
85 UartWrite(serial_handle, &byte, 1);
86 if (bAck)
87 {
88 UartRead(serial_handle, &received, 1);
89 if (received == byte)
90 {
91 UartWrite(serial_handle, (UINT8*)"\x01", 1); // ack success
92 break; // exit the loop
93 }
94 else
95 {
96 printf("Error transmitting monitor byte 0x%02X, got 0x%0X\n", byte, received);
97 UartWrite(serial_handle, (UINT8*)"\x00", 1); // ack fail, try again
98 }
99 }
100 else
101 break; // no loop
102 }
103 return 1;
104}
105
106
107// download our little monitor, the box must have been just freshly switched on for this to work
108int DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename)
109{
110 FILE* pFile;
111 size_t filesize;
112 UINT8 byte;
113 unsigned i;
114
115 // hard-coded parameters
116 bool bAck = true; // configure if acknowledged download (without useful for remote pin boot)
117 UINT32 TargetLoad = 0x0FFFF000; // target load address
118
119 pFile = fopen(szFilename, "rb");
120 if (pFile == NULL)
121 {
122 printf("\nMonitor file %s not found, exiting\n", szFilename);
123 exit(1);
124 }
125
126 // determine file size
127 fseek(pFile, 0, SEEK_END);
128 filesize = ftell(pFile);
129 fseek(pFile, 0, SEEK_SET);
130
131 // This is _really_ tricky! The box expects a BRR value in a nonstandard baudrate,
132 // which a PC can't generate. I'm using a higher one with some wild settings
133 // to generate a pulse series that:
134 // 1) looks like a stable byte when sampled with the nonstandard baudrate
135 // 2) gives a BRR value to the box which results in a baudrate the PC can also use
136 if (bRecorder)
137 {
138 ConfigFirstlevelRecorder(serial_handle);
139 }
140 else
141 {
142 ConfigFirstlevelPlayer(serial_handle);
143 }
144
145 UartWrite(serial_handle, bAck ? (UINT8*)"\x01" : (UINT8*)"\x00", 1); // ACK mode
146
147 // transmit the size, little endian
148 DownloadByte(serial_handle, (UINT8)( filesize & 0xFF), bAck);
149 DownloadByte(serial_handle, (UINT8)((filesize>>8) & 0xFF), bAck);
150 DownloadByte(serial_handle, (UINT8)((filesize>>16) & 0xFF), bAck);
151 DownloadByte(serial_handle, (UINT8)((filesize>>24) & 0xFF), bAck);
152
153 // transmit the load address, little endian
154 DownloadByte(serial_handle, (UINT8)( TargetLoad & 0xFF), bAck);
155 DownloadByte(serial_handle, (UINT8)((TargetLoad>>8) & 0xFF), bAck);
156 DownloadByte(serial_handle, (UINT8)((TargetLoad>>16) & 0xFF), bAck);
157 DownloadByte(serial_handle, (UINT8)((TargetLoad>>24) & 0xFF), bAck);
158
159 // transmit the command byte
160 DownloadByte(serial_handle, 0xFF, bAck); // 0xFF means execute the transferred image
161
162 // transmit the image
163 for (i=0; i<filesize; i++)
164 {
165 fread(&byte, 1, 1, pFile);
166 DownloadByte(serial_handle, byte, bAck);
167 }
168
169 fclose (pFile);
170
171 // now the image should have been started, red LED off
172
173 return 0;
174}
175
176
177// wait for a fixed string to be received (no foolproof algorithm,
178// may overlook if the searched string contains repeatitions)
179int WaitForString(tUartHandle serial_handle, char* pszWait)
180{
181 int i = 0;
182 unsigned char received;
183
184 while(pszWait[i] != '\0')
185 {
186 UartRead(serial_handle, &received, 1);
187
188 printf("%c", received); // debug
189
190 if (received == pszWait[i])
191 i++; // continue
192 else
193 i=0; // mismatch, start over
194 }
195 return 0;
196}
197
198
199// send a sting and check the echo
200int SendWithEcho(tUartHandle serial_handle, char* pszSend)
201{
202 int i = 0;
203 unsigned char received;
204
205 while(pszSend[i] != '\0')
206 {
207 UartWrite(serial_handle, (unsigned char*)(pszSend + i), 1); // send char
208 do
209 {
210 UartRead(serial_handle, &received, 1); // receive echo
211 printf("%c", received); // debug
212 }
213 while (received != pszSend[i]); // should normally be equal
214 i++; // next char
215 }
216 return 0;
217}
218
219
220// rarely used variant: download our monitor using the built-in Archos monitor
221int DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename)
222{
223 FILE* pFile;
224 size_t filesize;
225 UINT8 byte;
226 UINT16 checksum = 0;
227 unsigned i;
228
229 // the onboard monitor uses 115200 baud
230 if(!UartConfig(serial_handle, 115200, eNOPARITY, eONESTOPBIT, 8))
231 {
232 UINT32 dwErr = GET_LAST_ERR();
233 printf("Error %d setting up COM params for baudrate %d\n", dwErr, 115200);
234 exit(1);
235 }
236
237 // wait for receiving "#SERIAL#"
238 WaitForString(serial_handle, "#SERIAL#");
239
240 // send magic "SRL" command to get interactive mode
241 SendWithEcho(serial_handle, "SRL\r");
242
243 // wait for menu completion: "ROOT>" at the end
244 WaitForString(serial_handle, "ROOT>");
245
246 // send upload command "UP"
247 SendWithEcho(serial_handle, "UP\r");
248
249 pFile = fopen(szFilename, "rb");
250 if (pFile == NULL)
251 {
252 printf("\nMonitor file %s not found, exiting\n", szFilename);
253 exit(1);
254 }
255
256 // determine file size
257 fseek(pFile, 0, SEEK_END);
258 filesize = ftell(pFile);
259 fseek(pFile, 0, SEEK_SET);
260
261 // calculate checksum
262 for (i=0; i<filesize; i++)
263 {
264 fread(&byte, 1, 1, pFile);
265 checksum += byte;
266 }
267 fseek(pFile, 0, SEEK_SET);
268
269 // send header
270
271 // size as 32 bit little endian
272 byte = (UINT8)( filesize & 0xFF);
273 UartWrite(serial_handle, &byte, 1);
274 byte = (UINT8)((filesize>>8) & 0xFF);
275 UartWrite(serial_handle, &byte, 1);
276 byte = (UINT8)((filesize>>16) & 0xFF);
277 UartWrite(serial_handle, &byte, 1);
278 byte = (UINT8)((filesize>>24) & 0xFF);
279 UartWrite(serial_handle, &byte, 1);
280
281 // checksum as 16 bit little endian
282 byte = (UINT8)( checksum & 0xFF);
283 UartWrite(serial_handle, &byte, 1);
284 byte = (UINT8)((checksum>>8) & 0xFF);
285 UartWrite(serial_handle, &byte, 1);
286
287 UartWrite(serial_handle, (unsigned char*)"\x00", 1); // kind (3 means flash)
288 UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte
289
290 // wait for monitor to accept data
291 WaitForString(serial_handle, "#OKCTRL#");
292
293 // transmit the image
294 for (i=0; i<filesize; i++)
295 {
296 fread(&byte, 1, 1, pFile);
297 UartWrite(serial_handle, &byte, 1); // payload
298 }
299 fclose (pFile);
300
301 UartWrite(serial_handle, (unsigned char*)"\x00", 1); // ignored byte
302
303 // wait for menu completion: "ROOT>" at the end
304 WaitForString(serial_handle, "ROOT>");
305
306 // send start program command "SPRO"
307 SendWithEcho(serial_handle, "SPRO\r");
308
309 SLEEP(100); // wait a little while for startup
310
311 return 0;
312}
313
314
315/********** Target functions using the Monitor Protocol **********/
316
317// read a byte using the target monitor
318UINT8 ReadByte(tUartHandle serial_handle, UINT32 addr)
319{
320 UINT8 send;
321 UINT8 received;
322
323 // send the address command
324 send = ADDRESS;
325 UartWrite(serial_handle, &send, 1);
326
327 // transmit the address, big endian
328 send = (UINT8)((addr>>24) & 0xFF);
329 UartWrite(serial_handle, &send, 1);
330 send = (UINT8)((addr>>16) & 0xFF);
331 UartWrite(serial_handle, &send, 1);
332 send = (UINT8)((addr>>8) & 0xFF);
333 UartWrite(serial_handle, &send, 1);
334 send = (UINT8)(addr & 0xFF);
335 UartWrite(serial_handle, &send, 1);
336
337 UartRead(serial_handle, &received, 1); // response
338 if (received != ADDRESS)
339 {
340 printf("Protocol error!\n");
341 return 1;
342 }
343
344 // send the read command
345 send = BYTE_READ;
346 UartWrite(serial_handle, &send, 1);
347
348 UartRead(serial_handle, &received, 1); // response
349
350 return received;
351}
352
353
354// write a byte using the target monitor
355int WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte)
356{
357 UINT8 send;
358 UINT8 received;
359
360 // send the address command
361 send = ADDRESS;
362 UartWrite(serial_handle, &send, 1);
363
364 // transmit the address, big endian
365 send = (UINT8)((addr>>24) & 0xFF);
366 UartWrite(serial_handle, &send, 1);
367 send = (UINT8)((addr>>16) & 0xFF);
368 UartWrite(serial_handle, &send, 1);
369 send = (UINT8)((addr>>8) & 0xFF);
370 UartWrite(serial_handle, &send, 1);
371 send = (UINT8)(addr & 0xFF);
372 UartWrite(serial_handle, &send, 1);
373
374 UartRead(serial_handle, &received, 1); // response
375 if (received != ADDRESS)
376 {
377 printf("Protocol error, receiced 0x%02X!\n", received);
378 return 1;
379 }
380
381 // send the write command
382 send = BYTE_WRITE;
383 UartWrite(serial_handle, &send, 1);
384
385 // transmit the data
386 UartWrite(serial_handle, &byte, 1);
387
388 UartRead(serial_handle, &received, 1); // response
389
390 if (received != BYTE_WRITE)
391 {
392 printf("Protocol error!\n");
393 return 1;
394 }
395
396 return 0;
397}
398
399
400// read many bytes using the target monitor
401int ReadByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
402{
403 UINT8 send, received;
404
405 // send the address command
406 send = ADDRESS;
407 UartWrite(serial_handle, &send, 1);
408
409 // transmit the address, big endian
410 send = (UINT8)((addr>>24) & 0xFF);
411 UartWrite(serial_handle, &send, 1);
412 send = (UINT8)((addr>>16) & 0xFF);
413 UartWrite(serial_handle, &send, 1);
414 send = (UINT8)((addr>>8) & 0xFF);
415 UartWrite(serial_handle, &send, 1);
416 send = (UINT8)(addr & 0xFF);
417 UartWrite(serial_handle, &send, 1);
418
419 UartRead(serial_handle, &received, 1); // response
420 if (received != ADDRESS)
421 {
422 printf("Protocol error!\n");
423 return 1;
424 }
425
426 while (size)
427 {
428 if (size >= 16)
429 { // we can use a "burst" command
430 send = BYTE_READ16;
431 UartWrite(serial_handle, &send, 1); // send the read command
432 UartRead(serial_handle, pBuffer, 16); // data response
433 pBuffer += 16;
434 size -= 16;
435 }
436 else
437 { // use single byte command
438 send = BYTE_READ;
439 UartWrite(serial_handle, &send, 1); // send the read command
440 UartRead(serial_handle, pBuffer++, 1); // data response
441 size--;
442 }
443 }
444
445 return 0;
446}
447
448
449// write many bytes using the target monitor
450int WriteByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
451{
452 UINT8 send, received;
453
454 // send the address command
455 send = ADDRESS;
456 UartWrite(serial_handle, &send, 1);
457
458 // transmit the address, big endian
459 send = (UINT8)((addr>>24) & 0xFF);
460 UartWrite(serial_handle, &send, 1);
461 send = (UINT8)((addr>>16) & 0xFF);
462 UartWrite(serial_handle, &send, 1);
463 send = (UINT8)((addr>>8) & 0xFF);
464 UartWrite(serial_handle, &send, 1);
465 send = (UINT8)(addr & 0xFF);
466 UartWrite(serial_handle, &send, 1);
467
468 UartRead(serial_handle, &received, 1); // response
469 if (received != ADDRESS)
470 {
471 printf("Protocol error!\n");
472 return 1;
473 }
474
475 while (size)
476 {
477 if (size >= 16)
478 { // we can use a "burst" command
479 send = BYTE_WRITE16;
480 UartWrite(serial_handle, &send, 1); // send the write command
481 UartWrite(serial_handle, pBuffer, 16); // transmit the data
482 UartRead(serial_handle, &received, 1); // response
483 if (received != BYTE_WRITE16)
484 {
485 printf("Protocol error!\n");
486 return 1;
487 }
488 pBuffer += 16;
489 size -= 16;
490 }
491 else
492 { // use single byte command
493 send = BYTE_WRITE;
494 UartWrite(serial_handle, &send, 1); // send the write command
495 UartWrite(serial_handle, pBuffer++, 1); // transmit the data
496 UartRead(serial_handle, &received, 1); // response
497 if (received != BYTE_WRITE)
498 {
499 printf("Protocol error!\n");
500 return 1;
501 }
502 size--;
503 }
504 }
505
506 return 0;
507}
508
509
510// write many bytes using the target monitor
511int FlashByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer)
512{
513 UINT8 send, received;
514
515 // send the address command
516 send = ADDRESS;
517 UartWrite(serial_handle, &send, 1);
518
519 // transmit the address, big endian
520 send = (UINT8)((addr>>24) & 0xFF);
521 UartWrite(serial_handle, &send, 1);
522 send = (UINT8)((addr>>16) & 0xFF);
523 UartWrite(serial_handle, &send, 1);
524 send = (UINT8)((addr>>8) & 0xFF);
525 UartWrite(serial_handle, &send, 1);
526 send = (UINT8)(addr & 0xFF);
527 UartWrite(serial_handle, &send, 1);
528
529 UartRead(serial_handle, &received, 1); // response
530 if (received != ADDRESS)
531 {
532 printf("Protocol error!\n");
533 return 1;
534 }
535
536 while (size)
537 {
538 if (size >= 16)
539 { // we can use a "burst" command
540 send = BYTE_FLASH16;
541 UartWrite(serial_handle, &send, 1); // send the write command
542 UartWrite(serial_handle, pBuffer, 16); // transmit the data
543 UartRead(serial_handle, &received, 1); // response
544 if (received != BYTE_FLASH16)
545 {
546 printf("Protocol error!\n");
547 return 1;
548 }
549 pBuffer += 16;
550 size -= 16;
551 }
552 else
553 { // use single byte command
554 send = BYTE_FLASH;
555 UartWrite(serial_handle, &send, 1); // send the write command
556 UartWrite(serial_handle, pBuffer++, 1); // transmit the data
557 UartRead(serial_handle, &received, 1); // response
558 if (received != BYTE_FLASH)
559 {
560 printf("Protocol error!\n");
561 return 1;
562 }
563 size--;
564 }
565 }
566
567 return 0;
568}
569
570
571// read a 16bit halfword using the target monitor
572UINT16 ReadHalfword(tUartHandle serial_handle, UINT32 addr)
573{
574 UINT8 send;
575 UINT8 received;
576 UINT16 halfword;
577
578 // send the address command
579 send = ADDRESS;
580 UartWrite(serial_handle, &send, 1);
581
582 // transmit the address, big endian
583 send = (UINT8)((addr>>24) & 0xFF);
584 UartWrite(serial_handle, &send, 1);
585 send = (UINT8)((addr>>16) & 0xFF);
586 UartWrite(serial_handle, &send, 1);
587 send = (UINT8)((addr>>8) & 0xFF);
588 UartWrite(serial_handle, &send, 1);
589 send = (UINT8)(addr & 0xFF);
590 UartWrite(serial_handle, &send, 1);
591
592 UartRead(serial_handle, &received, 1); // response
593 if (received != ADDRESS)
594 {
595 printf("Protocol error!\n");
596 return 1;
597 }
598
599 // send the read command
600 send = HALFWORD_READ;
601 UartWrite(serial_handle, &send, 1);
602
603 UartRead(serial_handle, &received, 1); // response
604 halfword = received << 8; // highbyte
605 UartRead(serial_handle, &received, 1);
606 halfword |= received; // lowbyte
607
608 return halfword;
609}
610
611
612// write a 16bit halfword using the target monitor
613int WriteHalfword(tUartHandle serial_handle, UINT32 addr, UINT16 halfword)
614{
615 UINT8 send;
616 UINT8 received;
617
618 // send the address command
619 send = ADDRESS;
620 UartWrite(serial_handle, &send, 1);
621
622 // transmit the address, big endian
623 send = (UINT8)((addr>>24) & 0xFF);
624 UartWrite(serial_handle, &send, 1);
625 send = (UINT8)((addr>>16) & 0xFF);
626 UartWrite(serial_handle, &send, 1);
627 send = (UINT8)((addr>>8) & 0xFF);
628 UartWrite(serial_handle, &send, 1);
629 send = (UINT8)(addr & 0xFF);
630 UartWrite(serial_handle, &send, 1);
631
632 UartRead(serial_handle, &received, 1); // response
633 if (received != ADDRESS)
634 {
635 printf("Protocol error!\n");
636 return 1;
637 }
638
639 // send the write command
640 send = HALFWORD_WRITE;
641 UartWrite(serial_handle, &send, 1);
642
643 // transmit the data
644 send = halfword >> 8; // highbyte
645 UartWrite(serial_handle, &send, 1);
646 send = halfword & 0xFF; // lowbyte
647 UartWrite(serial_handle, &send, 1);
648
649 UartRead(serial_handle, &received, 1); // response
650
651 if (received != HALFWORD_WRITE)
652 {
653 printf("Protocol error!\n");
654 return 1;
655 }
656
657 return 0;
658}
659
660
661// change baudrate using target monitor
662int SetTargetBaudrate(tUartHandle serial_handle, long lClock, long lBaudrate)
663{
664 UINT8 send;
665 UINT8 received;
666 UINT8 brr;
667 long lBRR;
668
669 lBRR = lClock / lBaudrate;
670 lBRR = ((lBRR + 16) / 32) - 1; // with rounding
671 brr = (UINT8)lBRR;
672
673 // send the command
674 send = BAUDRATE;
675 UartWrite(serial_handle, &send, 1);
676 UartWrite(serial_handle, &brr, 1); // send the BRR value
677 UartRead(serial_handle, &received, 1); // response ack
678
679 if (received != BAUDRATE)
680 { // bad situation, now we're unclear about the baudrate of the target
681 printf("Protocol error!\n");
682 return 1;
683 }
684
685 SLEEP(100); // give it some time to settle
686
687 // change our baudrate, too
688 UartConfig(serial_handle, lBaudrate, eNOPARITY, eONESTOPBIT, 8);
689
690 return 0;
691}
692
693
694// call a subroutine using the target monitor
695int Execute(tUartHandle serial_handle, UINT32 addr, bool bReturns)
696{
697 UINT8 send;
698 UINT8 received;
699
700 // send the address command
701 send = ADDRESS;
702 UartWrite(serial_handle, &send, 1);
703
704 // transmit the address, big endian
705 send = (UINT8)((addr>>24) & 0xFF);
706 UartWrite(serial_handle, &send, 1);
707 send = (UINT8)((addr>>16) & 0xFF);
708 UartWrite(serial_handle, &send, 1);
709 send = (UINT8)((addr>>8) & 0xFF);
710 UartWrite(serial_handle, &send, 1);
711 send = (UINT8)(addr & 0xFF);
712 UartWrite(serial_handle, &send, 1);
713
714 UartRead(serial_handle, &received, 1); // response
715 if (received != ADDRESS)
716 {
717 printf("Protocol error!\n");
718 return 1;
719 }
720
721 // send the execute command
722 send = EXECUTE;
723 UartWrite(serial_handle, &send, 1);
724 if (bReturns)
725 { // we expect the call to return control to minimon
726 UartRead(serial_handle, &received, 1); // response
727
728 if (received != EXECUTE)
729 {
730 printf("Protocol error!\n");
731 return 1;
732 }
733 }
734
735 return 0;
736}
737
738
diff --git a/flash/uart_boot/client.h b/flash/uart_boot/client.h
new file mode 100644
index 0000000000..d2ef29aa2e
--- /dev/null
+++ b/flash/uart_boot/client.h
@@ -0,0 +1,21 @@
1#ifndef _CLIENT_H
2#define _CLIENT_H
3
4
5// setup function for monitor download
6int DownloadMonitor(tUartHandle serial_handle, bool bRecorder, char* szFilename);
7int DownloadArchosMonitor(tUartHandle serial_handle, char* szFilename);
8
9// target functions using the Monitor Protocol
10UINT8 ReadByte(tUartHandle serial_handle, UINT32 addr);
11int WriteByte(tUartHandle serial_handle, UINT32 addr, UINT8 byte);
12int ReadByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer);
13int WriteByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer);
14int FlashByteMultiple(tUartHandle serial_handle, UINT32 addr, UINT32 size, UINT8* pBuffer);
15UINT16 ReadHalfword(tUartHandle serial_handle, UINT32 addr);
16int WriteHalfword(tUartHandle serial_handle, UINT32 addr, UINT16 halfword);
17int SetTargetBaudrate(tUartHandle serial_handle, long lClock, long lBaudrate);
18int Execute(tUartHandle serial_handle, UINT32 addr, bool bReturns);
19
20
21#endif \ No newline at end of file
diff --git a/flash/uart_boot/flash.c b/flash/uart_boot/flash.c
new file mode 100644
index 0000000000..f27bb7ec0a
--- /dev/null
+++ b/flash/uart_boot/flash.c
@@ -0,0 +1,77 @@
1// flash.cpp : higher-level functions for flashing the chip
2//
3
4#include "scalar_types.h" // (U)INT8/16/32
5#include "Uart.h" // platform abstraction for UART
6#include "client.h" // client functions
7
8
9// read the manufacturer and device ID
10int ReadID(tUartHandle serial_handle, UINT32 base, UINT8* pManufacturerID, UINT8* pDeviceID)
11{
12 base &= 0xFFF80000; // round down to 512k align, to make shure
13
14 WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode
15 WriteByte(serial_handle, base + 0x2AAA, 0x55);
16 WriteByte(serial_handle, base + 0x5555, 0x90); // ID command
17 SLEEP(20); // Atmel wants 20ms pause here
18
19 *pManufacturerID = ReadByte(serial_handle, base + 0);
20 *pDeviceID = ReadByte(serial_handle, base + 1);
21
22 WriteByte(serial_handle, base + 0, 0xF0); // reset flash (back to normal read mode)
23 SLEEP(20); // Atmel wants 20ms pause here
24
25 return 0;
26}
27
28
29// erase the sector which contains the given address
30int EraseSector(tUartHandle serial_handle, UINT32 address)
31{
32 UINT32 base = address & 0xFFF80000; // round down to 512k align
33
34 WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode
35 WriteByte(serial_handle, base + 0x2AAA, 0x55);
36 WriteByte(serial_handle, base + 0x5555, 0x80); // eraze command
37 WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode
38 WriteByte(serial_handle, base + 0x2AAA, 0x55);
39 WriteByte(serial_handle, address, 0x30); // eraze the sector
40 SLEEP(25); // sector eraze time: 25ms
41
42 return 0;
43}
44
45
46// erase the whole flash
47int EraseChip(tUartHandle serial_handle, UINT32 base)
48{
49 base &= 0xFFF80000; // round down to 512k align, to make shure
50
51 WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode
52 WriteByte(serial_handle, base + 0x2AAA, 0x55);
53 WriteByte(serial_handle, base + 0x5555, 0x80); // eraze command
54 WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode
55 WriteByte(serial_handle, base + 0x2AAA, 0x55);
56 WriteByte(serial_handle, base + 0x5555, 0x10); // chip eraze command
57 SLEEP(100); // chip eraze time: 100ms
58
59 return 0;
60}
61
62
63// program a bunch of bytes "by hand"
64int ProgramBytes(tUartHandle serial_handle, UINT32 address, UINT8* pData, UINT32 size)
65{
66 UINT32 base = address & 0xFFF80000; // round down to 512k align
67
68 while (size--)
69 {
70 WriteByte(serial_handle, base + 0x5555, 0xAA); // enter command mode
71 WriteByte(serial_handle, base + 0x2AAA, 0x55);
72 WriteByte(serial_handle, base + 0x5555, 0xA0); // byte program command
73 WriteByte(serial_handle, address++, *pData++);
74 // UART protocol is slow enough such that I don't have to wait 20us here
75 }
76 return 0;
77} \ No newline at end of file
diff --git a/flash/uart_boot/flash.h b/flash/uart_boot/flash.h
new file mode 100644
index 0000000000..70c620108d
--- /dev/null
+++ b/flash/uart_boot/flash.h
@@ -0,0 +1,9 @@
1#ifndef _FLASH_H
2#define _FLASH_H
3
4int ReadID(tUartHandle serial_handle, UINT32 base, UINT8* pManufacturerID, UINT8* pDeviceID);
5int EraseSector(tUartHandle serial_handle, UINT32 address);
6int EraseChip(tUartHandle serial_handle, UINT32 base);
7int ProgramBytes(tUartHandle serial_handle, UINT32 address, UINT8* pData, UINT32 size);
8
9#endif \ No newline at end of file
diff --git a/flash/uart_boot/minimon.h b/flash/uart_boot/minimon.h
new file mode 100644
index 0000000000..51406d4b12
--- /dev/null
+++ b/flash/uart_boot/minimon.h
@@ -0,0 +1,23 @@
1#ifndef _MINIMON_H
2#define _MINIMON_H
3
4
5// Commands
6// all multibyte values (address, halfwords) are passed as big endian
7// (most significant of the bytes first)
8
9// set the address (all read/write commands will auto-increment it)
10#define BAUDRATE 0x00 // followed by BRR value; response: command byte
11#define ADDRESS 0x01 // followed by 4 bytes address; response: command byte
12#define BYTE_READ 0x02 // response: 1 byte content
13#define BYTE_WRITE 0x03 // followed by 1 byte content; response: command byte
14#define BYTE_READ16 0x04 // response: 16 bytes content
15#define BYTE_WRITE16 0x05 // followed by 16 bytes; response: command byte
16#define BYTE_FLASH 0x06 // followed by 1 byte content; response: command byte
17#define BYTE_FLASH16 0x07 // followed by 16 bytes; response: command byte
18#define HALFWORD_READ 0x08 // response: 2 byte content
19#define HALFWORD_WRITE 0x09 // followed by 2 byte content; response: command byte
20#define EXECUTE 0x0A // response: command byte if call returns
21
22
23#endif // _MINIMON_H
diff --git a/flash/uart_boot/scalar_types.h b/flash/uart_boot/scalar_types.h
new file mode 100644
index 0000000000..88d82c4ec1
--- /dev/null
+++ b/flash/uart_boot/scalar_types.h
@@ -0,0 +1,44 @@
1// this is meant to resolve platform dependency
2
3#ifndef _SCALAR_TYPES_H
4#define _SCALAR_TYPES_H
5
6
7#ifdef WIN32
8#include <windows.h>
9#define SLEEP Sleep
10#define GET_LAST_ERR GetLastError
11#endif
12// ToDo: add stuff for Linux
13
14
15
16#ifndef UINT8
17#define UINT8 unsigned char
18#endif
19
20#ifndef UINT16
21#define UINT16 unsigned short
22#endif
23
24#ifndef UINT32
25#define UINT32 unsigned long
26#endif
27
28#ifndef bool
29#define bool int
30#endif
31
32#ifndef true
33#define true 1
34#endif
35
36#ifndef false
37#define false 0
38#endif
39
40
41
42
43
44#endif \ No newline at end of file
diff --git a/flash/uart_boot/uart.h b/flash/uart_boot/uart.h
new file mode 100644
index 0000000000..46b082c497
--- /dev/null
+++ b/flash/uart_boot/uart.h
@@ -0,0 +1,56 @@
1// A general definition for the required UART functionality.
2// This will be used to gain platform abstraction.
3
4#ifndef _UART_H
5#define _UART_H
6
7// data types
8
9typedef void* tUartHandle;
10#define INVALID_UART_HANDLE (tUartHandle)-1
11
12typedef enum
13{
14 eNOPARITY,
15 eODDPARITY,
16 eEVENPARITY,
17 eMARKPARITY,
18 eSPACEPARITY,
19} tParity;
20
21typedef enum
22{
23 eONESTOPBIT,
24 eONE5STOPBITS,
25 eTWOSTOPBITS,
26} tStopBits;
27
28
29// prototypes
30
31tUartHandle UartOpen( // returns NULL on error
32 char* szPortName); // COMx for windows
33
34bool UartConfig( // returns true on success, false on error
35 tUartHandle handle, // the handle returned from UartOpen()
36 long lBaudRate, // must be one of the "standard" baudrates
37 tParity nParity, // what kind of parity
38 tStopBits nStopBits, // how many stop bits
39 int nByteSize); // size of the "payload", can be 5 to 8
40
41long UartWrite( // returns how much data was actually transmitted
42 tUartHandle handle, // the handle returned from UartOpen()
43 unsigned char* pData, // pointer to the data to be transmitted
44 long lSize); // how many bytes
45
46long UartRead( // returns how much data was actually received
47 tUartHandle handle, // the handle returned from UartOpen()
48 unsigned char* pBuffer, // pointer to the destination
49 long lSize); // how many bytes to read (pBuffer must have enough room)
50
51
52void UartClose(tUartHandle handle);
53
54
55
56#endif // _UART_H \ No newline at end of file
diff --git a/flash/uart_boot/uart_boot.c b/flash/uart_boot/uart_boot.c
new file mode 100644
index 0000000000..8110e9b678
--- /dev/null
+++ b/flash/uart_boot/uart_boot.c
@@ -0,0 +1,337 @@
1// uart_boot.cpp : Defines the entry point for the console application.
2//
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include "scalar_types.h" // (U)INT8/16/32
8#include "Uart.h" // platform abstraction for UART
9#include "client.h" // client functions
10#include "flash.h" // flash high level functions
11
12// command line configuration: what shall we do?
13struct
14{
15 char* szPort; // COM port to use
16 bool bRecorder; // it's a recorder
17 bool bArchos; // use the Archos monitor to load, instead of UART boot
18 bool bSpindown; // spindown the harddisk
19 bool bReadID; // read manufacturer+device ID
20 char* szFlashfile; // file to be programmed
21 char* szDumpfile; // file to dump into
22 char* szExecfile; // file with the executable
23 bool bTest; // debug action
24 bool bBlink; // blink red LED
25 bool bNoDownload;
26} gCmd;
27
28
29int ProcessCmdLine(int argc, char* argv[])
30{
31 argc--; // exclude our name
32 argv++;
33
34 memset(&gCmd, 0, sizeof(gCmd));
35
36 if (argc == 0)
37 {
38 printf("Usage: uart_boot [-option {filename}]\n");
39 printf(" uses activated UART boot mod, box has to be fresh started\n");
40 printf("The order of the options does not matter, one letter is sufficient.\n");
41 printf("Possible options are (in the order of later processing):\n");
42 printf("-port <name of COM port to use>\n");
43 printf("-recorder (this is a recorder/FM, default is player if not specified)\n");
44 printf("-archos (use Archos bootloader, this one needs powerup while program waits)\n");
45 printf("-nodownload (no MiniMon download, it's already active)\n");
46 printf("-spindown (spindown the harddisk, else it stays on by default)\n");
47 printf("-id (read manufacturer and device ID of flash, no checks)\n");
48 printf("-flash <filename of binary to program into flash>\n");
49 printf("-dump <filename to write flash content to>\n");
50 printf("-exec <filename of executable for 0x09000000:0x09000200>\n");
51 printf("-test (some test action currently under development, don't use!)\n");
52 printf("-blink (blink red LED forever, meant as diagnostics)\n");
53 printf("\n");
54 printf("Examples:\n");
55 printf("uart_boot -r -p COM1 -s -f flashfile.bin -d dumpfile.bin\n");
56 printf(" recorder on COM1, spindown HD, program and dump (for e.g. offline verify)\n");
57 printf("uart_boot -r -p COM2 -e rockbox.bin\n");
58 printf(" recorder on COM2, load Rockbox from file and start it\n");
59 exit (0);
60 }
61
62
63 while (argc)
64 {
65 if (!strncmp("-port", *argv, 2))
66 {
67 gCmd.szPort = *++argv;
68 if (--argc <= 0 || **argv == '-')
69 {
70 printf("No argument given for option %s, aborting.\n", argv[-1]);
71 exit (-2);
72 }
73 }
74 else if (!strncmp("-recorder", *argv, 2))
75 {
76 gCmd.bRecorder = true;
77 }
78 else if (!strncmp("-archos", *argv, 2))
79 {
80 gCmd.bArchos = true;
81 }
82 else if (!strncmp("-nodownload", *argv, 2))
83 {
84 gCmd.bNoDownload = true;
85 }
86 else if (!strncmp("-spindown", *argv, 2))
87 {
88 gCmd.bSpindown = true;
89 }
90 else if (!strncmp("-id", *argv, 2))
91 {
92 gCmd.bReadID = true;
93 }
94 else if (!strncmp("-flash", *argv, 2))
95 {
96 gCmd.szFlashfile = *++argv;
97 if (--argc <= 0 || **argv == '-')
98 {
99 printf("No argument given for option %s, aborting.\n", argv[-1]);
100 exit (-2);
101 }
102 }
103 else if (!strncmp("-dump", *argv, 2))
104 {
105 gCmd.szDumpfile = *++argv;
106 if (--argc <= 0 || **argv == '-')
107 {
108 printf("No argument given for option %s, aborting.\n", argv[-1]);
109 exit (-3);
110 }
111 }
112 else if (!strncmp("-exec", *argv, 2))
113 {
114 gCmd.szExecfile = *++argv;
115 if (--argc <= 0 || **argv == '-')
116 {
117 printf("No argument given for option %s, aborting.\n", argv[-1]);
118 exit (-4);
119 }
120 }
121 else if (!strncmp("-test", *argv, 2))
122 {
123 gCmd.bTest = true;
124 }
125 else if (!strncmp("-blink", *argv, 2))
126 {
127 gCmd.bBlink = true;
128 }
129 else
130 {
131 printf("Unknown option %s, aborting. Use 'uart_boot' without options for help.\n", *argv);
132 exit(-1);
133 }
134
135 argv++;
136 argc--;
137 }
138
139 return 0;
140}
141
142
143int main(int argc, char* argv[])
144{
145 tUartHandle serial_handle;
146 UINT16 reg;
147 FILE* pFile;
148 size_t size;
149 UINT8 abFirmware[512*1024]; // blocksize
150 memset(abFirmware, 0xFF, sizeof(abFirmware));
151
152 ProcessCmdLine(argc, argv); // what to do
153
154 if (!gCmd.szPort)
155 {
156 printf("No serial port given, use 'uart_boot' without parameters for options.\n");
157 exit(-1);
158 }
159
160 serial_handle = UartOpen(gCmd.szPort); // opening serial port
161 if (serial_handle == NULL)
162 {
163 printf("Cannot open port %s\n", gCmd.szPort);
164 return -1;
165 }
166
167 if (gCmd.bNoDownload)
168 { // just set our speed
169 if (!UartConfig(serial_handle, gCmd.bRecorder ? 115200 : 14400, eNOPARITY, eONESTOPBIT, 8))
170 {
171 printf("Error setting up COM params\n");
172 exit(1);
173 }
174 }
175 else
176 { // download the monitor program
177 if (gCmd.bArchos)
178 {
179 printf("Waiting for box startup to download monitor...");
180 DownloadArchosMonitor(serial_handle, "minimon_v2.bin"); // load the monitor image
181 printf("\b\b\b done.\n");
182 }
183 else
184 {
185 printf("Downloading monitor...");
186 DownloadMonitor(serial_handle, gCmd.bRecorder, "minimon.bin"); // load the monitor image
187 // From now on, we can talk to the box.
188 printf("\b\b\b done.\n");
189
190 if (gCmd.bRecorder)
191 { // we can be faster
192 SetTargetBaudrate(serial_handle, 11059200, 115200); // set to 115200
193 }
194 }
195 }
196
197 // do the action
198
199 if (gCmd.bSpindown)
200 {
201 // spindown the disk (works only for master)
202 UINT32 ata; // address of ATA_ALT_STATUS
203 printf("Harddisk spindown...");
204 ata = (gCmd.bRecorder && (ReadHalfword(serial_handle, 0x020000FC) & 0x0100)) ? 0x06200206 : 0x06200306;
205 WriteHalfword(serial_handle, 0x05FFFFCA, 0xBF99); // PACR2 (was 0xFF99)
206 WriteHalfword(serial_handle, 0x05FFFFC4, 0x0280); // PAIOR (was 0x0000)
207 WriteHalfword(serial_handle, 0x05FFFFC0, 0xA27F); // PADR (was 0xA0FF)
208 while (ReadByte(serial_handle, ata) & 0x80); // ATA_ALT_STATUS & STATUS_BSY
209 WriteByte(serial_handle, 0x06100107, 0xE0); // ATA_COMMAND = CMD_STANDBY_IMMEDIATE;
210 //while (ReadByte(serial_handle, ata) & 0x80); // ATA_ALT_STATUS & STATUS_BSY
211 printf("\b\b\b done.\n");
212 }
213
214
215 if (gCmd.bReadID)
216 {
217 UINT8 bMan, bID;
218 ReadID(serial_handle, 0x02000000, &bMan, &bID);
219 printf("Manufacturer ID = 0x%02X, Device ID = 0x%02X\n", bMan, bID);
220 }
221
222
223 if (gCmd.szFlashfile)
224 {
225 // flash a firmware file
226 printf("Flashing file %s...", gCmd.szFlashfile);
227 pFile = fopen(gCmd.szFlashfile, "rb");
228 if (pFile == NULL)
229 {
230 printf("\nFlash file %s not found, exiting.\n", gCmd.szFlashfile);
231 return -2;
232 }
233 size = fread(abFirmware, 1, sizeof(abFirmware), pFile);
234 fclose (pFile);
235
236 EraseChip(serial_handle, 0x02000000);
237 FlashByteMultiple(serial_handle, 0x02000000, size, abFirmware);
238 printf("\b\b\b done.\n");
239 }
240
241
242 if (gCmd.szDumpfile)
243 {
244 // dump the flash content
245 printf("Writing flash dump into file %s...", gCmd.szDumpfile);
246 ReadByteMultiple(serial_handle, 0x02000000, sizeof(abFirmware), abFirmware);
247 pFile = fopen(gCmd.szDumpfile, "wb");
248 if (pFile == NULL)
249 {
250 printf("\nDump file %s cannot be opened, exiting.\n", gCmd.szDumpfile);
251 return -3;
252 }
253 fwrite(abFirmware, 1, sizeof(abFirmware), pFile);
254 fclose (pFile);
255 printf("\b\b\b done.\n");
256 }
257
258
259 if (gCmd.szExecfile)
260 {
261 UINT32 size;
262
263 printf("Downloading program...");
264
265 // init the DRAM controller like the flash boot does
266 reg = ReadHalfword(serial_handle, 0x05FFFFCA); // PACR2
267 reg &= 0xFFFB; // PA1 config: /RAS
268 reg |= 0x0008;
269 WriteHalfword(serial_handle, 0x05FFFFCA, reg); // PACR2
270 reg = 0xAFFF; // CS1, CS3 config: /CASH. /CASL
271 WriteHalfword(serial_handle, 0x05FFFFEE, reg); // CASCR
272 reg = ReadHalfword(serial_handle, 0x05FFFFA0); // BCR
273 reg |= 0x8000; // DRAM enable, default bus
274 WriteHalfword(serial_handle, 0x05FFFFA0, reg); // BCR
275 reg = ReadHalfword(serial_handle, 0x05FFFFA2); // WCR1
276 reg &= 0xFDFD; // 1-cycle CAS
277 WriteHalfword(serial_handle, 0x05FFFFA2, reg); // WCR1
278 reg = 0x0E00; // CAS 35%, multiplexed, 10 bit row addr.
279 WriteHalfword(serial_handle, 0x05FFFFA8, reg); // DCR
280 reg = 0x5AB0; // refresh, 4 cycle waitstate
281 WriteHalfword(serial_handle, 0x05FFFFAC, reg); // RCR
282 reg = 0x9605; // refresh constant
283 WriteHalfword(serial_handle, 0x05FFFFB2, reg); // RTCOR
284 reg = 0xA518; // phi/32
285 WriteHalfword(serial_handle, 0x05FFFFAE, reg); // RTCSR
286
287
288 // download Rockbox/gdb
289 pFile = fopen(gCmd.szExecfile, "rb");
290 if (pFile == NULL)
291 {
292 printf("\nExecutable file %s cannot be opened, exiting.\n", gCmd.szExecfile);
293 return -3;
294 }
295
296 size = fread(abFirmware, 1, sizeof(abFirmware), pFile);
297 WriteByteMultiple(serial_handle, 0x09000000, size, abFirmware);
298 fclose (pFile);
299 printf("\b\b\b done.\n");
300
301 // start rockbox/gdb
302 printf("Starting program...");
303 Execute(serial_handle, 0x09000200, false);
304 printf("\b\b\b done.\n");
305 }
306
307
308 if (gCmd.bTest)
309 {
310 // test code: query keypad
311 while (1)
312 {
313 WriteByte(serial_handle, 0x05FFFEE8, 0x24); // ADCSR
314 while (!(ReadByte(serial_handle, 0x05FFFEE8) & 0x80));
315 reg = ReadHalfword(serial_handle, 0x05FFFEE0); // ADDRA
316 printf("ADC(4): %d\n", reg>>6);
317 }
318 }
319
320
321 if (gCmd.bBlink)
322 {
323 // blinking LED
324 UINT8 byte;
325 printf("Flashing red LED forever... (stop with Ctrl-C)\n");
326 byte = ReadByte(serial_handle, 0x05FFFFC3);
327 while (1)
328 {
329 byte ^= 0x40;
330 WriteByte(serial_handle, 0x05FFFFC3, byte);
331 Sleep(200);
332 }
333 }
334
335 return 0;
336}
337
diff --git a/flash/uart_boot/uart_boot.dsp b/flash/uart_boot/uart_boot.dsp
new file mode 100644
index 0000000000..4d94c72530
--- /dev/null
+++ b/flash/uart_boot/uart_boot.dsp
@@ -0,0 +1,130 @@
1# Microsoft Developer Studio Project File - Name="uart_boot" - Package Owner=<4>
2# Microsoft Developer Studio Generated Build File, Format Version 6.00
3# ** DO NOT EDIT **
4
5# TARGTYPE "Win32 (x86) Console Application" 0x0103
6
7CFG=uart_boot - Win32 Debug
8!MESSAGE This is not a valid makefile. To build this project using NMAKE,
9!MESSAGE use the Export Makefile command and run
10!MESSAGE
11!MESSAGE NMAKE /f "uart_boot.mak".
12!MESSAGE
13!MESSAGE You can specify a configuration when running NMAKE
14!MESSAGE by defining the macro CFG on the command line. For example:
15!MESSAGE
16!MESSAGE NMAKE /f "uart_boot.mak" CFG="uart_boot - Win32 Debug"
17!MESSAGE
18!MESSAGE Possible choices for configuration are:
19!MESSAGE
20!MESSAGE "uart_boot - Win32 Release" (based on "Win32 (x86) Console Application")
21!MESSAGE "uart_boot - Win32 Debug" (based on "Win32 (x86) Console Application")
22!MESSAGE
23
24# Begin Project
25# PROP AllowPerConfigDependencies 0
26# PROP Scc_ProjName ""
27# PROP Scc_LocalPath ""
28CPP=cl.exe
29RSC=rc.exe
30
31!IF "$(CFG)" == "uart_boot - Win32 Release"
32
33# PROP BASE Use_MFC 0
34# PROP BASE Use_Debug_Libraries 0
35# PROP BASE Output_Dir "Release"
36# PROP BASE Intermediate_Dir "Release"
37# PROP BASE Target_Dir ""
38# PROP Use_MFC 0
39# PROP Use_Debug_Libraries 0
40# PROP Output_Dir "Release"
41# PROP Intermediate_Dir "Release"
42# PROP Target_Dir ""
43# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
44# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /c
45# SUBTRACT CPP /YX /Yc /Yu
46# ADD BASE RSC /l 0x407 /d "NDEBUG"
47# ADD RSC /l 0x407 /d "NDEBUG"
48BSC32=bscmake.exe
49# ADD BASE BSC32 /nologo
50# ADD BSC32 /nologo
51LINK32=link.exe
52# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
53# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
54
55!ELSEIF "$(CFG)" == "uart_boot - Win32 Debug"
56
57# PROP BASE Use_MFC 0
58# PROP BASE Use_Debug_Libraries 1
59# PROP BASE Output_Dir "Debug"
60# PROP BASE Intermediate_Dir "Debug"
61# PROP BASE Target_Dir ""
62# PROP Use_MFC 0
63# PROP Use_Debug_Libraries 1
64# PROP Output_Dir "Debug"
65# PROP Intermediate_Dir "Debug"
66# PROP Target_Dir ""
67# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /GZ /c
68# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c
69# SUBTRACT CPP /YX /Yc /Yu
70# ADD BASE RSC /l 0x407 /d "_DEBUG"
71# ADD RSC /l 0x407 /d "_DEBUG"
72BSC32=bscmake.exe
73# ADD BASE BSC32 /nologo
74# ADD BSC32 /nologo
75LINK32=link.exe
76# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
77# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
78
79!ENDIF
80
81# Begin Target
82
83# Name "uart_boot - Win32 Release"
84# Name "uart_boot - Win32 Debug"
85# Begin Group "Source Files"
86
87# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
88# Begin Source File
89
90SOURCE=.\client.c
91# End Source File
92# Begin Source File
93
94SOURCE=.\flash.c
95# End Source File
96# Begin Source File
97
98SOURCE=.\uart_boot.c
99# End Source File
100# Begin Source File
101
102SOURCE=.\uart_win.c
103# End Source File
104# End Group
105# Begin Group "Header Files"
106
107# PROP Default_Filter "h;hpp;hxx;hm;inl"
108# Begin Source File
109
110SOURCE=.\client.h
111# End Source File
112# Begin Source File
113
114SOURCE=.\flash.h
115# End Source File
116# Begin Source File
117
118SOURCE=.\minimon.h
119# End Source File
120# Begin Source File
121
122SOURCE=.\scalar_types.h
123# End Source File
124# Begin Source File
125
126SOURCE=.\uart.h
127# End Source File
128# End Group
129# End Target
130# End Project
diff --git a/flash/uart_boot/uart_win.c b/flash/uart_boot/uart_win.c
new file mode 100644
index 0000000000..243017ac88
--- /dev/null
+++ b/flash/uart_boot/uart_win.c
@@ -0,0 +1,138 @@
1// UART wrapper implementation for the Win32 platform
2// make a new version of this file for different systems, e.g. Linux
3
4#include <windows.h>
5#include "scalar_types.h" // (U)INT8/16/32
6#include "Uart.h"
7
8// COMx for windows, returns NULL on error
9tUartHandle UartOpen(char* szPortName)
10{
11 HANDLE serial_handle;
12 DCB dcb;
13 COMMTIMEOUTS cto = { 0, 0, 0, 0, 0 };
14
15 memset(&dcb,0,sizeof(dcb));
16
17 /* -------------------------------------------------------------------- */
18 // set DCB to configure the serial port
19 dcb.DCBlength = sizeof(dcb);
20
21 dcb.fOutxCtsFlow = 0;
22 dcb.fOutxDsrFlow = 0;
23 dcb.fDtrControl = DTR_CONTROL_ENABLE; // enable for power
24 dcb.fDsrSensitivity = 0;
25 dcb.fRtsControl = RTS_CONTROL_ENABLE; // enable for power
26 dcb.fOutX = 0;
27 dcb.fInX = 0;
28
29 /* ----------------- misc parameters ----- */
30 dcb.fErrorChar = 0;
31 dcb.fBinary = 1;
32 dcb.fNull = 0;
33 dcb.fAbortOnError = 0;
34 dcb.wReserved = 0;
35 dcb.XonLim = 2;
36 dcb.XoffLim = 4;
37 dcb.XonChar = 0x13;
38 dcb.XoffChar = 0x19;
39 dcb.EvtChar = 0;
40
41 /* ----------------- defaults ----- */
42 dcb.BaudRate = 4800;
43 dcb.Parity = NOPARITY;
44 dcb.fParity = 0;
45 dcb.StopBits = ONESTOPBIT;
46 dcb.ByteSize = 8;
47
48
49 /* -------------------------------------------------------------------- */
50 // opening serial port
51 serial_handle = CreateFile(szPortName, GENERIC_READ | GENERIC_WRITE,
52 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
53
54 if (serial_handle == INVALID_HANDLE_VALUE)
55 {
56 //printf("Cannot open port \n");
57 return NULL;
58 }
59
60 SetCommMask(serial_handle, 0);
61 SetCommTimeouts(serial_handle, &cto);
62
63 if(!SetCommState(serial_handle, &dcb))
64 {
65 //printf("Error setting up COM params\n");
66 CloseHandle(serial_handle);
67 return NULL;
68 }
69
70 return serial_handle;
71}
72
73// returns true on success, false on error
74bool UartConfig(tUartHandle handle, long lBaudRate, tParity nParity, tStopBits nStopBits, int nByteSize)
75{
76 DCB dcb;
77
78 if (!GetCommState (handle, &dcb))
79 {
80 return false;
81 }
82
83 dcb.BaudRate = lBaudRate;
84 dcb.Parity = nParity;
85 dcb.StopBits = nStopBits;
86 dcb.ByteSize = nByteSize;
87
88 if(!SetCommState(handle, &dcb))
89 {
90 //DWORD dwErr = GetLastError();
91 //printf("Error %d setting up COM params for baudrate byte\n", dwErr);
92 return false;
93 }
94
95 return true;
96}
97
98// returns how much data was actually transmitted
99long UartWrite(tUartHandle handle, unsigned char* pData, long lSize)
100{
101 BOOL success;
102 DWORD result_nbr;
103
104 success = WriteFile(handle, pData, lSize, &result_nbr, NULL);
105
106 if(!success)
107 {
108 return 0;
109 }
110
111 return result_nbr;
112}
113
114// returns how much data was actually received
115long UartRead(tUartHandle handle, unsigned char* pBuffer, long lSize)
116{
117 BOOL success;
118 DWORD read_nbr;
119
120 success = ReadFile(handle, pBuffer, lSize, &read_nbr, NULL);
121 if(!success)
122 {
123 return 0;
124 }
125
126 return read_nbr;
127}
128
129
130void UartClose(tUartHandle handle)
131{
132 if (handle != NULL)
133 {
134 CloseHandle(handle);
135 }
136
137 return;
138}