OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

[/] [hf-risc/] [trunk/] [software/] [boot/] [monitor.c] - Blame information for rev 19

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 serginhofr
#include <hf-risc.h>
2
 
3
/* memory mapped I/O access */
4
#define MemoryRead(A)                   (*(volatile unsigned int*)(A))
5
#define MemoryWrite(A,V)                *(volatile unsigned int*)(A)=(V)
6
 
7
/* SPI interface - EXTIO_OUT pins 0 (chip select), 1 (clock), 2 (master output) and 3 (chip select 2) */
8
#define SPI_CS          0x01
9
#define SPI_SCK         0x02
10
#define SPI_MOSI        0x04
11
#define SPI_CS2         0x08
12
 
13
/* SPI interface - EXIO_IN pin 3 (master input) */
14
#define SPI_MISO        0x08
15
 
16
/* EEPROM config / commands */
17
#define PAGE_SIZE       64
18
#define CMD_READ        0x03
19
#define CMD_WRITE       0x02
20
#define CMD_WREN        0x06
21
 
22
/*
23
monitor auxiliry routines
24
*/
25
 
26
uint32_t getnum(void){
27
        int32_t i;
28
        uint32_t ch, ch2, value=0;
29
 
30
        for(i = 0; i < 16; ){
31
                ch = ch2 = getchar();
32
                if(ch == '\n' || ch == '\r')
33
                        break;
34
                if('0' <= ch && ch <= '9')
35
                        ch -= '0';
36
                else if('A' <= ch && ch <= 'Z')
37
                        ch = ch - 'A' + 10;
38
                else if('a' <= ch && ch <= 'z')
39
                        ch = ch - 'a' + 10;
40
                else if(ch == 8){
41
                        if(i > 0){
42
                                --i;
43
                                putchar(ch);
44
                                putchar(' ');
45
                                putchar(ch);
46
                        }
47
                        value >>= 4;
48
                        continue;
49
                }
50
                putchar(ch2);
51
                value = (value << 4) + ch;
52
                ++i;
53
        }
54
        return value;
55
}
56
 
57
void printnum(uint32_t n){
58
        int8_t buf[30];
59
        uint16_t i;
60
 
61
        itoa(n, buf, 10);
62
        i = 0;
63
        while (buf[i]) putchar(buf[i++]);
64
}
65
 
66
void printhex(uint32_t n){
67
        int8_t buf[30];
68
        uint16_t i;
69
 
70
        if (n < 16) putchar('0');
71
        itoa(n, buf, 16);
72
        i = 0;
73
        while (buf[i]) putchar(buf[i++]);
74
}
75
 
76
int32_t printstr(const int8_t *str){
77
        while(*str)
78
                putchar(*str++);
79
 
80
        return 0;
81
}
82
 
83
/*
84
SPI low level interface driver, mode 0
85
*/
86
 
87
void spi_setup(void){
88
        EXTIO_OUT |= SPI_CS | SPI_CS2;
89
        EXTIO_OUT &= ~SPI_SCK;
90
}
91
 
92
void spi_start(void){
93
        EXTIO_OUT &= ~SPI_CS2;
94
}
95
 
96
void spi_stop(void){
97
        EXTIO_OUT |= SPI_CS2;
98
}
99
 
100
int8_t spi_sendrecv(int8_t data){
101
        int32_t i;
102
        int8_t newdata = 0;
103
 
104
        for (i = 0; i < 8; i++){
105
                if (data & 0x80){
106
                        EXTIO_OUT |= SPI_MOSI;
107
                }else{
108
                        EXTIO_OUT &= ~SPI_MOSI;
109
                }
110
                data <<= 1;
111
                EXTIO_OUT |= SPI_SCK;
112
                newdata <<= 1;
113
                newdata |= ((EXTIO_IN & SPI_MISO) ? 1 : 0);
114
                EXTIO_OUT &= ~SPI_SCK;
115
        }
116
        return newdata;
117
}
118
 
119
/*
120
SPI EEPROM driver
121
EEPROM should be a 25lc128 (16KB) or 25lc256 (32KB) compatible chip!
122
if you need a different ROM size / configuration, change PAGE_SIZE accordingly.
123
*/
124
 
