still some bugs, though by setting pll mult -> br of 115200
[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 long *)(BANK0|0xaaa)))    // 0x555
29 #define B0F2AA  (*((volatile unsigned long *)(BANK0|0x554)))    // 0x2aa
30 #define B2F555  (*((volatile unsigned long *)(BANK2|0xaaa)))    // 0x555
31 #define B2F2AA  (*((volatile unsigned long *)(BANK2|0x554)))    // 0x2aa
32
33 /* commands */
34 #define CMD_READ                'R'
35 #define CMD_CHIP_ERASE          'E'
36 #define CMD_CHIP_ID             'I'
37
38 #define BUFSIZE                 16
39
40 /*
41  * type definitions
42  */
43
44 typedef unsigned char u8;
45 typedef unsigned short u16;
46 typedef unsigned int u32;
47
48 /*
49  * functions
50  */
51
52 void mmap_init(u8 memtype) {
53
54         MEMMAP=memtype;
55 }
56
57 void pll_init(void) {
58
59         /* configuration */
60         PLLCFG=0x02;            // multiplier = 2
61         PLLCON=0x03;            // enable and set as clk source for the lpc
62         /* feed sequence */
63         PLLFEED=0xaa;
64         PLLFEED=0x55;
65         /* wait for lock */
66         while(!(PLLSTAT&(1<<10)))
67                 continue;
68 }
69
70 void uart0_init(void) {
71
72         PINSEL0=0x05;                   // pin select -> tx, rx
73         UART0_FCR=0x07;                 // enable fifo
74         UART0_LCR=0x83;                 // set dlab + word length
75         UART0_DLL=0x04;                 // br: 38400 @ 10/4 mhz
76         UART0_DLM=0x00;
77         UART0_LCR=0x03;                 // unset dlab
78 }
79
80 void uart0_send_string(char *txbuf) {
81
82         int i;
83
84         i=0;
85
86         while(txbuf[i]) {
87                 UART0_THR=txbuf[i++];
88                 /* flush if tx buffer maximum reached */
89                 if(!(i%16))
90                         while(!(UART0_LSR&(1<<6)))
91                                 continue;
92         }
93         
94         /* flush if \n and \r do not fit in the tx buffer */
95         if(i>14)
96                 while(!(UART0_LSR&(1<<6)))
97                         continue;
98
99         UART0_THR='\n';
100         UART0_THR='\r';
101
102         /* flush uart0 anyways */
103         while(!(UART0_LSR&(1<<6)))
104                 continue;
105 }
106
107 void uart0_send_buf16(u16 *buf,int len) {
108
109         int i;
110
111         i=0;
112
113         for(i=0;i<len/2;i++) {
114                 if(!(i%8))
115                         while(!(UART0_LSR&(1<<6)))
116                                 continue;
117                 UART0_THR=buf[i]&0xff;
118                 UART0_THR=(buf[i]>>8)&0xff;
119         }
120 }
121
122 void uart0_send_buf32(u32 *buf,int len) {
123
124         int i;
125
126         i=0;
127
128         for(i=0;i<len/4;i++) {
129                 if(!(i%4))
130                         while(!(UART0_LSR&(1<<6)))
131                                 continue;
132                 UART0_THR=buf[i]&0xff;
133                 UART0_THR=(buf[i]>>8)&0xff;
134                 UART0_THR=(buf[i]>>16)&0xff;
135                 UART0_THR=(buf[i]>>24)&0xff;
136         }
137 }
138
139 void uart0_send_byte(u8 send) {
140
141         while(!(UART0_LSR&(1<<5)))
142                 continue;
143
144         UART0_THR=send;
145 }
146
147 u8 uart0_get_byte(void) {
148
149         u8 rx;
150
151         while(!(UART0_LSR&(1<<0)))
152                 continue;
153
154         rx=UART0_RBR;
155
156         return rx;
157 }
158
159 /*
160  * main function
161  */
162
163 int main(void) {
164
165         /* variables */
166
167         u32 i,addrlen,datalen,addr;
168         u8 buf[BUFSIZE];
169         u16 data;
170         u8 cmd;
171         u8 txrx;
172
173         /* memory mapping of interrupt vectors to static ram */
174
175         //mmap_init(MMAP_RAM);
176         
177         /* pll initialization */
178         pll_init();
179
180         /* uart initialization */
181         uart0_init();
182
183         /* external memory init */
184         BCFG0=0x1000FBEF;               // BCFG2 should be fine as is
185
186         /* begin the main loop */
187         while(1) {
188
189         /* receive cmd */
190         while(1) {
191
192                 cmd=uart0_get_byte();
193                 txrx=1;
194                 switch(cmd) {
195                         case CMD_CHIP_ERASE:
196                                 addrlen=0;
197                                 datalen=1;
198                                 break;
199                         case CMD_READ:
200                                 addrlen=4;
201                                 datalen=4;
202                                 break;
203                         case CMD_CHIP_ID:
204                                 addrlen=0;
205                                 datalen=1;
206                                 break;
207                         default:
208                                 txrx=0;
209                                 break;
210                 }
211
212                 if(txrx)
213                         break;
214         }
215
216         /* receive (only if there is) more data from uart0 */
217         addr=0;
218         for(i=0;i<addrlen;i++) {
219                 txrx=uart0_get_byte();
220                 addr|=(txrx<<((addrlen-i-1)*8));
221         }
222
223         for(i=0;i<datalen;i++)
224                 buf[i]=uart0_get_byte();
225
226         /* process the cmd */
227         switch(cmd) {
228                 case CMD_READ:
229                         /* data length to read */
230                         datalen=buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
231                         /* check addr and datalen */
232                         if((addr>=BANK0)&(addr+datalen<=BANK0+BANK_SIZE))
233                                 uart0_send_buf16((u16 *)addr,datalen);
234                         if((addr>=BANK2)&(addr+datalen<=BANK2+BANK_SIZE))
235                                 uart0_send_buf16((u16 *)addr,datalen);
236                         if((addr>=BOOTLOADER)&(addr+datalen<=BOOTLOADER+BL_SIZE))
237                                 uart0_send_buf32((u32 *)addr,datalen);
238                         break;
239                 case CMD_CHIP_ERASE:
240                         if(buf[0]=='0') {
241                                 B0F555=0xaa;
242                                 B0F2AA=0x55;
243                                 B0F555=0x80;
244                                 B0F555=0xaa;
245                                 B0F2AA=0x55;
246                                 B0F555=0x10;
247                         }
248                         else if(buf[0]=='2') {
249                                 B2F555=0xaa;
250                                 B2F2AA=0x55;
251                                 B2F555=0x80;
252                                 B2F555=0xaa;
253                                 B2F2AA=0x55;
254                                 B2F555=0x10;
255                         }
256                         uart0_send_byte(buf[0]);
257                         break;
258                 case CMD_CHIP_ID:
259                         if(buf[0]=='0') {
260                                 B0F555=0xaa;
261                                 B0F2AA=0x55;
262                                 B0F555=0x90;
263                                 data=*((u16 *)BANK0);
264                                 data=*((u16 *)(BANK0|0x200));
265                         }
266                         else if(buf[0]=='2') {
267                                 B2F555=0xaa;
268                                 B2F2AA=0x55;
269                                 B2F555=0x90;
270                                 data=*((u16 *)BANK2);
271                                 data=*((u16 *)(BANK2|0x200));
272                         }
273                         uart0_send_buf16(&data,2);
274                         break;
275                 default:
276                         break;
277         }
278                 
279         }
280
281         return 0;
282 }
283