+u8 uart0_get_byte(void) {
+
+ u8 rx;
+
+ while(!(UART0_LSR&(1<<0)))
+ continue;
+
+ rx=UART0_RBR;
+
+ 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
+ */
+
+int main(void) {
+
+ /* variables */
+
+ u32 i,addrlen,datalen,addr;
+ u8 buf[BUFSIZE];
+ u16 data;
+ u8 cmd;
+ u8 txrx;
+
+ /* memory mapping of interrupt vectors to static ram */
+
+ //mmap_init(MMAP_RAM);
+
+ /* pll initialization */
+ pll_init();
+
+ /* uart initialization */
+ uart0_init();
+
+ /* external memory init */
+ ext_mem_bank_init();
+
+ /* pin select init */
+ pin_select_init();
+
+ /* begin the main loop */
+ while(1) {
+
+ /* receive cmd */
+ while(1) {
+
+ cmd=uart0_get_byte();
+ txrx=1;
+ switch(cmd) {
+ case CMD_CHIP_ERASE:
+ addrlen=0;
+ datalen=1;
+ break;
+ case CMD_SECTOR_ERASE:
+ 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;
+ datalen=1;
+ break;
+ default:
+ txrx=0;
+ break;
+ }
+
+ if(txrx)
+ break;
+ }
+
+ /* receive (only if there is) more data from uart0 */
+ addr=0;
+ for(i=0;i<addrlen;i++) {
+ txrx=uart0_get_byte();
+ addr|=(txrx<<((addrlen-i-1)*8));
+ }
+
+ for(i=0;i<datalen;i++)
+ buf[i]=uart0_get_byte();
+
+ /* process the cmd */
+ switch(cmd) {
+ case CMD_SECTOR_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 */
+ if((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))
+ uart0_send_buf16((u16 *)addr,datalen);
+ if((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE))
+ uart0_send_buf16((u16 *)addr,datalen);
+ 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:
+ flash_chip_erase(buf[0]);
+ break;
+ case CMD_CHIP_ID:
+ if(buf[0]=='0') {
+ B0F555=0xaa;
+ 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);
+ }
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ return 0;
+}
+