Root/target/linux/at91/image/dfboot/src/at45.c

1/*----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support - ROUSSET -
3 *----------------------------------------------------------------------------
4 * The software is delivered "AS IS" without warranty or condition of any
5 * kind, either express, implied or statutory. This includes without
6 * limitation any warranty or condition with respect to merchantability or
7 * fitness for any particular purpose, or against the infringements of
8 * intellectual property rights of others.
9 *----------------------------------------------------------------------------
10 * File Name : at45c.h
11 * Object :
12 *
13 * 1.0 10/12/03 HIi : Creation.
14 * 1.01 03/05/04 HIi : Bug Fix in AT91F_DataFlashWaitReady() Function.
15 *----------------------------------------------------------------------------
16 */
17#include "config.h"
18#include "stdio.h"
19#include "AT91RM9200.h"
20#include "lib_AT91RM9200.h"
21#include "dataflash.h"
22#include "main.h"
23
24
25/*----------------------------------------------------------------------------*/
26/* \fn AT91F_SpiInit */
27/* \brief SPI Low level Init */
28/*----------------------------------------------------------------------------*/
29void AT91F_SpiInit(void) {
30    /* Configure PIOs */
31    AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 |
32                               AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
33                               AT91C_PA6_NPCS3 | AT91C_PA0_MISO |
34                               AT91C_PA2_SPCK;
35    AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 |
36                               AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
37                               AT91C_PA6_NPCS3 | AT91C_PA0_MISO |
38                               AT91C_PA2_SPCK;
39    /* Enable CLock */
40    AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
41
42    /* Reset the SPI */
43    AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
44
45    /* Configure SPI in Master Mode with No CS selected !!! */
46    AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
47
48    /* Configure CS0 and CS3 */
49    *(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) |
50                           (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) |
51                           ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
52    *(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) |
53                           (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) |
54                           ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
55}
56
57
58/*----------------------------------------------------------------------------*/
59/* \fn AT91F_SpiEnable */
60/* \brief Enable SPI chip select */
61/*----------------------------------------------------------------------------*/
62static void AT91F_SpiEnable(int cs) {
63    switch(cs) {
64    case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
65        AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
66        AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH << 16) & AT91C_SPI_PCS);
67        break;
68    case 3: /* Configure SPI CS3 for Serial DataFlash Card */
69        /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
70        AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */
71        AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */
72        /* Clear Output */
73        AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
74        /* Configure PCS */
75        AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
76        AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
77        break;
78    }
79
80    /* SPI_Enable */
81    AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
82}
83
84/*----------------------------------------------------------------------------*/
85/* \fn AT91F_SpiWrite */
86/* \brief Set the PDC registers for a transfert */
87/*----------------------------------------------------------------------------*/
88static unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc)
89{
90       unsigned int timeout;
91    
92       AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
93
94       /* Initialize the Transmit and Receive Pointer */
95        AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
96        AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
97
98        /* Intialize the Transmit and Receive Counters */
99        AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
100        AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
101
102    if ( pDesc->tx_data_size != 0 ) {
103           /* Initialize the Next Transmit and Next Receive Pointer */
104           AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
105        AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
106
107        /* Intialize the Next Transmit and Next Receive Counters */
108        AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
109         AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
110       }
111
112    /* ARM simple, non interrupt dependent timer */
113    timeout = 0;
114
115    AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
116    while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF));
117
118       AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
119
120    if (timeout >= AT91C_DATAFLASH_TIMEOUT){
121        return AT91C_DATAFLASH_ERROR;
122    }
123
124    return AT91C_DATAFLASH_OK;
125}
126
127
128/*----------------------------------------------------------------------*/
129/* \fn AT91F_DataFlashSendCommand */
130/* \brief Generic function to send a command to the dataflash */
131/*----------------------------------------------------------------------*/
132static 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    /* process the address to obtain page address and byte address */
141    adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size))
142            << pDataFlash->pDevice->page_offset) +
143            (DataflashAddress % (pDataFlash->pDevice->pages_size));
144
145    /* fill the command buffer */
146    pDataFlash->pDataFlashDesc->command[0] = OpCode;
147    if (pDataFlash->pDevice->pages_number >= 16384)
148    {
149        pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
150        pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
151        pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
152        pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
153    }
154    else
155    {
156        pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
157        pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
158        pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
159        pDataFlash->pDataFlashDesc->command[4] = 0;
160    }
161    pDataFlash->pDataFlashDesc->command[5] = 0;
162    pDataFlash->pDataFlashDesc->command[6] = 0;
163    pDataFlash->pDataFlashDesc->command[7] = 0;
164
165    /* Initialize the SpiData structure for the spi write fuction */
166    pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
167    pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ;
168    pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
169    pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ;
170
171    return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
172}
173
174
175/*----------------------------------------------------------------------*/
176/* \fn AT91F_DataFlashGetStatus */
177/* \brief Read the status register of the dataflash */
178/*----------------------------------------------------------------------*/
179static AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
180{
181    AT91S_DataFlashStatus status;
182
183    /* first send the read status command (D7H) */
184    pDesc->command[0] = DB_STATUS;
185    pDesc->command[1] = 0;
186
187    pDesc->DataFlash_state = GET_STATUS;
188        pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
189        pDesc->tx_cmd_pt = pDesc->command ;
190        pDesc->rx_cmd_pt = pDesc->command ;
191        pDesc->rx_cmd_size = 2 ;
192        pDesc->tx_cmd_size = 2 ;
193        status = AT91F_SpiWrite (pDesc);
194
195    pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
196    return status;
197}
198
199/*-----------------------------------------------------------------------------
200 * Function Name : AT91F_DataFlashWaitReady
201 * Object : wait for dataflash ready (bit7 of the status register == 1)
202 * Input Parameters : DataFlash Service and timeout
203 * Return value : DataFlash status "ready or not"
204 *-----------------------------------------------------------------------------
205 */
206static AT91S_DataFlashStatus AT91F_DataFlashWaitReady(
207    AT91PS_DataflashDesc pDataFlashDesc,
208    unsigned int timeout)
209{
210    pDataFlashDesc->DataFlash_state = IDLE;
211        do {
212                AT91F_DataFlashGetStatus(pDataFlashDesc);
213                timeout--;
214        }
215        while(((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0));
216
217        if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
218                return AT91C_DATAFLASH_ERROR;
219
220        return AT91C_DATAFLASH_OK;
221}
222
223
224/*------------------------------------------------------------------------------*/
225/* Function Name : AT91F_DataFlashContinuousRead */
226/* Object : Continuous stream Read */
227/* Input Parameters : DataFlash Service */
228/* : <src> = dataflash address */
229/* : <*dataBuffer> = data buffer pointer */
230/* : <sizeToRead> = data buffer size */
231/* Return value : State of the dataflash */
232/*------------------------------------------------------------------------------*/
233static AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
234     AT91PS_DataFlash pDataFlash,
235    int src,
236    unsigned char *dataBuffer,
237    int sizeToRead )
238{
239    AT91S_DataFlashStatus status;
240    /* Test the size to read in the device */
241    if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
242        return AT91C_DATAFLASH_MEMORY_OVERFLOW;
243
244    pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
245    pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
246    pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
247    pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
248    
249    status = AT91F_DataFlashSendCommand(pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
250    /* Send the command to the dataflash */
251    return(status);
252}
253
254
255
256/*------------------------------------------------------------------------------*/
257/* Function Name : AT91F_MainMemoryToBufferTransfer */
258/* Object : Read a page in the SRAM Buffer 1 or 2 */
259/* Input Parameters : DataFlash Service */
260/* : Page concerned */
261/* : */
262/* Return value : State of the dataflash */
263/*------------------------------------------------------------------------------*/
264static AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfer(
265    AT91PS_DataFlash pDataFlash,
266    unsigned char BufferCommand,
267    unsigned int page)
268{
269    int cmdsize;
270    /* Test if the buffer command is legal */
271    if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
272        return AT91C_DATAFLASH_BAD_COMMAND;
273
274    /* no data to transmit or receive */
275        pDataFlash->pDataFlashDesc->tx_data_size = 0;
276    cmdsize = 4;
277    if (pDataFlash->pDevice->pages_number >= 16384)
278        cmdsize = 5;
279    return(AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, cmdsize,
280                                      page*pDataFlash->pDevice->pages_size));
281}
282
283
284
285/*----------------------------------------------------------------------------- */
286/* Function Name : AT91F_DataFlashWriteBuffer */
287/* Object : Write data to the internal sram buffer 1 or 2 */
288/* Input Parameters : DataFlash Service */
289/* : <BufferCommand> = command to write buffer1 or buffer2 */
290/* : <*dataBuffer> = data buffer to write */
291/* : <bufferAddress> = address in the internal buffer */
292/* : <SizeToWrite> = data buffer size */
293/* Return value : State of the dataflash */
294/*------------------------------------------------------------------------------*/
295static AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
296    AT91PS_DataFlash pDataFlash,
297    unsigned char BufferCommand,
298    unsigned char *dataBuffer,
299    unsigned int bufferAddress,
300    int SizeToWrite )
301{
302    int cmdsize;
303    /* Test if the buffer command is legal */
304    if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
305        return AT91C_DATAFLASH_BAD_COMMAND;
306
307    /* buffer address must be lower than page size */
308    if (bufferAddress > pDataFlash->pDevice->pages_size)
309        return AT91C_DATAFLASH_BAD_ADDRESS;
310
311        /* Send first Write Command */
312    pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
313    pDataFlash->pDataFlashDesc->command[1] = 0;
314    if (pDataFlash->pDevice->pages_number >= 16384)
315    {
316           pDataFlash->pDataFlashDesc->command[2] = 0;
317           pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
318           pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
319        cmdsize = 5;
320    }
321    else
322    {
323           pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
324           pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
325           pDataFlash->pDataFlashDesc->command[4] = 0;
326        cmdsize = 4;
327    }
328        
329    pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
330    pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
331    pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
332    pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
333
334    pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
335    pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
336    pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ;
337    pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
338
339    return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
340}
341
342
343/*------------------------------------------------------------------------------*/
344/* Function Name : AT91F_PageErase */
345/* Object : Read a page in the SRAM Buffer 1 or 2 */
346/* Input Parameters : DataFlash Service */
347/* : Page concerned */
348/* : */
349/* Return value : State of the dataflash */
350/*------------------------------------------------------------------------------*/
351static AT91S_DataFlashStatus AT91F_PageErase(
352    AT91PS_DataFlash pDataFlash,
353    unsigned int page)
354{
355    int cmdsize;
356    /* Test if the buffer command is legal */
357    /* no data to transmit or receive */
358        pDataFlash->pDataFlashDesc->tx_data_size = 0;
359    
360    cmdsize = 4;
361    if (pDataFlash->pDevice->pages_number >= 16384)
362        cmdsize = 5;
363    return(AT91F_DataFlashSendCommand(pDataFlash, DB_PAGE_ERASE, cmdsize,
364                                      page*pDataFlash->pDevice->pages_size));
365}
366
367
368/*------------------------------------------------------------------------------*/
369/* Function Name : AT91F_WriteBufferToMain */
370/* Object : Write buffer to the main memory */
371/* Input Parameters : DataFlash Service */
372/* : <BufferCommand> = command to send to buf1 or buf2 */
373/* : <dest> = main memory address */
374/* Return value : State of the dataflash */
375/*------------------------------------------------------------------------------*/
376static AT91S_DataFlashStatus AT91F_WriteBufferToMain (
377    AT91PS_DataFlash pDataFlash,
378    unsigned char BufferCommand,
379    unsigned int dest )
380{
381    int cmdsize;
382    /* Test if the buffer command is correct */
383    if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
384        (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
385        (BufferCommand != DB_BUF2_PAGE_PGM) &&
386        (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
387        return AT91C_DATAFLASH_BAD_COMMAND;
388
389    /* no data to transmit or receive */
390    pDataFlash->pDataFlashDesc->tx_data_size = 0;
391
392    cmdsize = 4;
393    if (pDataFlash->pDevice->pages_number >= 16384)
394        cmdsize = 5;
395    /* Send the command to the dataflash */
396    return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
397}
398
399
400/*------------------------------------------------------------------------------*/
401/* Function Name : AT91F_PartialPageWrite */
402/* Object : Erase partially a page */
403/* Input Parameters : <page> = page number */
404/* : <AdrInpage> = adr to begin the fading */
405/* : <length> = Number of bytes to erase */
406/*------------------------------------------------------------------------------*/
407static AT91S_DataFlashStatus AT91F_PartialPageWrite (
408    AT91PS_DataFlash pDataFlash,
409    unsigned char *src,
410    unsigned int dest,
411    unsigned int size)
412{
413    unsigned int page;
414    unsigned int AdrInPage;
415
416    page = dest / (pDataFlash->pDevice->pages_size);
417    AdrInPage = dest % (pDataFlash->pDevice->pages_size);
418
419    /* Read the contents of the page in the Sram Buffer */
420    AT91F_MainMemoryToBufferTransfer(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
421    AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
422    
423    /*Update the SRAM buffer */
424    AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
425    AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
426    
427    /* Erase page if a 128 Mbits device */
428    if (pDataFlash->pDevice->pages_number >= 16384)
429    {
430        AT91F_PageErase(pDataFlash, page);
431        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
432    }
433
434    /* Rewrite the modified Sram Buffer in the main memory */
435    return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
436                                   (page*pDataFlash->pDevice->pages_size)));
437}
438
439
440/*------------------------------------------------------------------------------*/
441/* Function Name : AT91F_DataFlashWrite */
442/* Object : */
443/* Input Parameters : <*src> = Source buffer */
444/* : <dest> = dataflash adress */
445/* : <size> = data buffer size */
446/*------------------------------------------------------------------------------*/
447AT91S_DataFlashStatus AT91F_DataFlashWrite(
448    AT91PS_DataFlash pDataFlash,
449    unsigned char *src,
450    int dest,
451    int size )
452{
453    unsigned int length;
454    unsigned int page;
455    unsigned int status;
456
457    AT91F_SpiEnable(pDataFlash->pDevice->cs);
458
459    if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
460        return AT91C_DATAFLASH_MEMORY_OVERFLOW;
461
462        /* If destination does not fit a page start address */
463    if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) {
464        length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
465
466        if (size < length)
467            length = size;
468
469        if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
470            return AT91C_DATAFLASH_ERROR;
471
472        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
473
474        /* Update size, source and destination pointers */
475            size -= length;
476            dest += length;
477            src += length;
478    }
479
480    while (( size - pDataFlash->pDevice->pages_size ) >= 0 )
481    {
482        /* program dataflash page */
483        page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
484
485        status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
486                                            0, pDataFlash->pDevice->pages_size);
487        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
488    
489        status = AT91F_PageErase(pDataFlash, page);
490        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
491        if (!status)
492            return AT91C_DATAFLASH_ERROR;
493        
494        status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
495        if(!status)
496            return AT91C_DATAFLASH_ERROR;
497
498        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
499    
500        /* Update size, source and destination pointers */
501           size -= pDataFlash->pDevice->pages_size ;
502           dest += pDataFlash->pDevice->pages_size ;
503           src += pDataFlash->pDevice->pages_size ;
504    }
505
506    /* If still some bytes to read */
507    if ( size > 0 ) {
508        /* program dataflash page */
509        if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
510            return AT91C_DATAFLASH_ERROR;
511        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
512    }
513    return AT91C_DATAFLASH_OK;
514}
515
516
517/*------------------------------------------------------------------------------*/
518/* Function Name : AT91F_DataFlashRead */
519/* Object : Read a block in dataflash */
520/* Input Parameters : */
521/* Return value : */
522/*------------------------------------------------------------------------------*/
523int AT91F_DataFlashRead(
524    AT91PS_DataFlash pDataFlash,
525    unsigned long addr,
526    unsigned long size,
527    char *buffer)
528{
529    unsigned long SizeToRead;
530
531    AT91F_SpiEnable(pDataFlash->pDevice->cs);
532
533    if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
534        return -1;
535
536    while (size)
537    {
538        SizeToRead = (size < 0x8000)? size:0x8000;
539
540        if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT)
541            != AT91C_DATAFLASH_OK)
542            return -1;
543
544        if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer,
545                                           SizeToRead) != AT91C_DATAFLASH_OK)
546            return -1;
547
548        size -= SizeToRead;
549        addr += SizeToRead;
550        buffer += SizeToRead;
551    }
552
553       return AT91C_DATAFLASH_OK;
554}
555
556
557/*------------------------------------------------------------------------------*/
558/* Function Name : AT91F_DataflashProbe */
559/* Object : */
560/* Input Parameters : */
561/* Return value : Dataflash status register */
562/*------------------------------------------------------------------------------*/
563int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
564{
565    AT91F_SpiEnable(cs);
566       AT91F_DataFlashGetStatus(pDesc);
567       return ((pDesc->command[1] == 0xFF)? 0: (pDesc->command[1] & 0x3C));
568}
569
570/*------------------------------------------------------------------------------*/
571/* Function Name : AT91F_DataFlashErase */
572/* Object : */
573/* Input Parameters : <*pDataFlash> = Device info */
574/*------------------------------------------------------------------------------*/
575AT91S_DataFlashStatus AT91F_DataFlashErase(AT91PS_DataFlash pDataFlash)
576{
577    unsigned int page;
578    unsigned int status;
579
580    AT91F_SpiEnable(pDataFlash->pDevice->cs);
581 
582     for(page=0; page < pDataFlash->pDevice->pages_number; page++)
583        {
584        /* Erase dataflash page */
585        if ((page & 0x00FF) == 0)
586            printf("\rERA %d/%d", page, pDataFlash->pDevice->pages_number);
587        status = AT91F_PageErase(pDataFlash, page);
588        AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
589        if (!status)
590            return AT91C_DATAFLASH_ERROR;
591       }
592
593    return AT91C_DATAFLASH_OK;
594}
595
596

Archive Download this file



interactive