diff options
-rw-r--r-- | flash/bootloader/bootloader.c | 744 |
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 */ |
31 | UINT32 vectors[] __attribute__ ((section (".vectors"))) = | 31 | UINT32 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 */ |
42 | tpMain start_vector[] __attribute__ ((section (".startvector"))) = {main}; | 43 | tpMain 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 */ |
46 | void _main(void) | 47 | void _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 | ||
71 | void BootInit(void) | 72 | void 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 | ||
93 | int main(void) | 94 | int 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 */ |
117 | void PlatformInit(void) | 118 | void 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 | ||
164 | int ucl_nrv2e_decompress_8( | 166 | int 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 */ |
226 | void DecompressStart(tImage* pImage) | 228 | void 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 |
260 | int ReadADC(int channel) | 262 | int 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. */ |
276 | int ButtonPressed(void) // return 1,2,3 for F1,F2,F3, 0 if none pressed | 278 | int 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 */ |
303 | tImage* GetStartImage(int nPreferred) | 305 | tImage* 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 | ||
342 | void SetLed(BOOL bOn) | 346 | void 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 | ||
351 | void UartInit(void) | 355 | void 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 | ||
363 | UINT8 UartRead(void) | 367 | UINT8 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 | ||
373 | void UartWrite(UINT8 byte) | 377 | void 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 */ |
382 | void MiniMon(void) | 386 | void 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 | } |