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 *----------------------------------------------------------------------------
12 * Creation : HIi 10/10/2003
13 * Modif : HIi 15/06/2004 : add crc32 to verify the download
15 * : HIi 21/09/2004 : Set first PLLA to 180Mhz and MCK to
16 * 60Mhz to speed up dataflash boot (15Mhz)
17 * : MLC 12/04/2005 : Modify SetPLL() to avoid errata
18 * : USA 30/12/2005 : Change to page Size 1056
19 * Change startaddress to C0008400
20 * Change SPI Speed to ~4 Mhz
21 * Add retry on CRC Error
22 *----------------------------------------------------------------------------
26 #include "AT91RM9200.h"
27 #include "lib_AT91RM9200.h"
30 #include "dataflash.h"
31 #include "AT91C_MCI_Device.h"
43 #define AT91C_SDRAM_START 0x20000000
44 #define AT91C_BOOT_ADDR 0x21F00000
45 #define AT91C_BOOT_SIZE 128*PAGESIZE
47 #define AT91C_BOOT_DATAFLASH_ADDR 0xC0008400
49 #define AT91C_BOOT_DATAFLASH_ADDR 0xC0008000
51 #define AT91C_PLLA_VALUE 0x237A3E5A // crystal= 18.432MHz - fixes BRG error at 115kbps
52 //#define AT91C_PLLA_VALUE 0x2026BE04 // crystal= 18.432MHz
53 //#define AT91C_PLLA_VALUE 0x202CBE01 // crystal= 4MHz
57 #define DISP_LINE_LEN 16
59 // Reason for boot failure
60 #define IMAGE_BAD_SIZE 0
61 #define IMAGE_READ_FAILURE 1
62 #define IMAGE_CRC_ERROR 2
67 extern void AT91F_ST_ASM_HANDLER(void);
68 extern void Jump(unsigned int addr
);
70 const char *menu_dataflash
[] = {
95 volatile char XmodemComplete
= 0;
97 unsigned int StTick
= 0;
99 AT91S_RomBoot
const *pAT91
;
101 AT91S_SBuffer sXmBuffer
;
102 AT91S_SvcXmodem svcXmodem
;
103 AT91S_Pipe xmodemPipe
;
105 AT91S_CtlTempo ctlTempo
;
108 //*--------------------------------------------------------------------------------------
109 //* Function Name : GetTickCount()
110 //* Object : Return the number of systimer tick
111 //* Input Parameters :
112 //* Output Parameters :
113 //*--------------------------------------------------------------------------------------
114 unsigned int GetTickCount(void)
120 //*--------------------------------------------------------------------------------------
121 //* Function Name : AT91_XmodemComplete()
122 //* Object : Perform the remap and jump to appli in RAM
123 //* Input Parameters :
124 //* Output Parameters :
125 //*--------------------------------------------------------------------------------------
126 static void AT91_XmodemComplete(AT91S_PipeStatus status
, void *pVoid
)
128 /* stop the Xmodem tempo */
129 svcXmodem
.tempo
.Stop(&(svcXmodem
.tempo
));
134 //*--------------------------------------------------------------------------------------
135 //* Function Name : AT91F_XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
136 //* Object : Xmodem dispatcher
137 //* Input Parameters :
138 //* Output Parameters :
139 //*--------------------------------------------------------------------------------------
140 static void XmodemProtocol(AT91S_PipeStatus status
, void *pVoid
)
142 AT91PS_SBuffer pSBuffer
= (AT91PS_SBuffer
) xmodemPipe
.pBuffer
->pChild
;
143 AT91PS_USART pUsart
= svcXmodem
.pUsart
;
145 if (pSBuffer
->szRdBuffer
== 0) {
146 /* Start a tempo to wait the Xmodem protocol complete */
147 svcXmodem
.tempo
.Start(&(svcXmodem
.tempo
), 10, 0, AT91_XmodemComplete
, pUsart
);
152 //*--------------------------------------------------------------------------------------
153 //* Function Name : irq1_c_handler()
154 //* Object : C Interrupt handler for Interrutp source 1
155 //* Input Parameters : none
156 //* Output Parameters : none
157 //*--------------------------------------------------------------------------------------
158 void AT91F_ST_HANDLER(void)
160 volatile unsigned int csr
= *AT91C_DBGU_CSR
;
165 if (AT91C_BASE_ST
->ST_SR
& 0x01) {
167 ctlTempo
.CtlTempoTick(&ctlTempo
);
172 error
= AT91F_US_Error((AT91PS_USART
)AT91C_BASE_DBGU
);
174 /* Stop previous Xmodem transmition*/
175 *(AT91C_DBGU_CR
) = AT91C_US_RSTSTA
;
176 AT91F_US_DisableIt((AT91PS_USART
)AT91C_BASE_DBGU
, AT91C_US_ENDRX
);
177 AT91F_US_EnableIt((AT91PS_USART
)AT91C_BASE_DBGU
, AT91C_US_RXRDY
);
181 else if (csr
& (AT91C_US_TXRDY
| AT91C_US_ENDTX
| AT91C_US_TXEMPTY
|
182 AT91C_US_RXRDY
| AT91C_US_ENDRX
| AT91C_US_TIMEOUT
|
184 if ( !(svcXmodem
.eot
) )
185 svcXmodem
.Handler(&svcXmodem
, csr
);
191 //*-----------------------------------------------------------------------------
192 //* Function Name : AT91F_DisplayMenu()
194 //* Input Parameters :
196 //*-----------------------------------------------------------------------------
197 static int AT91F_DisplayMenu(void)
199 int i
, mci_present
= 0;
200 printf("\nDF LOADER %s %s %s\n",AT91C_VERSION
,__DATE__
,__TIME__
);
201 AT91F_DataflashPrintInfo();
202 mci_present
= AT91F_MCI_Init();
203 for(i
= 0; i
< MAXMENU
; i
++) {
204 puts(menu_dataflash
[i
]);
210 //*-----------------------------------------------------------------------------
211 //* Function Name : AsciiToHex()
212 //* Object : ascii to hexa conversion
213 //* Input Parameters :
215 //*-----------------------------------------------------------------------------
216 static unsigned int AsciiToHex(char *s
, unsigned int *val
)
222 if(s
[0] == '0' && ((s
[1] == 'x') || (s
[1] == 'X')))
225 while((n
< 8) && (s
[n
] !=0))
228 if ( (s
[n
] >= '0') && (s
[n
] <='9'))
229 *val
+= (s
[n
] - '0');
231 if ((s
[n
] >= 'a') && (s
[n
] <='f'))
232 *val
+= (s
[n
] - 0x57);
234 if ((s
[n
] >= 'A') && (s
[n
] <='F'))
235 *val
+= (s
[n
] - 0x37);
246 //*-----------------------------------------------------------------------------
247 //* Function Name : AT91F_MemoryDisplay()
248 //* Object : Display the content of the dataflash
249 //* Input Parameters :
251 //*-----------------------------------------------------------------------------
252 static int AT91F_MemoryDisplay(unsigned int addr
, unsigned int length
)
254 unsigned long i
, nbytes
, linebytes
;
256 // unsigned int *uip;
257 // unsigned short *usp;
259 char linebuf
[DISP_LINE_LEN
];
261 // nbytes = length * size;
265 // uip = (unsigned int *)linebuf;
266 // usp = (unsigned short *)linebuf;
267 ucp
= (unsigned char *)linebuf
;
269 printf("%08x:", addr
);
270 linebytes
= (nbytes
> DISP_LINE_LEN
)?DISP_LINE_LEN
:nbytes
;
271 if((addr
& 0xF0000000) == 0x20000000) {
272 for(i
= 0; i
< linebytes
; i
++) {
273 linebuf
[i
] = *(char *)(addr
+i
);
276 read_dataflash(addr
, linebytes
, linebuf
);
278 for (i
=0; i
<linebytes
; i
++)
281 printf(" %08x", *uip++);
283 printf(" %04x", *usp++);
286 printf(" %02x", *ucp
++);
292 for (i
=0; i
<linebytes
; i
++) {
293 if ((*cp
< 0x20) || (*cp
> 0x7e))
301 } while (nbytes
> 0);
306 //*--------------------------------------------------------------------------------------
307 //* Function Name : AT91F_SetPLL
308 //* Object : Set the PLLA to 180Mhz and Master clock to 60 Mhz
309 //* Input Parameters :
310 //* Output Parameters :
311 //*--------------------------------------------------------------------------------------
312 static unsigned int AT91F_SetPLL(void)
315 AT91PS_PMC pPmc
= AT91C_BASE_PMC
;
316 AT91PS_CKGR pCkgr
= AT91C_BASE_CKGR
;
318 pPmc
->PMC_IDR
= 0xFFFFFFFF;
320 /* -Setup the PLL A */
321 pCkgr
->CKGR_PLLAR
= AT91C_PLLA_VALUE
;
323 while (!(*AT91C_PMC_SR
& AT91C_PMC_LOCKA
));
325 /* - Switch Master Clock from PLLB to PLLA/3 */
326 tmp
= pPmc
->PMC_MCKR
;
327 /* See Atmel Errata #27 and #28 */
328 if (tmp
& 0x0000001C) {
329 tmp
= (tmp
& ~0x0000001C);
330 pPmc
->PMC_MCKR
= tmp
;
331 while (!(*AT91C_PMC_SR
& AT91C_PMC_MCKRDY
));
333 if (tmp
!= 0x00000202) {
334 pPmc
->PMC_MCKR
= 0x00000202;
335 if ((tmp
& 0x00000003) != 0x00000002)
336 while (!(*AT91C_PMC_SR
& AT91C_PMC_MCKRDY
));
343 //*--------------------------------------------------------------------------------------
344 //* Function Name : AT91F_ResetRegisters
345 //* Object : Restore the initial state to registers
346 //* Input Parameters :
347 //* Output Parameters :
348 //*--------------------------------------------------------------------------------------
349 static unsigned int AT91F_ResetRegisters(void)
353 /* set the PIOs in input*/
354 /* This disables the UART output, so dont execute for now*/
357 *AT91C_PIOA_ODR
= 0xFFFFFFFF; /* Disables all the output pins */
358 *AT91C_PIOA_PER
= 0xFFFFFFFF; /* Enables the PIO to control all the pins */
361 AT91F_AIC_DisableIt (AT91C_BASE_AIC
, AT91C_ID_SYS
);
362 /* close all peripheral clocks */
365 AT91C_BASE_PMC
->PMC_PCDR
= 0xFFFFFFFC;
367 /* Disable core interrupts and set supervisor mode */
368 __asm__ ("msr CPSR_c, #0xDF"); //* ARM_MODE_SYS(0x1F) | I_BIT(0x80) | F_BIT(0x40)
369 /* Clear all the interrupts */
370 *AT91C_AIC_ICCR
= 0xffffffff;
372 /* read the AIC_IVR and AIC_FVR */
376 /* write the end of interrupt control register */
377 *AT91C_AIC_EOICR
= 0;
383 static int AT91F_LoadBoot(void)
385 // volatile unsigned int crc1 = 0, crc2 = 0;
386 volatile unsigned int SizeToDownload
= 0x21400;
387 volatile unsigned int AddressToDownload
= AT91C_BOOT_ADDR
;
390 /* Read vector 6 to extract size to load */
391 if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR
, 32,
392 (char *)AddressToDownload
) != AT91C_DATAFLASH_OK
)
394 printf("Bad Code Size\n");
395 return IMAGE_BAD_SIZE
;
397 /* calculate the size to download */
398 SizeToDownload
= *(int *)(AddressToDownload
+ AT91C_OFFSET_VECT6
);
401 // printf("\nLoad UBOOT from dataflash[%x] to SDRAM[%x]\n",
402 // AT91C_BOOT_DATAFLASH_ADDR, AT91C_BOOT_ADDR);
403 if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR
, SizeToDownload
+ 8,
404 (char *)AddressToDownload
) != AT91C_DATAFLASH_OK
)
407 return IMAGE_READ_FAILURE
;
410 pAT91
->CRC32((const unsigned char *)AT91C_BOOT_ADDR
,
411 (unsigned int)SizeToDownload
, (unsigned int *)&crc2
);
412 crc1
= (int)(*(char *)(AddressToDownload
+ SizeToDownload
)) +
413 (int)(*(char *)(AddressToDownload
+ SizeToDownload
+ 1) << 8) +
414 (int)(*(char *)(AddressToDownload
+ SizeToDownload
+ 2) << 16) +
415 (int)(*(char *)(AddressToDownload
+ SizeToDownload
+ 3) << 24);
417 /* Restore the value of Vector 6 */
418 *(int *)(AddressToDownload
+ AT91C_OFFSET_VECT6
) =
419 *(int *)(AddressToDownload
+ SizeToDownload
+ 4);
422 printf("DF CRC bad %x != %x\n",crc1
,crc2
);
423 return IMAGE_CRC_ERROR
;
429 static int AT91F_StartBoot(void)
432 if((sts
= AT91F_LoadBoot()) != SUCCESS
) return sts
;
434 // printf("PLLA[180MHz], MCK[60Mhz] ==> Start UBOOT\n");
435 if (AT91F_ResetRegisters())
438 Jump(AT91C_BOOT_ADDR
);
445 static void AT91F_RepeatedStartBoot(void)
448 for(i
= 0; i
< CRC_RETRIES
; i
++) {
449 if(AT91F_StartBoot() != IMAGE_CRC_ERROR
){
460 #define TRX_MAGIC 0x30524448 /* "HDR0" */
461 #define TRX_VERSION 1
467 unsigned int flag_version
;
468 unsigned int offsets
[3];
471 #define AT91C_MCI_TIMEOUT 1000000
473 extern AT91S_MciDevice MCI_Device
;
474 extern void AT91F_MCIDeviceWaitReady(unsigned int);
475 extern int AT91F_MCI_ReadBlockSwab(AT91PS_MciDevice
, int, unsigned int *, int);
477 int Program_From_MCI(void)
480 unsigned int Max_Read_DataBlock_Length
;
482 int buffer
= AT91C_DOWNLOAD_BASE_ADDRESS
;
483 int bufpos
= AT91C_DOWNLOAD_BASE_ADDRESS
;
485 struct trx_header
*p
;
487 p
= (struct trx_header
*)bufpos
;
489 Max_Read_DataBlock_Length
= MCI_Device
.pMCI_DeviceFeatures
->Max_Read_DataBlock_Length
;
491 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT
);
493 AT91F_MCI_ReadBlockSwab(&MCI_Device
, block
*Max_Read_DataBlock_Length
, (unsigned int *)bufpos
, Max_Read_DataBlock_Length
);
495 if (p
->magic
!= TRX_MAGIC
) {
496 printf("Inv IMG 0x%08x\n", p
->magic
);
501 AT91C_BASE_PIOC
->PIO_CODR
= AT91C_PIO_PC7
| AT91C_PIO_PC15
| AT91C_PIO_PC8
| AT91C_PIO_PC14
;
502 for (i
=0; i
<(p
->len
/512); i
++) {
503 AT91F_MCI_ReadBlockSwab(&MCI_Device
, block
*Max_Read_DataBlock_Length
, (unsigned int *)bufpos
, Max_Read_DataBlock_Length
);
505 bufpos
+= Max_Read_DataBlock_Length
;
509 i
= dataflash_info
[0].Device
.pages_number
;
512 i
= ((p
->offsets
[1] - p
->offsets
[0])/ 512) + 1 + (NbPage
<< 13) + (dataflash_info
[0].Device
.pages_size
<< 17);
513 *(int *)(buffer
+ p
->offsets
[0] + AT91C_OFFSET_VECT6
) = i
;
516 AT91C_BASE_PIOC
->PIO_CODR
= AT91C_PIO_PC7
| AT91C_PIO_PC15
| AT91C_PIO_PC14
;
517 AT91C_BASE_PIOC
->PIO_SODR
= AT91C_PIO_PC8
;
518 write_dataflash(0xc0000000, buffer
+ p
->offsets
[0], p
->offsets
[1] - p
->offsets
[0]);
520 AT91C_BASE_PIOC
->PIO_CODR
= AT91C_PIO_PC7
| AT91C_PIO_PC15
;
521 AT91C_BASE_PIOC
->PIO_SODR
= AT91C_PIO_PC8
| AT91C_PIO_PC14
;
522 write_dataflash(0xc0008000, buffer
+ p
->offsets
[1], p
->offsets
[2] - p
->offsets
[1]);
524 AT91C_BASE_PIOC
->PIO_CODR
= AT91C_PIO_PC8
| AT91C_PIO_PC15
;
525 AT91C_BASE_PIOC
->PIO_SODR
= AT91C_PIO_PC7
| AT91C_PIO_PC14
;
526 write_dataflash(0xc0042000, buffer
+ p
->offsets
[2], p
->len
- p
->offsets
[2]);
527 AT91C_BASE_PIOC
->PIO_CODR
= AT91C_PIO_PC8
| AT91C_PIO_PC14
;
528 AT91C_BASE_PIOC
->PIO_SODR
= AT91C_PIO_PC7
| AT91C_PIO_PC15
;
532 //*----------------------------------------------------------------------------
533 //* Function Name : main
534 //* Object : Main function
535 //* Input Parameters : none
536 //* Output Parameters : True
537 //*----------------------------------------------------------------------------
541 AT91PS_Buffer pXmBuffer
;
542 AT91PS_SvcComm pSvcXmodem
;
544 AT91S_SvcTempo svcBootTempo
; // Link to a AT91S_Tempo object
546 volatile unsigned int AddressToDownload
, SizeToDownload
;
547 unsigned int DeviceAddress
= 0;
551 unsigned int crc1
= 0, crc2
= 0;
555 volatile int Nb_Device
= 0;
558 pAT91
= AT91C_ROM_BOOT_ADDRESS
;
568 /* Tempo Initialisation */
569 pAT91
->OpenCtlTempo(&ctlTempo
, (void *) &(pAT91
->SYSTIMER_DESC
));
570 ctlTempo
.CtlTempoStart((void *) &(pAT91
->SYSTIMER_DESC
));
572 // Attach the tempo to a tempo controler
573 ctlTempo
.CtlTempoCreate(&ctlTempo
, &svcBootTempo
);
578 /* Xmodem Initialisation */
579 pXmBuffer
= pAT91
->OpenSBuffer(&sXmBuffer
);
580 pSvcXmodem
= pAT91
->OpenSvcXmodem(&svcXmodem
,
581 (AT91PS_USART
)AT91C_BASE_DBGU
, &ctlTempo
);
582 pAT91
->OpenPipe(&xmodemPipe
, pSvcXmodem
, pXmBuffer
);
585 /* System Timer initialization */
586 AT91F_AIC_ConfigureIt(
587 AT91C_BASE_AIC
, // AIC base address
588 AT91C_ID_SYS
, // System peripheral ID
589 AT91C_AIC_PRIOR_HIGHEST
, // Max priority
590 AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE
, // Level sensitive
593 /* Enable ST interrupt */
594 AT91F_AIC_EnableIt(AT91C_BASE_AIC
, AT91C_ID_SYS
);
597 /* Start tempo to start Boot in a delay of
598 * AT91C_DELAY_TO_BOOT sec if no key pressed */
599 svcBootTempo
.Start(&svcBootTempo
, AT91C_DELAY_TO_BOOT
,
600 0, AT91F_StartBoot
, NULL
);
607 AddressToDownload
= AT91C_DOWNLOAD_BASE_ADDRESS
;
608 SizeToDownload
= AT91C_DOWNLOAD_MAX_SIZE
;
611 /* try to detect Dataflash */
613 Nb_Device
= AT91F_DataflashInit();
615 mci_present
= AT91F_DisplayMenu();
619 if (Program_From_MCI())
625 AT91F_ReadLine ("Enter: ", message
);
628 /* stop tempo ==> stop autoboot */
629 svcBootTempo
.Stop(&svcBootTempo
);
632 command
= message
[0];
633 for(ix
= 1; (message
[ix
] == ' ') && (ix
< 12); ix
++); // Skip some whitespace
635 if(!AsciiToHex(&message
[ix
], &DeviceAddress
) )
636 DeviceAddress
= 0; // Illegal DeviceAddress
645 DeviceAddress
= 0xC0000000;
646 // printf("Download DataflashBoot.bin to [0x%x]\n", DeviceAddress);
647 } else if(command
== '2') {
648 DeviceAddress
= AT91C_BOOT_DATAFLASH_ADDR
;
649 // printf("Download u-boot.bin to [0x%x]\n", DeviceAddress);
651 // printf("Download Dataflash to [0x%x]\n", DeviceAddress);
653 switch(DeviceAddress
& 0xFF000000)
655 case CFG_DATAFLASH_LOGIC_ADDR_CS0
:
656 if (dataflash_info
[0].id
== 0){
658 AT91F_WaitKeyPressed();
665 case CFG_DATAFLASH_LOGIC_ADDR_CS3
:
666 if (dataflash_info
[1].id
== 0){
668 AT91F_WaitKeyPressed();
696 AT91F_MemoryDisplay(DeviceAddress
, 256);
697 AT91F_ReadLine (NULL
, message
);
698 DeviceAddress
+= 0x100;
700 while(message
[0] == '\0');
706 switch(DeviceAddress
& 0xFF000000)
708 case CFG_DATAFLASH_LOGIC_ADDR_CS0
:
710 case CFG_DATAFLASH_LOGIC_ADDR_CS3
:
718 AT91F_ReadLine ("RDY ERA\nSure?",
720 if(message
[0] == 'Y' || message
[0] == 'y') {
721 erase_dataflash(DeviceAddress
& 0xFF000000);
722 // printf("Erase complete\n\n");
725 // printf("Erase aborted\n");
737 for(i
= 0; i
<= AT91C_DOWNLOAD_MAX_SIZE
; i
++)
738 *(unsigned char *)(AddressToDownload
+ i
) = 0;
740 xmodemPipe
.Read(&xmodemPipe
, (char *)AddressToDownload
,
741 SizeToDownload
, XmodemProtocol
, 0);
742 while(XmodemComplete
!=1);
743 SizeToDownload
= (unsigned int)((svcXmodem
.pData
) -
744 (unsigned int)AddressToDownload
);
746 /* Modification of vector 6 */
747 if ((DeviceAddress
== CFG_DATAFLASH_LOGIC_ADDR_CS0
)) {
748 // Vector 6 must be compliant to the BootRom description (ref Datasheet)
750 i
= dataflash_info
[device
].Device
.pages_number
;
753 i
= (SizeToDownload
/ 512)+1 + (NbPage
<< 13) +
754 (dataflash_info
[device
].Device
.pages_size
<< 17); //+4 to add crc32
755 SizeToDownload
= 512 * (i
&0xFF);
759 /* Save the contents of vector 6 ==> will be restored
760 * at boot time (AT91F_StartBoot) */
761 *(int *)(AddressToDownload
+ SizeToDownload
+ 4) =
762 *(int *)(AddressToDownload
+ AT91C_OFFSET_VECT6
);
763 /* Modify Vector 6 to contain the size of the
764 * file to copy (Dataflash -> SDRAM)*/
768 *(int *)(AddressToDownload
+ AT91C_OFFSET_VECT6
) = i
;
769 // printf("\nModification of Arm Vector 6 :%x\n", i);
771 // printf("\nWrite %d bytes in DataFlash [0x%x]\n",SizeToDownload, DeviceAddress);
773 pAT91
->CRC32((const unsigned char *)AddressToDownload
, SizeToDownload
, &crc1
);
775 /* Add the crc32 at the end of the code */
776 *(char *)(AddressToDownload
+ SizeToDownload
) = (char)(crc1
& 0x000000FF);
777 *(char *)(AddressToDownload
+ SizeToDownload
+ 1) = (char)((crc1
& 0x0000FF00) >> 8);
778 *(char *)(AddressToDownload
+ SizeToDownload
+ 2) = (char)((crc1
& 0x00FF0000) >> 16);
779 *(char *)(AddressToDownload
+ SizeToDownload
+ 3) = (char)((crc1
& 0xFF000000) >> 24);
781 /* write dataflash */
782 write_dataflash (DeviceAddress
, AddressToDownload
, (SizeToDownload
+ 8));
784 /* clear the buffer before read */
785 for(i
=0; i
<= SizeToDownload
; i
++)
786 *(unsigned char *)(AddressToDownload
+ i
) = 0;
788 /* Read dataflash to check the validity of the data */
789 read_dataflash (DeviceAddress
, (SizeToDownload
+ 4), (char *)(AddressToDownload
));
794 pAT91
->CRC32((const unsigned char *)AddressToDownload
, SizeToDownload
, &crc2
);
795 crc1
= (int)(*(char *)(AddressToDownload
+ SizeToDownload
)) +
796 (int)(*(char *)(AddressToDownload
+ SizeToDownload
+ 1) << 8) +
797 (int)(*(char *)(AddressToDownload
+ SizeToDownload
+ 2) << 16) +
798 (int)(*(char *)(AddressToDownload
+ SizeToDownload
+ 3) << 24);
807 AT91F_WaitKeyPressed();