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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [flash/] [arm/] [lpc2xxx/] [current/] [src/] [flash_arm_lpc2xxx.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      flash_arm_lpc2xxx.c
4
//
5
//      Flash programming for LPC2xxx
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
43
// Contributors: 
44
// Date:         2007-07-12
45
// Purpose:      
46
// Description:  
47
//              
48
//####DESCRIPTIONEND####
49
//
50
//==========================================================================
51
 
52
#include <pkgconf/system.h>
53
#include <pkgconf/devs_flash_arm_lpc2xxx.h>
54
#include <pkgconf/hal.h>
55
#include <pkgconf/hal_arm.h>
56
#include <cyg/hal/hal_intr.h>
57
 
58
#include <cyg/io/flash.h>
59
#include <cyg/io/flash_dev.h>
60
 
61
#include "flash_arm_lpc2xxx.h"
62
 
63
/* gcc builtins */
64
extern void* memcpy(void *, const void *, size_t);
65
extern void* memset(void *, int, size_t);
66
 
67
/* wrapper for simpler IAP access */
68
static void
69
iap(struct iap_param *param, struct iap_param *result)
70
{
71
  static void (* const iap)(struct iap_param *, struct iap_param *)
72
    = (void (*)(struct iap_param *, struct iap_param *)) IAP_LOCATION;
73
  cyg_uint32 cpsr;
74
 
75
  HAL_DISABLE_INTERRUPTS(cpsr);
76
  iap(param, result);
77
  HAL_RESTORE_INTERRUPTS(cpsr);
78
}
79
 
80
void
81
flash_query(void *data)
82
{
83
  /* nothing to do here */
84
}
85
 
86
/*
87
 * 248k in 31 blocks by 8k there actually less blocks since two of
88
 * them are 64k, but accessing anything but the last few 8k blocks is
89
 * not supported anyway
90
 */
91
int
92
flash_hwr_init(void)
93
{
94
  flash_info.block_size = 8 * 1024;
95
  flash_info.blocks = 31;
96
  flash_info.start = (void *) 0;
97
  flash_info.end = (void *) (248 * 1024);
98
 
99
  return FLASH_ERR_OK;
100
}
101
 
102
 
103
static const cyg_uint8 flash_errors[12] = {
104
  FLASH_ERR_OK,          /* IAP_CMD_SUCCESS */
105
  FLASH_ERR_PROTOCOL,    /* IAP_INV_COMMAND */
106
  FLASH_ERR_INVALID,     /* IAP_SRC_ADDRERR */
107
  FLASH_ERR_INVALID,     /* IAP_DST_ADDRERR */
108
  FLASH_ERR_INVALID,     /* IAP_SRC_ADDRMAP */
109
  FLASH_ERR_INVALID,     /* IAP_DST_ADDRMAP */
110
  FLASH_ERR_INVALID,     /* IAP_CNT_INVALID */
111
  FLASH_ERR_INVALID,     /* IAP_SEC_INVALID */
112
  FLASH_ERR_PROTOCOL,    /* IAP_SEC_NOTBLNK */
113
  FLASH_ERR_PROTOCOL,    /* IAP_SEC_NOTPREP */
114
  FLASH_ERR_DRV_VERIFY,  /* IAP_CMP_INEQUAL */
115
  FLASH_ERR_DRV_TIMEOUT, /* IAP_BSY         */
116
};
117
 
118
int
119
flash_hwr_map_error(e)
120
{
121
  if(e > 11)
122
    return FLASH_ERR_PROTOCOL;
123
  return flash_errors[e];
124
}
125
 
126
/* this will not work for flash addresses < 0x30000 */
127
static int
128
block_by_addr(cyg_uint32 addr)
129
{
130
  int block;
131
 
132
  block = (addr >> 13) & 0x1f;
133
  block -= 14;
134
 
135
  return block;
136
}
137
 
138
int
139
flash_erase_block(void *block, unsigned int size)
140
{
141
  struct iap_param param, result;
142
 
143
  param.code = IAP_PREPARE;
144
 
145
  param.p[0] = param.p[1] = block_by_addr((cyg_uint32) block);
146
  if(param.p[0] < 10)
147
    return FLASH_ERR_INVALID;
148
 
149
  /* prepare sector(s) */
150
  iap(&param, &result);
151
  if(result.code != IAP_CMD_SUCCESS)
152
    return result.code;
153
 
154
  param.code = IAP_ERASE;
155
  param.p[2] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
156
 
157
  /* erase sector(s) */
158
  iap(&param, &result);
159
  return result.code;
160
}
161
 
162
int
163
flash_program_buf(void *addr, void *data, int len)
164
{
165
  static const int size = CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE;
166
  static const cyg_uint32 b = (0x40004000 - 32 -
167
                               CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
168
  static void * const buf = (void *) (0x40004000 - 32 -
169
                                      CYGPKG_DEVS_FLASH_ARM_LPC2XXX_BUFSIZE);
170
  cyg_uint32 a = (cyg_uint32) addr;
171
  char *d = (char *) data;
172
  struct iap_param param, result;
173
 
174
  param.code = IAP_PREPARE;
175
  param.p[0] = block_by_addr(a);
176
  param.p[1] = block_by_addr(a + len - 1);
177
  if(param.p[0] < 10 || param.p[1] > 16)
178
    return FLASH_ERR_INVALID;
179
 
180
  do {
181
    /* prepare sector(s) */
182
    iap(&param, &result);
183
    if(result.code != IAP_CMD_SUCCESS)
184
      return result.code;
185
 
186
    if(len < size)
187
      memset(buf, 0xff, size);
188
    memcpy(buf, d, size);
189
 
190
    param.code = IAP_COPY;
191
    param.p[0] = a;
192
    param.p[1] = b;
193
    param.p[2] = size;
194
    param.p[3] = CYGNUM_HAL_ARM_LPC2XXX_CLOCK_SPEED / 1000;
195
 
196
    /* copy ram to flash */
197
    iap(&param, &result);
198
    if(result.code != IAP_CMD_SUCCESS)
199
      return result.code;
200
 
201
    len -= size;
202
    a += size;
203
    d += size;
204
  } while(len > 0);
205
 
206
  return(result.code);
207
}
208
 
209
bool
210
flash_code_overlaps(void *start, void *end)
211
{
212
  extern unsigned char _stext[], _etext[];
213
 
214
  return ((((unsigned long)&_stext >= (unsigned long)start) &&
215
           ((unsigned long)&_stext < (unsigned long)end)) ||
216
          (((unsigned long)&_etext >= (unsigned long)start) &&
217
           ((unsigned long)&_etext < (unsigned long)end)));
218
}

powered by: WebSVN 2.1.0

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