X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=betty%2Flpcload.c;h=9f60d88c8ab921602c72a0ed6d0d3a606d3f8fc9;hb=e013de8b92ff7ba9cf70c7c8669c023a315f1348;hp=19d5a5b2904aebc9dcdc242090ecd506331b4c95;hpb=ed474ffa00e2e35babccb09d039a7a65939097a0;p=my-code%2Farm.git diff --git a/betty/lpcload.c b/betty/lpcload.c index 19d5a5b..9f60d88 100644 --- a/betty/lpcload.c +++ b/betty/lpcload.c @@ -4,7 +4,7 @@ * author: hackbard@hackdaworld.org, rolf.anders@physik.uni-augsburg.de * * build: make - * usage: sudo ./lpcload -d /dev/ttyS0 -f firmware.hex [-v] + * usage: sudo ./lpcload -d /dev/ttyS0 -f firmware.hex -D0 fw0.bin [-v] */ #include @@ -21,6 +21,7 @@ #define BANK0 (1<<2) #define BANK2 (1<<3) #define BL (1<<4) +#define FLASHFW (1<<5) #define BANK0_ADDR 0x80000000 #define BANK2_ADDR 0x82000000 @@ -29,6 +30,8 @@ #define BL_SIZE 0x00002000 #define CMD_READ 'R' // stay compatible to fwflash! +#define CMD_WRITE 'W' +#define CMD_CHIP_ERASE 'E' #define TXRX_TYPE_SYNC 0x00 #define TXRX_TYPE_CKSM 0x00 @@ -54,6 +57,9 @@ #define INVALID_BAUD_RATE "17\r\n" #define INVALID_STOP_BIT "18\r\n" +#define RAM 0x01 +#define FLASH 0x02 + #define CRYSTFREQ "10000" #define RAMOFFSET 0x40000200 @@ -68,7 +74,7 @@ typedef struct s_lpc { char sdev[128]; /* seriel device */ int fwfd; /* fimrware fd */ char fwfile[128]; /* firmware file */ - u8 info; /* info/mode */ + u32 info; /* info/mode */ char freq[8]; /* frequency */ char bank0[127]; /* flash dump bank0 */ int b0fd; /* dumpfile fd bank0 */ @@ -76,6 +82,8 @@ typedef struct s_lpc { int b2fd; /* dumpfile fd bank0 */ char bl[127]; /* flash dump bootloader */ int blfd; /* dumpfile fd bootloader */ + char ffwfile[127]; /* file with firmware to be flashed */ + int ffwfd; /* fd of the above */ u32 roff; /* ram offset of uc */ u32 jaddr; /* addr for the jump */ } t_lpc; @@ -88,6 +96,7 @@ void usage(void) { printf(" -c \n"); printf(" -Dx \n"); printf(" x=0: bank0, x=2: bank2, x=b: bootloader\n"); + printf(" -w \n"); printf(" -v\n"); } @@ -165,6 +174,11 @@ int reconfig_serial_device(t_lpc *lpc) { cfsetispeed(&term,B115200); cfsetospeed(&term,B115200); + // timeouts + + term.c_cc[VMIN]=0; + term.c_cc[VTIME]=100; // 10 seconds timeout + ret=tcsetattr(lpc->sfd,TCSANOW,&term); return ret; @@ -176,8 +190,18 @@ int open_firmware(t_lpc *lpc) { lpc->fwfd=open(lpc->fwfile,O_RDONLY); - if(lpc->fwfd<0) + if(lpc->fwfd<0) { perror("fw open"); + return lpc->fwfd; + } + + if(lpc->info&FLASHFW) { + lpc->ffwfd=open(lpc->ffwfile,O_RDONLY); + if(lpc->ffwfd<0) { + perror("ffw open"); + return lpc->ffwfd; + } + } return lpc->fwfd; } @@ -490,17 +514,131 @@ int write_to_ram(t_lpc *lpc,char *buf,u32 addr,int len) { return 0; } -int firmware_to_ram(t_lpc *lpc) { +int send_cmd(int sfd,u32 addr,u32 len,u8 cmd) { + + int ret,i,cnt,size; + int as,ls; + u8 send[9]; + + switch(cmd) { + case CMD_READ: + case CMD_WRITE: + as=4; + ls=4; + break; + case CMD_CHIP_ERASE: + as=0; + ls=1; + break; + default: + printf("send cmd: cmd '%02x' not supported\n",cmd); + return -1; + } + + size=1+as+ls; + send[0]=cmd; + + for(i=0;i>((as-1-i)*8))&0xff; + for(i=0;i>((ls-1-i)*8))&0xff; + + cnt=0; + while(size) { + ret=write(sfd,send+cnt,size); + if(ret<0) { + perror("dump file: send cmd "); + return ret; + } + size-=ret; + cnt+=ret; + } + + return 0; +} + +int write_to_flash(t_lpc *lpc,u8 *buf,u32 addr,int len) { + + int cnt,ret; + u8 cksml,cksmr; + u8 check; + int i; + + /* send cmd */ + send_cmd(lpc->sfd,addr+lpc->roff,len,CMD_WRITE); + + /* transfer data */ + cnt=0; + cksml=0; + while(len) { + for(i=0;i<2;i++) { + while(1) { + ret=write(lpc->sfd,buf+cnt+i,1); + if(ret<0) { + perror("transmit flash content (w)"); + return ret; + } + if(ret==1) + break; + } + while(1) { + ret=read(lpc->sfd,&check,1); + if(ret<0) { + perror("transmit flash content (r)"); + return ret; + } + if(ret==1) + break; + } + if(buf[cnt+i]!=check) + printf("FATAL: write to flash: wrong transfer\n"); + } + cksml+=buf[cnt]; + cksml+=buf[cnt+1]; + cnt+=2; + len-=2; + } + + /* check ack */ + while(1) { + ret=read(lpc->sfd,&cksmr,1); + if(ret<0) { + perror("write to flash: read cksm"); + return ret; + } + if(ret==1) break; + } + if(cksml!=cksmr) { + printf("FATAL: wrong checksum or failure in flash write!\n"); + if(cksml+1==cksmr) + printf(" -> most probably due to flash write!"); + else + printf(" -> most probably due to failure in transfer!"); + } + + return 0; +} + +int firmware_to_mem(t_lpc *lpc,u8 memtype) { char buf[BUFSIZE]; u32 addr,len,type; int ret,temp; + int fd; + + /* prepare for memory type */ + if(memtype==RAM) + fd=lpc->fwfd; + else if(memtype==FLASH) + fd=lpc->ffwfd; + else + return -1; /* read a line */ ret=1; while(ret) { /* sync line */ - ret=read(lpc->fwfd,buf,1); + ret=read(fd,buf,1); switch(buf[0]) { case '\r': continue; @@ -510,25 +648,25 @@ int firmware_to_ram(t_lpc *lpc) { /* start code */ break; default: - printf("fw to ram: no ihex format\n"); + printf("fw to mem: no ihex format\n"); return -1; } /* read len */ - ret=read(lpc->fwfd,buf,2); + ret=read(fd,buf,2); sscanf(buf,"%02x",&len); /* read addr */ - ret=read(lpc->fwfd,buf,4); + ret=read(fd,buf,4); sscanf(buf,"%04x",&addr); /* read type */ - ret=read(lpc->fwfd,buf,2); + ret=read(fd,buf,2); sscanf(buf,"%02x",&type); /* successfull return if type is end of file */ if(type==0x01) return 0; /* read data (and cksum) */ - ret=read(lpc->fwfd,buf,2*(len+1)); + ret=read(fd,buf,2*(len+1)); if(ret!=(2*(len+1))) { - printf("fw to ram: data missing\n"); + printf("fw to mem: data missing\n"); return -1; } for(ret=0;retroff=((buf[0]<<24)|(buf[1]<<16)); @@ -555,7 +696,7 @@ int firmware_to_ram(t_lpc *lpc) { lpc->jaddr|=((buf[2]<<8)|buf[3]); break; default: - printf("fw to ram: unknown type %02x\n",type); + printf("fw to mem: unknown type %02x\n",type); return -1; } } @@ -585,36 +726,12 @@ int dump_files(int sfd,int dfd,u32 addr,u32 len) { int ret; int size; int cnt; - int i; u8 buf[16]; printf("dumping content (addr=0x%08x, len=0x%08x) ...\n",addr,len); - /* send cmd */ - size=1+4+4; - cnt=0; - buf[0]=CMD_READ; - buf[1]=(addr>>24)&0xff; - buf[2]=(addr>>16)&0xff; - buf[3]=(addr>>8)&0xff; - buf[4]=addr&0xff; - buf[5]=(len>>24)&0xff; - buf[6]=(len>>16)&0xff; - buf[7]=(len>>8)&0xff; - buf[8]=len&0xff; - printf(" sending cmd: "); - while(size) { - ret=write(sfd,buf+cnt,size); - for(i=cnt;i