fwflash taking over fwbc, lpcload taking over fwdump
authorhackbard <hackbard@staubsauger.localdomain>
Fri, 31 Aug 2007 15:35:01 +0000 (17:35 +0200)
committerhackbard <hackbard@staubsauger.localdomain>
Fri, 31 Aug 2007 15:35:01 +0000 (17:35 +0200)
betty/fwflash.c
betty/lpcload.c

index 8b89941..4fa0479 100644 (file)
@@ -59,7 +59,8 @@ void uart0_init(void) {
        PINSEL0=0x05;                   // pin select -> tx, rx
        UART0_FCR=0x07;                 // enable fifo
        UART0_LCR=0x83;                 // set dlab + word length
-       UART0_DLL=0x10;                 // br: 9600 @ 10/4 mhz
+       //UART0_DLL=0x10;                       // br: 9600 @ 10/4 mhz
+       UART0_DLL=0x04;                 // br: 38400 @ 10/4 mhz
        UART0_DLM=0x00;
        UART0_LCR=0x03;                 // unset dlab
 }
@@ -97,7 +98,7 @@ void uart0_send_buf16(u16 *buf,int len) {
 
        i=0;
 
-       for(i=0;i<len;i++) {
+       for(i=0;i<len/2;i++) {
                if(!(i%8))
                        while(!(UART0_LSR&(1<<6)))
                                continue;
@@ -112,7 +113,7 @@ void uart0_send_buf32(u32 *buf,int len) {
 
        i=0;
 
-       for(i=0;i<len;i++) {
+       for(i=0;i<len/4;i++) {
                if(!(i%4))
                        while(!(UART0_LSR&(1<<6)))
                                continue;
@@ -189,16 +190,12 @@ int main(void) {
                                datalen=1;
                                break;
                        default:
-                               uart0_send_byte('f');
                                txrx=0;
                                break;
                }
 
-               if(txrx) {
-                       /* send an ack */
-                       uart0_send_byte(cmd);
+               if(txrx)
                        break;
-               }
        }
 
        /* receive (only if there is) more data from uart0 */
@@ -217,11 +214,11 @@ int main(void) {
                        /* data length to read */
                        datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
                        /* check addr and datalen */
-                       if((addr>=BANK0)&(addr+datalen<BANK0+BANK_SIZE))
+                       if((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))
                                uart0_send_buf16((u16 *)addr,datalen);
-                       if((addr>=BANK2)&(addr+datalen<BANK2+BANK_SIZE))
+                       if((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE))
                                uart0_send_buf16((u16 *)addr,datalen);
-                       if((addr>=BOOTLOADER)&(addr+datalen<BOOTLOADER+BL_SIZE))
+                       if((addr>=BOOTLOADER)&(addr+datalen<=BOOTLOADER+BL_SIZE))
                                uart0_send_buf32((u32 *)addr,datalen);
                        break;
                case CMD_CHIP_ERASE:
index 30a808e..f7911a8 100644 (file)
 
 #define VERBOSE                        (1<<0)
 #define FIRMWARE               (1<<1)
+#define BANK0                  (1<<2)
+#define BANK2                  (1<<3)
+#define BL                     (1<<4)
+
+#define BANK0_ADDR             0x80000000
+#define BANK2_ADDR             0x82000000
+#define BANK_SIZE              0x00100000
+#define BL_ADDR                        0x7fffe000
+#define BL_SIZE                        0x00000800
+
+#define CMD_READ               'R'             // stay compatible to fwflash!
 
 #define TXRX_TYPE_SYNC         0x00
 #define TXRX_TYPE_CKSM         0x00
@@ -59,6 +70,12 @@ typedef struct s_lpc {
        char fwfile[128];       /* firmware file */
        u8 info;                /* info/mode */
        char freq[8];           /* frequency */
+       char bank0[127];        /* flash dump bank0 */
+       int b0fd;               /* dumpfile fd bank0 */
+       char bank2[127];        /* flash dump bank2 */
+       int b2fd;               /* dumpfile fd bank0 */
+       char bl[127];           /* flash dump bootloader */
+       int blfd;               /* dumpfile fd bootloader */
        u32 roff;               /* ram offset of uc */
        u32 jaddr;              /* addr for the jump */
 } t_lpc;
@@ -66,10 +83,11 @@ typedef struct s_lpc {
 void usage(void) {
 
        printf("possible argv:\n");
-       printf("  -d <serial device>\n");
-       printf("  -f <firmware>\n");
-       printf("  -c <crystal freq>\n");
-       printf("  -r <ram offset>\n");
+       printf("  -d  <serial device>\n");
+       printf("  -f  <firmware>\n");
+       printf("  -c  <crystal freq>\n");
+       printf("  -Dx <filename>\n");
+       printf("      x=0: bank0, x=2: bank2, x=b: bootloader\n");
        printf("  -v\n");
 
 }
@@ -142,6 +160,37 @@ int open_firmware(t_lpc *lpc) {
        return lpc->fwfd;
 }
 
+int open_dumpfiles(t_lpc *lpc) {
+
+       /* open dumpfiles */
+
+       if(lpc->info&BANK0) {
+               lpc->b0fd=open(lpc->bank0,O_WRONLY|O_CREAT);
+               if(lpc->b0fd<0) {
+                       perror("bank0 dump file open");
+                       return lpc->b0fd;
+               }
+       }
+
+       if(lpc->info&BANK2) {
+               lpc->b2fd=open(lpc->bank2,O_WRONLY|O_CREAT);
+               if(lpc->b2fd<0) {
+                       perror("bank2 dump file open");
+                       return lpc->b2fd;
+               }
+       }
+
+       if(lpc->info&BL) {
+               lpc->blfd=open(lpc->bl,O_WRONLY|O_CREAT);
+               if(lpc->blfd<0) {
+                       perror("bootloader dump file open");
+                       return lpc->blfd;
+               }
+       }
+
+       return 0;
+
+}
 int txrx(t_lpc *lpc,char *buf,int len,u8 type) {
 
        int ret,cnt;
@@ -173,6 +222,8 @@ int txrx(t_lpc *lpc,char *buf,int len,u8 type) {
                printf("| (%d)\n",cnt);
        }
 
+
+
        /* cut the echo if not of type auto baud */
 
        if(type!=TXRX_TYPE_BAUD) {
@@ -186,6 +237,11 @@ int txrx(t_lpc *lpc,char *buf,int len,u8 type) {
                }
        }
 
+       /* return if type is go */
+
+       if(type==TXRX_TYPE_GO)
+               return cnt;
+
        /* return here if type is data */
 
        if(type==TXRX_TYPE_DATA)
@@ -239,11 +295,6 @@ int txrx(t_lpc *lpc,char *buf,int len,u8 type) {
        }
        buf[cnt+1]='\0';
 
-       /* return if type is go */
-
-       if(type==TXRX_TYPE_GO)
-               return 0;
-
        /* check/strip return code if type is cmd */
 
        if(type==TXRX_TYPE_CMD) {
@@ -490,6 +541,85 @@ int firmware_to_ram(t_lpc *lpc) {
        return 0;
 }
 
+int lpc_txbuf_flush(t_lpc *lpc) {
+
+       int i,ret;
+       u8 buf[16];
+
+       ret=1;
+       printf("flushing lpc tx buffer: ");
+       while(ret) {
+               ret=read(lpc->sfd,buf,16);
+               for(i=0;i<ret;i++)
+                       printf("%02x ",buf[i]);
+       }
+       printf("\n");
+
+       return 0;
+}
+
+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<cnt+ret;i++)
+                       printf("%02x ",buf[i]);
+               if(ret<0) {
+                       perror("dump file: send cmd ");
+                       return ret;
+               }
+               size-=ret;
+               cnt+=ret;
+       }
+       printf("\n");
+
+       /* receive data and dump it to file */
+       ret=1;
+       cnt=0;
+       printf("  receiving data ...\n");
+       while(ret) {
+               ret=read(sfd,buf,16);
+               if(ret<0) {
+                       perror("dump file: read data");
+                       return ret;
+               }
+               size=ret;
+               cnt=0;
+               while(size) {
+                       ret=write(dfd,buf+cnt,size-cnt);
+                       if(ret<0) {
+                               perror("dump file: write data");
+                               return ret;
+                       }
+                       cnt+=ret;
+                       size-=ret;
+               }
+       }
+
+       return 0;
+}
+
 int main(int argc,char **argv) {
 
        t_lpc lpc;
@@ -528,6 +658,27 @@ int main(int argc,char **argv) {
                        case 'c':
                                strncpy(lpc.freq,argv[++i],7);
                                break;
+                       case 'D':
+                               if(argv[i][2]=='0') {
+                                       lpc.info|=BANK0;
+                                       strncpy(lpc.bank0,argv[++i],127);
+                                       break;
+                               }
+                               else if(argv[i][2]=='2') {
+                                       lpc.info|=BANK2;
+                                       strncpy(lpc.bank2,argv[++i],127);
+                                       break;
+                               }
+                               else if(argv[i][2]=='b') {
+                                       lpc.info|=BANK0;
+                                       strncpy(lpc.bl,argv[++i],127);
+                                       break;
+                               }
+                               else {
+                                       usage();
+                                       return -1;
+                               }
+                               
                        default:
                                usage();
                                return -1;
@@ -554,6 +705,10 @@ int main(int argc,char **argv) {
        if(open_firmware(&lpc)<0)
                goto end;
 
+       /* open dump files */
+       if(open_dumpfiles(&lpc)<0)
+               goto end;
+
        /* parse intel hex file and write to ram */
        printf("write firmware to ram ...\n");
        firmware_to_ram(&lpc);
@@ -566,9 +721,28 @@ int main(int argc,char **argv) {
        printf("go ...\n");
        ret=go(&lpc);
 
+       /* flush the lpc2220 tx buf */
+       lpc_txbuf_flush(&lpc);
+
+       /* download flash/bootloader content */
+       if(lpc.info&BANK0)
+               dump_files(lpc.sfd,lpc.b0fd,BANK0_ADDR,BANK_SIZE);
+       if(lpc.info&BANK2)
+               dump_files(lpc.sfd,lpc.b2fd,BANK2_ADDR,BANK_SIZE);
+       if(lpc.info&BL)
+               dump_files(lpc.sfd,lpc.blfd,BL_ADDR,BL_SIZE);
+
 end:
-       close(lpc.sfd);
-       close(lpc.fwfd);
+       if(lpc.sfd)
+               close(lpc.sfd);
+       if(lpc.fwfd)
+               close(lpc.fwfd);
+       if(lpc.b0fd)
+               close(lpc.b0fd);
+       if(lpc.b2fd)
+               close(lpc.b2fd);
+       if(lpc.blfd)
+               close(lpc.blfd);
 
        return 0;
 }