From: hackbard <hackbard@staubsauger.localdomain>
Date: Sat, 1 Sep 2007 18:19:16 +0000 (+0200)
Subject: initial version fwflash supporting writes to flash (not tested!)
X-Git-Url: https://hackdaworld.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=783e1e614cda26e0868c909561fb0c0029b26391;p=my-code%2Farm.git

initial version fwflash supporting writes to flash (not tested!)
---

diff --git a/betty/fwflash.c b/betty/fwflash.c
index b6d48a6..c4a2155 100644
--- a/betty/fwflash.c
+++ b/betty/fwflash.c
@@ -32,12 +32,9 @@
 #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;