blob: 8247aa03b5f30df32a39f598b79d172f8b497870 [file] [log] [blame]
wdenk2abbe072003-06-16 23:50:08 +00001/* LowLevel function for ATMEL DataFlash support
2 * Author : Hamid Ikdoumi (Atmel)
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 *
19 */
20#include <common.h>
21#include <config.h>
wdenk2abbe072003-06-16 23:50:08 +000022#include <asm/hardware.h>
23#include <dataflash.h>
24
wdenk2abbe072003-06-16 23:50:08 +000025static AT91S_DataFlash DataFlashInst;
26
wdenk2abbe072003-06-16 23:50:08 +000027extern void AT91F_SpiInit (void);
28extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
29extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
30 unsigned long addr,
31 unsigned long size, char *buffer);
wdenk5779d8d2003-12-06 23:55:10 +000032extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash,
Peter Pearsed4fc6012007-08-14 10:10:52 +010033 unsigned char *src,
34 int dest,
35 int size );
wdenk2abbe072003-06-16 23:50:08 +000036
37int AT91F_DataflashInit (void)
38{
39 int i, j;
40 int dfcode;
Stelian Pop5604e212008-03-26 21:52:36 +010041 int part;
Peter Pearsed4fc6012007-08-14 10:10:52 +010042 int last_part;
43 int found[CFG_MAX_DATAFLASH_BANKS];
44 unsigned char protected;
wdenk2abbe072003-06-16 23:50:08 +000045
46 AT91F_SpiInit ();
47
48 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
Peter Pearsed4fc6012007-08-14 10:10:52 +010049 found[i] = 0;
wdenk5779d8d2003-12-06 23:55:10 +000050 dataflash_info[i].Desc.state = IDLE;
wdenk2abbe072003-06-16 23:50:08 +000051 dataflash_info[i].id = 0;
52 dataflash_info[i].Device.pages_number = 0;
Stelian Popd49fe4b2008-01-20 21:07:00 +000053 dfcode = AT91F_DataflashProbe (cs[i].cs,
Peter Pearsed4fc6012007-08-14 10:10:52 +010054 &dataflash_info[i].Desc);
wdenk2abbe072003-06-16 23:50:08 +000055
56 switch (dfcode) {
57 case AT45DB161:
58 dataflash_info[i].Device.pages_number = 4096;
59 dataflash_info[i].Device.pages_size = 528;
60 dataflash_info[i].Device.page_offset = 10;
61 dataflash_info[i].Device.byte_mask = 0x300;
Stelian Popd49fe4b2008-01-20 21:07:00 +000062 dataflash_info[i].Device.cs = cs[i].cs;
wdenk2abbe072003-06-16 23:50:08 +000063 dataflash_info[i].Desc.DataFlash_state = IDLE;
Stelian Popd49fe4b2008-01-20 21:07:00 +000064 dataflash_info[i].logical_address = cs[i].addr;
wdenk2abbe072003-06-16 23:50:08 +000065 dataflash_info[i].id = dfcode;
Peter Pearsed4fc6012007-08-14 10:10:52 +010066 found[i] += dfcode;;
wdenk2abbe072003-06-16 23:50:08 +000067 break;
68
69 case AT45DB321:
70 dataflash_info[i].Device.pages_number = 8192;
71 dataflash_info[i].Device.pages_size = 528;
72 dataflash_info[i].Device.page_offset = 10;
73 dataflash_info[i].Device.byte_mask = 0x300;
Stelian Popd49fe4b2008-01-20 21:07:00 +000074 dataflash_info[i].Device.cs = cs[i].cs;
wdenk2abbe072003-06-16 23:50:08 +000075 dataflash_info[i].Desc.DataFlash_state = IDLE;
Stelian Popd49fe4b2008-01-20 21:07:00 +000076 dataflash_info[i].logical_address = cs[i].addr;
wdenk2abbe072003-06-16 23:50:08 +000077 dataflash_info[i].id = dfcode;
Peter Pearsed4fc6012007-08-14 10:10:52 +010078 found[i] += dfcode;;
wdenk2abbe072003-06-16 23:50:08 +000079 break;
80
81 case AT45DB642:
82 dataflash_info[i].Device.pages_number = 8192;
83 dataflash_info[i].Device.pages_size = 1056;
84 dataflash_info[i].Device.page_offset = 11;
85 dataflash_info[i].Device.byte_mask = 0x700;
Stelian Popd49fe4b2008-01-20 21:07:00 +000086 dataflash_info[i].Device.cs = cs[i].cs;
wdenk2abbe072003-06-16 23:50:08 +000087 dataflash_info[i].Desc.DataFlash_state = IDLE;
Stelian Popd49fe4b2008-01-20 21:07:00 +000088 dataflash_info[i].logical_address = cs[i].addr;
wdenk2abbe072003-06-16 23:50:08 +000089 dataflash_info[i].id = dfcode;
Peter Pearsed4fc6012007-08-14 10:10:52 +010090 found[i] += dfcode;;
wdenk2abbe072003-06-16 23:50:08 +000091 break;
Peter Pearsed4fc6012007-08-14 10:10:52 +010092
wdenk5779d8d2003-12-06 23:55:10 +000093 case AT45DB128:
94 dataflash_info[i].Device.pages_number = 16384;
95 dataflash_info[i].Device.pages_size = 1056;
96 dataflash_info[i].Device.page_offset = 11;
97 dataflash_info[i].Device.byte_mask = 0x700;
Stelian Popd49fe4b2008-01-20 21:07:00 +000098 dataflash_info[i].Device.cs = cs[i].cs;
wdenk5779d8d2003-12-06 23:55:10 +000099 dataflash_info[i].Desc.DataFlash_state = IDLE;
Stelian Popd49fe4b2008-01-20 21:07:00 +0000100 dataflash_info[i].logical_address = cs[i].addr;
wdenk5779d8d2003-12-06 23:55:10 +0000101 dataflash_info[i].id = dfcode;
Peter Pearsed4fc6012007-08-14 10:10:52 +0100102 found[i] += dfcode;;
wdenk5779d8d2003-12-06 23:55:10 +0000103 break;
wdenk2abbe072003-06-16 23:50:08 +0000104
105 default:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100106 dfcode = 0;
wdenk2abbe072003-06-16 23:50:08 +0000107 break;
108 }
wdenk5779d8d2003-12-06 23:55:10 +0000109 /* set the last area end to the dataflash size*/
110 area_list[NB_DATAFLASH_AREA -1].end =
111 (dataflash_info[i].Device.pages_number *
112 dataflash_info[i].Device.pages_size)-1;
wdenk2abbe072003-06-16 23:50:08 +0000113
Stelian Pop5604e212008-03-26 21:52:36 +0100114 part = 0;
115 last_part = 0;
wdenk5779d8d2003-12-06 23:55:10 +0000116 /* set the area addresses */
117 for(j = 0; j<NB_DATAFLASH_AREA; j++) {
Peter Pearsed4fc6012007-08-14 10:10:52 +0100118 if(found[i]!=0) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200119 dataflash_info[i].Device.area_list[j].start =
120 area_list[part].start +
Peter Pearsed4fc6012007-08-14 10:10:52 +0100121 dataflash_info[i].logical_address;
122 if(area_list[part].end == 0xffffffff) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200123 dataflash_info[i].Device.area_list[j].end =
124 dataflash_info[i].end_address +
Peter Pearsed4fc6012007-08-14 10:10:52 +0100125 dataflash_info [i].logical_address;
126 last_part = 1;
127 } else {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200128 dataflash_info[i].Device.area_list[j].end =
129 area_list[part].end +
Peter Pearsed4fc6012007-08-14 10:10:52 +0100130 dataflash_info[i].logical_address;
131 }
132 protected = area_list[part].protected;
133 /* Set the environment according to the label...*/
134 if(protected == FLAG_PROTECT_INVALID) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200135 dataflash_info[i].Device.area_list[j].protected =
Peter Pearsed4fc6012007-08-14 10:10:52 +0100136 FLAG_PROTECT_INVALID;
137 } else {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200138 dataflash_info[i].Device.area_list[j].protected =
Peter Pearsed4fc6012007-08-14 10:10:52 +0100139 protected;
140 }
141 strcpy((char*)(dataflash_info[i].Device.area_list[j].label),
142 (const char *)area_list[part].label);
143 }
144 part++;
wdenk5779d8d2003-12-06 23:55:10 +0000145 }
wdenk2abbe072003-06-16 23:50:08 +0000146 }
Peter Pearsed4fc6012007-08-14 10:10:52 +0100147 return found[0];
wdenk2abbe072003-06-16 23:50:08 +0000148}
149
Ulf Samuelssonc3a60cb2008-04-12 20:29:44 +0200150void AT91F_DataflashSetEnv (void)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100151{
152 int i, j;
153 int part;
154 unsigned char env;
155 unsigned char s[32]; /* Will fit a long int in hex */
156 unsigned long start;
Stelian Pop5604e212008-03-26 21:52:36 +0100157
Peter Pearsed4fc6012007-08-14 10:10:52 +0100158 for (i = 0, part= 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
159 for(j = 0; j<NB_DATAFLASH_AREA; j++) {
160 env = area_list[part].setenv;
161 /* Set the environment according to the label...*/
162 if((env & FLAG_SETENV) == FLAG_SETENV) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200163 start =
Peter Pearsed4fc6012007-08-14 10:10:52 +0100164 dataflash_info[i].Device.area_list[j].start;
Ulf Samuelssonc3a60cb2008-04-12 20:29:44 +0200165 sprintf((char*) s,"%X",start);
166 setenv((char*) area_list[part].label,(char*) s);
Peter Pearsed4fc6012007-08-14 10:10:52 +0100167 }
168 part++;
169 }
170 }
171}
wdenk2abbe072003-06-16 23:50:08 +0000172
wdenk2abbe072003-06-16 23:50:08 +0000173void dataflash_print_info (void)
174{
wdenk5779d8d2003-12-06 23:55:10 +0000175 int i, j;
wdenk2abbe072003-06-16 23:50:08 +0000176
177 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
178 if (dataflash_info[i].id != 0) {
Peter Pearsed4fc6012007-08-14 10:10:52 +0100179 printf("DataFlash:");
wdenk2abbe072003-06-16 23:50:08 +0000180 switch (dataflash_info[i].id) {
181 case AT45DB161:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100182 printf("AT45DB161\n");
wdenk2abbe072003-06-16 23:50:08 +0000183 break;
184
185 case AT45DB321:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100186 printf("AT45DB321\n");
wdenk2abbe072003-06-16 23:50:08 +0000187 break;
188
189 case AT45DB642:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100190 printf("AT45DB642\n");
wdenk2abbe072003-06-16 23:50:08 +0000191 break;
wdenk5779d8d2003-12-06 23:55:10 +0000192 case AT45DB128:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100193 printf("AT45DB128\n");
wdenk5779d8d2003-12-06 23:55:10 +0000194 break;
wdenk2abbe072003-06-16 23:50:08 +0000195 }
196
Peter Pearsed4fc6012007-08-14 10:10:52 +0100197 printf("Nb pages: %6d\n"
wdenk2abbe072003-06-16 23:50:08 +0000198 "Page Size: %6d\n"
199 "Size=%8d bytes\n"
200 "Logical address: 0x%08X\n",
201 (unsigned int) dataflash_info[i].Device.pages_number,
202 (unsigned int) dataflash_info[i].Device.pages_size,
203 (unsigned int) dataflash_info[i].Device.pages_number *
204 dataflash_info[i].Device.pages_size,
205 (unsigned int) dataflash_info[i].logical_address);
wdenk5779d8d2003-12-06 23:55:10 +0000206 for (j=0; j< NB_DATAFLASH_AREA; j++) {
Peter Pearsed4fc6012007-08-14 10:10:52 +0100207 switch(dataflash_info[i].Device.area_list[j].protected) {
208 case FLAG_PROTECT_SET:
209 case FLAG_PROTECT_CLEAR:
210 printf("Area %i:\t%08lX to %08lX %s", j,
211 dataflash_info[i].Device.area_list[j].start,
212 dataflash_info[i].Device.area_list[j].end,
213 (dataflash_info[i].Device.area_list[j].protected==FLAG_PROTECT_SET) ? "(RO)" : " ");
Peter Pearsed4fc6012007-08-14 10:10:52 +0100214 printf(" %s\n", dataflash_info[i].Device.area_list[j].label);
Peter Pearsed4fc6012007-08-14 10:10:52 +0100215 break;
Peter Pearsed4fc6012007-08-14 10:10:52 +0100216 case FLAG_PROTECT_INVALID:
217 break;
Peter Pearsed4fc6012007-08-14 10:10:52 +0100218 }
wdenk5779d8d2003-12-06 23:55:10 +0000219 }
wdenk2abbe072003-06-16 23:50:08 +0000220 }
221 }
222}
223
Peter Pearsed4fc6012007-08-14 10:10:52 +0100224/*---------------------------------------------------------------------------*/
Stelian Pop5604e212008-03-26 21:52:36 +0100225/* Function Name : AT91F_DataflashSelect */
Peter Pearsed4fc6012007-08-14 10:10:52 +0100226/* Object : Select the correct device */
227/*---------------------------------------------------------------------------*/
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200228AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
Peter Pearsed4fc6012007-08-14 10:10:52 +0100229 unsigned long *addr)
wdenk2abbe072003-06-16 23:50:08 +0000230{
231 char addr_valid = 0;
232 int i;
233
234 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100235 if ( dataflash_info[i].id
Stelian Popc77ce472008-01-14 22:08:14 +0100236 && ((((int) *addr) & 0xFF000000) ==
Peter Pearsed4fc6012007-08-14 10:10:52 +0100237 dataflash_info[i].logical_address)) {
wdenk2abbe072003-06-16 23:50:08 +0000238 addr_valid = 1;
239 break;
240 }
241 if (!addr_valid) {
242 pFlash = (AT91PS_DataFlash) 0;
243 return pFlash;
244 }
245 pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
246 pFlash->pDevice = &(dataflash_info[i].Device);
247 *addr -= dataflash_info[i].logical_address;
248 return (pFlash);
249}
250
Peter Pearsed4fc6012007-08-14 10:10:52 +0100251/*---------------------------------------------------------------------------*/
Stelian Pop5604e212008-03-26 21:52:36 +0100252/* Function Name : addr_dataflash */
Peter Pearsed4fc6012007-08-14 10:10:52 +0100253/* Object : Test if address is valid */
254/*---------------------------------------------------------------------------*/
wdenk2abbe072003-06-16 23:50:08 +0000255int addr_dataflash (unsigned long addr)
256{
257 int addr_valid = 0;
258 int i;
259
260 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
261 if ((((int) addr) & 0xFF000000) ==
262 dataflash_info[i].logical_address) {
263 addr_valid = 1;
264 break;
265 }
266 }
267
268 return addr_valid;
269}
Stelian Pop5604e212008-03-26 21:52:36 +0100270
Peter Pearsed4fc6012007-08-14 10:10:52 +0100271/*---------------------------------------------------------------------------*/
Stelian Pop5604e212008-03-26 21:52:36 +0100272/* Function Name : size_dataflash */
Peter Pearsed4fc6012007-08-14 10:10:52 +0100273/* Object : Test if address is valid regarding the size */
274/*---------------------------------------------------------------------------*/
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200275int size_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr,
Peter Pearsed4fc6012007-08-14 10:10:52 +0100276 unsigned long size)
wdenk5779d8d2003-12-06 23:55:10 +0000277{
278 /* is outside the dataflash */
279 if (((int)addr & 0x0FFFFFFF) > (pdataFlash->pDevice->pages_size *
280 pdataFlash->pDevice->pages_number)) return 0;
281 /* is too large for the dataflash */
282 if (size > ((pdataFlash->pDevice->pages_size *
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200283 pdataFlash->pDevice->pages_number) -
Peter Pearsed4fc6012007-08-14 10:10:52 +0100284 ((int)addr & 0x0FFFFFFF))) return 0;
wdenk5779d8d2003-12-06 23:55:10 +0000285
286 return 1;
287}
Stelian Pop5604e212008-03-26 21:52:36 +0100288
Peter Pearsed4fc6012007-08-14 10:10:52 +0100289/*---------------------------------------------------------------------------*/
Stelian Pop5604e212008-03-26 21:52:36 +0100290/* Function Name : prot_dataflash */
Peter Pearsed4fc6012007-08-14 10:10:52 +0100291/* Object : Test if destination area is protected */
292/*---------------------------------------------------------------------------*/
wdenk5779d8d2003-12-06 23:55:10 +0000293int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr)
294{
Stelian Pop5604e212008-03-26 21:52:36 +0100295 int area;
296
wdenk5779d8d2003-12-06 23:55:10 +0000297 /* find area */
298 for (area=0; area < NB_DATAFLASH_AREA; area++) {
299 if ((addr >= pdataFlash->pDevice->area_list[area].start) &&
300 (addr < pdataFlash->pDevice->area_list[area].end))
301 break;
302 }
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200303 if (area == NB_DATAFLASH_AREA)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100304 return -1;
305
wdenk5779d8d2003-12-06 23:55:10 +0000306 /*test protection value*/
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200307 if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100308 return 0;
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200309 if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_INVALID)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100310 return 0;
wdenk5779d8d2003-12-06 23:55:10 +0000311
312 return 1;
313}
Stelian Pop5604e212008-03-26 21:52:36 +0100314
Peter Pearsed4fc6012007-08-14 10:10:52 +0100315/*--------------------------------------------------------------------------*/
316/* Function Name : dataflash_real_protect */
317/* Object : protect/unprotect area */
318/*--------------------------------------------------------------------------*/
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200319int dataflash_real_protect (int flag, unsigned long start_addr,
Peter Pearsed4fc6012007-08-14 10:10:52 +0100320 unsigned long end_addr)
wdenk5779d8d2003-12-06 23:55:10 +0000321{
Stelian Pop5604e212008-03-26 21:52:36 +0100322 int i,j, area1, area2, addr_valid = 0;
323
wdenk5779d8d2003-12-06 23:55:10 +0000324 /* find dataflash */
325 for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
326 if ((((int) start_addr) & 0xF0000000) ==
327 dataflash_info[i].logical_address) {
328 addr_valid = 1;
329 break;
330 }
331 }
332 if (!addr_valid) {
333 return -1;
334 }
335 /* find start area */
336 for (area1=0; area1 < NB_DATAFLASH_AREA; area1++) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200337 if (start_addr == dataflash_info[i].Device.area_list[area1].start)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100338 break;
wdenk5779d8d2003-12-06 23:55:10 +0000339 }
340 if (area1 == NB_DATAFLASH_AREA) return -1;
341 /* find end area */
342 for (area2=0; area2 < NB_DATAFLASH_AREA; area2++) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200343 if (end_addr == dataflash_info[i].Device.area_list[area2].end)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100344 break;
wdenk5779d8d2003-12-06 23:55:10 +0000345 }
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200346 if (area2 == NB_DATAFLASH_AREA)
Peter Pearsed4fc6012007-08-14 10:10:52 +0100347 return -1;
wdenk5779d8d2003-12-06 23:55:10 +0000348
349 /*set protection value*/
350 for(j = area1; j < area2+1 ; j++)
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200351 if(dataflash_info[i].Device.area_list[j].protected
Peter Pearsed4fc6012007-08-14 10:10:52 +0100352 != FLAG_PROTECT_INVALID) {
353 if (flag == 0) {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200354 dataflash_info[i].Device.area_list[j].protected
Peter Pearsed4fc6012007-08-14 10:10:52 +0100355 = FLAG_PROTECT_CLEAR;
356 } else {
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200357 dataflash_info[i].Device.area_list[j].protected
Peter Pearsed4fc6012007-08-14 10:10:52 +0100358 = FLAG_PROTECT_SET;
359 }
360 }
wdenk5779d8d2003-12-06 23:55:10 +0000361
362 return (area2-area1+1);
363}
wdenk2abbe072003-06-16 23:50:08 +0000364
Peter Pearsed4fc6012007-08-14 10:10:52 +0100365/*---------------------------------------------------------------------------*/
Stelian Pop5604e212008-03-26 21:52:36 +0100366/* Function Name : read_dataflash */
Peter Pearsed4fc6012007-08-14 10:10:52 +0100367/* Object : dataflash memory read */
368/*---------------------------------------------------------------------------*/
wdenk2abbe072003-06-16 23:50:08 +0000369int read_dataflash (unsigned long addr, unsigned long size, char *result)
370{
Wolfgang Denkd52fb7e2006-03-11 22:53:33 +0100371 unsigned long AddrToRead = addr;
wdenk2abbe072003-06-16 23:50:08 +0000372 AT91PS_DataFlash pFlash = &DataFlashInst;
373
374 pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
wdenk5779d8d2003-12-06 23:55:10 +0000375
wdenk2abbe072003-06-16 23:50:08 +0000376 if (pFlash == 0)
wdenk5779d8d2003-12-06 23:55:10 +0000377 return ERR_UNKNOWN_FLASH_TYPE;
378
379 if (size_dataflash(pFlash,addr,size) == 0)
380 return ERR_INVAL;
wdenk2abbe072003-06-16 23:50:08 +0000381
382 return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
383}
384
Peter Pearsed4fc6012007-08-14 10:10:52 +0100385/*---------------------------------------------------------------------------*/
Stelian Pop5604e212008-03-26 21:52:36 +0100386/* Function Name : write_dataflash */
Peter Pearsed4fc6012007-08-14 10:10:52 +0100387/* Object : write a block in dataflash */
388/*---------------------------------------------------------------------------*/
wdenk2abbe072003-06-16 23:50:08 +0000389int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
Peter Pearsed4fc6012007-08-14 10:10:52 +0100390 unsigned long size)
wdenk2abbe072003-06-16 23:50:08 +0000391{
Wolfgang Denkd52fb7e2006-03-11 22:53:33 +0100392 unsigned long AddrToWrite = addr_dest;
wdenk2abbe072003-06-16 23:50:08 +0000393 AT91PS_DataFlash pFlash = &DataFlashInst;
394
395 pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
wdenk5779d8d2003-12-06 23:55:10 +0000396
397 if (pFlash == 0)
398 return ERR_UNKNOWN_FLASH_TYPE;
399
400 if (size_dataflash(pFlash,addr_dest,size) == 0)
401 return ERR_INVAL;
402
403 if (prot_dataflash(pFlash,addr_dest) == 0)
404 return ERR_PROTECTED;
405
wdenk2abbe072003-06-16 23:50:08 +0000406 if (AddrToWrite == -1)
407 return -1;
408
Wolfgang Denkf01dbb52007-08-14 18:42:36 +0200409 return AT91F_DataFlashWrite (pFlash, (uchar *)addr_src,
Peter Pearsed4fc6012007-08-14 10:10:52 +0100410 AddrToWrite, size);
wdenk2abbe072003-06-16 23:50:08 +0000411}
412
wdenk2abbe072003-06-16 23:50:08 +0000413void dataflash_perror (int err)
414{
415 switch (err) {
416 case ERR_OK:
417 break;
418 case ERR_TIMOUT:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100419 printf("Timeout writing to DataFlash\n");
wdenk2abbe072003-06-16 23:50:08 +0000420 break;
421 case ERR_PROTECTED:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100422 printf("Can't write to protected/invalid DataFlash sectors\n");
wdenk2abbe072003-06-16 23:50:08 +0000423 break;
424 case ERR_INVAL:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100425 printf("Outside available DataFlash\n");
wdenk2abbe072003-06-16 23:50:08 +0000426 break;
427 case ERR_UNKNOWN_FLASH_TYPE:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100428 printf("Unknown Type of DataFlash\n");
wdenk2abbe072003-06-16 23:50:08 +0000429 break;
430 case ERR_PROG_ERROR:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100431 printf("General DataFlash Programming Error\n");
wdenk2abbe072003-06-16 23:50:08 +0000432 break;
433 default:
Peter Pearsed4fc6012007-08-14 10:10:52 +0100434 printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
wdenk2abbe072003-06-16 23:50:08 +0000435 break;
436 }
437}