125
uint8_t spi_eeprom_readbyte(uint16_t addr){
126
        uint8_t data;
127
 
128
        spi_start();
129
        spi_sendrecv(CMD_READ);
130
        spi_sendrecv(addr >> 8);
131
        spi_sendrecv(addr & 0xff);
132
        data = spi_sendrecv(0);
133
        spi_stop();
134
 
135
        return data;
136
}
137
 
138
void spi_eeprom_read(uint16_t addr, uint8_t *buf, uint16_t size){
139
        uint8_t data;
140
        uint16_t i;
141
 
142
        spi_start();
143
        spi_sendrecv(CMD_READ);
144
        spi_sendrecv(addr >> 8);
145
        spi_sendrecv(addr & 0xff);
146
        for(i = 0; i < size; i++)
147
                buf[i] = spi_sendrecv(0);
148
        spi_stop();
149
}
150
 
151
void spi_eeprom_writepage(uint16_t page, uint8_t *data){
152
        uint16_t i;
153
 
154
        spi_start();
155
        spi_sendrecv(CMD_WREN);
156
        spi_stop();
157
        spi_start();
158
        spi_sendrecv(CMD_WRITE);
159
        spi_sendrecv((page * PAGE_SIZE) >> 8);
160
        spi_sendrecv((page * PAGE_SIZE) & 0xff);
161
        for (i = 0; i < PAGE_SIZE; i++)
162
                spi_sendrecv(data[i]);
163
        spi_stop();
164
        delay_ms(10);
165
}
166
 
167
void boot_spi(void){
168
        uint32_t signature, size;
169
        uint8_t *ptr1;
170
        funcptr funcPtr;
171
/*
172
        -initialize SPI, mode 0;
173
        -try to read a 4 byte signature (0xb16b00b5). on fail (no eeprom, no valid data or no jumper) return to monitor;
174
        -read image size on next 4 bytes (e.g: 2350 bytes will be 0x0000092e;
175
        -copy ROM data to RAM, starting at 0x40000000
176
        -jump to 0x40000000
177
*/
178
        spi_setup();
179
        signature = (spi_eeprom_readbyte(0) << 24) | (spi_eeprom_readbyte(1) << 16) | (spi_eeprom_readbyte(2) << 8) | spi_eeprom_readbyte(3);
180
        if (signature != 0xb16b00b5) return;
181
        size = (spi_eeprom_readbyte(4) << 24) | (spi_eeprom_readbyte(5) << 16) | (spi_eeprom_readbyte(6) << 8) | spi_eeprom_readbyte(7);
182
        ptr1 = (uint8_t *)ADDR_RAM_BASE;
183
        // skip header and copy EEPROM data to RAM
184
        spi_eeprom_read(8, ptr1, size);
185
        funcPtr = (funcptr)ADDR_RAM_BASE;
186
        funcPtr((void *)0);
187
}
188
 
189
/*
190
monitor main program.
191
we are using the last portion of SRAM as the program stack!
192
*/
193
 
