no byte reply anymore (due to ack and tcflush) -> incredible speedup!
[my-code/arm.git] / betty / fwflash.c
index c4a2155..85a64fa 100644 (file)
@@ -68,6 +68,8 @@ unsigned long sector_address[19]={
  * functions
  */
 
+void uart0_send_byte(u8 send);
+
 void mmap_init(u8 memtype) {
 
        MEMMAP=memtype;
@@ -86,105 +88,6 @@ void pll_init(void) {
                continue;
 }
 
-int flash_sector_erase(u8 flash,u8 sector) {
-
-       u32 a18_12;
-       u32 base;
-
-       if(sector>18)
-               return -1;
-       a18_12=sector_address[sector]<<1;
-
-       if((flash!='0')|(flash!='2'))
-               return -1;
-
-       switch(flash) {
-               case '0':
-                       base=0x80000000;
-                       B0F555=0xaa;
-                       B0F2AA=0x55;
-                       B0F555=0x80;
-                       B0F555=0xaa;
-                       B0F2AA=0x55;
-                       *((volatile u16 *)(base|a18_12))=0x30;
-                       break;
-               case '2': 
-                       base=0x82000000;
-                       B2F555=0xaa;
-                       B2F2AA=0x55;
-                       B2F555=0x80;
-                       B2F555=0xaa;
-                       B2F2AA=0x55;
-                       *((volatile u16 *)(base|a18_12))=0x30;
-                       break;
-               default:
-                       return -1;
-       }
-
-       return 0;
-}
-
-int flash_chip_erase(u8 bank) {
-
-       if((bank!='0')|(bank!='2'))
-               return -1;
-
-       if(bank=='0') {
-               B0F555=0xaa;
-               B0F2AA=0x55;
-               B0F555=0x80;
-               B0F555=0xaa;
-               B0F2AA=0x55;
-               B0F555=0x10;
-       }
-       else {
-               B2F555=0xaa;
-               B2F2AA=0x55;
-               B2F555=0x80;
-               B2F555=0xaa;
-               B2F2AA=0x55;
-               B2F555=0x10;
-       }
-}
-
-void unlock_bypass(u8 bank) {
-
-       if((bank!='0')|(bank!='2'))
-               return;
-
-       if(bank=='0') {
-               B0F555=0xaa;
-               B0F2AA=0x55;
-               B0F555=0x20;
-       }
-       else {
-               B2F555=0xaa;
-               B2F2AA=0x55;
-               B2F555=0x20;
-       }
-}
-
-void unlock_bypass_reset(u8 bank) {
-
-       if((bank!='0')|(bank!='2'))
-               return;
-
-       if(bank=='0') {
-               B0F=0x90;
-               B0F=0x00;
-       }
-       else {
-               B2F=0x90;
-               B2F=0x00;
-       }
-}
-
-void flash_write(u32 addr,u16 data) {
-
-       *((volatile unsigned short *)addr)=0xa0;
-       *((volatile unsigned short *)addr)=data;
-}
-
 void ext_mem_bank_init(void) {
 
        BCFG0=0x10000420;       // flash 1
@@ -290,11 +193,152 @@ u8 uart0_get_byte(void) {
        return rx;
 }
 
-void receive_data_and_write_to_flash(u32 addr,u32 datalen) {
+void flash_reset(u8 bank) {
+
+       if((bank!='0')&(bank!='2'))
+               return;
+
+       if(bank=='0')
+               B0F=0xf0;
+       else
+               B2F=0xf0;
+}
+
+void flash_sector_erase(u8 flash,u8 sector) {
+
+       u32 a18_12;
+       u32 base;
+
+       if(sector>18)
+               return;
+       a18_12=sector_address[sector]<<1;
+
+       if((flash!='0')&(flash!='2'))
+               return;
+
+       switch(flash) {
+               case '0':
+                       base=0x80000000;
+                       B0F555=0xaa;
+                       B0F2AA=0x55;
+                       B0F555=0x80;
+                       B0F555=0xaa;
+                       B0F2AA=0x55;
+                       *((volatile u16 *)(base|a18_12))=0x30;
+                       break;
+               case '2': 
+                       base=0x82000000;
+                       B2F555=0xaa;
+                       B2F2AA=0x55;
+                       B2F555=0x80;
+                       B2F555=0xaa;
+                       B2F2AA=0x55;
+                       *((volatile u16 *)(base|a18_12))=0x30;
+                       break;
+               default:
+                       return;
+       }
+
+       return;
+}
+
+void flash_chip_erase(u8 bank) {
+
+       u8 status;
+
+       if((bank!='0')&(bank!='2'))
+               return;
+
+       if(bank=='0') {
+               B0F555=0xaa;
+               B0F2AA=0x55;
+               B0F555=0x80;
+               B0F555=0xaa;
+               B0F2AA=0x55;
+               B0F555=0x10;
+       }
+       else {
+               B2F555=0xaa;
+               B2F2AA=0x55;
+               B2F555=0x80;
+               B2F555=0xaa;
+               B2F2AA=0x55;
+               B2F555=0x10;
+       }
+
+       while(1) {
+               if(bank=='0')
+                       status=B0F;
+               else
+                       status=B2F;
+
+               if(status&0x80) {
+                       /* send an ack */
+                       uart0_send_byte(status);
+                       break;
+               }
+       }
+}
+
+void unlock_bypass(u8 bank) {
+
+       if((bank!='0')&(bank!='2'))
+               return;
+
+       if(bank=='0') {
+               B0F555=0xaa;
+               B0F2AA=0x55;
+               B0F555=0x20;
+       }
+       else {
+               B2F555=0xaa;
+               B2F2AA=0x55;
+               B2F555=0x20;
+       }
+}
+
+void unlock_bypass_reset(u8 bank) {
+
+       if((bank!='0')&(bank!='2'))
+               return;
+
+       if(bank=='0') {
+               B0F=0x90;
+               B0F=0x00;
+       }
+       else {
+               B2F=0x90;
+               B2F=0x00;
+       }
+}
+
+int flash_write(u32 addr,u16 data) {
+
+       u16 check;
+
+       if(data==0xffff)
+               return 0;
+
+       *((unsigned volatile short *)addr)=0xa0;
+       *((unsigned volatile short *)addr)=data;
+       while(1) {
+               check=*((unsigned short *)addr);
+               if((data&0x80)==(check&0x80))
+                       break;
+       }
+       if(data!=check)
+               return -1;
+
+       return 0;
+}
+
+int receive_data_and_write_to_flash(u32 addr,u32 datalen) {
 
        u8 bank;
-       u32 i;
+       u32 i,ret;
        u16 data;
+       u8 cksm;
+       u8 byte;
 
        /* which bank to program */
        if(addr<0x82000000)
@@ -306,16 +350,31 @@ void receive_data_and_write_to_flash(u32 addr,u32 datalen) {
        unlock_bypass(bank);
 
        /* receive and write data */
+       cksm=0;
+       ret=0;
        for(i=0;i<datalen/2;i++) {
-               data=uart0_get_byte();
-               data=uart0_get_byte()<<8;
-               *((unsigned volatile short *)addr)=0xa0;
-               *((unsigned volatile short *)addr)=data;
+               byte=uart0_get_byte();
+               data=byte;
+               cksm+=byte;
+               byte=uart0_get_byte();
+               cksm+=byte;
+               data|=byte<<8;
+               if(flash_write(addr,data)<0)
+                       ret=-1;
                addr+=2;
        }
 
        /* relock bypass */
        unlock_bypass_reset(bank);
+
+       /* modify cksm on purpose, so the user knows ... */
+       if(ret==-1)
+               cksm+=1;
+
+       /* send the cksm */
+       uart0_send_byte(cksm);
+
+       return ret;
 }
 
 /*