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