194
int32_t main(void){
195
        int32_t i, j, k, l, ch;
196
        uint32_t addr, addr2, value, size = 0;
197
        funcptr funcPtr;
198
        uint32_t *ptr;
199
        uint8_t *ptr1;
200
        uint8_t eeprom_page[PAGE_SIZE];
201
 
202
        uart_init(57600);
203
 
204
        boot_spi();
205
 
206
        printstr("\nHF-RISC bootloader - ");
207
        printstr(__DATE__);
208
        printstr("\n");
209
 
210
        for(;;){
211
                printstr("\n[u, U] upload binary");
212
                printstr("\n[b, B] boot ");
213
                printstr("\n[p   ] program EEPROM");
214
                printstr("\n[d   ] mem dump");
215
                printstr("\n[f   ] mem fill");
216
                printstr("\n[w   ] write data");
217
                printstr("\n");
218
                ch = getchar();
219
                getchar();
220
 
221
                switch(ch){
222
                        case 'u':
223
                                ptr1 = (uint8_t *)ADDR_RAM_BASE;
224
                                goto waiting;
225
                        case 'U':
226
                                printstr("\naddress (hex):");
227
                                addr = getnum();
228
                                ptr1 = (uint8_t *)addr;
229
                        waiting:
230
                                printstr("\nwaiting for binary...");
231
                                ch = getchar();
232
                                for(i = 0; ; i++){
233
                                        ptr1[i] = (uint8_t)ch;
234
                                        for(j = 0; j < (CPU_SPEED / 100); j++){
235
                                                if(kbhit()){
236
                                                        ch = getchar();
237
                                                        break;
238
                                                }
239
                                        }
240
                                        if (j >= (CPU_SPEED / 100)) break;
241
                                        if ((i % 1024) == 0) putchar('*');
242
                                }
243
                                i++;
244
                                printstr("--> ");
245
                                printnum(i);
246
                                printstr(" bytes");
247
                                size = i;
248
                                break;
249
                        case 'b':
250
                                funcPtr = (funcptr)ADDR_RAM_BASE;
251
                                goto booting;
252
                        case 'B':
253
                                printstr("\naddress (hex):");
254
                                addr = getnum();
255
                                funcPtr = (funcptr)addr;
256
                        booting:
257
                                printstr("\nboot\n");
258
                                funcPtr((void *)0);
259
                                break;
260
                        case 'p':
261
                                if (!size) break;
262
                                ptr1 = (uint8_t *)ADDR_RAM_BASE;
263
                                printstr("\nprogramming "); printnum(size); printstr(" bytes");
264
                                // signature
265
                                eeprom_page[0] = 0xb1; eeprom_page[1] = 0x6b; eeprom_page[2] = 0x00; eeprom_page[3] = 0xb5;
266
                                // image size
267
                                eeprom_page[4] = (size >> 24) & 0xff;
268
                                eeprom_page[5] = (size >> 16) & 0xff;
269
                                eeprom_page[6] = (size >> 8) & 0xff;
270
                                eeprom_page[7] = size & 0xff;
271
 
272
                                // first page
273
                                i = 0; k = 0;
274
                                for (j = 8; j < PAGE_SIZE; j++){
275
                                        if (i < size){
276
                                                eeprom_page[j] = ptr1[i++];
277
                                        }else{
278
                                                eeprom_page[j] = 0x00;
279
                                        }
280
                                }
281
                                spi_eeprom_writepage(k, eeprom_page);
282
                                // next pages
283
                                while(i < size){
284
                                        k++;
285
                                        for (j = 0; j < PAGE_SIZE; j++){
286
                                                if (i < size){
287
                                                        eeprom_page[j] = ptr1[i++];
288
                                                }else{
289
                                                        eeprom_page[j] = 0x00;
290
                                                }
291
                                        }
292
                                        spi_eeprom_writepage(k, eeprom_page);
293
                                }
294
                                break;
295
                        case 'd':
296
                                printstr("\naddress (hex):");
297
                                addr = getnum();
298
                                ptr1 = (uint8_t *)addr;
299
                                printstr("\nlength (hex):");
300
                                i = getnum();
301
                                for(k = 0; k < i; k += 16){
302
                                        printstr("\n");
303
                                        printhex(addr + k);
304
                                        printstr("  ");
305
                                        for(l = 0; l < 16; l++){
306
                                                printhex(ptr1[k+l]);
307
                                                printstr(" ");
308
                                                if (l == 7) printstr(" ");
309
                                        }
310
                                        printstr(" |");
311
                                        for(l = 0; l < 16; l++){
312
                                                ch = ptr1[k+l];
313
                                                if ((ch >= 32) && (ch <= 126))
314
                                                        putchar((uint8_t)ch);
315
                                                else
316
                                                        printstr(".");
317
                                        }
318
                                        printstr("|");
319
                                }
320
                                break;
321
                        case 'f':
322
                                printstr("\naddress (hex):");
323
                                addr = getnum();
324
                                ptr1 = (uint8_t *)addr;
325
                                printstr("\nlength (hex):");
326
                                i = getnum();
327
                                printstr("\nbyte (hex):");
328
                                ch = (uint8_t)getnum();
329
                                for (l = 0; l < i; l++)
330
                                        ptr1[l] = ch;
331
                                break;
332
                        case 'w':
333
                                printstr("\naddress (hex):");
334
                                addr = getnum();
335
                                printstr("\ndata (hex):");
336
                                value = getnum();
337
                                MemoryWrite(addr, value);
338
                                break;
339
                        default:
340
                                break;
341
                }
342
        }
343
 
344
        return 0;
345
}
346
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.