dev_spiflash.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  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. OS_EVENT 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. SPIFlash_ReadSR(Ctrl);
  156. if (Ctrl->FlashSR != 0xff && Ctrl->FlashSR != 0x0)
  157. {
  158. if (!Ctrl->SPIError)
  159. {
  160. SPIFlash_WriteEnable(Ctrl);
  161. SPIFlash_WriteSR(Ctrl, 0);
  162. SPIFlash_ReadSR(Ctrl);
  163. while(Ctrl->FlashSR & SPIFLASH_SR_BUSY)
  164. {
  165. SPIFlash_ReadSR(Ctrl);
  166. }
  167. }
  168. }
  169. }
  170. int32_t SPIFlash_ID(SPIFlash_CtrlStruct *Ctrl)
  171. {
  172. uint32_t i,j;
  173. for(i = 0; i < 10; i++)
  174. {
  175. Ctrl->Tx[0] = SPIFLASH_CMD_RDID;
  176. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
  177. if (Ctrl->Rx[1] == 0xff || !Ctrl->Rx[1])
  178. {
  179. SPIFlash_Wait(Ctrl, 10 * CORE_TICK_1MS);
  180. }
  181. else
  182. {
  183. break;
  184. }
  185. }
  186. if (!Ctrl->SPIError)
  187. {
  188. memcpy(Ctrl->FlashID, Ctrl->Rx+1, 3);
  189. for (i = 0; i < sizeof(SPI_FLASH_VENDOR_DICT)/sizeof(uint8_t); i++)
  190. {
  191. //读取到正确的ID后,开始解除FLASH锁定
  192. if (Ctrl->FlashID[0] == SPI_FLASH_VENDOR_DICT[i])
  193. {
  194. Ctrl->Size = 32;
  195. for (j = 0; j < sizeof(SPI_FLASH_SIZE_DICT)/sizeof(uint8_t); j++)
  196. {
  197. if (Ctrl->FlashID[2] == SPI_FLASH_SIZE_DICT[j])
  198. {
  199. return ERROR_NONE;
  200. }
  201. Ctrl->Size *= 2;
  202. }
  203. }
  204. }
  205. return -ERROR_DEVICE_BUSY;
  206. }
  207. return ERROR_NONE;
  208. }
  209. int32_t SPIFlash_ReadSR(SPIFlash_CtrlStruct *Ctrl)
  210. {
  211. Ctrl->FlashSR = 0xff;
  212. Ctrl->Tx[0] = SPIFLASH_CMD_RDSR;
  213. Ctrl->Rx[1] = 0xff;
  214. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 2);
  215. if (!Ctrl->SPIError)
  216. {
  217. Ctrl->FlashSR = Ctrl->Rx[1];
  218. }
  219. else
  220. {
  221. DBGF;
  222. return -ERROR_OPERATION_FAILED;
  223. }
  224. //SF_DBG("%02x", Ctrl->FlashSR);
  225. return ERROR_NONE;
  226. }
  227. int32_t SPIFlash_CheckBusy(SPIFlash_CtrlStruct *Ctrl)
  228. {
  229. int Result = SPIFlash_ReadSR(Ctrl);
  230. if (Result < 0)
  231. {
  232. return -ERROR_OPERATION_FAILED;
  233. }
  234. if (!Ctrl->SPIError && !(Ctrl->FlashSR & SPIFLASH_SR_BUSY))
  235. {
  236. //DBGF;
  237. Ctrl->IsPPErase = 0;
  238. }
  239. else
  240. {
  241. //DBGF;
  242. }
  243. return ERROR_NONE;
  244. }
  245. uint8_t SPIFlash_WaitOpDone(SPIFlash_CtrlStruct *Ctrl)
  246. {
  247. uint32_t FlashAddress, DummyLen;
  248. switch(Ctrl->State)
  249. {
  250. case SPIFLASH_STATE_READ:
  251. if (SPI_IsTransferBusy(Ctrl->SpiID))
  252. {
  253. if (GetSysTick() > Ctrl->SPIEndTick)
  254. {
  255. SF_DBG("spi xfer timeout!");
  256. Ctrl->SPIError = 1;
  257. Ctrl->State = SPIFLASH_STATE_IDLE;
  258. SPI_TransferStop(Ctrl->SpiID);
  259. SPIFlash_CS(Ctrl, 0);
  260. return 1;
  261. }
  262. }
  263. else
  264. {
  265. Ctrl->State = SPIFLASH_STATE_IDLE;
  266. SPIFlash_CS(Ctrl, 0);
  267. return 1;
  268. }
  269. break;
  270. case SPIFLASH_STATE_ERASE:
  271. SPIFlash_CheckBusy(Ctrl);
  272. if (!Ctrl->IsPPErase)
  273. {
  274. if (Ctrl->FinishLen >= Ctrl->DataLen)
  275. {
  276. Ctrl->FlashError = 0;
  277. Ctrl->State = SPIFLASH_STATE_IDLE;
  278. return 1;
  279. }
  280. SPIFlash_WriteEnable(Ctrl);
  281. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  282. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  283. if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
  284. {
  285. SF_DBG("erase block 0x%x", FlashAddress);
  286. Ctrl->Tx[0] = SPIFLASH_CMD_BE;
  287. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseBlockTime * CORE_TICK_1MS;
  288. Ctrl->FinishLen += SPI_FLASH_BLOCK_SIZE;
  289. }
  290. else
  291. {
  292. SF_DBG("erase sector 0x%x", FlashAddress);
  293. Ctrl->Tx[0] = SPIFLASH_CMD_SE;
  294. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseSectorTime * CORE_TICK_1MS;
  295. Ctrl->FinishLen += SPI_FLASH_SECTOR_SIZE;
  296. }
  297. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  298. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  299. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  300. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
  301. }
  302. else
  303. {
  304. if (GetSysTick() >= Ctrl->FlashOPEndTick)
  305. {
  306. SF_DBG("erase timeout!");
  307. Ctrl->FlashError = 1;
  308. Ctrl->State = SPIFLASH_STATE_IDLE;
  309. return 1;
  310. }
  311. }
  312. break;
  313. case SPIFLASH_STATE_WRITE:
  314. if (SPI_IsTransferBusy(Ctrl->SpiID))
  315. {
  316. if (GetSysTick() > Ctrl->SPIEndTick)
  317. {
  318. SF_DBG("spi xfer timeout!");
  319. Ctrl->SPIError = 1;
  320. Ctrl->FlashError = 1;
  321. Ctrl->State = SPIFLASH_STATE_IDLE;
  322. SPI_TransferStop(Ctrl->SpiID);
  323. SPIFlash_CS(Ctrl, 0);
  324. return 1;
  325. }
  326. }
  327. else
  328. {
  329. SPIFlash_CheckBusy(Ctrl);
  330. if (!Ctrl->IsPPErase)
  331. {
  332. if (Ctrl->FinishLen >= Ctrl->DataLen)
  333. {
  334. Ctrl->FlashError = 0;
  335. Ctrl->State = SPIFLASH_STATE_IDLE;
  336. return 1;
  337. }
  338. SPIFlash_WriteEnable(Ctrl);
  339. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  340. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  341. SF_DBG("Program 0x%x", FlashAddress);
  342. Ctrl->Tx[0] = SPIFLASH_CMD_PP;
  343. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  344. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  345. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  346. if (DummyLen > SPIFLASH_PAGE_LEN)
  347. {
  348. DummyLen = SPIFLASH_PAGE_LEN;
  349. }
  350. memcpy(Ctrl->Tx + 4, Ctrl->TxBuf + Ctrl->FinishLen, DummyLen);
  351. SPIFlash_CS(Ctrl, 1);
  352. Ctrl->SPIError = 0;
  353. SPI_Transfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, DummyLen + 4, Ctrl->IsSpiDMAMode);
  354. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->ProgramTime * CORE_TICK_1MS;
  355. Ctrl->SPIEndTick = GetSysTick() + CORE_TICK_1MS;
  356. Ctrl->FinishLen += DummyLen;
  357. }
  358. else
  359. {
  360. if (GetSysTick() >= Ctrl->FlashOPEndTick)
  361. {
  362. SF_DBG("Program timeout!");
  363. Ctrl->FlashError = 1;
  364. Ctrl->State = SPIFLASH_STATE_IDLE;
  365. return 1;
  366. }
  367. }
  368. }
  369. break;
  370. default:
  371. Ctrl->FlashError = 1;
  372. Ctrl->State = SPIFLASH_STATE_IDLE;
  373. return 1;
  374. }
  375. return 0;
  376. }
  377. int32_t SPIFlash_WriteEnable(SPIFlash_CtrlStruct *Ctrl)
  378. {
  379. Ctrl->Tx[0] = SPIFLASH_CMD_WREN;
  380. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 1);
  381. return 0;
  382. }
  383. int32_t SPIFlash_WriteSR(SPIFlash_CtrlStruct *Ctrl, uint8_t SR)
  384. {
  385. Ctrl->Tx[0] = SPIFLASH_CMD_WRSR;
  386. Ctrl->Tx[1] = SR;
  387. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 2);
  388. return 0;
  389. }
  390. int32_t SPIFlash_Read(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint8_t *Buf, uint32_t Length, uint8_t FastRead)
  391. {
  392. #ifdef __BUILD_OS__
  393. OS_EVENT Event;
  394. #endif
  395. Ctrl->FlashError = 0;
  396. Ctrl->Tx[1] = (Address & 0x00ff0000) >> 16;
  397. Ctrl->Tx[2] = (Address & 0x0000ff00) >> 8;
  398. Ctrl->Tx[3] = (Address & 0x000000ff);
  399. SPIFlash_CS(Ctrl, 1);
  400. Ctrl->SPIError = 0;
  401. switch (FastRead)
  402. {
  403. case 0:
  404. Ctrl->Tx[0] = SPIFLASH_CMD_READ;
  405. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, 4);
  406. break;
  407. default:
  408. Ctrl->Tx[0] = SPIFLASH_CMD_FTRD;
  409. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, 5);
  410. break;
  411. }
  412. if (Ctrl->IsBlockMode)
  413. {
  414. #ifdef __BUILD_OS__
  415. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  416. {
  417. Ctrl->SPIError = 0;
  418. SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
  419. SPI_Transfer(Ctrl->SpiID, Buf, Buf, Length, Ctrl->IsSpiDMAMode);
  420. if (Task_GetEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, &Event, Ctrl->TaskCB, Length * CORE_TICK_1US + CORE_TICK_1MS))
  421. {
  422. Ctrl->SPIError = 1;
  423. SPI_TransferStop(Ctrl->SpiID);
  424. }
  425. SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
  426. SPIFlash_CS(Ctrl, 0);
  427. }
  428. else
  429. #endif
  430. {
  431. SPI_BlockTransfer(Ctrl->SpiID, Buf, Buf, Length);
  432. SPIFlash_CS(Ctrl, 0);
  433. }
  434. }
  435. else
  436. {
  437. Ctrl->State = SPIFLASH_STATE_READ;
  438. SPIFlash_CS(Ctrl, 1);
  439. Ctrl->SPIError = 0;
  440. SPI_Transfer(Ctrl->SpiID, Buf, Buf, Length, Ctrl->IsSpiDMAMode);
  441. Ctrl->SPIEndTick = GetSysTick() + Length * CORE_TICK_1US + CORE_TICK_1MS;
  442. }
  443. return Ctrl->FlashError;
  444. }
  445. int32_t SPIFlash_Write(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, const uint8_t *Buf, uint32_t Length)
  446. {
  447. #ifdef __BUILD_OS__
  448. OS_EVENT Event;
  449. #endif
  450. uint32_t FlashAddress, DummyLen;
  451. Ctrl->FlashError = 0;
  452. Ctrl->AddrStart = Address;
  453. Ctrl->TxBuf = Buf;
  454. Ctrl->DataLen = Length;
  455. Ctrl->FinishLen = 0;
  456. Ctrl->SPIError = 0;
  457. // SF_DBG("%x,%u", Address, Length);
  458. if (Ctrl->IsBlockMode)
  459. {
  460. while((Ctrl->FinishLen < Ctrl->DataLen) && !Ctrl->SPIError)
  461. {
  462. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  463. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  464. SPIFlash_WriteEnable(Ctrl);
  465. Ctrl->Tx[0] = SPIFLASH_CMD_PP;
  466. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  467. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  468. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  469. if (DummyLen > SPIFLASH_PAGE_LEN)
  470. {
  471. DummyLen = SPIFLASH_PAGE_LEN;
  472. }
  473. memcpy(Ctrl->Tx + 4, Ctrl->TxBuf + Ctrl->FinishLen, DummyLen);
  474. #ifdef __BUILD_OS__
  475. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  476. {
  477. SPIFlash_CS(Ctrl, 1);
  478. Ctrl->SPIError = 0;
  479. SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
  480. SPI_Transfer(Ctrl->SpiID, Ctrl->Tx, Ctrl->Rx, DummyLen + 4, Ctrl->IsSpiDMAMode);
  481. if (Task_GetEvent(Ctrl->NotifyTask, DEV_SPIFLASH_SPI_DONE, &Event, Ctrl->TaskCB, CORE_TICK_1MS))
  482. {
  483. Ctrl->SPIError = 1;
  484. SPI_TransferStop(Ctrl->SpiID);
  485. }
  486. SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
  487. SPIFlash_CS(Ctrl, 0);
  488. }
  489. else
  490. #endif
  491. {
  492. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, DummyLen + 4);
  493. }
  494. Ctrl->FinishLen += DummyLen;
  495. if (Ctrl->SPIError)
  496. {
  497. break;
  498. }
  499. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->ProgramTime * CORE_TICK_1MS;
  500. Ctrl->IsPPErase = 1;
  501. while (Ctrl->IsPPErase && (GetSysTick() < Ctrl->FlashOPEndTick))
  502. {
  503. SPIFlash_Wait(Ctrl, Ctrl->ProgramWaitTimeUS * CORE_TICK_1US);
  504. SPIFlash_CheckBusy(Ctrl);
  505. }
  506. if (Ctrl->IsPPErase)
  507. {
  508. DBGF;
  509. Ctrl->FlashError = 1;
  510. return -ERROR_OPERATION_FAILED;
  511. }
  512. }
  513. //SF_DBG("write ok!")
  514. if (Ctrl->SPIError)
  515. {
  516. DBGF;
  517. Ctrl->FlashError = 1;
  518. return -ERROR_OPERATION_FAILED;
  519. }
  520. }
  521. else
  522. {
  523. Ctrl->State = SPIFLASH_STATE_WRITE;
  524. }
  525. return Ctrl->FlashError;
  526. }
  527. int32_t SPIFlash_Erase(SPIFlash_CtrlStruct *Ctrl, uint32_t Address, uint32_t Length)
  528. {
  529. uint32_t FlashAddress, DummyLen, Tick;
  530. Ctrl->FlashError = 0;
  531. Ctrl->AddrStart = Address;
  532. Ctrl->DataLen = Length;
  533. Ctrl->FinishLen = 0;
  534. if (Ctrl->IsBlockMode)
  535. {
  536. while(Ctrl->FinishLen < Ctrl->DataLen)
  537. {
  538. SPIFlash_WriteEnable(Ctrl);
  539. FlashAddress = Ctrl->AddrStart + Ctrl->FinishLen;
  540. DummyLen = Ctrl->DataLen - Ctrl->FinishLen;
  541. if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
  542. {
  543. // SF_DBG("erase block 0x%x", FlashAddress);
  544. Ctrl->Tx[0] = SPIFLASH_CMD_BE;
  545. Tick = Ctrl->EraseBlockWaitTime * CORE_TICK_1MS;
  546. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseBlockTime * CORE_TICK_1MS;
  547. Ctrl->FinishLen += SPI_FLASH_BLOCK_SIZE;
  548. }
  549. else
  550. {
  551. // SF_DBG("erase sector 0x%x", FlashAddress);
  552. Ctrl->Tx[0] = SPIFLASH_CMD_SE;
  553. Tick = Ctrl->EraseSectorWaitTime * CORE_TICK_1MS;
  554. Ctrl->FlashOPEndTick = GetSysTick() + Ctrl->EraseSectorTime * CORE_TICK_1MS;
  555. Ctrl->FinishLen += SPI_FLASH_SECTOR_SIZE;
  556. }
  557. Ctrl->Tx[1] = (FlashAddress & 0x00ff0000) >> 16;
  558. Ctrl->Tx[2] = (FlashAddress & 0x0000ff00) >> 8;
  559. Ctrl->Tx[3] = (FlashAddress & 0x000000ff);
  560. SPIFlash_SpiBlockXfer(Ctrl, Ctrl->Tx, Ctrl->Rx, 4);
  561. Ctrl->IsPPErase = 1;
  562. while (Ctrl->IsPPErase && (GetSysTick() < Ctrl->FlashOPEndTick))
  563. {
  564. SPIFlash_Wait(Ctrl, Tick);
  565. SPIFlash_CheckBusy(Ctrl);
  566. }
  567. if (Ctrl->IsPPErase)
  568. {
  569. Ctrl->FlashError = 1;
  570. return -ERROR_OPERATION_FAILED;
  571. }
  572. }
  573. }
  574. else
  575. {
  576. Ctrl->State = SPIFLASH_STATE_ERASE;
  577. }
  578. return Ctrl->FlashError;
  579. }