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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [flash/] [sst/] [39vf400/] [current/] [include/] [flash_sst_39vf400.inl] - Blame information for rev 838

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

Line No. Rev Author Line
1 786 skrzyp
#ifndef CYGONCE_DEVS_FLASH_SST_39VF400_INL
2
#define CYGONCE_DEVS_FLASH_SST_39VF400_INL
3
//==========================================================================
4
//
5
//      flash_sst_39vf4000.inl
6
//
7
//      SST SST39VF400 FLASH driver
8
//
9
//==========================================================================
10
// ####ECOSGPLCOPYRIGHTBEGIN####
11
// -------------------------------------------
12
// This file is part of eCos, the Embedded Configurable Operating System.
13
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
14
//
15
// eCos is free software; you can redistribute it and/or modify it under
16
// the terms of the GNU General Public License as published by the Free
17
// Software Foundation; either version 2 or (at your option) any later
18
// version.
19
//
20
// eCos is distributed in the hope that it will be useful, but WITHOUT
21
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23
// for more details.
24
//
25
// You should have received a copy of the GNU General Public License
26
// along with eCos; if not, write to the Free Software Foundation, Inc.,
27
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
28
//
29
// As a special exception, if other files instantiate templates or use
30
// macros or inline functions from this file, or you compile this file
31
// and link it with other works to produce a work based on this file,
32
// this file does not by itself cause the resulting work to be covered by
33
// the GNU General Public License. However the source code for this file
34
// must still be made available in accordance with section (3) of the GNU
35
// General Public License v2.
36
//
37
// This exception does not invalidate any other reasons why a work based
38
// on this file might be covered by the GNU General Public License.
39
// -------------------------------------------
40
// ####ECOSGPLCOPYRIGHTEND####
41
//==========================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):    Chris Garry 
45
// Contributors:
46
// Date:         2003-04-21
47
// Purpose:
48
// Description:  SST SST39VF400 flash driver
49
//
50
//####DESCRIPTIONEND####
51
//
52
//==========================================================================
53
 
54
#include 
55
#include 
56
#include 
57
#include 
58
#include  /* HAL_DELAY_US */
59
#include    /* Required for diag_printf */
60
#include CYGHWR_MEMORY_LAYOUT_H
61
 
62
#define  _FLASH_PRIVATE_
63
#include 
64
 
65
//----------------------------------------------------------------------------
66
// Platform code must define the below
67
// #define CYGNUM_FLASH_INTERLEAVE      : Number of interleaved devices (in parallel)
68
// #define CYGNUM_FLASH_SERIES          : Number of devices in series
69
// #define CYGNUM_FLASH_BASE            : Base address of the FLASH
70
//
71
// Note:
72
// Currently the driver only supports CYGNUM_FLASH_INTERLEAVE = 1 and
73
// CYGNUM_FLASH_SERIES = 1
74
 
75
 
76
// Definitions for the SST 39VF400A part
77
#define SST_ID                    0x00BF          /* SST Manufacturer's ID code   */
78
#define SST_39VF400A              0x2780          /* SST39VF400/SST39VF400A device code */
79
#define CYGNUM_FLASH_SECTOR_SIZE (0x1000)         /* Size of physical sectors */
80
#define CYGNUM_FLASH_BLOCK_SIZE  (0x1000)         /* Driver 'blocks' may be a multiple of physical sectors */
81
#define CYGNUM_FLASH_BLOCK_NUM   (0x80000/CYGNUM_FLASH_BLOCK_SIZE) /* Number of blocks */
82
#define CYGNUM_FLASH_WIDTH       (16)             /* This part is always 16 bits wide */
83
#define CYGNUM_FLASH_BLANK       (1)
84
 
85
 
86
#ifndef FLASH_P2V
87
# define FLASH_P2V( _a_ ) ((volatile flash_data_t *)((CYG_ADDRWORD)(_a_)))
88
#endif
89
#ifndef CYGHWR_FLASH_AM29XXXXX_PLF_INIT
90
# define CYGHWR_FLASH_AM29XXXXX_PLF_INIT()
91
#endif
92
 
93
// Structure to hold device ID
94
typedef struct
95
{
96
    cyg_uint16 man_id;
97
    cyg_uint16 dev_id;
98
} device_id_t;
99
 
100
// FLASH registers
101
volatile cyg_uint16 *flash_data_add0 = (cyg_uint16 *)(CYGNUM_FLASH_BASE);
102
volatile cyg_uint16 *flash_data_add1 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x0001 << 1));
103
volatile cyg_uint16 *flash_cmd_add1 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
104
volatile cyg_uint16 *flash_cmd_add2 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x2AAA << 1));
105
volatile cyg_uint16 *flash_cmd_add3 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
106
volatile cyg_uint16 *flash_cmd_add4 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x5555 << 1));
107
volatile cyg_uint16 *flash_cmd_add5 = (cyg_uint16 *)(CYGNUM_FLASH_BASE + (0x2AAA << 1));
108
 
