| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600 |
- #ifdef __BUILD_OS__
- #include "app_inc.h"
- #else
- #include "bl_inc.h"
- #endif
- enum
- {
- SPIFLASH_STATE_IDLE = 0,
- SPIFLASH_STATE_RUN,
- SPIFLASH_STATE_READ,
- SPIFLASH_STATE_ERASE,
- SPIFLASH_STATE_WRITE,
- };
- const uint8_t SPI_FLASH_VENDOR_DICT[] = {
- 0xA1,//"FM"
- 0xC8,//"GD"
- 0x9D,//"ISSI"
- 0xC2,//"KH"
- 0xEF,//"WB"
- 0x68,
- };
- const uint8_t SPI_FLASH_SIZE_DICT[] = {
- 0x09,//"256Kbit"
- 0x10,//"512Kbit"
- 0x11,//"1Mbit"
- 0x12,//"2Mbit"
- 0x13,//"4Mbit"
- 0x14,//"8Mbit"
- 0x15,//"16Mbit"
- 0x16,//"32Mbit"
- 0x17,//"64Mbit"
- 0x18,//"128Mbit"
- };
- #define SF_DBG DBG_INFO
- static void SPIFlash_CS(SPIFlash_CtrlStruct *Ctrl, uint8_t OnOff)
- {
- GPIO_Output(Ctrl->CSPin, !OnOff);
- if (Ctrl->CSDelayUS)
- {
- SysTickDelay(Ctrl->CSDelayUS * CORE_TICK_1US);
- }
- }
- static void SPIFlash_SpiXfer(SPIFlash_CtrlStruct *Ctrl, uint8_t *TxData, uint8_t *RxData, uint32_t Len)
- {
- SPIFlash_CS(Ctrl, 1);
- Ctrl->SPIError = 0;
- Ctrl->SPIEndTick = GetSysTick() + Len * CORE_TICK_1US + CORE_TICK_1MS;
- SPI_Transfer(Ctrl->SpiID, TxData, RxData, Len, Ctrl->IsSpiDMAMode);
- }
- static void SPIFlash_SpiBlockXfer(SPIFlash_CtrlStruct *Ctrl, uint8_t *TxData, uint8_t *RxData, uint32_t Len)
- {
- SPIFlash_CS(Ctrl, 1);
- Ctrl->SPIError = 0;
- SPI_BlockTransfer(Ctrl->SpiID, TxData, RxData, Len);
- SPIFlash_CS(Ctrl, 0);
- }
- static int32_t SPIFlash_SpiIrqCB(void *pData, void *pParam)
- {
- SPIFlash_CtrlStruct *Ctrl = (SPIFlash_CtrlStruct *)pParam;
- SPIFlash_CS(Ctrl, 0);
- #ifdef __BUILD_OS__
- if (Ctrl->NotifyTask && Ctrl->IsBlockMode)
- {
- Task_SendEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, 0, 0, 0);
- }
- #endif
- }
- static void SPIFlash_Wait(SPIFlash_CtrlStruct *Ctrl, uint32_t Tick)
- {
- #ifdef __BUILD_OS__
- Task_EventStruct Event;
- if (Ctrl->NotifyTask && Ctrl->TaskCB)
- {
- Task_GetEvent(Ctrl->NotifyTask, 0xffffffff, &Event, Ctrl->TaskCB, Tick);
- }
- else
- {
- Task_DelayTick(Tick);
- }
- #else
- SysTickDelay(Tick);
- #endif
- }
- //用外部flash存储文件才需要开启
- #if 0
- static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
- lfs_off_t off, void *buffer, lfs_size_t size)
- {
- int ret = (SPIFlash_Read((SPIFlash_CtrlStruct *)cfg->context, (block + __APP_BAK_FLASH_SECTOR_NUM__ + __SCRIPT_FLASH_SECTOR_NUM__) * cfg->block_size + off, buffer, size, 0)) ? LFS_ERR_IO: LFS_ERR_OK;
- //DBG_Trace("block_device_read block %d off %d size %d ret %d", block, off, size, ret);
- return ret;
- }
- static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
- lfs_off_t off, const void *buffer, lfs_size_t size)
- {
- int ret = (SPIFlash_Write((SPIFlash_CtrlStruct *)cfg->context, (block + __APP_BAK_FLASH_SECTOR_NUM__ + __SCRIPT_FLASH_SECTOR_NUM__) * cfg->block_size + off, buffer, size)) ? LFS_ERR_IO: LFS_ERR_OK;
- //DBG_Trace("block_device_prog block %d off %d size %d ret", block, off, size, ret);
- return ret;
- }
- static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block)
- {
- int ret = (SPIFlash_Erase((SPIFlash_CtrlStruct *)cfg->context, (block + __APP_BAK_FLASH_SECTOR_NUM__ + __SCRIPT_FLASH_SECTOR_NUM__) * cfg->block_size, cfg->block_size)) ? LFS_ERR_IO: LFS_ERR_OK;
- //DBG_Trace("block_device_erase block %d ret %d", block, ret);
- //DDBG_TraceBG("block_device_erase addr %d size %d", (block + __APP_BAK_FLASH_SECTOR_NUM__ + __SCRIPT_FLASH_SECTOR_NUM__) * cfg->block_size, cfg->block_size);
- return ret;
- }
- static int block_device_sync(const struct lfs_config *cfg)
- {
- //DBG_Trace("block_device_sync");
- return 0;
- }
- #define LFS_BLOCK_DEVICE_READ_SIZE (256)
- #define LFS_BLOCK_DEVICE_PROG_SIZE (SPIFLASH_PAGE_LEN)
- #define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
- #define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
- //__attribute__ ((aligned (8))) static char lfs_cache_buff[LFS_BLOCK_DEVICE_CACHE_SIZE];
- __attribute__ ((aligned (8))) static char lfs_read_buff[LFS_BLOCK_DEVICE_READ_SIZE];
- __attribute__ ((aligned (8))) static char lfs_prog_buff[LFS_BLOCK_DEVICE_PROG_SIZE];
- __attribute__ ((aligned (8))) static char lfs_lookahead_buff[16];
- #endif
- void SPIFlash_Init(SPIFlash_CtrlStruct *Ctrl, void *LFSConfig)
- {
- Ctrl->State = SPIFLASH_STATE_IDLE;
- SPIFlash_ID(Ctrl);
- //用外部flash存储文件才需要开启
- #if 0
- struct lfs_config *config = LFSConfig;
- //SF_DBG("ID:%02x,%02x,%02x,Size:%uKB", Ctrl->FlashID[0], Ctrl->FlashID[1], Ctrl->FlashID[2], Ctrl->Size);
- config->context = Ctrl;
- config->cache_size = LFS_BLOCK_DEVICE_READ_SIZE;
- config->prog_size = SPIFLASH_PAGE_LEN;
- config->block_size = SPIFLASH_SECTOR_LEN;
- config->read_size = LFS_BLOCK_DEVICE_READ_SIZE;
- config->block_cycles = 200;
- config->lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
- //config->block_count = (Ctrl->Size / 4) - __APP_BAK_FLASH_SECTOR_NUM__ - __SCRIPT_FLASH_SECTOR_NUM__;
- config->block_count = 336 / 4 ; // TODO fixed as Air302, for now, modify later.
- config->name_max = 63;
- config->read = block_device_read;
- config->prog = block_device_prog;
- config->erase = block_device_erase;
- config->sync = block_device_sync;
- //config->buffer = (void*)lfs_cache_buff;
- config->read_buffer = (void*)lfs_read_buff;
- config->prog_buffer = (void*)lfs_prog_buff;
- config->lookahead_buffer = (void*)lfs_lookahead_buff;
- #endif
- SF_DBG("ID:%02x,%02x,%02x,Size:%uKB", Ctrl->FlashID[0], Ctrl->FlashID[1], Ctrl->FlashID[2], Ctrl->Size);
- Ctrl->EraseSectorWaitTime = 50;
- Ctrl->EraseBlockWaitTime = 250;
- Ctrl->ProgramWaitTimeUS = 300;
- Ctrl->ProgramTime = 3;
- Ctrl->EraseSectorTime = 400;
- Ctrl->EraseBlockTime = 2400;
- }
- int32_t SPIFlash_ID(SPIFlash_CtrlStruct *Ctrl)
- {
- uint32_t i,j;
- for(i = 0; i < 10; i++)
- {
- Ctrl->Tx[0] = SPIFLASH_CMD_RDID;
- SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
- if (Ctrl->Rx[1] == 0xff || !Ctrl->Rx[1])
- {
- SPIFlash_Wait(Ctrl, 10 * CORE_TICK_1MS);
- }
- else
- {
- break;
- }
- }
- if (!Ctrl->SPIError)
- {
- memcpy(Ctrl->FlashID, Ctrl->Rx+1, 3);
- for (i = 0; i < sizeof(SPI_FLASH_VENDOR_DICT)/sizeof(uint8_t); i++)
- {
- //读取到正确的ID后,开始解除FLASH锁定
- if (Ctrl->FlashID[0] == SPI_FLASH_VENDOR_DICT[i])
- {
- Ctrl->Size = 32;
- for (j = 0; j < sizeof(SPI_FLASH_SIZE_DICT)/sizeof(uint8_t); j++)
- {
- if (Ctrl->FlashID[2] == SPI_FLASH_SIZE_DICT[j])
- {
- return ERROR_NONE;
- }
- Ctrl->Size *= 2;
- }
- }
- }
- }
- return ERROR_NONE;
- }
- int32_t SPIFlash_ReadSR(SPIFlash_CtrlStruct *Ctrl)
- {
- Ctrl->FlashSR = 0xff;
- Ctrl->Tx[0] = SPIFLASH_CMD_RDSR;
- Ctrl->Rx[1] = 0xff;
- SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 2);
- if (!Ctrl->SPIError)
- {
- Ctrl->FlashSR = Ctrl->Rx[1];
- }
- else
- {
- DBGF;
- return -ERROR_OPERATION_FAILED;
- }
- //SF_DBG("%02x", Ctrl->FlashSR);
- return ERROR_NONE;
- }
- int32_t SPIFlash_CheckBusy(SPIFlash_CtrlStruct *Ctrl)
- {
- int Result = SPIFlash_ReadSR(Ctrl);
- if (Result < 0)
- {
- return -ERROR_OPERATION_FAILED;
- }
- if (!Ctrl->SPIError && !(Ctrl->FlashSR & SPIFLASH_SR_BUSY))
- {
- //DBGF;
- Ctrl->IsPPErase = 0;
- }
- else
- {
- //DBGF;
- }
- return ERROR_NONE;
- }
- uint8_t SPIFlash_WaitOpDone(SPIFlash_CtrlStruct *Ctrl)
- {
- uint32_t FlashAddress, DummyLen;
- switch(Ctrl->State)
- {
- case SPIFLASH_STATE_READ:
- if (SPI_IsTransferBusy(Ctrl->SpiID))
- {
- if (GetSysTick() > Ctrl->SPIEndTick)
- {
- SF_DBG("spi xfer timeout!");
- Ctrl->SPIError = 1;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- SPI_TransferStop(Ctrl->SpiID);
- SPIFlash_CS(Ctrl, 0);
- return 1;
- }
- }
- else
- {
- Ctrl->State = SPIFLASH_STATE_IDLE;
- SPIFlash_CS(Ctrl, 0);
- return 1;
- }
- break;
- case SPIFLASH_STATE_ERASE:
- SPIFlash_CheckBusy(Ctrl);
- if (!Ctrl->IsPPErase)
- {
- if (Ctrl->FinishLen >= Ctrl->DataLen)
- {
- Ctrl->FlashError = 0;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- return 1;
- }
- SPIFlash_WriteEnable(Ctrl);
- FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
- DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
- if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
- {
- SF_DBG("erase block 0x%x", FlashAddress);
- Ctrl->Tx[0] = SPIFLASH_CMD_BE;
- Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseBlockTime * CORE_TICK_1MS;
- Ctrl->FinishLen += SPI_FLASH_BLOCK_SIZE;
- }
- else
- {
- SF_DBG("erase sector 0x%x", FlashAddress);
- Ctrl->Tx[0] = SPIFLASH_CMD_SE;
- Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseSectorTime * CORE_TICK_1MS;
- Ctrl->FinishLen += SPI_FLASH_SECTOR_SIZE;
- }
- Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
- Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
- Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
- SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
- }
- else
- {
- if (GetSysTick() >= Ctrl->FlashOPEndTick)
- {
- SF_DBG("erase timeout!");
- Ctrl->FlashError = 1;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- return 1;
- }
- }
- break;
- case SPIFLASH_STATE_WRITE:
- if (SPI_IsTransferBusy(Ctrl->SpiID))
- {
- if (GetSysTick() > Ctrl->SPIEndTick)
- {
- SF_DBG("spi xfer timeout!");
- Ctrl->SPIError = 1;
- Ctrl->FlashError = 1;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- SPI_TransferStop(Ctrl->SpiID);
- SPIFlash_CS(Ctrl, 0);
- return 1;
- }
- }
- else
- {
- SPIFlash_CheckBusy(Ctrl);
- if (!Ctrl->IsPPErase)
- {
- if (Ctrl->FinishLen >= Ctrl->DataLen)
- {
- Ctrl->FlashError = 0;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- return 1;
- }
- SPIFlash_WriteEnable(Ctrl);
- FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
- DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
- SF_DBG("Program 0x%x", FlashAddress);
- Ctrl->Tx[0] = SPIFLASH_CMD_PP;
- Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
- Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
- Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
- if (DummyLen > SPIFLASH_PAGE_LEN)
- {
- DummyLen = SPIFLASH_PAGE_LEN;
- }
- memcpy(Ctrl->Tx + 4, Ctrl->TxBuf + Ctrl->FinishLen, DummyLen);
- SPIFlash_CS(Ctrl, 1);
- Ctrl->SPIError = 0;
- SPI_Transfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, DummyLen + 4, Ctrl->IsSpiDMAMode);
- Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->ProgramTime * CORE_TICK_1MS;
- Ctrl->SPIEndTick = GetSysTick() + CORE_TICK_1MS;
- Ctrl->FinishLen += DummyLen;
- }
- else
- {
- if (GetSysTick() >= Ctrl->FlashOPEndTick)
- {
- SF_DBG("Program timeout!");
- Ctrl->FlashError = 1;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- return 1;
- }
- }
- }
- break;
- default:
- Ctrl->FlashError = 1;
- Ctrl->State = SPIFLASH_STATE_IDLE;
- return 1;
- }
- return 0;
- }
- int32_t SPIFlash_WriteEnable(SPIFlash_CtrlStruct *Ctrl)
- {
- Ctrl->Tx[0] = SPIFLASH_CMD_WREN;
- SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 1);
- return 0;
- }
- int32_t SPIFlash_Read(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint8_t *Buf, uint32_t Length, uint8_t FastRead)
- {
- #ifdef __BUILD_OS__
- Task_EventStruct Event;
- #endif
- Ctrl->FlashError = 0;
- Ctrl->Tx[1] = (Address & 0x00ff0000) >> 16;
- Ctrl->Tx[2] = (Address & 0x0000ff00) >> 8;
- Ctrl->Tx[3] = (Address & 0x000000ff);
- SPIFlash_CS(Ctrl, 1);
- Ctrl->SPIError = 0;
- switch (FastRead)
- {
- case 0:
- Ctrl->Tx[0] = SPIFLASH_CMD_READ;
- SPI_BlockTransfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, 4);
- break;
- default:
- Ctrl->Tx[0] = SPIFLASH_CMD_FTRD;
- SPI_BlockTransfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, 5);
- break;
- }
- if (Ctrl->IsBlockMode)
- {
- #ifdef __BUILD_OS__
- if (Ctrl->NotifyTask && Ctrl->TaskCB)
- {
- Ctrl->SPIError = 0;
- SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
- SPI_Transfer(Ctrl->SpiID, Buf, Buf, Length, Ctrl->IsSpiDMAMode);
- if (Task_GetEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, &Event, Ctrl->TaskCB, Length * CORE_TICK_1US + CORE_TICK_1MS))
- {
- Ctrl->SPIError = 1;
- SPI_TransferStop(Ctrl->SpiID);
- }
- SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
- SPIFlash_CS(Ctrl, 0);
- }
- else
- #endif
- {
- SPI_BlockTransfer(Ctrl->SpiID, Buf, Buf, Length);
- SPIFlash_CS(Ctrl, 0);
- }
- }
- else
- {
- Ctrl->State = SPIFLASH_STATE_READ;
- SPIFlash_CS(Ctrl, 1);
- Ctrl->SPIError = 0;
- SPI_Transfer(Ctrl->SpiID, Buf, Buf, Length, Ctrl->IsSpiDMAMode);
- Ctrl->SPIEndTick = GetSysTick() + Length * CORE_TICK_1US + CORE_TICK_1MS;
- }
- return Ctrl->FlashError;
- }
- int32_t SPIFlash_Write(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, const uint8_t *Buf, uint32_t Length)
- {
- #ifdef __BUILD_OS__
- Task_EventStruct Event;
- #endif
- uint32_t FlashAddress, DummyLen;
- Ctrl->FlashError = 0;
- Ctrl->AddrStart = Address;
- Ctrl->TxBuf = Buf;
- Ctrl->DataLen = Length;
- Ctrl->FinishLen = 0;
- Ctrl->SPIError = 0;
- // SF_DBG("%x,%u", Address, Length);
- if (Ctrl->IsBlockMode)
- {
- while((Ctrl->FinishLen < Ctrl->DataLen) && !Ctrl->SPIError)
- {
- FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
- DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
- SPIFlash_WriteEnable(Ctrl);
- Ctrl->Tx[0] = SPIFLASH_CMD_PP;
- Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
- Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
- Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
- if (DummyLen > SPIFLASH_PAGE_LEN)
- {
- DummyLen = SPIFLASH_PAGE_LEN;
- }
- memcpy(Ctrl->Tx + 4, Ctrl->TxBuf + Ctrl->FinishLen, DummyLen);
- #ifdef __BUILD_OS__
- if (Ctrl->NotifyTask && Ctrl->TaskCB)
- {
- SPIFlash_CS(Ctrl, 1);
- Ctrl->SPIError = 0;
- SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
- SPI_Transfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, DummyLen + 4, Ctrl->IsSpiDMAMode);
- if (Task_GetEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, &Event, Ctrl->TaskCB, CORE_TICK_1MS))
- {
- Ctrl->SPIError = 1;
- SPI_TransferStop(Ctrl->SpiID);
- }
- SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
- SPIFlash_CS(Ctrl, 0);
- }
- else
- #endif
- {
- SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, DummyLen + 4);
- }
- Ctrl->FinishLen += DummyLen;
- if (Ctrl->SPIError)
- {
- break;
- }
- Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->ProgramTime * CORE_TICK_1MS;
- Ctrl->IsPPErase = 1;
- while (Ctrl->IsPPErase && (GetSysTick() < Ctrl->FlashOPEndTick))
- {
- SPIFlash_Wait(Ctrl, Ctrl->ProgramWaitTimeUS * CORE_TICK_1US);
- SPIFlash_CheckBusy(Ctrl);
- }
- if (Ctrl->IsPPErase)
- {
- DBGF;
- Ctrl->FlashError = 1;
- return -ERROR_OPERATION_FAILED;
- }
- }
- //SF_DBG("write ok!")
- if (Ctrl->SPIError)
- {
- DBGF;
- Ctrl->FlashError = 1;
- return -ERROR_OPERATION_FAILED;
- }
- }
- else
- {
- Ctrl->State = SPIFLASH_STATE_WRITE;
- }
- return Ctrl->FlashError;
- }
- int32_t SPIFlash_Erase(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint32_t Length)
- {
- uint32_t FlashAddress, DummyLen, Tick;
- Ctrl->FlashError = 0;
- Ctrl->AddrStart = Address;
- Ctrl->DataLen = Length;
- Ctrl->FinishLen = 0;
- if (Ctrl->IsBlockMode)
- {
- while(Ctrl->FinishLen < Ctrl->DataLen)
- {
- SPIFlash_WriteEnable(Ctrl);
- FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
- DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
- if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
- {
- // SF_DBG("erase block 0x%x", FlashAddress);
- Ctrl->Tx[0] = SPIFLASH_CMD_BE;
- Tick = Ctrl->EraseBlockWaitTime * CORE_TICK_1MS;
- Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseBlockTime * CORE_TICK_1MS;
- Ctrl->FinishLen += SPI_FLASH_BLOCK_SIZE;
- }
- else
- {
- // SF_DBG("erase sector 0x%x", FlashAddress);
- Ctrl->Tx[0] = SPIFLASH_CMD_SE;
- Tick = Ctrl->EraseSectorWaitTime * CORE_TICK_1MS;
- Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseSectorTime * CORE_TICK_1MS;
- Ctrl->FinishLen += SPI_FLASH_SECTOR_SIZE;
- }
- Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
- Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
- Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
- SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
- Ctrl->IsPPErase = 1;
- while (Ctrl->IsPPErase && (GetSysTick() < Ctrl->FlashOPEndTick))
- {
- SPIFlash_Wait(Ctrl, Tick);
- SPIFlash_CheckBusy(Ctrl);
- }
- if (Ctrl->IsPPErase)
- {
- Ctrl->FlashError = 1;
- return -ERROR_OPERATION_FAILED;
- }
- }
- }
- else
- {
- Ctrl->State = SPIFLASH_STATE_ERASE;
- }
- return Ctrl->FlashError;
- }
|