bullshit commit, sync for travel (to zn00H!) :)
[my-code/arm.git] / betty / lpcload.c
index 4f62a59..38d5386 100644 (file)
@@ -22,6 +22,7 @@
 #define BANK2                  (1<<3)
 #define BL                     (1<<4)
 #define FLASHFW                        (1<<5)
+#define BINARY                 (1<<6)
 
 #define BANK0_ADDR             0x80000000
 #define BANK2_ADDR             0x82000000
@@ -97,6 +98,7 @@ void usage(void) {
        printf("  -Dx <filename>\n");
        printf("      x=0: bank0, x=2: bank2, x=b: bootloader\n");
        printf("  -w <firmware which goes to flash>\n");
+       printf("  -b (if firmware for flash is a binary)\n");
        printf("  -v\n");
 
 }
@@ -174,6 +176,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;
@@ -539,42 +546,66 @@ int send_cmd(int sfd,u32 addr,u32 len,u8 cmd) {
                send[1+i+as]=(len>>((ls-1-i)*8))&0xff;
 
        cnt=0;
-       printf("  sending cmd: ");
        while(size) {
                ret=write(sfd,send+cnt,size);
                if(ret<0) {
                        perror("dump file: send cmd ");
                        return ret;
                }
-               for(i=cnt;i<cnt+ret;i++)
-                       printf("%02x ",send[i]);
                size-=ret;
                cnt+=ret;
        }
-       printf("\n");
+
+       /* flush  */
+       tcflush(sfd,TCIOFLUSH);
 
        return 0;
 }
 
-int write_to_flash(t_lpc *lpc,char *buf,u32 addr,int len) {
+int write_to_flash(t_lpc *lpc,u8 *buf,u32 addr,int len) {
+
+       int cnt,ret;
+       u8 cksml,cksmr;
+       int i;
 
-       int cnt,size,ret;
+       /* prepare addr */
+       addr+=lpc->roff;
 
        /* send cmd */
        send_cmd(lpc->sfd,addr,len,CMD_WRITE);
 
        /* transfer data */
+       cnt=0;
+       cksml=0;
        while(len) {
-               size=2;
-               while(size) {
-                       ret=write(lpc->sfd,buf+cnt,2);
-                       if(ret<0) {
-                               perror("transmit flash content");
-                               return ret;
-                       }
-                       size-=ret;
+               ret=write(lpc->sfd,buf+cnt,len);
+               if(ret<0) {
+                       perror("transmit flash content (w)");
+                       return ret;
                }
-               cnt+=2;
+               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;
@@ -595,6 +626,29 @@ int firmware_to_mem(t_lpc *lpc,u8 memtype) {
        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) {
@@ -647,7 +701,7 @@ int firmware_to_mem(t_lpc *lpc,u8 memtype) {
                                if(memtype==RAM)
                                        write_to_ram(lpc,buf,addr,len);
                                else
-                                       write_to_flash(lpc,buf,addr,len);
+                                       write_to_flash(lpc,(u8 *)buf,addr,len);
                                break;
                        case 0x04:
                                lpc->roff=((buf[0]<<24)|(buf[1]<<16));
@@ -782,6 +836,9 @@ int main(int argc,char **argv) {
                                strncpy(lpc.ffwfile,argv[++i],127);
                                lpc.info|=FLASHFW;
                                break;
+                       case 'b':
+                               lpc.info|=BINARY;
+                               break;
                        default:
                                usage();
                                return -1;
@@ -841,7 +898,12 @@ int main(int argc,char **argv) {
 
        /* write a firmware to the lpc flash */
        if(lpc.info&FLASHFW) {
-               send_cmd(lpc.sfd,0,0,CMD_CHIP_ERASE);
+               printf("writing firmware to flash ...\n");
+               send_cmd(lpc.sfd,0,'0',CMD_CHIP_ERASE);
+               /* ack */
+               ret=0;
+               while(!ret)
+                       read(lpc.sfd,&ret,1);
                lpc.roff=BANK0_ADDR;
                firmware_to_mem(&lpc,FLASH);
        }