#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'
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) {
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
*/
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) {
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;
/* 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))
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') {
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;