+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;i++)
+ send[1+i]=(addr>>((as-1-i)*8))&0xff;
+ for(i=0;i<ls;i++)
+ send[1+i+as]=(len>>((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;
+ }
+
+ /* flush */
+ tcflush(sfd,TCIOFLUSH);
+
+ return 0;
+}
+
+int write_to_flash(t_lpc *lpc,u8 *buf,u32 addr,int len) {
+
+ int cnt,ret;
+ u8 cksml,cksmr;
+ int i;
+
+ /* prepare addr */
+ addr+=lpc->roff;
+
+ /* send cmd */
+ send_cmd(lpc->sfd,addr,len,CMD_WRITE);
+
+ /* transfer data */
+ cnt=0;
+ cksml=0;
+ while(len) {
+ ret=write(lpc->sfd,buf+cnt,len);
+ if(ret<0) {
+ perror("transmit flash content (w)");
+ return ret;
+ }
+ for(i=cnt;i<cnt+ret;i++)
+ cksml+=buf[i];
+ len-=ret;
+ cnt+=ret;
+ }
+
+
+ /* 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!\n");
+ else
+ printf(" -> most probably failure in transfer!\n");
+ printf(" addr:0x%08x l:%02x r:%02x\n",addr,cksml,cksmr);
+ }
+
+ 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;
+
+ /* another evil hack to support binary format */
+ if((lpc->info&BINARY)&&(memtype==FLASH)) {
+ addr=0;
+ ret=1;
+ while(ret) {
+ ret=read(fd,buf,16);
+ if(ret!=16) {
+ printf("D'OH ...\n");
+ return -1;
+ }
+ buf[16]='s'; // skip
+ for(temp=0;temp<16;temp++)
+ if((u8)buf[temp]!=0xff)
+ buf[16]='w'; // write
+ printf("addr:%08x\r",addr+lpc->roff);
+ fflush(stdout);
+ if(buf[16]=='w')
+ write_to_flash(lpc,(u8 *)buf,addr,16);
+ addr+=16;
+ }
+ return 0;
+ }
+
+ /* read a line */
+ ret=1;
+ while(ret) {
+ /* sync line */
+ ret=read(fd,buf,1);
+ switch(buf[0]) {
+ case '\r':
+ continue;
+ case '\n':
+ continue;
+ case ':':
+ /* start code */
+ break;
+ default:
+ printf("fw to mem: no ihex format\n");
+ return -1;
+ }
+ /* read len */
+ ret=read(fd,buf,2);
+ sscanf(buf,"%02x",&len);
+ /* read addr */
+ ret=read(fd,buf,4);
+ sscanf(buf,"%04x",&addr);
+ /* read type */
+ 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(fd,buf,2*(len+1));
+ if(ret!=(2*(len+1))) {
+ printf("fw to mem: data missing\n");
+ return -1;
+ }
+ for(ret=0;ret<len;ret++) {
+ sscanf(buf+2*ret,"%02x",&temp);
+ buf[ret]=temp;
+ }
+ /* act according to type */
+ switch(type) {
+ //case 0x03:
+ // /* get cs and ip */
+ // break;
+ case 0x00:
+ if(len%4) {
+ printf("fw to mem: invalid len\n");
+ return -1;
+ }
+ if(memtype==RAM)
+ write_to_ram(lpc,buf,addr,len);
+ else
+ write_to_flash(lpc,(u8 *)buf,addr,len);
+ break;
+ case 0x04:
+ lpc->roff=((buf[0]<<24)|(buf[1]<<16));
+ break;
+ case 0x05:
+ lpc->jaddr=((buf[0]<<24)|(buf[1]<<16));
+ lpc->jaddr|=((buf[2]<<8)|buf[3]);
+ break;
+ default:
+ printf("fw to mem: unknown type %02x\n",type);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int lpc_txbuf_flush(t_lpc *lpc) {