2 * fwflash.c - handling the betty flashes
4 * author: hackbard@hackdaworld.org
20 /* bank 0/2 and boootloader addr/size */
21 #define BANK0 0x80000000
22 #define BANK2 0x82000000
23 #define BANK_SIZE 0x00100000
24 #define BOOTLOADER 0x7fffe000
25 #define BL_SIZE 0x00002000
27 /* flash cmd addresses - flash[0-18] <--> arm[1-19]*/
28 #define B0F555 (*((volatile unsigned short *)(BANK0|0xaaa))) // 0x555
29 #define B0F2AA (*((volatile unsigned short *)(BANK0|0x554))) // 0x2aa
30 #define B0F (*((volatile unsigned short *)(BANK0)))
31 #define B2F555 (*((volatile unsigned short *)(BANK2|0xaaa))) // 0x555
32 #define B2F2AA (*((volatile unsigned short *)(BANK2|0x554))) // 0x2aa
33 #define B2F (*((volatile unsigned short *)(BANK2)))
38 #define CMD_CHIP_ERASE 'E'
39 #define CMD_SECTOR_ERASE 'S'
40 #define CMD_CHIP_ID 'I'
48 typedef unsigned char u8;
49 typedef unsigned short u16;
50 typedef unsigned int u32;
56 unsigned long sector_address[19]={
57 0x00000,0x02000,0x03000,0x04000,0x08000,
71 void uart0_send_byte(u8 send);
73 void mmap_init(u8 memtype) {
81 PLLCFG=0x42; // multiplier = 3 (for cclk), dividor = 4 (for f_cco)
82 PLLCON=0x03; // enable and set as clk source for the lpc
87 while(!(PLLSTAT&(1<<10)))
91 void ext_mem_bank_init(void) {
93 BCFG0=0x10000420; // flash 1
94 BCFG1=0x00000c42; // lcd
95 BCFG2=0x10000420; // flash 2
98 void pin_select_init() {
101 * a[19:2] -> address lines
107 void uart0_init(void) {
109 PINSEL0=0x05; // pin select -> tx, rx
110 UART0_FCR=0x07; // enable fifo
111 UART0_LCR=0x83; // set dlab + word length
112 UART0_DLL=0x04; // br: 38400 @ 10/4 mhz
114 UART0_LCR=0x03; // unset dlab
117 void uart0_send_string(char *txbuf) {
124 UART0_THR=txbuf[i++];
125 /* flush if tx buffer maximum reached */
127 while(!(UART0_LSR&(1<<6)))
131 /* flush if \n and \r do not fit in the tx buffer */
133 while(!(UART0_LSR&(1<<6)))
139 /* flush uart0 anyways */
140 while(!(UART0_LSR&(1<<6)))
144 void uart0_send_buf16(u16 *buf,int len) {
150 for(i=0;i<len/2;i++) {
152 while(!(UART0_LSR&(1<<6)))
154 UART0_THR=buf[i]&0xff;
155 UART0_THR=(buf[i]>>8)&0xff;
159 void uart0_send_buf32(u32 *buf,int len) {
165 for(i=0;i<len/4;i++) {
167 while(!(UART0_LSR&(1<<6)))
169 UART0_THR=buf[i]&0xff;
170 UART0_THR=(buf[i]>>8)&0xff;
171 UART0_THR=(buf[i]>>16)&0xff;
172 UART0_THR=(buf[i]>>24)&0xff;
176 void uart0_send_byte(u8 send) {
178 while(!(UART0_LSR&(1<<5)))
184 u8 uart0_get_byte(void) {
188 while(!(UART0_LSR&(1<<0)))
196 void flash_reset(u8 bank) {
198 if((bank!='0')&(bank!='2'))
207 void flash_sector_erase(u8 flash,u8 sector) {
214 a18_12=sector_address[sector]<<1;
216 if((flash!='0')&(flash!='2'))
227 *((volatile u16 *)(base|a18_12))=0x30;
236 *((volatile u16 *)(base|a18_12))=0x30;
245 void flash_chip_erase(u8 bank) {
249 if((bank!='0')&(bank!='2'))
280 void unlock_bypass(u8 bank) {
282 if((bank!='0')&(bank!='2'))
297 void unlock_bypass_reset(u8 bank) {
299 if((bank!='0')&(bank!='2'))
312 int flash_write(u32 addr,u16 data) {
316 *((unsigned volatile short *)addr)=0xa0;
317 *((unsigned volatile short *)addr)=data;
319 check=*((unsigned short *)addr);
320 if((data&0x80)==(check&0x80))
329 int receive_data_and_write_to_flash(u32 addr,u32 datalen) {
337 /* which bank to program */
346 /* receive and write data */
349 for(i=0;i<datalen/2;i++) {
350 byte=uart0_get_byte();
351 uart0_send_byte(byte);
354 byte=uart0_get_byte();
355 uart0_send_byte(byte);
358 if(flash_write(addr,data)<0)
364 unlock_bypass_reset(bank);
366 /* modify cksm on purpose, so the user knows ... */
370 uart0_send_byte(cksm);
383 u32 i,addrlen,datalen,addr;
389 /* memory mapping of interrupt vectors to static ram */
391 //mmap_init(MMAP_RAM);
393 /* pll initialization */
396 /* uart initialization */
399 /* external memory init */
402 /* pin select init */
405 /* begin the main loop */
411 cmd=uart0_get_byte();
418 case CMD_SECTOR_ERASE:
442 /* receive (only if there is) more data from uart0 */
444 for(i=0;i<addrlen;i++) {
445 txrx=uart0_get_byte();
446 addr|=(txrx<<((addrlen-i-1)*8));
449 for(i=0;i<datalen;i++)
450 buf[i]=uart0_get_byte();
452 /* process the cmd */
454 case CMD_SECTOR_ERASE:
455 flash_sector_erase(buf[0],buf[1]);
458 /* data length to read */
459 datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
460 /* check addr and datalen */
461 if((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))
462 uart0_send_buf16((u16 *)addr,datalen);
463 if((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE))
464 uart0_send_buf16((u16 *)addr,datalen);
465 if((addr>=BOOTLOADER)&(addr+datalen<=BOOTLOADER+BL_SIZE))
466 uart0_send_buf32((u32 *)addr,datalen);
470 datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
471 /* check addr and data len */
472 if(((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))|
473 ((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE)))
474 receive_data_and_write_to_flash(addr,datalen);
477 flash_chip_erase(buf[0]);
484 data=*((u16 *)BANK0);
485 uart0_send_buf16(&data,2);
486 data=*((u16 *)(BANK0|0x200));
487 uart0_send_buf16(&data,2);
489 else if(buf[0]=='2') {
493 data=*((u16 *)BANK2);
494 uart0_send_buf16(&data,2);
495 data=*((u16 *)(BANK2|0x200));
496 uart0_send_buf16(&data,2);