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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [flash/] [atmel/] [at29cxxxx/] [v2_0/] [include/] [flash_at29cxxxx.inl] - Blame information for rev 308

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

Line No. Rev Author Line
1 27 unneback
#ifndef CYGONCE_DEVS_FLASH_ATMEL_AT29CXXXX_INL
2
#define CYGONCE_DEVS_FLASH_ATMEL_AT29CXXXX_INL
3
//==========================================================================
4
//
5
//      at29cxxxx.inl
6
//
7
//      Atmel AT29Cxxxx series 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 Red Hat, 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 version.
18
//
19
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22
// for more details.
23
//
24
// You should have received a copy of the GNU General Public License along
25
// with eCos; if not, write to the Free Software Foundation, Inc.,
26
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27
//
28
// As a special exception, if other files instantiate templates or use macros
29
// or inline functions from this file, or you compile this file and link it
30
// with other works to produce a work based on this file, this file does not
31
// by itself cause the resulting work to be covered by the GNU General Public
32
// License. However the source code for this file must still be made available
33
// in accordance with section (3) of the GNU General Public License.
34
//
35
// This exception does not invalidate any other reasons why a work based on
36
// this file might be covered by the GNU General Public License.
37
//
38
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39
// at http://sources.redhat.com/ecos/ecos-license/
40
// -------------------------------------------
41
//####ECOSGPLCOPYRIGHTEND####
42
//==========================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):    gthomas
46
// Contributors: gthomas, jskov
47
// Date:         2001-02-21
48
// Purpose:
49
// Description:
50
//
51
// Notes:        FLASH_P2V is not properly used.
52
//               Needs locking.
53
//####DESCRIPTIONEND####
54
//
55
//==========================================================================
56
 
57
#include 
58
#include 
59
#include 
60
#include CYGHWR_MEMORY_LAYOUT_H
61
 
62
#define  _FLASH_PRIVATE_
63
#include 
64
 
65
 
66
//----------------------------------------------------------------------------
67
// Common device details.
68
#define FLASH_Read_ID                   FLASHWORD( 0x90 )
69
#define FLASH_Read_ID_Exit              FLASHWORD( 0xF0 )
70
#define FLASH_Reset                     FLASHWORD( 0xFF )
71
#define FLASH_Program                   FLASHWORD( 0xA0 )
72
#define FLASH_Block_Erase               FLASHWORD( 0x30 )
73
 
74
#define FLASH_Data                      FLASHWORD( 0x80 ) // Data complement
75
#define FLASH_Busy                      FLASHWORD( 0x40 ) // "Toggle" bit
76
#define FLASH_Err                       FLASHWORD( 0x20 )
77
#define FLASH_Sector_Erase_Timer        FLASHWORD( 0x08 )
78
 
79
#define FLASH_Setup_Addr1               (0x5555)
80
#define FLASH_Setup_Addr2               (0x2AAA)
81
#define FLASH_Setup_Code1               FLASHWORD( 0xAA )
82
#define FLASH_Setup_Code2               FLASHWORD( 0x55 )
83
#define FLASH_Setup_Erase               FLASHWORD( 0x80 )
84
 
85
// Platform code must define the below
86
// #define CYGNUM_FLASH_INTERLEAVE      : Number of interleaved devices (in parallel)
87
// #define CYGNUM_FLASH_SERIES          : Number of devices in series
88
// #define CYGNUM_FLASH_BASE            : Address of first device
89
// And select one of the below device variants
90
 
91
#ifdef CYGPKG_DEVS_FLASH_ATMEL_AT29C040A
92
# define FLASH_BLOCK_SIZE               (0x10000*CYGNUM_FLASH_INTERLEAVE)
93
# define FLASH_NUM_REGIONS              (8)
94
# define CYGNUM_FLASH_BASE_MASK         (0xFFF80000u) // 512kB devices
95
# define CYGNUM_FLASH_WIDTH             (8)
96
# define CYGNUM_FLASH_BLANK             (1)
97
# define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x1F)
98
# define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0xA4)
99
#endif
100
#ifdef CYGPKG_DEVS_FLASH_ATMEL_AT29LV1024
101
# define FLASH_BLOCK_SIZE               (0x100*CYGNUM_FLASH_INTERLEAVE)
102
# define FLASH_NUM_REGIONS              (512)
103
# define CYGNUM_FLASH_BASE_MASK         (0xFFFe0000u) // 128kB devices
104
# define CYGNUM_FLASH_WIDTH             (16)
105
# define CYGNUM_FLASH_BLANK             (1)
106
# define CYGNUM_FLASH_ID_MANUFACTURER   FLASHWORD(0x1F)
107
# define CYGNUM_FLASH_ID_DEVICE         FLASHWORD(0x26)
108
#endif
109
 
