initial version fwflash supporting writes to flash (not tested!)
authorhackbard <hackbard@staubsauger.localdomain>
Sat, 1 Sep 2007 18:19:16 +0000 (20:19 +0200)
committerhackbard <hackbard@staubsauger.localdomain>
Sat, 1 Sep 2007 18:19:16 +0000 (20:19 +0200)
betty/fwflash.c

index b6d48a6..c4a2155 100644 (file)
 #define B2F2AA (*((volatile unsigned short *)(BANK2|0x554)))   // 0x2aa
 #define B2F    (*((volatile unsigned short *)(BANK2)))
 
-#define FLASH0_555     (*((volatile unsigned short *) 0x80000AAA))
-#define FLASH0_2AA     (*((volatile unsigned short *) 0x80000554))
-#define FLASH0         (*((volatile unsigned short *) 0x80000000))
-
 /* commands */
 #define CMD_READ               'R'
+#define CMD_WRITE              'W'
 #define CMD_CHIP_ERASE         'E'
 #define CMD_SECTOR_ERASE       'S'
 #define CMD_CHIP_ID            'I'
@@ -127,25 +124,81 @@ int flash_sector_erase(u8 flash,u8 sector) {
        return 0;
 }
 
-void flash_sector0_erase(void) {
-       B0F555=0xaa;
-       B0F2AA=0x55;
-       B0F555=0x80;
-       B0F555=0xaa;
-       B0F2AA=0x55;
-       *((volatile u16 *)(0x80000000))=0x30;
+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
+       BCFG1=0x00000c42;       // lcd
+       BCFG2=0x10000420;       // flash 2
 }
 
-void flash_chip_erase(void) {
+void pin_select_init() {
 
-       /* test, erase flash at bank0 */
+       /*
+        * a[19:2] -> address lines
+        */
 
-       B0F555=0xaa;
-       B0F2AA=0x55;
-       B0F555=0x80;
-       B0F555=0xaa;
-       B0F2AA=0x55;
-       B0F555=0x10;
+       PINSEL2=0x0d6041d4;
 }
 
 void uart0_init(void) {
@@ -237,6 +290,34 @@ u8 uart0_get_byte(void) {
        return rx;
 }
 
+void receive_data_and_write_to_flash(u32 addr,u32 datalen) {
+
+       u8 bank;
+       u32 i;
+       u16 data;
+
+       /* which bank to program */
+       if(addr<0x82000000)
+               bank='0';
+       else
+               bank='2';
+
+       /* unlock bypass */
+       unlock_bypass(bank);
+
+       /* receive and write data */
+       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;
+               addr+=2;
+       }
+
+       /* relock bypass */
+       unlock_bypass_reset(bank);
+}
+
 /*
  * main function
  */
@@ -262,15 +343,10 @@ int main(void) {
        uart0_init();
 
        /* external memory init */
-       BCFG0=0x10000420;
-       BCFG2=0x10000420;
+       ext_mem_bank_init();
 
-FLASH0_555 = 0xAA;
-FLASH0_2AA = 0x55;
-FLASH0_555 = 0x80;
-FLASH0_555 = 0xAA;
-FLASH0_2AA = 0x55;
-FLASH0 = 0x30;
+       /* pin select init */
+       pin_select_init();
 
        /* begin the main loop */
        while(1) {
@@ -286,12 +362,15 @@ FLASH0 = 0x30;
                                datalen=1;
                                break;
                        case CMD_SECTOR_ERASE:
-                               addrlen=1;
-                               datalen=0;
+                               addrlen=0;
+                               datalen=2;
                                break;
                        case CMD_READ:
                                addrlen=4;
                                datalen=4;
+                       case CMD_WRITE:
+                               addrlen=4;
+                               datalen=4;
                                break;
                        case CMD_CHIP_ID:
                                addrlen=0;
@@ -319,14 +398,12 @@ FLASH0 = 0x30;
        /* process the cmd */
        switch(cmd) {
                case CMD_SECTOR_ERASE:
-                       flash_sector0_erase();
+                       flash_sector_erase(buf[0],buf[1]);
                        break;
                case CMD_READ:
                        /* data length to read */
                        datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
                        /* check addr and datalen */
-datalen=0x40;
-addr=0x80000000;
                        if((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))
                                uart0_send_buf16((u16 *)addr,datalen);
                        if((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE))
@@ -334,19 +411,16 @@ addr=0x80000000;
                        if((addr>=BOOTLOADER)&(addr+datalen<=BOOTLOADER+BL_SIZE))
                                uart0_send_buf32((u32 *)addr,datalen);
                        break;
+               case CMD_WRITE:
+                       /* data length */
+                       datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
+                       /* check addr and data len */
+                       if(((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))|
+                          ((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE)))
+                               receive_data_and_write_to_flash(addr,datalen);
+                       break;
                case CMD_CHIP_ERASE:
-                       if(buf[0]=='0') {
-                               flash_chip_erase();
-                       }
-                       else if(buf[0]=='2') {
-                               B2F555=0xaa;
-                               B2F2AA=0x55;
-                               B2F555=0x80;
-                               B2F555=0xaa;
-                               B2F2AA=0x55;
-                               B2F555=0x10;
-                       }
-                       uart0_send_byte(buf[0]);
+                       flash_chip_erase(buf[0]);
                        break;
                case CMD_CHIP_ID:
                        if(buf[0]=='0') {
@@ -354,16 +428,19 @@ addr=0x80000000;
                                B0F2AA=0x55;
                                B0F555=0x90;
                                data=*((u16 *)BANK0);
+                               uart0_send_buf16(&data,2);
                                data=*((u16 *)(BANK0|0x200));
+                               uart0_send_buf16(&data,2);
                        }
                        else if(buf[0]=='2') {
                                B2F555=0xaa;
                                B2F2AA=0x55;
                                B2F555=0x90;
                                data=*((u16 *)BANK2);
+                               uart0_send_buf16(&data,2);
                                data=*((u16 *)(BANK2|0x200));
+                               uart0_send_buf16(&data,2);
                        }
-                       uart0_send_buf16(&data,2);
                        break;
                default:
                        break;