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
13 //* 1.0 10/12/03 HIi : Creation.
14 //* 1.01 03/05/04 HIi : Bug Fix in AT91F_DataFlashWaitReady() Function.
15 //*----------------------------------------------------------------------------
17 #include <AT91RM9200.h>
18 #include <lib_AT91RM9200.h>
19 #include "dataflash.h"
22 #define AT91C_SPI_CLK 8000000
23 #define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */
24 #define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3 : NPCS3 %0111 */
26 /*----------------------------------------------------------------------------*/
27 /* \fn AT91F_SpiInit */
28 /* \brief SPI Low level Init */
29 /*----------------------------------------------------------------------------*/
30 void AT91F_SpiInit(void) {
32 AT91C_BASE_PIOA
->PIO_ASR
= AT91C_PA3_NPCS0
| AT91C_PA4_NPCS1
| AT91C_PA1_MOSI
| AT91C_PA5_NPCS2
|
33 AT91C_PA6_NPCS3
| AT91C_PA0_MISO
| AT91C_PA2_SPCK
;
34 AT91C_BASE_PIOA
->PIO_PDR
= AT91C_PA3_NPCS0
| AT91C_PA4_NPCS1
| AT91C_PA1_MOSI
| AT91C_PA5_NPCS2
|
35 AT91C_PA6_NPCS3
| AT91C_PA0_MISO
| AT91C_PA2_SPCK
;
37 AT91C_BASE_PMC
->PMC_PCER
= 1 << AT91C_ID_SPI
;
40 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SWRST
;
42 /* Configure SPI in Master Mode with No CS selected !!! */
43 AT91C_BASE_SPI
->SPI_MR
= AT91C_SPI_MSTR
| AT91C_SPI_MODFDIS
| AT91C_SPI_PCS
;
45 /* Configure CS0 and CS3 */
46 *(AT91C_SPI_CSR
+ 0) = AT91C_SPI_NCPHA
| (AT91C_SPI_DLYBS
& 0x100000) | ((AT91C_MASTER_CLOCK
/ (2*AT91C_SPI_CLK
)) << 8);
47 *(AT91C_SPI_CSR
+ 3) = AT91C_SPI_NCPHA
| (AT91C_SPI_DLYBS
& 0x100000) | ((AT91C_MASTER_CLOCK
/ (2*AT91C_SPI_CLK
)) << 8);
52 /*----------------------------------------------------------------------------*/
53 /* \fn AT91F_SpiEnable */
54 /* \brief Enable SPI chip select */
55 /*----------------------------------------------------------------------------*/
56 void AT91F_SpiEnable(int cs
) {
58 case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
59 AT91C_BASE_SPI
->SPI_MR
&= 0xFFF0FFFF;
60 AT91C_BASE_SPI
->SPI_MR
|= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH
<<16) & AT91C_SPI_PCS
);
62 case 3: /* Configure SPI CS3 for Serial DataFlash Card */
63 /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
64 AT91C_BASE_PIOB
->PIO_PER
= AT91C_PIO_PB7
; /* Set in PIO mode */
65 AT91C_BASE_PIOB
->PIO_OER
= AT91C_PIO_PB7
; /* Configure in output */
67 AT91C_BASE_PIOB
->PIO_CODR
= AT91C_PIO_PB7
;
69 AT91C_BASE_SPI
->SPI_MR
&= 0xFFF0FFFF;
70 AT91C_BASE_SPI
->SPI_MR
|= ((AT91C_SPI_PCS3_DATAFLASH_CARD
<<16) & AT91C_SPI_PCS
);
75 AT91C_BASE_SPI
->SPI_CR
= AT91C_SPI_SPIEN
;
78 /*----------------------------------------------------------------------------*/
79 /* \fn AT91F_SpiWrite */
80 /* \brief Set the PDC registers for a transfert */
81 /*----------------------------------------------------------------------------*/
82 unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc
)
88 AT91C_BASE_SPI
->SPI_PTCR
= AT91C_PDC_TXTDIS
+ AT91C_PDC_RXTDIS
;
90 /* Initialize the Transmit and Receive Pointer */
91 AT91C_BASE_SPI
->SPI_RPR
= (unsigned int)pDesc
->rx_cmd_pt
;
92 AT91C_BASE_SPI
->SPI_TPR
= (unsigned int)pDesc
->tx_cmd_pt
;
94 /* Intialize the Transmit and Receive Counters */
95 AT91C_BASE_SPI
->SPI_RCR
= pDesc
->rx_cmd_size
;
96 AT91C_BASE_SPI
->SPI_TCR
= pDesc
->tx_cmd_size
;
98 if ( pDesc
->tx_data_size
!= 0 ) {
99 /* Initialize the Next Transmit and Next Receive Pointer */
100 AT91C_BASE_SPI
->SPI_RNPR
= (unsigned int)pDesc
->rx_data_pt
;
101 AT91C_BASE_SPI
->SPI_TNPR
= (unsigned int)pDesc
->tx_data_pt
;
103 /* Intialize the Next Transmit and Next Receive Counters */
104 AT91C_BASE_SPI
->SPI_RNCR
= pDesc
->rx_data_size
;
105 AT91C_BASE_SPI
->SPI_TNCR
= pDesc
->tx_data_size
;
108 /* arm simple, non interrupt dependent timer */
111 AT91C_BASE_SPI
->SPI_PTCR
= AT91C_PDC_TXTEN
+ AT91C_PDC_RXTEN
;
112 while(!(AT91C_BASE_SPI
->SPI_SR
& AT91C_SPI_RXBUFF
));
114 AT91C_BASE_SPI
->SPI_PTCR
= AT91C_PDC_TXTDIS
+ AT91C_PDC_RXTDIS
;
117 if (timeout
>= AT91C_DATAFLASH_TIMEOUT
){
118 return AT91C_DATAFLASH_ERROR
;
121 return AT91C_DATAFLASH_OK
;
125 /*----------------------------------------------------------------------*/
126 /* \fn AT91F_DataFlashSendCommand */
127 /* \brief Generic function to send a command to the dataflash */
128 /*----------------------------------------------------------------------*/
129 AT91S_DataFlashStatus
AT91F_DataFlashSendCommand(
130 AT91PS_DataFlash pDataFlash
,
131 unsigned char OpCode
,
132 unsigned int CmdSize
,
133 unsigned int DataflashAddress
)
137 if ( (pDataFlash
->pDataFlashDesc
->state
) != IDLE
)
138 return AT91C_DATAFLASH_BUSY
;
140 /* process the address to obtain page address and byte address */
141 adr
= ((DataflashAddress
/ (pDataFlash
->pDevice
->pages_size
)) << pDataFlash
->pDevice
->page_offset
) + (DataflashAddress
% (pDataFlash
->pDevice
->pages_size
));
143 /* fill the command buffer */
144 pDataFlash
->pDataFlashDesc
->command
[0] = OpCode
;
145 if (pDataFlash
->pDevice
->pages_number
>= 16384)
147 pDataFlash
->pDataFlashDesc
->command
[1] = (unsigned char)((adr
& 0x0F000000) >> 24);
148 pDataFlash
->pDataFlashDesc
->command
[2] = (unsigned char)((adr
& 0x00FF0000) >> 16);
149 pDataFlash
->pDataFlashDesc
->command
[3] = (unsigned char)((adr
& 0x0000FF00) >> 8);
150 pDataFlash
->pDataFlashDesc
->command
[4] = (unsigned char)(adr
& 0x000000FF);
154 pDataFlash
->pDataFlashDesc
->command
[1] = (unsigned char)((adr
& 0x00FF0000) >> 16);
155 pDataFlash
->pDataFlashDesc
->command
[2] = (unsigned char)((adr
& 0x0000FF00) >> 8);
156 pDataFlash
->pDataFlashDesc
->command
[3] = (unsigned char)(adr
& 0x000000FF) ;
157 pDataFlash
->pDataFlashDesc
->command
[4] = 0;
159 pDataFlash
->pDataFlashDesc
->command
[5] = 0;
160 pDataFlash
->pDataFlashDesc
->command
[6] = 0;
161 pDataFlash
->pDataFlashDesc
->command
[7] = 0;
163 /* Initialize the SpiData structure for the spi write fuction */
164 pDataFlash
->pDataFlashDesc
->tx_cmd_pt
= pDataFlash
->pDataFlashDesc
->command
;
165 pDataFlash
->pDataFlashDesc
->tx_cmd_size
= CmdSize
;
166 pDataFlash
->pDataFlashDesc
->rx_cmd_pt
= pDataFlash
->pDataFlashDesc
->command
;
167 pDataFlash
->pDataFlashDesc
->rx_cmd_size
= CmdSize
;
169 return AT91F_SpiWrite (pDataFlash
->pDataFlashDesc
);
173 /*----------------------------------------------------------------------*/
174 /* \fn AT91F_DataFlashGetStatus */
175 /* \brief Read the status register of the dataflash */
176 /*----------------------------------------------------------------------*/
177 AT91S_DataFlashStatus
AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc
)
179 AT91S_DataFlashStatus status
;
181 /* if a transfert is in progress ==> return 0 */
182 if( (pDesc
->state
) != IDLE
)
183 return AT91C_DATAFLASH_BUSY
;
185 /* first send the read status command (D7H) */
186 pDesc
->command
[0] = DB_STATUS
;
187 pDesc
->command
[1] = 0;
189 pDesc
->DataFlash_state
= GET_STATUS
;
190 pDesc
->tx_data_size
= 0 ; /* Transmit the command and receive response */
191 pDesc
->tx_cmd_pt
= pDesc
->command
;
192 pDesc
->rx_cmd_pt
= pDesc
->command
;
193 pDesc
->rx_cmd_size
= 2 ;
194 pDesc
->tx_cmd_size
= 2 ;
195 status
= AT91F_SpiWrite (pDesc
);
197 pDesc
->DataFlash_state
= *( (unsigned char *) (pDesc
->rx_cmd_pt
) +1);
202 /*----------------------------------------------------------------------*/
203 /* fn AT91F_DataFlashExtID */
204 /* brief Read the extended ID */
205 /*----------------------------------------------------------------------*/
206 AT91S_DataFlashStatus
AT91F_DataFlashExtID(AT91PS_DataflashDesc pDesc
)
208 AT91S_DataFlashStatus status
;
210 /* if a transfert is in progress ==> return 0 */
211 if( (pDesc
->state
) != IDLE
)
212 return AT91C_DATAFLASH_BUSY
;
214 /* first send the read status command (D7H) */
215 pDesc
->command
[0] = 0x9F;
216 pDesc
->command
[1] = 0;
218 pDesc
->DataFlash_state
= GET_STATUS
;
219 pDesc
->tx_data_size
= 0 ; /* Transmit the command and receive response */
220 pDesc
->tx_cmd_pt
= pDesc
->command
;
221 pDesc
->rx_cmd_pt
= pDesc
->command
;
222 pDesc
->rx_cmd_size
= 5 ;
223 pDesc
->tx_cmd_size
= 5 ;
224 status
= AT91F_SpiWrite (pDesc
);
226 pDesc
->DataFlash_state
= *( (unsigned char *) (pDesc
->rx_cmd_pt
) +1);
233 //*-----------------------------------------------------------------------------
234 //* Function Name : AT91F_DataFlashWaitReady
235 //* Object : wait for dataflash ready (bit7 of the status register == 1)
236 //* Input Parameters : DataFlash Service and timeout
237 //* Return value : DataFlash status "ready or not"
238 //*-----------------------------------------------------------------------------
239 AT91S_DataFlashStatus
AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc
, unsigned int timeout
)
241 volatile unsigned int tick
;
242 unsigned int NbTry
= 0;
244 tick
= GetTickCount();
246 while((pDataFlashDesc
->state
!= IDLE
) && ((volatile unsigned int)GetTickCount() < (tick
+ timeout
)));
248 if(pDataFlashDesc
->state
!= IDLE
)
249 return AT91C_DATAFLASH_ERROR
;
251 pDataFlashDesc
->DataFlash_state
= 0;
254 (volatile unsigned int)AT91F_DataFlashGetStatus(pDataFlashDesc
);
255 if((pDataFlashDesc
->DataFlash_state
& 0x80) == 0x80)
256 return AT91C_DATAFLASH_OK
;
263 tick = GetTickCount();
264 AT91F_DataFlashGetStatus(pDataFlashDesc);
265 while((pDataFlashDesc->state != IDLE) && (GetTickCount() < (tick + 5)));
266 if((pDataFlashDesc->DataFlash_state & 0x80) == 0x80)
267 return AT91C_DATAFLASH_OK;
273 return AT91C_DATAFLASH_ERROR
;
283 /*------------------------------------------------------------------------------*/
284 /* Function Name : AT91F_DataFlashContinuousRead */
285 /* Object : Continuous stream Read */
286 /* Input Parameters : DataFlash Service */
287 /* : <src> = dataflash address */
288 /* : <*dataBuffer> = data buffer pointer */
289 /* : <sizeToRead> = data buffer size */
290 /* Return value : State of the dataflash */
291 /*------------------------------------------------------------------------------*/
292 AT91S_DataFlashStatus
AT91F_DataFlashContinuousRead (
293 AT91PS_DataFlash pDataFlash
,
295 unsigned char *dataBuffer
,
298 AT91S_DataFlashStatus status
;
299 /* Test the size to read in the device */
300 if ( (src
+ sizeToRead
) > (pDataFlash
->pDevice
->pages_size
* (pDataFlash
->pDevice
->pages_number
)))
301 return AT91C_DATAFLASH_MEMORY_OVERFLOW
;
303 pDataFlash
->pDataFlashDesc
->rx_data_pt
= dataBuffer
;
304 pDataFlash
->pDataFlashDesc
->rx_data_size
= sizeToRead
;
305 pDataFlash
->pDataFlashDesc
->tx_data_pt
= dataBuffer
;
306 pDataFlash
->pDataFlashDesc
->tx_data_size
= sizeToRead
;
308 status
= AT91F_DataFlashSendCommand (pDataFlash
, DB_CONTINUOUS_ARRAY_READ
, 8, src
);
309 /* Send the command to the dataflash */
315 /*------------------------------------------------------------------------------*/
316 /* Function Name : AT91F_MainMemoryToBufferTransfert */
317 /* Object : Read a page in the SRAM Buffer 1 or 2 */
318 /* Input Parameters : DataFlash Service */
319 /* : Page concerned */
321 /* Return value : State of the dataflash */
322 /*------------------------------------------------------------------------------*/
323 AT91S_DataFlashStatus
AT91F_MainMemoryToBufferTransfert(
324 AT91PS_DataFlash pDataFlash
,
325 unsigned char BufferCommand
,
329 /* Test if the buffer command is legal */
330 if ((BufferCommand
!= DB_PAGE_2_BUF1_TRF
) && (BufferCommand
!= DB_PAGE_2_BUF2_TRF
))
331 return AT91C_DATAFLASH_BAD_COMMAND
;
333 /* no data to transmit or receive */
334 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
336 if (pDataFlash
->pDevice
->pages_number
>= 16384)
338 return(AT91F_DataFlashSendCommand (pDataFlash
, BufferCommand
, cmdsize
, page
*pDataFlash
->pDevice
->pages_size
));
343 /*----------------------------------------------------------------------------- */
344 /* Function Name : AT91F_DataFlashWriteBuffer */
345 /* Object : Write data to the internal sram buffer 1 or 2 */
346 /* Input Parameters : DataFlash Service */
347 /* : <BufferCommand> = command to write buffer1 or buffer2 */
348 /* : <*dataBuffer> = data buffer to write */
349 /* : <bufferAddress> = address in the internal buffer */
350 /* : <SizeToWrite> = data buffer size */
351 /* Return value : State of the dataflash */
352 /*------------------------------------------------------------------------------*/
353 AT91S_DataFlashStatus
AT91F_DataFlashWriteBuffer (
354 AT91PS_DataFlash pDataFlash
,
355 unsigned char BufferCommand
,
356 unsigned char *dataBuffer
,
357 unsigned int bufferAddress
,
361 /* Test if the buffer command is legal */
362 if ((BufferCommand
!= DB_BUF1_WRITE
) && (BufferCommand
!= DB_BUF2_WRITE
))
363 return AT91C_DATAFLASH_BAD_COMMAND
;
365 /* buffer address must be lower than page size */
366 if (bufferAddress
> pDataFlash
->pDevice
->pages_size
)
367 return AT91C_DATAFLASH_BAD_ADDRESS
;
369 if ( (pDataFlash
->pDataFlashDesc
->state
) != IDLE
)
370 return AT91C_DATAFLASH_BUSY
;
372 /* Send first Write Command */
373 pDataFlash
->pDataFlashDesc
->command
[0] = BufferCommand
;
374 pDataFlash
->pDataFlashDesc
->command
[1] = 0;
375 if (pDataFlash
->pDevice
->pages_number
>= 16384)
377 pDataFlash
->pDataFlashDesc
->command
[2] = 0;
378 pDataFlash
->pDataFlashDesc
->command
[3] = (unsigned char)(((unsigned int)(bufferAddress
& pDataFlash
->pDevice
->byte_mask
)) >> 8) ;
379 pDataFlash
->pDataFlashDesc
->command
[4] = (unsigned char)((unsigned int)bufferAddress
& 0x00FF) ;
384 pDataFlash
->pDataFlashDesc
->command
[2] = (unsigned char)(((unsigned int)(bufferAddress
& pDataFlash
->pDevice
->byte_mask
)) >> 8) ;
385 pDataFlash
->pDataFlashDesc
->command
[3] = (unsigned char)((unsigned int)bufferAddress
& 0x00FF) ;
386 pDataFlash
->pDataFlashDesc
->command
[4] = 0;
390 pDataFlash
->pDataFlashDesc
->tx_cmd_pt
= pDataFlash
->pDataFlashDesc
->command
;
391 pDataFlash
->pDataFlashDesc
->tx_cmd_size
= cmdsize
;
392 pDataFlash
->pDataFlashDesc
->rx_cmd_pt
= pDataFlash
->pDataFlashDesc
->command
;
393 pDataFlash
->pDataFlashDesc
->rx_cmd_size
= cmdsize
;
395 pDataFlash
->pDataFlashDesc
->rx_data_pt
= dataBuffer
;
396 pDataFlash
->pDataFlashDesc
->tx_data_pt
= dataBuffer
;
397 pDataFlash
->pDataFlashDesc
->rx_data_size
= SizeToWrite
;
398 pDataFlash
->pDataFlashDesc
->tx_data_size
= SizeToWrite
;
400 return AT91F_SpiWrite(pDataFlash
->pDataFlashDesc
);
405 /*------------------------------------------------------------------------------*/
406 /* Function Name : AT91F_PageErase */
407 /* Object : Read a page in the SRAM Buffer 1 or 2 */
408 /* Input Parameters : DataFlash Service */
409 /* : Page concerned */
411 /* Return value : State of the dataflash */
412 /*------------------------------------------------------------------------------*/
413 AT91S_DataFlashStatus
AT91F_PageErase(
414 AT91PS_DataFlash pDataFlash
,
418 /* Test if the buffer command is legal */
419 /* no data to transmit or receive */
420 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
423 if (pDataFlash
->pDevice
->pages_number
>= 16384)
425 return(AT91F_DataFlashSendCommand (pDataFlash
, DB_PAGE_ERASE
, cmdsize
, page
*pDataFlash
->pDevice
->pages_size
));
430 /*------------------------------------------------------------------------------*/
431 /* Function Name : AT91F_WriteBufferToMain */
432 /* Object : Write buffer to the main memory */
433 /* Input Parameters : DataFlash Service */
434 /* : <BufferCommand> = command to send to buffer1 or buffer2 */
435 /* : <dest> = main memory address */
436 /* Return value : State of the dataflash */
437 /*------------------------------------------------------------------------------*/
438 AT91S_DataFlashStatus
AT91F_WriteBufferToMain (
439 AT91PS_DataFlash pDataFlash
,
440 unsigned char BufferCommand
,
444 /* Test if the buffer command is correct */
445 if ((BufferCommand
!= DB_BUF1_PAGE_PGM
) &&
446 (BufferCommand
!= DB_BUF1_PAGE_ERASE_PGM
) &&
447 (BufferCommand
!= DB_BUF2_PAGE_PGM
) &&
448 (BufferCommand
!= DB_BUF2_PAGE_ERASE_PGM
) )
449 return AT91C_DATAFLASH_BAD_COMMAND
;
451 /* no data to transmit or receive */
452 pDataFlash
->pDataFlashDesc
->tx_data_size
= 0;
455 if (pDataFlash
->pDevice
->pages_number
>= 16384)
457 /* Send the command to the dataflash */
458 return(AT91F_DataFlashSendCommand (pDataFlash
, BufferCommand
, cmdsize
, dest
));
462 /*------------------------------------------------------------------------------*/
463 /* Function Name : AT91F_PartialPageWrite */
464 /* Object : Erase partielly a page */
465 /* Input Parameters : <page> = page number */
466 /* : <AdrInpage> = adr to begin the fading */
467 /* : <length> = Number of bytes to erase */
468 /*------------------------------------------------------------------------------*/
469 AT91S_DataFlashStatus
AT91F_PartialPageWrite (
470 AT91PS_DataFlash pDataFlash
,
476 unsigned int AdrInPage
;
478 page
= dest
/ (pDataFlash
->pDevice
->pages_size
);
479 AdrInPage
= dest
% (pDataFlash
->pDevice
->pages_size
);
481 /* Read the contents of the page in the Sram Buffer */
482 AT91F_MainMemoryToBufferTransfert(pDataFlash
, DB_PAGE_2_BUF1_TRF
, page
);
483 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
485 /*Update the SRAM buffer */
486 AT91F_DataFlashWriteBuffer(pDataFlash
, DB_BUF1_WRITE
, src
, AdrInPage
, size
);
487 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
489 /* Erase page if a 128 Mbits device */
490 if (pDataFlash
->pDevice
->pages_number
>= 16384)
492 AT91F_PageErase(pDataFlash
, page
);
493 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
496 /* Rewrite the modified Sram Buffer in the main memory */
497 return(AT91F_WriteBufferToMain(pDataFlash
, DB_BUF1_PAGE_ERASE_PGM
, (page
*pDataFlash
->pDevice
->pages_size
)));
502 /*------------------------------------------------------------------------------*/
503 /* Function Name : AT91F_DataFlashWrite */
505 /* Input Parameters : <*src> = Source buffer */
506 /* : <dest> = dataflash adress */
507 /* : <size> = data buffer size */
508 /*------------------------------------------------------------------------------*/
509 AT91S_DataFlashStatus
AT91F_DataFlashWrite(
510 AT91PS_DataFlash pDataFlash
,
519 AT91F_SpiEnable(pDataFlash
->pDevice
->cs
);
521 if ( (dest
+ size
) > (pDataFlash
->pDevice
->pages_size
* (pDataFlash
->pDevice
->pages_number
)))
522 return AT91C_DATAFLASH_MEMORY_OVERFLOW
;
524 /* If destination does not fit a page start address */
525 if ((dest
% ((unsigned int)(pDataFlash
->pDevice
->pages_size
))) != 0 ) {
526 length
= pDataFlash
->pDevice
->pages_size
- (dest
% ((unsigned int)(pDataFlash
->pDevice
->pages_size
)));
531 if(!AT91F_PartialPageWrite(pDataFlash
,src
, dest
, length
))
532 return AT91C_DATAFLASH_ERROR
;
534 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
536 /* Update size, source and destination pointers */
542 while (( size
- pDataFlash
->pDevice
->pages_size
) >= 0 )
544 /* program dataflash page */
545 page
= (unsigned int)dest
/ (pDataFlash
->pDevice
->pages_size
);
547 status
= AT91F_DataFlashWriteBuffer(pDataFlash
, DB_BUF1_WRITE
, src
, 0, pDataFlash
->pDevice
->pages_size
);
548 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
550 status
= AT91F_PageErase(pDataFlash
, page
);
551 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
553 return AT91C_DATAFLASH_ERROR
;
555 status
= AT91F_WriteBufferToMain (pDataFlash
, DB_BUF1_PAGE_PGM
, dest
);
557 return AT91C_DATAFLASH_ERROR
;
559 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
561 /* Update size, source and destination pointers */
562 size
-= pDataFlash
->pDevice
->pages_size
;
563 dest
+= pDataFlash
->pDevice
->pages_size
;
564 src
+= pDataFlash
->pDevice
->pages_size
;
567 /* If still some bytes to read */
569 /* program dataflash page */
570 if(!AT91F_PartialPageWrite(pDataFlash
, src
, dest
, size
) )
571 return AT91C_DATAFLASH_ERROR
;
572 AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
);
574 return AT91C_DATAFLASH_OK
;
579 /*------------------------------------------------------------------------------*/
580 /* Function Name : AT91F_DataFlashRead */
581 /* Object : Read a block in dataflash */
582 /* Input Parameters : */
584 /*------------------------------------------------------------------------------*/
585 int AT91F_DataFlashRead(
586 AT91PS_DataFlash pDataFlash
,
591 unsigned long SizeToRead
;
593 AT91F_SpiEnable(pDataFlash
->pDevice
->cs
);
595 if(AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
) != AT91C_DATAFLASH_OK
)
600 SizeToRead
= (size
< 0x8000)? size
:0x8000;
602 if (AT91F_DataFlashWaitReady(pDataFlash
->pDataFlashDesc
, AT91C_DATAFLASH_TIMEOUT
) != AT91C_DATAFLASH_OK
)
605 if (AT91F_DataFlashContinuousRead (pDataFlash
, addr
, (unsigned char *)buffer
, SizeToRead
) != AT91C_DATAFLASH_OK
)
610 buffer
+= SizeToRead
;
613 return AT91C_DATAFLASH_OK
;
617 /*------------------------------------------------------------------------------*/
618 /* Function Name : AT91F_DataflashProbe */
620 /* Input Parameters : */
621 /* Return value : Dataflash status register */
622 /*------------------------------------------------------------------------------*/
623 int AT91F_DataflashProbe(int cs
, AT91PS_DataflashDesc pDesc
)
626 AT91F_DataFlashGetStatus(pDesc
);
627 return ((pDesc
->command
[1] == 0xFF)? 0: (pDesc
->command
[1] & 0x3C));