Fix lock unlock
[romboot.git] / main.cpp
blobb2b53d52ae7ed64e9a8cf710079966510849dbec
1 //*----------------------------------------------------------------------------
2 //* ATMEL Microcontroller Software Support - ROUSSET -
3 //*----------------------------------------------------------------------------
4 //* The software is delivered "AS IS" without warranty or condition of any
5 //* kind, either express, implied or statutory. This includes without
6 //* limitation any warranty or condition with respect to merchantability or
7 //* fitness for any particular purpose, or against the infringements of
8 //* intellectual property rights of others.
9 //*----------------------------------------------------------------------------
10 //* File Name : main.c
11 //* Object :
12 //* Creation : HIi 10/10/2003
13 //*----------------------------------------------------------------------------
14 #include <AT91RM9200.h>
15 #include <lib_AT91RM9200.h>
17 #include "com.h"
18 #include "main.h"
19 #include "dataflash.h"
21 #define AT91C_UBOOT_ADDR 0x21F00000
22 #define AT91C_UBOOT_SIZE 512*1024
23 #define AT91C_UBOOT_DATAFLASH_ADDR 0xC0008400
25 // crystal= 18.432MHz
26 #define AT91C_PLLA_VALUE 0x20263E04 // -> 179.712MHz
27 #define AT91C_PLLA_MCK 0x0000202
29 // crystal= 20.000MHz
30 // #define AT91C_PLLA_VALUE 0x2023BE04 // -> 180MHz
31 // #define AT91C_PLLA_MCK 0x0000202
33 #define DELAY_MAIN_FREQ 1000
34 #define DISP_LINE_LEN 16
36 //* prototypes
37 extern void AT91F_DBGU_Printk(char *);
38 extern "C" void AT91F_ST_ASM_Handler(void);
39 extern "C" void Jump(unsigned int addr);
41 const char *menu_separ = "*----------------------------------------*\n\r";
43 const char *menu_dataflash = {
44 "1: Download Dataflash [addr]\n\r"
45 "2: Read Dataflash [addr]\n\r"
46 "3: Start U-BOOT\n\r"
47 "4: Clear bootloader section in Dataflash\n\r"
48 "5: Read Dram [addr]\n\r"
49 "6: Lock the flash\n\r"
50 "7: Unlock the flash\r\n"
51 "8: Read the lock register status of the flash\r\n"
54 //* Globales variables
55 char message[40];
56 volatile char XmodemComplete = 0;
57 unsigned int StTick;
59 AT91S_RomBoot const *pAT91;
60 AT91S_SBuffer sXmBuffer;
61 AT91S_SvcXmodem svcXmodem;
62 AT91S_Pipe xmodemPipe;
63 AT91S_CtlTempo ctlTempo;
64 AT91S_SvcTempo svcTempo; // Link to a AT91S_Tempo object
66 void switch_led();
68 //*--------------------------------------------------------------------------------------
69 //* Function Name : GetTickCount()
70 //* Object : Return the number of systimer tick
71 //* Input Parameters :
72 //* Output Parameters :
73 //*--------------------------------------------------------------------------------------
74 unsigned int GetTickCount(void)
76 return StTick;
80 //*--------------------------------------------------------------------------------------
81 //* Function Name : AT91_XmodemComplete()
82 //* Object : Perform the remap and jump to appli in RAM
83 //* Input Parameters :
84 //* Output Parameters :
85 //*--------------------------------------------------------------------------------------
86 void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid)
88 // stop the Xmodem tempo
89 svcXmodem.tempo.Stop(&(svcXmodem.tempo));
90 XmodemComplete = 1;
94 //*--------------------------------------------------------------------------------------
95 //* Function Name : AT91F_XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
96 //* Object : Xmodem dispatcher
97 //* Input Parameters :
98 //* Output Parameters :
99 //*--------------------------------------------------------------------------------------
100 void XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
102 AT91PS_SBuffer pSBuffer = (AT91PS_SBuffer) xmodemPipe.pBuffer->pChild;
103 AT91PS_USART pUsart = svcXmodem.pUsart;
105 if (pSBuffer->szRdBuffer == 0) {
106 // Start a tempo to wait the Xmodem protocol complete
107 svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, pUsart);
112 //*-------------------------- Interrupt handlers ----------------------------------------
113 //*--------------------------------------------------------------------------------------
114 //* Function Name : irq1_c_handler()
115 //* Object : C Interrupt handler for Interrutp source 1
116 //* Input Parameters : none
117 //* Output Parameters : none
118 //*--------------------------------------------------------------------------------------
119 extern "C" void AT91F_ST_Handler(void);
121 void AT91F_ST_Handler(void)
123 volatile unsigned int csr = *AT91C_DBGU_CSR;
124 unsigned int error;
126 /* ========== Systimer interrupt ============== */
127 if (AT91C_BASE_ST->ST_SR & 0x01) {
128 StTick++;
129 switch_led();
130 ctlTempo.CtlTempoTick(&ctlTempo);
131 return;
134 error = AT91F_US_Error((AT91PS_USART)AT91C_BASE_DBGU);
135 if (csr & error) {
136 // Stop previous Xmodem transmition
137 *(AT91C_DBGU_CR) = AT91C_US_RSTSTA;
138 AT91F_US_DisableIt((AT91PS_USART)AT91C_BASE_DBGU, AT91C_US_ENDRX);
139 AT91F_US_EnableIt((AT91PS_USART)AT91C_BASE_DBGU, AT91C_US_RXRDY);
143 else if (csr & (AT91C_US_TXRDY | AT91C_US_ENDTX | AT91C_US_TXEMPTY |
144 AT91C_US_RXRDY | AT91C_US_ENDRX | AT91C_US_TIMEOUT |
145 AT91C_US_RXBUFF)) {
146 if ( !(svcXmodem.eot) )
147 svcXmodem.Handler(&svcXmodem, csr);
152 //*-----------------------------------------------------------------------------
153 //* Function Name : AT91F_DisplayMenu()
154 //* Object :
155 //* Input Parameters :
156 //* Return value :
157 //*-----------------------------------------------------------------------------
158 void AT91F_DisplayMenu(void)
160 printf("\n\rATMEL LOADER %s %s %s\n\r", AT91C_VERSION, __DATE__, __TIME__);
161 printf(menu_separ);
162 AT91F_DataflashPrintInfo();
163 printf(menu_separ);
164 printf(menu_dataflash);
165 printf(menu_separ);
168 //*-----------------------------------------------------------------------------
169 //* Function Name : AsciiToHex()
170 //* Object : ascii to hexa conversion
171 //* Input Parameters :
172 //* Return value :
173 //*-----------------------------------------------------------------------------
174 unsigned int AsciiToHex(char *s, unsigned int *val)
176 int n;
178 *val=0;
180 if(s[0] == '0' && ((s[1] == 'x') || (s[1] == 'X')))
181 s+=2;
182 n = 0;
183 while((n < 8) && (s[n] !=0))
185 *val <<= 4;
186 if ( (s[n] >= '0') && (s[n] <='9'))
187 *val += (s[n] - '0');
188 else
189 if ((s[n] >= 'a') && (s[n] <='f'))
190 *val += (s[n] - 0x57);
191 else
192 if ((s[n] >= 'A') && (s[n] <='F'))
193 *val += (s[n] - 0x37);
194 else
195 return 0;
196 n++;
199 return 1;
203 //*-----------------------------------------------------------------------------
204 //* Function Name : AT91F_MemoryDisplay()
205 //* Object : Display the content of the dataflash
206 //* Input Parameters :
207 //* Return value :
208 //*-----------------------------------------------------------------------------
209 int AT91F_MemoryDisplay(unsigned int addr, unsigned int size, unsigned int length)
211 unsigned long i, nbytes, linebytes;
212 char *cp;
213 unsigned int *uip;
214 unsigned short *usp;
215 unsigned char *ucp;
216 char linebuf[DISP_LINE_LEN];
218 nbytes = length * size;
221 uip = (unsigned int *)linebuf;
222 usp = (unsigned short *)linebuf;
223 ucp = (unsigned char *)linebuf;
225 printf("%08x:", addr);
226 linebytes = (nbytes > DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
228 read_dataflash(addr, (linebytes/size)*size, linebuf);
229 for (i=0; i<linebytes; i+= size)
231 if (size == 4)
232 printf(" %08x", *uip++);
233 else if (size == 2)
234 printf(" %04x", *usp++);
235 else
236 printf(" %02x", *ucp++);
237 addr += size;
239 printf(" ");
240 cp = linebuf;
241 for (i=0; i<linebytes; i++) {
242 if ((*cp < 0x20) || (*cp > 0x7e))
243 printf(".");
244 else
245 printf("%c", *cp);
246 cp++;
248 printf("\n\r");
249 nbytes -= linebytes;
250 } while (nbytes > 0);
251 return 0;
254 //*-----------------------------------------------------------------------------
255 //* Function Name : AT91F_DramDisplay()
256 //* Object : Display the content of the sdram
257 //* Input Parameters :
258 //* Return value :
259 //*-----------------------------------------------------------------------------
260 int AT91F_SdramDisplay(unsigned int addr, unsigned int size, unsigned int length)
262 unsigned long i, nbytes, linebytes;
263 char *cp;
264 unsigned int *uip;
265 unsigned short *usp;
266 unsigned char *ucp;
268 nbytes = length * size;
271 uip = (unsigned int *)addr;
272 usp = (unsigned short *)addr;
273 ucp = (unsigned char *)addr;
275 printf("%08x:", addr);
276 linebytes = (nbytes > DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
278 for (i=0; i<linebytes; i+= size)
280 if (size == 4)
281 printf(" %08x", *uip++);
282 else if (size == 2)
283 printf(" %04x", *usp++);
284 else
285 printf(" %02x", *ucp++);
286 addr += size;
288 printf(" ");
289 for (i=0; i<linebytes; i++) {
290 if ((*cp < 0x20) || (*cp > 0x7e))
291 printf(".");
292 else
293 printf("%c", *cp);
294 cp++;
296 printf("\n\r");
297 nbytes -= linebytes;
298 } while (nbytes > 0);
299 return 0;
303 //*--------------------------------------------------------------------------------------
304 //* Function Name : AT91F_SetPLL
305 //* Object : Set the PLLA to 180Mhz and Master clock to 60 Mhz
306 //* Input Parameters :
307 //* Output Parameters :
308 //*--------------------------------------------------------------------------------------
309 void AT91F_SetPLL(void)
311 volatile int tmp = 0;
313 AT91PS_PMC pPmc = AT91C_BASE_PMC;
314 AT91PS_CKGR pCkgr = AT91C_BASE_CKGR;
316 pPmc->PMC_IDR = 0xFFFFFFFF;
318 //* -Setup the PLL A
319 pCkgr->CKGR_PLLAR = AT91C_PLLA_VALUE;
321 while(!(pPmc->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY_MAIN_FREQ));
323 //* - Commuting Master Clock from PLLB to PLLA/3
324 pPmc->PMC_MCKR = AT91C_PLLA_MCK;
328 //*--------------------------------------------------------------------------------------
329 //* Function Name : AT91F_ResetRegisters
330 //* Object : Restore the initial state to registers
331 //* Input Parameters :
332 //* Output Parameters :
333 //*--------------------------------------------------------------------------------------
334 static void AT91F_ResetRegisters(void)
336 volatile int i = 0;
338 //* set the PIOs in input
339 *AT91C_PIOA_ODR = 0xFFFFFFFF; /* Disables all the output pins */
340 *AT91C_PIOA_PER = 0xFFFFFFFF; /* Enables the PIO to control all the pins */
342 AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SYS);
344 /* close all peripheral clocks */
345 AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFC;
347 //* Disable core interrupts and set supervisor mode
348 __asm__ ("msr CPSR_c, #0xDF"); //* ARM_MODE_SYS(0x1F) | I_BIT(0x80) | F_BIT(0x40)
350 //* Clear all the interrupts
351 *AT91C_AIC_ICCR = 0xffffffff;
353 /* read the AIC_IVR and AIC_FVR */
354 i = *AT91C_AIC_IVR;
355 i = *AT91C_AIC_FVR;
357 /* write the end of interrupt control register */
358 *AT91C_AIC_EOICR = 0;
360 AT91F_SetPLL();
363 void AT91F_StartUboot(unsigned int dummy, void *pvoid)
365 printf("Load U-BOOT from dataflash[%x] to SDRAM[%x]\n\r", AT91C_UBOOT_DATAFLASH_ADDR, AT91C_UBOOT_ADDR);
366 read_dataflash(AT91C_UBOOT_DATAFLASH_ADDR, AT91C_UBOOT_SIZE, (char *)(AT91C_UBOOT_ADDR));
367 printf("Set PLLA to 180Mhz and Master clock to 60Mhz and start U-BOOT\n\r");
368 //* Reset registers
369 AT91F_ResetRegisters();
370 Jump(AT91C_UBOOT_ADDR);
371 while(1);
374 void turn_led_off()
376 *AT91C_PIOD_ODR = AT91C_PIO_PD6; /* Disables all the output pins */
377 *AT91C_PIOD_PER = AT91C_PIO_PD6; /* Enables the PIO to control all the pins */
378 *AT91C_PIOD_OER = AT91C_PIO_PD6; /* Enables the PIO to control all the pins */
379 *AT91C_PIOD_SODR = AT91C_PIO_PD6; /* Enables the PIO to control all the pins */
382 void turn_led_on()
384 *AT91C_PIOD_ODR = AT91C_PIO_PD6; /* Disables all the output pins */
385 *AT91C_PIOD_PER = AT91C_PIO_PD6; /* Enables the PIO to control all the pins */
386 *AT91C_PIOD_OER = AT91C_PIO_PD6; /* Enables the PIO to control all the pins */
387 *AT91C_PIOD_CODR = AT91C_PIO_PD6; /* Enables the PIO to control all the pins */
390 #define ILIM0 0
391 #define ILIM1 100
392 #define ILIM2 200
393 int cnt=0;
394 void switch_led()
396 switch ( cnt)
398 case ILIM0 :
400 turn_led_on();
401 cnt++;
402 break;
405 case ILIM1:
407 turn_led_off();
408 cnt++;
409 break;
411 case ILIM2:
413 cnt = ILIM0;
414 break;
416 default:
418 cnt++;
419 break;
424 AT91S_DataflashDesc desc;
426 unsigned char read_lock_cmd[4]=
428 0x32,0x00,0x00,0x00
431 void clear_desc( AT91S_DataflashDesc *d)
433 d->tx_cmd_pt = 0;
434 d->rx_cmd_pt = 0;
435 d->tx_cmd_size = 0;
436 d->rx_cmd_size = 0;
437 d->tx_data_size = 0;
438 d->rx_data_size = 0;
439 d->tx_data_pt = 0;
440 d->rx_data_pt = 0;
441 d->state = 0;
442 d->DataFlash_state = 0;
443 d->command[0] = 0;
444 d->command[1] = 0;
445 d->command[2] = 0;
446 d->command[3] = 0;
447 d->command[4] = 0;
448 d->command[5] = 0;
449 d->command[6] = 0;
450 d->command[7] = 0;
453 void read_lock_reg()
455 int i;
456 unsigned char rx[33];
458 clear_desc(&desc);
459 rx[0] = 0x8;
460 desc.tx_cmd_pt = read_lock_cmd;
461 desc.rx_cmd_pt = rx;
462 desc.tx_cmd_size = 4;
463 desc.rx_cmd_size = 4;
464 desc.tx_data_size = 32;
465 desc.rx_data_size = 32;
466 desc.tx_data_pt = rx;
467 desc.rx_data_pt = rx;
469 AT91F_SpiWrite(&desc);
470 printf("Lock status = \r\n");
471 for ( i = 0 ; i < 16 ; i++ )
473 printf("0x%02x:",rx[i]);
475 for ( i = 16 ; i < 32 ; i++ )
477 printf("0x%02x:",rx[i]);
481 unsigned char clear_lock_cmd[4]=
483 0x3D,0x2A,0x7F,0xCF
486 void clear_lock_reg()
488 int i;
489 unsigned char rx[33];
490 for ( i = 0 ; i < 32 ; i++)
492 rx[i] = 0;
495 clear_desc(&desc);
497 desc.tx_cmd_pt = clear_lock_cmd;
498 desc.rx_cmd_pt = rx;
499 desc.tx_cmd_size = 4;
500 desc.rx_cmd_size = 4;
501 AT91F_SpiWrite(&desc);
502 read_lock_reg();
505 unsigned char lock_unlock_cmd[4]=
507 0x3D,0x2A,0x7F,0xFC
510 unsigned char enable_lock_unlock_cmd[4]=
512 0x3D,0x2A,0x7F,0xA9
515 unsigned char disable_lock_unlock_cmd[4]=
517 0x3D,0x2A,0x7F,0x9A
519 void flash_lock_reg()
521 unsigned char rxf[4];
522 unsigned char rx[33];
523 int i;
525 clear_lock_reg();
527 clear_desc(&desc);
529 desc.tx_cmd_pt = enable_lock_unlock_cmd;
530 desc.rx_cmd_pt = rxf;
531 desc.tx_cmd_size = 4;
532 desc.rx_cmd_size = 4;
534 AT91F_SpiWrite(&desc);
535 clear_desc(&desc);
537 for ( i = 0 ; i < 32 ; i++)
539 rx[i] = 0xff;
541 desc.tx_cmd_pt = lock_unlock_cmd;
542 desc.rx_cmd_pt = rxf;
543 desc.tx_cmd_size = 4;
544 desc.rx_cmd_size = 4;
545 desc.tx_data_size = 32;
546 desc.rx_data_size = 32;
547 desc.tx_data_pt = rx;
548 desc.rx_data_pt = rx;
550 AT91F_SpiWrite(&desc);
555 void flash_unlock_reg()
557 int i;
558 unsigned char rxf[4];
559 unsigned char rx[33];
561 clear_desc(&desc);
563 for ( i = 0 ; i < 32 ; i++)
565 rx[i] = 0;
568 desc.tx_cmd_pt = lock_unlock_cmd;
569 desc.rx_cmd_pt = rxf;
570 desc.tx_cmd_size = 4;
571 desc.rx_cmd_size = 4;
572 desc.tx_data_size = 32;
573 desc.rx_data_size = 32;
574 desc.tx_data_pt = rx;
575 desc.rx_data_pt = rx;
577 AT91F_SpiWrite(&desc);
579 clear_desc(&desc);
581 desc.tx_cmd_pt = disable_lock_unlock_cmd;
582 desc.rx_cmd_pt = rxf;
583 desc.tx_cmd_size = 4;
584 desc.rx_cmd_size = 4;
586 AT91F_SpiWrite(&desc);
590 //*----------------------------------------------------------------------------
591 //* Function Name : main
592 //* Object : Main function
593 //* Input Parameters : none
594 //* Output Parameters : True
595 //*----------------------------------------------------------------------------
596 int main(void)
598 AT91PS_Buffer pXmBuffer;
599 AT91PS_SvcComm pSvcXmodem;
600 AT91S_SvcTempo svcUbootTempo; // Link to a AT91S_Tempo object
602 unsigned int AddressToDownload, SizeToDownload;
603 unsigned int DeviceAddress = 0;
604 volatile int i = 0;
605 char command = 0;
606 unsigned int crc1 = 0, crc2 = 0;
607 volatile int device;
608 int NbPage;
610 stdin = fopen(0, at91_dbgu_getc);
611 stdout = fopen(at91_dbgu_putc, 0);
613 pAT91 = AT91C_ROM_BOOT_ADDRESS;
615 // Tempo Initialisation
616 pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC));
617 ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC));
619 // Attach the tempo to a tempo controler
620 ctlTempo.CtlTempoCreate(&ctlTempo, &svcUbootTempo);
622 // Xmodem Initialisation
623 pXmBuffer = pAT91->OpenSBuffer(&sXmBuffer);
624 pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem, (AT91PS_USART)AT91C_BASE_DBGU, &ctlTempo);
625 pAT91->OpenPipe(&xmodemPipe, pSvcXmodem, pXmBuffer);
627 //* System Timer initialization
628 AT91F_AIC_ConfigureIt (
629 AT91C_BASE_AIC, // AIC base address
630 AT91C_ID_SYS, // System peripheral ID
631 AT91C_AIC_PRIOR_HIGHEST, // Max priority
632 AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive
633 AT91F_ST_ASM_Handler );
634 //* Enable ST interrupt
635 AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
637 // DataFlash on SPI Configuration
638 AT91F_DataflashInit ();
640 // start tempo to start Uboot in a delay of 1 sec if no key pressed
641 svcUbootTempo.Start(&svcUbootTempo, 200, 0, AT91F_StartUboot, (void *)0);
643 printf("press any key to enter bootloader\n\r");
644 getc();
646 // stop tempo
647 svcUbootTempo.Stop(&svcUbootTempo);
649 while(1)
651 while(command == 0)
653 AddressToDownload = AT91C_DOWNLOAD_BASE_ADDRESS;
654 SizeToDownload = AT91C_DOWNLOAD_MAX_SIZE;
655 DeviceAddress = 0;
657 AT91F_DisplayMenu();
658 message[0] = 0;
659 message[2] = 0;
660 AT91F_ReadLine("Enter: ", message);
662 command = message[0];
663 if(command == '1' || command == '2' || command == '5' )
664 if(AsciiToHex(&message[2], &DeviceAddress) == 0)
665 command = 0;
667 switch(command)
669 case '1':
670 printf("Download Dataflash [0x%x]\n\r", DeviceAddress);
672 switch(DeviceAddress & 0xFF000000)
674 case CFG_DATAFLASH_LOGIC_ADDR_CS0:
675 device = 0;
676 break;
678 case CFG_DATAFLASH_LOGIC_ADDR_CS3:
679 device = 1;
680 break;
682 default:
683 command = 0;
684 break;
686 break;
688 case '2':
691 AT91F_MemoryDisplay(DeviceAddress, 4, 64);
692 AT91F_ReadLine ((char *)0, message);
693 DeviceAddress += 0x100;
695 while(message[0] == '\0');
696 command = 0;
697 break;
699 case '3':
700 AT91F_StartUboot(0, (void *)0);
701 command = 0;
702 break;
703 case '4':
705 int *i;
706 for(i = (int *)0x20000000; i < (int *)0x20004000; i++)
707 *i = 0;
709 write_dataflash(0xc0000000, 0x20000000, 0x4000);
710 printf("Bootsection cleared\r\n");
711 command = 0;
712 break;
713 case '5':
716 AT91F_SdramDisplay(DeviceAddress, 4, 64);
717 AT91F_ReadLine ((char *)0, message);
718 DeviceAddress += 0x100;
720 while(message[0] == '\0');
721 command = 0;
722 break;
723 case '6':
725 flash_lock_reg();
726 command = 0;
727 break;
729 case '7':
731 flash_unlock_reg();
732 command = 0;
733 break;
735 case '8':
737 read_lock_reg();
738 command = 0;
739 break;
741 case '9':
743 clear_lock_reg();
744 command = 0;
745 break;
748 default:
749 command = 0;
750 break;
754 xmodemPipe.Read(&xmodemPipe, (char *)AddressToDownload, SizeToDownload, XmodemProtocol, 0);
755 while(XmodemComplete !=1);
756 SizeToDownload = (unsigned int)(svcXmodem.pData) - (unsigned int)AddressToDownload;
758 // Modification of vector 6
759 NbPage = 0;
760 i = dataflash_info[device].Device.pages_number;
761 while(i >>= 1)
762 NbPage++;
763 i = (SizeToDownload / 512) + 1 + (NbPage << 13) + (dataflash_info[device].Device.pages_size << 17);
764 *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) = i;
766 printf("\n\rModification of Arm Vector 6 :%x\n\r", i);
768 printf("\n\rWrite %d bytes in DataFlash [0x%x]\n\r",SizeToDownload, DeviceAddress);
769 crc1 = 0;
770 pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc1);
772 // write the dataflash
773 write_dataflash (DeviceAddress, AddressToDownload, SizeToDownload);
774 // clear the buffer before read
775 for(i=0; i < SizeToDownload; i++)
776 *(unsigned char *)(AddressToDownload + i) = 0;
778 //* Read dataflash page in TestBuffer
779 read_dataflash (DeviceAddress, SizeToDownload, (char *)(AddressToDownload));
781 printf("Verify Dataflash: ");
782 crc2 = 0;
784 pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc2);
785 if (crc1 != crc2)
786 printf("Failed\r\n");
787 else
788 printf("OK\r\n");
790 command = 0;
791 XmodemComplete = 0;
792 AT91F_WaitKeyPressed();