X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=betty%2Flpcload.c;h=80af804153dc5697da32ba6ae3f30a598cfcd45d;hb=9fe785e6bc1cf36626f4a3db7877b5f7df76ed61;hp=905ebbdcb2e29a0544989d05c0fcce4092cb5c85;hpb=c085074294f2852dbe03000d077c9a44b0d7d888;p=my-code%2Farm.git diff --git a/betty/lpcload.c b/betty/lpcload.c index 905ebbd..80af804 100644 --- a/betty/lpcload.c +++ b/betty/lpcload.c @@ -1,8 +1,10 @@ /* * lpcload.c - load firmware into ram of lpc2220 via uart0 * - * author: hackbard@hackdaworld.org + * author: hackbard@hackdaworld.org, rolf.anders@physik.uni-augsburg.de * + * build: make + * usage: sudo ./lpcload -d /dev/ttyS0 -f firmware.hex [-v] */ #include @@ -56,8 +58,6 @@ typedef struct s_lpc { char fwfile[128]; /* firmware file */ u8 info; /* info/mode */ char freq[8]; /* frequency */ - int partid; /* part id */ - u8 bcv[2]; /* boot code version */ u32 hoff; /* start addr of ihex file */ u32 roff; /* ram offset of uc */ } t_lpc; @@ -110,13 +110,17 @@ int open_serial_device(t_lpc *lpc) { // input options -> enable flow control //term.c_iflag&=~(IXON|IXOFF|IXANY|INLCR|ICRNL); - term.c_iflag&=~(INLCR|ICRNL); - term.c_iflag|=(IXON|IXOFF|IXANY); + term.c_iflag&=~(INLCR|ICRNL|IXANY); + term.c_iflag|=(IXON|IXOFF); + + // output options + + term.c_oflag=0; // more control options -> timeout / flow control term.c_cc[VMIN]=0; - term.c_cc[VTIME]=10; // 1 second timeout + term.c_cc[VTIME]=40; // 4 second timeout term.c_cc[VSTART]=0x11; term.c_cc[VSTOP]=0x13; @@ -184,79 +188,68 @@ int txrx(t_lpc *lpc,char *buf,int len,u8 type) { /* cut the echo if not of type auto baud */ if(type!=TXRX_TYPE_BAUD) { - while(cnt>0) { + while(cnt) { ret=read(lpc->sfd,buf,cnt); if(ret<0) { perror("txrx echo cut"); return ret; } - if(type==TXRX_TYPE_CKSM) { - printf(" cksm resp: "); - for(i=0;isfd,buf,BUFSIZE); - for(i=0;iinfo&VERBOSE) - printf(" << "); + ret=read(lpc->sfd,buf,1); + if(ret<0) { + perror("txrx read (first byte)"); + return ret; + } + + switch(buf[0]) { + case 'S': + cnt=13; + break; + case 'O': + cnt=3; + break; + case 'R': + cnt=7; + break; + case '0': + cnt=2; + break; + default: + printf("txrx read: bad return byte '%02x'\n",buf[0]); + break; + } + ret=1; - cnt=0; - while(ret) { - ret=read(lpc->sfd,buf+cnt,BUFSIZE-cnt); + i=cnt; + while(i) { + ret=read(lpc->sfd,buf+1+cnt-i,i); if(ret<0) { - perror("txrx read"); + perror("txrx read (next bytes)"); return ret; } - if(ret+cnt>BUFSIZE) { - printf("txrx read: too small buf size (%d)!\n",BUFSIZE); - return -1; - } - if(lpc->info&VERBOSE) - for(i=0;i0x19)&(buf[cnt+i]<0x7f))? - buf[cnt+i]:'.'); - cnt+=ret; + i-=ret; } if(lpc->info&VERBOSE) { + printf(" << "); + for(i=0;i0x19)&(buf[i]<0x7f))? + buf[i]:'.'); printf(" | "); - for(i=0;ipartid=atoi(buf); - - return lpc->partid; -} - -int read_bcv(t_lpc *lpc) { - - char buf[BUFSIZE]; - char *ptr; - - memcpy(buf,"K\r\n",3); - txrx(lpc,buf,3,TXRX_TYPE_CMD); - ptr=strtok(buf,"\r\n"); - lpc->bcv[0]=strtol(ptr,NULL,16); - ptr=strtok(NULL,"\r\n"); - lpc->bcv[1]=strtol(ptr,NULL,16); - - return 0; -} - int unlock_go(t_lpc *lpc) { char buf[BUFSIZE]; @@ -354,27 +321,18 @@ int go(t_lpc *lpc) { snprintf(buf,BUFSIZE,"G %d A\r\n",lpc->roff); len=strlen(buf); - ret=txrx(lpc,buf,ret,TXRX_TYPE_CMD); + ret=txrx(lpc,buf,len,TXRX_TYPE_CMD); return ret; } -int uuencode(char *in,char *out) { +int uuencode(u8 *in,u8 *out,int len) { - int i; - - out[0]=0x20+((in[0]>>2)&0x3f); - out[1]=0x20+(((in[0]<<4)|(in[1]>>4))&0x3f); - out[2]=0x20+(((in[1]<<2)|(in[2]>>6))&0x3f); - out[3]=0x20+(in[2]&0x3f); - - printf(" enc: "); - for(i=0;i<3;i++) - printf("%02x ",in[i]); - printf("-> "); - for(i=0;i<4;i++) - printf("%02x ",out[i]); - printf("\n"); + out[0]=0x20+len; + out[1]=0x20+((in[0]>>2)&0x3f); + out[2]=0x20+(((in[0]<<4)|(in[1]>>4))&0x3f); + out[3]=0x20+(((in[1]<<2)|(in[2]>>6))&0x3f); + out[4]=0x20+(in[2]&0x3f); return 0; } @@ -395,7 +353,7 @@ int write_to_ram(t_lpc *lpc,char *buf,u32 addr,int len) { } /* make it a multiple of 3 (reason: uuencode) */ - nlen=(len/3+1)*3; + nlen=(!(len%3))?len:((len/3+1)*3); if(nlen>BUFSIZE) { printf("ram write: too much data\n"); return -1; @@ -413,10 +371,6 @@ int write_to_ram(t_lpc *lpc,char *buf,u32 addr,int len) { /* send command and check return code */ txrx(lpc,txrxbuf,slen,TXRX_TYPE_CMD); - //if(strncmp(txrxbuf,"OK\r\n",4)) { - // printf("ram write: write command failed\n"); - // return -1; - //} /* send data */ lcount=0; @@ -426,16 +380,16 @@ int write_to_ram(t_lpc *lpc,char *buf,u32 addr,int len) { while(bcnt %d %d\n",checksum,bcnt); + checksum+=((u8)buf[bcnt]+(u8)buf[bcnt+1]+(u8)buf[bcnt+2]); /* send a data line */ - txrx(lpc,txrxbuf,6,TXRX_TYPE_DATA); + txrx(lpc,txrxbuf,7,TXRX_TYPE_DATA); /* increase counters */ lcount+=1; @@ -444,11 +398,15 @@ int write_to_ram(t_lpc *lpc,char *buf,u32 addr,int len) { /* checksum */ if((!(lcount%20))|(bcnt==nlen)) { + /* send backtick */ + memcpy(txrxbuf,"`\r\n",3); + //txrx(lpc,txrxbuf,3,TXRX_TYPE_DATA); /* send checksum */ - snprintf(txrxbuf,BUFSIZE,"%d\r\n",checksum%0x100); + snprintf(txrxbuf,BUFSIZE,"%d\r\n",checksum); slen=strlen(txrxbuf); txrx(lpc,txrxbuf,slen,TXRX_TYPE_CKSM); - if(!strncmp(txrxbuf,"RESEND\r\n",8)) { + if(!strncmp(txrxbuf,"RESE",4)) { + read(lpc->sfd,txrxbuf+4,4); printf("ram write: resending ...\n"); bcnt-=count; } @@ -470,9 +428,10 @@ int firmware_to_ram(t_lpc *lpc) { char buf[BUFSIZE]; u32 addr,len,type; - int ret; + int ret,temp; /* read a line */ + ret=1; while(ret) { /* sync line */ ret=read(lpc->fwfd,buf,1); @@ -504,22 +463,27 @@ int firmware_to_ram(t_lpc *lpc) { /* successfull return if type is end of file */ if(type==0x01) return 0; - /* read data */ - ret=read(lpc->fwfd,buf,2*len); - if(ret!=(2*len)) { + /* read data (and cksum) */ + ret=read(lpc->fwfd,buf,2*(len+1)); + if(ret!=(2*(len+1))) { printf("fw to ram: data missing\n"); return -1; } - /* checksum */ - ret=read(lpc->fwfd,buf,2); + for(ret=0;ret aborting\n"); + goto end; + } - /* read boot code version */ - read_bcv(&lpc); - printf("boot code version: %02x %02x\n",lpc.bcv[0],lpc.bcv[1]); + /* open firmware file */ + if(open_firmware(&lpc)<0) + goto end; /* parse intel hex file and write to ram */ + printf("write firmware to ram ...\n"); firmware_to_ram(&lpc); /* unlock go cmd */ + printf("unlock go command ...\n"); unlock_go(&lpc); /* go! */ - go(&lpc); + printf("go ...\n"); + ret=go(&lpc); + + /* tell the user that the error might be due to the jump */ + printf("\n\n"); + if(ret<0) + printf("the above error might be due to the jump!\n\n"); + + /* query user for serial port listening */ + printf("continue listening on serial port? (ctrl+c to quit) [y|n]: "); + buf[0]=getchar(); + printf("\n"); + + if(buf[0]!='y') + goto end; + + /* continue lsitening on serial port */ + ret=1; + while(ret) { + ret=read(lpc.sfd,buf,BUFSIZE); + printf("\rread %d bytes: ",ret); + for(i=0;i