OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [apps/] [cfi_ctrl_programmer/] [cfi_ctrl_programmer.c] - Blame information for rev 751

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

Line No. Rev Author Line
1 655 julius
// Program that will erase and program a flash via cfi_ctrl module
2
 
3
#include "cpu-utils.h"
4
#include "board.h"
5
#include "uart.h"
6
#include "printf.h"
7
#include "cfi_ctrl.h"
8
 
9
// TODO: detect this manually - it is CFI after all!
10
#define BLOCK_SIZE_BYTES (128*1024)
11
 
12
//#define VERBOSE_PROGRAMMING
13
#define VERBOSE_VERIFY_ERRORS
14
//#define VERIFY_WHEN_WRITE
15
 
16
unsigned long programming_file_start;
17
unsigned long programming_file_end;
18
unsigned long programming_file_length;
19
 
20
extern unsigned long userprogram_data, _userprogram_data;
21
extern unsigned long end_userprogram_data, _end_userprogram_data;
22
 
23
// Globals
24
int timeout_counter;
25
volatile char dump;
26
int programming_base_offset;
27
 
28
#define RESET_PC 0xf0000100
29
 
30
int
31
console_get_num(void)
32
{
33
  char c = 0x30;
34
  int num_nums = 0;
35
  int num_nums_total;
36
  char nums[16]; // up to 16 decimal digits long
37
  int retval = 0;
38
  int decimal_multiplier;
39
  int i;
40
 
41
  printf("Enter decimal value: ");
42
 
43
  while (c >= 0x30 && c < 0x40)
44
    {
45
      c = uart_getc(DEFAULT_UART);
46
 
47
      if (c >= 0x30 && c < 0x40)
48
        {
49
          printf("%d", c-0x30);
50
          nums[num_nums] = c-0x30;
51
          num_nums++;
52
        }
53
 
54
    }
55
  printf("\n");
56
 
57
  num_nums_total = num_nums;
58
 
59
  while(num_nums--)
60
    {
61
      decimal_multiplier = 1;
62
      for(i=1;i<num_nums_total - num_nums;i++)
63
        decimal_multiplier *= 10;
64
      //printf("%d * %d\n",decimal_multiplier,nums[num_nums]);
65
 
66
      retval += (decimal_multiplier * nums[num_nums]);
67
    }
68
  //printf("%d\n",retval);
69
  return retval;
70
}
71
 
72
void
73
console_browse_buffer(char* buf)
74
{
75
  char c = 0;
76
  int offset = 0;
77
  const int linesize = 16;
78
  int i;
79
  printf("Press space to scroll through buffer, q to return\n");
80
  printf("+/- alter address offset\n");
81
  cfi_ctrl_enable_data_read();
82
  while (1)
83
    {
84
      c = uart_getc(DEFAULT_UART);
85
 
86
      if (c == 'q')
87
        return;
88
      else if (c == 'r')
89
        offset=0;
90
      else if (c == '+')
91
        {
92
          offset+=linesize;
93
          printf("%04x:\r",offset);
94
        }
95
      else if (c == '-')
96
        {
97
          if (offset >=linesize)
98
            offset-=linesize;
99
 
100
          printf("%04x:\r",offset);
101
        }
102
      else if (c == 0x20) // space, print al ine
103
        {
104
          printf("%04x:",offset);
105
          // print another line of the buffer
106
          for (i=0;i<linesize;i++)
107
            {
108
              printf(" %02x", buf[offset+i]&0xff);
109
            }
110
          printf("\n");
111
 
112
          offset += linesize;
113
 
114
        }
115
    }
116
 
117
}
118
 
119
void
120
delay(int n)
121
{
122
  volatile int i=0;
123
  while(i<n)
124
    i++;
125
}
126
 
127
void
128
timeout_reset(void)
129
{
130
  timeout_counter = 0;
131
}
132
 
