We can now have u-boot on the second flash
[romboot.git] / at45.cpp
blob3d65b93c5ce0bbbe99fd6eee310410e39f7bcad4
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 //*----------------------------------------------------------------------------
17 #include <AT91RM9200.h>
18 #include <lib_AT91RM9200.h>
19 #include "dataflash.h"
20 #include "main.h"
22 #define AT91C_SPI_CLK 8000000
23 #define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */
24 #define AT91C_SPI_PCS1_SERIAL_DATAFLASH 0xD /* Chip Select 0 : NPCS0 %1101 */
25 #define AT91C_SPI_PCS2_SERIAL_DATAFLASH 0xB /* Chip Select 0 : NPCS0 %1011 */
26 #define AT91C_SPI_PCS3_SERIAL_DATAFLASH 0x7 /* Chip Select 0 : NPCS0 %0111 */
28 /*----------------------------------------------------------------------------*/
29 /* \fn AT91F_SpiInit */
30 /* \brief SPI Low level Init */
31 /*----------------------------------------------------------------------------*/
32 void AT91F_SpiInit(void) {
33 /* Configure PIOs */
34 AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
35 AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
36 AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
37 AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
38 /* Enable CLock */
39 AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
41 /* Reset the SPI */
42 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
44 /* Configure SPI in Master Mode with No CS selected !!! */
45 AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
47 /* Configure CS0 and CS3 */
48 *(AT91C_SPI_CSR + 0) = AT91C_SPI_NCPHA | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
49 *(AT91C_SPI_CSR + 1) = AT91C_SPI_NCPHA | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
50 *(AT91C_SPI_CSR + 2) = AT91C_SPI_NCPHA | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
51 *(AT91C_SPI_CSR + 3) = AT91C_SPI_NCPHA | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
56 /*----------------------------------------------------------------------------*/
57 /* \fn AT91F_SpiEnable */
58 /* \brief Enable SPI chip select */
59 /*----------------------------------------------------------------------------*/
60 void AT91F_SpiEnable(int cs) {
61 switch(cs) {
62 case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
63 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
64 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
65 break;
66 case 1: /* Configure SPI CS1 for Serial DataFlash AT45DBxx */
67 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
68 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS1_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
69 break;
70 case 2: /* Configure SPI CS2 for Serial DataFlash AT45DBxx */
71 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
72 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS2_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
73 break;
74 case 3: /* Configure SPI CS3 for Serial DataFlash AT45DBxx */
75 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
76 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
77 break;
78 #if 0
79 case 3: /* Configure SPI CS3 for Serial DataFlash Card */
80 /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
81 AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */
82 AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */
83 /* Clear Output */
84 AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
85 /* Configure PCS */
86 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
87 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
88 break;
89 #endif
92 /* SPI_Enable */
93 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
96 /*----------------------------------------------------------------------------*/
97 /* \fn AT91F_SpiWrite */
98 /* \brief Set the PDC registers for a transfert */
99 /*----------------------------------------------------------------------------*/
100 unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc)
102 unsigned int timeout;
104 pDesc->state = BUSY;
106 AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
108 /* Initialize the Transmit and Receive Pointer */
109 AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
110 AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
112 /* Intialize the Transmit and Receive Counters */
113 AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
114 AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
116 if ( pDesc->tx_data_size != 0 ) {
117 /* Initialize the Next Transmit and Next Receive Pointer */
118 AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
119 AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
121 /* Intialize the Next Transmit and Next Receive Counters */
122 AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
123 AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
126 /* arm simple, non interrupt dependent timer */
127 timeout = 0;
129 AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
130 while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF));
132 AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
133 pDesc->state = IDLE;
135 if (timeout >= AT91C_DATAFLASH_TIMEOUT){
136 return AT91C_DATAFLASH_ERROR;
139 return AT91C_DATAFLASH_OK;
143 /*----------------------------------------------------------------------*/
144 /* \fn AT91F_DataFlashSendCommand */
145 /* \brief Generic function to send a command to the dataflash */
146 /*----------------------------------------------------------------------*/
147 AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
148 AT91PS_DataFlash pDataFlash,
149 unsigned char OpCode,
150 unsigned int CmdSize,
151 unsigned int DataflashAddress)
153 unsigned int adr;
155 if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
156 return AT91C_DATAFLASH_BUSY;
158 /* process the address to obtain page address and byte address */
159 adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
161 /* fill the command buffer */
162 pDataFlash->pDataFlashDesc->command[0] = OpCode;
163 if (pDataFlash->pDevice->pages_number >= 16384)
165 pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
166 pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
167 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
168 pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
170 else
172 pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
173 pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
174 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
175 pDataFlash->pDataFlashDesc->command[4] = 0;
177 pDataFlash->pDataFlashDesc->command[5] = 0;
178 pDataFlash->pDataFlashDesc->command[6] = 0;
179 pDataFlash->pDataFlashDesc->command[7] = 0;
181 /* Initialize the SpiData structure for the spi write fuction */
182 pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
183 pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ;
184 pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
185 pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ;
187 return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
191 /*----------------------------------------------------------------------*/
192 /* \fn AT91F_DataFlashGetStatus */
193 /* \brief Read the status register of the dataflash */
194 /*----------------------------------------------------------------------*/
195 AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
197 AT91S_DataFlashStatus status;
199 /* if a transfert is in progress ==> return 0 */
200 if( (pDesc->state) != IDLE)
201 return AT91C_DATAFLASH_BUSY;
203 /* first send the read status command (D7H) */
204 pDesc->command[0] = DB_STATUS;
205 pDesc->command[1] = 0;
207 pDesc->DataFlash_state = GET_STATUS;
208 pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
209 pDesc->tx_cmd_pt = pDesc->command ;
210 pDesc->rx_cmd_pt = pDesc->command ;
211 pDesc->rx_cmd_size = 2 ;
212 pDesc->tx_cmd_size = 2 ;
213 status = AT91F_SpiWrite (pDesc);
215 pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
216 return status;
219 #if 0
220 /*----------------------------------------------------------------------*/
221 /* fn AT91F_DataFlashExtID */
222 /* brief Read the extended ID */
223 /*----------------------------------------------------------------------*/
224 AT91S_DataFlashStatus AT91F_DataFlashExtID(AT91PS_DataflashDesc pDesc)
226 AT91S_DataFlashStatus status;
228 /* if a transfert is in progress ==> return 0 */
229 if( (pDesc->state) != IDLE)
230 return AT91C_DATAFLASH_BUSY;
232 /* first send the read status command (D7H) */
233 pDesc->command[0] = 0x9F;
234 pDesc->command[1] = 0;
236 pDesc->DataFlash_state = GET_STATUS;
237 pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
238 pDesc->tx_cmd_pt = pDesc->command ;
239 pDesc->rx_cmd_pt = pDesc->command ;
240 pDesc->rx_cmd_size = 5 ;
241 pDesc->tx_cmd_size = 5 ;
242 status = AT91F_SpiWrite (pDesc);
244 pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
246 return status;
248 #endif
251 //*-----------------------------------------------------------------------------
252 //* Function Name : AT91F_DataFlashWaitReady
253 //* Object : wait for dataflash ready (bit7 of the status register == 1)
254 //* Input Parameters : DataFlash Service and timeout
255 //* Return value : DataFlash status "ready or not"
256 //*-----------------------------------------------------------------------------
257 AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
259 volatile unsigned int tick;
260 unsigned int NbTry = 0;
262 tick = GetTickCount();
264 while((pDataFlashDesc->state != IDLE) && ((volatile unsigned int)GetTickCount() < (tick + timeout)));
266 if(pDataFlashDesc->state != IDLE)
267 return AT91C_DATAFLASH_ERROR;
269 pDataFlashDesc->DataFlash_state = 0;
272 (volatile unsigned int)AT91F_DataFlashGetStatus(pDataFlashDesc);
273 if((pDataFlashDesc->DataFlash_state & 0x80) == 0x80)
274 return AT91C_DATAFLASH_OK;
276 while(1);
281 tick = GetTickCount();
282 AT91F_DataFlashGetStatus(pDataFlashDesc);
283 while((pDataFlashDesc->state != IDLE) && (GetTickCount() < (tick + 5)));
284 if((pDataFlashDesc->DataFlash_state & 0x80) == 0x80)
285 return AT91C_DATAFLASH_OK;
286 NbTry++;
288 while(NbTry < 1000);
291 return AT91C_DATAFLASH_ERROR;
301 /*------------------------------------------------------------------------------*/
302 /* Function Name : AT91F_DataFlashContinuousRead */
303 /* Object : Continuous stream Read */
304 /* Input Parameters : DataFlash Service */
305 /* : <src> = dataflash address */
306 /* : <*dataBuffer> = data buffer pointer */
307 /* : <sizeToRead> = data buffer size */
308 /* Return value : State of the dataflash */
309 /*------------------------------------------------------------------------------*/
310 AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
311 AT91PS_DataFlash pDataFlash,
312 int src,
313 unsigned char *dataBuffer,
314 int sizeToRead )
316 AT91S_DataFlashStatus status;
317 /* Test the size to read in the device */
318 if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
319 return AT91C_DATAFLASH_MEMORY_OVERFLOW;
321 pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
322 pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
323 pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
324 pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
326 status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
327 /* Send the command to the dataflash */
328 return(status);
333 /*------------------------------------------------------------------------------*/
334 /* Function Name : AT91F_MainMemoryToBufferTransfert */
335 /* Object : Read a page in the SRAM Buffer 1 or 2 */
336 /* Input Parameters : DataFlash Service */
337 /* : Page concerned */
338 /* : */
339 /* Return value : State of the dataflash */
340 /*------------------------------------------------------------------------------*/
341 AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
342 AT91PS_DataFlash pDataFlash,
343 unsigned char BufferCommand,
344 unsigned int page)
346 int cmdsize;
347 /* Test if the buffer command is legal */
348 if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
349 return AT91C_DATAFLASH_BAD_COMMAND;
351 /* no data to transmit or receive */
352 pDataFlash->pDataFlashDesc->tx_data_size = 0;
353 cmdsize = 4;
354 if (pDataFlash->pDevice->pages_number >= 16384)
355 cmdsize = 5;
356 return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, page*pDataFlash->pDevice->pages_size));
361 /*----------------------------------------------------------------------------- */
362 /* Function Name : AT91F_DataFlashWriteBuffer */
363 /* Object : Write data to the internal sram buffer 1 or 2 */
364 /* Input Parameters : DataFlash Service */
365 /* : <BufferCommand> = command to write buffer1 or buffer2 */
366 /* : <*dataBuffer> = data buffer to write */
367 /* : <bufferAddress> = address in the internal buffer */
368 /* : <SizeToWrite> = data buffer size */
369 /* Return value : State of the dataflash */
370 /*------------------------------------------------------------------------------*/
371 AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
372 AT91PS_DataFlash pDataFlash,
373 unsigned char BufferCommand,
374 unsigned char *dataBuffer,
375 unsigned int bufferAddress,
376 int SizeToWrite )
378 int cmdsize;
379 /* Test if the buffer command is legal */
380 if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
381 return AT91C_DATAFLASH_BAD_COMMAND;
383 /* buffer address must be lower than page size */
384 if (bufferAddress > pDataFlash->pDevice->pages_size)
385 return AT91C_DATAFLASH_BAD_ADDRESS;
387 if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
388 return AT91C_DATAFLASH_BUSY;
390 /* Send first Write Command */
391 pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
392 pDataFlash->pDataFlashDesc->command[1] = 0;
393 if (pDataFlash->pDevice->pages_number >= 16384)
395 pDataFlash->pDataFlashDesc->command[2] = 0;
396 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
397 pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
398 cmdsize = 5;
400 else
402 pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
403 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
404 pDataFlash->pDataFlashDesc->command[4] = 0;
405 cmdsize = 4;
408 pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
409 pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
410 pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
411 pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
413 pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
414 pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
415 pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ;
416 pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
418 return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
423 /*------------------------------------------------------------------------------*/
424 /* Function Name : AT91F_PageErase */
425 /* Object : Read a page in the SRAM Buffer 1 or 2 */
426 /* Input Parameters : DataFlash Service */
427 /* : Page concerned */
428 /* : */
429 /* Return value : State of the dataflash */
430 /*------------------------------------------------------------------------------*/
431 AT91S_DataFlashStatus AT91F_PageErase(
432 AT91PS_DataFlash pDataFlash,
433 unsigned int page)
435 int cmdsize;
436 /* Test if the buffer command is legal */
437 /* no data to transmit or receive */
438 pDataFlash->pDataFlashDesc->tx_data_size = 0;
440 cmdsize = 4;
441 if (pDataFlash->pDevice->pages_number >= 16384)
442 cmdsize = 5;
443 return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, page*pDataFlash->pDevice->pages_size));
448 /*------------------------------------------------------------------------------*/
449 /* Function Name : AT91F_WriteBufferToMain */
450 /* Object : Write buffer to the main memory */
451 /* Input Parameters : DataFlash Service */
452 /* : <BufferCommand> = command to send to buffer1 or buffer2 */
453 /* : <dest> = main memory address */
454 /* Return value : State of the dataflash */
455 /*------------------------------------------------------------------------------*/
456 AT91S_DataFlashStatus AT91F_WriteBufferToMain (
457 AT91PS_DataFlash pDataFlash,
458 unsigned char BufferCommand,
459 unsigned int dest )
461 int cmdsize;
462 /* Test if the buffer command is correct */
463 if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
464 (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
465 (BufferCommand != DB_BUF2_PAGE_PGM) &&
466 (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
467 return AT91C_DATAFLASH_BAD_COMMAND;
469 /* no data to transmit or receive */
470 pDataFlash->pDataFlashDesc->tx_data_size = 0;
472 cmdsize = 4;
473 if (pDataFlash->pDevice->pages_number >= 16384)
474 cmdsize = 5;
475 /* Send the command to the dataflash */
476 return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
480 /*------------------------------------------------------------------------------*/
481 /* Function Name : AT91F_PartialPageWrite */
482 /* Object : Erase partielly a page */
483 /* Input Parameters : <page> = page number */
484 /* : <AdrInpage> = adr to begin the fading */
485 /* : <length> = Number of bytes to erase */
486 /*------------------------------------------------------------------------------*/
487 AT91S_DataFlashStatus AT91F_PartialPageWrite (
488 AT91PS_DataFlash pDataFlash,
489 unsigned char *src,
490 unsigned int dest,
491 unsigned int size)
493 unsigned int page;
494 unsigned int AdrInPage;
496 page = dest / (pDataFlash->pDevice->pages_size);
497 AdrInPage = dest % (pDataFlash->pDevice->pages_size);
499 /* Read the contents of the page in the Sram Buffer */
500 AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
501 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
503 /*Update the SRAM buffer */
504 AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
505 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
507 /* Erase page if a 128 Mbits device */
508 if (pDataFlash->pDevice->pages_number >= 16384)
510 AT91F_PageErase(pDataFlash, page);
511 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
514 /* Rewrite the modified Sram Buffer in the main memory */
515 return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
520 /*------------------------------------------------------------------------------*/
521 /* Function Name : AT91F_DataFlashWrite */
522 /* Object : */
523 /* Input Parameters : <*src> = Source buffer */
524 /* : <dest> = dataflash adress */
525 /* : <size> = data buffer size */
526 /*------------------------------------------------------------------------------*/
527 AT91S_DataFlashStatus AT91F_DataFlashWrite(
528 AT91PS_DataFlash pDataFlash,
529 unsigned char *src,
530 int dest,
531 int size )
533 unsigned int length;
534 unsigned int page;
535 unsigned int status;
537 AT91F_SpiEnable(pDataFlash->pDevice->cs);
539 if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
540 return AT91C_DATAFLASH_MEMORY_OVERFLOW;
542 /* If destination does not fit a page start address */
543 if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) {
544 length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
546 if (size < length)
547 length = size;
549 if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
550 return AT91C_DATAFLASH_ERROR;
552 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
554 /* Update size, source and destination pointers */
555 size -= length;
556 dest += length;
557 src += length;
560 while (( size - pDataFlash->pDevice->pages_size ) >= 0 )
562 /* program dataflash page */
563 page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
565 status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 0, pDataFlash->pDevice->pages_size);
566 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
568 status = AT91F_PageErase(pDataFlash, page);
569 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
570 if (!status)
571 return AT91C_DATAFLASH_ERROR;
573 status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
574 if(!status)
575 return AT91C_DATAFLASH_ERROR;
577 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
579 /* Update size, source and destination pointers */
580 size -= pDataFlash->pDevice->pages_size ;
581 dest += pDataFlash->pDevice->pages_size ;
582 src += pDataFlash->pDevice->pages_size ;
585 /* If still some bytes to read */
586 if ( size > 0 ) {
587 /* program dataflash page */
588 if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
589 return AT91C_DATAFLASH_ERROR;
590 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
592 return AT91C_DATAFLASH_OK;
597 /*------------------------------------------------------------------------------*/
598 /* Function Name : AT91F_DataFlashRead */
599 /* Object : Read a block in dataflash */
600 /* Input Parameters : */
601 /* Return value : */
602 /*------------------------------------------------------------------------------*/
603 int AT91F_DataFlashRead(
604 AT91PS_DataFlash pDataFlash,
605 unsigned long addr,
606 unsigned long size,
607 char *buffer)
609 unsigned long SizeToRead;
611 AT91F_SpiEnable(pDataFlash->pDevice->cs);
613 if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
614 return -1;
616 while (size)
618 SizeToRead = (size < 0x8000)? size:0x8000;
620 if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
621 return -1;
623 if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer, SizeToRead) != AT91C_DATAFLASH_OK)
624 return -1;
626 size -= SizeToRead;
627 addr += SizeToRead;
628 buffer += SizeToRead;
631 return AT91C_DATAFLASH_OK;
635 /*------------------------------------------------------------------------------*/
636 /* Function Name : AT91F_DataflashProbe */
637 /* Object : */
638 /* Input Parameters : */
639 /* Return value : Dataflash status register */
640 /*------------------------------------------------------------------------------*/
641 int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
643 AT91F_SpiEnable(cs);
644 AT91F_DataFlashGetStatus(pDesc);
645 return ((pDesc->command[1] == 0xFF)? 0: (pDesc->command[1] & 0x3C));