summaryrefslogtreecommitdiff
path: root/flash/bootloader/bootloader.c
diff options
context:
space:
mode:
Diffstat (limited to 'flash/bootloader/bootloader.c')
-rw-r--r--flash/bootloader/bootloader.c744
1 files changed, 375 insertions, 369 deletions
diff --git a/flash/bootloader/bootloader.c b/flash/bootloader/bootloader.c
index e5bab34abd..370ac5bee5 100644
--- a/flash/bootloader/bootloader.c
+++ b/flash/bootloader/bootloader.c
@@ -7,8 +7,8 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2003 by Jörg Hohensohn 10 * Copyright (C) 2003 by Jörg Hohensohn
11 * 11 *
12 * Second-level bootloader, with dual-boot feature by holding F1/Menu 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. 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. 14 * It's task is to copy Rockbox from Flash to DRAM.
@@ -27,266 +27,268 @@
27 27
28 28
29#ifdef NO_ROM 29#ifdef NO_ROM
30// start with the vector table 30/* start with the vector table */
31UINT32 vectors[] __attribute__ ((section (".vectors"))) = 31UINT32 vectors[] __attribute__ ((section (".vectors"))) =
32{ 32{
33 (UINT32)_main, // entry point, the copy routine 33 (UINT32)_main, /* entry point, the copy routine */
34 (UINT32)(end_stack - 1), // initial stack pointer 34 (UINT32)(end_stack - 1), /* initial stack pointer */
35 FLASH_BASE + 0x200, // source of image in flash 35 FLASH_BASE + 0x200, /* source of image in flash */
36 (UINT32)total_size, // size of image 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, 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,
38 0x03020080 // mask and version (just as a suggestion) 38 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,
39 0x03020080 /* mask and version (just as a suggestion) */
39}; 40};
40#else 41#else
41// our binary has to start with a vector to the entry point 42/* our binary has to start with a vector to the entry point */
42tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main}; 43tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main};
43#endif 44#endif
44 45
45#ifdef NO_ROM // some code which is only needed for the romless variant 46#ifdef NO_ROM /* some code which is only needed for the romless variant */
46void _main(void) 47void _main(void)
47{ 48{
48 UINT32* pSrc; 49 UINT32* pSrc;
49 UINT32* pDest; 50 UINT32* pDest;
50 UINT32* pEnd; 51 UINT32* pEnd;
51/* 52/*
52 asm volatile ("ldc %0,sr" : : "r"(0xF0)); // disable interrupts 53 asm volatile ("ldc %0,sr" : : "r"(0xF0)); // disable interrupts
53 asm volatile ("mov.l @%0,r15" : : "r"(4)); // load stack 54 asm volatile ("mov.l @%0,r15" : : "r"(4)); // load stack
54 asm volatile ("ldc %0,vbr" : : "r"(0)); // load vector base 55 asm volatile ("ldc %0,vbr" : : "r"(0)); // load vector base
55*/ 56*/
56 // copy everything to IRAM and continue there 57 /* copy everything to IRAM and continue there */
57 pSrc = begin_iramcopy; 58 pSrc = begin_iramcopy;
58 pDest = begin_text; 59 pDest = begin_text;
59 pEnd = pDest + (begin_stack - begin_text); 60 pEnd = pDest + (begin_stack - begin_text);
60 61
61 do 62 do
62 { 63 {
63 *pDest++ = *pSrc++; 64 *pDest++ = *pSrc++;
64 } 65 }
65 while (pDest < pEnd); 66 while (pDest < pEnd);
66 67
67 main(); // jump to the real main() 68 main(); /* jump to the real main() */
68} 69}
69 70
70 71
71void BootInit(void) 72void BootInit(void)
72{ 73{
73 // inits from the boot ROM, whether they make sense or not 74 /* inits from the boot ROM, whether they make sense or not */
74 PBDR &= 0xFFBF; // LED off (0x131E) 75 PBDR &= 0xFFBF; /* LED off (0x131E) */
75 PBCR2 = 0; // all GPIO 76 PBCR2 = 0; /* all GPIO */
76 PBIOR |= 0x40; // LED output 77 PBIOR |= 0x0040; /* LED output */
77 PBIOR &= 0xFFF1; // LCD lines input 78 PBIOR &= 0xFFF1; /* LCD lines input */
78 79
79 // init DRAM like the boot ROM does 80 /* init DRAM like the boot ROM does */
80 PACR2 &= 0xFFFB; 81 PACR2 &= 0xFFFB;
81 PACR2 |= 0x0008; 82 PACR2 |= 0x0008;
82 CASCR = 0xAF; 83 CASCR = 0xAF;
83 BCR |= 0x8000; 84 BCR |= 0x8000;
84 WCR1 &= 0xFDFD; 85 WCR1 &= 0xFDFD;
85 DCR = 0x0E00; 86 DCR = 0x0E00;
86 RCR = 0x5AB0; 87 RCR = 0x5AB0;
87 RTCOR = 0x9605; 88 RTCOR = 0x9605;
88 RTCSR = 0xA518; 89 RTCSR = 0xA518;
89} 90}
90#endif // #ifdef NO_ROM 91#endif /* #ifdef NO_ROM */
91 92
92 93
93int main(void) 94int main(void)
94{ 95{
95 int nButton; 96 int nButton;
96 97
97 PlatformInit(); // model-specific inits 98 PlatformInit(); /* model-specific inits */
98 99
99 nButton = ButtonPressed(); 100 nButton = ButtonPressed();
100 101
101 if (nButton == 3) 102 if (nButton == 3)
102 { // F3 means start monitor 103 { /* F3 means start monitor */
103 MiniMon(); 104 MiniMon();
104 } 105 }
105 else 106 else
106 { 107 {
107 tImage* pImage; 108 tImage* pImage;
108 pImage = GetStartImage(nButton); // which image 109 pImage = GetStartImage(nButton); /* which image */
109 DecompressStart(pImage); // move into place and start it 110 DecompressStart(pImage); /* move into place and start it */
110 } 111 }
111 112
112 return 0; // I guess we won't return ;-) 113 return 0; /* I guess we won't return ;-) */
113} 114}
114 115
115 116
116// init code that is specific to certain platform 117/* init code that is specific to certain platform */
117void PlatformInit(void) 118void PlatformInit(void)
118{ 119{
119#ifdef NO_ROM 120#ifdef NO_ROM
120 BootInit(); // if not started by boot ROM, we need to init what it did 121 BootInit(); /* if not started by boot ROM, we need to init what it did */
121#endif 122#endif
122 123
123#if defined PLATFORM_PLAYER 124#if defined PLATFORM_PLAYER
124 BRR1 = 0x0019; // 14400 Baud for monitor 125 BRR1 = 0x19; /* 14400 Baud for monitor */
125 PACR2 &= 0xFFFC; // GPIO for PA0 (charger detection, input by default) 126 PACR2 &= 0xFFFC; /* GPIO for PA0 (charger detection, input by default) */
126 if (FW_VERSION > 451 && (PADRL & 0x01)) 127 if (FW_VERSION > 451 && (PADRL & 0x01))
127 { // "new" Player and charger not plugged? 128 { /* "new" Player and charger not plugged? */
128 PBDR |= 0x10; // set PB4 to 1 to power-up the harddisk early 129 PBDR |= 0x0010; /* set PB4 to 1 to power-up the harddisk early */
129 PBIOR |= 0x10; // make PB4 an output 130 PBIOR |= 0x0010; /* make PB4 an output */
130 } 131 }
131#elif defined PLATFORM_RECORDER 132#elif defined PLATFORM_RECORDER
132 BRR1 = 0x0002; // 115200 Baud for monitor 133 BRR1 = 0x02; /* 115200 Baud for monitor */
133 if (ReadADC(7) > 0x100) // charger plugged? 134 if (ReadADC(7) > 0x100) /* charger plugged? */
134 { // switch off the HD, else a flat battery may not start 135 { /* switch off the HD, else a flat battery may not start */
135 PACR2 &= 0xFBFF; // GPIO for PA5 136 PACR2 &= 0xFBFF; /* GPIO for PA5 */
136 PAIOR |= 0x20; // make PA5 an output (low by default) 137 PAIOR |= 0x0020; /* make PA5 an output (low by default) */
137 } 138 }
138#elif defined PLATFORM_FM 139#elif defined PLATFORM_FM
139 BRR1 = 0x0002; // 115200 Baud for monitor 140 BRR1 = 0x02; /* 115200 Baud for monitor */
140 PBDR |= 0x20; // set PB5 to keep power (fixes the ON-holding problem) 141 PBDR |= 0x0020; /* set PB5 to keep power (fixes the ON-holding problem) */
141 PBIOR |= 0x20; // make PB5 an output 142 PBIOR |= 0x0020; /* make PB5 an output */
142 if (ReadADC(0) < 0x1FF) // charger plugged? 143 if (ReadADC(0) < 0x1FF) /* charger plugged? */
143 { // switch off the HD, else a flat battery may not start 144 { /* switch off the HD, else a flat battery may not start */
144 PACR2 &= 0xFBFF; // GPIO for PA5 145 PACR2 &= 0xFBFF; /* GPIO for PA5 */
145 PAIOR |= 0x20; // make PA5 an output (low by default) 146 PAIOR |= 0x0020; /* make PA5 an output (low by default) */
146 } 147 }
147#elif defined PLATFORM_ONDIO 148#elif defined PLATFORM_ONDIO
148 BRR1 = 0x0019; // 14400 Baud for monitor 149 BRR1 = 0x19; /* 14400 Baud for monitor */
149 PBDR |= 0x20; // set PB5 to keep power (fixes the ON-holding problem) 150 PBDR |= 0x0020; /* set PB5 to keep power (fixes the ON-holding problem) */
150 PBIOR |= 0x20; // make PB5 an output 151 PBIOR |= 0x0020; /* make PB5 an output */
151#endif 152#endif
152 153
153 // platform-independent inits 154 /* platform-independent inits */
154 DCR |= 0x1000; // enable burst mode on DRAM 155 DCR |= 0x1000; /* enable burst mode on DRAM */
155 BCR |= 0x2000; // activate Warp mode (simultaneous internal and external mem access) 156 BCR |= 0x2000; /* activate Warp mode (simultaneous internal and external
157 * mem access) */
156} 158}
157 159
158 160
159// Thinned out version of the UCL 2e decompression sourcecode 161/* Thinned out version of the UCL 2e decompression sourcecode
160// Original (C) Markus F.X.J Oberhumer under GNU GPL license 162 * Original (C) Markus F.X.J Oberhumer under GNU GPL license */
161#define GETBIT(bb, src, ilen) \ 163#define GETBIT(bb, src, ilen) \
162 (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1) 164 (((bb = bb & 0x7f ? bb*2 : ((unsigned)src[ilen++]*2+1)) >> 8) & 1)
163 165
164int ucl_nrv2e_decompress_8( 166int ucl_nrv2e_decompress_8(
165 const UINT8 *src, UINT8 *dst, UINT32* dst_len) 167 const UINT8 *src, UINT8 *dst, UINT32* dst_len)
166{ 168{
167 UINT32 bb = 0; 169 UINT32 bb = 0;
168 unsigned ilen = 0, olen = 0, last_m_off = 1; 170 unsigned ilen = 0, olen = 0, last_m_off = 1;
169 171
170 for (;;) 172 for (;;)
171 { 173 {
172 unsigned m_off, m_len; 174 unsigned m_off, m_len;
173 175
174 while (GETBIT(bb,src,ilen)) 176 while (GETBIT(bb,src,ilen))
175 { 177 {
176 dst[olen++] = src[ilen++]; 178 dst[olen++] = src[ilen++];
177 } 179 }
178 m_off = 1; 180 m_off = 1;
179 for (;;) 181 for (;;)
180 { 182 {
181 m_off = m_off*2 + GETBIT(bb,src,ilen); 183 m_off = m_off*2 + GETBIT(bb,src,ilen);
182 if (GETBIT(bb,src,ilen)) break; 184 if (GETBIT(bb,src,ilen)) break;
183 m_off = (m_off-1)*2 + GETBIT(bb,src,ilen); 185 m_off = (m_off-1)*2 + GETBIT(bb,src,ilen);
184 } 186 }
185 if (m_off == 2) 187 if (m_off == 2)
186 { 188 {
187 m_off = last_m_off; 189 m_off = last_m_off;
188 m_len = GETBIT(bb,src,ilen); 190 m_len = GETBIT(bb,src,ilen);
189 } 191 }
190 else 192 else
191 { 193 {
192 m_off = (m_off-3)*256 + src[ilen++]; 194 m_off = (m_off-3)*256 + src[ilen++];
193 if (m_off == 0xffffffff) 195 if (m_off == 0xffffffff)
194 break; 196 break;
195 m_len = (m_off ^ 0xffffffff) & 1; 197 m_len = (m_off ^ 0xffffffff) & 1;
196 m_off >>= 1; 198 m_off >>= 1;
197 last_m_off = ++m_off; 199 last_m_off = ++m_off;
198 } 200 }
199 if (m_len) 201 if (m_len)
200 m_len = 1 + GETBIT(bb,src,ilen); 202 m_len = 1 + GETBIT(bb,src,ilen);
201 else if (GETBIT(bb,src,ilen)) 203 else if (GETBIT(bb,src,ilen))
202 m_len = 3 + GETBIT(bb,src,ilen); 204 m_len = 3 + GETBIT(bb,src,ilen);
203 else 205 else
204 { 206 {
205 m_len++; 207 m_len++;
206 do { 208 do {
207 m_len = m_len*2 + GETBIT(bb,src,ilen); 209 m_len = m_len*2 + GETBIT(bb,src,ilen);
208 } while (!GETBIT(bb,src,ilen)); 210 } while (!GETBIT(bb,src,ilen));
209 m_len += 3; 211 m_len += 3;
210 } 212 }
211 m_len += (m_off > 0x500); 213 m_len += (m_off > 0x500);
212 { 214 {
213 const UINT8 *m_pos; 215 const UINT8 *m_pos;
214 m_pos = dst + olen - m_off; 216 m_pos = dst + olen - m_off;
215 dst[olen++] = *m_pos++; 217 dst[olen++] = *m_pos++;
216 do dst[olen++] = *m_pos++; while (--m_len > 0); 218 do dst[olen++] = *m_pos++; while (--m_len > 0);
217 } 219 }
218 } 220 }
219 *dst_len = olen; 221 *dst_len = olen;
220 222
221 return ilen; 223 return ilen;
222} 224}
223 225
224 226
225// move the image into place and start it 227/* move the image into place and start it */
226void DecompressStart(tImage* pImage) 228void DecompressStart(tImage* pImage)
227{ 229{
228 UINT32* pSrc; 230 UINT32* pSrc;
229 UINT32* pDest; 231 UINT32* pDest;
230 232
231 pSrc = pImage->image; 233 pSrc = pImage->image;
232 pDest = pImage->pDestination; 234 pDest = pImage->pDestination;
233 235
234 if (pSrc != pDest) // if not linked to that flash address 236 if (pSrc != pDest) /* if not linked to that flash address */
235 { 237 {
236 if (pImage->flags & IF_UCL_2E) 238 if (pImage->flags & IF_UCL_2E)
237 { // UCL compressed, algorithm 2e 239 { /* UCL compressed, algorithm 2e */
238 UINT32 dst_len; // dummy 240 UINT32 dst_len; /* dummy */
239 ucl_nrv2e_decompress_8((UINT8*)pSrc, (UINT8*)pDest, &dst_len); 241 ucl_nrv2e_decompress_8((UINT8*)pSrc, (UINT8*)pDest, &dst_len);
240 } 242 }
241 else 243 else
242 { // uncompressed, copy it 244 { /* uncompressed, copy it */
243 UINT32 size = pImage->size; 245 UINT32 size = pImage->size;
244 UINT32* pEnd; 246 UINT32* pEnd;
245 size = (size + 3) / 4; // round up to 32bit-words 247 size = (size + 3) / 4; /* round up to 32bit-words */
246 pEnd = pDest + size; 248 pEnd = pDest + size;
247 249
248 do 250 do
249 { 251 {
250 *pDest++ = *pSrc++; 252 *pDest++ = *pSrc++;
251 } 253 }
252 while (pDest < pEnd); 254 while (pDest < pEnd);
253 } 255 }
254 } 256 }
255 257
256 pImage->pExecute(); 258 pImage->pExecute();
257} 259}
258 260
259#ifdef USE_ADC 261#ifdef USE_ADC
260int ReadADC(int channel) 262int ReadADC(int channel)
261{ 263{
262 // after channel 3, the ports wrap and get re-used 264 /* after channel 3, the ports wrap and get re-used */
263 volatile UINT16* pResult = (UINT16*)(ADDRAH_ADDR + 2 * (channel & 0x03)); 265 volatile UINT16* pResult = (UINT16*)(ADDRAH_ADDR + 2 * (channel & 0x03));
264 int timeout = 266; // conversion takes 266 clock cycles 266 int timeout = 266; /* conversion takes 266 clock cycles */
265 267
266 ADCSR = 0x20 | channel; // start single conversion 268 ADCSR = 0x20 | channel; /* start single conversion */
267 while (((ADCSR & 0x80) == 0) && (--timeout)); // 6 instructions per round 269 while (((ADCSR & 0x80) == 0) && (--timeout)); /* 6 instructions per round*/
268 270
269 return (timeout == 0) ? -1 : *pResult>>6; 271 return (timeout == 0) ? -1 : *pResult>>6;
270} 272}
271#endif 273#endif
272 274
273 275
274// This function is platform-dependent, 276/* This function is platform-dependent,
275// until I figure out how to distinguish at runtime. 277 * until I figure out how to distinguish at runtime. */
276int ButtonPressed(void) // return 1,2,3 for F1,F2,F3, 0 if none pressed 278int ButtonPressed(void) /* return 1,2,3 for F1,F2,F3, 0 if none pressed */
277{ 279{
278#ifdef USE_ADC 280#ifdef USE_ADC
279 int value = ReadADC(CHANNEL); 281 int value = ReadADC(CHANNEL);
280 282
281 if (value >= F1_LOWER && value <= F1_UPPER) // in range 283 if (value >= F1_LOWER && value <= F1_UPPER) /* in range */
282 return 1; 284 return 1;
283 else if (value >= F2_LOWER && value <= F2_UPPER) // in range 285 else if (value >= F2_LOWER && value <= F2_UPPER) /* in range */
284 return 2; 286 return 2;
285 else if (value >= F3_LOWER && value <= F3_UPPER) // in range 287 else if (value >= F3_LOWER && value <= F3_UPPER) /* in range */
286 return 3; 288 return 3;
287#else 289#else
288 int value = PCDR; 290 int value = PCDR;
289 291
290 if (!(value & F1_MASK)) 292 if (!(value & F1_MASK))
291 return 1; 293 return 1;
292 else if (!(value & F2_MASK)) 294 else if (!(value & F2_MASK))
@@ -294,205 +296,209 @@ int ButtonPressed(void) // return 1,2,3 for F1,F2,F3, 0 if none pressed
294 else if (!(value & F3_MASK)) 296 else if (!(value & F3_MASK))
295 return 3; 297 return 3;
296#endif 298#endif
297 299
298 return 0; 300 return 0;
299} 301}
300 302
301 303
302// Determine the image to be started 304/* Determine the image to be started */
303tImage* GetStartImage(int nPreferred) 305tImage* GetStartImage(int nPreferred)
304{ 306{
305 tImage* pImage1; 307 tImage* pImage1;
306 tImage* pImage2 = NULL; // default to not present 308 tImage* pImage2 = NULL; /* default to not present */
307 UINT32 pos; 309 UINT32 pos;
308 UINT32* pFlash = (UINT32*)FLASH_BASE; 310 UINT32* pFlash = (UINT32*)FLASH_BASE;
309 311
310 // determine the first image position 312 /* determine the first image position */
311 pos = pFlash[2] + pFlash[3]; // position + size of the bootloader = after it 313 pos = pFlash[2] + pFlash[3]; /* position + size of the bootloader
312 pos = (pos + 3) & ~3; // be shure it's 32 bit aligned 314 * = after it */
313 315 pos = (pos + 3) & ~3; /* be sure it's 32 bit aligned */
314 pImage1 = (tImage*)pos; 316
315 317 pImage1 = (tImage*)pos;
316 if (pImage1->size != 0) 318
317 { // check for second image 319 if (pImage1->size != 0)
318 pos = (UINT32)(&pImage1->image) + pImage1->size; 320 { /* check for second image */
319 pImage2 = (tImage*)pos; 321 pos = (UINT32)(&pImage1->image) + pImage1->size;
320 322 pImage2 = (tImage*)pos;
321 // does it make sense? (not in FF or 00 erazed space) 323
322 if (pImage2->pDestination == (void*)0xFFFFFFFF 324 /* does it make sense? (not in FF or 00 erazed space) */
323 || pImage2->size == 0xFFFFFFFF 325 if (pImage2->pDestination == (void*)0xFFFFFFFF
324 || pImage2->pExecute == (void*)0xFFFFFFFF 326 || pImage2->size == 0xFFFFFFFF
325 || pImage2->flags == 0xFFFFFFFF 327 || pImage2->pExecute == (void*)0xFFFFFFFF
326 || pImage2->pDestination == NULL) // size, execute and flags can legally be 0 328 || pImage2->flags == 0xFFFFFFFF
327 { 329 || pImage2->pDestination == NULL)
328 pImage2 = NULL; // invalidate 330 /* size, execute and flags can legally be 0 */
329 } 331 {
330 } 332 pImage2 = NULL; /* invalidate */
331 333 }
332 if (pImage2 == NULL || nPreferred == 1) 334 }
333 { // no second image or overridden: return the first 335
334 return pImage1; 336 if (pImage2 == NULL || nPreferred == 1)
335 } 337 { /* no second image or overridden: return the first */
336 338 return pImage1;
337 return pImage2; // return second image 339 }
340
341 return pImage2; /* return second image */
338} 342}
339 343
340// diagnostic functions 344/* diagnostic functions */
341 345
342void SetLed(BOOL bOn) 346void SetLed(BOOL bOn)
343{ 347{
344 if (bOn) 348 if (bOn)
345 PBDR |= 0x40; 349 PBDR |= 0x0040;
346 else 350 else
347 PBDR &= ~0x40; 351 PBDR &= ~0x0040;
348} 352}
349 353
350 354
351void UartInit(void) 355void UartInit(void)
352{ 356{
353 PBIOR &= 0xFBFF; // input: RXD1 remote pin 357 PBIOR &= 0xFBFF; /* input: RXD1 remote pin */
354 PBCR1 |= 0x00A0; // set PB3+PB2 to UART 358 PBCR1 |= 0x00A0; /* set PB11+PB10 to UART */
355 PBCR1 &= 0xFFAF; // clear bits 6, 4 -> UART 359 PBCR1 &= 0xFFAF; /* clear bits 6, 4 -> UART */
356 SMR1 = 0x0000; // async format 8N1, baud generator input is CPU clock 360 SMR1 = 0x00; /* async format 8N1, baud generator input is CPU clock */
357 SCR1 = 0x0030; // transmit+receive enable 361 SCR1 = 0x30; /* transmit+receive enable */
358 PBCR1 &= 0x00FF; // set bit 12...15 as GPIO 362 PBCR1 &= 0x00FF; /* set bit 12...15 as GPIO */
359 SSR1 &= 0x00BF; // clear bit 6 (RDRF, receive data register full) 363 SSR1 &= 0xBF; /* clear bit 6 (RDRF, receive data register full) */
360} 364}
361 365
362 366
363UINT8 UartRead(void) 367UINT8 UartRead(void)
364{ 368{
365 UINT8 byte; 369 UINT8 byte;
366 while (!(SSR1 & SCI_RDRF)); // wait for char to be available 370 while (!(SSR1 & SCI_RDRF)); /* wait for char to be available */
367 byte = RDR1; 371 byte = RDR1;
368 SSR1 &= ~SCI_RDRF; 372 SSR1 &= ~SCI_RDRF;
369 return byte; 373 return byte;
370} 374}
371 375
372 376
373void UartWrite(UINT8 byte) 377void UartWrite(UINT8 byte)
374{ 378{
375 while (!(SSR1 & SCI_TDRE)); // wait for transmit buffer empty 379 while (!(SSR1 & SCI_TDRE)); /* wait for transmit buffer empty */
376 TDR1 = byte; 380 TDR1 = byte;
377 SSR1 &= ~SCI_TDRE; 381 SSR1 &= ~SCI_TDRE;
378} 382}
379 383
380 384
381// include the mini monitor as a rescue feature, started with F3 385/* include the mini monitor as a rescue feature, started with F3 */
382void MiniMon(void) 386void MiniMon(void)
383{ 387{
384 UINT8 cmd; 388 UINT8 cmd;
385 UINT32 addr; 389 UINT32 addr;
386 UINT32 size; 390 UINT32 size;
387 UINT32 content; 391 UINT32 content;
388 volatile UINT8* paddr = NULL; 392 volatile UINT8* paddr = NULL;
389 volatile UINT8* pflash = NULL; // flash base address 393 volatile UINT8* pflash = NULL; /* flash base address */
390 394
391 UartInit(); 395 UartInit();
392 396
393 while (1) 397 while (1)
394 { 398 {
395 cmd = UartRead(); 399 cmd = UartRead();
396 switch (cmd) 400 switch (cmd)
397 { 401 {
398 case BAUDRATE: 402 case BAUDRATE:
399 content = UartRead(); 403 content = UartRead();
400 UartWrite(cmd); // acknowledge by returning the command value 404 UartWrite(cmd); /* acknowledge by returning the command value */
401 while (!(SSR1 & SCI_TEND)); // wait for empty shift register, before changing baudrate 405 while (!(SSR1 & SCI_TEND)); /* wait for empty shift register,
402 BRR1 = content; 406 * before changing baudrate */
403 break; 407 BRR1 = content;
404 408 break;
405 case ADDRESS: 409
406 addr = (UartRead() << 24) | (UartRead() << 16) | (UartRead() << 8) | UartRead(); 410 case ADDRESS:
407 paddr = (UINT8*)addr; 411 addr = (UartRead() << 24) | (UartRead() << 16)
408 pflash = (UINT8*)(addr & 0xFFF80000); // round down to 512k align 412 | (UartRead() << 8) | UartRead();
409 UartWrite(cmd); // acknowledge by returning the command value 413 paddr = (UINT8*)addr;
410 break; 414 pflash = (UINT8*)(addr & 0xFFF80000); /* round down to 512k align*/
411 415 UartWrite(cmd); /* acknowledge by returning the command value */
412 case BYTE_READ: 416 break;
413 content = *paddr++; 417
414 UartWrite(content); // the content is the ack 418 case BYTE_READ:
415 break; 419 content = *paddr++;
416 420 UartWrite(content); /* the content is the ack */
417 case BYTE_WRITE: 421 break;
418 content = UartRead(); 422
419 *paddr++ = content; 423 case BYTE_WRITE:
420 UartWrite(cmd); // acknowledge by returning the command value 424 content = UartRead();
421 break; 425 *paddr++ = content;
422 426 UartWrite(cmd); /* acknowledge by returning the command value */
423 case BYTE_READ16: 427 break;
424 size = 16; 428
425 while (size--) 429 case BYTE_READ16:
426 { 430 size = 16;
427 content = *paddr++; 431 while (size--)
428 UartWrite(content); // the content is the ack 432 {
429 } 433 content = *paddr++;
430 break; 434 UartWrite(content); /* the content is the ack */
431 435 }
432 case BYTE_WRITE16: 436 break;
433 size = 16; 437
434 while (size--) 438 case BYTE_WRITE16:
435 { 439 size = 16;
436 content = UartRead(); 440 while (size--)
437 *paddr++ = content; 441 {
438 } 442 content = UartRead();
439 UartWrite(cmd); // acknowledge by returning the command value 443 *paddr++ = content;
440 break; 444 }
441 445 UartWrite(cmd); /* acknowledge by returning the command value */
442 case BYTE_FLASH: 446 break;
443 content = UartRead(); 447
444 pflash[0x5555] = 0xAA; // set flash to command mode 448 case BYTE_FLASH:
445 pflash[0x2AAA] = 0x55; 449 content = UartRead();
446 pflash[0x5555] = 0xA0; // byte program command 450 pflash[0x5555] = 0xAA; /* set flash to command mode */
447 *paddr++ = content; 451 pflash[0x2AAA] = 0x55;
448 UartWrite(cmd); // acknowledge by returning the command value 452 pflash[0x5555] = 0xA0; /* byte program command */
449 break; 453 *paddr++ = content;
450 454 UartWrite(cmd); /* acknowledge by returning the command value */
451 case BYTE_FLASH16: 455 break;
452 size = 16; 456
453 while (size--) 457 case BYTE_FLASH16:
454 { 458 size = 16;
455 content = UartRead(); 459 while (size--)
456 pflash[0x5555] = 0xAA; // set flash to command mode 460 {
457 pflash[0x2AAA] = 0x55; 461 content = UartRead();
458 pflash[0x5555] = 0xA0; // byte program command 462 pflash[0x5555] = 0xAA; /* set flash to command mode */
459 *paddr++ = content; 463 pflash[0x2AAA] = 0x55;
460 } 464 pflash[0x5555] = 0xA0; /* byte program command */
461 UartWrite(cmd); // acknowledge by returning the command value 465 *paddr++ = content;
462 break; 466 }
463 467 UartWrite(cmd); /* acknowledge by returning the command value */
464 case HALFWORD_READ: 468 break;
465 content = *(UINT16*)paddr; 469
466 paddr += 2; 470 case HALFWORD_READ:
467 UartWrite(content >> 8); // highbyte 471 content = *(UINT16*)paddr;
468 UartWrite(content & 0xFF); // lowbyte 472 paddr += 2;
469 break; 473 UartWrite(content >> 8); /* highbyte */
470 474 UartWrite(content & 0xFF); /* lowbyte */
471 case HALFWORD_WRITE: 475 break;
472 content = UartRead() << 8 | UartRead(); 476
473 *(UINT16*)paddr = content; 477 case HALFWORD_WRITE:
474 paddr += 2; 478 content = UartRead() << 8 | UartRead();
475 UartWrite(cmd); // acknowledge by returning the command value 479 *(UINT16*)paddr = content;
476 break; 480 paddr += 2;
477 481 UartWrite(cmd); /* acknowledge by returning the command value */
478 case EXECUTE: 482 break;
479 { 483
480 tpFunc pFunc = (tpFunc)paddr; 484 case EXECUTE:
481 pFunc(); 485 {
482 UartWrite(cmd); // acknowledge by returning the command value 486 tpFunc pFunc = (tpFunc)paddr;
483 } 487 pFunc();
484 break; 488 UartWrite(cmd); /* acknowledge by returning the command value*/
485 489 }
486 case VERSION: 490 break;
487 UartWrite(1); // return our version number 491
488 break; 492 case VERSION:
489 493 UartWrite(1); /* return our version number */
490 default: 494 break;
491 { 495
492 SetLed(TRUE); 496 default:
493 UartWrite(~cmd); // error acknowledge 497 {
494 } 498 SetLed(TRUE);
495 499 UartWrite(~cmd); /* error acknowledge */
496 } // case 500 }
497 } // while (1) 501
502 } /* case */
503 } /* while (1) */
498} 504}