1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-12-02 14:29:42 +02:00
openwrt-xburst/openwrt/target/linux/image/ar7/src/srec2bin.c

639 lines
20 KiB
C
Raw Normal View History

/*-----------------------------------------------------------------------------*/
/* */
/* Copyright (C) 1999-2000 by Texas Instruments, Inc. All rights reserved. */
/* */
/* IMPORTANT - READ CAREFULLY BEFORE PROCEEDING TO USE SOFTWARE. */
/* */
/* This document is displayed for you to read prior to using the software */
/* and documentation. By using the software and documentation, or opening */
/* the sealed packet containing the software, or proceeding to download the */
/* software from a Bulletin Board System(BBS) or a WEB Server, you agree to */
/* abide by the following Texas Instruments License Agreement. If you choose */
/* not to agree with these provisions, promptly discontinue use of the */
/* software and documentation and return the material to the place you */
/* obtained it. */
/* */
/* Texas Instruments License Agreement */
/* */
/* 1. License - Texas Instruments (hereinafter "TI"), grants you a license */
/* to use the software program and documentation in this package ("Licensed */
/* Materials") for Texas Instruments broadband products. */
/* */
/* 2. Restrictions - You may not reverse-assemble or reverse-compile the */
/* Licensed Materials provided in object code or executable format. You may */
/* not sublicense, transfer, assign, rent, or lease the Licensed Materials */
/* or this Agreement without written permission from TI. */
/* */
/* 3. Copyright - The Licensed Materials are copyrighted. Accordingly, you */
/* may either make one copy of the Licensed Materials for backup and/or */
/* archival purposes or copy the Licensed Materials to another medium and */
/* keep the original Licensed Materials for backup and/or archival purposes. */
/* */
/* 4. Runtime and Applications Software - You may create modified or */
/* derivative programs of software identified as Runtime Libraries or */
/* Applications Software, which, in source code form, remain subject to this */
/* Agreement, but object code versions of such derivative programs are not */
/* subject to this Agreement. */
/* */
/* 5. Warranty - TI warrants the media to be free from defects in material */
/* and workmanship and that the software will substantially conform to the */
/* related documentation for a period of ninety (90) days after the date of */
/* your purchase. TI does not warrant that the Licensed Materials will be */
/* free from error or will meet your specific requirements. */
/* */
/* 6. Remedies - If you find defects in the media or that the software does */
/* not conform to the enclosed documentation, you may return the Licensed */
/* Materials along with the purchase receipt, postage prepaid, to the */
/* following address within the warranty period and receive a refund. */
/* */
/* TEXAS INSTRUMENTS */
/* Application Specific Products, MS 8650 */
/* c/o ADAM2 Application Manager */
/* 12500 TI Boulevard */
/* Dallas, TX 75243 - U.S.A. */
/* */
/* 7. Limitations - TI makes no warranty or condition, either expressed or */
/* implied, including, but not limited to, any implied warranties of */
/* merchantability and fitness for a particular purpose, regarding the */
/* licensed materials. */
/* */
/* Neither TI nor any applicable licensor will be liable for any indirect, */
/* incidental or consequential damages, including but not limited to loss of */
/* profits. */
/* */
/* 8. Term - The license is effective until terminated. You may terminate */
/* it at any other time by destroying the program together with all copies, */
/* modifications and merged portions in any form. It also will terminate if */
/* you fail to comply with any term or condition of this Agreement. */
/* */
/* 9. Export Control - The re-export of United States origin software and */
/* documentation is subject to the U.S. Export Administration Regulations or */
/* your equivalent local regulations. Compliance with such regulations is */
/* your responsibility. */
/* */
/* *** IMPORTANT NOTICE *** */
/* */
/* Texas Instruments (TI) reserves the right to make changes to or to */
/* discontinue any semiconductor product or service identified in this */
/* publication without notice. TI advises its customers to obtain the latest */
/* version of the relevant information to verify, before placing orders, */
/* that the information being relied upon is current. */
/* */
/* TI warrants performance of its semiconductor products and related */
/* software to current specifications in accordance with TI's standard */
/* warranty. Testing and other quality control techniques are utilized to */
/* the extent TI deems necessary to support this warranty. Unless mandated */
/* by government requirements, specific testing of all parameters of each */
/* device is not necessarily performed. */
/* */
/* Please be aware that Texas Instruments products are not intended for use */
/* in life-support appliances, devices, or systems. Use of a TI product in */
/* such applications without the written approval of the appropriate TI */
/* officer is prohibited. Certain applications using semiconductor devices */
/* may involve potential risks of injury, property damage, or loss of life. */
/* In order to minimize these risks, adequate design and operating */
/* safeguards should be provided by the customer to minimize inherent or */
/* procedural hazards. Inclusion of TI products in such applications is */
/* understood to be fully at the risk of the customer using TI devices or */
/* systems. */
/* */
/* TI assumes no liability for TI applications assistance, customer product */
/* design, software performance, or infringement of patents or services */
/* described herein. Nor does TI warrant or represent that license, either */
/* expressed or implied, is granted under any patent right, copyright, mask */
/* work right, or other intellectual property right of TI covering or */
/* relating to any combination, machine, or process in which such */
/* semiconductor products or services might be or are used. */
/* */
/* All company and/or product names are trademarks and/or registered */
/* trademarks of their respective manaufacturers. */
/* */
/*-----------------------------------------------------------------------------*/
//
// #include <string.h>
#include <stdio.h>
#include <ctype.h>
//Rev 0.1 Original
// 8 Jan 2001 MJH Added code to write data to Binary file
// note: outputfile is name.bin, where name is first part
// of input file. ie tmp.rec -> tmp.bin
//
// srec2bin <input SREC file> <Output Binary File> <If Present, Big Endian>
//
// TAG
// bit32u TAG_BIG = 0xDEADBE42;
// bit32u TAG_LITTLE = 0xFEEDFA42;
//
// File Structure
//
// TAG : 32 Bits
// [DATA RECORDS]
//
// Data Records Structure
//
// LENGTH : 32 Bits <- Length of DATA, excludes ADDRESS and CHECKSUM
// ADDRESS : 32 Bits
// DATA : 8 Bits * LENGTH
// CHECKSUM: 32 Bits <- 0 - (Sum of Length --> End of Data)
//
// Note : If Length == 0, Address will be Program Start
//
//
//
//
//
#define MajRevNum 0
#define MinRevNum 2
#define EndianSwitch(x) ((x >> 24) | (x << 24) | ((x << 8) & (0x00FF0000)) | ((x >> 8) & (0x0000FF00)) )
typedef unsigned char bit8u;
typedef unsigned int bit32u;
typedef int bit32;
#define FALSE 0
#define TRUE (!FALSE)
bit32u CheckSum;
int RecStart;
int debug;
int verbose;
FILE *OpenOutputFile( char *Name );
FILE *fOut;
bit32u RecLength=0;
bit32u AddressCurrent;
bit32u gh(char *cp,int nibs);
int BigEndian;
int inputline;
// char buf[16*1024];
char buffer[2048];
char *cur_ptr;
int cur_line=0;
int cur_len=0;
int s1s2s3_total=0;
bit32u PBVal;
int PBValid;
bit32u PBAdr;
void dumpfTell(char *s, bit32u Value)
{
int Length;
Length = (int) RecLength;
if (debug)
printf("[%s ] ftell()[0x%08lX] Length[0x%4X] Length[%4d] Value[0x%08x]\n",
s, ftell(fOut), Length, Length, Value);
}
void DispHex(bit32u Hex)
{
// printf("%X", Hex);
}
void WaitDisplay(void)
{
static int Count=0;
static int Index=0;
char iline[]={"-\\|/"};
Count++;
if ((Count % 32)==0)
{
if (verbose)
printf("%c%c",iline[Index++],8);
Index &= 3;
}
}
void binOut32 ( bit32u Data )
{
// On UNIX machine all 32bit writes need ENDIAN switched
// Data = EndianSwitch(Data);
// fwrite( &Data, sizeof(bit32u), 1, fOut);
char sdat[4];
int i;
for(i=0;i<4;i++)
sdat[i]=(char)(Data>>(i*8));
fwrite( sdat, 1, 4, fOut);
dumpfTell("Out32" , Data);
}
// Only update RecLength on Byte Writes
// All 32 bit writes will be for Length etc
void binOut8 ( bit8u Data )
{
int n;
dumpfTell("B4Data" , (bit32u) (Data & 0xFF) );
n = fwrite( &Data, sizeof(bit8u), 1, fOut);
if (n != 1)
printf("Error in writing %X for Address 0x%8X\n", Data, AddressCurrent);
RecLength += 1;
}
// Currently ONLY used for outputting Program Start
void binRecStart(bit32u Address)
{
RecLength = 0;
CheckSum = Address;
RecStart = TRUE;
if (debug)
printf("[RecStart] CheckSum[0x%08X] Length[%4d] Address[0x%08X]\n",
CheckSum, RecLength, Address);
dumpfTell("RecLength", RecLength);
binOut32( RecLength );
dumpfTell("Address", Address);
binOut32( Address );
}
void binRecEnd(void)
{
long RecEnd;
if (!RecStart) // if no record started, do not end it
{
return;
}
RecStart = FALSE;
RecEnd = ftell(fOut); // Save Current position
if (debug)
printf("[RecEnd ] CheckSum[0x%08X] Length[%4d] Length[0x%X] RecEnd[0x%08lX]\n",
CheckSum, RecLength, RecLength, RecEnd);
fseek( fOut, -(RecLength), SEEK_CUR); // move back Start Of Data
dumpfTell("Data ", -1);
fseek( fOut, -4, SEEK_CUR); // move back Start Of Address
dumpfTell("Address ", -1);
fseek( fOut, -4, SEEK_CUR); // move back Start Of Length
dumpfTell("Length ", -1);
binOut32( RecLength );
fseek( fOut, RecEnd, SEEK_SET); // move to end of Record
CheckSum += RecLength;
CheckSum = ~CheckSum + 1; // Two's complement
binOut32( CheckSum );
if (verbose)
printf("[Created Record of %d Bytes with CheckSum [0x%8X]\n", RecLength, CheckSum);
}
void binRecOutProgramStart(bit32u Address)
{
if (Address != (AddressCurrent+1))
{
binRecEnd();
binRecStart(Address);
}
AddressCurrent = Address;
}
void binRecOutByte(bit32u Address, bit8u Data)
{
// If Address is one after Current Address, output Byte
// If not, close out last record, update Length, write checksum
// Then Start New Record, updating Current Address
if (Address != (AddressCurrent+1))
{
binRecEnd();
binRecStart(Address);
}
AddressCurrent = Address;
CheckSum += Data;
binOut8( Data );
}
//=============================================================================
// SUPPORT FUNCTIONS
//=============================================================================
int readline(FILE *fil,char *buf,int len)
{
int rlen;
rlen=0;
if (len==0) return(0);
while(1)
{
if (cur_len==0)
{
cur_len=fread(buffer, 1, sizeof(buffer), fil);
if (cur_len==0)
{
if (rlen)
{
*buf=0;
return(rlen);
}
return(-1);
}
cur_ptr=buffer;
}
if (cur_len)
{
if (*cur_ptr=='\n')
{
*buf=0;
cur_ptr++;
cur_len--;
return(rlen);
}
else
{
if ((len>1)&&(*cur_ptr!='\r'))
{
*buf++=*cur_ptr++;
len--;
}
else
cur_ptr++;
rlen++;
cur_len--;
}
}
else
{
*buf=0;
cur_ptr++;
cur_len--;
return(rlen);
}
}
}
int SRLerrorout(char *c1,char *c2)
{
printf("\nERROR: %s - '%s'.",c1,c2);
return(FALSE);
}
int checksum(char *cp,int count)
{
char *scp;
int cksum;
int dum;
scp=cp;
while(*scp)
{
if (!isxdigit(*scp++))
return(SRLerrorout("Invalid hex digits",cp));
}
scp=cp;
cksum=count;
while(count)
{
cksum += gh(scp,2);
if (count == 2)
dum = ~cksum;
scp += 2;
count--;
}
cksum&=0x0ff;
// printf("\nCk:%02x",cksum);
return(cksum==0x0ff);
}
bit32u gh(char *cp,int nibs)
{
int i;
bit32u j;
j=0;
for(i=0;i<nibs;i++)
{
j<<=4;
if ((*cp>='a')&&(*cp<='z')) *cp &= 0x5f;
if ((*cp>='0')&&(*cp<='9'))
j += (*cp-0x30);
else
if ((*cp>='A')&&(*cp<='F'))
j += (*cp-0x37);
else
SRLerrorout("Bad Hex char", cp);
cp++;
}
return(j);
}
//=============================================================================
// PROCESS SREC LINE
//=============================================================================
int srecLine(char *pSrecLine)
{
char *scp,ch;
int itmp,count,dat;
bit32u adr;
static bit32u RecordCounter=0;
cur_line++;
scp=pSrecLine;
if (*pSrecLine!='S')
return(SRLerrorout("Not an Srecord file",scp));
pSrecLine++;
if (strlen(pSrecLine)<4)
return(SRLerrorout("Srecord too short",scp));
ch=*pSrecLine++;
count=gh(pSrecLine,2);
pSrecLine += 2;
// if(debug)
// printf("count %d, strlen(pSrecLine) = %d, pSrecLine =[%s]\n", count, strlen(pSrecLine), pSrecLine);
RecordCounter++;
DispHex(RecordCounter);
if ((count*2) != strlen(pSrecLine)) return(SRLerrorout("Count field larger than record",scp));
if (!checksum(pSrecLine, count)) return(SRLerrorout("Bad Checksum",scp));
switch(ch)
{
case '0': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2;
if (itmp) return(SRLerrorout("Srecord 1 address not zero",scp));
break;
case '1': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
return(SRLerrorout("Srecord Not valid for MIPS",scp));
break;
case '2': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp));
return(SRLerrorout("Srecord Not valid for MIPS",scp));
break;
case '3': if (count<5) return(SRLerrorout("Invalid Srecord count field",scp));
adr=gh(pSrecLine,8); pSrecLine+=8; count-=4;
count--;
while(count)
{
dat=gh(pSrecLine,2); pSrecLine+=2; count--;
binRecOutByte(adr, (char) (dat & 0xFF));
adr++;
}
s1s2s3_total++;
break;
case '4': return(SRLerrorout("Invalid Srecord type",scp));
break;
case '5': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
itmp=gh(pSrecLine,4); pSrecLine+=4; count-=2;
if (itmp|=s1s2s3_total) return(SRLerrorout("Incorrect number of S3 Record processed",scp));
break;
case '6': return(SRLerrorout("Invalid Srecord type",scp));
break;
case '7': // PROGRAM START
if (count<5) return(SRLerrorout("Invalid Srecord count field",scp));
adr=gh(pSrecLine,8); pSrecLine+=8; count-=4;
if (count!=1) return(SRLerrorout("Invalid Srecord count field",scp));
binRecOutProgramStart(adr);
break;
case '8': if (count<4) return(SRLerrorout("Invalid Srecord count field",scp));
return(SRLerrorout("Srecord Not valid for MIPS",scp));
break;
case '9': if (count<3) return(SRLerrorout("Invalid Srecord count field",scp));
return(SRLerrorout("Srecord Not valid for MIPS",scp));
break;
default:
break;
}
return(TRUE);
}
//=============================================================================
// MAIN LOGIC, READS IN LINE AND OUTPUTS BINARY
//=============================================================================
int srec2bin(int argc,char *argv[],int verbose)
{
int i,rlen,sts;
FILE *fp;
char ac;
char buff[256];
bit32u TAG_BIG = 0xDEADBE42;
bit32u TAG_LITTLE = 0xFEEDFA42;
bit32u Tag;
if(argc < 3)
{
printf("\nError: <srec2bin <srec input file> <bin output file>\n\n");
return(0);
}
if (argc > 3) BigEndian=TRUE; else BigEndian=FALSE;
if (BigEndian)
Tag = TAG_BIG;
else
Tag = TAG_LITTLE;
if (verbose)
printf("\nEndian: %s, Tag is 0x%8X\n",(BigEndian)?"BIG":"LITTLE", Tag);
fp = fopen(argv[1],"rt");
if (fp==NULL)
{
printf("\nError: Opening input file, %s.", argv[1]);
return(0);
}
fOut = fopen( argv[2], "wb");
if (fOut==NULL)
{
printf("\nError: Opening Output file, %s.", argv[2]);
if(fp) fclose(fp);
return(0);
}
RecStart = FALSE;
AddressCurrent = 0xFFFFFFFFL;
// Setup Tag
dumpfTell("Tag", Tag);
binOut32(Tag);
inputline=0;
sts=TRUE;
rlen = readline(fp,buff,sizeof buff);
while( (sts) && (rlen != -1))
{
if (strlen(buff))
{
sts &= srecLine(buff);
WaitDisplay();
}
rlen = readline(fp,buff,sizeof buff);
}
// printf("PC: 0x%08X, Length 0x%08X, Tag 0x%08X\n", ProgramStart, RecLength, TAG_LITTLE);
binRecEnd();
if(fp) fclose(fp);
if(fOut) fclose(fOut);
return(1);
}
main(int argc, char *argv[])
{
debug = TRUE;
debug = FALSE;
verbose = FALSE;
srec2bin(argc,argv,verbose);
return 0;
}