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 * Modif : HIi 15/06/2004 : add crc32 to verify the download 14 * from dataflash 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 *---------------------------------------------------------------------------- 23 */ 24#include "config.h" 25#include "stdio.h" 26#include "AT91RM9200.h" 27#include "lib_AT91RM9200.h" 28#include "com.h" 29#include "main.h" 30#include "dataflash.h" 31#include "AT91C_MCI_Device.h" 32 33#define DEBUGOUT 34#define XMODEM 35#define MEMDISP 36 37#ifdef PAGESZ_1056 38#define PAGESIZE 1056 39#else 40#define PAGESIZE 1024 41#endif 42 43#define AT91C_SDRAM_START 0x20000000 44#define AT91C_BOOT_ADDR 0x21F00000 45#define AT91C_BOOT_SIZE 128*PAGESIZE 46#ifdef PAGESZ_1056 47#define AT91C_BOOT_DATAFLASH_ADDR 0xC0008400 48#else 49#define AT91C_BOOT_DATAFLASH_ADDR 0xC0008000 50#endif 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 54 55 56 57#define DISP_LINE_LEN 16 58 59// Reason for boot failure 60#define IMAGE_BAD_SIZE 0 61#define IMAGE_READ_FAILURE 1 62#define IMAGE_CRC_ERROR 2 63#define IMAGE_ERROR 3 64#define SUCCESS -1 65 66/* prototypes*/ 67extern void AT91F_ST_ASM_HANDLER(void); 68extern void Jump(unsigned int addr); 69 70const char *menu_dataflash[] = { 71#ifdef XMODEM 72 "1: P DFboot\n", 73 "2: P U-Boot\n", 74#endif 75 "3: P SDCard\n", 76#ifdef PAGESZ_1056 77 "4: R UBOOT\n", 78#else 79 "4: R UBOOT\n", 80#endif 81#ifdef XMODEM 82 "5: P DF [addr]\n", 83#endif 84 "6: RD DF [addr]\n", 85 "7: E DF\n" 86}; 87#ifdef XMODEM 88#define MAXMENU 7 89#else 90#define MAXMENU 4 91#endif 92 93char message[20]; 94#ifdef XMODEM 95volatile char XmodemComplete = 0; 96#endif 97unsigned int StTick = 0; 98 99AT91S_RomBoot const *pAT91; 100#ifdef XMODEM 101AT91S_SBuffer sXmBuffer; 102AT91S_SvcXmodem svcXmodem; 103AT91S_Pipe xmodemPipe; 104#endif 105AT91S_CtlTempo ctlTempo; 106 107 108//*-------------------------------------------------------------------------------------- 109//* Function Name : GetTickCount() 110//* Object : Return the number of systimer tick 111//* Input Parameters : 112//* Output Parameters : 113//*-------------------------------------------------------------------------------------- 114unsigned int GetTickCount(void) 115{ 116 return StTick; 117} 118 119#ifdef XMODEM 120//*-------------------------------------------------------------------------------------- 121//* Function Name : AT91_XmodemComplete() 122//* Object : Perform the remap and jump to appli in RAM 123//* Input Parameters : 124//* Output Parameters : 125//*-------------------------------------------------------------------------------------- 126static void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid) 127{ 128 /* stop the Xmodem tempo */ 129 svcXmodem.tempo.Stop(&(svcXmodem.tempo)); 130 XmodemComplete = 1; 131} 132 133 134//*-------------------------------------------------------------------------------------- 135//* Function Name : AT91F_XmodemProtocol(AT91S_PipeStatus status, void *pVoid) 136//* Object : Xmodem dispatcher 137//* Input Parameters : 138//* Output Parameters : 139//*-------------------------------------------------------------------------------------- 140static void XmodemProtocol(AT91S_PipeStatus status, void *pVoid) 141{ 142 AT91PS_SBuffer pSBuffer = (AT91PS_SBuffer) xmodemPipe.pBuffer->pChild; 143 AT91PS_USART pUsart = svcXmodem.pUsart; 144 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); 148 } 149} 150#endif 151 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//*-------------------------------------------------------------------------------------- 158void AT91F_ST_HANDLER(void) 159{ 160 volatile unsigned int csr = *AT91C_DBGU_CSR; 161#ifdef XMODEM 162 unsigned int error; 163#endif 164 165 if (AT91C_BASE_ST->ST_SR & 0x01) { 166 StTick++; 167 ctlTempo.CtlTempoTick(&ctlTempo); 168 return; 169 } 170 171#ifdef XMODEM 172 error = AT91F_US_Error((AT91PS_USART)AT91C_BASE_DBGU); 173 if (csr & error) { 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); 178 179 } 180 181 else if (csr & (AT91C_US_TXRDY | AT91C_US_ENDTX | AT91C_US_TXEMPTY | 182 AT91C_US_RXRDY | AT91C_US_ENDRX | AT91C_US_TIMEOUT | 183 AT91C_US_RXBUFF)) { 184 if ( !(svcXmodem.eot) ) 185 svcXmodem.Handler(&svcXmodem, csr); 186 } 187#endif 188} 189 190 191//*----------------------------------------------------------------------------- 192//* Function Name : AT91F_DisplayMenu() 193//* Object : 194//* Input Parameters : 195//* Return value : 196//*----------------------------------------------------------------------------- 197static int AT91F_DisplayMenu(void) 198{ 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]); 205 } 206 return mci_present; 207} 208 209 210//*----------------------------------------------------------------------------- 211//* Function Name : AsciiToHex() 212//* Object : ascii to hexa conversion 213//* Input Parameters : 214//* Return value : 215//*----------------------------------------------------------------------------- 216static unsigned int AsciiToHex(char *s, unsigned int *val) 217{ 218 int n; 219 220 *val=0; 221 222 if(s[0] == '0' && ((s[1] == 'x') || (s[1] == 'X'))) 223 s+=2; 224 n = 0; 225 while((n < 8) && (s[n] !=0)) 226 { 227 *val <<= 4; 228 if ( (s[n] >= '0') && (s[n] <='9')) 229 *val += (s[n] - '0'); 230 else 231 if ((s[n] >= 'a') && (s[n] <='f')) 232 *val += (s[n] - 0x57); 233 else 234 if ((s[n] >= 'A') && (s[n] <='F')) 235 *val += (s[n] - 0x37); 236 else 237 return 0; 238 n++; 239 } 240 241 return 1; 242} 243 244 245#ifdef MEMDISP 246//*----------------------------------------------------------------------------- 247//* Function Name : AT91F_MemoryDisplay() 248//* Object : Display the content of the dataflash 249//* Input Parameters : 250//* Return value : 251//*----------------------------------------------------------------------------- 252static int AT91F_MemoryDisplay(unsigned int addr, unsigned int length) 253{ 254 unsigned long i, nbytes, linebytes; 255 char *cp; 256// unsigned int *uip; 257// unsigned short *usp; 258 unsigned char *ucp; 259 char linebuf[DISP_LINE_LEN]; 260 261// nbytes = length * size; 262 nbytes = length; 263 do 264 { 265// uip = (unsigned int *)linebuf; 266// usp = (unsigned short *)linebuf; 267 ucp = (unsigned char *)linebuf; 268 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); 274 } 275 } else { 276 read_dataflash(addr, linebytes, linebuf); 277 } 278 for (i=0; i<linebytes; i++) 279 { 280/* if (size == 4) 281 printf(" %08x", *uip++); 282 else if (size == 2) 283 printf(" %04x", *usp++); 284 else 285*/ 286 printf(" %02x", *ucp++); 287// addr += size; 288 addr++; 289 } 290 printf(" "); 291 cp = linebuf; 292 for (i=0; i<linebytes; i++) { 293 if ((*cp < 0x20) || (*cp > 0x7e)) 294 printf("."); 295 else 296 printf("%c", *cp); 297 cp++; 298 } 299 printf("\n"); 300 nbytes -= linebytes; 301 } while (nbytes > 0); 302 return 0; 303} 304#endif 305 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//*-------------------------------------------------------------------------------------- 312static unsigned int AT91F_SetPLL(void) 313{ 314 AT91_REG tmp; 315 AT91PS_PMC pPmc = AT91C_BASE_PMC; 316 AT91PS_CKGR pCkgr = AT91C_BASE_CKGR; 317 318 pPmc->PMC_IDR = 0xFFFFFFFF; 319 320 /* -Setup the PLL A */ 321 pCkgr->CKGR_PLLAR = AT91C_PLLA_VALUE; 322 323 while (!(*AT91C_PMC_SR & AT91C_PMC_LOCKA)); 324 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)); 332 } 333 if (tmp != 0x00000202) { 334 pPmc->PMC_MCKR = 0x00000202; 335 if ((tmp & 0x00000003) != 0x00000002) 336 while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY)); 337 } 338 339 return 1; 340} 341 342 343//*-------------------------------------------------------------------------------------- 344//* Function Name : AT91F_ResetRegisters 345//* Object : Restore the initial state to registers 346//* Input Parameters : 347//* Output Parameters : 348//*-------------------------------------------------------------------------------------- 349static unsigned int AT91F_ResetRegisters(void) 350{ 351 volatile int i = 0; 352 353 /* set the PIOs in input*/ 354 /* This disables the UART output, so dont execute for now*/ 355 356#ifndef DEBUGOUT 357 *AT91C_PIOA_ODR = 0xFFFFFFFF; /* Disables all the output pins */ 358 *AT91C_PIOA_PER = 0xFFFFFFFF; /* Enables the PIO to control all the pins */ 359#endif 360 361 AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SYS); 362 /* close all peripheral clocks */ 363 364#ifndef DEBUGOUT 365 AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFC; 366#endif 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; 371 372 /* read the AIC_IVR and AIC_FVR */ 373 i = *AT91C_AIC_IVR; 374 i = *AT91C_AIC_FVR; 375 376 /* write the end of interrupt control register */ 377 *AT91C_AIC_EOICR = 0; 378 379 return 1; 380} 381 382 383static int AT91F_LoadBoot(void) 384{ 385// volatile unsigned int crc1 = 0, crc2 = 0; 386 volatile unsigned int SizeToDownload = 0x21400; 387 volatile unsigned int AddressToDownload = AT91C_BOOT_ADDR; 388 389#if 0 390 /* Read vector 6 to extract size to load */ 391 if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR, 32, 392 (char *)AddressToDownload) != AT91C_DATAFLASH_OK) 393 { 394 printf("Bad Code Size\n"); 395 return IMAGE_BAD_SIZE; 396 } 397 /* calculate the size to download */ 398 SizeToDownload = *(int *)(AddressToDownload + AT91C_OFFSET_VECT6); 399#endif 400 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) 405 { 406 printf("F DF RD\n"); 407 return IMAGE_READ_FAILURE; 408 } 409#if 0 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); 416 417 /* Restore the value of Vector 6 */ 418 *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) = 419 *(int *)(AddressToDownload + SizeToDownload + 4); 420 421 if (crc1 != crc2) { 422 printf("DF CRC bad %x != %x\n",crc1,crc2); 423 return IMAGE_CRC_ERROR; 424 } 425#endif 426 return SUCCESS; 427} 428 429static int AT91F_StartBoot(void) 430{ 431 int sts; 432 if((sts = AT91F_LoadBoot()) != SUCCESS) return sts; 433// printf("\n"); 434// printf("PLLA[180MHz], MCK[60Mhz] ==> Start UBOOT\n"); 435 if (AT91F_ResetRegisters()) 436 { 437 printf("Jump"); 438 Jump(AT91C_BOOT_ADDR); 439// LED_blink(0); 440 } 441 return IMAGE_ERROR; 442} 443 444#if 0 445static void AT91F_RepeatedStartBoot(void) 446{ 447 int i; 448 for(i = 0; i < CRC_RETRIES; i++) { 449 if(AT91F_StartBoot() != IMAGE_CRC_ERROR){ 450// LED_blink(1); 451 return; 452 } 453 } 454 return; 455} 456#endif 457 458#define TRUE 1 459#define FALSE 0 460#define TRX_MAGIC 0x30524448 /* "HDR0" */ 461#define TRX_VERSION 1 462 463struct trx_header { 464 unsigned int magic; 465 unsigned int len; 466 unsigned int crc32; 467 unsigned int flag_version; 468 unsigned int offsets[3]; 469}; 470 471#define AT91C_MCI_TIMEOUT 1000000 472 473extern AT91S_MciDevice MCI_Device; 474extern void AT91F_MCIDeviceWaitReady(unsigned int); 475extern int AT91F_MCI_ReadBlockSwab(AT91PS_MciDevice, int, unsigned int *, int); 476 477int Program_From_MCI(void) 478{ 479 int i; 480 unsigned int Max_Read_DataBlock_Length; 481 int block = 0; 482 int buffer = AT91C_DOWNLOAD_BASE_ADDRESS; 483 int bufpos = AT91C_DOWNLOAD_BASE_ADDRESS; 484 int NbPage = 0; 485 struct trx_header *p; 486 487 p = (struct trx_header *)bufpos; 488 489 Max_Read_DataBlock_Length = MCI_Device.pMCI_DeviceFeatures->Max_Read_DataBlock_Length; 490 491 AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); 492 493 AT91F_MCI_ReadBlockSwab(&MCI_Device, block*Max_Read_DataBlock_Length, (unsigned int *)bufpos, Max_Read_DataBlock_Length); 494 495 if (p->magic != TRX_MAGIC) { 496 printf("Inv IMG 0x%08x\n", p->magic); 497 return FALSE; 498 } 499 500 printf("RDSD"); 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); 504 block++; 505 bufpos += Max_Read_DataBlock_Length; 506 } 507 508 NbPage = 0; 509 i = dataflash_info[0].Device.pages_number; 510 while(i >>= 1) 511 NbPage++; 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; 514 515 printf(" WDFB"); 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]); 519 printf(" WUB"); 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]); 523 printf(" WKRFS"); 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; 529 return TRUE; 530} 531 532//*---------------------------------------------------------------------------- 533//* Function Name : main 534//* Object : Main function 535//* Input Parameters : none 536//* Output Parameters : True 537//*---------------------------------------------------------------------------- 538int main(void) 539{ 540#ifdef XMODEM 541 AT91PS_Buffer pXmBuffer; 542 AT91PS_SvcComm pSvcXmodem; 543#endif 544 AT91S_SvcTempo svcBootTempo; // Link to a AT91S_Tempo object 545 unsigned int ix; 546 volatile unsigned int AddressToDownload, SizeToDownload; 547 unsigned int DeviceAddress = 0; 548 char command = 0; 549#ifdef XMODEM 550 volatile int i = 0; 551 unsigned int crc1 = 0, crc2 = 0; 552 volatile int device; 553 int NbPage; 554#endif 555 volatile int Nb_Device = 0; 556 int mci_present = 0; 557 558 pAT91 = AT91C_ROM_BOOT_ADDRESS; 559 560 if (!AT91F_SetPLL()) 561 { 562 printf("F SetPLL"); 563 while(1); 564 } 565 566 at91_init_uarts(); 567 568 /* Tempo Initialisation */ 569 pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC)); 570 ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)); 571 572 // Attach the tempo to a tempo controler 573 ctlTempo.CtlTempoCreate(&ctlTempo, &svcBootTempo); 574// LED_init(); 575// LED_blink(2); 576 577#ifdef XMODEM 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); 583#endif 584 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 591 AT91F_ST_ASM_HANDLER 592 ); 593 /* Enable ST interrupt */ 594 AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS); 595 596#ifndef PRODTEST 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); 601#endif 602 603 while(1) 604 { 605 while(command == 0) 606 { 607 AddressToDownload = AT91C_DOWNLOAD_BASE_ADDRESS; 608 SizeToDownload = AT91C_DOWNLOAD_MAX_SIZE; 609 DeviceAddress = 0; 610 611 /* try to detect Dataflash */ 612 if (!Nb_Device) 613 Nb_Device = AT91F_DataflashInit(); 614 615 mci_present = AT91F_DisplayMenu(); 616 617#ifdef PRODTEST 618 if (mci_present) { 619 if (Program_From_MCI()) 620 AT91F_StartBoot(); 621 } 622#endif 623 624 message[0] = 0; 625 AT91F_ReadLine ("Enter: ", message); 626 627#ifndef PRODTEST 628 /* stop tempo ==> stop autoboot */ 629 svcBootTempo.Stop(&svcBootTempo); 630#endif 631 632 command = message[0]; 633 for(ix = 1; (message[ix] == ' ') && (ix < 12); ix++); // Skip some whitespace 634 635 if(!AsciiToHex(&message[ix], &DeviceAddress) ) 636 DeviceAddress = 0; // Illegal DeviceAddress 637 638 switch(command) 639 { 640#ifdef XMODEM 641 case '1': 642 case '2': 643 case '5': 644 if(command == '1') { 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); 650 } else { 651// printf("Download Dataflash to [0x%x]\n", DeviceAddress); 652 } 653 switch(DeviceAddress & 0xFF000000) 654 { 655 case CFG_DATAFLASH_LOGIC_ADDR_CS0: 656 if (dataflash_info[0].id == 0){ 657 printf("No DF"); 658 AT91F_WaitKeyPressed(); 659 command = 0; 660 } 661 662 device = 0; 663 break; 664 665 case CFG_DATAFLASH_LOGIC_ADDR_CS3: 666 if (dataflash_info[1].id == 0){ 667 printf("No DF"); 668 AT91F_WaitKeyPressed(); 669 command = 0; 670 } 671 device = 1; 672 break; 673 674 default: 675 command = 0; 676 break; 677 } 678 break; 679#endif 680 681 case '3': 682 if (mci_present) 683 Program_From_MCI(); 684 command = 0; 685 break; 686 687 case '4': 688 AT91F_StartBoot(); 689 command = 0; 690 break; 691 692#ifdef MEMDISP 693 case '6': 694 do 695 { 696 AT91F_MemoryDisplay(DeviceAddress, 256); 697 AT91F_ReadLine (NULL, message); 698 DeviceAddress += 0x100; 699 } 700 while(message[0] == '\0'); 701 command = 0; 702 break; 703#endif 704 705 case '7': 706 switch(DeviceAddress & 0xFF000000) 707 { 708 case CFG_DATAFLASH_LOGIC_ADDR_CS0: 709 break; 710 case CFG_DATAFLASH_LOGIC_ADDR_CS3: 711 break; 712 default: 713 command = 0; 714 break; 715 } 716 717 if (command != 0) { 718 AT91F_ReadLine ("RDY ERA\nSure?", 719 message); 720 if(message[0] == 'Y' || message[0] == 'y') { 721 erase_dataflash(DeviceAddress & 0xFF000000); 722// printf("Erase complete\n\n"); 723 } 724// else 725// printf("Erase aborted\n"); 726 } 727 command = 0; 728 729 break; 730 731 default: 732 command = 0; 733 break; 734 } 735 } 736#ifdef XMODEM 737 for(i = 0; i <= AT91C_DOWNLOAD_MAX_SIZE; i++) 738 *(unsigned char *)(AddressToDownload + i) = 0; 739 740 xmodemPipe.Read(&xmodemPipe, (char *)AddressToDownload, 741 SizeToDownload, XmodemProtocol, 0); 742 while(XmodemComplete !=1); 743 SizeToDownload = (unsigned int)((svcXmodem.pData) - 744 (unsigned int)AddressToDownload); 745 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) 749 NbPage = 0; 750 i = dataflash_info[device].Device.pages_number; 751 while(i >>= 1) 752 NbPage++; 753 i = (SizeToDownload / 512)+1 + (NbPage << 13) + 754 (dataflash_info[device].Device.pages_size << 17); //+4 to add crc32 755 SizeToDownload = 512 * (i &0xFF); 756 } 757 else 758 { 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)*/ 765 i = SizeToDownload; 766 } 767 768 *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) = i; 769// printf("\nModification of Arm Vector 6 :%x\n", i); 770 771// printf("\nWrite %d bytes in DataFlash [0x%x]\n",SizeToDownload, DeviceAddress); 772 crc1 = 0; 773 pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc1); 774 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); 780 781 /* write dataflash */ 782 write_dataflash (DeviceAddress, AddressToDownload, (SizeToDownload + 8)); 783 784 /* clear the buffer before read */ 785 for(i=0; i <= SizeToDownload; i++) 786 *(unsigned char *)(AddressToDownload + i) = 0; 787 788 /* Read dataflash to check the validity of the data */ 789 read_dataflash (DeviceAddress, (SizeToDownload + 4), (char *)(AddressToDownload)); 790 791 printf("VFY: "); 792 crc2 = 0; 793 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); 799 800 if (crc1 != crc2) 801 printf("ERR"); 802 else 803 printf("OK"); 804 805 command = 0; 806 XmodemComplete = 0; 807 AT91F_WaitKeyPressed(); 808#endif 809 } 810} 811 812