diff options
Diffstat (limited to 'apps/plugins')
-rw-r--r-- | apps/plugins/rockbox_flash.c | 292 |
1 files changed, 240 insertions, 52 deletions
diff --git a/apps/plugins/rockbox_flash.c b/apps/plugins/rockbox_flash.c index a6efc249af..4644521329 100644 --- a/apps/plugins/rockbox_flash.c +++ b/apps/plugins/rockbox_flash.c | |||
@@ -23,7 +23,9 @@ | |||
23 | 23 | ||
24 | /* Only build for target */ | 24 | /* Only build for target */ |
25 | #ifndef SIMULATOR | 25 | #ifndef SIMULATOR |
26 | #ifdef HAVE_LCD_BITMAP | 26 | |
27 | /* define DUMMY if you only want to "play" with the UI, does no harm */ | ||
28 | /* #define DUMMY */ | ||
27 | 29 | ||
28 | #ifndef UINT8 | 30 | #ifndef UINT8 |
29 | #define UINT8 unsigned char | 31 | #define UINT8 unsigned char |
@@ -123,6 +125,10 @@ bool ReadID(volatile UINT8* pBase, UINT8* pManufacturerID, UINT8* pDeviceID) | |||
123 | /* erase the sector which contains the given address */ | 125 | /* erase the sector which contains the given address */ |
124 | bool EraseSector(volatile UINT8* pAddr) | 126 | bool EraseSector(volatile UINT8* pAddr) |
125 | { | 127 | { |
128 | #ifdef DUMMY | ||
129 | (void)pAddr; /* prevents warning */ | ||
130 | return true; | ||
131 | #else | ||
126 | volatile UINT8* pBase = | 132 | volatile UINT8* pBase = |
127 | (UINT8*)((UINT32)pAddr & 0xFFF80000); /* round down to 512k align */ | 133 | (UINT8*)((UINT32)pAddr & 0xFFF80000); /* round down to 512k align */ |
128 | unsigned timeout = 43000; /* the timeout loop should be no less than | 134 | unsigned timeout = 43000; /* the timeout loop should be no less than |
@@ -140,11 +146,17 @@ bool EraseSector(volatile UINT8* pAddr) | |||
140 | while (*pAddr != 0xFF && --timeout); /* poll for erased */ | 146 | while (*pAddr != 0xFF && --timeout); /* poll for erased */ |
141 | 147 | ||
142 | return (timeout != 0); | 148 | return (timeout != 0); |
149 | #endif | ||
143 | } | 150 | } |
144 | 151 | ||
145 | /* address must be in an erased location */ | 152 | /* address must be in an erased location */ |
146 | inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) | 153 | inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) |
147 | { | 154 | { |
155 | #ifdef DUMMY | ||
156 | (void)pAddr; /* prevents warnings */ | ||
157 | (void)data; | ||
158 | return true; | ||
159 | #else | ||
148 | unsigned timeout = 35; /* the timeout loop should be no less than 20us */ | 160 | unsigned timeout = 35; /* the timeout loop should be no less than 20us */ |
149 | 161 | ||
150 | if (~*pAddr & data) /* just a safety feature, not really necessary */ | 162 | if (~*pAddr & data) /* just a safety feature, not really necessary */ |
@@ -161,6 +173,7 @@ inline bool ProgramByte(volatile UINT8* pAddr, UINT8 data) | |||
161 | while (*pAddr != data && --timeout); /* poll for programmed */ | 173 | while (*pAddr != data && --timeout); /* poll for programmed */ |
162 | 174 | ||
163 | return (timeout != 0); | 175 | return (timeout != 0); |
176 | #endif | ||
164 | } | 177 | } |
165 | 178 | ||
166 | /* this returns true if supported and fills the info struct */ | 179 | /* this returns true if supported and fills the info struct */ |
@@ -197,10 +210,10 @@ bool GetFlashInfo(tFlashInfo* pInfo) | |||
197 | /* place a 32 bit value into memory, big endian */ | 210 | /* place a 32 bit value into memory, big endian */ |
198 | void Write32(UINT8* pByte, UINT32 value) | 211 | void Write32(UINT8* pByte, UINT32 value) |
199 | { | 212 | { |
200 | pByte[0] = (UINT8)(value >> 24); | 213 | pByte[0] = (UINT8)(value >> 24); |
201 | pByte[1] = (UINT8)(value >> 16); | 214 | pByte[1] = (UINT8)(value >> 16); |
202 | pByte[2] = (UINT8)(value >> 8); | 215 | pByte[2] = (UINT8)(value >> 8); |
203 | pByte[3] = (UINT8)(value); | 216 | pByte[3] = (UINT8)(value); |
204 | } | 217 | } |
205 | 218 | ||
206 | /* read a 32 bit value from memory, big endian */ | 219 | /* read a 32 bit value from memory, big endian */ |
@@ -220,7 +233,7 @@ UINT32 Read32(UINT8* pByte) | |||
220 | tImageHeader* GetSecondImage(void) | 233 | tImageHeader* GetSecondImage(void) |
221 | { | 234 | { |
222 | tImageHeader* pImage1; | 235 | tImageHeader* pImage1; |
223 | UINT32 pos = 0; /* default: not found */ | 236 | UINT32 pos = 0; /* default: not found */ |
224 | UINT32* pFlash = (UINT32*)FB; | 237 | UINT32* pFlash = (UINT32*)FB; |
225 | 238 | ||
226 | UINT16 version = *(UINT16*)(FB + VERS_ADR); | 239 | UINT16 version = *(UINT16*)(FB + VERS_ADR); |
@@ -244,8 +257,8 @@ tImageHeader* GetSecondImage(void) | |||
244 | /* success, we have a second image */ | 257 | /* success, we have a second image */ |
245 | pos = (UINT32)pImage1 + sizeof(tImageHeader) + pImage1->size; | 258 | pos = (UINT32)pImage1 + sizeof(tImageHeader) + pImage1->size; |
246 | if (((pos + SECTORSIZE-1) & ~(SECTORSIZE-1)) != pos) | 259 | if (((pos + SECTORSIZE-1) & ~(SECTORSIZE-1)) != pos) |
247 | { /* not sector-aligned */ | 260 | { /* not sector-aligned */ |
248 | pos = 0; // sanity check failed | 261 | pos = 0; /* sanity check failed */ |
249 | } | 262 | } |
250 | } | 263 | } |
251 | 264 | ||
@@ -449,7 +462,18 @@ unsigned VerifyImageFile(char* filename, UINT8* pos, | |||
449 | 462 | ||
450 | 463 | ||
451 | /***************** User Interface Functions *****************/ | 464 | /***************** User Interface Functions *****************/ |
452 | /* (to be changed for Player) */ | 465 | |
466 | int WaitForButton(void) | ||
467 | { | ||
468 | int button; | ||
469 | |||
470 | do | ||
471 | { | ||
472 | button = rb->button_get(true); | ||
473 | } while (button & BUTTON_REL); | ||
474 | |||
475 | return button; | ||
476 | } | ||
453 | 477 | ||
454 | /* helper for DoUserDialog() */ | 478 | /* helper for DoUserDialog() */ |
455 | void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) | 479 | void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) |
@@ -458,7 +482,7 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) | |||
458 | 482 | ||
459 | if (!pInfo->manufacturer) | 483 | if (!pInfo->manufacturer) |
460 | { | 484 | { |
461 | rb->lcd_puts(0, 0, "Flash: M=?? D=??"); | 485 | rb->lcd_puts_scroll(0, 0, "Flash: M=?? D=??"); |
462 | } | 486 | } |
463 | else | 487 | else |
464 | { | 488 | { |
@@ -466,11 +490,11 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) | |||
466 | { | 490 | { |
467 | rb->snprintf(buf, sizeof(buf), "Flash size: %d KB", | 491 | rb->snprintf(buf, sizeof(buf), "Flash size: %d KB", |
468 | pInfo->size / 1024); | 492 | pInfo->size / 1024); |
469 | rb->lcd_puts(0, 0, buf); | 493 | rb->lcd_puts_scroll(0, 0, buf); |
470 | } | 494 | } |
471 | else | 495 | else |
472 | { | 496 | { |
473 | rb->lcd_puts(0, 0, "Unsupported chip"); | 497 | rb->lcd_puts_scroll(0, 0, "Unsupported chip"); |
474 | } | 498 | } |
475 | 499 | ||
476 | } | 500 | } |
@@ -479,23 +503,23 @@ void ShowFlashInfo(tFlashInfo* pInfo, tImageHeader* pImageHeader) | |||
479 | { | 503 | { |
480 | rb->snprintf(buf, sizeof(buf), "Image at %d KB", | 504 | rb->snprintf(buf, sizeof(buf), "Image at %d KB", |
481 | ((UINT8*)pImageHeader - FB) / 1024); | 505 | ((UINT8*)pImageHeader - FB) / 1024); |
482 | rb->lcd_puts(0, 1, buf); | 506 | rb->lcd_puts_scroll(0, 1, buf); |
483 | } | 507 | } |
484 | else | 508 | else |
485 | { | 509 | { |
486 | rb->lcd_puts(0, 1, "No image found!"); | 510 | rb->lcd_puts_scroll(0, 1, "No image found!"); |
487 | } | 511 | } |
488 | |||
489 | rb->lcd_update(); | ||
490 | } | 512 | } |
491 | 513 | ||
492 | 514 | ||
493 | /* Kind of our main function, defines the application flow. */ | 515 | /* Kind of our main function, defines the application flow. */ |
494 | void DoUserDialog(char* filename) | 516 | #ifdef HAVE_LCD_BITMAP |
517 | /* recorder version */ | ||
518 | void DoUserDialog(char* filename, bool show_greet) | ||
495 | { | 519 | { |
496 | tImageHeader ImageHeader; | 520 | tImageHeader ImageHeader; |
497 | tFlashInfo FlashInfo; | 521 | tFlashInfo FlashInfo; |
498 | char buf[32]; | 522 | static char buf[MAX_PATH]; |
499 | int button; | 523 | int button; |
500 | int rc; /* generic return code */ | 524 | int rc; /* generic return code */ |
501 | UINT32 space, aligned_size, true_size; | 525 | UINT32 space, aligned_size, true_size; |
@@ -516,6 +540,8 @@ void DoUserDialog(char* filename) | |||
516 | rc = GetFlashInfo(&FlashInfo); | 540 | rc = GetFlashInfo(&FlashInfo); |
517 | 541 | ||
518 | ShowFlashInfo(&FlashInfo, (void*)pos); | 542 | ShowFlashInfo(&FlashInfo, (void*)pos); |
543 | rb->lcd_update(); | ||
544 | |||
519 | if (FlashInfo.size == 0) /* no valid chip */ | 545 | if (FlashInfo.size == 0) /* no valid chip */ |
520 | { | 546 | { |
521 | rb->splash(HZ*3, 0, true, "Not flashable"); | 547 | rb->splash(HZ*3, 0, true, "Not flashable"); |
@@ -523,36 +549,42 @@ void DoUserDialog(char* filename) | |||
523 | } | 549 | } |
524 | else if (pos == 0) | 550 | else if (pos == 0) |
525 | { | 551 | { |
526 | rb->splash(HZ*3, 0, true, "No Image"); | 552 | rb->splash(HZ*3, 0, true, "No image"); |
527 | return; /* exit */ | 553 | return; /* exit */ |
528 | } | 554 | } |
529 | 555 | ||
530 | rb->lcd_puts(0, 3, "using file:"); | 556 | if (show_greet) |
531 | rb->lcd_puts_scroll(0, 4, filename); | ||
532 | rb->lcd_puts(0, 6, "[F1] to check file"); | ||
533 | rb->lcd_puts(0, 7, "other key to exit"); | ||
534 | rb->lcd_update(); | ||
535 | |||
536 | button = rb->button_get(true); | ||
537 | button = rb->button_get(true); | ||
538 | |||
539 | if (button != BUTTON_F1) | ||
540 | { | 557 | { |
541 | return; | 558 | rb->lcd_puts(0, 3, "using file:"); |
559 | rb->lcd_puts_scroll(0, 4, filename); | ||
560 | rb->lcd_puts(0, 6, "[F1] to check file"); | ||
561 | rb->lcd_puts(0, 7, "other key to exit"); | ||
562 | rb->lcd_update(); | ||
563 | |||
564 | if (WaitForButton() != BUTTON_F1) | ||
565 | { | ||
566 | return; | ||
567 | } | ||
568 | rb->lcd_clear_display(); | ||
542 | } | 569 | } |
543 | 570 | ||
544 | rb->lcd_clear_display(); | 571 | rb->lcd_puts(0, show_greet ? 0 : 3, "Checking..."); |
545 | rb->lcd_puts(0, 0, "checking..."); | ||
546 | rb->lcd_update(); | 572 | rb->lcd_update(); |
547 | 573 | ||
548 | space = FlashInfo.size - (pos-FB + sizeof(ImageHeader)); | 574 | space = FlashInfo.size - (pos-FB + sizeof(ImageHeader)); |
549 | /* size minus start */ | 575 | /* size minus start */ |
550 | 576 | ||
551 | rc = CheckImageFile(filename, space, &ImageHeader); | 577 | rc = CheckImageFile(filename, space, &ImageHeader); |
552 | rb->lcd_puts(0, 0, "checked:"); | 578 | if (rc != eOK) |
579 | { | ||
580 | rb->lcd_clear_display(); /* make room for error message */ | ||
581 | show_greet = true; /* verbose */ | ||
582 | } | ||
583 | |||
584 | rb->lcd_puts(0, show_greet ? 0 : 3, "Checked:"); | ||
553 | switch (rc) { | 585 | switch (rc) { |
554 | case eOK: | 586 | case eOK: |
555 | rb->lcd_puts(0, 1, "File OK."); | 587 | rb->lcd_puts(0, show_greet ? 0 : 4, "File OK."); |
556 | break; | 588 | break; |
557 | case eNotUCL: | 589 | case eNotUCL: |
558 | rb->lcd_puts(0, 1, "File not UCL "); | 590 | rb->lcd_puts(0, 1, "File not UCL "); |
@@ -592,7 +624,7 @@ void DoUserDialog(char* filename) | |||
592 | } | 624 | } |
593 | 625 | ||
594 | if (rc == eOK) | 626 | if (rc == eOK) |
595 | { /* was OK */ | 627 | { /* was OK */ |
596 | rb->lcd_puts(0, 6, "[F2] to program"); | 628 | rb->lcd_puts(0, 6, "[F2] to program"); |
597 | rb->lcd_puts(0, 7, "other key to exit"); | 629 | rb->lcd_puts(0, 7, "other key to exit"); |
598 | } | 630 | } |
@@ -600,12 +632,9 @@ void DoUserDialog(char* filename) | |||
600 | { /* error occured */ | 632 | { /* error occured */ |
601 | rb->lcd_puts(0, 6, "Any key to exit"); | 633 | rb->lcd_puts(0, 6, "Any key to exit"); |
602 | } | 634 | } |
603 | |||
604 | rb->lcd_update(); | 635 | rb->lcd_update(); |
605 | 636 | ||
606 | button = rb->button_get(true); | 637 | button = WaitForButton(); |
607 | button = rb->button_get(true); | ||
608 | |||
609 | if (rc != eOK || button != BUTTON_F2) | 638 | if (rc != eOK || button != BUTTON_F2) |
610 | { | 639 | { |
611 | return; | 640 | return; |
@@ -620,24 +649,23 @@ void DoUserDialog(char* filename) | |||
620 | the next sector */ | 649 | the next sector */ |
621 | 650 | ||
622 | rb->lcd_clear_display(); | 651 | rb->lcd_clear_display(); |
623 | rb->lcd_puts(0, 0, "Programming..."); | 652 | rb->lcd_puts_scroll(0, 0, "Programming..."); |
624 | rb->lcd_update(); | 653 | rb->lcd_update(); |
625 | 654 | ||
626 | rc = ProgramImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); | 655 | rc = ProgramImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); |
627 | if (rc) | 656 | if (rc) |
628 | { /* errors */ | 657 | { /* errors */ |
629 | rb->lcd_clear_display(); | 658 | rb->lcd_clear_display(); |
659 | rb->snprintf(buf, sizeof(buf), "%d errors", rc); | ||
630 | rb->lcd_puts(0, 0, "Error:"); | 660 | rb->lcd_puts(0, 0, "Error:"); |
631 | rb->lcd_puts(0, 1, "Programming fail!"); | 661 | rb->lcd_puts(0, 1, "Programming fail!"); |
632 | rb->snprintf(buf, sizeof(buf), "%d errors", rc); | ||
633 | rb->lcd_puts(0, 2, buf); | 662 | rb->lcd_puts(0, 2, buf); |
634 | rb->lcd_update(); | 663 | rb->lcd_update(); |
635 | button = rb->button_get(true); | 664 | button = WaitForButton(); |
636 | button = rb->button_get(true); | ||
637 | } | 665 | } |
638 | 666 | ||
639 | rb->lcd_clear_display(); | 667 | rb->lcd_clear_display(); |
640 | rb->lcd_puts(0, 0, "Verifying..."); | 668 | rb->lcd_puts_scroll(0, 0, "Verifying..."); |
641 | rb->lcd_update(); | 669 | rb->lcd_update(); |
642 | 670 | ||
643 | rc = VerifyImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); | 671 | rc = VerifyImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); |
@@ -649,9 +677,9 @@ void DoUserDialog(char* filename) | |||
649 | } | 677 | } |
650 | else | 678 | else |
651 | { | 679 | { |
680 | rb->snprintf(buf, sizeof(buf), "%d errors", rc); | ||
652 | rb->lcd_puts(0, 0, "Error:"); | 681 | rb->lcd_puts(0, 0, "Error:"); |
653 | rb->lcd_puts(0, 1, "Verify fail!"); | 682 | rb->lcd_puts(0, 1, "Verify fail!"); |
654 | rb->snprintf(buf, sizeof(buf), "%d errors", rc); | ||
655 | rb->lcd_puts(0, 2, buf); | 683 | rb->lcd_puts(0, 2, buf); |
656 | rb->lcd_puts(0, 3, "Use safe image"); | 684 | rb->lcd_puts(0, 3, "Use safe image"); |
657 | rb->lcd_puts(0, 4, "if booting hangs:"); | 685 | rb->lcd_puts(0, 4, "if booting hangs:"); |
@@ -659,16 +687,172 @@ void DoUserDialog(char* filename) | |||
659 | } | 687 | } |
660 | rb->lcd_puts(0, 7, "Any key to exit"); | 688 | rb->lcd_puts(0, 7, "Any key to exit"); |
661 | rb->lcd_update(); | 689 | rb->lcd_update(); |
690 | WaitForButton(); | ||
691 | } | ||
692 | |||
693 | #else /* #ifdef HAVE_LCD_BITMAP */ | ||
694 | |||
695 | /* Player version */ | ||
696 | void DoUserDialog(char* filename, bool show_greet) | ||
697 | { | ||
698 | tImageHeader ImageHeader; | ||
699 | tFlashInfo FlashInfo; | ||
700 | static char buf[MAX_PATH]; | ||
701 | int button; | ||
702 | int rc; /* generic return code */ | ||
703 | UINT32 space, aligned_size, true_size; | ||
704 | UINT8* pos; | ||
705 | int memleft; | ||
706 | |||
707 | /* "allocate" memory */ | ||
708 | sector = rb->plugin_get_buffer(&memleft); | ||
709 | if (memleft < SECTORSIZE) /* need buffer for a flash sector */ | ||
710 | { | ||
711 | rb->splash(HZ*3, 0, true, "Out of memory"); | ||
712 | return; /* exit */ | ||
713 | } | ||
714 | |||
715 | pos = (void*)GetSecondImage(); | ||
716 | rc = GetFlashInfo(&FlashInfo); | ||
717 | |||
718 | if (show_greet) | ||
719 | { | ||
720 | ShowFlashInfo(&FlashInfo, (void*)pos); | ||
721 | WaitForButton(); | ||
722 | } | ||
723 | |||
724 | if (FlashInfo.size == 0) /* no valid chip */ | ||
725 | { | ||
726 | rb->splash(HZ*3, 0, true, "Not flashable"); | ||
727 | return; /* exit */ | ||
728 | } | ||
729 | else if (pos == 0) | ||
730 | { | ||
731 | rb->splash(HZ*3, 0, true, "No image"); | ||
732 | return; /* exit */ | ||
733 | } | ||
734 | |||
735 | if (show_greet) | ||
736 | { | ||
737 | rb->snprintf(buf, sizeof(buf), "File: %s", filename); | ||
738 | rb->lcd_puts_scroll(0, 0, buf); | ||
739 | rb->lcd_puts_scroll(0, 1, "[Menu] to check file, other key to exit"); | ||
740 | |||
741 | if (WaitForButton() != BUTTON_MENU) | ||
742 | { | ||
743 | return; | ||
744 | } | ||
745 | rb->lcd_clear_display(); | ||
746 | } | ||
747 | |||
748 | rb->lcd_puts(0, 0, "Checking..."); | ||
749 | |||
750 | space = FlashInfo.size - (pos-FB + sizeof(ImageHeader)); | ||
751 | /* size minus start */ | ||
662 | 752 | ||
663 | button = rb->button_get(true); | 753 | rc = CheckImageFile(filename, space, &ImageHeader); |
664 | button = rb->button_get(true); | 754 | rb->lcd_puts(0, 0, "Checked:"); |
755 | switch (rc) { | ||
756 | case eOK: | ||
757 | rb->lcd_puts(0, 1, "File OK."); | ||
758 | rb->sleep(HZ*1); | ||
759 | break; | ||
760 | case eNotUCL: | ||
761 | rb->lcd_puts_scroll(0, 1, "File not UCL compressed."); | ||
762 | break; | ||
763 | case eWrongAlgorithm: | ||
764 | rb->lcd_puts_scroll(0, 1, "Wrong compression algorithm."); | ||
765 | break; | ||
766 | case eFileNotFound: | ||
767 | rb->lcd_puts_scroll(0, 1, "File not found."); | ||
768 | break; | ||
769 | case eTooBig: | ||
770 | rb->lcd_puts_scroll(0, 1, "File too big."); | ||
771 | break; | ||
772 | case eTooSmall: | ||
773 | rb->lcd_puts_scroll(0, 1, "File too small. Incomplete?"); | ||
774 | break; | ||
775 | case eReadErr: | ||
776 | rb->lcd_puts_scroll(0, 1, "File read error."); | ||
777 | break; | ||
778 | case eMultiBlocks: | ||
779 | rb->lcd_puts_scroll(0, 1, "File invalid. Blocksize too small?"); | ||
780 | break; | ||
781 | default: | ||
782 | rb->lcd_puts_scroll(0, 1, "Check failed."); | ||
783 | break; | ||
784 | } | ||
785 | |||
786 | if (rc == eOK) | ||
787 | { /* was OK */ | ||
788 | rb->lcd_clear_display(); | ||
789 | rb->lcd_puts_scroll(0, 0, "[ON] to program,"); | ||
790 | rb->lcd_puts_scroll(0, 1, "other key to exit."); | ||
791 | } | ||
792 | else | ||
793 | { /* error occured */ | ||
794 | WaitForButton(); | ||
795 | rb->lcd_clear_display(); | ||
796 | rb->lcd_puts_scroll(0, 0, "Flash failed."); | ||
797 | rb->lcd_puts_scroll(0, 1, "Any key to exit."); | ||
798 | } | ||
799 | |||
800 | button = WaitForButton(); | ||
801 | if (rc != eOK || button != BUTTON_ON) | ||
802 | { | ||
803 | return; | ||
804 | } | ||
805 | |||
806 | true_size = ImageHeader.size; | ||
807 | aligned_size = ((sizeof(tImageHeader) + true_size + SECTORSIZE-1) & | ||
808 | ~(SECTORSIZE-1)) - sizeof(tImageHeader); /* round up to | ||
809 | next flash | ||
810 | sector */ | ||
811 | ImageHeader.size = aligned_size; /* increase image size such that we reach | ||
812 | the next sector */ | ||
813 | |||
814 | rb->lcd_clear_display(); | ||
815 | rb->lcd_puts_scroll(0, 0, "Programming..."); | ||
816 | |||
817 | rc = ProgramImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); | ||
818 | if (rc) | ||
819 | { /* errors */ | ||
820 | rb->lcd_clear_display(); | ||
821 | rb->snprintf(buf, sizeof(buf), "%d errors", rc); | ||
822 | rb->lcd_puts_scroll(0, 0, "Programming failed!"); | ||
823 | rb->lcd_puts_scroll(0, 1, buf); | ||
824 | button = WaitForButton(); | ||
825 | } | ||
826 | |||
827 | rb->lcd_clear_display(); | ||
828 | rb->lcd_puts_scroll(0, 0, "Verifying..."); | ||
829 | |||
830 | rc = VerifyImageFile(filename, pos, &ImageHeader, UCL_HEADER, true_size); | ||
831 | |||
832 | rb->lcd_clear_display(); | ||
833 | if (rc == 0) | ||
834 | { | ||
835 | rb->lcd_puts(0, 0, "Verify OK."); | ||
836 | } | ||
837 | else | ||
838 | { | ||
839 | rb->snprintf(buf, sizeof(buf), "Verify fail! %d errors", rc); | ||
840 | rb->lcd_puts_scroll(0, 0, buf); | ||
841 | rb->lcd_puts_scroll(0, 1, "Use safe image if booting hangs: [Menu] during power-on"); | ||
842 | button = WaitForButton(); | ||
843 | } | ||
665 | } | 844 | } |
666 | 845 | ||
846 | #endif /* not HAVE_LCD_BITMAP */ | ||
847 | |||
848 | |||
849 | |||
667 | /***************** Plugin Entry Point *****************/ | 850 | /***************** Plugin Entry Point *****************/ |
668 | 851 | ||
669 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | 852 | enum plugin_status plugin_start(struct plugin_api* api, void* parameter) |
670 | { | 853 | { |
671 | char* filename; | 854 | char* filename; |
855 | bool show_greet; | ||
672 | 856 | ||
673 | /* this macro should be called as the first thing you do in the plugin. | 857 | /* this macro should be called as the first thing you do in the plugin. |
674 | it test that the api version and model the plugin was compiled for | 858 | it test that the api version and model the plugin was compiled for |
@@ -676,18 +860,22 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter) | |||
676 | TEST_PLUGIN_API(api); | 860 | TEST_PLUGIN_API(api); |
677 | 861 | ||
678 | if (parameter == NULL) | 862 | if (parameter == NULL) |
863 | { | ||
679 | filename = DEFAULT_FILENAME; | 864 | filename = DEFAULT_FILENAME; |
865 | show_greet = true; | ||
866 | } | ||
680 | else | 867 | else |
868 | { | ||
681 | filename = (char*) parameter; | 869 | filename = (char*) parameter; |
870 | show_greet = false; | ||
871 | } | ||
682 | 872 | ||
683 | rb = api; /* copy to global api pointer */ | 873 | rb = api; /* copy to global api pointer */ |
684 | 874 | ||
685 | /* now go ahead and have fun! */ | 875 | /* now go ahead and have fun! */ |
686 | DoUserDialog(filename); | 876 | DoUserDialog(filename, show_greet); |
687 | 877 | ||
688 | return PLUGIN_OK; | 878 | return PLUGIN_OK; |
689 | } | 879 | } |
690 | 880 | ||
691 | #endif // #ifdef HAVE_LCD_BITMAP | 881 | #endif /* #ifndef SIMULATOR */ |
692 | |||
693 | #endif // #ifndef SIMULATOR | ||