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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [apps/] [spiflash/] [spiflash-program.c] - Blame information for rev 397

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

Line No. Rev Author Line
1 349 julius
// Program that will erase and program an SPI flash
2
 
3
#include "or32-utils.h"
4
#include "spr-defs.h"
5
#include "board.h"
6
#include "uart.h"
7
#include "simple-spi.h"
8
#include "printf.h"
9
 
10
 
11
unsigned long programming_file_start;
12
unsigned long programming_file_end;
13
unsigned long programming_file_length;
14
int spi_master;
15
char slave;
16
 
17
 
18
 
19
// Little program to dump the contents of the SPI flash memory it's connected 
20
// to on the board
21
 
22
void
23
spi_write_ignore_read(int core, char dat)
24
{
25
  spi_core_write_data(core,dat);
26
  while (!(spi_core_data_avail(core))); // Wait for the transaction (should 
27
                                        // generate a byte)
28
  spi_core_read_data(core);
29
}
30
 
31
char
32
spi_read_ignore_write(int core)
33
{
34
  spi_core_write_data(core, 0x00);
35
  while (!(spi_core_data_avail(core))); // Wait for the transaction (should 
36
                                        // generate a byte)
37
  return spi_core_read_data(core);
38
}
39
 
40
 
41
unsigned long
42
spi_read_id(int core, char slave_sel)
43
{
44
  unsigned long rdid;
45
  char* rdid_ptr = (char*) &rdid;
46
  int i;
47
  spi_core_slave_select(core, slave_sel); // Select slave
48
  rdid_ptr[3] = 0;
49
  // Send the RDID command
50
  spi_write_ignore_read(core,0x9f); // 0x9f is READ ID command
51
  // Now we read the next 3 bytes
52
  for(i=0;i<3;i++)
53
    {
54
      rdid_ptr[i] = spi_read_ignore_write(core);
55
    }
56
  spi_core_slave_select(core, 0); // Deselect slave
57
  return rdid;
58
}
59
 
60
// Read status regsiter
61
char
62
spi_read_sr(int core, char slave_sel)
63
{
64
  char rdsr;
65
  spi_core_slave_select(core, slave_sel); // Select slave
66
  // Send the RDSR command
67
  spi_write_ignore_read(core,0x05); // 0x05 is READ status register command
68
  rdsr = spi_read_ignore_write(core);
69
  spi_core_slave_select(core, 0); // Deselect slave  
70
  return rdsr;
71
}
72
 
73
 
74
void
75
spi_read_block(int core, char slave_sel, unsigned int addr, int num_bytes,
76
               char* buf)
77
{
78
  int i;
79
  spi_core_slave_select(core, slave_sel); // Select slave
80
  spi_write_ignore_read(core, 0x3); // READ command
81
  spi_write_ignore_read(core,((addr >> 16) & 0xff)); // addres high byte
82
  spi_write_ignore_read(core,((addr >> 8) & 0xff)); // addres middle byte
83
  spi_write_ignore_read(core,((addr >> 0) & 0xff)); // addres low byte
84
  for(i=0;i<num_bytes;i++)
85
    buf[i] = spi_read_ignore_write(core);
86
 
87
  spi_core_slave_select(core, 0); // Deselect slave  
88
}
89
 
90
 
91
void
92
spi_set_write_enable(int core, char slave_sel)
93
{
94
  spi_core_slave_select(core, slave_sel); // Select slave
95
  spi_write_ignore_read(core,0x06); // 0x06 is to set write enable
96
  spi_core_slave_select(core, 0); // Deselect slave  
97
}
98
 
99
 
100
// Write up to 256 bytes of data to a page, always from offset 0
101
void
102
spi_page_program(int core, char slave_sel, short page_num, int num_bytes,
103
                 char* buf)
104
{
105
 
106
  // Set WE latch
107
  spi_set_write_enable(core, slave_sel);
108
  while(!(spi_read_sr(core, slave_sel) & 0x2)); // Check it's set
109
 
110
  int i;
111
  if (!(num_bytes > 0)) return;
112
  if (num_bytes > 256) return;
113
  spi_core_slave_select(core, slave_sel); // Select slave
114
  spi_write_ignore_read(core, 0x2); // Page program command
115
  spi_write_ignore_read(core,((page_num >> 8) & 0xff)); // addres high byte
116
  spi_write_ignore_read(core,((page_num >> 0) & 0xff)); // addres middle byte
117
  spi_write_ignore_read(core,0); // addres low byte
118
  for(i=0;i<num_bytes;i++)
119
    spi_write_ignore_read(core, buf[i]);
120
  spi_core_slave_select(core, 0); // Deselect slave  
121
 
122
 // Now poll status reg for WIP bit
123
  while((spi_read_sr(core, slave_sel) & 0x1));
124
}
125
 
126
 
127
// Erase a sector - assumes 128KByte memory, so 4 sectors of 32KBytes each
128
void
129
spi_sector_erase(int core, char slave_sel, unsigned int sector)
130
{
131
  // Set WE latch
132
  spi_set_write_enable(core, slave_sel);
133
  while(!(spi_read_sr(core, slave_sel) & 0x2)); // Check it's set
134
 
135
  spi_core_slave_select(core, slave_sel); // Select slave
136
  spi_write_ignore_read(core, 0xd8); // Sector erase command
137
  spi_write_ignore_read(core,(sector>>1)&0x1); // sector select high bit (bit 
138
                                               // 16 of addr)
139
  spi_write_ignore_read(core,(sector&0x1)<<7); // sector select low bit (bit 15
140
                                               // of addr)
141
  spi_write_ignore_read(core,0); // addres low byte  
142
  spi_core_slave_select(core, 0); // Deselect slave  
143
 
144
  // Now poll status reg for WIP bit
145
  while((spi_read_sr(core, slave_sel) & 0x1));
146
 
147
}
148
 