133
int
134
timeout(void)
135
{
136
  timeout_counter++;
137
  if (timeout_counter == 20000)
138
    {
139
      printf("timeout\n");
140
      cfi_ctrl_reset_flash();
141
 
142
      return 1;
143
    }
144
  return 0;
145
}
146
 
147
void
148
print_cfi_status(void)
149
{
150
  char flashid[5];
151
  int i;
152
  printf("\tcfi_ctrl flash status:\n");
153
 
154
  printf("Device status byte: 0x%02x\n",cfi_ctrl_get_status()&0xff);
155
  printf("\n");
156
  printf("Programming file from 0x%x-0x%x, %d bytes\n",
157
         programming_file_start, programming_file_end,
158
         programming_file_length);
159
  //    printf("Embedded length: %d\n", (unsigned long) userprogram_data);
160
  printf("Page programming base: %d (set with 'o' command)\n",
161
         programming_base_offset);
162
}
163
 
164
void
165
verify_image(int base_offset, char* data, int length_bytes)
166
{
167
 
168
  int base_block = base_offset / BLOCK_SIZE_BYTES;
169
 
170
  int num_blocks = (length_bytes/BLOCK_SIZE_BYTES) + 1;
171
  int i;
172
 
173
  int verify_error = 0;
174
 
175
  printf("\tVerifying %d bytes of image from 0x%08x\n",length_bytes,
176
         base_offset);
177
 
178
  unsigned int waddr;
179
  short * data_shorts;
180
  int short_counter;
181
  data_shorts = (short*) data;
182
 
183
  // Read the pages
184
  cfi_ctrl_enable_data_read();
185
  for(waddr=base_offset, short_counter=0;
186
      waddr<(base_offset + length_bytes);
187
      waddr +=2, short_counter++)
188
    {
189
      /* Check what we wrote */
190
      short verify_data = REG16(CFI_CTRL_BASE+waddr);
191
 
192
      if (verify_data != data_shorts[short_counter])
193
        {
194
          printf("\tERROR: word verify failed at 0x%08x.\n",waddr);
195
          printf("\tERROR: Read 0x%04x instead of 0x%04x.\n",verify_data,
196
                 data_shorts[short_counter]);
197
          verify_error ++;
198
        }
199
 
200
    }
201
 
202
  if (verify_error)
203
    printf("\tVerify complete - %d errors were detected\n",
204
           verify_error);
205
  else
206
    printf("\tImage verified. Press esacpe to boot from 0x%08x.\n",RESET_PC);
207
}
208
 
209
void
210
program_image(int base_offset, char* data, int length_bytes)
211
{
212
 
213
  int base_block = base_offset / BLOCK_SIZE_BYTES;
214
 
215
  int num_blocks = (length_bytes/BLOCK_SIZE_BYTES) + 1;
216
 
217
  int i;
218
 
219
  unsigned int waddr;
220
 
221
  short * data_shorts;
222
  int short_counter;
223
 
224
  printf("\tErasing blocks (%d - %d)\n",base_block,
225
         base_block + num_blocks-1);
226
 
227
  // Erase the appropriate blocks
228
  for(i=base_block;i<base_block + num_blocks;i++)
229
    {
230
      printf("\tErasing block %d\n",i);
231
      cfi_ctrl_unlock_block(i*BLOCK_SIZE_BYTES);
232
      if (cfi_ctrl_erase_block(i*BLOCK_SIZE_BYTES))
233
        {
234
          printf("\tErase failed, trying again\n");
235
          i--; // Try erasing again
236
          continue;
237
        }
238
    }
239
  printf("\tErase complete\n");
240
 
241
  printf("\n\tProgramming %d bytes\n", length_bytes);
242
 
243
  data_shorts = (short*) data;
244
 
245
  // Program the pages
246
  for(waddr=base_offset, short_counter=0;
247
      waddr<(base_offset + length_bytes);
248
      waddr +=2, short_counter++)
249
    {
250
      if (cfi_ctrl_write_short(data_shorts[short_counter],waddr))
251
        {
252
          printf("\tERROR: word program failed at 0x%08x\n",waddr);
253
          return;
254
        }
255
      else
256
        {
257
#ifdef VERIFY_WHEN_WRITE
258
          /* Check what we wrote */
259
          cfi_ctrl_enable_data_read();
260
          short verify_data = REG16(CFI_CTRL_BASE+waddr);
261
          if (verify_data != data_shorts[short_counter])
262
            {
263
              printf("\tERROR: word verify failed at 0x%08x.\n",waddr);
264
              printf("\tERROR: Read 0x%04x instead of 0x%04x.\n",verify_data,
265
                     data_shorts[short_counter]);
266
              return;
267
            }
268
#endif
269
        }
270
    }
271
 
272
  printf("\tProgramming %d bytes complete\n", length_bytes);
273
}
274
 
