dev_spiflash.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. #ifdef __BUILD_OS__
  2. #include "app_inc.h"
  3. #else
  4. #include "bl_inc.h"
  5. #endif
  6. enum
  7. {
  8. SPIFLASH_STATE_IDLE = 0,
  9. SPIFLASH_STATE_RUN,
  10. SPIFLASH_STATE_READ,
  11. SPIFLASH_STATE_ERASE,
  12. SPIFLASH_STATE_WRITE,
  13. };
  14. const uint8_t SPI_FLASH_VENDOR_DICT[] = {
  15. 0xA1,//"FM"
  16. 0xC8,//"GD"
  17. 0x9D,//"ISSI"
  18. 0xC2,//"KH"
  19. 0xEF,//"WB"
  20. 0x68,
  21. };
  22. const uint8_t SPI_FLASH_SIZE_DICT[] = {
  23. 0x09,//"256Kbit"
  24. 0x10,//"512Kbit"
  25. 0x11,//"1Mbit"
  26. 0x12,//"2Mbit"
  27. 0x13,//"4Mbit"
  28. 0x14,//"8Mbit"
  29. 0x15,//"16Mbit"
  30. 0x16,//"32Mbit"
  31. 0x17,//"64Mbit"
  32. 0x18,//"128Mbit"
  33. };
  34. #define SF_DBG DBG_INFO
  35. static void SPIFlash_CS(SPIFlash_CtrlStruct *Ctrl, uint8_t OnOff)
  36. {
  37. GPIO_Output(Ctrl->CSPin, !OnOff);
  38. if (Ctrl->CSDelayUS)
  39. {
  40. SysTickDelay(Ctrl->CSDelayUS * CORE_TICK_1US);
  41. }
  42. }
  43. static void SPIFlash_SpiXfer(SPIFlash_CtrlStruct *Ctrl, uint8_t *TxData, uint8_t *RxData, uint32_t Len)
  44. {
  45. SPIFlash_CS(Ctrl, 1);
  46. Ctrl->SPIError = 0;
  47. Ctrl->SPIEndTick = GetSysTick() + Len * CORE_TICK_1US + CORE_TICK_1MS;
  48. SPI_Transfer(Ctrl->SpiID, TxData, RxData, Len, Ctrl->IsSpiDMAMode);
  49. }
  50. static void SPIFlash_SpiBlockXfer(SPIFlash_CtrlStruct *Ctrl, uint8_t *TxData, uint8_t *RxData, uint32_t Len)
  51. {
  52. SPIFlash_CS(Ctrl, 1);
  53. Ctrl->SPIError = 0;
  54. SPI_BlockTransfer(Ctrl->SpiID, TxData, RxData, Len);
  55. SPIFlash_CS(Ctrl, 0);
  56. }
  57. static int32_t SPIFlash_SpiIrqCB(void *pData, void *pParam)
  58. {
  59. SPIFlash_CtrlStruct *Ctrl = (SPIFlash_CtrlStruct *)pParam;
  60. SPIFlash_CS(Ctrl, 0);
  61. #ifdef __BUILD_OS__
  62. if (Ctrl->NotifyTask && Ctrl->IsBlockMode)
  63. {
  64. Task_SendEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, 0, 0, 0);
  65. }
  66. #endif
  67. }
  68. static void SPIFlash_Wait(SPIFlash_CtrlStruct *Ctrl, uint32_t Tick)
  69. {
  70. #ifdef __BUILD_OS__
  71. Task_EventStruct Event;
  72. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  73. {
  74. Task_GetEvent(Ctrl->NotifyTask, 0xffffffff, &Event, Ctrl->TaskCB, Tick);
  75. }
  76. else
  77. {
  78. Task_DelayTick(Tick);
  79. }
  80. #else
  81. SysTickDelay(Tick);
  82. #endif
  83. }
  84. //用外部flash存储文件才需要开启
  85. #if 0
  86. static int block_device_read(const struct lfs_config *cfg, lfs_block_t block,
  87. lfs_off_t off, void *buffer, lfs_size_t size)
  88. {
  89. 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;
  90. //DBG_Trace("block_device_read block %d off %d size %d ret %d", block, off, size, ret);
  91. return ret;
  92. }
  93. static int block_device_prog(const struct lfs_config *cfg, lfs_block_t block,
  94. lfs_off_t off, const void *buffer, lfs_size_t size)
  95. {
  96. 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;
  97. //DBG_Trace("block_device_prog block %d off %d size %d ret", block, off, size, ret);
  98. return ret;
  99. }
  100. static int block_device_erase(const struct lfs_config *cfg, lfs_block_t block)
  101. {
  102. 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;
  103. //DBG_Trace("block_device_erase block %d ret %d", block, ret);
  104. //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);
  105. return ret;
  106. }
  107. static int block_device_sync(const struct lfs_config *cfg)
  108. {
  109. //DBG_Trace("block_device_sync");
  110. return 0;
  111. }
  112. #define LFS_BLOCK_DEVICE_READ_SIZE (256)
  113. #define LFS_BLOCK_DEVICE_PROG_SIZE (SPIFLASH_PAGE_LEN)
  114. #define LFS_BLOCK_DEVICE_LOOK_AHEAD (16)
  115. #define LFS_BLOCK_DEVICE_CACHE_SIZE (256)
  116. //__attribute__ ((aligned (8))) static char lfs_cache_buff[LFS_BLOCK_DEVICE_CACHE_SIZE];
  117. __attribute__ ((aligned (8))) static char lfs_read_buff[LFS_BLOCK_DEVICE_READ_SIZE];
  118. __attribute__ ((aligned (8))) static char lfs_prog_buff[LFS_BLOCK_DEVICE_PROG_SIZE];
  119. __attribute__ ((aligned (8))) static char lfs_lookahead_buff[16];
  120. #endif
  121. void SPIFlash_Init(SPIFlash_CtrlStruct *Ctrl, void *LFSConfig)
  122. {
  123. Ctrl->State = SPIFLASH_STATE_IDLE;
  124. SPIFlash_ID(Ctrl);
  125. //用外部flash存储文件才需要开启
  126. #if 0
  127. struct lfs_config *config = LFSConfig;
  128. //SF_DBG("ID:%02x,%02x,%02x,Size:%uKB", Ctrl->FlashID[0], Ctrl->FlashID[1], Ctrl->FlashID[2], Ctrl->Size);
  129. config->context = Ctrl;
  130. config->cache_size = LFS_BLOCK_DEVICE_READ_SIZE;
  131. config->prog_size = SPIFLASH_PAGE_LEN;
  132. config->block_size = SPIFLASH_SECTOR_LEN;
  133. config->read_size = LFS_BLOCK_DEVICE_READ_SIZE;
  134. config->block_cycles = 200;
  135. config->lookahead_size = LFS_BLOCK_DEVICE_LOOK_AHEAD;
  136. //config->block_count = (Ctrl->Size / 4) - __APP_BAK_FLASH_SECTOR_NUM__ - __SCRIPT_FLASH_SECTOR_NUM__;
  137. config->block_count = 336 / 4 ; // TODO fixed as Air302, for now, modify later.
  138. config->name_max = 63;
  139. config->read = block_device_read;
  140. config->prog = block_device_prog;
  141. config->erase = block_device_erase;
  142. config->sync = block_device_sync;
  143. //config->buffer = (void*)lfs_cache_buff;
  144. config->read_buffer = (void*)lfs_read_buff;
  145. config->prog_buffer = (void*)lfs_prog_buff;
  146. config->lookahead_buffer = (void*)lfs_lookahead_buff;
  147. #endif
  148. SF_DBG("ID:%02x,%02x,%02x,Size:%uKB", Ctrl->FlashID[0], Ctrl->FlashID[1], Ctrl->FlashID[2], Ctrl->Size);
  149. Ctrl->EraseSectorWaitTime = 50;
  150. Ctrl->EraseBlockWaitTime = 250;
  151. Ctrl->ProgramWaitTimeUS = 300;
  152. Ctrl->ProgramTime = 3;
  153. Ctrl->EraseSectorTime = 400;
  154. Ctrl->EraseBlockTime = 2400;
  155. }
  156. int32_t SPIFlash_ID(SPIFlash_CtrlStruct *Ctrl)
  157. {
  158. uint32_t i,j;
  159. for(i = 0; i < 10; i++)
  160. {
  161. Ctrl->Tx[0] = SPIFLASH_CMD_RDID;
  162. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
  163. if (Ctrl->Rx[1] == 0xff || !Ctrl->Rx[1])
  164. {
  165. SPIFlash_Wait(Ctrl, 10 * CORE_TICK_1MS);
  166. }
  167. else
  168. {
  169. break;
  170. }
  171. }
  172. if (!Ctrl->SPIError)
  173. {
  174. memcpy(Ctrl->FlashID, Ctrl->Rx+1, 3);
  175. for (i = 0; i < sizeof(SPI_FLASH_VENDOR_DICT)/sizeof(uint8_t); i++)
  176. {
  177. //读取到正确的ID后,开始解除FLASH锁定
  178. if (Ctrl->FlashID[0] == SPI_FLASH_VENDOR_DICT[i])
  179. {
  180. Ctrl->Size = 32;
  181. for (j = 0; j < sizeof(SPI_FLASH_SIZE_DICT)/sizeof(uint8_t); j++)
  182. {
  183. if (Ctrl->FlashID[2] == SPI_FLASH_SIZE_DICT[j])
  184. {
  185. return ERROR_NONE;
  186. }
  187. Ctrl->Size *= 2;
  188. }
  189. }
  190. }
  191. }
  192. return ERROR_NONE;
  193. }
  194. int32_t SPIFlash_ReadSR(SPIFlash_CtrlStruct *Ctrl)
  195. {
  196. Ctrl->FlashSR = 0xff;
  197. Ctrl->Tx[0] = SPIFLASH_CMD_RDSR;
  198. Ctrl->Rx[1] = 0xff;
  199. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 2);
  200. if (!Ctrl->SPIError)
  201. {
  202. Ctrl->FlashSR = Ctrl->Rx[1];
  203. }
  204. else
  205. {
  206. DBGF;
  207. return -ERROR_OPERATION_FAILED;
  208. }
  209. //SF_DBG("%02x", Ctrl->FlashSR);
  210. return ERROR_NONE;
  211. }
  212. int32_t SPIFlash_CheckBusy(SPIFlash_CtrlStruct *Ctrl)
  213. {
  214. int Result = SPIFlash_ReadSR(Ctrl);
  215. if (Result < 0)
  216. {
  217. return -ERROR_OPERATION_FAILED;
  218. }
  219. if (!Ctrl->SPIError && !(Ctrl->FlashSR & SPIFLASH_SR_BUSY))
  220. {
  221. //DBGF;
  222. Ctrl->IsPPErase = 0;
  223. }
  224. else
  225. {
  226. //DBGF;
  227. }
  228. return ERROR_NONE;
  229. }
  230. uint8_t SPIFlash_WaitOpDone(SPIFlash_CtrlStruct *Ctrl)
  231. {
  232. uint32_t FlashAddress, DummyLen;
  233. switch(Ctrl->State)
  234. {
  235. case SPIFLASH_STATE_READ:
  236. if (SPI_IsTransferBusy(Ctrl->SpiID))
  237. {
  238. if (GetSysTick() > Ctrl->SPIEndTick)
  239. {
  240. SF_DBG("spi xfer timeout!");
  241. Ctrl->SPIError = 1;
  242. Ctrl->State = SPIFLASH_STATE_IDLE;
  243. SPI_TransferStop(Ctrl->SpiID);
  244. SPIFlash_CS(Ctrl, 0);
  245. return 1;
  246. }
  247. }
  248. else
  249. {
  250. Ctrl->State = SPIFLASH_STATE_IDLE;
  251. SPIFlash_CS(Ctrl, 0);
  252. return 1;
  253. }
  254. break;
  255. case SPIFLASH_STATE_ERASE:
  256. SPIFlash_CheckBusy(Ctrl);
  257. if (!Ctrl->IsPPErase)
  258. {
  259. if (Ctrl->FinishLen >= Ctrl->DataLen)
  260. {
  261. Ctrl->FlashError = 0;
  262. Ctrl->State = SPIFLASH_STATE_IDLE;
  263. return 1;
  264. }
  265. SPIFlash_WriteEnable(Ctrl);
  266. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  267. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  268. if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
  269. {
  270. SF_DBG("erase block 0x%x", FlashAddress);
  271. Ctrl->Tx[0] = SPIFLASH_CMD_BE;
  272. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseBlockTime * CORE_TICK_1MS;
  273. Ctrl->FinishLen += SPI_FLASH_BLOCK_SIZE;
  274. }
  275. else
  276. {
  277. SF_DBG("erase sector 0x%x", FlashAddress);
  278. Ctrl->Tx[0] = SPIFLASH_CMD_SE;
  279. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseSectorTime * CORE_TICK_1MS;
  280. Ctrl->FinishLen += SPI_FLASH_SECTOR_SIZE;
  281. }
  282. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  283. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  284. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  285. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
  286. }
  287. else
  288. {
  289. if (GetSysTick() >= Ctrl->FlashOPEndTick)
  290. {
  291. SF_DBG("erase timeout!");
  292. Ctrl->FlashError = 1;
  293. Ctrl->State = SPIFLASH_STATE_IDLE;
  294. return 1;
  295. }
  296. }
  297. break;
  298. case SPIFLASH_STATE_WRITE:
  299. if (SPI_IsTransferBusy(Ctrl->SpiID))
  300. {
  301. if (GetSysTick() > Ctrl->SPIEndTick)
  302. {
  303. SF_DBG("spi xfer timeout!");
  304. Ctrl->SPIError = 1;
  305. Ctrl->FlashError = 1;
  306. Ctrl->State = SPIFLASH_STATE_IDLE;
  307. SPI_TransferStop(Ctrl->SpiID);
  308. SPIFlash_CS(Ctrl, 0);
  309. return 1;
  310. }
  311. }
  312. else
  313. {
  314. SPIFlash_CheckBusy(Ctrl);
  315. if (!Ctrl->IsPPErase)
  316. {
  317. if (Ctrl->FinishLen >= Ctrl->DataLen)
  318. {
  319. Ctrl->FlashError = 0;
  320. Ctrl->State = SPIFLASH_STATE_IDLE;
  321. return 1;
  322. }
  323. SPIFlash_WriteEnable(Ctrl);
  324. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  325. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  326. SF_DBG("Program 0x%x", FlashAddress);
  327. Ctrl->Tx[0] = SPIFLASH_CMD_PP;
  328. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  329. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  330. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  331. if (DummyLen > SPIFLASH_PAGE_LEN)
  332. {
  333. DummyLen = SPIFLASH_PAGE_LEN;
  334. }
  335. memcpy(Ctrl->Tx + 4, Ctrl->TxBuf + Ctrl->FinishLen, DummyLen);
  336. SPIFlash_CS(Ctrl, 1);
  337. Ctrl->SPIError = 0;
  338. SPI_Transfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, DummyLen + 4, Ctrl->IsSpiDMAMode);
  339. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->ProgramTime * CORE_TICK_1MS;
  340. Ctrl->SPIEndTick = GetSysTick() + CORE_TICK_1MS;
  341. Ctrl->FinishLen += DummyLen;
  342. }
  343. else
  344. {
  345. if (GetSysTick() >= Ctrl->FlashOPEndTick)
  346. {
  347. SF_DBG("Program timeout!");
  348. Ctrl->FlashError = 1;
  349. Ctrl->State = SPIFLASH_STATE_IDLE;
  350. return 1;
  351. }
  352. }
  353. }
  354. break;
  355. default:
  356. Ctrl->FlashError = 1;
  357. Ctrl->State = SPIFLASH_STATE_IDLE;
  358. return 1;
  359. }
  360. return 0;
  361. }
  362. int32_t SPIFlash_WriteEnable(SPIFlash_CtrlStruct *Ctrl)
  363. {
  364. Ctrl->Tx[0] = SPIFLASH_CMD_WREN;
  365. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 1);
  366. return 0;
  367. }
  368. int32_t SPIFlash_Read(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint8_t *Buf, uint32_t Length, uint8_t FastRead)
  369. {
  370. #ifdef __BUILD_OS__
  371. Task_EventStruct Event;
  372. #endif
  373. Ctrl->FlashError = 0;
  374. Ctrl->Tx[1] = (Address & 0x00ff0000) >> 16;
  375. Ctrl->Tx[2] = (Address & 0x0000ff00) >> 8;
  376. Ctrl->Tx[3] = (Address & 0x000000ff);
  377. SPIFlash_CS(Ctrl, 1);
  378. Ctrl->SPIError = 0;
  379. switch (FastRead)
  380. {
  381. case 0:
  382. Ctrl->Tx[0] = SPIFLASH_CMD_READ;
  383. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, 4);
  384. break;
  385. default:
  386. Ctrl->Tx[0] = SPIFLASH_CMD_FTRD;
  387. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, 5);
  388. break;
  389. }
  390. if (Ctrl->IsBlockMode)
  391. {
  392. #ifdef __BUILD_OS__
  393. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  394. {
  395. Ctrl->SPIError = 0;
  396. SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
  397. SPI_Transfer(Ctrl->SpiID, Buf, Buf, Length, Ctrl->IsSpiDMAMode);
  398. if (Task_GetEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, &Event, Ctrl->TaskCB, Length * CORE_TICK_1US + CORE_TICK_1MS))
  399. {
  400. Ctrl->SPIError = 1;
  401. SPI_TransferStop(Ctrl->SpiID);
  402. }
  403. SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
  404. SPIFlash_CS(Ctrl, 0);
  405. }
  406. else
  407. #endif
  408. {
  409. SPI_BlockTransfer(Ctrl->SpiID, Buf, Buf, Length);
  410. SPIFlash_CS(Ctrl, 0);
  411. }
  412. }
  413. else
  414. {
  415. Ctrl->State = SPIFLASH_STATE_READ;
  416. SPIFlash_CS(Ctrl, 1);
  417. Ctrl->SPIError = 0;
  418. SPI_Transfer(Ctrl->SpiID, Buf, Buf, Length, Ctrl->IsSpiDMAMode);
  419. Ctrl->SPIEndTick = GetSysTick() + Length * CORE_TICK_1US + CORE_TICK_1MS;
  420. }
  421. return Ctrl->FlashError;
  422. }
  423. int32_t SPIFlash_Write(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, const uint8_t *Buf, uint32_t Length)
  424. {
  425. #ifdef __BUILD_OS__
  426. Task_EventStruct Event;
  427. #endif
  428. uint32_t FlashAddress, DummyLen;
  429. Ctrl->FlashError = 0;
  430. Ctrl->AddrStart = Address;
  431. Ctrl->TxBuf = Buf;
  432. Ctrl->DataLen = Length;
  433. Ctrl->FinishLen = 0;
  434. Ctrl->SPIError = 0;
  435. // SF_DBG("%x,%u", Address, Length);
  436. if (Ctrl->IsBlockMode)
  437. {
  438. while((Ctrl->FinishLen < Ctrl->DataLen) && !Ctrl->SPIError)
  439. {
  440. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  441. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  442. SPIFlash_WriteEnable(Ctrl);
  443. Ctrl->Tx[0] = SPIFLASH_CMD_PP;
  444. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  445. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  446. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  447. if (DummyLen > SPIFLASH_PAGE_LEN)
  448. {
  449. DummyLen = SPIFLASH_PAGE_LEN;
  450. }
  451. memcpy(Ctrl->Tx + 4, Ctrl->TxBuf + Ctrl->FinishLen, DummyLen);
  452. #ifdef __BUILD_OS__
  453. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  454. {
  455. SPIFlash_CS(Ctrl, 1);
  456. Ctrl->SPIError = 0;
  457. SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
  458. SPI_Transfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, DummyLen + 4, Ctrl->IsSpiDMAMode);
  459. if (Task_GetEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, &Event, Ctrl->TaskCB, CORE_TICK_1MS))
  460. {
  461. Ctrl->SPIError = 1;
  462. SPI_TransferStop(Ctrl->SpiID);
  463. }
  464. SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
  465. SPIFlash_CS(Ctrl, 0);
  466. }
  467. else
  468. #endif
  469. {
  470. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, DummyLen + 4);
  471. }
  472. Ctrl->FinishLen += DummyLen;
  473. if (Ctrl->SPIError)
  474. {
  475. break;
  476. }
  477. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->ProgramTime * CORE_TICK_1MS;
  478. Ctrl->IsPPErase = 1;
  479. while (Ctrl->IsPPErase && (GetSysTick() < Ctrl->FlashOPEndTick))
  480. {
  481. SPIFlash_Wait(Ctrl, Ctrl->ProgramWaitTimeUS * CORE_TICK_1US);
  482. SPIFlash_CheckBusy(Ctrl);
  483. }
  484. if (Ctrl->IsPPErase)
  485. {
  486. DBGF;
  487. Ctrl->FlashError = 1;
  488. return -ERROR_OPERATION_FAILED;
  489. }
  490. }
  491. //SF_DBG("write ok!")
  492. if (Ctrl->SPIError)
  493. {
  494. DBGF;
  495. Ctrl->FlashError = 1;
  496. return -ERROR_OPERATION_FAILED;
  497. }
  498. }
  499. else
  500. {
  501. Ctrl->State = SPIFLASH_STATE_WRITE;
  502. }
  503. return Ctrl->FlashError;
  504. }
  505. int32_t SPIFlash_Erase(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint32_t Length)
  506. {
  507. uint32_t FlashAddress, DummyLen, Tick;
  508. Ctrl->FlashError = 0;
  509. Ctrl->AddrStart = Address;
  510. Ctrl->DataLen = Length;
  511. Ctrl->FinishLen = 0;
  512. if (Ctrl->IsBlockMode)
  513. {
  514. while(Ctrl->FinishLen < Ctrl->DataLen)
  515. {
  516. SPIFlash_WriteEnable(Ctrl);
  517. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  518. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  519. if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
  520. {
  521. // SF_DBG("erase block 0x%x", FlashAddress);
  522. Ctrl->Tx[0] = SPIFLASH_CMD_BE;
  523. Tick = Ctrl->EraseBlockWaitTime * CORE_TICK_1MS;
  524. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseBlockTime * CORE_TICK_1MS;
  525. Ctrl->FinishLen += SPI_FLASH_BLOCK_SIZE;
  526. }
  527. else
  528. {
  529. // SF_DBG("erase sector 0x%x", FlashAddress);
  530. Ctrl->Tx[0] = SPIFLASH_CMD_SE;
  531. Tick = Ctrl->EraseSectorWaitTime * CORE_TICK_1MS;
  532. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseSectorTime * CORE_TICK_1MS;
  533. Ctrl->FinishLen += SPI_FLASH_SECTOR_SIZE;
  534. }
  535. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  536. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  537. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  538. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
  539. Ctrl->IsPPErase = 1;
  540. while (Ctrl->IsPPErase && (GetSysTick() < Ctrl->FlashOPEndTick))
  541. {
  542. SPIFlash_Wait(Ctrl, Tick);
  543. SPIFlash_CheckBusy(Ctrl);
  544. }
  545. if (Ctrl->IsPPErase)
  546. {
  547. Ctrl->FlashError = 1;
  548. return -ERROR_OPERATION_FAILED;
  549. }
  550. }
  551. }
  552. else
  553. {
  554. Ctrl->State = SPIFLASH_STATE_ERASE;
  555. }
  556. return Ctrl->FlashError;
  557. }