318 lines
7.4 KiB
C
318 lines
7.4 KiB
C
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) David Welch, 2000, 2003, 2008, 2009, 2012
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
FILE *fp;
|
|
|
|
#include "ser.h"
|
|
|
|
unsigned int seq;
|
|
unsigned int ra,rb,rc,rd;
|
|
unsigned int addr;
|
|
unsigned int firstaddr;
|
|
|
|
unsigned char data[128];
|
|
unsigned char sdata[512];
|
|
unsigned char rdata[5000];
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int check_packet ( void )
|
|
{
|
|
unsigned int ra;
|
|
unsigned int rb;
|
|
unsigned int rc;
|
|
|
|
|
|
if(rdata[0]!=0x7C) return(2);
|
|
if(rdata[1]!=(~rdata[2]&0xFF)) return(2);
|
|
if(rdata[3]!=sdata[3]) return(2);
|
|
if(rdata[4]!=sdata[4]) return(2);
|
|
if(rdata[3+rdata[1]]!=0x7D) return(2);
|
|
ra=3;
|
|
ra=rdata[1]+5;
|
|
for(rb=0,rc=0;rb<ra;rb++) rc+=rdata[rb];
|
|
rc&=0xFF;
|
|
if(rc!=0xFF) return(2);
|
|
return(rdata[5]);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
int raspload ( unsigned int addr, unsigned int data )
|
|
{
|
|
unsigned int ra;
|
|
unsigned int rb;
|
|
unsigned int rc;
|
|
unsigned int rd;
|
|
|
|
//printf("load 0x%08X, 0x%04X\n",addr,data);
|
|
|
|
if(firstaddr==0xFFFFFFFF) firstaddr=addr;
|
|
|
|
ra=0;
|
|
sdata[ra++]=0x7C;
|
|
sdata[ra++]=2+5+4;
|
|
sdata[ra]=~sdata[ra-1]; ra++;
|
|
//
|
|
sdata[ra++]=0x07;
|
|
sdata[ra++]=seq&0xFF; seq++;
|
|
sdata[ra++]=0;
|
|
sdata[ra++]=0;
|
|
sdata[ra++]=0;
|
|
|
|
sdata[ra++]=(addr>>24)&0xFF;
|
|
sdata[ra++]=(addr>>16)&0xFF;
|
|
sdata[ra++]=(addr>> 8)&0xFF;
|
|
sdata[ra++]=(addr>> 0)&0xFF;
|
|
// for(rd=0;rd<rb;rd+=2)
|
|
{
|
|
sdata[ra++]=(data>>8)&0xFF;
|
|
sdata[ra++]=(data>>0)&0xFF;
|
|
}
|
|
//
|
|
sdata[ra++]=0x7D;
|
|
for(rd=0,rc=0;rd<ra;rd++) rc+=sdata[rd];
|
|
sdata[ra++]=(~rc)&0xFF;
|
|
|
|
//for(rd=0;rd<ra;rd++) printf("%02X ",sdata[rd]); printf("\n");
|
|
|
|
//for(rd=0,rc=0x00;rd<ra;rd++) rc+=sdata[rd];
|
|
//rc&=0xFF;
|
|
|
|
ser_senddata(sdata,ra);
|
|
rb=0;
|
|
rc=0;
|
|
while(1)
|
|
{
|
|
rb=ser_copystring(rdata);
|
|
//if(rb!=rc) printf("%u\n",rb);
|
|
rc=rb;
|
|
if(rb==10)
|
|
{
|
|
//for(ra=0;ra<rb;ra++) printf("%02X ",rdata[ra]); printf("\n");
|
|
ra=check_packet();
|
|
if(ra) return(1);
|
|
ser_dump(rc);
|
|
break;
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
int readhex ( FILE *fp )
|
|
{
|
|
char gstring[80];
|
|
char newline[1024];
|
|
unsigned char hexline[1024];
|
|
|
|
//intimately tied to the .balign value in the bootloader startup
|
|
#define RAMMASK 0x1FFFFF
|
|
|
|
unsigned int addhigh;
|
|
unsigned int add;
|
|
unsigned int data;
|
|
|
|
unsigned int ra;
|
|
|
|
unsigned int line;
|
|
|
|
unsigned char checksum;
|
|
|
|
unsigned int len;
|
|
unsigned int maxadd;
|
|
|
|
unsigned char t;
|
|
|
|
maxadd=0;
|
|
|
|
addhigh=0;
|
|
|
|
line=0;
|
|
while(fgets(newline,sizeof(newline)-1,fp))
|
|
{
|
|
line++;
|
|
//printf("%s",newline);
|
|
if(newline[0]!=':')
|
|
{
|
|
printf("Syntax error <%u> no colon\n",line);
|
|
continue;
|
|
}
|
|
gstring[0]=newline[1];
|
|
gstring[1]=newline[2];
|
|
gstring[2]=0;
|
|
len=strtoul(gstring,NULL,16);
|
|
for(ra=0;ra<(len+5);ra++)
|
|
{
|
|
gstring[0]=newline[(ra<<1)+1];
|
|
gstring[1]=newline[(ra<<1)+2];
|
|
gstring[2]=0;
|
|
hexline[ra]=(unsigned char)strtoul(gstring,NULL,16);
|
|
}
|
|
checksum=0;
|
|
for(ra=0;ra<(len+5);ra++) checksum+=hexline[ra];
|
|
//checksum&=0xFF;
|
|
if(checksum)
|
|
{
|
|
printf("checksum error <%u>\n",line);
|
|
}
|
|
add=hexline[1]; add<<=8;
|
|
add|=hexline[2];
|
|
add|=addhigh;
|
|
if(add>RAMMASK)
|
|
{
|
|
printf("address too big 0x%08X\n",add);
|
|
//return(1);
|
|
continue;
|
|
}
|
|
if(add&3)
|
|
{
|
|
printf("bad address 0x%08X\n",add);
|
|
return(1);
|
|
}
|
|
t=hexline[3];
|
|
if(t!=0x02)
|
|
{
|
|
if(len&3)
|
|
{
|
|
printf("bad length\n");
|
|
return(1);
|
|
}
|
|
}
|
|
|
|
//:0011223344
|
|
//;llaaaattdddddd
|
|
//01234567890
|
|
switch(t)
|
|
{
|
|
default:
|
|
printf("UNKNOWN type %02X <%u>\n",t,line);
|
|
break;
|
|
case 0x00:
|
|
for(ra=0;ra<len;ra+=4)
|
|
{
|
|
if(add>RAMMASK)
|
|
{
|
|
printf("address too big 0x%08X\n",add);
|
|
break;
|
|
}
|
|
data= hexline[ra+4+1];
|
|
data<<=8; data|=hexline[ra+4+0];
|
|
if(raspload(add,data)) return(1);
|
|
add+=2;
|
|
|
|
data= hexline[ra+4+3];
|
|
data<<=8; data|=hexline[ra+4+2];
|
|
if(raspload(add,data)) return(1);
|
|
add+=2;
|
|
if(add>maxadd) maxadd=add;
|
|
}
|
|
break;
|
|
case 0x01:
|
|
// printf("End of data\n");
|
|
break;
|
|
case 0x02:
|
|
addhigh=hexline[5];
|
|
addhigh<<=8;
|
|
addhigh|=hexline[4];
|
|
addhigh<<=16;
|
|
break;
|
|
case 0x03:
|
|
data= hexline[4+0];
|
|
data<<=8; data|=hexline[4+1];
|
|
data<<=8; data|=hexline[4+2];
|
|
data<<=8; data|=hexline[4+3];
|
|
printf("TYPE 3 0x%08X\n",data);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//printf("%u lines processed\n",line);
|
|
//printf("%08X\n",maxadd);
|
|
//for(ra=0;ra<maxadd;ra+=4)
|
|
//{
|
|
//printf("0x%08X: 0x%08X\n",ra,ram[ra>>2]);
|
|
//}
|
|
return(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int main ( int argc, char *argv[] )
|
|
{
|
|
unsigned int ra;
|
|
//unsigned int rb;
|
|
unsigned int rc;
|
|
|
|
if(argc<3)
|
|
{
|
|
printf("prograspi filename.hex /dev/ttyXYZ\n");
|
|
return(1);
|
|
}
|
|
fp=fopen(argv[1],"rt");
|
|
if(fp==NULL)
|
|
{
|
|
printf("Error opening file [%s]\n",argv[1]);
|
|
return(1);
|
|
}
|
|
printf("file opened\n");
|
|
|
|
|
|
if(ser_open(argv[2]))
|
|
{
|
|
printf("ser_open() failed\n");
|
|
return(1);
|
|
}
|
|
printf("port opened\n");
|
|
|
|
seq=17;
|
|
firstaddr=0xFFFFFFFF;
|
|
if(readhex(fp))
|
|
{
|
|
return(1);
|
|
}
|
|
|
|
printf("Entry point: 0x%08X\n",firstaddr);
|
|
|
|
ra=0;
|
|
sdata[ra++]=0x7C;
|
|
sdata[ra++]=5+4;
|
|
sdata[ra]=~sdata[ra-1]; ra++;
|
|
//
|
|
sdata[ra++]=0x08;
|
|
sdata[ra++]=seq&0xFF; seq++;
|
|
sdata[ra++]=0;
|
|
sdata[ra++]=0;
|
|
sdata[ra++]=0;
|
|
|
|
sdata[ra++]=(firstaddr>>24)&0xFF;
|
|
sdata[ra++]=(firstaddr>>16)&0xFF;
|
|
sdata[ra++]=(firstaddr>> 8)&0xFF;
|
|
sdata[ra++]=(firstaddr>> 0)&0xFF;
|
|
//
|
|
sdata[ra++]=0x7D;
|
|
for(rd=0,rc=0;rd<ra;rd++) rc+=sdata[rd];
|
|
sdata[ra++]=(~rc)&0xFF;
|
|
|
|
//for(rd=0;rd<ra;rd++) printf("%02X ",sdata[rd]); printf("\n");
|
|
|
|
for(rd=0,rc=0x00;rd<ra;rd++) rc+=sdata[rd];
|
|
rc&=0xFF;
|
|
|
|
ser_senddata(sdata,ra);
|
|
|
|
ser_close();
|
|
printf("\n\n");
|
|
return(0);
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) David Welch, 2000, 2003, 2008, 2009, 2012
|
|
//-----------------------------------------------------------------------------
|
|
|