109
 
110
//----------------------------------------------------------------------------
111
// Now that device properties are defined, include magic for defining
112
// accessor type and constants.
113
#include 
114
 
115
//----------------------------------------------------------------------------
116
// Functions that put the flash device into non-read mode must reside
117
// in RAM.
118
static device_id_t get_device_id(void) __attribute__ ((section (".2ram.get_device_id")));
119
int  flash_erase_block(void* block, unsigned int size)
120
    __attribute__ ((section (".2ram.flash_erase_block")));
121
int  flash_program_buf(void* addr, void* data, int len)
122
    __attribute__ ((section (".2ram.flash_program_buf")));
123
 
124
//----------------------------------------------------------------------------
125
// Get Device ID
126
//
127
// Reads the manufacturer and part number codes for the device
128
//
129
static device_id_t get_device_id(void)
130
{
131
    device_id_t device_id;
132
    int i;
133
 
134
    /*  Issue the Software ID command */
135
    *flash_cmd_add1 = 0xAAAA;
136
    *flash_cmd_add2 = 0x5555;
137
    *flash_cmd_add3 = 0x9090;
138
 
139
    /* Tida delay time, Tida = 150 ns */
140
    /* Can use any function that is in ROM */
141
    for (i = 0; i < 100; i++)
142
    {
143
        /* Do nothing */
144
    }
145
 
146
    /* Read the product ID */
147
    device_id.man_id = *flash_data_add0 & 0xFF;
148
    device_id.dev_id = *flash_data_add1;
149
 
150
    /* Issue the Software ID EXIT command */
151
    *flash_data_add0 = 0xF0F0;
152
 
153
    /* Tida delay time, Tida = 150 ns */
154
    /* Can use any function that is in ROM */
155
    for (i = 0; i < 100; i++)
156
    {
157
        /* Do nothing */
158
    }
159
 
160
    return(device_id);
161
}
162
 
163
 
164
//----------------------------------------------------------------------------
165
// Initialize driver details
166
//
167
int flash_hwr_init(void)
168
{
169
    device_id_t device_id;
170
 
171
    /* Call the function to get the device ID */
172
    device_id = get_device_id();
173
 
174
    /* Determine whether there is a SST39VF400A installed or not */
175
    if ((device_id.man_id != SST_ID) || (device_id.dev_id != SST_39VF400A))
176
    {
177
        return FLASH_ERR_DRV_WRONG_PART;
178
    }
179
 
180
    // Hard wired for now
181
    flash_info.block_size = CYGNUM_FLASH_BLOCK_SIZE;
182
    flash_info.blocks = CYGNUM_FLASH_BLOCK_NUM;
183
    flash_info.start = (void *)CYGNUM_FLASH_BASE;
184
    flash_info.end = (void *)(CYGNUM_FLASH_BASE + (flash_info.block_size * flash_info.blocks));
185
 
186
    return FLASH_ERR_OK;
187
}
188
 
189
//----------------------------------------------------------------------------
190
// Map a hardware status to a package error
191
int flash_hwr_map_error(int e)
192
{
193
    return e;
194
}
195
 
196
 
197
//----------------------------------------------------------------------------
198
// See if a range of FLASH addresses overlaps currently running code
199
bool flash_code_overlaps(void *start, void *end)
200
{
201
    extern unsigned char _stext[], _etext[];
202
 
203
    return ((((unsigned long)&_stext >= (unsigned long)start) &&
204
             ((unsigned long)&_stext < (unsigned long)end)) ||
205
            (((unsigned long)&_etext >= (unsigned long)start) &&
206
             ((unsigned long)&_etext < (unsigned long)end)));
207
}
208
 
