+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;
+ }
+
+ 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) {