110
#define FLASH_DEVICE_SIZE               (FLASH_BLOCK_SIZE*FLASH_NUM_REGIONS)
111
#define CYGNUM_FLASH_DEVICES            (CYGNUM_FLASH_INTERLEAVE*CYGNUM_FLASH_SERIES)
112
 
113
//----------------------------------------------------------------------------
114
// Now that device properties are defined, include magic for defining
115
// accessor type and constants.
116
#include 
117
 
118
//----------------------------------------------------------------------------
119
// Functions that put the flash device into non-read mode must reside
120
// in RAM.
121
void flash_query(void* data) __attribute__ ((section (".2ram.flash_query")));
122
int  flash_erase_block(void* block, unsigned int size)
123
    __attribute__ ((section (".2ram.flash_erase_block")));
124
int  flash_program_buf(void* addr, void* data, int len)
125
    __attribute__ ((section (".2ram.flash_program_buf")));
126
 
127
 
128
//----------------------------------------------------------------------------
129
// Initialize driver details
130
int
131
flash_hwr_init(void)
132
{
133
    flash_data_t id[2];
134
 
135
    flash_dev_query(id);
136
 
137
    // Check that flash_id data is matching the one the driver was
138
    // configured for.
139
    if (id[0] != CYGNUM_FLASH_ID_MANUFACTURER
140
        || id[1] != CYGNUM_FLASH_ID_DEVICE)
141
        return FLASH_ERR_DRV_WRONG_PART;
142
 
143
    // Hard wired for now
144
    flash_info.block_size = FLASH_BLOCK_SIZE;
145
    flash_info.blocks = FLASH_NUM_REGIONS;
146
    flash_info.start = (void *)CYGNUM_FLASH_BASE;
147
    flash_info.end = (void *)(CYGNUM_FLASH_BASE+ (FLASH_NUM_REGIONS * FLASH_BLOCK_SIZE * CYGNUM_FLASH_SERIES));
148
    return FLASH_ERR_OK;
149
}
150
 
151
//----------------------------------------------------------------------------
152
// Map a hardware status to a package error
153
int
154
flash_hwr_map_error(int e)
155
{
156
    return e;
157
}
158
 
159
 
160
//----------------------------------------------------------------------------
161
// See if a range of FLASH addresses overlaps currently running code
162
bool
163
flash_code_overlaps(void *start, void *end)
164
{
165
    extern unsigned char _stext[], _etext[];
166
 
167
    return ((((unsigned long)&_stext >= (unsigned long)start) &&
168
             ((unsigned long)&_stext < (unsigned long)end)) ||
169
            (((unsigned long)&_etext >= (unsigned long)start) &&
170
             ((unsigned long)&_etext < (unsigned long)end)));
171
}
172
 
173
//----------------------------------------------------------------------------
174
// Flash Query
175
//
176
// Only reads the manufacturer and part number codes for the first
177
// device(s) in series. It is assumed that any devices in series
178
// will be of the same type.
179
 
180
void
181
flash_query(void* data)
182
{
183
    volatile flash_data_t *ROM;
184
    flash_data_t* id = (flash_data_t*) data;
185
    int i;
186
 
187
    ROM = (volatile flash_data_t*) CYGNUM_FLASH_BASE;
188
 
189
    ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
190
    ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
191
    ROM[FLASH_Setup_Addr1] = FLASH_Read_ID;
192
 
193
    // FIXME: 10ms delay
194
    for (i = 10000; i > 0; i--);
195
 
196
    // Manufacturers' code
197
    id[0] = ROM[0];
198
    // Part number
199
    id[1] = ROM[1];
200
 
201
    ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
202
    ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
203
    ROM[FLASH_Setup_Addr1] = FLASH_Read_ID_Exit;
204
 
205
    // FIXME: 10ms delay
206
    for (i = 10000; i > 0; i--);
207
}
208
 
