OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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*/ |
||
67 | extern void AT91F_ST_ASM_HANDLER(void); |
||
68 | extern void Jump(unsigned int addr); |
||
69 | |||
70 | const 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 | |||
93 | char message[20]; |
||
94 | #ifdef XMODEM |
||
95 | volatile char XmodemComplete = 0; |
||
96 | #endif |
||
97 | unsigned int StTick = 0; |
||
98 | |||
99 | AT91S_RomBoot const *pAT91; |
||
100 | #ifdef XMODEM |
||
101 | AT91S_SBuffer sXmBuffer; |
||
102 | AT91S_SvcXmodem svcXmodem; |
||
103 | AT91S_Pipe xmodemPipe; |
||
104 | #endif |
||
105 | AT91S_CtlTempo ctlTempo; |
||
106 | |||
107 | |||
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) |
||
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 | //*-------------------------------------------------------------------------------------- |
||
126 | static 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 | //*-------------------------------------------------------------------------------------- |
||
140 | static 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 | //*-------------------------------------------------------------------------------------- |
||
158 | void 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 | //*----------------------------------------------------------------------------- |
||
197 | static 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 | //*----------------------------------------------------------------------------- |
||
216 | static 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 | //*----------------------------------------------------------------------------- |
||
252 | static 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 | //*-------------------------------------------------------------------------------------- |
||
312 | static 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 | //*-------------------------------------------------------------------------------------- |
||
349 | static 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 | |||
383 | static 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 | |||
429 | static 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 |
||
445 | static 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 | |||
463 | struct 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 | |||
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); |
||
476 | |||
477 | int 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 | //*---------------------------------------------------------------------------- |
||
538 | int 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 |