]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/edb7xxx/v2_0/support/dl_edb7xxx.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / edb7xxx / v2_0 / support / dl_edb7xxx.c
1 //****************************************************************************
2 //
3 // DOWNLOAD.C - Automates the download of code into the flash on the
4 //              Cirrus Logic EDB7XXX boards.
5 //
6 // Copyright (c) 1999 Cirrus Logic, Inc.
7 //
8 // Adapted for Linux by Red Hat, Inc.
9 //   Renamed 'dl_edb7xxx' to indicate support for all Cirrus Logic eval boards.
10 //
11 //****************************************************************************
12 #include <stdio.h>
13 #include "bootcode.h"
14
15 #ifndef _WIN32
16 #define CHAR_READY_IS_RELIABLE
17 #endif
18
19 #define DEFAULT_PORT "/dev/ttyS0"
20 extern char _ReceiveChar(long);
21 extern void _SendChar(long, char);
22 extern void _SetBaud(long, long);
23 extern int  _CharRead(long port);
24 extern void _WaitForOutputReady(long port);
25 extern long _OpenPort(char *);
26 extern int  _CharReady(long port);
27
28 #define ReceiveChar _ReceiveChar
29 #define SendChar    _SendChar
30 #define SetBaud     _SetBaud
31 #define CharRead    _CharRead
32 #define WaitForOutputEmpty _WaitForOutputEmpty
33 #define OpenPort    _OpenPort
34 #define CharReady   _CharReady
35
36 //****************************************************************************
37 //
38 // WaitFor waits until a specific character is read from the comm port.
39 //
40 //****************************************************************************
41 void
42 WaitFor(long lPort, char cWaitChar)
43 {
44     char cChar;
45
46     //
47     // Wait until we read a specific character from the comm port.
48     //
49     while(1)
50     {
51         //
52         // Read a character.
53         //
54         cChar = ReceiveChar(lPort);
55
56         //
57         // Stop waiting if we received the character.
58         //
59         if(cChar == cWaitChar)
60         {
61             break;
62         }
63     }
64 }
65
66 //****************************************************************************
67 //
68 // This program waits for the '<' character from the boot ROM, sends the boot
69 // code, waits for the '>' from the boot ROM, waits for the '?' from the boot
70 // code, changes the serial port rate (preferably to 115200), downloads the
71 // user data file, and then prints out progress status as the boot code writes
72 // the user data file to the flash.
73 //
74 //****************************************************************************
75 void
76 main(int argc, char *argv[])
77 {
78     long lPort;
79     long lRate = 38400;
80     long lFileSize, lIdx;
81     char cChar, cFirstChar, *pcFile, cRateChar;
82     FILE *pFile;
83
84     //
85     // Make sure that a filename was specified.
86     //
87     if(argc < 2)
88     {
89         fprintf(stderr, "Usage: %s <filename> {<baud rate> {<comm port>}}\n", argv[0]);
90         return;
91     }
92
93     //
94     // If a baud rate was specified, then read it and make sure it is valid.
95     //
96     if(argc > 2)
97     {
98         lRate = atoi(argv[2]);
99         if((lRate != 9600) && (lRate != 19200) && (lRate != 28800) &&
100            (lRate != 38400) && (lRate != 57600) && (lRate != 115200))
101         {
102             fprintf(stderr, "Invalid baud rate: %d(%s).\n", lRate, argv[2]);
103             return;
104         }
105     }
106
107     //
108     // If a comm port was specified, then read it and make sure it is valid.
109     //
110     if(argc > 3)
111     {
112         lPort = OpenPort(argv[3]);
113         if (lPort < 0)
114         {
115             fprintf(stderr, "Can't open port: %s\n", argv[3]);
116             return;
117         }
118     } else 
119     {
120         lPort = OpenPort(DEFAULT_PORT);
121         if (lPort < 0)
122         {
123             fprintf(stderr, "Can't open port: %s\n", DEFAULT_PORT);
124             return;
125         }
126     }
127
128     //
129     // Open the file to be downloaded.
130     //
131     pFile = fopen(argv[1], "rb");
132     if(!pFile)
133     {
134         fprintf(stderr, "Could not open file '%s'.\n", argv[1]);
135         return;
136     }
137
138     //
139     // Get the size of the file.
140     //
141     fseek(pFile, 0, SEEK_END);
142     lFileSize = ftell(pFile);
143     fseek(pFile, 0, SEEK_SET);
144
145     //
146     // Allocate memory to hold the file contents.
147     //
148     pcFile = (char *)malloc(lFileSize);
149     if(!pcFile)
150     {
151         fprintf(stderr, "Failed to allocate memory for the file.\n");
152         return;
153     }
154
155     //
156     // Read the contents of the file into memory.
157     //
158     if(fread(pcFile, 1, lFileSize, pFile) != lFileSize)
159     {
160         fprintf(stderr, "Failed to read file '%s'.\n", argv[1]);
161         return;
162     }
163
164     //
165     // Close the file.
166     //
167     fclose(pFile);
168
169     //
170     // Get the baud rate divisor for the given baud rate.
171     //
172     SetBaud(lPort, 9600);
173     switch(lRate)
174     {
175         case 9600:
176         {
177             cRateChar = '0';
178             break;
179         }
180
181         case 19200:
182         {
183             cRateChar = '1';
184             break;
185         }
186
187         case 28800:
188         {
189             cRateChar = '2';
190             break;
191         }
192
193         case 38400:
194         {
195             cRateChar = '3';
196             break;
197         }
198
199         case 57600:
200         {
201             cRateChar = '4';
202             break;
203         }
204
205         case 115200:
206         {
207             cRateChar = '5';
208             break;
209         }
210     }
211
212     //
213     // Empty out the input queue.
214     //
215 #ifdef CHAR_READY_IS_RELIABLE
216     while(CharReady(lPort))
217     {
218         cChar = ReceiveChar(lPort);
219     }
220 #endif
221
222     //
223     // Tell the user to reset the board.
224     //
225     fprintf(stderr, "Waiting for the board to wakeup...");
226
227     //
228     // Wait until we read a '<' from the comm port.
229     //
230     WaitFor(lPort, '<');
231
232     //
233     // Tell the user that we are downloading the boot code.
234     //
235     fprintf(stderr, "\nDownloading boot code...(  0%%)");
236
237     //
238     // Write the boot code to the comm port.
239     //
240     for(lIdx = 0; lIdx < 2048; lIdx++)
241     {
242         //
243         // Write this character.
244         //
245         SendChar(lPort, pcBoot[lIdx]);
246
247         //
248         // Periodically print out our progress.
249         //
250         if((lIdx & 127) == 127)
251         {
252             fprintf(stderr, "\b\b\b\b\b%3d%%)", ((lIdx + 1) * 100) / 2048);
253         }
254     }
255             
256     //
257     // Wait until we read a '>' from the comm port.
258     //
259     WaitFor(lPort, '>');
260
261     //
262     // Wait until we read a '?' from the comm port.
263     //
264     WaitFor(lPort, '?');
265
266     //
267     // Tell the boot code to switch to the desired baud rate.
268     //
269     SendChar(lPort, 'B');
270     SendChar(lPort, cRateChar);
271
272     //
273     // Wait until the output buffer is empty.
274     //
275     WaitForOutputEmpty();
276
277     //
278     // Switch our baud rate to the desired rate.
279     //
280     SetBaud(lPort, lRate);
281
282     //
283     // Send a '-' character until we receive back a '?' character.
284     //
285     while(1)
286     {
287         //
288         // Send a '-' character.
289         //
290         SendChar(lPort, '-');
291
292         //
293         // Wait a little bit.
294         //
295         for(lIdx = 0; lIdx < 1024 * 1024; lIdx++)
296         {
297         }
298
299         //
300         // See if there is a character waiting to be read.
301         //
302 #ifdef CHAR_READY_IS_RELIABLE
303         if(CharReady(lPort))
304 #else
305         if (1)
306 #endif
307         {
308             //
309             // Read the character.
310             //
311             cChar = ReceiveChar(lPort);
312
313             //
314             // Quit waiting if this is a '?'.
315             //
316             if(cChar == '?')
317             {
318                 break;
319             }
320         }
321     }
322
323     //
324     // Empty out the input queue.
325     //
326 #ifdef CHAR_READY_IS_RELIABLE
327     while(CharReady(lPort))
328     {
329         cChar = ReceiveChar(lPort);
330     }
331 #endif
332
333     //
334     // Send the program flash command.
335     //
336     SendChar(lPort, 'F');
337
338     //
339     // We always program the flash at location 0.
340     //
341     SendChar(lPort, 0);
342     SendChar(lPort, 0);
343     SendChar(lPort, 0);
344     SendChar(lPort, 0);
345
346     //
347     // Send the length of the data file.
348     //
349     SendChar(lPort, (char)(lFileSize & 0xFF));
350     SendChar(lPort, (char)((lFileSize >> 8) & 0xFF));
351     SendChar(lPort, (char)((lFileSize >> 16) & 0xFF));
352     SendChar(lPort, (char)((lFileSize >> 24) & 0xFF));
353
354     //
355     // Tell the user that we are downloading the file data.
356     //
357     fprintf(stderr, "\nDownloading file data...(  0%%)");
358
359     //
360     // Send the actual data in the file.
361     //
362     for(lIdx = 0; lIdx < lFileSize; lIdx++)
363     {
364         //
365         // Send this byte.
366         //
367         SendChar(lPort, pcFile[lIdx]);
368
369         //
370         // Periodically print out our progress.
371         //
372         if((lIdx & 127) == 127)
373         {
374             fprintf(stderr, "\b\b\b\b\b%3d%%)", ((lIdx + 1) * 100) / lFileSize);
375         }
376     }
377
378     //
379     // Tell the user that we are erasing the flash.
380     //
381     fprintf(stderr, "\nErasing the flash...(  0%%)");
382
383     //
384     // Wait until the flash has been erased.
385     //
386     cFirstChar = cChar = ReceiveChar(lPort);
387     while(cChar != '1')
388     {
389         //
390         // Print out our progress.
391         //
392         fprintf(stderr, "\b\b\b\b\b%3d%%)",
393                ((cFirstChar - cChar + 1) * 100) / (cFirstChar - '0'));
394         fprintf(stderr, "%c\n", cChar);
395
396         //
397         // Read a character from the boot code.
398         //
399         cChar = ReceiveChar(lPort);
400     }
401
402     //
403     // Tell the user that we are programming the flash.
404     //
405     fprintf(stderr, "\nProgramming the flash...(  0%%)");
406
407     //
408     // Wait until the flash has been programmed.
409     //
410     lIdx = 0;
411     while(1)
412     {
413         //
414         // Read a character from the boot code.
415         //
416         cChar = ReceiveChar(lPort);
417
418         //
419         // If the character is a '?', then we are done.
420         //
421         if(cChar == '?')
422         {
423             break;
424         }
425
426         //
427         // Print out our progress.
428         //
429         fprintf(stderr, "\b\b\b\b\b%3d%%)",
430                (++lIdx * 100) / ((lFileSize + 1023) / 1024));
431     }
432
433     //
434     // Tell the user we are done.
435     //
436     fprintf(stderr, "\nSuccessfully downloaded '%s'.\n", argv[1]);
437 }
438