209
//----------------------------------------------------------------------------
210
// Erase Block
211
// This function actually uses the sector erase command instead of the block
212
// erase command. this allows for the effective block size to be smaller
213
// than 64K (as small as the 4K sector size)
214
int flash_erase_block(void* block, unsigned int size)
215
{
216
 
217
    volatile cyg_uint16 *block_addr;
218
    volatile cyg_uint16 *verify_addr;
219
    int verify_failed;
220
    cyg_uint32 i, timeout;
221
    int j;
222
    int retry;
223
 
224
    block_addr = block;
225
 
226
    for (j = 0; j < (size / CYGNUM_FLASH_SECTOR_SIZE); j++)
227
    {
228
        retry = 0;
229
        while (retry < 16)
230
        {
231
            /* Issue the Sector-Erase command */
232
            *flash_cmd_add1 = 0xAAAA;
233
            *flash_cmd_add2 = 0x5555;
234
            *flash_cmd_add3 = 0x8080;
235
            *flash_cmd_add4 = 0xAAAA;
236
            *flash_cmd_add5 = 0x5555;
237
            *block_addr = 0x3030;  /* Sector Erase command */
238
 
239
            /* Wait for the Erase operation to complete */
240
            /* With a timeout to stop the board locking up with a H/W error*/
241
            timeout = 0;
242
            i = 0;
243
            while (i < 5)
244
            {
245
                if (*block_addr == 0xFFFF)
246
                {
247
                    i++;
248
                }
249
                else
250
                {
251
                    i = 0;
252
                }
253
 
254
                if (++timeout > 0x01000000)
255
                {
256
                    /* Timeout - return with ERROR status */
257
                    return (FLASH_ERR_DRV_TIMEOUT);
258
                }
259
            }
260
 
261
            /* Verify this sector has been erased */
262
            verify_addr = block_addr;
263
            verify_failed = 0;
264
            while ((cyg_uint32)(verify_addr) < ((cyg_uint32)block_addr + (cyg_uint32)CYGNUM_FLASH_SECTOR_SIZE))
265
            {
266
                if (*verify_addr != 0xFFFF)
267
                {
268
                    /* Error verifying segment data */
269
                    retry++;
270
                    verify_failed = 1;
271
                    break;
272
                }
273
                ++verify_addr;
274
            }
275
 
276
            if (verify_failed == 0)
277
            {
278
                /* Sector erase verified */
279
                break;
280
            }
281
        }
282
 
283
        /* Increment the block address by 1 sector */
284
        (cyg_uint32)block_addr += CYGNUM_FLASH_SECTOR_SIZE;
285
    }
286
 
287
    /* Verify the entire block has been set to all 0xFFFFs */
288
    block_addr = block;
289
    while ((cyg_uint32)(block_addr) < ((cyg_uint32)block + (cyg_uint32)size))
290
    {
291
        if (*block_addr != 0xFFFF)
292
        {
293
            /* Error verifying data */
294
            return (FLASH_ERR_DRV_VERIFY);
295
        }
296
 
297
        ++block_addr;
298
    }
299
 
300
    return (FLASH_ERR_OK);
301
}
302
 
303
 
304
//----------------------------------------------------------------------------
305
// Program Buffer
306
int
307
flash_program_buf(void* addr, void* data, int len)
308
{
309
    volatile cyg_uint16 *write_ptr;
310
    volatile cyg_uint16 *data_ptr;
311
    int i;
312
    cyg_uint32 timeout;
313
    cyg_uint16 read_data1, read_data2;
314
 
315
    write_ptr = addr;  /* Initialise local pointers */
316
    data_ptr = data;
317
 
318
    /* Loop for writing the data */
319
    while ((cyg_uint32)write_ptr < ((cyg_uint32)addr + (cyg_uint32)len))
320
    {
321
        /* Write word of data to FLASH */
322
        /* Issue the Word-Program command */
323
        *flash_cmd_add1 = 0xAAAA;
324
        *flash_cmd_add2 = 0x5555;
325
        *flash_cmd_add3 = 0xA0A0;
326
        /* Write data word to FLASH */
327
        *write_ptr = *data_ptr;
328
 
329
        /* Wait for the operation to complete */
330
        /* Wait for the Erase operation to complete */
331
        /* With a timeout to stop the board locking up with a H/W error*/
332
        timeout = 0;
333
        i = 0;
334
        while (i < 5)
335
        {
336
            read_data1 = *write_ptr;
337
            read_data2 = *write_ptr;
338
            if (read_data1 == read_data2)
339
            {
340
                /* Bit 6 can no longer be toggling */
341
                i++;
342
            }
343
            else
344
            {
345
                i = 0;
346
            }
347
 
348
            if (++timeout > 0x01000000)
349
            {
350
                /* Timeout - return with ERROR status */
351
                return (FLASH_ERR_DRV_TIMEOUT);
352
            }
353
        }
354
 
355
        /* Increment pointers to next words */
356
        ++write_ptr;
357
        ++data_ptr;
358
    }
359
 
360
    /* Data write complete - verify the data */
361
    write_ptr = addr;  /* Re-initialise local pointers */
362
    data_ptr = data;
363
 
364
    /* Loop for verifying the data */
365
    while ((cyg_uint32)write_ptr < ((cyg_uint32)addr + (cyg_uint32)len))
366
    {
367
        if (*write_ptr != *data_ptr)
368
        {
369
            /* Error verifying data */
370
            return (FLASH_ERR_DRV_VERIFY);
371
        }
372
 
373
        /* Increment pointers to next words */
374
        ++write_ptr;
375
        ++data_ptr;
376
    }
377
 
378
    return (FLASH_ERR_OK);
379
}
380
 
381
#endif // CYGONCE_DEVS_FLASH_SST_39VF400_INL
382
 
383
 
384
 
385
 
386
 
387
 
388
 

powered by: WebSVN 2.1.0

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