X-Git-Url: https://hackdaworld.org/gitweb/?a=blobdiff_plain;f=betty%2Ffwflash.c;h=2704fd5a41d96c484e26dc020be8b8e174fe2105;hb=eca427bb7d2ac0dbd337a3797fcea63991c51b38;hp=8d837e780cb5e2e5b2ca63ada07df815ab70b55e;hpb=4e4a1db6c0107ba6491a06ad82515246f97402c0;p=my-code%2Farm.git diff --git a/betty/fwflash.c b/betty/fwflash.c index 8d837e7..2704fd5 100644 --- a/betty/fwflash.c +++ b/betty/fwflash.c @@ -9,19 +9,35 @@ * include files */ +#include + #include "lpc2xxx.h" /* * defines */ -/* band 0/2 addr */ +/* bank 0/2 and boootloader addr/size */ #define BANK0 0x80000000 #define BANK2 0x82000000 +#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 @@ -34,155 +50,155 @@ 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 SEND_OK TX_BYTE('o'); TX_BYTE('k'); TX_BYTE('\n'); \ - TX_BYTE('\r'); +unsigned long sector_address[19]={ + 0x00000,0x02000,0x03000,0x04000,0x08000, + 0x10000,0x18000, + 0x20000,0x28000, + 0x30000,0x38000, + 0x40000,0x48000, + 0x50000,0x58000, + 0x60000,0x68000, + 0x70000,0x78000 +}; /* - * function prototypes + * functions */ -void mmap_init(u8 memtype); -void uart0_init(void); -void uart0_send_string(char *txbuf); -void uart0_send_char(char send); +void mmap_init(u8 memtype) { -/* - * main function - */ + MEMMAP=memtype; +} -int main(void) { +void pll_init(void) { - /* variables */ - - u32 i,addrlen,datalen; - u8 buf[BUFSIZE]; - u32 addr; - u16 *dptr; - u8 cmd; - u8 txrx; + /* configuration */ + PLLCFG=0x42; // multiplier = 3 (for cclk), dividor = 4 (for f_cco) + PLLCON=0x03; // enable and set as clk source for the lpc + /* feed sequence */ + PLLFEED=0xaa; + PLLFEED=0x55; + /* wait for lock */ + while(!(PLLSTAT&(1<<10))) + continue; +} - /* memory mapping of interrupt vectors to static ram */ +int flash_sector_erase(u8 flash,u8 sector) { - //mmap_init(MMAP_RAM); + u32 a18_12; + u32 base; - /* uart initialization */ + if(sector>18) + return -1; + a18_12=sector_address[sector]<<1; - //uart0_init(); + if((flash!='0')|(flash!='2')) + return -1; - 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 + 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 -1; + } - /* external memory init */ + return 0; +} - BCFG0=0x1000FBEF; // no boot[1:0] influence? (thnx colibri) - // BCFG2 should be fine as is +int flash_chip_erase(u8 bank) { - /* begin the main loop */ - while(1) { + if((bank!='0')|(bank!='2')) + return -1; - /* receive cmd */ - while(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; + } +} - while(!(UART0_LSR&(1<<0))) - continue; - cmd=UART0_RBR; +void unlock_bypass(u8 bank) { - if(cmd==CMD_CHIP_ERASE) { -SEND_OK - addrlen=0; - datalen=1; - break; - } + if((bank!='0')|(bank!='2')) + return; - if(cmd==CMD_READ) { - addrlen=4; - datalen=1; - break; - } + if(bank=='0') { + B0F555=0xaa; + B0F2AA=0x55; + B0F555=0x20; + } + else { + B2F555=0xaa; + B2F2AA=0x55; + B2F555=0x20; } +} - /* receive (only if there is) more data from uart0 */ +void unlock_bypass_reset(u8 bank) { - addr=0; - for(i=0;i address lines + */ - MEMMAP=memtype; + PINSEL2=0x0d6041d4; } void uart0_init(void) { @@ -190,7 +206,7 @@ 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_DLL=0x04; // br: 38400 @ 10/4 mhz UART0_DLM=0x00; UART0_LCR=0x03; // unset dlab } @@ -201,15 +217,60 @@ void uart0_send_string(char *txbuf) { i=0; - while(txbuf[i]) + 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'; - while(!(UART0_LSR&(1<<6))) {} + /* 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_char(char send) { +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; @@ -217,3 +278,186 @@ void uart0_send_char(char send) { UART0_THR=send; } +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; + u8 byte; + u8 cksm; + + /* which bank to program */ + if(addr<0x82000000) + bank='0'; + else + bank='2'; + + /* unlock bypass */ + unlock_bypass(bank); + + /* receive and write data */ + cksm=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<=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; +} +