1 //****************************************************************************
3 // DOWNLOAD.C - Automates the download of code into the flash on the
4 // Cirrus Logic EDB7XXX boards.
6 // Copyright (c) 1999 Cirrus Logic, Inc.
8 // Adapted for Linux by Red Hat, Inc.
9 // Renamed 'dl_edb7xxx' to indicate support for all Cirrus Logic eval boards.
11 //****************************************************************************
16 #define CHAR_READY_IS_RELIABLE
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);
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
36 //****************************************************************************
38 // WaitFor waits until a specific character is read from the comm port.
40 //****************************************************************************
42 WaitFor(long lPort, char cWaitChar)
47 // Wait until we read a specific character from the comm port.
54 cChar = ReceiveChar(lPort);
57 // Stop waiting if we received the character.
59 if(cChar == cWaitChar)
66 //****************************************************************************
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.
74 //****************************************************************************
76 main(int argc, char *argv[])
81 char cChar, cFirstChar, *pcFile, cRateChar;
85 // Make sure that a filename was specified.
89 fprintf(stderr, "Usage: %s <filename> {<baud rate> {<comm port>}}\n", argv[0]);
94 // If a baud rate was specified, then read it and make sure it is valid.
98 lRate = atoi(argv[2]);
99 if((lRate != 9600) && (lRate != 19200) && (lRate != 28800) &&
100 (lRate != 38400) && (lRate != 57600) && (lRate != 115200))
102 fprintf(stderr, "Invalid baud rate: %d(%s).\n", lRate, argv[2]);
108 // If a comm port was specified, then read it and make sure it is valid.
112 lPort = OpenPort(argv[3]);
115 fprintf(stderr, "Can't open port: %s\n", argv[3]);
120 lPort = OpenPort(DEFAULT_PORT);
123 fprintf(stderr, "Can't open port: %s\n", DEFAULT_PORT);
129 // Open the file to be downloaded.
131 pFile = fopen(argv[1], "rb");
134 fprintf(stderr, "Could not open file '%s'.\n", argv[1]);
139 // Get the size of the file.
141 fseek(pFile, 0, SEEK_END);
142 lFileSize = ftell(pFile);
143 fseek(pFile, 0, SEEK_SET);
146 // Allocate memory to hold the file contents.
148 pcFile = (char *)malloc(lFileSize);
151 fprintf(stderr, "Failed to allocate memory for the file.\n");
156 // Read the contents of the file into memory.
158 if(fread(pcFile, 1, lFileSize, pFile) != lFileSize)
160 fprintf(stderr, "Failed to read file '%s'.\n", argv[1]);
170 // Get the baud rate divisor for the given baud rate.
172 SetBaud(lPort, 9600);
213 // Empty out the input queue.
215 #ifdef CHAR_READY_IS_RELIABLE
216 while(CharReady(lPort))
218 cChar = ReceiveChar(lPort);
223 // Tell the user to reset the board.
225 fprintf(stderr, "Waiting for the board to wakeup...");
228 // Wait until we read a '<' from the comm port.
233 // Tell the user that we are downloading the boot code.
235 fprintf(stderr, "\nDownloading boot code...( 0%%)");
238 // Write the boot code to the comm port.
240 for(lIdx = 0; lIdx < 2048; lIdx++)
243 // Write this character.
245 SendChar(lPort, pcBoot[lIdx]);
248 // Periodically print out our progress.
250 if((lIdx & 127) == 127)
252 fprintf(stderr, "\b\b\b\b\b%3d%%)", ((lIdx + 1) * 100) / 2048);
257 // Wait until we read a '>' from the comm port.
262 // Wait until we read a '?' from the comm port.
267 // Tell the boot code to switch to the desired baud rate.
269 SendChar(lPort, 'B');
270 SendChar(lPort, cRateChar);
273 // Wait until the output buffer is empty.
275 WaitForOutputEmpty();
278 // Switch our baud rate to the desired rate.
280 SetBaud(lPort, lRate);
283 // Send a '-' character until we receive back a '?' character.
288 // Send a '-' character.
290 SendChar(lPort, '-');
293 // Wait a little bit.
295 for(lIdx = 0; lIdx < 1024 * 1024; lIdx++)
300 // See if there is a character waiting to be read.
302 #ifdef CHAR_READY_IS_RELIABLE
309 // Read the character.
311 cChar = ReceiveChar(lPort);
314 // Quit waiting if this is a '?'.
324 // Empty out the input queue.
326 #ifdef CHAR_READY_IS_RELIABLE
327 while(CharReady(lPort))
329 cChar = ReceiveChar(lPort);
334 // Send the program flash command.
336 SendChar(lPort, 'F');
339 // We always program the flash at location 0.
347 // Send the length of the data file.
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));
355 // Tell the user that we are downloading the file data.
357 fprintf(stderr, "\nDownloading file data...( 0%%)");
360 // Send the actual data in the file.
362 for(lIdx = 0; lIdx < lFileSize; lIdx++)
367 SendChar(lPort, pcFile[lIdx]);
370 // Periodically print out our progress.
372 if((lIdx & 127) == 127)
374 fprintf(stderr, "\b\b\b\b\b%3d%%)", ((lIdx + 1) * 100) / lFileSize);
379 // Tell the user that we are erasing the flash.
381 fprintf(stderr, "\nErasing the flash...( 0%%)");
384 // Wait until the flash has been erased.
386 cFirstChar = cChar = ReceiveChar(lPort);
390 // Print out our progress.
392 fprintf(stderr, "\b\b\b\b\b%3d%%)",
393 ((cFirstChar - cChar + 1) * 100) / (cFirstChar - '0'));
394 fprintf(stderr, "%c\n", cChar);
397 // Read a character from the boot code.
399 cChar = ReceiveChar(lPort);
403 // Tell the user that we are programming the flash.
405 fprintf(stderr, "\nProgramming the flash...( 0%%)");
408 // Wait until the flash has been programmed.
414 // Read a character from the boot code.
416 cChar = ReceiveChar(lPort);
419 // If the character is a '?', then we are done.
427 // Print out our progress.
429 fprintf(stderr, "\b\b\b\b\b%3d%%)",
430 (++lIdx * 100) / ((lFileSize + 1023) / 1024));
434 // Tell the user we are done.
436 fprintf(stderr, "\nSuccessfully downloaded '%s'.\n", argv[1]);