testing commit
[my-code/arm.git] / betty / fwflash.c
1 /*
2  * fwflash.c - handling the betty flashes
3  *
4  * author: hackbard@hackdaworld.org
5  *
6  */
7
8 /*
9  * include files
10  */
11
12 #include <stdio.h>
13
14 #include "lpc2xxx.h"
15
16 /*
17  * defines
18  */
19
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
26
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)))
34
35 #define FLASH0_555      (*((volatile unsigned short *) 0x80000AAA))
36 #define FLASH0_2AA      (*((volatile unsigned short *) 0x80000554))
37 #define FLASH0          (*((volatile unsigned short *) 0x80000000))
38
39 /* commands */
40 #define CMD_READ                'R'
41 #define CMD_CHIP_ERASE          'E'
42 #define CMD_SECTOR_ERASE        'S'
43 #define CMD_CHIP_ID             'I'
44
45 #define BUFSIZE                 16
46
47 /*
48  * type definitions
49  */
50
51 typedef unsigned char u8;
52 typedef unsigned short u16;
53 typedef unsigned int u32;
54
55 /*
56  * sector addresses
57  */
58
59 unsigned long sector_address[19]={
60         0x00000,0x02000,0x03000,0x04000,0x08000,
61         0x10000,0x18000,
62         0x20000,0x28000,
63         0x30000,0x38000,
64         0x40000,0x48000,
65         0x50000,0x58000,
66         0x60000,0x68000,
67         0x70000,0x78000
68 };
69
70 /*
71  * functions
72  */
73
74 void mmap_init(u8 memtype) {
75
76         MEMMAP=memtype;
77 }
78
79 void pll_init(void) {
80
81         /* configuration */
82         PLLCFG=0x42;    // multiplier = 3 (for cclk), dividor = 4 (for f_cco)
83         PLLCON=0x03;    // enable and set as clk source for the lpc
84         /* feed sequence */
85         PLLFEED=0xaa;
86         PLLFEED=0x55;
87         /* wait for lock */
88         while(!(PLLSTAT&(1<<10)))
89                 continue;
90 }
91
92 int flash_sector_erase(u8 flash,u8 sector) {
93
94         u32 a18_12;
95         u32 base;
96
97         if(sector>18)
98                 return -1;
99         a18_12=sector_address[sector]<<1;
100
101         if((flash!='0')|(flash!='2'))
102                 return -1;
103
104         switch(flash) {
105                 case '0':
106                         base=0x80000000;
107                         B0F555=0xaa;
108                         B0F2AA=0x55;
109                         B0F555=0x80;
110                         B0F555=0xaa;
111                         B0F2AA=0x55;
112                         *((volatile u16 *)(base|a18_12))=0x30;
113                         break;
114                 case '2': 
115                         base=0x82000000;
116                         B2F555=0xaa;
117                         B2F2AA=0x55;
118                         B2F555=0x80;
119                         B2F555=0xaa;
120                         B2F2AA=0x55;
121                         *((volatile u16 *)(base|a18_12))=0x30;
122                         break;
123                 default:
124                         return -1;
125         }
126
127         return 0;
128 }
129
130 void flash_sector0_erase(void) {
131         B0F555=0xaa;
132         B0F2AA=0x55;
133         B0F555=0x80;
134         B0F555=0xaa;
135         B0F2AA=0x55;
136         *((volatile u16 *)(0x80000000))=0x30;
137 }
138
139 void flash_chip_erase(void) {
140
141         /* test, erase flash at bank0 */
142
143         B0F555=0xaa;
144         B0F2AA=0x55;
145         B0F555=0x80;
146         B0F555=0xaa;
147         B0F2AA=0x55;
148         B0F555=0x10;
149 }
150
151 void uart0_init(void) {
152
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
157         UART0_DLM=0x00;
158         UART0_LCR=0x03;                 // unset dlab
159 }
160
161 void uart0_send_string(char *txbuf) {
162
163         int i;
164
165         i=0;
166
167         while(txbuf[i]) {
168                 UART0_THR=txbuf[i++];
169                 /* flush if tx buffer maximum reached */
170                 if(!(i%16))
171                         while(!(UART0_LSR&(1<<6)))
172                                 continue;
173         }
174         
175         /* flush if \n and \r do not fit in the tx buffer */
176         if(i>14)
177                 while(!(UART0_LSR&(1<<6)))
178                         continue;
179
180         UART0_THR='\n';
181         UART0_THR='\r';
182
183         /* flush uart0 anyways */
184         while(!(UART0_LSR&(1<<6)))
185                 continue;
186 }
187
188 void uart0_send_buf16(u16 *buf,int len) {
189
190         int i;
191
192         i=0;
193
194         for(i=0;i<len/2;i++) {
195                 if(!(i%8))
196                         while(!(UART0_LSR&(1<<6)))
197                                 continue;
198                 UART0_THR=buf[i]&0xff;
199                 UART0_THR=(buf[i]>>8)&0xff;
200         }
201 }
202
203 void uart0_send_buf32(u32 *buf,int len) {
204
205         int i;
206
207         i=0;
208
209         for(i=0;i<len/4;i++) {
210                 if(!(i%4))
211                         while(!(UART0_LSR&(1<<6)))
212                                 continue;
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;
217         }
218 }
219
220 void uart0_send_byte(u8 send) {
221
222         while(!(UART0_LSR&(1<<5)))
223                 continue;
224
225         UART0_THR=send;
226 }
227
228 u8 uart0_get_byte(void) {
229
230         u8 rx;
231
232         while(!(UART0_LSR&(1<<0)))
233                 continue;
234
235         rx=UART0_RBR;
236
237         return rx;
238 }
239
240 /*
241  * main function
242  */
243
244 int main(void) {
245
246         /* variables */
247
248         u32 i,addrlen,datalen,addr;
249         u8 buf[BUFSIZE];
250         u16 data;
251         u8 cmd;
252         u8 txrx;
253
254         /* memory mapping of interrupt vectors to static ram */
255
256         //mmap_init(MMAP_RAM);
257         
258         /* pll initialization */
259         pll_init();
260
261         /* uart initialization */
262         uart0_init();
263
264         /* external memory init */
265         BCFG0=0x10000420;
266         BCFG2=0x10000420;
267
268 FLASH0_555 = 0xAA;
269 FLASH0_2AA = 0x55;
270 FLASH0_555 = 0x80;
271 FLASH0_555 = 0xAA;
272 FLASH0_2AA = 0x55;
273 FLASH0 = 0x30;
274
275         /* begin the main loop */
276         while(1) {
277
278         /* receive cmd */
279         while(1) {
280
281                 cmd=uart0_get_byte();
282                 txrx=1;
283                 switch(cmd) {
284                         case CMD_CHIP_ERASE:
285                                 addrlen=0;
286                                 datalen=1;
287                                 break;
288                         case CMD_SECTOR_ERASE:
289                                 addrlen=1;
290                                 datalen=0;
291                                 break;
292                         case CMD_READ:
293                                 addrlen=4;
294                                 datalen=4;
295                                 break;
296                         case CMD_CHIP_ID:
297                                 addrlen=0;
298                                 datalen=1;
299                                 break;
300                         default:
301                                 txrx=0;
302                                 break;
303                 }
304
305                 if(txrx)
306                         break;
307         }
308
309         /* receive (only if there is) more data from uart0 */
310         addr=0;
311         for(i=0;i<addrlen;i++) {
312                 txrx=uart0_get_byte();
313                 addr|=(txrx<<((addrlen-i-1)*8));
314         }
315
316         for(i=0;i<datalen;i++)
317                 buf[i]=uart0_get_byte();
318
319         /* process the cmd */
320         switch(cmd) {
321                 case CMD_SECTOR_ERASE:
322                         flash_sector0_erase();
323                         break;
324                 case CMD_READ:
325                         /* data length to read */
326                         datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
327                         /* check addr and datalen */
328 datalen=0x40;
329 addr=0x80000000;
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);
336                         break;
337                 case CMD_CHIP_ERASE:
338                         if(buf[0]=='0') {
339                                 flash_chip_erase();
340                         }
341                         else if(buf[0]=='2') {
342                                 B2F555=0xaa;
343                                 B2F2AA=0x55;
344                                 B2F555=0x80;
345                                 B2F555=0xaa;
346                                 B2F2AA=0x55;
347                                 B2F555=0x10;
348                         }
349                         uart0_send_byte(buf[0]);
350                         break;
351                 case CMD_CHIP_ID:
352                         if(buf[0]=='0') {
353                                 B0F555=0xaa;
354                                 B0F2AA=0x55;
355                                 B0F555=0x90;
356                                 data=*((u16 *)BANK0);
357                                 data=*((u16 *)(BANK0|0x200));
358                         }
359                         else if(buf[0]=='2') {
360                                 B2F555=0xaa;
361                                 B2F2AA=0x55;
362                                 B2F555=0x90;
363                                 data=*((u16 *)BANK2);
364                                 data=*((u16 *)(BANK2|0x200));
365                         }
366                         uart0_send_buf16(&data,2);
367                         break;
368                 default:
369                         break;
370         }
371                 
372         }
373
374         return 0;
375 }
376