main.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  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. #define DEBUGOUT
  33. #define XMODEM
  34. #define MEMDISP
  35. #ifdef PAGESZ_1056
  36. #define PAGESIZE 1056
  37. #else
  38. #define PAGESIZE 1024
  39. #endif
  40. #define AT91C_SDRAM_START 0x20000000
  41. #define AT91C_BOOT_ADDR 0x21F00000
  42. #define AT91C_BOOT_SIZE 128*PAGESIZE
  43. #ifdef PAGESZ_1056
  44. #define AT91C_BOOT_DATAFLASH_ADDR 0xC0008400
  45. #else
  46. #define AT91C_BOOT_DATAFLASH_ADDR 0xC0008000
  47. #endif
  48. #define AT91C_PLLA_VALUE 0x237A3E5A // crystal= 18.432MHz - fixes BRG error at 115kbps
  49. //#define AT91C_PLLA_VALUE 0x2026BE04 // crystal= 18.432MHz
  50. //#define AT91C_PLLA_VALUE 0x202CBE01 // crystal= 4MHz
  51. #define DISP_LINE_LEN 16
  52. // Reason for boot failure
  53. #define IMAGE_BAD_SIZE 0
  54. #define IMAGE_READ_FAILURE 1
  55. #define IMAGE_CRC_ERROR 2
  56. #define IMAGE_ERROR 3
  57. #define SUCCESS -1
  58. /* prototypes*/
  59. extern void AT91F_ST_ASM_HANDLER(void);
  60. extern void Jump(unsigned int addr);
  61. const char *menu_dataflash[] = {
  62. #ifdef XMODEM
  63. "1: P DFboot\n",
  64. "2: P U-Boot\n",
  65. #endif
  66. "3: P SDCard\n",
  67. #ifdef PAGESZ_1056
  68. "4: R UBOOT\n",
  69. #else
  70. "4: R UBOOT\n",
  71. #endif
  72. #ifdef XMODEM
  73. "5: P DF [addr]\n",
  74. #endif
  75. "6: RD DF [addr]\n",
  76. "7: E DF\n"
  77. };
  78. #ifdef XMODEM
  79. #define MAXMENU 7
  80. #else
  81. #define MAXMENU 4
  82. #endif
  83. char message[20];
  84. #ifdef XMODEM
  85. volatile char XmodemComplete = 0;
  86. #endif
  87. unsigned int StTick = 0;
  88. AT91S_RomBoot const *pAT91;
  89. #ifdef XMODEM
  90. AT91S_SBuffer sXmBuffer;
  91. AT91S_SvcXmodem svcXmodem;
  92. AT91S_Pipe xmodemPipe;
  93. #endif
  94. AT91S_CtlTempo ctlTempo;
  95. //*--------------------------------------------------------------------------------------
  96. //* Function Name : GetTickCount()
  97. //* Object : Return the number of systimer tick
  98. //* Input Parameters :
  99. //* Output Parameters :
  100. //*--------------------------------------------------------------------------------------
  101. unsigned int GetTickCount(void)
  102. {
  103. return StTick;
  104. }
  105. #ifdef XMODEM
  106. //*--------------------------------------------------------------------------------------
  107. //* Function Name : AT91_XmodemComplete()
  108. //* Object : Perform the remap and jump to appli in RAM
  109. //* Input Parameters :
  110. //* Output Parameters :
  111. //*--------------------------------------------------------------------------------------
  112. static void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid)
  113. {
  114. /* stop the Xmodem tempo */
  115. svcXmodem.tempo.Stop(&(svcXmodem.tempo));
  116. XmodemComplete = 1;
  117. }
  118. //*--------------------------------------------------------------------------------------
  119. //* Function Name : AT91F_XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
  120. //* Object : Xmodem dispatcher
  121. //* Input Parameters :
  122. //* Output Parameters :
  123. //*--------------------------------------------------------------------------------------
  124. static void XmodemProtocol(AT91S_PipeStatus status, void *pVoid)
  125. {
  126. AT91PS_SBuffer pSBuffer = (AT91PS_SBuffer) xmodemPipe.pBuffer->pChild;
  127. AT91PS_USART pUsart = svcXmodem.pUsart;
  128. if (pSBuffer->szRdBuffer == 0) {
  129. /* Start a tempo to wait the Xmodem protocol complete */
  130. svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, pUsart);
  131. }
  132. }
  133. #endif
  134. //*--------------------------------------------------------------------------------------
  135. //* Function Name : irq1_c_handler()
  136. //* Object : C Interrupt handler for Interrutp source 1
  137. //* Input Parameters : none
  138. //* Output Parameters : none
  139. //*--------------------------------------------------------------------------------------
  140. void AT91F_ST_HANDLER(void)
  141. {
  142. volatile unsigned int csr = *AT91C_DBGU_CSR;
  143. #ifdef XMODEM
  144. unsigned int error;
  145. #endif
  146. if (AT91C_BASE_ST->ST_SR & 0x01) {
  147. StTick++;
  148. ctlTempo.CtlTempoTick(&ctlTempo);
  149. return;
  150. }
  151. #ifdef XMODEM
  152. error = AT91F_US_Error((AT91PS_USART)AT91C_BASE_DBGU);
  153. if (csr & error) {
  154. /* Stop previous Xmodem transmition*/
  155. *(AT91C_DBGU_CR) = AT91C_US_RSTSTA;
  156. AT91F_US_DisableIt((AT91PS_USART)AT91C_BASE_DBGU, AT91C_US_ENDRX);
  157. AT91F_US_EnableIt((AT91PS_USART)AT91C_BASE_DBGU, AT91C_US_RXRDY);
  158. }
  159. else if (csr & (AT91C_US_TXRDY | AT91C_US_ENDTX | AT91C_US_TXEMPTY |
  160. AT91C_US_RXRDY | AT91C_US_ENDRX | AT91C_US_TIMEOUT |
  161. AT91C_US_RXBUFF)) {
  162. if ( !(svcXmodem.eot) )
  163. svcXmodem.Handler(&svcXmodem, csr);
  164. }
  165. #endif
  166. }
  167. //*-----------------------------------------------------------------------------
  168. //* Function Name : AT91F_DisplayMenu()
  169. //* Object :
  170. //* Input Parameters :
  171. //* Return value :
  172. //*-----------------------------------------------------------------------------
  173. static int AT91F_DisplayMenu(void)
  174. {
  175. int i, mci_present = 0;
  176. printf("\nDF LOADER %s %s %s\n",AT91C_VERSION,__DATE__,__TIME__);
  177. AT91F_DataflashPrintInfo();
  178. mci_present = AT91F_MCI_Init();
  179. for(i = 0; i < MAXMENU; i++) {
  180. puts(menu_dataflash[i]);
  181. }
  182. return mci_present;
  183. }
  184. //*-----------------------------------------------------------------------------
  185. //* Function Name : AsciiToHex()
  186. //* Object : ascii to hexa conversion
  187. //* Input Parameters :
  188. //* Return value :
  189. //*-----------------------------------------------------------------------------
  190. static unsigned int AsciiToHex(char *s, unsigned int *val)
  191. {
  192. int n;
  193. *val=0;
  194. if(s[0] == '0' && ((s[1] == 'x') || (s[1] == 'X')))
  195. s+=2;
  196. n = 0;
  197. while((n < 8) && (s[n] !=0))
  198. {
  199. *val <<= 4;
  200. if ( (s[n] >= '0') && (s[n] <='9'))
  201. *val += (s[n] - '0');
  202. else
  203. if ((s[n] >= 'a') && (s[n] <='f'))
  204. *val += (s[n] - 0x57);
  205. else
  206. if ((s[n] >= 'A') && (s[n] <='F'))
  207. *val += (s[n] - 0x37);
  208. else
  209. return 0;
  210. n++;
  211. }
  212. return 1;
  213. }
  214. #ifdef MEMDISP
  215. //*-----------------------------------------------------------------------------
  216. //* Function Name : AT91F_MemoryDisplay()
  217. //* Object : Display the content of the dataflash
  218. //* Input Parameters :
  219. //* Return value :
  220. //*-----------------------------------------------------------------------------
  221. static int AT91F_MemoryDisplay(unsigned int addr, unsigned int length)
  222. {
  223. unsigned long i, nbytes, linebytes;
  224. char *cp;
  225. // unsigned int *uip;
  226. // unsigned short *usp;
  227. unsigned char *ucp;
  228. char linebuf[DISP_LINE_LEN];
  229. // nbytes = length * size;
  230. nbytes = length;
  231. do
  232. {
  233. // uip = (unsigned int *)linebuf;
  234. // usp = (unsigned short *)linebuf;
  235. ucp = (unsigned char *)linebuf;
  236. printf("%08x:", addr);
  237. linebytes = (nbytes > DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
  238. if((addr & 0xF0000000) == 0x20000000) {
  239. for(i = 0; i < linebytes; i ++) {
  240. linebuf[i] = *(char *)(addr+i);
  241. }
  242. } else {
  243. read_dataflash(addr, linebytes, linebuf);
  244. }
  245. for (i=0; i<linebytes; i++)
  246. {
  247. /* if (size == 4)
  248. printf(" %08x", *uip++);
  249. else if (size == 2)
  250. printf(" %04x", *usp++);
  251. else
  252. */
  253. printf(" %02x", *ucp++);
  254. // addr += size;
  255. addr++;
  256. }
  257. printf(" ");
  258. cp = linebuf;
  259. for (i=0; i<linebytes; i++) {
  260. if ((*cp < 0x20) || (*cp > 0x7e))
  261. printf(".");
  262. else
  263. printf("%c", *cp);
  264. cp++;
  265. }
  266. printf("\n");
  267. nbytes -= linebytes;
  268. } while (nbytes > 0);
  269. return 0;
  270. }
  271. #endif
  272. //*--------------------------------------------------------------------------------------
  273. //* Function Name : AT91F_SetPLL
  274. //* Object : Set the PLLA to 180Mhz and Master clock to 60 Mhz
  275. //* Input Parameters :
  276. //* Output Parameters :
  277. //*--------------------------------------------------------------------------------------
  278. static unsigned int AT91F_SetPLL(void)
  279. {
  280. AT91_REG tmp;
  281. AT91PS_PMC pPmc = AT91C_BASE_PMC;
  282. AT91PS_CKGR pCkgr = AT91C_BASE_CKGR;
  283. pPmc->PMC_IDR = 0xFFFFFFFF;
  284. /* -Setup the PLL A */
  285. pCkgr->CKGR_PLLAR = AT91C_PLLA_VALUE;
  286. while (!(*AT91C_PMC_SR & AT91C_PMC_LOCKA));
  287. /* - Switch Master Clock from PLLB to PLLA/3 */
  288. tmp = pPmc->PMC_MCKR;
  289. /* See Atmel Errata #27 and #28 */
  290. if (tmp & 0x0000001C) {
  291. tmp = (tmp & ~0x0000001C);
  292. pPmc->PMC_MCKR = tmp;
  293. while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
  294. }
  295. if (tmp != 0x00000202) {
  296. pPmc->PMC_MCKR = 0x00000202;
  297. if ((tmp & 0x00000003) != 0x00000002)
  298. while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
  299. }
  300. return 1;
  301. }
  302. //*--------------------------------------------------------------------------------------
  303. //* Function Name : AT91F_ResetRegisters
  304. //* Object : Restore the initial state to registers
  305. //* Input Parameters :
  306. //* Output Parameters :
  307. //*--------------------------------------------------------------------------------------
  308. static unsigned int AT91F_ResetRegisters(void)
  309. {
  310. volatile int i = 0;
  311. /* set the PIOs in input*/
  312. /* This disables the UART output, so dont execute for now*/
  313. #ifndef DEBUGOUT
  314. *AT91C_PIOA_ODR = 0xFFFFFFFF; /* Disables all the output pins */
  315. *AT91C_PIOA_PER = 0xFFFFFFFF; /* Enables the PIO to control all the pins */
  316. #endif
  317. AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SYS);
  318. /* close all peripheral clocks */
  319. #ifndef DEBUGOUT
  320. AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFC;
  321. #endif
  322. /* Disable core interrupts and set supervisor mode */
  323. __asm__ ("msr CPSR_c, #0xDF"); //* ARM_MODE_SYS(0x1F) | I_BIT(0x80) | F_BIT(0x40)
  324. /* Clear all the interrupts */
  325. *AT91C_AIC_ICCR = 0xffffffff;
  326. /* read the AIC_IVR and AIC_FVR */
  327. i = *AT91C_AIC_IVR;
  328. i = *AT91C_AIC_FVR;
  329. /* write the end of interrupt control register */
  330. *AT91C_AIC_EOICR = 0;
  331. return 1;
  332. }
  333. static int AT91F_LoadBoot(void)
  334. {
  335. // volatile unsigned int crc1 = 0, crc2 = 0;
  336. volatile unsigned int SizeToDownload = 0x21400;
  337. volatile unsigned int AddressToDownload = AT91C_BOOT_ADDR;
  338. #if 0
  339. /* Read vector 6 to extract size to load */
  340. if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR, 32,
  341. (char *)AddressToDownload) != AT91C_DATAFLASH_OK)
  342. {
  343. printf("Bad Code Size\n");
  344. return IMAGE_BAD_SIZE;
  345. }
  346. /* calculate the size to download */
  347. SizeToDownload = *(int *)(AddressToDownload + AT91C_OFFSET_VECT6);
  348. #endif
  349. // printf("\nLoad UBOOT from dataflash[%x] to SDRAM[%x]\n",
  350. // AT91C_BOOT_DATAFLASH_ADDR, AT91C_BOOT_ADDR);
  351. if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR, SizeToDownload + 8,
  352. (char *)AddressToDownload) != AT91C_DATAFLASH_OK)
  353. {
  354. printf("F DF RD\n");
  355. return IMAGE_READ_FAILURE;
  356. }
  357. #if 0
  358. pAT91->CRC32((const unsigned char *)AT91C_BOOT_ADDR,
  359. (unsigned int)SizeToDownload , (unsigned int *)&crc2);
  360. crc1 = (int)(*(char *)(AddressToDownload + SizeToDownload)) +
  361. (int)(*(char *)(AddressToDownload + SizeToDownload + 1) << 8) +
  362. (int)(*(char *)(AddressToDownload + SizeToDownload + 2) << 16) +
  363. (int)(*(char *)(AddressToDownload + SizeToDownload + 3) << 24);
  364. /* Restore the value of Vector 6 */
  365. *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) =
  366. *(int *)(AddressToDownload + SizeToDownload + 4);
  367. if (crc1 != crc2) {
  368. printf("DF CRC bad %x != %x\n",crc1,crc2);
  369. return IMAGE_CRC_ERROR;
  370. }
  371. #endif
  372. return SUCCESS;
  373. }
  374. static int AT91F_StartBoot(void)
  375. {
  376. int sts;
  377. if((sts = AT91F_LoadBoot()) != SUCCESS) return sts;
  378. // printf("\n");
  379. // printf("PLLA[180MHz], MCK[60Mhz] ==> Start UBOOT\n");
  380. if (AT91F_ResetRegisters())
  381. {
  382. printf("Jump");
  383. Jump(AT91C_BOOT_ADDR);
  384. // LED_blink(0);
  385. }
  386. return IMAGE_ERROR;
  387. }
  388. #if 0
  389. static void AT91F_RepeatedStartBoot(void)
  390. {
  391. int i;
  392. for(i = 0; i < CRC_RETRIES; i++) {
  393. if(AT91F_StartBoot() != IMAGE_CRC_ERROR){
  394. // LED_blink(1);
  395. return;
  396. }
  397. }
  398. return;
  399. }
  400. #endif
  401. #define TRUE 1
  402. #define FALSE 0
  403. #define TRX_MAGIC 0x30524448 /* "HDR0" */
  404. #define TRX_VERSION 1
  405. struct trx_header {
  406. unsigned int magic;
  407. unsigned int len;
  408. unsigned int crc32;
  409. unsigned int flag_version;
  410. unsigned int offsets[3];
  411. };
  412. #define AT91C_MCI_TIMEOUT 1000000
  413. extern AT91S_MciDevice MCI_Device;
  414. extern void AT91F_MCIDeviceWaitReady(unsigned int);
  415. extern int AT91F_MCI_ReadBlockSwab(AT91PS_MciDevice, int, unsigned int *, int);
  416. int Program_From_MCI(void)
  417. {
  418. int i;
  419. unsigned int Max_Read_DataBlock_Length;
  420. int block = 0;
  421. int buffer = AT91C_DOWNLOAD_BASE_ADDRESS;
  422. int bufpos = AT91C_DOWNLOAD_BASE_ADDRESS;
  423. int NbPage = 0;
  424. struct trx_header *p;
  425. p = (struct trx_header *)bufpos;
  426. Max_Read_DataBlock_Length = MCI_Device.pMCI_DeviceFeatures->Max_Read_DataBlock_Length;
  427. AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT);
  428. AT91F_MCI_ReadBlockSwab(&MCI_Device, block*Max_Read_DataBlock_Length, (unsigned int *)bufpos, Max_Read_DataBlock_Length);
  429. if (p->magic != TRX_MAGIC) {
  430. printf("Inv IMG 0x%08x\n", p->magic);
  431. return FALSE;
  432. }
  433. printf("RDSD");
  434. AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC7 | AT91C_PIO_PC15 | AT91C_PIO_PC8 | AT91C_PIO_PC14;
  435. for (i=0; i<(p->len/512); i++) {
  436. AT91F_MCI_ReadBlockSwab(&MCI_Device, block*Max_Read_DataBlock_Length, (unsigned int *)bufpos, Max_Read_DataBlock_Length);
  437. block++;
  438. bufpos += Max_Read_DataBlock_Length;
  439. }
  440. NbPage = 0;
  441. i = dataflash_info[0].Device.pages_number;
  442. while(i >>= 1)
  443. NbPage++;
  444. i = ((p->offsets[1] - p->offsets[0])/ 512) + 1 + (NbPage << 13) + (dataflash_info[0].Device.pages_size << 17);
  445. *(int *)(buffer + p->offsets[0] + AT91C_OFFSET_VECT6) = i;
  446. printf(" WDFB");
  447. AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC7 | AT91C_PIO_PC15 | AT91C_PIO_PC14;
  448. AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC8;
  449. write_dataflash(0xc0000000, buffer + p->offsets[0], p->offsets[1] - p->offsets[0]);
  450. printf(" WUB");
  451. AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC7 | AT91C_PIO_PC15;
  452. AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC8 | AT91C_PIO_PC14;
  453. write_dataflash(0xc0008000, buffer + p->offsets[1], p->offsets[2] - p->offsets[1]);
  454. printf(" WKRFS");
  455. AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC8 | AT91C_PIO_PC15;
  456. AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC7 | AT91C_PIO_PC14;
  457. write_dataflash(0xc0042000, buffer + p->offsets[2], p->len - p->offsets[2]);
  458. AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC8 | AT91C_PIO_PC14;
  459. AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC7 | AT91C_PIO_PC15;
  460. return TRUE;
  461. }
  462. //*----------------------------------------------------------------------------
  463. //* Function Name : main
  464. //* Object : Main function
  465. //* Input Parameters : none
  466. //* Output Parameters : True
  467. //*----------------------------------------------------------------------------
  468. int main(void)
  469. {
  470. #ifdef XMODEM
  471. AT91PS_Buffer pXmBuffer;
  472. AT91PS_SvcComm pSvcXmodem;
  473. #endif
  474. AT91S_SvcTempo svcBootTempo; // Link to a AT91S_Tempo object
  475. unsigned int ix;
  476. volatile unsigned int AddressToDownload, SizeToDownload;
  477. unsigned int DeviceAddress = 0;
  478. char command = 0;
  479. #ifdef XMODEM
  480. volatile int i = 0;
  481. unsigned int crc1 = 0, crc2 = 0;
  482. volatile int device;
  483. int NbPage;
  484. #endif
  485. volatile int Nb_Device = 0;
  486. int mci_present = 0;
  487. pAT91 = AT91C_ROM_BOOT_ADDRESS;
  488. if (!AT91F_SetPLL())
  489. {
  490. printf("F SetPLL");
  491. while(1);
  492. }
  493. at91_init_uarts();
  494. /* Tempo Initialisation */
  495. pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC));
  496. ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC));
  497. // Attach the tempo to a tempo controler
  498. ctlTempo.CtlTempoCreate(&ctlTempo, &svcBootTempo);
  499. // LED_init();
  500. // LED_blink(2);
  501. #ifdef XMODEM
  502. /* Xmodem Initialisation */
  503. pXmBuffer = pAT91->OpenSBuffer(&sXmBuffer);
  504. pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem,
  505. (AT91PS_USART)AT91C_BASE_DBGU, &ctlTempo);
  506. pAT91->OpenPipe(&xmodemPipe, pSvcXmodem, pXmBuffer);
  507. #endif
  508. /* System Timer initialization */
  509. AT91F_AIC_ConfigureIt(
  510. AT91C_BASE_AIC, // AIC base address
  511. AT91C_ID_SYS, // System peripheral ID
  512. AT91C_AIC_PRIOR_HIGHEST, // Max priority
  513. AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive
  514. AT91F_ST_ASM_HANDLER
  515. );
  516. /* Enable ST interrupt */
  517. AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
  518. #ifndef PRODTEST
  519. /* Start tempo to start Boot in a delay of
  520. * AT91C_DELAY_TO_BOOT sec if no key pressed */
  521. svcBootTempo.Start(&svcBootTempo, AT91C_DELAY_TO_BOOT,
  522. 0, AT91F_StartBoot, NULL);
  523. #endif
  524. while(1)
  525. {
  526. while(command == 0)
  527. {
  528. AddressToDownload = AT91C_DOWNLOAD_BASE_ADDRESS;
  529. SizeToDownload = AT91C_DOWNLOAD_MAX_SIZE;
  530. DeviceAddress = 0;
  531. /* try to detect Dataflash */
  532. if (!Nb_Device)
  533. Nb_Device = AT91F_DataflashInit();
  534. mci_present = AT91F_DisplayMenu();
  535. #ifdef PRODTEST
  536. if (mci_present) {
  537. if (Program_From_MCI())
  538. AT91F_StartBoot();
  539. }
  540. #endif
  541. message[0] = 0;
  542. AT91F_ReadLine ("Enter: ", message);
  543. #ifndef PRODTEST
  544. /* stop tempo ==> stop autoboot */
  545. svcBootTempo.Stop(&svcBootTempo);
  546. #endif
  547. command = message[0];
  548. for(ix = 1; (message[ix] == ' ') && (ix < 12); ix++); // Skip some whitespace
  549. if(!AsciiToHex(&message[ix], &DeviceAddress) )
  550. DeviceAddress = 0; // Illegal DeviceAddress
  551. switch(command)
  552. {
  553. #ifdef XMODEM
  554. case '1':
  555. case '2':
  556. case '5':
  557. if(command == '1') {
  558. DeviceAddress = 0xC0000000;
  559. // printf("Download DataflashBoot.bin to [0x%x]\n", DeviceAddress);
  560. } else if(command == '2') {
  561. DeviceAddress = AT91C_BOOT_DATAFLASH_ADDR;
  562. // printf("Download u-boot.bin to [0x%x]\n", DeviceAddress);
  563. } else {
  564. // printf("Download Dataflash to [0x%x]\n", DeviceAddress);
  565. }
  566. switch(DeviceAddress & 0xFF000000)
  567. {
  568. case CFG_DATAFLASH_LOGIC_ADDR_CS0:
  569. if (dataflash_info[0].id == 0){
  570. printf("No DF");
  571. AT91F_WaitKeyPressed();
  572. command = 0;
  573. }
  574. device = 0;
  575. break;
  576. case CFG_DATAFLASH_LOGIC_ADDR_CS3:
  577. if (dataflash_info[1].id == 0){
  578. printf("No DF");
  579. AT91F_WaitKeyPressed();
  580. command = 0;
  581. }
  582. device = 1;
  583. break;
  584. default:
  585. command = 0;
  586. break;
  587. }
  588. break;
  589. #endif
  590. case '3':
  591. if (mci_present)
  592. Program_From_MCI();
  593. command = 0;
  594. break;
  595. case '4':
  596. AT91F_StartBoot();
  597. command = 0;
  598. break;
  599. #ifdef MEMDISP
  600. case '6':
  601. do
  602. {
  603. AT91F_MemoryDisplay(DeviceAddress, 256);
  604. AT91F_ReadLine (NULL, message);
  605. DeviceAddress += 0x100;
  606. }
  607. while(message[0] == '\0');
  608. command = 0;
  609. break;
  610. #endif
  611. case '7':
  612. switch(DeviceAddress & 0xFF000000)
  613. {
  614. case CFG_DATAFLASH_LOGIC_ADDR_CS0:
  615. break;
  616. case CFG_DATAFLASH_LOGIC_ADDR_CS3:
  617. break;
  618. default:
  619. command = 0;
  620. break;
  621. }
  622. if (command != 0) {
  623. AT91F_ReadLine ("RDY ERA\nSure?",
  624. message);
  625. if(message[0] == 'Y' || message[0] == 'y') {
  626. erase_dataflash(DeviceAddress & 0xFF000000);
  627. // printf("Erase complete\n\n");
  628. }
  629. // else
  630. // printf("Erase aborted\n");
  631. }
  632. command = 0;
  633. break;
  634. default:
  635. command = 0;
  636. break;
  637. }
  638. }
  639. #ifdef XMODEM
  640. for(i = 0; i <= AT91C_DOWNLOAD_MAX_SIZE; i++)
  641. *(unsigned char *)(AddressToDownload + i) = 0;
  642. xmodemPipe.Read(&xmodemPipe, (char *)AddressToDownload,
  643. SizeToDownload, XmodemProtocol, 0);
  644. while(XmodemComplete !=1);
  645. SizeToDownload = (unsigned int)((svcXmodem.pData) -
  646. (unsigned int)AddressToDownload);
  647. /* Modification of vector 6 */
  648. if ((DeviceAddress == CFG_DATAFLASH_LOGIC_ADDR_CS0)) {
  649. // Vector 6 must be compliant to the BootRom description (ref Datasheet)
  650. NbPage = 0;
  651. i = dataflash_info[device].Device.pages_number;
  652. while(i >>= 1)
  653. NbPage++;
  654. i = (SizeToDownload / 512)+1 + (NbPage << 13) +
  655. (dataflash_info[device].Device.pages_size << 17); //+4 to add crc32
  656. SizeToDownload = 512 * (i &0xFF);
  657. }
  658. else
  659. {
  660. /* Save the contents of vector 6 ==> will be restored
  661. * at boot time (AT91F_StartBoot) */
  662. *(int *)(AddressToDownload + SizeToDownload + 4) =
  663. *(int *)(AddressToDownload + AT91C_OFFSET_VECT6);
  664. /* Modify Vector 6 to contain the size of the
  665. * file to copy (Dataflash -> SDRAM)*/
  666. i = SizeToDownload;
  667. }
  668. *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) = i;
  669. // printf("\nModification of Arm Vector 6 :%x\n", i);
  670. // printf("\nWrite %d bytes in DataFlash [0x%x]\n",SizeToDownload, DeviceAddress);
  671. crc1 = 0;
  672. pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc1);
  673. /* Add the crc32 at the end of the code */
  674. *(char *)(AddressToDownload + SizeToDownload) = (char)(crc1 & 0x000000FF);
  675. *(char *)(AddressToDownload + SizeToDownload + 1) = (char)((crc1 & 0x0000FF00) >> 8);
  676. *(char *)(AddressToDownload + SizeToDownload + 2) = (char)((crc1 & 0x00FF0000) >> 16);
  677. *(char *)(AddressToDownload + SizeToDownload + 3) = (char)((crc1 & 0xFF000000) >> 24);
  678. /* write dataflash */
  679. write_dataflash (DeviceAddress, AddressToDownload, (SizeToDownload + 8));
  680. /* clear the buffer before read */
  681. for(i=0; i <= SizeToDownload; i++)
  682. *(unsigned char *)(AddressToDownload + i) = 0;
  683. /* Read dataflash to check the validity of the data */
  684. read_dataflash (DeviceAddress, (SizeToDownload + 4), (char *)(AddressToDownload));
  685. printf("VFY: ");
  686. crc2 = 0;
  687. pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc2);
  688. crc1 = (int)(*(char *)(AddressToDownload + SizeToDownload)) +
  689. (int)(*(char *)(AddressToDownload + SizeToDownload + 1) << 8) +
  690. (int)(*(char *)(AddressToDownload + SizeToDownload + 2) << 16) +
  691. (int)(*(char *)(AddressToDownload + SizeToDownload + 3) << 24);
  692. if (crc1 != crc2)
  693. printf("ERR");
  694. else
  695. printf("OK");
  696. command = 0;
  697. XmodemComplete = 0;
  698. AT91F_WaitKeyPressed();
  699. #endif
  700. }
  701. }