summaryrefslogtreecommitdiff
path: root/apps/plugins/rockbox_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/rockbox_flash.c')
-rw-r--r--apps/plugins/rockbox_flash.c151
1 files changed, 80 insertions, 71 deletions
diff --git a/apps/plugins/rockbox_flash.c b/apps/plugins/rockbox_flash.c
index c942683cf1..a6efc249af 100644
--- a/apps/plugins/rockbox_flash.c
+++ b/apps/plugins/rockbox_flash.c
@@ -7,9 +7,10 @@
7* \/ \/ \/ \/ \/ 7* \/ \/ \/ \/ \/
8* $Id$ 8* $Id$
9* 9*
10* Plugin for reprogramming only the second Rockbox image. 10* Plugin for reprogramming only the second image in Flash ROM.
11* !!! DON'T MESS WITH THIS CODE UNLESS YOU'RE ABSOLUTELY SHURE WHAT YOU DO !!!
11* 12*
12* Copyright (C) 2003 Jörg Hohensohn [IDC]Dragon 13* Copyright (C) 2003 Jörg Hohensohn aka [IDC]Dragon
13* 14*
14* All files in this archive are subject to the GNU General Public License. 15* 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* See the file COPYING in the source tree root for full license agreement.
@@ -78,8 +79,7 @@ typedef struct
78 79
79static struct plugin_api* rb; /* here is a global api struct pointer */ 80static struct plugin_api* rb; /* here is a global api struct pointer */
80 81
81#define SEC_SIZE 4096 /* size of one flash sector */ 82static UINT8* sector; /* better not place this on the stack... */
82static UINT8 sector[SEC_SIZE]; /* better not place this on the stack... */
83 83
84/***************** Flash Functions *****************/ 84/***************** Flash Functions *****************/
85 85
@@ -89,25 +89,25 @@ bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID)
89{ 89{
90 UINT8 not_manu, not_id; /* read values before switching to ID mode */ 90 UINT8 not_manu, not_id; /* read values before switching to ID mode */
91 UINT8 manu, id; /* read values when in ID mode */ 91 UINT8 manu, id; /* read values when in ID mode */
92 92
93 pBase = (UINT8*)((UINT32)pBase & 0xFFF80000); /* round down to 512k align, 93 pBase = (UINT8*)((UINT32)pBase & 0xFFF80000); /* round down to 512k align,
94 to make sure */ 94 to make sure */
95 95
96 not_manu = pBase[0]; /* read the normal content */ 96 not_manu = pBase[0]; /* read the normal content */
97 not_id = pBase[1]; /* should be 'A' (0x41) and 'R' (0x52) from the 97 not_id = pBase[1]; /* should be 'A' (0x41) and 'R' (0x52) from the
98 "ARCH" marker */ 98 "ARCH" marker */
99 99
100 pBase[0x5555] = 0xAA; /* enter command mode */ 100 pBase[0x5555] = 0xAA; /* enter command mode */
101 pBase[0x2AAA] = 0x55; 101 pBase[0x2AAA] = 0x55;
102 pBase[0x5555] = 0x90; /* ID command */ 102 pBase[0x5555] = 0x90; /* ID command */
103 rb->sleep(HZ/50); /* Atmel wants 20ms pause here */ 103 rb->sleep(HZ/50); /* Atmel wants 20ms pause here */
104 104
105 manu = pBase[0]; 105 manu = pBase[0];
106 id = pBase[1]; 106 id = pBase[1];
107 107
108 pBase[0] = 0xF0; /* reset flash (back to normal read mode) */ 108 pBase[0] = 0xF0; /* reset flash (back to normal read mode) */
109 rb->sleep(HZ/50); /* Atmel wants 20ms pause here */ 109 rb->sleep(HZ/50); /* Atmel wants 20ms pause here */
110 110
111 /* I assume success if the obtained values are different from 111 /* I assume success if the obtained values are different from
112 the normal flash content. This is not perfectly bulletproof, they 112 the normal flash content. This is not perfectly bulletproof, they
113 could theoretically be the same by chance, causing us to fail. */ 113 could theoretically be the same by chance, causing us to fail. */
@@ -120,46 +120,46 @@ bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID)
120 return false; /* fail */ 120 return false; /* fail */
121} 121}
122 122
123/* eraze the sector which contains the given address */ 123/* erase the sector which contains the given address */
124bool ErazeSector(volatile UINT8* pAddr) 124bool EraseSector(volatile UINT8* pAddr)
125{ 125{
126 volatile UINT8* pBase = 126 volatile UINT8* pBase =
127 (UINT8*)((UINT32)pAddr & 0xFFF80000); /* round down to 512k align */ 127 (UINT8*)((UINT32)pAddr & 0xFFF80000); /* round down to 512k align */
128 unsigned timeout = 43000; /* the timeout loop should be no less than 128 unsigned timeout = 43000; /* the timeout loop should be no less than
129 25ms */ 129 25ms */
130 130
131 pBase[0x5555] = 0xAA; /* enter command mode */ 131 pBase[0x5555] = 0xAA; /* enter command mode */
132 pBase[0x2AAA] = 0x55; 132 pBase[0x2AAA] = 0x55;
133 pBase[0x5555] = 0x80; /* eraze command */ 133 pBase[0x5555] = 0x80; /* erase command */
134 pBase[0x5555] = 0xAA; /* enter command mode */ 134 pBase[0x5555] = 0xAA; /* enter command mode */
135 pBase[0x2AAA] = 0x55; 135 pBase[0x2AAA] = 0x55;
136 *pAddr = 0x30; /* eraze the sector */ 136 *pAddr = 0x30; /* erase the sector */
137 137
138 /* I counted 7 instructions for this loop -> min. 0.58 us per round 138 /* I counted 7 instructions for this loop -> min. 0.58 us per round
139 Plus memory waitstates it will be much more, gives margin */ 139 Plus memory waitstates it will be much more, gives margin */
140 while (*pAddr != 0xFF && --timeout); /* poll for erazed */ 140 while (*pAddr != 0xFF && --timeout); /* poll for erased */
141 141
142 return (timeout != 0); 142 return (timeout != 0);
143} 143}
144 144
145/* address must be in an erazed location */ 145/* address must be in an erased location */
146inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) 146inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data)
147{ 147{
148 unsigned timeout = 35; /* the timeout loop should be no less than 20us */ 148 unsigned timeout = 35; /* the timeout loop should be no less than 20us */
149 149
150 if (~*pAddr & data) /* just a safety feature, not really necessary */ 150 if (~*pAddr & data) /* just a safety feature, not really necessary */
151 return false; /* can't set any bit from 0 to 1 */ 151 return false; /* can't set any bit from 0 to 1 */
152 152
153 FB[0x5555] = 0xAA; /* enter command mode */ 153 FB[0x5555] = 0xAA; /* enter command mode */
154 FB[0x2AAA] = 0x55; 154 FB[0x2AAA] = 0x55;
155 FB[0x5555] = 0xA0; /* byte program command */ 155 FB[0x5555] = 0xA0; /* byte program command */
156 156
157 *pAddr = data; 157 *pAddr = data;
158 158
159 /* I counted 7 instructions for this loop -> min. 0.58 us per round 159 /* I counted 7 instructions for this loop -> min. 0.58 us per round
160 Plus memory waitstates it will be much more, gives margin */ 160 Plus memory waitstates it will be much more, gives margin */
161 while (*pAddr != data && --timeout); /* poll for programmed */ 161 while (*pAddr != data && --timeout); /* poll for programmed */
162 162
163 return (timeout != 0); 163 return (timeout != 0);
164} 164}
165 165
@@ -167,10 +167,10 @@ inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data)
167bool GetFlashInfo(tFlashInfo* pInfo) 167bool GetFlashInfo(tFlashInfo* pInfo)
168{ 168{
169 rb->memset(pInfo, 0, sizeof(tFlashInfo)); 169 rb->memset(pInfo, 0, sizeof(tFlashInfo));
170 170
171 if (!ReadID(FB, &pInfo->manufacturer, &pInfo->id)) 171 if (!ReadID(FB, &pInfo->manufacturer, &pInfo->id))
172 return false; 172 return false;
173 173
174 if (pInfo->manufacturer == 0xBF) /* SST */ 174 if (pInfo->manufacturer == 0xBF) /* SST */
175 { 175 {
176 if (pInfo->id == 0xD6) 176 if (pInfo->id == 0xD6)
@@ -241,7 +241,7 @@ tImageHeader* GetSecondImage(void)
241 241
242 if (pImage1->size != 0) 242 if (pImage1->size != 0)
243 { 243 {
244 /* success, we have a second image */ 244 /* success, we have a second image */
245 pos = (UINT32)pImage1 + sizeof(tImageHeader) + pImage1->size; 245 pos = (UINT32)pImage1 + sizeof(tImageHeader) + pImage1->size;
246 if (((pos + SECTORSIZE-1) & ~(SECTORSIZE-1)) != pos) 246 if (((pos + SECTORSIZE-1) & ~(SECTORSIZE-1)) != pos)
247 { /* not sector-aligned */ 247 { /* not sector-aligned */
@@ -264,7 +264,7 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
264 264
265 int fileread = 0; /* total size as read from the file */ 265 int fileread = 0; /* total size as read from the file */
266 int read; /* how many for this sector */ 266 int read; /* how many for this sector */
267 267
268 /* magic file header for compressed files */ 268 /* magic file header for compressed files */
269 static const UINT8 magic[8] = { 0x00,0xe9,0x55,0x43,0x4c,0xff,0x01,0x1a }; 269 static const UINT8 magic[8] = { 0x00,0xe9,0x55,0x43,0x4c,0xff,0x01,0x1a };
270 UINT8 ucl_header[UCL_HEADER]; 270 UINT8 ucl_header[UCL_HEADER];
@@ -272,7 +272,7 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
272 fd = rb->open(filename, O_RDONLY); 272 fd = rb->open(filename, O_RDONLY);
273 if (fd < 0) 273 if (fd < 0)
274 return eFileNotFound; 274 return eFileNotFound;
275 275
276 filesize = rb->filesize(fd); 276 filesize = rb->filesize(fd);
277 if (filesize - (int)sizeof(ucl_header) - 8 > space) 277 if (filesize - (int)sizeof(ucl_header) - 8 > space)
278 { 278 {
@@ -284,9 +284,9 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
284 rb->close(fd); 284 rb->close(fd);
285 return eTooSmall; 285 return eTooSmall;
286 } 286 }
287 287
288 /* do some sanity checks */ 288 /* do some sanity checks */
289 289
290 read = rb->read(fd, ucl_header, sizeof(ucl_header)); 290 read = rb->read(fd, ucl_header, sizeof(ucl_header));
291 fileread += read; 291 fileread += read;
292 if (read != sizeof(ucl_header)) 292 if (read != sizeof(ucl_header))
@@ -294,7 +294,7 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
294 rb->close(fd); 294 rb->close(fd);
295 return eReadErr; 295 return eReadErr;
296 } 296 }
297 297
298 /* compare the magic header */ 298 /* compare the magic header */
299 for (i=0; i<8; i++) 299 for (i=0; i<8; i++)
300 { 300 {
@@ -304,7 +304,7 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
304 return eNotUCL; 304 return eNotUCL;
305 } 305 }
306 } 306 }
307 307
308 /* check for supported algorithm */ 308 /* check for supported algorithm */
309 if (ucl_header[12] != 0x2E) 309 if (ucl_header[12] != 0x2E)
310 { 310 {
@@ -318,10 +318,10 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
318 rb->close(fd); 318 rb->close(fd);
319 return eMultiBlocks; 319 return eMultiBlocks;
320 } 320 }
321 321
322 if (Read32(ucl_header + 18) > pHeader->size) /* compare with uncompressed 322 if (Read32(ucl_header + 18) > pHeader->size) /* compare with uncompressed
323 size */ 323 size */
324 { /* normal case */ 324 { /* normal case */
325 pHeader->flags = 0x00000001; /* flags for UCL compressed */ 325 pHeader->flags = 0x00000001; /* flags for UCL compressed */
326 } 326 }
327 else 327 else
@@ -333,12 +333,12 @@ tCheckResult CheckImageFile(char* filename, int space, tImageHeader* pHeader)
333 /* check if we can read the whole file */ 333 /* check if we can read the whole file */
334 do 334 do
335 { 335 {
336 read = rb->read(fd, sector, SEC_SIZE); 336 read = rb->read(fd, sector, SECTORSIZE);
337 fileread += read; 337 fileread += read;
338 } while (read == SEC_SIZE); 338 } while (read == SECTORSIZE);
339 339
340 rb->close(fd); 340 rb->close(fd);
341 341
342 if (fileread != filesize) 342 if (fileread != filesize)
343 return eReadErr; 343 return eReadErr;
344 344
@@ -358,7 +358,7 @@ unsigned ProgramImageFile(char* filename, UINT8* pos,
358 int fd; 358 int fd;
359 int read; /* how many for this sector */ 359 int read; /* how many for this sector */
360 unsigned failures = 0; 360 unsigned failures = 0;
361 361
362 fd = rb->open(filename, O_RDONLY); 362 fd = rb->open(filename, O_RDONLY);
363 if (fd < 0) 363 if (fd < 0)
364 return false; 364 return false;
@@ -366,17 +366,17 @@ unsigned ProgramImageFile(char* filename, UINT8* pos,
366 /* no error checking necessary here, we checked for minimum size 366 /* no error checking necessary here, we checked for minimum size
367 already */ 367 already */
368 rb->lseek(fd, start, SEEK_SET); /* go to start position */ 368 rb->lseek(fd, start, SEEK_SET); /* go to start position */
369 369
370 *(tImageHeader*)sector = *pImageHeader; /* copy header into sector 370 *(tImageHeader*)sector = *pImageHeader; /* copy header into sector
371 buffer */ 371 buffer */
372 read = rb->read(fd, sector + sizeof(tImageHeader), 372 read = rb->read(fd, sector + sizeof(tImageHeader),
373 SEC_SIZE - sizeof(tImageHeader)); /* payload behind */ 373 SECTORSIZE - sizeof(tImageHeader)); /* payload behind */
374 size -= read; 374 size -= read;
375 read += sizeof(tImageHeader); /* to be programmed, but not part of the 375 read += sizeof(tImageHeader); /* to be programmed, but not part of the
376 file */ 376 file */
377 377
378 do { 378 do {
379 if (!ErazeSector(pos)) 379 if (!EraseSector(pos))
380 { 380 {
381 /* nothing we can do, let the programming count the errors */ 381 /* nothing we can do, let the programming count the errors */
382 } 382 }
@@ -389,14 +389,14 @@ unsigned ProgramImageFile(char* filename, UINT8* pos,
389 } 389 }
390 } 390 }
391 391
392 pos += SEC_SIZE; 392 pos += SECTORSIZE;
393 read = rb->read(fd, sector, (size > SEC_SIZE) ? SEC_SIZE : size); 393 read = rb->read(fd, sector, (size > SECTORSIZE) ? SECTORSIZE : size);
394 /* payload for next sector */ 394 /* payload for next sector */
395 size -= read; 395 size -= read;
396 } while (read > 0); 396 } while (read > 0);
397 397
398 rb->close(fd); 398 rb->close(fd);
399 399
400 return failures; 400 return failures;
401} 401}
402 402
@@ -408,7 +408,7 @@ unsigned VerifyImageFile(char* filename, UINT8* pos,
408 int fd; 408 int fd;
409 int read; /* how many for this sector */ 409 int read; /* how many for this sector */
410 unsigned failures = 0; 410 unsigned failures = 0;
411 411
412 fd = rb->open(filename, O_RDONLY); 412 fd = rb->open(filename, O_RDONLY);
413 if (fd < 0) 413 if (fd < 0)
414 return false; 414 return false;
@@ -416,11 +416,11 @@ unsigned VerifyImageFile(char* filename, UINT8* pos,
416 /* no error checking necessary here, we checked for minimum size 416 /* no error checking necessary here, we checked for minimum size
417 already */ 417 already */
418 rb->lseek(fd, start, SEEK_SET); /* go to start position */ 418 rb->lseek(fd, start, SEEK_SET); /* go to start position */
419 419
420 *(tImageHeader*)sector = *pImageHeader; /* copy header into sector 420 *(tImageHeader*)sector = *pImageHeader; /* copy header into sector
421 buffer */ 421 buffer */
422 read = rb->read(fd, sector + sizeof(tImageHeader), 422 read = rb->read(fd, sector + sizeof(tImageHeader),
423 SEC_SIZE - sizeof(tImageHeader)); /* payload behind */ 423 SECTORSIZE - sizeof(tImageHeader)); /* payload behind */
424 424
425 size -= read; 425 size -= read;
426 read += sizeof(tImageHeader); /* to be programmed, but not part of the 426 read += sizeof(tImageHeader); /* to be programmed, but not part of the
@@ -436,8 +436,8 @@ unsigned VerifyImageFile(char* filename, UINT8* pos,
436 } 436 }
437 } 437 }
438 438
439 pos += SEC_SIZE; 439 pos += SECTORSIZE;
440 read = rb->read(fd, sector, (size > SEC_SIZE) ? SEC_SIZE : size); 440 read = rb->read(fd, sector, (size > SECTORSIZE) ? SECTORSIZE : size);
441 /* payload for next sector */ 441 /* payload for next sector */
442 size -= read; 442 size -= read;
443 } while (read); 443 } while (read);
@@ -455,7 +455,7 @@ unsigned VerifyImageFile(char* filename, UINT8* pos,
455void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) 455void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
456{ 456{
457 char buf[32]; 457 char buf[32];
458 458
459 if (!pInfo->manufacturer) 459 if (!pInfo->manufacturer)
460 { 460 {
461 rb->lcd_puts(0, 0, "Flash: M=?? D=??"); 461 rb->lcd_puts(0, 0, "Flash: M=?? D=??");
@@ -481,10 +481,10 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader)
481 ((UINT8*)pImageHeader - FB) / 1024); 481 ((UINT8*)pImageHeader - FB) / 1024);
482 rb->lcd_puts(0, 1, buf); 482 rb->lcd_puts(0, 1, buf);
483 } 483 }
484 else 484 else
485 { 485 {
486 rb->lcd_puts(0, 1, "No image found!"); 486 rb->lcd_puts(0, 1, "No image found!");
487 } 487 }
488 488
489 rb->lcd_update(); 489 rb->lcd_update();
490} 490}
@@ -500,9 +500,18 @@ void DoUserDialog(char* filename)
500 int rc; /* generic return code */ 500 int rc; /* generic return code */
501 UINT32 space, aligned_size, true_size; 501 UINT32 space, aligned_size, true_size;
502 UINT8* pos; 502 UINT8* pos;
503 int memleft;
503 504
504 rb->lcd_setfont(FONT_SYSFIXED); 505 rb->lcd_setfont(FONT_SYSFIXED);
505 506
507 /* "allocate" memory */
508 sector = rb->plugin_get_buffer(&memleft);
509 if (memleft < SECTORSIZE) /* need buffer for a flash sector */
510 {
511 rb->splash(HZ*3, 0, true, "Out of memory");
512 return; /* exit */
513 }
514
506 pos = (void*)GetSecondImage(); 515 pos = (void*)GetSecondImage();
507 rc = GetFlashInfo(&FlashInfo); 516 rc = GetFlashInfo(&FlashInfo);
508 517
@@ -531,11 +540,11 @@ void DoUserDialog(char* filename)
531 { 540 {
532 return; 541 return;
533 } 542 }
534 543
535 rb->lcd_clear_display(); 544 rb->lcd_clear_display();
536 rb->lcd_puts(0, 0, "checking..."); 545 rb->lcd_puts(0, 0, "checking...");
537 rb->lcd_update(); 546 rb->lcd_update();
538 547
539 space = FlashInfo.size - (pos-FB + sizeof(ImageHeader)); 548 space = FlashInfo.size - (pos-FB + sizeof(ImageHeader));
540 /* size minus start */ 549 /* size minus start */
541 550
@@ -545,43 +554,43 @@ void DoUserDialog(char* filename)
545 case eOK: 554 case eOK:
546 rb->lcd_puts(0, 1, "File OK."); 555 rb->lcd_puts(0, 1, "File OK.");
547 break; 556 break;
548 case eNotUCL: 557 case eNotUCL:
549 rb->lcd_puts(0, 1, "File not UCL "); 558 rb->lcd_puts(0, 1, "File not UCL ");
550 rb->lcd_puts(0, 2, "compressed."); 559 rb->lcd_puts(0, 2, "compressed.");
551 rb->lcd_puts(0, 3, "Use uclpack --2e"); 560 rb->lcd_puts(0, 3, "Use uclpack --2e");
552 rb->lcd_puts(0, 4, " --10 rockbox.bin"); 561 rb->lcd_puts(0, 4, " --10 rockbox.bin");
553 break; 562 break;
554 case eWrongAlgorithm: 563 case eWrongAlgorithm:
555 rb->lcd_puts(0, 1, "Wrong algorithm"); 564 rb->lcd_puts(0, 1, "Wrong algorithm");
556 rb->lcd_puts(0, 2, "for compression."); 565 rb->lcd_puts(0, 2, "for compression.");
557 rb->lcd_puts(0, 3, "Use uclpack --2e"); 566 rb->lcd_puts(0, 3, "Use uclpack --2e");
558 rb->lcd_puts(0, 4, " --10 rockbox.bin"); 567 rb->lcd_puts(0, 4, " --10 rockbox.bin");
559 break; 568 break;
560 case eFileNotFound: 569 case eFileNotFound:
561 rb->lcd_puts(0, 1, "File not found:"); 570 rb->lcd_puts(0, 1, "File not found:");
562 rb->lcd_puts_scroll(0, 2, filename); 571 rb->lcd_puts_scroll(0, 2, filename);
563 break; 572 break;
564 case eTooBig: 573 case eTooBig:
565 rb->lcd_puts(0, 1, "File too big,"); 574 rb->lcd_puts(0, 1, "File too big,");
566 rb->lcd_puts(0, 2, "won't fit in chip."); 575 rb->lcd_puts(0, 2, "won't fit in chip.");
567 break; 576 break;
568 case eTooSmall: 577 case eTooSmall:
569 rb->lcd_puts(0, 1, "File too small."); 578 rb->lcd_puts(0, 1, "File too small.");
570 rb->lcd_puts(0, 2, "Incomplete?"); 579 rb->lcd_puts(0, 2, "Incomplete?");
571 break; 580 break;
572 case eReadErr: 581 case eReadErr:
573 rb->lcd_puts(0, 1, "File read error."); 582 rb->lcd_puts(0, 1, "File read error.");
574 break; 583 break;
575 case eMultiBlocks: 584 case eMultiBlocks:
576 rb->lcd_puts(0, 1, "File invalid."); 585 rb->lcd_puts(0, 1, "File invalid.");
577 rb->lcd_puts(0, 2, "Blocksize"); 586 rb->lcd_puts(0, 2, "Blocksize");
578 rb->lcd_puts(0, 3, " too small?"); 587 rb->lcd_puts(0, 3, " too small?");
579 break; 588 break;
580 default: 589 default:
581 rb->lcd_puts(0, 1, "Check failed."); 590 rb->lcd_puts(0, 1, "Check failed.");
582 break; 591 break;
583 } 592 }
584 593
585 if (rc == eOK) 594 if (rc == eOK)
586 { /* was OK */ 595 { /* was OK */
587 rb->lcd_puts(0, 6, "[F2] to program"); 596 rb->lcd_puts(0, 6, "[F2] to program");
@@ -591,7 +600,7 @@ void DoUserDialog(char* filename)
591 { /* error occured */ 600 { /* error occured */
592 rb->lcd_puts(0, 6, "Any key to exit"); 601 rb->lcd_puts(0, 6, "Any key to exit");
593 } 602 }
594 603
595 rb->lcd_update(); 604 rb->lcd_update();
596 605
597 button = rb->button_get(true); 606 button = rb->button_get(true);
@@ -613,7 +622,7 @@ void DoUserDialog(char* filename)
613 rb->lcd_clear_display(); 622 rb->lcd_clear_display();
614 rb->lcd_puts(0, 0, "Programming..."); 623 rb->lcd_puts(0, 0, "Programming...");
615 rb->lcd_update(); 624 rb->lcd_update();
616 625
617 rc = ProgramImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); 626 rc = ProgramImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size);
618 if (rc) 627 if (rc)
619 { /* errors */ 628 { /* errors */
@@ -630,9 +639,9 @@ void DoUserDialog(char* filename)
630 rb->lcd_clear_display(); 639 rb->lcd_clear_display();
631 rb->lcd_puts(0, 0, "Verifying..."); 640 rb->lcd_puts(0, 0, "Verifying...");
632 rb->lcd_update(); 641 rb->lcd_update();
633 642
634 rc = VerifyImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); 643 rc = VerifyImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size);
635 644
636 rb->lcd_clear_display(); 645 rb->lcd_clear_display();
637 if (rc == 0) 646 if (rc == 0)
638 { 647 {
@@ -665,20 +674,20 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
665 it test that the api version and model the plugin was compiled for 674 it test that the api version and model the plugin was compiled for
666 matches the machine it is running on */ 675 matches the machine it is running on */
667 TEST_PLUGIN_API(api); 676 TEST_PLUGIN_API(api);
668 677
669 if (parameter == NULL) 678 if (parameter == NULL)
670 filename = DEFAULT_FILENAME; 679 filename = DEFAULT_FILENAME;
671 else 680 else
672 filename = (char*) parameter; 681 filename = (char*) parameter;
673 682
674 rb = api; /* copy to global api pointer */ 683 rb = api; /* copy to global api pointer */
675 684
676 /* now go ahead and have fun! */ 685 /* now go ahead and have fun! */
677 DoUserDialog(filename); 686 DoUserDialog(filename);
678 687
679 return PLUGIN_OK; 688 return PLUGIN_OK;
680} 689}
681 690
682#endif 691#endif // #ifdef HAVE_LCD_BITMAP
683 692
684#endif 693#endif // #ifndef SIMULATOR