blob: 40c0dc5c54af793f330e81adb88b833f4460ed1d [file] [log] [blame]
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
Nicolas Pennequin357ffb32008-05-05 10:32:46 +000010 * Copyright (C) 2003 by Jörg Hohensohn
Jens Arnold4b3501f2004-12-03 21:43:21 +000011 *
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000012 * 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 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000017 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000021 *
22 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
23 * KIND, either express or implied.
24 *
25 ****************************************************************************/
26
27#include "sh7034.h"
28#include "bootloader.h"
29
Jens Arnoldca99f8e2008-10-12 22:10:22 +000030// prototypes
31static void PlatformInit(void);
Jens Arnoldca99f8e2008-10-12 22:10:22 +000032static void DecompressStart(tImage* pImage);
33#ifdef USE_ADC
34static int ReadADC(int channel);
35#endif
36static int ButtonPressed(void);
37static tImage* GetStartImage(int nPreferred);
38// test functions
39static void SetLed(BOOL bOn);
40static void UartInit(void);
41static UINT8 UartRead(void);
42static void UartWrite(UINT8 byte);
Jens Arnolde13e3182008-10-30 00:17:45 +000043static void MiniMon(void);
Jens Arnoldca99f8e2008-10-12 22:10:22 +000044
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000045
46#ifdef NO_ROM
Jens Arnold4b3501f2004-12-03 21:43:21 +000047/* start with the vector table */
48UINT32 vectors[] __attribute__ ((section (".vectors"))) =
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000049{
Jens Arnold4b3501f2004-12-03 21:43:21 +000050 (UINT32)_main, /* entry point, the copy routine */
51 (UINT32)(end_stack - 1), /* initial stack pointer */
52 FLASH_BASE + 0x200, /* source of image in flash */
53 (UINT32)total_size, /* size of image */
54 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,
55 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,
56 0x03020080 /* mask and version (just as a suggestion) */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000057};
58#else
Jens Arnold4b3501f2004-12-03 21:43:21 +000059/* our binary has to start with a vector to the entry point */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000060tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
61#endif
62
Jens Arnold4b3501f2004-12-03 21:43:21 +000063#ifdef NO_ROM /* some code which is only needed for the romless variant */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000064void _main(void)
65{
Jens Arnold4b3501f2004-12-03 21:43:21 +000066 UINT32* pSrc;
67 UINT32* pDest;
68 UINT32* pEnd;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000069/*
Jens Arnold4b3501f2004-12-03 21:43:21 +000070 asm volatile ("ldc %0,sr" : : "r"(0xF0)); // disable interrupts
71 asm volatile ("mov.l @%0,r15" : : "r"(4)); // load stack
72 asm volatile ("ldc %0,vbr" : : "r"(0)); // load vector base
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000073*/
Jens Arnold4b3501f2004-12-03 21:43:21 +000074 /* copy everything to IRAM and continue there */
75 pSrc = begin_iramcopy;
76 pDest = begin_text;
77 pEnd = pDest + (begin_stack - begin_text);
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000078
Jens Arnold4b3501f2004-12-03 21:43:21 +000079 do
80 {
81 *pDest++ = *pSrc++;
82 }
83 while (pDest < pEnd);
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000084
Jens Arnold4b3501f2004-12-03 21:43:21 +000085 main(); /* jump to the real main() */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000086}
87
88
Jens Arnoldca99f8e2008-10-12 22:10:22 +000089static void BootInit(void)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000090{
Jens Arnold4b3501f2004-12-03 21:43:21 +000091 /* inits from the boot ROM, whether they make sense or not */
92 PBDR &= 0xFFBF; /* LED off (0x131E) */
93 PBCR2 = 0; /* all GPIO */
94 PBIOR |= 0x0040; /* LED output */
95 PBIOR &= 0xFFF1; /* LCD lines input */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +000096
Jens Arnold4b3501f2004-12-03 21:43:21 +000097 /* init DRAM like the boot ROM does */
98 PACR2 &= 0xFFFB;
99 PACR2 |= 0x0008;
100 CASCR = 0xAF;
101 BCR |= 0x8000;
102 WCR1 &= 0xFDFD;
103 DCR = 0x0E00;
104 RCR = 0x5AB0;
105 RTCOR = 0x9605;
106 RTCSR = 0xA518;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000107}
Jens Arnold4b3501f2004-12-03 21:43:21 +0000108#endif /* #ifdef NO_ROM */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000109
110
111int main(void)
112{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000113 int nButton;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000114
Jens Arnold4b3501f2004-12-03 21:43:21 +0000115 PlatformInit(); /* model-specific inits */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000116
Jens Arnold4b3501f2004-12-03 21:43:21 +0000117 nButton = ButtonPressed();
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000118
Jens Arnold4b3501f2004-12-03 21:43:21 +0000119 if (nButton == 3)
120 { /* F3 means start monitor */
121 MiniMon();
122 }
123 else
124 {
125 tImage* pImage;
126 pImage = GetStartImage(nButton); /* which image */
127 DecompressStart(pImage); /* move into place and start it */
128 }
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000129
Jens Arnold4b3501f2004-12-03 21:43:21 +0000130 return 0; /* I guess we won't return ;-) */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000131}
132
133
Jens Arnold4b3501f2004-12-03 21:43:21 +0000134/* init code that is specific to certain platform */
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000135static void PlatformInit(void)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000136{
137#ifdef NO_ROM
Jens Arnold4b3501f2004-12-03 21:43:21 +0000138 BootInit(); /* if not started by boot ROM, we need to init what it did */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000139#endif
140
141#if defined PLATFORM_PLAYER
Jens Arnold78acda22004-12-16 22:24:57 +0000142 BRR1 = 0x19; /* 14400 Baud for monitor */
143 PBDRL |= 0x10; /* set PB4 to 1 to power the hd early (and prepare for
144 * probing in case the charger is connected) */
145 PBIORL |= 0x10; /* make PB4 an output */
146 PACR2 &= 0xFFFC; /* GPIO for PA0 (charger detection, input by default) */
147 if (!(PADRL & 0x01)) /* charger plugged? */
148 { /* we need to probe whether the box is able to control hd power */
149 int i;
150
151 PBIORL &= ~0x10; /* set PB4 to input */
152 /* wait whether it goes low, max. ~1 ms */
153 for (i = 0; (PBDRL & 0x10) && i < 1000; i++);
154
155 if (~(PBDRL & 0x10)) /* pulled low -> power controllable */
156 PBDRL &= 0x10; /* set PB4 low */
157 else /* still floating high -> not controllable */
158 PBDRL |= 0x10; /* set PB4 high */
159 PBIORL |= 0x10; /* ..and output again */
Jens Arnold4b3501f2004-12-03 21:43:21 +0000160 }
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000161#elif defined PLATFORM_RECORDER
Jens Arnold4b3501f2004-12-03 21:43:21 +0000162 BRR1 = 0x02; /* 115200 Baud for monitor */
163 if (ReadADC(7) > 0x100) /* charger plugged? */
164 { /* switch off the HD, else a flat battery may not start */
165 PACR2 &= 0xFBFF; /* GPIO for PA5 */
166 PAIOR |= 0x0020; /* make PA5 an output (low by default) */
167 }
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000168#elif defined PLATFORM_FM
Jens Arnold4b3501f2004-12-03 21:43:21 +0000169 BRR1 = 0x02; /* 115200 Baud for monitor */
170 PBDR |= 0x0020; /* set PB5 to keep power (fixes the ON-holding problem) */
171 PBIOR |= 0x0020; /* make PB5 an output */
172 if (ReadADC(0) < 0x1FF) /* charger plugged? */
173 { /* switch off the HD, else a flat battery may not start */
174 PACR2 &= 0xFBFF; /* GPIO for PA5 */
175 PAIOR |= 0x0020; /* make PA5 an output (low by default) */
176 }
Jörg Hohensohn4e423102004-09-29 21:54:29 +0000177#elif defined PLATFORM_ONDIO
Jens Arnold4b3501f2004-12-03 21:43:21 +0000178 BRR1 = 0x19; /* 14400 Baud for monitor */
179 PBDR |= 0x0020; /* set PB5 to keep power (fixes the ON-holding problem) */
180 PBIOR |= 0x0020; /* make PB5 an output */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000181#endif
182
Jens Arnold4b3501f2004-12-03 21:43:21 +0000183 /* platform-independent inits */
184 DCR |= 0x1000; /* enable burst mode on DRAM */
185 BCR |= 0x2000; /* activate Warp mode (simultaneous internal and external
186 * mem access) */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000187}
188
189
Jens Arnold4b3501f2004-12-03 21:43:21 +0000190/* move the image into place and start it */
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000191static void DecompressStart(tImage* pImage)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000192{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000193 UINT32* pSrc;
194 UINT32* pDest;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000195
Jens Arnold4b3501f2004-12-03 21:43:21 +0000196 pSrc = pImage->image;
197 pDest = pImage->pDestination;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000198
Jens Arnold4b3501f2004-12-03 21:43:21 +0000199 if (pSrc != pDest) /* if not linked to that flash address */
200 {
201 if (pImage->flags & IF_UCL_2E)
202 { /* UCL compressed, algorithm 2e */
203 UINT32 dst_len; /* dummy */
204 ucl_nrv2e_decompress_8((UINT8*)pSrc, (UINT8*)pDest, &dst_len);
205 }
206 else
207 { /* uncompressed, copy it */
208 UINT32 size = pImage->size;
209 UINT32* pEnd;
210 size = (size + 3) / 4; /* round up to 32bit-words */
211 pEnd = pDest + size;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000212
Jens Arnold4b3501f2004-12-03 21:43:21 +0000213 do
214 {
215 *pDest++ = *pSrc++;
216 }
217 while (pDest < pEnd);
218 }
219 }
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000220
Jens Arnold4b3501f2004-12-03 21:43:21 +0000221 pImage->pExecute();
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000222}
223
Jens Arnoldb8b94f12004-11-19 23:49:21 +0000224#ifdef USE_ADC
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000225static int ReadADC(int channel)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000226{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000227 /* after channel 3, the ports wrap and get re-used */
228 volatile UINT16* pResult = (UINT16*)(ADDRAH_ADDR + 2 * (channel & 0x03));
229 int timeout = 266; /* conversion takes 266 clock cycles */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000230
Jens Arnold4b3501f2004-12-03 21:43:21 +0000231 ADCSR = 0x20 | channel; /* start single conversion */
232 while (((ADCSR & 0x80) == 0) && (--timeout)); /* 6 instructions per round*/
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000233
Jens Arnold4b3501f2004-12-03 21:43:21 +0000234 return (timeout == 0) ? -1 : *pResult>>6;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000235}
Jens Arnoldb8b94f12004-11-19 23:49:21 +0000236#endif
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000237
238
Jens Arnold4b3501f2004-12-03 21:43:21 +0000239/* This function is platform-dependent,
240 * until I figure out how to distinguish at runtime. */
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000241static int ButtonPressed(void) /* return 1,2,3 for F1,F2,F3, 0 if none pressed */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000242{
Jens Arnoldb8b94f12004-11-19 23:49:21 +0000243#ifdef USE_ADC
Jens Arnold4b3501f2004-12-03 21:43:21 +0000244 int value = ReadADC(CHANNEL);
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000245
Jens Arnold4b3501f2004-12-03 21:43:21 +0000246 if (value >= F1_LOWER && value <= F1_UPPER) /* in range */
247 return 1;
248 else if (value >= F2_LOWER && value <= F2_UPPER) /* in range */
249 return 2;
250 else if (value >= F3_LOWER && value <= F3_UPPER) /* in range */
251 return 3;
Jens Arnoldb8b94f12004-11-19 23:49:21 +0000252#else
253 int value = PCDR;
Jens Arnold4b3501f2004-12-03 21:43:21 +0000254
Jens Arnoldb8b94f12004-11-19 23:49:21 +0000255 if (!(value & F1_MASK))
256 return 1;
257 else if (!(value & F2_MASK))
258 return 2;
259 else if (!(value & F3_MASK))
260 return 3;
261#endif
Jens Arnold4b3501f2004-12-03 21:43:21 +0000262
263 return 0;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000264}
265
266
Jens Arnold4b3501f2004-12-03 21:43:21 +0000267/* Determine the image to be started */
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000268static tImage* GetStartImage(int nPreferred)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000269{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000270 tImage* pImage1;
271 tImage* pImage2 = NULL; /* default to not present */
272 UINT32 pos;
273 UINT32* pFlash = (UINT32*)FLASH_BASE;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000274
Jens Arnold4b3501f2004-12-03 21:43:21 +0000275 /* determine the first image position */
276 pos = pFlash[2] + pFlash[3]; /* position + size of the bootloader
277 * = after it */
278 pos = (pos + 3) & ~3; /* be sure it's 32 bit aligned */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000279
Jens Arnold4b3501f2004-12-03 21:43:21 +0000280 pImage1 = (tImage*)pos;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000281
Jens Arnold4b3501f2004-12-03 21:43:21 +0000282 if (pImage1->size != 0)
283 { /* check for second image */
284 pos = (UINT32)(&pImage1->image) + pImage1->size;
285 pImage2 = (tImage*)pos;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000286
Jens Arnold4b3501f2004-12-03 21:43:21 +0000287 /* does it make sense? (not in FF or 00 erazed space) */
288 if (pImage2->pDestination == (void*)0xFFFFFFFF
289 || pImage2->size == 0xFFFFFFFF
290 || pImage2->pExecute == (void*)0xFFFFFFFF
291 || pImage2->flags == 0xFFFFFFFF
292 || pImage2->pDestination == NULL)
293 /* size, execute and flags can legally be 0 */
294 {
295 pImage2 = NULL; /* invalidate */
296 }
297 }
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000298
Jens Arnold4b3501f2004-12-03 21:43:21 +0000299 if (pImage2 == NULL || nPreferred == 1)
300 { /* no second image or overridden: return the first */
301 return pImage1;
302 }
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000303
Jens Arnold4b3501f2004-12-03 21:43:21 +0000304 return pImage2; /* return second image */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000305}
306
Jens Arnold4b3501f2004-12-03 21:43:21 +0000307/* diagnostic functions */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000308
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000309static void SetLed(BOOL bOn)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000310{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000311 if (bOn)
312 PBDR |= 0x0040;
313 else
314 PBDR &= ~0x0040;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000315}
316
317
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000318static void UartInit(void)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000319{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000320 PBIOR &= 0xFBFF; /* input: RXD1 remote pin */
321 PBCR1 |= 0x00A0; /* set PB11+PB10 to UART */
322 PBCR1 &= 0xFFAF; /* clear bits 6, 4 -> UART */
323 SMR1 = 0x00; /* async format 8N1, baud generator input is CPU clock */
324 SCR1 = 0x30; /* transmit+receive enable */
325 PBCR1 &= 0x00FF; /* set bit 12...15 as GPIO */
326 SSR1 &= 0xBF; /* clear bit 6 (RDRF, receive data register full) */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000327}
328
329
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000330static UINT8 UartRead(void)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000331{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000332 UINT8 byte;
333 while (!(SSR1 & SCI_RDRF)); /* wait for char to be available */
334 byte = RDR1;
335 SSR1 &= ~SCI_RDRF;
336 return byte;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000337}
338
339
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000340static void UartWrite(UINT8 byte)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000341{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000342 while (!(SSR1 & SCI_TDRE)); /* wait for transmit buffer empty */
343 TDR1 = byte;
344 SSR1 &= ~SCI_TDRE;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000345}
346
347
Jens Arnold4b3501f2004-12-03 21:43:21 +0000348/* include the mini monitor as a rescue feature, started with F3 */
Jens Arnoldca99f8e2008-10-12 22:10:22 +0000349static void MiniMon(void)
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000350{
Jens Arnold4b3501f2004-12-03 21:43:21 +0000351 UINT8 cmd;
352 UINT32 addr;
353 UINT32 size;
354 UINT32 content;
355 volatile UINT8* paddr = NULL;
356 volatile UINT8* pflash = NULL; /* flash base address */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000357
Jens Arnold4b3501f2004-12-03 21:43:21 +0000358 UartInit();
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000359
Jens Arnold4b3501f2004-12-03 21:43:21 +0000360 while (1)
361 {
362 cmd = UartRead();
363 switch (cmd)
364 {
365 case BAUDRATE:
366 content = UartRead();
367 UartWrite(cmd); /* acknowledge by returning the command value */
368 while (!(SSR1 & SCI_TEND)); /* wait for empty shift register,
369 * before changing baudrate */
370 BRR1 = content;
371 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000372
Jens Arnold4b3501f2004-12-03 21:43:21 +0000373 case ADDRESS:
374 addr = (UartRead() << 24) | (UartRead() << 16)
375 | (UartRead() << 8) | UartRead();
376 paddr = (UINT8*)addr;
377 pflash = (UINT8*)(addr & 0xFFF80000); /* round down to 512k align*/
378 UartWrite(cmd); /* acknowledge by returning the command value */
379 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000380
Jens Arnold4b3501f2004-12-03 21:43:21 +0000381 case BYTE_READ:
382 content = *paddr++;
383 UartWrite(content); /* the content is the ack */
384 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000385
Jens Arnold4b3501f2004-12-03 21:43:21 +0000386 case BYTE_WRITE:
387 content = UartRead();
388 *paddr++ = content;
389 UartWrite(cmd); /* acknowledge by returning the command value */
390 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000391
Jens Arnold4b3501f2004-12-03 21:43:21 +0000392 case BYTE_READ16:
393 size = 16;
394 while (size--)
395 {
396 content = *paddr++;
397 UartWrite(content); /* the content is the ack */
398 }
399 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000400
Jens Arnold4b3501f2004-12-03 21:43:21 +0000401 case BYTE_WRITE16:
402 size = 16;
403 while (size--)
404 {
405 content = UartRead();
406 *paddr++ = content;
407 }
408 UartWrite(cmd); /* acknowledge by returning the command value */
409 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000410
Jens Arnold4b3501f2004-12-03 21:43:21 +0000411 case BYTE_FLASH:
412 content = UartRead();
413 pflash[0x5555] = 0xAA; /* set flash to command mode */
414 pflash[0x2AAA] = 0x55;
415 pflash[0x5555] = 0xA0; /* byte program command */
416 *paddr++ = content;
417 UartWrite(cmd); /* acknowledge by returning the command value */
418 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000419
Jens Arnold4b3501f2004-12-03 21:43:21 +0000420 case BYTE_FLASH16:
421 size = 16;
422 while (size--)
423 {
424 content = UartRead();
425 pflash[0x5555] = 0xAA; /* set flash to command mode */
426 pflash[0x2AAA] = 0x55;
427 pflash[0x5555] = 0xA0; /* byte program command */
428 *paddr++ = content;
429 }
430 UartWrite(cmd); /* acknowledge by returning the command value */
431 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000432
Jens Arnold4b3501f2004-12-03 21:43:21 +0000433 case HALFWORD_READ:
434 content = *(UINT16*)paddr;
435 paddr += 2;
436 UartWrite(content >> 8); /* highbyte */
437 UartWrite(content & 0xFF); /* lowbyte */
438 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000439
Jens Arnold4b3501f2004-12-03 21:43:21 +0000440 case HALFWORD_WRITE:
441 content = UartRead() << 8 | UartRead();
442 *(UINT16*)paddr = content;
443 paddr += 2;
444 UartWrite(cmd); /* acknowledge by returning the command value */
445 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000446
Jens Arnold4b3501f2004-12-03 21:43:21 +0000447 case EXECUTE:
448 {
449 tpFunc pFunc = (tpFunc)paddr;
450 pFunc();
451 UartWrite(cmd); /* acknowledge by returning the command value*/
452 }
453 break;
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000454
Jens Arnold4b3501f2004-12-03 21:43:21 +0000455 case VERSION:
456 UartWrite(1); /* return our version number */
457 break;
458
459 default:
460 {
461 SetLed(TRUE);
462 UartWrite(~cmd); /* error acknowledge */
463 }
464
465 } /* case */
466 } /* while (1) */
Jörg Hohensohn6a4e4c82003-11-30 11:37:43 +0000467}