]> git.sur5r.net Git - u-boot/blob - cpu/at91rm9200/at45.c
* Allow crc32 to be used at address 0x000
[u-boot] / cpu / at91rm9200 / at45.c
1 /* Driver 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
21 #include <config.h>
22 #include <common.h>
23 #include <asm/hardware.h>
24
25 #ifdef CONFIG_HAS_DATAFLASH
26 #include <dataflash.h>
27
28 #define SPI_CLK 5000000
29 #define AT91C_SPI_PCS0_SERIAL_DATAFLASH         0xE     /* Chip Select 0 : NPCS0 %1110 */
30 #define AT91C_SPI_PCS3_DATAFLASH_CARD           0x7     /* Chip Select 3 : NPCS3 %0111 */
31
32 void AT91F_SpiInit(void) {
33
34 /*-------------------------------------------------------------------*/
35 /*      SPI DataFlash Init                                                              */
36 /*-------------------------------------------------------------------*/
37         /* Configure PIOs */
38         AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
39                                    AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
40         AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
41                                    AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
42         /* Enable CLock */
43         AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
44
45         /* Reset the SPI */
46         AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
47
48         /* Configure SPI in Master Mode with No CS selected !!! */
49         AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
50
51         /* Configure CS0 and CS3 */
52         *(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
53
54         *(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
55
56 }
57
58 void AT91F_SpiEnable(int cs) {
59         switch(cs) {
60         case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
61                 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
62                 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
63                 break;
64         case 3: /* Configure SPI CS3 for Serial DataFlash Card */
65                 /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
66                 AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7;       /* Set in PIO mode */
67                 AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7;       /* Configure in output */
68                 /* Clear Output */
69                 AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
70                 /* Configure PCS */
71                 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
72                 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
73                 break;
74         }
75
76         /* SPI_Enable */
77         AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
78 }
79
80 /*----------------------------------------------------------------------------*/
81 /* \fn    AT91F_SpiWrite                                                      */
82 /* \brief Set the PDC registers for a transfert                               */
83 /*----------------------------------------------------------------------------*/
84 unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
85 {
86         unsigned int timeout;
87
88         pDesc->state = BUSY;
89
90         AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
91
92         /* Initialize the Transmit and Receive Pointer */
93         AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
94         AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
95
96         /* Intialize the Transmit and Receive Counters */
97         AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
98         AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
99
100         if ( pDesc->tx_data_size != 0 ) {
101                 /* Initialize the Next Transmit and Next Receive Pointer */
102                 AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
103                 AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
104
105                 /* Intialize the Next Transmit and Next Receive Counters */
106                 AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
107                 AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
108         }
109
110         /* arm simple, non interrupt dependent timer */
111         reset_timer_masked();
112         timeout = 0;
113
114         AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
115         while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && ((timeout = get_timer_masked() ) < CFG_SPI_WRITE_TOUT));
116         AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
117         pDesc->state = IDLE;
118
119         if (timeout >= CFG_SPI_WRITE_TOUT){
120                 printf("Error Timeout\n\r");
121                 return DATAFLASH_ERROR;
122         }
123
124         return DATAFLASH_OK;
125 }
126
127
128 /*----------------------------------------------------------------------*/
129 /* \fn    AT91F_DataFlashSendCommand                                    */
130 /* \brief Generic function to send a command to the dataflash           */
131 /*----------------------------------------------------------------------*/
132 AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
133         AT91PS_DataFlash pDataFlash,
134         unsigned char OpCode,
135         unsigned int CmdSize,
136         unsigned int DataflashAddress)
137 {
138     unsigned int adr;
139
140         if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
141                 return DATAFLASH_BUSY;
142
143         /* process the address to obtain page address and byte address */
144         adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
145
146         /* fill the  command  buffer */
147         pDataFlash->pDataFlashDesc->command[0] = OpCode;
148         pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
149         pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
150         pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
151         pDataFlash->pDataFlashDesc->command[4] = 0;
152         pDataFlash->pDataFlashDesc->command[5] = 0;
153         pDataFlash->pDataFlashDesc->command[6] = 0;
154         pDataFlash->pDataFlashDesc->command[7] = 0;
155
156         /* Initialize the SpiData structure for the spi write fuction */
157         pDataFlash->pDataFlashDesc->tx_cmd_pt   =  pDataFlash->pDataFlashDesc->command ;
158         pDataFlash->pDataFlashDesc->tx_cmd_size =  CmdSize ;
159         pDataFlash->pDataFlashDesc->rx_cmd_pt   =  pDataFlash->pDataFlashDesc->command ;
160         pDataFlash->pDataFlashDesc->rx_cmd_size =  CmdSize ;
161
162         /* send the command and read the data */
163         return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
164 }
165
166
167 /*----------------------------------------------------------------------*/
168 /* \fn    AT91F_DataFlashGetStatus                                      */
169 /* \brief Read the status register of the dataflash                     */
170 /*----------------------------------------------------------------------*/
171 AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
172 {
173         AT91S_DataFlashStatus status;
174
175         /* if a transfert is in progress ==> return 0 */
176         if( (pDesc->state) != IDLE)
177                 return DATAFLASH_BUSY;
178
179         /* first send the read status command (D7H) */
180         pDesc->command[0] = DB_STATUS;
181         pDesc->command[1] = 0;
182
183         pDesc->DataFlash_state  = GET_STATUS;
184         pDesc->tx_data_size     = 0 ;   /* Transmit the command and receive response */
185         pDesc->tx_cmd_pt                = pDesc->command ;
186         pDesc->rx_cmd_pt                = pDesc->command ;
187         pDesc->rx_cmd_size              = 2 ;
188         pDesc->tx_cmd_size              = 2 ;
189         status = AT91F_SpiWrite (pDesc);
190
191         pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
192
193         return status;
194 }
195
196
197 /*----------------------------------------------------------------------*/
198 /* \fn    AT91F_DataFlashWaitReady                                      */
199 /* \brief wait for dataflash ready (bit7 of the status register == 1)   */
200 /*----------------------------------------------------------------------*/
201 AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
202 {
203         pDataFlashDesc->DataFlash_state = IDLE;
204
205         do {
206                 AT91F_DataFlashGetStatus(pDataFlashDesc);
207                 timeout--;
208         }
209         while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
210
211         if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
212                 return DATAFLASH_ERROR;
213
214         return DATAFLASH_OK;
215 }
216
217
218 /*------------------------------------------------------------------------------*/
219 /* Function Name       : AT91F_DataFlashContinuousRead                          */
220 /* Object              : Continuous stream Read                                 */
221 /* Input Parameters    : DataFlash Service                                      */
222 /*                                              : <src> = dataflash address     */
223 /*                     : <*dataBuffer> = data buffer pointer                    */
224 /*                     : <sizeToRead> = data buffer size                        */
225 /* Return value         : State of the dataflash                                */
226 /*------------------------------------------------------------------------------*/
227 AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
228         AT91PS_DataFlash pDataFlash,
229         int src,
230         unsigned char *dataBuffer,
231         int sizeToRead )
232 {
233         /* Test the size to read in the device */
234         if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
235                 return DATAFLASH_MEMORY_OVERFLOW;
236
237         pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
238         pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
239         pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
240         pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
241
242         /* Send the command to the dataflash */
243         return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
244 }
245
246
247 /*------------------------------------------------------------------------------*/
248 /* Function Name       : AT91F_DataFlashPagePgmBuf                              */
249 /* Object              : Main memory page program through buffer 1 or buffer 2  */
250 /* Input Parameters    : DataFlash Service                                      */
251 /*                                              : <*src> = Source buffer        */
252 /*                     : <dest> = dataflash destination address                 */
253 /*                     : <SizeToWrite> = data buffer size                       */
254 /* Return value         : State of the dataflash                                */
255 /*------------------------------------------------------------------------------*/
256 AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
257         AT91PS_DataFlash pDataFlash,
258         unsigned char *src,
259         unsigned int dest,
260         unsigned int SizeToWrite)
261 {
262         pDataFlash->pDataFlashDesc->tx_data_pt = src ;
263         pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
264         pDataFlash->pDataFlashDesc->rx_data_pt = src;
265         pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
266
267         /* Send the command to the dataflash */
268         return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
269 }
270
271
272 /*------------------------------------------------------------------------------*/
273 /* Function Name       : AT91F_MainMemoryToBufferTransfert                      */
274 /* Object              : Read a page in the SRAM Buffer 1 or 2                  */
275 /* Input Parameters    : DataFlash Service                                      */
276 /*                     : Page concerned                                         */
277 /*                     :                                                        */
278 /* Return value         : State of the dataflash                                */
279 /*------------------------------------------------------------------------------*/
280 AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
281         AT91PS_DataFlash pDataFlash,
282         unsigned char BufferCommand,
283         unsigned int page)
284 {
285         /* Test if the buffer command is legal */
286         if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
287                 return DATAFLASH_BAD_COMMAND;
288
289         /* no data to transmit or receive */
290         pDataFlash->pDataFlashDesc->tx_data_size = 0;
291
292         return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
293 }
294
295
296 /*----------------------------------------------------------------------------- */
297 /* Function Name       : AT91F_DataFlashWriteBuffer                             */
298 /* Object              : Write data to the internal sram buffer 1 or 2          */
299 /* Input Parameters    : DataFlash Service                                      */
300 /*                      : <BufferCommand> = command to write buffer1 or buffer2 */
301 /*                     : <*dataBuffer> = data buffer to write                   */
302 /*                     : <bufferAddress> = address in the internal buffer       */
303 /*                     : <SizeToWrite> = data buffer size                       */
304 /* Return value         : State of the dataflash                                */
305 /*------------------------------------------------------------------------------*/
306 AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
307         AT91PS_DataFlash pDataFlash,
308         unsigned char BufferCommand,
309         unsigned char *dataBuffer,
310         unsigned int bufferAddress,
311         int SizeToWrite )
312 {
313         /* Test if the buffer command is legal */
314         if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
315                 return DATAFLASH_BAD_COMMAND;
316
317         /* buffer address must be lower than page size */
318         if (bufferAddress > pDataFlash->pDevice->pages_size)
319                 return DATAFLASH_BAD_ADDRESS;
320
321         if ( (pDataFlash->pDataFlashDesc->state)  != IDLE)
322                 return DATAFLASH_BUSY;
323
324         /* Send first Write Command */
325         pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
326         pDataFlash->pDataFlashDesc->command[1] = 0;
327         pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
328         pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
329
330
331         pDataFlash->pDataFlashDesc->tx_cmd_pt    = pDataFlash->pDataFlashDesc->command ;
332         pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ;
333         pDataFlash->pDataFlashDesc->rx_cmd_pt    = pDataFlash->pDataFlashDesc->command ;
334         pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
335
336         pDataFlash->pDataFlashDesc->rx_data_pt  = dataBuffer ;
337         pDataFlash->pDataFlashDesc->tx_data_pt  = dataBuffer ;
338         pDataFlash->pDataFlashDesc->rx_data_size        = SizeToWrite ;
339         pDataFlash->pDataFlashDesc->tx_data_size        = SizeToWrite ;
340
341         return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
342 }
343
344
345 /*------------------------------------------------------------------------------*/
346 /* Function Name       : AT91F_WriteBufferToMain                                */
347 /* Object              : Write buffer to the main memory                        */
348 /* Input Parameters    : DataFlash Service                                      */
349 /*              : <BufferCommand> = command to send to buffer1 or buffer2       */
350 /*                     : <dest> = main memory address                           */
351 /* Return value         : State of the dataflash                                */
352 /*------------------------------------------------------------------------------*/
353 AT91S_DataFlashStatus AT91F_WriteBufferToMain (
354         AT91PS_DataFlash pDataFlash,
355         unsigned char BufferCommand,
356         unsigned int dest )
357 {
358         /* Test if the buffer command is correct */
359         if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
360             (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
361             (BufferCommand != DB_BUF2_PAGE_PGM) &&
362             (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
363                 return DATAFLASH_BAD_COMMAND;
364
365         /* no data to transmit or receive */
366         pDataFlash->pDataFlashDesc->tx_data_size = 0;
367
368         /* Send the command to the dataflash */
369         return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest));
370 }
371
372
373 /*------------------------------------------------------------------------------*/
374 /* Function Name       : AT91F_PartialPageWrite                                 */
375 /* Object              : Erase partielly a page                                 */
376 /* Input Parameters    : <page> = page number                                   */
377 /*                      : <AdrInpage> = adr to begin the fading                 */
378 /*                     : <length> = Number of bytes to erase                    */
379 /*------------------------------------------------------------------------------*/
380 AT91S_DataFlashStatus AT91F_PartialPageWrite (
381         AT91PS_DataFlash pDataFlash,
382         unsigned char *src,
383         unsigned int dest,
384         unsigned int size)
385 {
386         unsigned int page;
387         unsigned int AdrInPage;
388
389         page = dest / (pDataFlash->pDevice->pages_size);
390         AdrInPage = dest % (pDataFlash->pDevice->pages_size);
391
392         /* Read the contents of the page in the Sram Buffer */
393         AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
394         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
395         /*Update the SRAM buffer */
396         AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
397         AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
398
399         /* Rewrite the modified Sram Buffer in the main memory */
400         return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
401 }
402
403
404 /*------------------------------------------------------------------------------*/
405 /* Function Name       : AT91F_DataFlashWrite_Overloaded                        */
406 /* Object              :                                                        */
407 /* Input Parameters    : <*src> = Source buffer                                 */
408 /*                     : <dest> = dataflash adress                              */
409 /*                     : <size> = data buffer size                              */
410 /*------------------------------------------------------------------------------*/
411 AT91S_DataFlashStatus AT91F_DataFlashWrite(
412         AT91PS_DataFlash pDataFlash,
413         unsigned char *src,
414         int dest,
415         int size )
416 {
417         unsigned int length;
418
419         AT91F_SpiEnable(pDataFlash->pDevice->cs);
420
421         if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
422                 return DATAFLASH_MEMORY_OVERFLOW;
423
424         /* If destination does not fit a page start address */
425         if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size)))  != 0 ) {
426                 length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
427
428                 if (size < length)
429                         length = size;
430
431                 if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
432                         return DATAFLASH_ERROR;
433
434                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
435
436                 /* Update size, source and destination pointers */
437                 size -= length;
438                 dest += length;
439                 src += length;
440         }
441
442         while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
443                 /* program dataflash page */
444                 if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
445                         return DATAFLASH_ERROR;
446
447                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
448
449                 /* Update size, source and destination pointers */
450                 size -= pDataFlash->pDevice->pages_size ;
451                 dest += pDataFlash->pDevice->pages_size ;
452                 src  += pDataFlash->pDevice->pages_size ;
453         }
454
455         /* If still some bytes to read */
456         if ( size > 0 ) {
457                 /* program dataflash page */
458                 if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
459                         return DATAFLASH_ERROR;
460
461                 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
462         }
463         return DATAFLASH_OK;
464 }
465
466
467 /*------------------------------------------------------------------------------*/
468 /* Function Name       : AT91F_DataFlashRead                                    */
469 /* Object              : Read a block in dataflash                              */
470 /* Input Parameters    :                                                        */
471 /* Return value         :                                                       */
472 /*------------------------------------------------------------------------------*/
473 int AT91F_DataFlashRead(
474         AT91PS_DataFlash pDataFlash,
475         unsigned long addr,
476         unsigned long size,
477         char *buffer)
478 {
479         unsigned long SizeToRead;
480
481         AT91F_SpiEnable(pDataFlash->pDevice->cs);
482
483         if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
484                 return -1;
485
486         while (size) {
487                 SizeToRead = (size < 0x8000)? size:0x8000;
488
489                 if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
490                         return -1;
491
492                 if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
493                         return -1;
494
495                 size -= SizeToRead;
496                 addr += SizeToRead;
497                 buffer += SizeToRead;
498         }
499
500         return DATAFLASH_OK;
501 }
502
503
504 /*------------------------------------------------------------------------------*/
505 /* Function Name       : AT91F_DataflashProbe                                   */
506 /* Object              :                                                        */
507 /* Input Parameters    :                                                        */
508 /* Return value        : Dataflash status register                              */
509 /*------------------------------------------------------------------------------*/
510 int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
511 {
512         AT91F_SpiEnable(cs);
513         AT91F_DataFlashGetStatus(pDesc);
514         return((pDesc->command[1] == 0xFF)? 0: pDesc->command[1] & 0x3C);
515 }
516
517 #endif