149
// Erase entire device
150
void
151
spi_bulk_erase(int core, char slave_sel)
152
{
153
 // Set WE latch
154
  spi_set_write_enable(core, slave_sel);
155
  while(!(spi_read_sr(core, slave_sel) & 0x2)); // Check it's set
156
 
157
  spi_core_slave_select(core, slave_sel); // Select slave
158
  spi_write_ignore_read(core, 0xc7); // Bulk erase
159
  spi_core_slave_select(core, 0); // Deselect slave  
160
 
161
 // Now poll status reg for WIP bit
162
  while((spi_read_sr(core, slave_sel) & 0x1));
163
}
164
 
165
extern unsigned long spiprogram_data, _spiprogram_data;
166
extern unsigned long end_spiprogram_data, _end_spiprogram_data;
167
 
168
#define printhelp() printf("\nUsage: \n\t[p]rogram\t\twrite program to flash\n\t[v]erify\t\tveryify written program\n\t[s]tatus\t\tprint status of SPI flash\n\n")
169
 
170
void
171
print_spi_status(void)
172
{
173
 
174
  printf("SPI core: %d\n",spi_master);
175
  printf("SPI slave select: 0x%x\n",slave&0xff);
176
 
177
  printf("SPI slave info:\n");
178
  printf("\tID:\t%x\n", spi_read_id(spi_master, slave));
179
  printf("\tSR:\t%x\n", spi_read_sr(spi_master, slave));
180
  printf("\n");
181
  printf("Programming file from 0x%x-0x%x, %d bytes\n",programming_file_start,
182
         programming_file_end,
183
         programming_file_length);
184
  printf("Embedded length: %d\n", (unsigned long) spiprogram_data);
185
}
186
 
187
 
188
// Verify contents of SPI flash
189
void
190
verify_spi(int core, char slave_sel, char * data, unsigned int length)
191
{
192
  unsigned int i;
193
  unsigned int page_num = 0;
194
  unsigned int bytes_this_page;
195
  char verify_buf[256];
196
  int verify_error = 0;
197
  printf("* Verifying contents of SPI flash.\n");
198
  while(length)
199
    {
200
      bytes_this_page = (length >= 256) ? 256 : length;
201
      spi_read_block(spi_master, slave, (page_num<<8), bytes_this_page,
202
                     verify_buf);
203
      for(i=0;i<bytes_this_page;i++)
204
        {
205
          if (verify_buf[i] != data[i])
206
            {
207
              printf("* Verify error! Byte %d of page %d - was 0x%x, expected 0x%x\n", i, page_num, verify_buf[i] & 0xff, data[i] & 0xff);
208
              verify_error=1;
209
            }
210
        }
211
      data +=256;
212
      length -= (length >= 256) ? 256 : length;
213
      page_num++;
214
    }
215
  if (verify_error)
216
    printf("* SPI flash verify NOT OK\n");
217
  else
218
    printf("* SPI flash verify OK\n");
219
 
220
}
221
 
222
// Function to fully erase and program SPI flash
223
void
224
program_spi(int core, char slave_sel, char * data, unsigned int length)
225
{
226
  char *program_data_ptr = data;
227
  unsigned int program_data_length = length;
228
  unsigned int i;
229
  unsigned int page_num = 0;
230
  unsigned int bytes_this_page;
231
  printf("* Erasing SPI flash\n");
232
  spi_bulk_erase(core,slave_sel);
233
  printf("* SPI flash erased\n");
234
  while(length)
235
    {
236
      bytes_this_page = (length >= 256) ? 256 : length;
237
      printf("* SPI page %d being programmed with %d bytes", page_num, bytes_this_page);
238
      spi_page_program(core, slave_sel, page_num, bytes_this_page, data);
239
      printf("\n");
240
      data +=256;
241
      length -= (length >= 256) ? 256 : length;
242
      page_num++;
243
    }
244
  printf("* SPI flash programmed\n");
245
 
246
  verify_spi(core,slave_sel,program_data_ptr,program_data_length);
247
 
248
}
249
 
250
 
251
int
252
main()
253
{
254
 
255
  uart_init(0); // init the UART before we can printf
256
 
257
  volatile char c;
258
  int i,j;
259
  spi_master = 0;
260
  slave = 1;
261
 
262
  spi_core_slave_select(spi_master, 0); // Deselect slaves
263
 
264
  // Clear the read FIFO
265
  while (spi_core_data_avail(spi_master))
266
    c = spi_core_read_data(spi_master);
267
 
268
  programming_file_start = (unsigned long) &spiprogram_data;
269
  programming_file_end = (unsigned long) &end_spiprogram_data;
270
  programming_file_length = programming_file_end - programming_file_start;
271
 
272
  // SPI core 0, should already be configured to read out data
273
  // when we reset.
274
 
275
  printf("\n\n\tSPI flash programming app\n\n");
276
 
277
  while(1){
278
    printf("[p,v,s,h] > ");
279
    c = uart_getc(DEFAULT_UART);
280
    printf("%c",c);
281
    printf("\n");
282
 
283
    if (c == 'h')
284
      printhelp();
285
    else if (c == 's')
286
      print_spi_status();
287
    else if (c == 'p')
288
      program_spi(spi_master, slave, (char *) &spiprogram_data, programming_file_length);
289
    else if (c == 'v')
290
      verify_spi(spi_master, slave, (char *) &spiprogram_data, programming_file_length);
291
 
292
 
293
  }
294
 
295
  return 0;
296
 
297
}

powered by: WebSVN 2.1.0

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