275
#define printhelp() printf("\nUsage: \n \
276
\t[p]rogram\t\terase req. blocks, write image to flash\n \
277
\t[o]ffset\t\tset page offset to write to\n \
278
\t[v]erify\t\tverify written program\n \
279
\t[s]tatus\t\tprint status of CFI flash\n \
280
\t[e]rase\t\t\terase block of CFI flash\n \
281
\t[r]ead\t\t\tread, browse page of CFI flash\n \
282
\t[i]nspect\t\tinspect page of image in RAM\n \
283
\t[R]eset\t\t\treset CFI flash controller\n \
284
\t[ESC]\t\t\treset by jumping to 0x%08x\n \
285
\n",RESET_PC)
286
 
287
int
288
main()
289
{
290
  uart_init(0); // init the UART before we can printf
291
 
292
  volatile char c;
293
  int i,j;
294
 
295
  programming_base_offset = 0;
296
 
297
  programming_file_start = (unsigned long) &userprogram_data;
298
  programming_file_end = (unsigned long) &end_userprogram_data;
299
  programming_file_length = programming_file_end - programming_file_start;
300
 
301
  printf("\n\n\tcfi_ctrl flash programming app\n\n");
302
  printf("\ttype 'h' for help menu\n\n");
303
 
304
  while(1){
305
    printf(" > ");
306
    c = uart_getc(DEFAULT_UART);
307
    printf("%c",c);
308
    printf("\n");
309
 
310
    if (c == 'h')
311
      printhelp();
312
    else if (c == 's')
313
      print_cfi_status();
314
    else if (c == 'c')
315
      cfi_ctrl_clear_status();
316
    else if (c == 'p')
317
      program_image(programming_base_offset,
318
                    (char *) &userprogram_data,
319
                    programming_file_length);
320
    else if (c == 'v')
321
      verify_image(programming_base_offset,
322
                   (char *) &userprogram_data,
323
                   programming_file_length);
324
    else if (c == 'o')
325
      {
326
        printf("Enter byte offset to program from.\n");
327
        programming_base_offset = console_get_num();
328
      }
329
    // Support/debug commands:
330
    else if (c == 'e')
331
      {
332
        printf("Erase a block.\n");
333
        i = console_get_num();
334
        // program a specific page
335
        cfi_ctrl_erase_block_no_wait(i*BLOCK_SIZE_BYTES);
336
      }
337
    else if (c == 'r')
338
      {
339
        printf("Inspect memory.\n");
340
        i = console_get_num();
341
        // read a page
342
        console_browse_buffer((char*)CFI_CTRL_BASE + i);
343
      }
344
    else if (c == 'i')
345
      {
346
        printf("Inspect image to program.\n");
347
        console_browse_buffer((char*) &userprogram_data);
348
      }
349
    else if (c == 'R')
350
      {
351
        printf("Reset command to controller\n");
352
        cfi_ctrl_reset_flash();
353
      }
354
    else if (c == 0x1b) // Esacpe key
355
      {
356
        // Reset
357
        void (*reset_function) (void) =
358
          (void *)RESET_PC;
359
        (*reset_function)();
360
      }
361
 
362
  }
363
 
364
  return 0;
365
 
366
}

powered by: WebSVN 2.1.0

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