X-Git-Url: https://hackdaworld.org/cgi-bin/gitweb.cgi?p=my-code%2Farm.git;a=blobdiff_plain;f=betty%2Ffwflash.c;h=26a68a8198065f095ed306618faf003de87814e9;hp=e2f78d9895b6a039e1d3360ccfc6b6b23b85f68c;hb=HEAD;hpb=f8569c0f53d6b77d5d69d8e31a9d2c25b654265c diff --git a/betty/fwflash.c b/betty/fwflash.c index e2f78d9..26a68a8 100644 --- a/betty/fwflash.c +++ b/betty/fwflash.c @@ -17,19 +17,27 @@ * defines */ -/* bank 0/2 addr */ +/* bank 0/2 and boootloader addr/size */ #define BANK0 0x80000000 #define BANK2 0x82000000 - -/* flash cmd addresses */ -#define B0F555 (*((volatile unsigned long *)(BANK0|0x555))) -#define B0F2AA (*((volatile unsigned long *)(BANK0|0x2aa))) -#define B2F555 (*((volatile unsigned long *)(BANK2|0x555))) -#define B2F2AA (*((volatile unsigned long *)(BANK2|0x2aa))) +#define BANK_SIZE 0x00100000 +#define BOOTLOADER 0x7fffe000 +#define BL_SIZE 0x00002000 + +/* flash cmd addresses - flash[0-18] <--> arm[1-19]*/ +#define B0F555 (*((volatile unsigned short *)(BANK0|0xaaa))) // 0x555 +#define B0F2AA (*((volatile unsigned short *)(BANK0|0x554))) // 0x2aa +#define B0F (*((volatile unsigned short *)(BANK0))) +#define B2F555 (*((volatile unsigned short *)(BANK2|0xaaa))) // 0x555 +#define B2F2AA (*((volatile unsigned short *)(BANK2|0x554))) // 0x2aa +#define B2F (*((volatile unsigned short *)(BANK2))) /* commands */ #define CMD_READ 'R' +#define CMD_WRITE 'W' #define CMD_CHIP_ERASE 'E' +#define CMD_SECTOR_ERASE 'S' +#define CMD_CHIP_ID 'I' #define BUFSIZE 16 @@ -42,33 +50,332 @@ typedef unsigned short u16; typedef unsigned int u32; /* - * define macros + * sector addresses */ -#define TX_BYTE(x) while(!(UART0_LSR&(1<<5))) continue; \ - UART0_THR=x - -#define TX_NL TX_BYTE('\n'); TX_BYTE('\r') - -#define TX_STRING(x,len) for(scnt=0;scnt address lines + */ + + PINSEL2=0x0d6041d4; +} + +void uart0_init(void) { + + PINSEL0=0x05; // pin select -> tx, rx + UART0_FCR=0x07; // enable fifo + UART0_LCR=0x83; // set dlab + word length + UART0_DLL=0x04; // br: 38400 @ 10/4 mhz + UART0_DLM=0x00; + UART0_LCR=0x03; // unset dlab +} + +void uart0_send_string(char *txbuf) { + + int i; + + i=0; + + while(txbuf[i]) { + UART0_THR=txbuf[i++]; + /* flush if tx buffer maximum reached */ + if(!(i%16)) + while(!(UART0_LSR&(1<<6))) + continue; + } + + /* flush if \n and \r do not fit in the tx buffer */ + if(i>14) + while(!(UART0_LSR&(1<<6))) + continue; + + UART0_THR='\n'; + UART0_THR='\r'; + + /* flush uart0 anyways */ + while(!(UART0_LSR&(1<<6))) + continue; +} + +void uart0_send_buf16(u16 *buf,int len) { + + int i; + + i=0; + + for(i=0;i>8)&0xff; + } +} + +void uart0_send_buf32(u32 *buf,int len) { + + int i; + + i=0; + + for(i=0;i>8)&0xff; + UART0_THR=(buf[i]>>16)&0xff; + UART0_THR=(buf[i]>>24)&0xff; + } +} + +void uart0_send_byte(u8 send) { + + while(!(UART0_LSR&(1<<5))) + continue; + + UART0_THR=send; +} + +u8 uart0_get_byte(void) { + + u8 rx; + + while(!(UART0_LSR&(1<<0))) + continue; + + rx=UART0_RBR; + + return rx; +} + +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; + } -int scnt; + 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,ret; + u16 data; + u8 cksm; + u8 byte; + + /* which bank to program */ + if(addr<0x82000000) + bank='0'; + else + bank='2'; + + /* unlock bypass */ + unlock_bypass(bank); + + /* receive and write data */ + cksm=0; + ret=0; + for(i=0;i tx, rx - UART0_FCR=0x07; // enable fifo - UART0_LCR=0x83; // set dlab + word length - UART0_DLL=0x10; // br: 9600 @ 10/4 mhz - UART0_DLM=0x00; - UART0_LCR=0x03; // unset dlab + uart0_init(); /* external memory init */ + ext_mem_bank_init(); - BCFG0=0x1000FBEF; // BCFG2 should be fine as is + /* pin select init */ + pin_select_init(); /* begin the main loop */ while(1) { @@ -110,120 +413,101 @@ int main(void) { /* receive cmd */ while(1) { - while(!(UART0_LSR&(1<<0))) - continue; - cmd=UART0_RBR; - - if(cmd==CMD_CHIP_ERASE) { - addrlen=0; - datalen=1; - break; + 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(cmd==CMD_READ) { - addrlen=4; - datalen=1; + if(txrx) break; - } } /* receive (only if there is) more data from uart0 */ - addr=0; for(i=0;i=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=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=0x80; - B0F555=0xaa; - B0F2AA=0x55; - B0F555=0x10; + 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=0x80; - B2F555=0xaa; - B2F2AA=0x55; - B2F555=0x10; + B2F555=0x90; + data=*((u16 *)BANK2); + uart0_send_buf16(&data,2); + data=*((u16 *)(BANK2|0x200)); + uart0_send_buf16(&data,2); } break; default: break; } - - /* send an ack, the cmd! */ - TX_BYTE(cmd); } return 0; } -/* - * functions - */ - -void mmap_init(u8 memtype) { - - MEMMAP=memtype; -} - -void uart0_init(void) { - - PINSEL0=0x05; // pin select -> tx, rx - UART0_FCR=0x07; // enable fifo - UART0_LCR=0x83; // set dlab + word length - UART0_DLL=0x10; // br: 9600 @ 10/4 mhz - UART0_DLM=0x00; - UART0_LCR=0x03; // unset dlab -} - -void uart0_send_string(char *txbuf) { - - int i; - - i=0; - - while(txbuf[i]) - UART0_THR=txbuf[i++]; - UART0_THR='\n'; - UART0_THR='\r'; - - while(!(UART0_LSR&(1<<6))) {} -} - -void uart0_send_char(char send) { - - while(!(UART0_LSR&(1<<5))) - continue; - - UART0_THR=send; -} -