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