00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #include <board.h>
00073 #include <assert.h>
00074 #include "stdlib.h"
00075 #include "string.h"
00076
00077
00078
00079
00080
00081 static QspiInstFrame_t *pDev, *pMem;
00082
00083 static QspiDma_t qspiDma;
00084 static sXdmad qspiDmaInst;
00085
00086
00087
00088
00089
00090 #define READ_DEV 0
00091 #define WRITE_DEV 1
00092
00093 #define PAGE_SIZE 256
00094
00095
00096
00097 void XDMAC_Handler(void)
00098 {
00099 XDMAD_Handler(&qspiDmaInst);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 static uint8_t S25FL1D_SendCommand(uint8_t Instr, uint32_t *pTxData,
00112 uint32_t *pRxData, Access_t ReadWrite, uint32_t size)
00113 {
00114 qspiDma.Qspid.qspiCommand.Instruction = Instr;
00115
00116 if(qspiDma.Qspid.qspiMode) {
00117 pDev->InstFrame.bm.bInstEn = 1;
00118 qspiDma.Qspid.pQspiFrame = pDev;
00119 qspiDma.Qspid.qspiBuffer.pDataTx = pTxData;
00120 qspiDma.Qspid.qspiBuffer.pDataRx = pRxData;
00121
00122
00123 if( (size % sizeof(uint32_t)) && size > 1) {
00124 size += (sizeof(uint32_t) - (size % sizeof(uint32_t)));
00125 }
00126
00127 if(ReadWrite == CmdAccess) {
00128 pDev->InstFrame.bm.bXfrType
00129 = (QSPI_IFR_TFRTYP_TRSFR_READ >> QSPI_IFR_TFRTYP_Pos);
00130 pDev->InstFrame.bm.bDataEn = 0;
00131
00132 QSPI_SendCommand(&qspiDma.Qspid, 0);
00133
00134 } else if (ReadWrite == WriteAccess) {
00135 pDev->InstFrame.bm.bDataEn = 1;
00136 pDev->InstFrame.bm.bXfrType
00137 = (QSPI_IFR_TFRTYP_TRSFR_WRITE >> QSPI_IFR_TFRTYP_Pos);
00138 qspiDma.Qspid.qspiBuffer.TxDataSize = size;
00139 QSPI_SendCommandWithData(&qspiDma.Qspid, 0);
00140
00141 } else {
00142 pDev->InstFrame.bm.bXfrType
00143 = (QSPI_IFR_TFRTYP_TRSFR_READ >> QSPI_IFR_TFRTYP_Pos);
00144 pDev->InstFrame.bm.bDataEn = 1;
00145 qspiDma.Qspid.qspiBuffer.RxDataSize = size;
00146 QSPI_ReadCommand(&qspiDma.Qspid, 0);
00147 }
00148 } else {
00149 if((ReadWrite == CmdAccess) || (ReadWrite == WriteAccess)) {
00150 qspiDma.Qspid.qspiBuffer.pDataTx = malloc(size+1);
00151 qspiDma.Qspid.qspiBuffer.pDataTx[0]
00152 = qspiDma.Qspid.qspiCommand.Instruction;
00153 if(size) {
00154 memcpy(&qspiDma.Qspid.qspiBuffer.pDataTx[1], pTxData, size);
00155 }
00156 qspiDma.Qspid.qspiBuffer.TxDataSize = size+1;
00157
00158 QSPI_MultiWriteSPI(&qspiDma.Qspid,
00159 (uint16_t const*)qspiDma.Qspid.qspiBuffer.pDataTx,
00160 qspiDma.Qspid.qspiBuffer.TxDataSize);
00161
00162 free(qspiDma.Qspid.qspiBuffer.pDataTx);
00163 } else if (ReadWrite == ReadAccess) {
00164 qspiDma.Qspid.qspiBuffer.pDataRx = pRxData;
00165 QSPI_SingleWriteSPI(&qspiDma.Qspid,
00166 (uint16_t const*)&qspiDma.Qspid.qspiCommand.Instruction);
00167 QSPI_MultiReadSPI(&qspiDma.Qspid,
00168 (uint16_t *)qspiDma.Qspid.qspiBuffer.pDataRx, size);
00169 } else {
00170 TRACE_ERROR("%s Wrong access parameter \n\r", __FUNCTION__);
00171 }
00172 QSPI_EndTransfer(qspiDma.Qspid.pQspiHw);
00173 }
00174 return 0;
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 static uint8_t S25FL1D_MemoryAccess(uint8_t Instr, uint32_t Addr,
00188 uint32_t *pTxData, uint32_t *pRxData, Access_t ReadWrite,
00189 uint32_t size, uint8_t Secure)
00190 {
00191 uint8_t SpiBuffer[4];
00192 qspiDma.Qspid.qspiCommand.Instruction = Instr;
00193
00194 if(qspiDma.Qspid.qspiMode) {
00195 qspiDma.Qspid.qspiBuffer.pDataTx = pTxData;
00196 qspiDma.Qspid.qspiBuffer.pDataRx = pRxData;
00197 pMem->Addr=Addr;
00198 pMem->InstFrame.bm.bInstEn = 1;
00199 pMem->InstFrame.bm.bDataEn = 1;
00200 pMem->InstFrame.bm.bAddrEn = 1;
00201 qspiDma.Qspid.pQspiFrame = pMem;
00202 if (ReadWrite == WriteAccess) {
00203 pMem->InstFrame.bm.bXfrType
00204 = (QSPI_IFR_TFRTYP_TRSFR_WRITE_MEMORY >> QSPI_IFR_TFRTYP_Pos);
00205 qspiDma.Qspid.qspiBuffer.TxDataSize = size;
00206 } else {
00207 pMem->InstFrame.bm.bXfrType
00208 = (QSPI_IFR_TFRTYP_TRSFR_READ_MEMORY >> QSPI_IFR_TFRTYP_Pos);
00209 qspiDma.Qspid.qspiBuffer.RxDataSize = size;
00210 }
00211 QSPI_EnableMemAccess(&qspiDma.Qspid, 0, Secure);
00212 #ifdef USE_QSPI_DMA
00213 QSPID_ReadWriteQSPI(&qspiDma, ReadWrite);
00214 #else
00215 QSPI_ReadWriteMem(&qspiDma.Qspid, ReadWrite);
00216 #endif
00217 } else {
00218 qspiDma.Qspid.qspiBuffer.pDataTx = malloc((size+4));
00219 SpiBuffer[0] = Instr;
00220 SpiBuffer[1] = (uint8_t)(Addr >> 16);
00221 SpiBuffer[2] = (uint8_t)(Addr >> 8);
00222 SpiBuffer[3] = (uint8_t)(Addr);
00223 memcpy(qspiDma.Qspid.qspiBuffer.pDataTx, SpiBuffer, 4);
00224 if(pTxData !=NULL) {
00225 memcpy((qspiDma.Qspid.qspiBuffer.pDataTx+1), pTxData, size);
00226 }
00227
00228 if (ReadWrite == WriteAccess) {
00229 qspiDma.Qspid.qspiBuffer.TxDataSize = size+4;
00230 #ifdef USE_QSPI_DMA
00231 qspiDma.Qspid.qspiBuffer.RxDataSize = size+4;
00232 qspiDma.Qspid.qspiBuffer.pDataRx = qspiDma.Qspid.qspiBuffer.pDataTx;
00233 QSPID_ReadWriteSPI(&qspiDma, ReadWrite);
00234 #else
00235
00236 QSPI_MultiWriteSPI(&qspiDma.Qspid,
00237 (uint16_t *)qspiDma.Qspid.qspiBuffer.pDataTx,
00238 qspiDma.Qspid.qspiBuffer.TxDataSize);
00239 #endif
00240 } else {
00241 #ifdef USE_QSPI_DMA
00242 qspiDma.Qspid.qspiBuffer.pDataRx = pRxData;
00243
00244 qspiDma.Qspid.qspiBuffer.RxDataSize = size+6;
00245 qspiDma.Qspid.qspiBuffer.TxDataSize = size+6;
00246 QSPID_ReadWriteSPI(&qspiDma, ReadWrite);
00247 while(qspiDma.progress);
00248
00249
00250
00251
00252 #else
00253 qspiDma.Qspid.qspiBuffer.pDataRx = pRxData;
00254 qspiDma.Qspid.qspiBuffer.RxDataSize = size;
00255 qspiDma.Qspid.qspiBuffer.TxDataSize = 4;
00256 QSPI_MultiWriteSPI(&qspiDma.Qspid,
00257 (uint16_t *)qspiDma.Qspid.qspiBuffer.pDataTx,
00258 qspiDma.Qspid.qspiBuffer.TxDataSize);
00259 QSPI_MultiReadSPI(&qspiDma.Qspid,
00260 (uint16_t *)qspiDma.Qspid.qspiBuffer.pDataRx,
00261 size);
00262 QSPI_EndTransfer(qspiDma.Qspid.pQspiHw);
00263 #endif
00264 }
00265 free(qspiDma.Qspid.qspiBuffer.pDataTx);
00266 qspiDma.Qspid.qspiBuffer.pDataTx= NULL;
00267 }
00268 return 0;
00269 }
00270
00271
00272
00273
00274
00275
00276 static uint32_t S25FL1D_ReadStatus(void)
00277 {
00278 uint32_t status, ReadStatus;
00279
00280 S25FL1D_SendCommand(READ_STATUS_1, 0, &ReadStatus, ReadAccess, 1);
00281 status = ReadStatus;
00282
00283 S25FL1D_SendCommand(READ_STATUS_2, 0, &ReadStatus, ReadAccess, 1);
00284 status |= ((ReadStatus << 8) & 0xFF00);
00285
00286 S25FL1D_SendCommand(READ_STATUS_3, 0, &ReadStatus, ReadAccess, 1);
00287 status |= ((ReadStatus << 16) & 0xFF0000);
00288 return status;
00289 }
00290
00291
00292
00293
00294
00295
00296 static uint8_t S25FL1D_ReadStatus1(void)
00297 {
00298 uint8_t status;
00299 S25FL1D_SendCommand(READ_STATUS_1, 0, (uint32_t *)&status, ReadAccess, 1);
00300 return status;
00301 }
00302
00303
00304
00305
00306
00307
00308 static uint8_t S25FL1D_ReadStatus2(void)
00309 {
00310 uint8_t status;
00311 S25FL1D_SendCommand(READ_STATUS_2, 0, (uint32_t *)&status, ReadAccess, 1);
00312 return status;
00313 }
00314
00315
00316
00317
00318
00319
00320 static uint8_t S25FL1D_ReadStatus3(void)
00321 {
00322 uint8_t status;
00323 S25FL1D_SendCommand(READ_STATUS_3, 0, (uint32_t *)&status, ReadAccess, 1);
00324 return status;
00325 }
00326
00327
00328
00329
00330
00331
00332 static void S25FL1D_IsBusy(void)
00333 {
00334 #ifdef USE_QSPI_DMA
00335 while(QSPID_IsBusy(&qspiDma.progress) ) {
00336 Wait(1);
00337 }
00338 #endif
00339 while(S25FL1D_ReadStatus1() & STATUS_RDYBSY);
00340 }
00341
00342 static void S25FL1D_EnableWrite(void)
00343 {
00344 uint8_t status = 0;
00345
00346
00347 while(!(status & STATUS_WEL)) {
00348 S25FL1D_SendCommand(WRITE_ENABLE, 0, 0, CmdAccess, 0);
00349 status = S25FL1D_ReadStatus1();
00350 }
00351 }
00352
00353
00354 static void S25FL1D_DisableWrite(void)
00355 {
00356 uint8_t status;
00357
00358 status = S25FL1D_ReadStatus1();
00359
00360 while( (status & STATUS_WEL) != 0) {
00361 S25FL1D_SendCommand(WRITE_DISABLE, 0, 0, CmdAccess, 0);
00362 status = S25FL1D_ReadStatus1();
00363 }
00364 }
00365
00366
00367
00368
00369
00370
00371
00372 static void S25FL1D_WriteStatus( uint8_t *pStatus)
00373 {
00374 S25FL1D_EnableWrite();
00375
00376 S25FL1D_SendCommand(WRITE_STATUS, (uint32_t *)pStatus, 0, WriteAccess, 3);
00377
00378 S25FL1D_DisableWrite();
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388 static void S25FL1D_WriteVolatileStatus( uint8_t *pStatus)
00389 {
00390 uint32_t DataWr = 0;
00391 DataWr = *pStatus;
00392
00393 S25FL1D_SendCommand(0x50, 0, 0 , CmdAccess, 0);
00394
00395 S25FL1D_SendCommand(WRITE_STATUS,&DataWr, 0 , WriteAccess, 3);
00396 S25FL1D_DisableWrite();
00397 }
00398
00399
00400 static uint8_t S25FL1D_CheckProtectedAddr(uint8_t Status1, uint32_t Addr)
00401 {
00402 const uint32_t AddrJump
00403 = (Status1 & SEC_PROTECT_Msk) ? 0x001000UL : 0x010000UL;
00404 static uint8_t Protected = 0;
00405
00406 const uint8_t blockBits = ((Status1 & BLOCK_PROTECT_Msk) >> 2);
00407
00408 switch(blockBits) {
00409 case 1:
00410 if (Status1 & TOP_BTM_PROTECT_Msk) {
00411 if( ( Addr > 0x000000) && ( Addr < (0x000000 + AddrJump - 1) ) ) {
00412 Protected = 1;
00413 }
00414 } else {
00415 if( ( Addr > (0x1FFFFF - AddrJump + 1) ) && ( Addr < 0x1FFFFF ) ) {
00416 Protected = 1;
00417 }
00418 }
00419 break;
00420
00421 case 2:
00422 if (Status1 & TOP_BTM_PROTECT_Msk) {
00423 if( ( Addr > 0x000000) && ( Addr < (0x000000 + (2* AddrJump)- 1 )) ) {
00424 Protected = 1;
00425 }
00426 } else {
00427 if( ( Addr > (0x1FFFFF - ( 2*AddrJump ) + 1) ) && ( Addr < 0x1FFFFF ) ){
00428 Protected = 1;
00429 }
00430 }
00431 break;
00432 case 3:
00433 if (Status1 & TOP_BTM_PROTECT_Msk) {
00434 if( ( Addr > 0x000000) && ( Addr < (0x000000 + (4 * AddrJump) - 1) )) {
00435 Protected = 1;
00436 }
00437 } else {
00438 if( ( Addr > (0x1FFFFF - ( 4*AddrJump ) + 1) ) && ( Addr < 0x1FFFFF )) {
00439 Protected = 1;
00440 }
00441 }
00442 break;
00443
00444 case 4:
00445 if (Status1 & TOP_BTM_PROTECT_Msk) {
00446 if( ( Addr > 0x000000) && ( Addr < (0x000000 + (8 * AddrJump) - 1) )) {
00447 Protected = 1;
00448 }
00449 } else {
00450 if( ( Addr > (0x1FFFFF - ( 8*AddrJump ) + 1) ) && ( Addr < 0x1FFFFF )) {
00451 Protected = 1;
00452 }
00453 }
00454 break;
00455 case 5:
00456 if( !(Status1 & SEC_PROTECT_Msk) ) {
00457 if (Status1 & TOP_BTM_PROTECT_Msk) {
00458 if( ( Addr > 0x000000) && ( Addr < (0x000000 + (16 * AddrJump) - 1) )) {
00459 Protected = 1;
00460 }
00461 } else {
00462 if( ( Addr > (0x1FFFFF - ( 16*AddrJump ) + 1) ) && ( Addr < 0x1FFFFF )) {
00463 Protected = 1;
00464 }
00465 }
00466 }
00467 break;
00468
00469 case 6:
00470
00471 if( !(Status1 & SEC_PROTECT_Msk) ) {
00472
00473 if (Status1 & TOP_BTM_PROTECT_Msk) {
00474 if( ( Addr > 0x000000) && ( Addr < (0x000000 + (32 * AddrJump) - 1) )) {
00475 Protected = 1;
00476 }
00477 }
00478 }
00479 break;
00480 }
00481
00482 return Protected;
00483 }
00484
00485
00486
00487
00488 void S25FL1D_InitFlashInterface(uint8_t Mode)
00489 {
00490 if(Mode) {
00491 QSPID_Configure(&qspiDma, QspiMemMode,
00492 QSPI_MR_CSMODE_LASTXFER, &qspiDmaInst);
00493 qspiDma.Qspid.qspiMode = (QspiMode_t)QSPI_MR_SMM_MEMORY;
00494
00495 pDev = (QspiInstFrame_t *)malloc (sizeof(QspiInstFrame_t));
00496 memset(pDev, 0, sizeof(QspiInstFrame_t));
00497 pDev->InstFrame.bm.bwidth = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
00498
00499
00500 pMem = (QspiInstFrame_t *)malloc (sizeof(QspiInstFrame_t));
00501 memset(pMem, 0, sizeof(QspiInstFrame_t));
00502 pMem->InstFrame.bm.bwidth = QSPI_IFR_WIDTH_SINGLE_BIT_SPI;
00503 } else {
00504 QSPID_Configure(&qspiDma,
00505 SpiMode,(QSPI_MR_CSMODE_LASTXFER | QSPI_MR_DLYCS (20)),
00506 &qspiDmaInst);
00507 qspiDma.Qspid.qspiMode = (QspiMode_t)QSPI_MR_SMM_SPI;
00508 }
00509
00510 QSPI_ConfigureClock(QSPI, ClockMode_00, QSPI_SCR_SCBR(1));
00511
00512 QSPI_Enable(QSPI);
00513
00514 }
00515
00516
00517
00518
00519
00520
00521 uint32_t S25FL1D_ReadJedecId(void)
00522 {
00523 static uint32_t pId;
00524 S25FL1D_SendCommand(READ_JEDEC_ID, 0, &pId, ReadAccess, 3);
00525
00526 return pId;
00527 }
00528
00529
00530
00531
00532
00533
00534
00535 void S25FL1D_QuadMode(uint8_t Enable)
00536 {
00537
00538 uint8_t status[3];
00539
00540 status[0] = S25FL1D_ReadStatus1();
00541 status[1] = S25FL1D_ReadStatus2();
00542 status[2] = S25FL1D_ReadStatus3();
00543
00544 if(Enable) {
00545 while(!(status[1] & STATUS_QUAD_ENABLE)) {
00546 status[1] |= STATUS_QUAD_ENABLE ;
00547 S25FL1D_WriteStatus(status);
00548 status[1] = S25FL1D_ReadStatus2();
00549 Wait(50);
00550 }
00551 } else {
00552 while((status[1] & STATUS_QUAD_ENABLE)) {
00553 status[1] &= (~STATUS_QUAD_ENABLE);
00554 S25FL1D_WriteStatus(status);
00555 status[1] = S25FL1D_ReadStatus2();
00556 Wait(50);
00557 }
00558 }
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568 void S25FL1D_EnableWrap(uint8_t ByetAlign)
00569 {
00570
00571 uint8_t status[3];
00572
00573 status[0] = S25FL1D_ReadStatus1();
00574 status[1] = S25FL1D_ReadStatus2();
00575 status[2] = S25FL1D_ReadStatus3();
00576
00577 status[2] |= (ByetAlign << 5);
00578
00579 pDev->InstFrame.bm.bDummyCycles = 24;
00580 S25FL1D_SendCommand(WRAP_ENABLE,(uint32_t *)&status[2], 0, WriteAccess, 1);
00581
00582 S25FL1D_WriteVolatileStatus(status);
00583 status[2] = S25FL1D_ReadStatus3();
00584 Wait(50);
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594 void S25FL1D_SetReadLatencyControl(uint8_t Latency)
00595 {
00596
00597 uint8_t status[3];
00598
00599 status[0] = S25FL1D_ReadStatus();
00600 status[1] = S25FL1D_ReadStatus2();
00601 status[2] = S25FL1D_ReadStatus3();
00602
00603 status[2] |= Latency;
00604
00605 qspiDma.Qspid.qspiBuffer.pDataTx = (uint32_t *)&status[2];
00606 while( (status[2] & STATUS_LATENCY_CTRL) != Latency) {
00607 S25FL1D_WriteVolatileStatus(status);
00608 status[2] = S25FL1D_ReadStatus3();
00609 Wait(50);
00610 }
00611 }
00612 void S25FL1D_SoftReset(void)
00613 {
00614 S25FL1D_SendCommand(SOFT_RESET_ENABLE,0, 0, CmdAccess, 0);
00615 S25FL1D_SendCommand(SOFT_RESET, 0, 0, CmdAccess, 0);
00616 }
00617
00618
00619
00620
00621
00622
00623 void S25FL1D_ContReadModeReset(void)
00624 {
00625 S25FL1D_ReadStatus();
00626 S25FL1D_SendCommand(CONT_MODE_RESET, 0, 0, CmdAccess, 0);
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637 unsigned char S25FL1D_Unprotect(void)
00638 {
00639 unsigned char status[3];
00640
00641 status[0]= S25FL1D_ReadStatus();
00642 status[1]= S25FL1D_ReadStatus2();
00643 status[2]= S25FL1D_ReadStatus3();
00644 if ((status[0] & STATUS_SWP) == STATUS_SWP_PROTNONE) {
00645
00646
00647 return 0;
00648 }
00649
00650 status[0] &= (!STATUS_SWP);
00651
00652 if ((status[0] & STATUS_SPRL) == STATUS_SPRL_LOCKED) {
00653 status[0] &= (!STATUS_SPRL);
00654
00655 S25FL1D_WriteStatus(status);
00656 }
00657 S25FL1D_WriteStatus(status);
00658
00659
00660 status[0] = S25FL1D_ReadStatus();
00661 if ((status[0] & (STATUS_SPRL | STATUS_SWP)) != 0) {
00662 return ERROR_PROTECTED;
00663 } else {
00664
00665 return 0;
00666 }
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677 unsigned char S25FL1D_Protect(uint32_t StartAddr, uint32_t Size)
00678 {
00679 unsigned char status[3];
00680
00681 status[0]= S25FL1D_ReadStatus1();
00682 status[1]= S25FL1D_ReadStatus2();
00683 status[2]= S25FL1D_ReadStatus3();
00684
00685 status[0] &= (!STATUS_SWP);
00686
00687 if ((status[0] & STATUS_SPRL) == STATUS_SPRL_LOCKED) {
00688 status[0] &= (!STATUS_SPRL);
00689
00690 S25FL1D_WriteStatus(status);
00691 }
00692 S25FL1D_WriteStatus(status);
00693
00694
00695 status[0] = S25FL1D_ReadStatus();
00696 if ((status[0] & (STATUS_SPRL | STATUS_SWP)) != 0) {
00697 return ERROR_PROTECTED;
00698 } else {
00699 return 0;
00700 }
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712 unsigned char S25FL1D_EraseChip(void)
00713 {
00714 char wait_ch[4] = {'\\','|','/','-' };
00715 uint8_t i=0;
00716 uint8_t Status = STATUS_RDYBSY;
00717 uint8_t ChipStatus= S25FL1D_ReadStatus1();
00718
00719 if(ChipStatus & CHIP_PROTECT_Msk) {
00720 TRACE_ERROR("Chip is Protected \n\r");
00721 TRACE_INFO("Flash Status Register 1 is %x", ChipStatus);
00722 return 1;
00723 } else {
00724 S25FL1D_EnableWrite();
00725 S25FL1D_SendCommand(CHIP_ERASE_2, 0, 0, CmdAccess, 0);
00726
00727 while(Status & STATUS_RDYBSY) {
00728
00729 Wait(200);
00730 printf("Erasing flash memory %c\r", wait_ch[i]);
00731 i++;
00732 Status = S25FL1D_ReadStatus1();
00733 memory_barrier();
00734 i = i % 4;
00735 }
00736 printf("\rErasing flash memory done..... 100%%\n\r");
00737 return 0;
00738 }
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750 unsigned char S25FL1D_EraseSector(unsigned int address)
00751 {
00752 uint8_t status;
00753 uint8_t Secure = 0;
00754
00755 status = S25FL1D_ReadStatus1();
00756 if ((status & STATUS_RDYBSY) != STATUS_RDYBSY_READY) {
00757 TRACE_ERROR("%s : Flash busy\n\r", __FUNCTION__);
00758 return ERROR_BUSY;
00759 } else if (status & BLOCK_PROTECT_Msk) {
00760 if(S25FL1D_CheckProtectedAddr(status, address)) {
00761 TRACE_ERROR("%s : Flash Addrs is protected\n\r", __FUNCTION__);
00762 return ERROR_PROTECTED;
00763 }
00764 }
00765
00766
00767 S25FL1D_EnableWrite();
00768
00769 if(qspiDma.Qspid.qspiMode) {
00770 pDev->Addr = address;
00771 pDev->InstFrame.bm.bAddrEn = 1;
00772
00773 S25FL1D_SendCommand(BLOCK_ERASE_4K, 0, 0, CmdAccess, 0);
00774 } else {
00775
00776 S25FL1D_MemoryAccess(BLOCK_ERASE_4K, address, 0, 0, WriteAccess,
00777 0, Secure);
00778 }
00779
00780 S25FL1D_IsBusy();
00781 return 0;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793 unsigned char S25FL1D_Erase64KBlock( unsigned int address)
00794 {
00795 unsigned char status;
00796
00797
00798 status = S25FL1D_ReadStatus();
00799 if ((status & STATUS_RDYBSY) != STATUS_RDYBSY_READY) {
00800 TRACE_ERROR("S25FL1D_EraseBlock : Flash busy\n\r");
00801 return ERROR_BUSY;
00802 }
00803 else if ((status & STATUS_SWP) != STATUS_SWP_PROTNONE) {
00804 TRACE_ERROR("EraseBlock : Flash protected\n\r");
00805 return ERROR_PROTECTED;
00806 }
00807
00808
00809 S25FL1D_EnableWrite();
00810
00811 if(qspiDma.Qspid.qspiMode) {
00812 pDev->Addr = address;
00813 pDev->InstFrame.bm.bAddrEn = 1;
00814
00815 S25FL1D_SendCommand(BLOCK_ERASE_64K, 0, 0, CmdAccess, 0);
00816 } else {
00817 #ifdef USE_QSPI_DMA
00818 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
00819 return 1;
00820 #endif
00821
00822 S25FL1D_MemoryAccess(BLOCK_ERASE_64K, address, 0, 0, WriteAccess, 0, 0);
00823 #ifdef USE_QSPI_DMA
00824 QSPID_DisableSpiChannel(&qspiDma);
00825 #endif
00826 }
00827
00828
00829 S25FL1D_IsBusy();
00830 return 0;
00831 }
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 unsigned char S25FL1D_Write(
00847 uint32_t *pData,
00848 uint32_t size,
00849 uint32_t address,
00850 uint8_t Secure)
00851 {
00852 unsigned int i = 0;
00853
00854 uint32_t NumberOfWrites = (size >> 8);
00855 uint32_t Addrs = address;
00856
00857 #ifdef USE_QSPI_DMA
00858 if(qspiDma.Qspid.qspiMode) {
00859 if(QSPID_EnableQspiTxChannel(&qspiDma) == QSPID_ERROR_LOCK)
00860 return 1;
00861 } else {
00862 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
00863 return 1;
00864 }
00865 #endif
00866
00867 if(NumberOfWrites == 0) {
00868 S25FL1D_EnableWrite();
00869 S25FL1D_MemoryAccess(BYTE_PAGE_PROGRAM , Addrs, pData, 0,
00870 WriteAccess, size, Secure);
00871
00872 } else {
00873 for(i=0; i< NumberOfWrites; i++) {
00874 S25FL1D_EnableWrite();
00875 S25FL1D_MemoryAccess(BYTE_PAGE_PROGRAM , Addrs, pData, 0,
00876 WriteAccess, PAGE_SIZE, Secure);
00877 S25FL1D_IsBusy();
00878 pData += (PAGE_SIZE >> 2);
00879 Addrs += PAGE_SIZE;
00880 }
00881 if(size % PAGE_SIZE ) {
00882 S25FL1D_EnableWrite();
00883 S25FL1D_MemoryAccess(BYTE_PAGE_PROGRAM , Addrs, pData, 0,
00884 WriteAccess, (size - (NumberOfWrites * PAGE_SIZE)),
00885 Secure);
00886 S25FL1D_IsBusy();
00887 }
00888 }
00889 #ifdef USE_QSPI_DMA
00890
00891 if(qspiDma.Qspid.qspiMode) {
00892 QSPID_DisableQspiTxChannel(&qspiDma);
00893 } else {
00894 QSPID_DisableSpiChannel(&qspiDma);
00895 }
00896
00897 #endif
00898 S25FL1D_DisableWrite();
00899 return 0;
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 unsigned char S25FL1D_Read(
00913 uint32_t *pData,
00914 uint32_t size,
00915 uint32_t address)
00916 {
00917 uint8_t Secure = 0;
00918
00919 #ifdef USE_QSPI_DMA
00920 if(qspiDma.Qspid.qspiMode) {
00921 if(QSPID_EnableQspiRxChannel(&qspiDma) == QSPID_ERROR_LOCK)
00922 return 1;
00923 } else {
00924 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
00925 return 1;
00926 }
00927 #endif
00928
00929 S25FL1D_MemoryAccess(READ_ARRAY , address, 0, pData,
00930 ReadAccess, size , Secure);
00931
00932 #ifdef USE_QSPI_DMA
00933
00934 if(qspiDma.Qspid.qspiMode) {
00935 QSPID_DisableQspiRxChannel(&qspiDma);
00936 } else {
00937 QSPID_DisableSpiChannel(&qspiDma);
00938 }
00939 #endif
00940 return 0;
00941
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 unsigned char S25FL1D_ReadDual(
00955 uint32_t *pData,
00956 uint32_t size,
00957 uint32_t address)
00958 {
00959
00960 uint8_t Secure = 0;
00961 #ifdef USE_QSPI_DMA
00962 if(qspiDma.Qspid.qspiMode) {
00963 if(QSPID_EnableQspiRxChannel(&qspiDma) == QSPID_ERROR_LOCK)
00964 return 1;
00965 } else {
00966 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
00967 return 1;
00968 }
00969 #endif
00970 pMem->InstFrame.bm.bDummyCycles = 8;
00971 pMem->InstFrame.bm.bwidth = QSPI_IFR_WIDTH_DUAL_OUTPUT;
00972
00973 S25FL1D_MemoryAccess(READ_ARRAY_DUAL , address, 0, pData,
00974 ReadAccess, size, Secure);
00975
00976 #ifdef USE_QSPI_DMA
00977 while(QSPID_IsBusy(&qspiDma.progress) ) {
00978 Wait(1);
00979 }
00980 if(qspiDma.Qspid.qspiMode) {
00981 QSPID_DisableQspiRxChannel(&qspiDma);
00982 } else {
00983 QSPID_DisableSpiChannel(&qspiDma);
00984 }
00985 #endif
00986 return 0;
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999 unsigned char S25FL1D_ReadQuad(
01000 uint32_t *pData,
01001 uint32_t size,
01002 uint32_t address)
01003 {
01004 uint8_t Secure = 0;
01005 #ifdef USE_QSPI_DMA
01006 if(qspiDma.Qspid.qspiMode) {
01007 if(QSPID_EnableQspiRxChannel(&qspiDma) == QSPID_ERROR_LOCK)
01008 return 1;
01009 } else {
01010 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
01011 return 1;
01012 }
01013 #endif
01014 pMem->InstFrame.bm.bDummyCycles = 8;
01015 pMem->InstFrame.bm.bwidth = QSPI_IFR_WIDTH_QUAD_OUTPUT;
01016 S25FL1D_MemoryAccess(READ_ARRAY_QUAD, address, 0, pData,
01017 ReadAccess, size, Secure);
01018
01019 #ifdef USE_QSPI_DMA
01020 while(QSPID_IsBusy(&qspiDma.progress) ) {
01021 Wait(1);
01022 }
01023 if(qspiDma.Qspid.qspiMode) {
01024 QSPID_DisableQspiRxChannel(&qspiDma);
01025 } else {
01026 QSPID_DisableSpiChannel(&qspiDma);
01027 }
01028 #endif
01029 return 0;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 unsigned char S25FL1D_ReadDualIO(
01043 uint32_t *pData,
01044 uint32_t size,
01045 uint32_t address,
01046 uint8_t ContMode,
01047 uint8_t Secure)
01048 {
01049 #ifdef USE_QSPI_DMA
01050 if(qspiDma.Qspid.qspiMode) {
01051 if(QSPID_EnableQspiRxChannel(&qspiDma) == QSPID_ERROR_LOCK)
01052 return 1;
01053 } else {
01054 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
01055 return 1;
01056 }
01057 #endif
01058 pMem->InstFrame.bm.bDummyCycles = 4;
01059 if(ContMode) {
01060 pMem->InstFrame.bm.bOptLen
01061 = (QSPI_IFR_OPTL_OPTION_4BIT >> QSPI_IFR_OPTL_Pos);
01062 qspiDma.Qspid.qspiCommand.Option= 0x2;
01063 pMem->InstFrame.bm.bContinuesRead = ContMode;
01064 pMem->InstFrame.bm.bDummyCycles = 3;
01065 }
01066 pMem->InstFrame.bm.bwidth = QSPI_IFR_WIDTH_DUAL_IO;
01067 S25FL1D_MemoryAccess(READ_ARRAY_DUAL_IO , address, 0,
01068 pData, ReadAccess, size, Secure);
01069 pMem->InstFrame.bm.bOptEn = 0;
01070 pMem->InstFrame.bm.bContinuesRead = 0;
01071 #ifdef USE_QSPI_DMA
01072 while(QSPID_IsBusy(&qspiDma.progress) ) {
01073 Wait(1);
01074 }
01075 if(qspiDma.Qspid.qspiMode) {
01076 QSPID_DisableQspiRxChannel(&qspiDma);
01077 } else {
01078 QSPID_DisableSpiChannel(&qspiDma);
01079 }
01080 #endif
01081 return 0;
01082 }
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 unsigned char S25FL1D_ReadQuadIO(
01095 uint32_t *pData,
01096 uint32_t size,
01097 uint32_t address,
01098 uint8_t ContMode,
01099 uint8_t Secure)
01100 {
01101 #ifdef USE_QSPI_DMA
01102 if(qspiDma.Qspid.qspiMode) {
01103 if(QSPID_EnableQspiRxChannel(&qspiDma) == QSPID_ERROR_LOCK)
01104 return 1;
01105 } else {
01106 if(QSPID_EnableSpiChannel(&qspiDma) == QSPID_ERROR_LOCK)
01107 return 1;
01108 }
01109 #endif
01110 pMem->InstFrame.bm.bDummyCycles = 6;
01111 if(ContMode) {
01112 pMem->InstFrame.bm.bOptLen
01113 = (QSPI_IFR_OPTL_OPTION_4BIT >> QSPI_IFR_OPTL_Pos);
01114 qspiDma.Qspid.qspiCommand.Option= 0x2;
01115 pMem->InstFrame.bm.bContinuesRead = ContMode;
01116 pMem->InstFrame.bm.bDummyCycles = 5;
01117 pMem->InstFrame.bm.bOptEn = 1;
01118 }
01119
01120 pMem->InstFrame.bm.bwidth = QSPI_IFR_WIDTH_QUAD_IO;
01121 S25FL1D_MemoryAccess(READ_ARRAY_QUAD_IO , address, 0,
01122 pData, ReadAccess, size, Secure);
01123 pMem->InstFrame.bm.bOptEn = 0;
01124 pMem->InstFrame.bm.bContinuesRead = 0;
01125 #ifdef USE_QSPI_DMA
01126 while(QSPID_IsBusy(&qspiDma.progress) ) {
01127 Wait(1);
01128 }
01129 if(qspiDma.Qspid.qspiMode) {
01130 QSPID_DisableQspiRxChannel(&qspiDma);
01131 } else {
01132 QSPID_DisableSpiChannel(&qspiDma);
01133 }
01134 #endif
01135 return 0;
01136 }
01137