Added SRIO boot example, added binary support for writers
[keystone-rtos/mcsdk-tools.git] / writer / eeprom / src / eepromwriter.c
1 /******************************************************************************
2  * Copyright (c) 2011 Texas Instruments Incorporated - http://www.ti.com
3  *
4  *  Redistribution and use in source and binary forms, with or without
5  *  modification, are permitted provided that the following conditions
6  *  are met:
7  *
8  *    Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *
11  *    Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the
14  *    distribution.
15  *
16  *    Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  *****************************************************************************/
34 /**************************************************************************************
35  * FILE PURPOSE: EEPROM writer utility
36  **************************************************************************************
37  * FILE NAME: eepromwriter.c
38  *
39  * DESCRIPTION: A simple EEPROM writer using platform lib APIs to program the EEPROM
40  *              with an image that the ibl can read.
41  *
42  ***************************************************************************************/
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include "platform.h"
47 #include "types.h"
49 /* EEPROM writer utility version */
50 char version[] = "01.00.00.02";
52 /* The input file name is hard coded */
53 char *input_file = "eepromwriter_input.txt";
55 /* Parameters defined in the input_file */
56 #define FILE_NAME      "file_name"
57 #define BUS_ADDR       "bus_addr"
58 #define START_ADDR     "start_addr"
59 #define SWAP_DATA      "swap_data"
61 /* Memory address to store the write data */
62 #define WRITE_DATA_ADDRESS     0x80000000
64 /******************************************************************************
65  * Structure:   EEPROM_WRITER_INFO_T
66  *
67  *              EEPROM writer control data. This structure should be filled in
68  *              by the user before running
69  ******************************************************************************/
70 #define MAX_LINE_LENGTH 40
71 typedef struct EEPROM_WRITER_INFO_tag
72 {
73     char        file_name[MAX_LINE_LENGTH]; /* CCS format data file name */
74     uint32_t    busAddr;                    /* Slave bus address */
75     uint32_t    startAddr;                  /* Start address to write */
76     uint32_t    swapData;                   /* Swap byte in the 32-bit word of the data */
77     uint32_t    deviceTotalBytes;           /* Total number of bytes available in the device */
78     uint32_t    writeBytes;                 /* Number of bytes to be written into the device */
79     uint8_t     *writeData;                 /* Address to store the write data */
80     uint8_t     *readData;                  /* Address to store the read data */
82 } EEPROM_WRITER_INFO_T;
84 EEPROM_WRITER_INFO_T eepromWriterInfo;
86 /******************************************************************************
87  * Function:    print_platform_errno
88  ******************************************************************************/
89 void
90 print_platform_errno
91 (
92     void
93 )
94 {
95     printf ("Returned platform error number is %d\n", platform_errno);
96 }
98 /******************************************************************************
99  * Function:    form_block
100  *
101  *      Form a block of data to write to the NOR. The block is
102  *      created as a byte stream from the 4 byte stream in which
103  *      the MSB is always sent first.
104  ******************************************************************************/
105 void
106 formBlock
108     uint32_t      *data,
109     uint32_t      blockSize,
110     uint8_t       *scratch
113     uint32_t i, j;
115     /* Convert the data to a byte stream */
116     for (i = j = 0; j < blockSize; i++, j+=4)
117     {
118         scratch[j+0] = (data[i] >> 24) & 0xff;
119         scratch[j+1] = (data[i] >> 16) & 0xff;
120         scratch[j+2] = (data[i] >>  8) & 0xff;
121         scratch[j+3] = (data[i] >>  0) & 0xff;
122     }
125 /******************************************************************************
126  * Function:    flash_eeprom
127  *
128  *              Write the data from memory to EEPROM.
129  *              Returns TRUE if the data is written successfully
130  *                      FALSE if the data write fails
131  ******************************************************************************/
132 Bool
133 flash_eeprom
135     PLATFORM_DEVICE_info    *p_device
138     uint8_t       *scrach_block;
140     printf ("Writing %d bytes from DSP memory address 0x%08x to EEPROM bus address 0x%04x starting from device address 0x%04x ...\n",
141             eepromWriterInfo.writeBytes,
142             (uint32_t)eepromWriterInfo.writeData,
143             eepromWriterInfo.busAddr,
144             eepromWriterInfo.startAddr);
146     if (eepromWriterInfo.swapData)
147     {
148             scrach_block = malloc(eepromWriterInfo.deviceTotalBytes);
149             if (scrach_block == NULL)
150             {
151                 printf ("Can not allocate scratch block memory!\n");
152                 return (FALSE);
153             }
154         formBlock((uint32_t *)(eepromWriterInfo.writeData), eepromWriterInfo.deviceTotalBytes, scrach_block);
155         }
156         else
157         {
158                 scrach_block = eepromWriterInfo.writeData;
159         }
161     if(platform_device_write(p_device->handle, eepromWriterInfo.startAddr, scrach_block, eepromWriterInfo.writeBytes) != Platform_EOK)
162     {
163         print_platform_errno();
164         if (eepromWriterInfo.swapData)
165                 free (scrach_block);
166         return FALSE;
167     }
169         if(eepromWriterInfo.swapData)
170         free (scrach_block);
172     return TRUE;
175 /******************************************************************************
176  * Function:    flash_verify
177  *
178  *              Read back the data file that was just flashed.
179  *              Returns TRUE if the data verified correctly.
180  *                      FALSE if the data verification failed
181  ******************************************************************************/
182 Bool
183 flash_verify
185     PLATFORM_DEVICE_info    *p_device
188     uint32_t    i, j;
189     uint8_t     *scrach_block;
190     uint32_t    *read_data_w;
192     printf ("Reading %d bytes from EEPROM bus address 0x%04x to DSP memory address 0x%08x starting from device address 0x%04x ...\n",
193             eepromWriterInfo.writeBytes,
194             eepromWriterInfo.busAddr,
195             (uint32_t)eepromWriterInfo.readData,
196             eepromWriterInfo.startAddr);
198     if (eepromWriterInfo.swapData)
199     {
200             scrach_block = malloc(eepromWriterInfo.deviceTotalBytes);
201             if (scrach_block == NULL)
202             {
203                 printf ("Can not allocate scratch block memory!\n");
204                 return (FALSE);
205             }
206         }
207         else
208         {
209                 scrach_block = eepromWriterInfo.readData;
210         }
212     if(platform_device_read(p_device->handle, eepromWriterInfo.startAddr, scrach_block, eepromWriterInfo.writeBytes) != Platform_EOK)
213     {
214         print_platform_errno();
215         return FALSE;
216     }
218     printf ("Verifying data read ...\n");
220     if (eepromWriterInfo.swapData)
221     {
222         /* Convert the packed data */
223         read_data_w = (uint32_t *)(eepromWriterInfo.readData);
224         for  (i = 0, j = 0; i < eepromWriterInfo.deviceTotalBytes; i += 4)
225             read_data_w[j++] = (scrach_block[i+0] << 24) | (scrach_block[i+1] << 16) | (scrach_block[i+2] << 8) | scrach_block[i+3];
226    }
229     for (i = 0; i < eepromWriterInfo.writeBytes; i++)
230     {
231         if (eepromWriterInfo.readData[i] != eepromWriterInfo.writeData[i])
232         {
233             printf ("Failure at byte %d, expected 0x%08x, read 0x%08x\n", i, eepromWriterInfo.writeData[i], eepromWriterInfo.readData[i]);
234             return (FALSE);
235         }
236     }
238     return (TRUE);
241 /******************************************************************************
242  * Function:    parse_input_file
243  ******************************************************************************/
244 static Bool
245 parse_input_file
247     FILE*               fp
250     char line[MAX_LINE_LENGTH];
251     char tokens[] = " :=;\n";
252     char *key, *data;
254     memset(line, 0, MAX_LINE_LENGTH);
256     fgets(line, MAX_LINE_LENGTH, fp);
257     key  = (char *)strtok(line, tokens);
258     data = (char *)strtok(NULL, tokens);
260     if(strlen(data) == 0)
261     {
262        return FALSE;
263     }
265     if(strcmp(key, FILE_NAME) != 0)
266     {
267         return FALSE;
268     }
270     strcpy (eepromWriterInfo.file_name, data);
272     fgets(line, MAX_LINE_LENGTH, fp);
273     key  = (char *)strtok(line, tokens);
274     data = (char *)strtok(NULL, tokens);
276     if(strlen(data) == 0)
277     {
278        return FALSE;
279     }
281     if(strcmp(key, BUS_ADDR) != 0)
282     {
283         return FALSE;
284     }
286     eepromWriterInfo.busAddr = (uint32_t)atoi(data);
288     fgets(line, MAX_LINE_LENGTH, fp);
289     key  = (char *)strtok(line, tokens);
290     data = (char *)strtok(NULL, tokens);
292     if(strlen(data) == 0)
293     {
294        return FALSE;
295     }
297     if(strcmp(key, START_ADDR) != 0)
298     {
299         return FALSE;
300     }
302     eepromWriterInfo.startAddr = (uint32_t)atoi(data);
304     fgets(line, MAX_LINE_LENGTH, fp);
305     key  = (char *)strtok(line, tokens);
306     data = (char *)strtok(NULL, tokens);
308     if(strlen(data) == 0)
309     {
310        return FALSE;
311     }
313     if(strcmp(key, SWAP_DATA) != 0)
314     {
315         return FALSE;
316     }
318     eepromWriterInfo.swapData = (uint32_t)atoi(data);
320     return TRUE;
323 /******************************************************************************
324  * Function:    find_file_length
325  ******************************************************************************/
326 static Bool
327 find_file_length
329     FILE*               fp
332     char        line[MAX_LINE_LENGTH];
333     char        *pEnd;
334     char        *ext;
335     uint32_t    data_len, write_addr;
337     memset(line, 0, MAX_LINE_LENGTH);
339     ext = strrchr(eepromWriterInfo.file_name, '.');
342     if (ext && (strcmp(ext, ".dat") == 0))
343     {
344         
345         fgets(line, MAX_LINE_LENGTH, fp);
346         
347         /* Read the write address from the CCS header */
348         strtoul (line,&pEnd,16);
349         strtoul (pEnd,&pEnd,16);
350         write_addr = strtoul (pEnd,&pEnd,16);
351         strtoul (pEnd,&pEnd,16);
352         
353         /* Read the data length */
354         data_len = (strtoul (pEnd,NULL,16)) * 4;
355     }
356     else
357     {
358         /* find the data length by seeking to the end and getting position */
359         fseek(fp, 0, SEEK_END);
360         data_len = ftell(fp);
361         fseek(fp, 0, SEEK_SET);
362     }
364     if (data_len > (eepromWriterInfo.deviceTotalBytes - eepromWriterInfo.startAddr))
365     {
366         printf ("The data file is too big to fit into the device.\n");
367         return FALSE;
368     }
370     eepromWriterInfo.writeBytes = data_len;
371     if (write_addr != WRITE_DATA_ADDRESS)
372         write_addr = WRITE_DATA_ADDRESS;
373     eepromWriterInfo.writeData  = (uint8_t *)write_addr;
374     eepromWriterInfo.readData   = (uint8_t *)(write_addr + eepromWriterInfo.deviceTotalBytes);
376     return TRUE;
379 /******************************************************************************
380  * Function:    main
381  ******************************************************************************/
382 void main ()
384     FILE                    *fp;
385     platform_init_flags     init_flags;
386     platform_init_config    init_config;
387     PLATFORM_DEVICE_info    *p_device;
388     Bool                    ret;
390     printf("EEPROM Writer Utility Version %s\n\n", version);
392     fp = fopen(input_file, "r");
393     if (fp == NULL)
394     {
395         printf("Error in opening %s input file\n", input_file);
396         return;
397     }
399     ret = parse_input_file(fp);
400     fclose (fp);
402     if (ret == FALSE)
403     {
404         printf("Error in parsing %s input file\n", input_file);
405         return;
406     }
408     /* Initialize main Platform lib */
409     memset(&init_config, 0, sizeof(platform_init_config));
410     memset(&init_flags, 0x01, sizeof(platform_init_flags));
411     init_flags.phy = 0;
413     if (platform_init(&init_flags, &init_config) != Platform_EOK)
414     {
415         printf ("Platform init failed!\n");
416         print_platform_errno();
417         return;
418     }
420     p_device = platform_device_open(eepromWriterInfo.busAddr, 0);
421     if (p_device == NULL)
422     {
423         printf ("EEPROM device open failed!\n");
424         print_platform_errno();
425         return;
426     }
427     eepromWriterInfo.deviceTotalBytes = p_device->block_count * p_device->page_count * p_device->page_size;
429     /* Open and find the length of the data file */
430     fp = fopen (eepromWriterInfo.file_name, "rb");
431     if (fp == NULL)
432     {
433         printf ("Failed to open file %s\n", eepromWriterInfo.file_name);
434         print_platform_errno();
435         platform_device_close(p_device->handle);
436         return;
437     }
439     /* Parse the CCS format file */
440     ret = find_file_length(fp);
441     fclose (fp);
442     if (ret == FALSE)
443     {
444         printf("Error in parsing CCS file %s\n", eepromWriterInfo.file_name);
445         platform_device_close(p_device->handle);
446         return;
447     }
449     /* Write the EEPROM */
450     if (flash_eeprom (p_device) == FALSE)
451     {
452         printf ("EEPROM write failed\n");
453         platform_device_close(p_device->handle);
454         return;
455     }
457     /* verify the flash */
458     if(flash_verify (p_device) == FALSE)
459     {
460         printf ("EEPROM read verify failed\n");
461         platform_device_close(p_device->handle);
462         return;
463     }
466     printf ("EEPROM programming completed successfully\n");
468     platform_device_close(p_device->handle);
470     return;