209
//----------------------------------------------------------------------------
210
// Erase Block
211
int
212
flash_erase_block(void* block, unsigned int len)
213
{
214
    volatile flash_data_t* ROM;
215
    volatile flash_data_t* addr_ptr = (volatile flash_data_t*) block;
216
    volatile flash_data_t* addr_ptr2;
217
 
218
    int res = FLASH_ERR_OK;
219
 
220
    while ((FLASH_ERR_OK == res) && (len > 0)) {
221
        int len2, i, timeout;
222
        flash_data_t state, prev_state;
223
 
224
        // Base address of device(s) being programmed.
225
        ROM = (volatile flash_data_t*)((unsigned long)block & ~(FLASH_DEVICE_SIZE-1));
226
 
227
        // Program data [byte] - 4 step sequence
228
        ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
229
        ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
230
        ROM[FLASH_Setup_Addr1] = FLASH_Program;
231
 
232
        addr_ptr2 = addr_ptr;
233
        len2 = len;
234
 
235
        // Always load 256 bytes
236
        for (i = 0; i < 256;) {
237
            *addr_ptr2++ = FLASH_BlankValue;
238
            i += sizeof(*addr_ptr2);
239
        }
240
 
241
        // Wait for completion (bit 6 stops toggling)
242
        timeout = 5000000;
243
        prev_state = *addr_ptr & FLASH_Busy;
244
        while (true) {
245
            state = *addr_ptr & FLASH_Busy;
246
            if (prev_state == state) {
247
                break;
248
            }
249
            if (--timeout == 0) {
250
                res = FLASH_ERR_DRV_TIMEOUT;
251
                break;
252
            }
253
            prev_state = state;
254
        }
255
 
256
        // Verify loaded data bytes
257
        for (i = 0; (len > 0) && (i < 256) ;) {
258
            if (*addr_ptr != FLASH_BlankValue) {
259
                // Only update return value if erase operation was OK
260
                if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
261
                break;
262
            }
263
            addr_ptr++;
264
            len -= sizeof(*addr_ptr);
265
            i += sizeof(*addr_ptr);
266
        }
267
    }
268
 
269
    return FLASH_ERR_OK;
270
}
271
 
272
//----------------------------------------------------------------------------
273
// Program Buffer
274
int
275
flash_program_buf(void* addr, void* data, int len)
276
{
277
    volatile flash_data_t* ROM;
278
    volatile flash_data_t* addr_ptr = (volatile flash_data_t*) addr;
279
    volatile flash_data_t* data_ptr = (volatile flash_data_t*) data;
280
    volatile flash_data_t* addr_ptr2;
281
    volatile flash_data_t* data_ptr2;
282
 
283
    int res = FLASH_ERR_OK;
284
 
285
#if 0
286
    CYG_ASSERT((unsigned long)data_ptr & (sizeof(flash_data_t)-1) == 0,
287
               "Data not properly aligned");
288
    CYG_ASSERT((unsigned long)addr_ptr & (CYGNUM_FLASH_INTERLEAVE*sizeof(flash_data_t)-1) == 0,
289
               "Addr not properly aligned (to first interleaved device)");
290
#endif
291
 
292
    while ((FLASH_ERR_OK == res) && (len > 0)) {
293
        int len2, i, timeout;
294
        flash_data_t state, prev_state;
295
 
296
        // Base address of device(s) being programmed.
297
        ROM = (volatile flash_data_t*)((unsigned long)addr & ~(FLASH_DEVICE_SIZE-1));
298
 
299
        // Program data [byte] - 4 step sequence
300
        ROM[FLASH_Setup_Addr1] = FLASH_Setup_Code1;
301
        ROM[FLASH_Setup_Addr2] = FLASH_Setup_Code2;
302
        ROM[FLASH_Setup_Addr1] = FLASH_Program;
303
 
304
        addr_ptr2 = addr_ptr;
305
        data_ptr2 = data_ptr;
306
        len2 = len;
307
 
308
        // Always load 256 bytes
309
        for (i = 0; i < 256;) {
310
            if (len2 > 0) {
311
                *addr_ptr2++ = *data_ptr2++;
312
                len2 -= sizeof(*data_ptr2);
313
            } else {
314
                *addr_ptr2++ = FLASH_BlankValue;
315
            }
316
            i += sizeof(*data_ptr2);
317
        }
318
 
319
        // Wait for completion (bit 6 stops toggling)
320
        timeout = 5000000;
321
        prev_state = *addr_ptr & FLASH_Busy;
322
        while (true) {
323
            state = *addr_ptr & FLASH_Busy;
324
            if (prev_state == state) {
325
                break;
326
            }
327
            if (--timeout == 0) {
328
                res = FLASH_ERR_DRV_TIMEOUT;
329
                break;
330
            }
331
            prev_state = state;
332
        }
333
 
334
        // Verify loaded data bytes
335
        for (i = 0; (len > 0) && (i < 256) ;) {
336
            if (*addr_ptr != *data_ptr) {
337
                // Only update return value if erase operation was OK
338
                if (FLASH_ERR_OK == res) res = FLASH_ERR_DRV_VERIFY;
339
                break;
340
            }
341
            addr_ptr++;
342
            data_ptr++;
343
            len -= sizeof(*data_ptr);
344
            i += sizeof(*data_ptr);
345
        }
346
    }
347
 
348
 
349
    // Ideally, we'd want to return not only the failure code, but also
350
    // the address/device that reported the error.
351
    return res;
352
}
353
 
354
#endif // CYGONCE_DEVS_FLASH_ATMEL_AT29CXXXX_INL

powered by: WebSVN 2.1.0

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