Call AT91F_InitUdp to disable usb clock
[romboot.git] / at45.cpp
blob2fdc8de839038c442dace58070c798a4e115deb4
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_SpiDisable() {
61 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
64 void AT91F_SpiEnable(int cs) {
65 switch(cs) {
66 case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
67 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
68 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
69 break;
70 case 1: /* Configure SPI CS1 for Serial DataFlash AT45DBxx */
71 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
72 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS1_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
73 break;
74 case 2: /* Configure SPI CS2 for Serial DataFlash AT45DBxx */
75 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
76 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS2_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
77 break;
78 case 3: /* Configure SPI CS3 for Serial DataFlash AT45DBxx */
79 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
80 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
81 break;
82 #if 0
83 case 3: /* Configure SPI CS3 for Serial DataFlash Card */
84 /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
85 AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */
86 AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */
87 /* Clear Output */
88 AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
89 /* Configure PCS */
90 AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
91 AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
92 break;
93 #endif
96 /* SPI_Enable */
97 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
100 /*----------------------------------------------------------------------------*/
101 /* \fn AT91F_SpiWrite */
102 /* \brief Set the PDC registers for a transfert */
103 /*----------------------------------------------------------------------------*/
104 unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc)
106 unsigned int timeout;
108 pDesc->state = BUSY;
110 AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
112 /* Initialize the Transmit and Receive Pointer */
113 AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
114 AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
116 /* Intialize the Transmit and Receive Counters */
117 AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
118 AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
120 if ( pDesc->tx_data_size != 0 ) {
121 /* Initialize the Next Transmit and Next Receive Pointer */
122 AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
123 AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
125 /* Intialize the Next Transmit and Next Receive Counters */
126 AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
127 AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
130 /* arm simple, non interrupt dependent timer */
131 timeout = 0;
133 AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
134 while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF));
136 AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
137 pDesc->state = IDLE;
139 if (timeout >= AT91C_DATAFLASH_TIMEOUT){
140 return AT91C_DATAFLASH_ERROR;
143 return AT91C_DATAFLASH_OK;
147 /*----------------------------------------------------------------------*/
148 /* \fn AT91F_DataFlashSendCommand */
149 /* \brief Generic function to send a command to the dataflash */
150 /*----------------------------------------------------------------------*/
151 AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
152 AT91PS_DataFlash pDataFlash,
153 unsigned char OpCode,
154 unsigned int CmdSize,
155 unsigned int DataflashAddress)
157 unsigned int adr;
159 if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
160 return AT91C_DATAFLASH_BUSY;
162 /* process the address to obtain page address and byte address */
163 adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
165 /* fill the command buffer */
166 pDataFlash->pDataFlashDesc->command[0] = OpCode;
167 if (pDataFlash->pDevice->pages_number >= 16384)
169 pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
170 pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
171 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
172 pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
174 else
176 pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
177 pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
178 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
179 pDataFlash->pDataFlashDesc->command[4] = 0;
181 pDataFlash->pDataFlashDesc->command[5] = 0;
182 pDataFlash->pDataFlashDesc->command[6] = 0;
183 pDataFlash->pDataFlashDesc->command[7] = 0;
185 /* Initialize the SpiData structure for the spi write fuction */
186 pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
187 pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ;
188 pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
189 pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ;
191 return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
195 /*----------------------------------------------------------------------*/
196 /* \fn AT91F_DataFlashGetStatus */
197 /* \brief Read the status register of the dataflash */
198 /*----------------------------------------------------------------------*/
199 AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
201 AT91S_DataFlashStatus status;
203 /* if a transfert is in progress ==> return 0 */
204 if( (pDesc->state) != IDLE)
205 return AT91C_DATAFLASH_BUSY;
207 /* first send the read status command (D7H) */
208 pDesc->command[0] = DB_STATUS;
209 pDesc->command[1] = 0;
211 pDesc->DataFlash_state = GET_STATUS;
212 pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
213 pDesc->tx_cmd_pt = pDesc->command ;
214 pDesc->rx_cmd_pt = pDesc->command ;
215 pDesc->rx_cmd_size = 2 ;
216 pDesc->tx_cmd_size = 2 ;
217 status = AT91F_SpiWrite (pDesc);
219 pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
220 return status;
223 #if 0
224 /*----------------------------------------------------------------------*/
225 /* fn AT91F_DataFlashExtID */
226 /* brief Read the extended ID */
227 /*----------------------------------------------------------------------*/
228 AT91S_DataFlashStatus AT91F_DataFlashExtID(AT91PS_DataflashDesc pDesc)
230 AT91S_DataFlashStatus status;
232 /* if a transfert is in progress ==> return 0 */
233 if( (pDesc->state) != IDLE)
234 return AT91C_DATAFLASH_BUSY;
236 /* first send the read status command (D7H) */
237 pDesc->command[0] = 0x9F;
238 pDesc->command[1] = 0;
240 pDesc->DataFlash_state = GET_STATUS;
241 pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */
242 pDesc->tx_cmd_pt = pDesc->command ;
243 pDesc->rx_cmd_pt = pDesc->command ;
244 pDesc->rx_cmd_size = 5 ;
245 pDesc->tx_cmd_size = 5 ;
246 status = AT91F_SpiWrite (pDesc);
248 pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
250 return status;
252 #endif
255 //*-----------------------------------------------------------------------------
256 //* Function Name : AT91F_DataFlashWaitReady
257 //* Object : wait for dataflash ready (bit7 of the status register == 1)
258 //* Input Parameters : DataFlash Service and timeout
259 //* Return value : DataFlash status "ready or not"
260 //*-----------------------------------------------------------------------------
261 AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
263 volatile unsigned int tick;
264 unsigned int NbTry = 0;
266 tick = GetTickCount();
268 while((pDataFlashDesc->state != IDLE) && ((volatile unsigned int)GetTickCount() < (tick + timeout)));
270 if(pDataFlashDesc->state != IDLE)
271 return AT91C_DATAFLASH_ERROR;
273 pDataFlashDesc->DataFlash_state = 0;
276 (volatile unsigned int)AT91F_DataFlashGetStatus(pDataFlashDesc);
277 if((pDataFlashDesc->DataFlash_state & 0x80) == 0x80)
278 return AT91C_DATAFLASH_OK;
280 while(1);
285 tick = GetTickCount();
286 AT91F_DataFlashGetStatus(pDataFlashDesc);
287 while((pDataFlashDesc->state != IDLE) && (GetTickCount() < (tick + 5)));
288 if((pDataFlashDesc->DataFlash_state & 0x80) == 0x80)
289 return AT91C_DATAFLASH_OK;
290 NbTry++;
292 while(NbTry < 1000);
295 return AT91C_DATAFLASH_ERROR;
305 /*------------------------------------------------------------------------------*/
306 /* Function Name : AT91F_DataFlashContinuousRead */
307 /* Object : Continuous stream Read */
308 /* Input Parameters : DataFlash Service */
309 /* : <src> = dataflash address */
310 /* : <*dataBuffer> = data buffer pointer */
311 /* : <sizeToRead> = data buffer size */
312 /* Return value : State of the dataflash */
313 /*------------------------------------------------------------------------------*/
314 AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
315 AT91PS_DataFlash pDataFlash,
316 int src,
317 unsigned char *dataBuffer,
318 int sizeToRead )
320 AT91S_DataFlashStatus status;
321 /* Test the size to read in the device */
322 if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
323 return AT91C_DATAFLASH_MEMORY_OVERFLOW;
325 pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
326 pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
327 pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
328 pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
330 status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
331 /* Send the command to the dataflash */
332 return(status);
337 /*------------------------------------------------------------------------------*/
338 /* Function Name : AT91F_MainMemoryToBufferTransfert */
339 /* Object : Read a page in the SRAM Buffer 1 or 2 */
340 /* Input Parameters : DataFlash Service */
341 /* : Page concerned */
342 /* : */
343 /* Return value : State of the dataflash */
344 /*------------------------------------------------------------------------------*/
345 AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
346 AT91PS_DataFlash pDataFlash,
347 unsigned char BufferCommand,
348 unsigned int page)
350 int cmdsize;
351 /* Test if the buffer command is legal */
352 if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
353 return AT91C_DATAFLASH_BAD_COMMAND;
355 /* no data to transmit or receive */
356 pDataFlash->pDataFlashDesc->tx_data_size = 0;
357 cmdsize = 4;
358 if (pDataFlash->pDevice->pages_number >= 16384)
359 cmdsize = 5;
360 return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, page*pDataFlash->pDevice->pages_size));
365 /*----------------------------------------------------------------------------- */
366 /* Function Name : AT91F_DataFlashWriteBuffer */
367 /* Object : Write data to the internal sram buffer 1 or 2 */
368 /* Input Parameters : DataFlash Service */
369 /* : <BufferCommand> = command to write buffer1 or buffer2 */
370 /* : <*dataBuffer> = data buffer to write */
371 /* : <bufferAddress> = address in the internal buffer */
372 /* : <SizeToWrite> = data buffer size */
373 /* Return value : State of the dataflash */
374 /*------------------------------------------------------------------------------*/
375 AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
376 AT91PS_DataFlash pDataFlash,
377 unsigned char BufferCommand,
378 unsigned char *dataBuffer,
379 unsigned int bufferAddress,
380 int SizeToWrite )
382 int cmdsize;
383 /* Test if the buffer command is legal */
384 if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
385 return AT91C_DATAFLASH_BAD_COMMAND;
387 /* buffer address must be lower than page size */
388 if (bufferAddress > pDataFlash->pDevice->pages_size)
389 return AT91C_DATAFLASH_BAD_ADDRESS;
391 if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
392 return AT91C_DATAFLASH_BUSY;
394 /* Send first Write Command */
395 pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
396 pDataFlash->pDataFlashDesc->command[1] = 0;
397 if (pDataFlash->pDevice->pages_number >= 16384)
399 pDataFlash->pDataFlashDesc->command[2] = 0;
400 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
401 pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
402 cmdsize = 5;
404 else
406 pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
407 pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
408 pDataFlash->pDataFlashDesc->command[4] = 0;
409 cmdsize = 4;
412 pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
413 pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
414 pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
415 pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
417 pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
418 pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
419 pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ;
420 pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
422 return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
427 /*------------------------------------------------------------------------------*/
428 /* Function Name : AT91F_PageErase */
429 /* Object : Read a page in the SRAM Buffer 1 or 2 */
430 /* Input Parameters : DataFlash Service */
431 /* : Page concerned */
432 /* : */
433 /* Return value : State of the dataflash */
434 /*------------------------------------------------------------------------------*/
435 AT91S_DataFlashStatus AT91F_PageErase(
436 AT91PS_DataFlash pDataFlash,
437 unsigned int page)
439 int cmdsize;
440 /* Test if the buffer command is legal */
441 /* no data to transmit or receive */
442 pDataFlash->pDataFlashDesc->tx_data_size = 0;
444 cmdsize = 4;
445 if (pDataFlash->pDevice->pages_number >= 16384)
446 cmdsize = 5;
447 return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, page*pDataFlash->pDevice->pages_size));
452 /*------------------------------------------------------------------------------*/
453 /* Function Name : AT91F_WriteBufferToMain */
454 /* Object : Write buffer to the main memory */
455 /* Input Parameters : DataFlash Service */
456 /* : <BufferCommand> = command to send to buffer1 or buffer2 */
457 /* : <dest> = main memory address */
458 /* Return value : State of the dataflash */
459 /*------------------------------------------------------------------------------*/
460 AT91S_DataFlashStatus AT91F_WriteBufferToMain (
461 AT91PS_DataFlash pDataFlash,
462 unsigned char BufferCommand,
463 unsigned int dest )
465 int cmdsize;
466 /* Test if the buffer command is correct */
467 if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
468 (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
469 (BufferCommand != DB_BUF2_PAGE_PGM) &&
470 (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
471 return AT91C_DATAFLASH_BAD_COMMAND;
473 /* no data to transmit or receive */
474 pDataFlash->pDataFlashDesc->tx_data_size = 0;
476 cmdsize = 4;
477 if (pDataFlash->pDevice->pages_number >= 16384)
478 cmdsize = 5;
479 /* Send the command to the dataflash */
480 return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
484 /*------------------------------------------------------------------------------*/
485 /* Function Name : AT91F_PartialPageWrite */
486 /* Object : Erase partielly a page */
487 /* Input Parameters : <page> = page number */
488 /* : <AdrInpage> = adr to begin the fading */
489 /* : <length> = Number of bytes to erase */
490 /*------------------------------------------------------------------------------*/
491 AT91S_DataFlashStatus AT91F_PartialPageWrite (
492 AT91PS_DataFlash pDataFlash,
493 unsigned char *src,
494 unsigned int dest,
495 unsigned int size)
497 unsigned int page;
498 unsigned int AdrInPage;
500 page = dest / (pDataFlash->pDevice->pages_size);
501 AdrInPage = dest % (pDataFlash->pDevice->pages_size);
503 /* Read the contents of the page in the Sram Buffer */
504 AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
505 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
507 /*Update the SRAM buffer */
508 AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
509 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
511 /* Erase page if a 128 Mbits device */
512 if (pDataFlash->pDevice->pages_number >= 16384)
514 AT91F_PageErase(pDataFlash, page);
515 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
518 /* Rewrite the modified Sram Buffer in the main memory */
519 return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
524 /*------------------------------------------------------------------------------*/
525 /* Function Name : AT91F_DataFlashWrite */
526 /* Object : */
527 /* Input Parameters : <*src> = Source buffer */
528 /* : <dest> = dataflash adress */
529 /* : <size> = data buffer size */
530 /*------------------------------------------------------------------------------*/
531 AT91S_DataFlashStatus AT91F_DataFlashWrite(
532 AT91PS_DataFlash pDataFlash,
533 unsigned char *src,
534 int dest,
535 int size )
537 unsigned int length;
538 unsigned int page;
539 unsigned int status;
541 AT91F_SpiEnable(pDataFlash->pDevice->cs);
543 if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
544 return AT91C_DATAFLASH_MEMORY_OVERFLOW;
546 /* If destination does not fit a page start address */
547 if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) {
548 length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
550 if (size < length)
551 length = size;
553 if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
554 return AT91C_DATAFLASH_ERROR;
556 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
558 /* Update size, source and destination pointers */
559 size -= length;
560 dest += length;
561 src += length;
564 while (( size - pDataFlash->pDevice->pages_size ) >= 0 )
566 /* program dataflash page */
567 page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
569 status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 0, pDataFlash->pDevice->pages_size);
570 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
572 status = AT91F_PageErase(pDataFlash, page);
573 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
574 if (!status)
575 return AT91C_DATAFLASH_ERROR;
577 status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
578 if(!status)
579 return AT91C_DATAFLASH_ERROR;
581 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
583 /* Update size, source and destination pointers */
584 size -= pDataFlash->pDevice->pages_size ;
585 dest += pDataFlash->pDevice->pages_size ;
586 src += pDataFlash->pDevice->pages_size ;
589 /* If still some bytes to read */
590 if ( size > 0 ) {
591 /* program dataflash page */
592 if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
593 return AT91C_DATAFLASH_ERROR;
594 AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT);
596 return AT91C_DATAFLASH_OK;
601 /*------------------------------------------------------------------------------*/
602 /* Function Name : AT91F_DataFlashRead */
603 /* Object : Read a block in dataflash */
604 /* Input Parameters : */
605 /* Return value : */
606 /*------------------------------------------------------------------------------*/
607 int AT91F_DataFlashRead(
608 AT91PS_DataFlash pDataFlash,
609 unsigned long addr,
610 unsigned long size,
611 char *buffer)
613 unsigned long SizeToRead;
615 AT91F_SpiEnable(pDataFlash->pDevice->cs);
617 if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
618 return -1;
620 while (size)
622 SizeToRead = (size < 0x8000)? size:0x8000;
624 if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
625 return -1;
627 if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer, SizeToRead) != AT91C_DATAFLASH_OK)
628 return -1;
630 size -= SizeToRead;
631 addr += SizeToRead;
632 buffer += SizeToRead;
635 return AT91C_DATAFLASH_OK;
639 /*------------------------------------------------------------------------------*/
640 /* Function Name : AT91F_DataflashProbe */
641 /* Object : */
642 /* Input Parameters : */
643 /* Return value : Dataflash status register */
644 /*------------------------------------------------------------------------------*/
645 int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
647 AT91F_SpiEnable(cs);
648 AT91F_DataFlashGetStatus(pDesc);
649 return ((pDesc->command[1] == 0xFF)? 0: (pDesc->command[1] & 0x3C));