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)))
35 #define FLASH0_555 (*((volatile unsigned short *) 0x80000AAA))
36 #define FLASH0_2AA (*((volatile unsigned short *) 0x80000554))
37 #define FLASH0 (*((volatile unsigned short *) 0x80000000))
41 #define CMD_CHIP_ERASE 'E'
42 #define CMD_SECTOR_ERASE 'S'
43 #define CMD_CHIP_ID 'I'
51 typedef unsigned char u8;
52 typedef unsigned short u16;
53 typedef unsigned int u32;
59 unsigned long sector_address[19]={
60 0x00000,0x02000,0x03000,0x04000,0x08000,
74 void mmap_init(u8 memtype) {
82 PLLCFG=0x42; // multiplier = 3 (for cclk), dividor = 4 (for f_cco)
83 PLLCON=0x03; // enable and set as clk source for the lpc
88 while(!(PLLSTAT&(1<<10)))
92 int flash_sector_erase(u8 flash,u8 sector) {
99 a18_12=sector_address[sector]<<1;
101 if((flash!='0')|(flash!='2'))
112 *((volatile u16 *)(base|a18_12))=0x30;
121 *((volatile u16 *)(base|a18_12))=0x30;
130 void flash_sector0_erase(void) {
136 *((volatile u16 *)(0x80000000))=0x30;
139 void flash_chip_erase(void) {
141 /* test, erase flash at bank0 */
151 void uart0_init(void) {
153 PINSEL0=0x05; // pin select -> tx, rx
154 UART0_FCR=0x07; // enable fifo
155 UART0_LCR=0x83; // set dlab + word length
156 UART0_DLL=0x04; // br: 38400 @ 10/4 mhz
158 UART0_LCR=0x03; // unset dlab
161 void uart0_send_string(char *txbuf) {
168 UART0_THR=txbuf[i++];
169 /* flush if tx buffer maximum reached */
171 while(!(UART0_LSR&(1<<6)))
175 /* flush if \n and \r do not fit in the tx buffer */
177 while(!(UART0_LSR&(1<<6)))
183 /* flush uart0 anyways */
184 while(!(UART0_LSR&(1<<6)))
188 void uart0_send_buf16(u16 *buf,int len) {
194 for(i=0;i<len/2;i++) {
196 while(!(UART0_LSR&(1<<6)))
198 UART0_THR=buf[i]&0xff;
199 UART0_THR=(buf[i]>>8)&0xff;
203 void uart0_send_buf32(u32 *buf,int len) {
209 for(i=0;i<len/4;i++) {
211 while(!(UART0_LSR&(1<<6)))
213 UART0_THR=buf[i]&0xff;
214 UART0_THR=(buf[i]>>8)&0xff;
215 UART0_THR=(buf[i]>>16)&0xff;
216 UART0_THR=(buf[i]>>24)&0xff;
220 void uart0_send_byte(u8 send) {
222 while(!(UART0_LSR&(1<<5)))
228 u8 uart0_get_byte(void) {
232 while(!(UART0_LSR&(1<<0)))
248 u32 i,addrlen,datalen,addr;
254 /* memory mapping of interrupt vectors to static ram */
256 //mmap_init(MMAP_RAM);
258 /* pll initialization */
261 /* uart initialization */
264 /* external memory init */
275 /* begin the main loop */
281 cmd=uart0_get_byte();
288 case CMD_SECTOR_ERASE:
309 /* receive (only if there is) more data from uart0 */
311 for(i=0;i<addrlen;i++) {
312 txrx=uart0_get_byte();
313 addr|=(txrx<<((addrlen-i-1)*8));
316 for(i=0;i<datalen;i++)
317 buf[i]=uart0_get_byte();
319 /* process the cmd */
321 case CMD_SECTOR_ERASE:
322 flash_sector0_erase();
325 /* data length to read */
326 datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
327 /* check addr and datalen */
330 if((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))
331 uart0_send_buf16((u16 *)addr,datalen);
332 if((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE))
333 uart0_send_buf16((u16 *)addr,datalen);
334 if((addr>=BOOTLOADER)&(addr+datalen<=BOOTLOADER+BL_SIZE))
335 uart0_send_buf32((u32 *)addr,datalen);
341 else if(buf[0]=='2') {
349 uart0_send_byte(buf[0]);
356 data=*((u16 *)BANK0);
357 data=*((u16 *)(BANK0|0x200));
359 else if(buf[0]=='2') {
363 data=*((u16 *)BANK2);
364 data=*((u16 *)(BANK2|0x200));
366 uart0_send_buf16(&data,2);