core_flash.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #include "bl_inc.h"
  22. #ifdef __RUN_IN_RAM__
  23. #define __disable_irq()
  24. #define __disable_fault_irq()
  25. #define __enable_fault_irq()
  26. #define __enable_irq()
  27. #endif
  28. void __FUNC_IN_RAM__ CACHE_EncryptInit(uint8_t *key, uint8_t *iv, uint32_t start, uint32_t end)
  29. {
  30. int i;
  31. uint32_t ckey[4];
  32. uint32_t civ[4];
  33. for(i = 0; i < 4; i++)
  34. {
  35. ckey[3 - i] = BytesGetBe32(key + i * 4);
  36. civ[3 - i] = BytesGetBe32(iv + i * 4);
  37. }
  38. __disable_irq();
  39. for (i = 0; i < 5000; i++)
  40. {
  41. if (CACHE->CACHE_CS & CACHE_IS_BUSY) //cache正在从Flash中取指
  42. {
  43. continue;
  44. }
  45. break;
  46. }
  47. CACHE->CACHE_CS = 0x00000000 + CACHE_KEY_GEN; //密钥生成模式
  48. CACHE->CACHE_I3 = civ[3];
  49. CACHE->CACHE_I2 = civ[2];
  50. CACHE->CACHE_I1 = civ[1];
  51. CACHE->CACHE_I0 = civ[0];
  52. CACHE->CACHE_K3 = ckey[3];
  53. CACHE->CACHE_K2 = ckey[2];
  54. CACHE->CACHE_K1 = ckey[1];
  55. CACHE->CACHE_K0 = ckey[0];
  56. CACHE->CACHE_CS |= CACHE_KEY_GEN_START;
  57. for (i = 0; i < 10000; i++)
  58. {
  59. if((CACHE->CACHE_CS & CACHE_KEY_GEN_START) == 0)
  60. {
  61. break;
  62. }
  63. }
  64. CACHE->CACHE_CS = 0;
  65. CACHE->CACHE_SADDR = start;
  66. CACHE->CACHE_EADDR = end;
  67. CACHE->CACHE_CONFIG = 0xA5A50055;
  68. __enable_irq();
  69. }
  70. void __FUNC_IN_RAM__ CACHE_CleanAll(CACHE_TypeDef *Cache)
  71. {
  72. while (Cache->CACHE_CS & CACHE_IS_BUSY);
  73. Cache->CACHE_REF = CACHE_REFRESH_ALLTAG;
  74. Cache->CACHE_REF |= CACHE_REFRESH;
  75. while ((Cache->CACHE_REF & CACHE_REFRESH));
  76. }
  77. #ifdef __RUN_IN_RAM__
  78. typedef struct
  79. {
  80. uint8_t Instruction;
  81. QSPI_BusModeTypeDef BusMode;
  82. QSPI_CmdFormatTypeDef CmdFormat;
  83. uint32_t Address;
  84. uint32_t WrData;
  85. uint32_t RdData;
  86. }FLASH_CommandTypeDef;
  87. #define QSPI_FIFO_NUM 32
  88. #define FLASH_QSPI_TIMEOUT_DEFAULT_CNT (19000) //18944
  89. #define FLASH_QSPI_ACCESS_REQ_ENABLE (0x00000001U)
  90. #define FLASH_QSPI_FLASH_READY_ENABLE (0x0000006BU)
  91. static int32_t prvQSPI_Command(FLASH_CommandTypeDef *cmd, int32_t timeout)
  92. {
  93. int32_t i;
  94. int32_t status = -ERROR_OPERATION_FAILED;
  95. QSPI->REG_WDATA = cmd->WrData;
  96. QSPI->ADDRES = (QSPI->ADDRES & ~QUADSPI_ADDRESS_ADR) | (cmd->Address << 8);
  97. QSPI->FCU_CMD = (QSPI->FCU_CMD & ~(QUADSPI_FCU_CMD_CODE | QUADSPI_FCU_CMD_BUS_MODE | QUADSPI_FCU_CMD_CMD_FORMAT | QUADSPI_FCU_CMD_ACCESS_REQ)) | ((cmd->Instruction << 24) |((uint32_t)( cmd->BusMode<< 8)) |((uint32_t)( cmd->CmdFormat << 4))| (FLASH_QSPI_ACCESS_REQ_ENABLE));
  98. //Wait For CMD done
  99. for (i = 0; i < timeout; i += 4)
  100. {
  101. if (QSPI->INT_RAWSTATUS & QUADSPI_INT_RAWSTATUS_DONE_IR)
  102. {
  103. QSPI->INT_CLEAR = QUADSPI_INT_CLEAR_DONE;
  104. status = ERROR_NONE;
  105. break;
  106. }
  107. }
  108. cmd->RdData = QSPI->REG_RDATA;
  109. return status;
  110. }
  111. static int32_t prvQSPI_WriteEnable(QSPI_BusModeTypeDef bus_mode)
  112. {
  113. FLASH_CommandTypeDef sCommand;
  114. sCommand.Instruction = SPIFLASH_CMD_WREN;
  115. sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8;
  116. if (QSPI_BUSMODE_444 == bus_mode)
  117. {
  118. sCommand.BusMode = QSPI_BUSMODE_444;
  119. }
  120. else
  121. {
  122. sCommand.BusMode = QSPI_BUSMODE_111;
  123. }
  124. if (prvQSPI_Command(&sCommand, FLASH_QSPI_TIMEOUT_DEFAULT_CNT))
  125. {
  126. return -ERROR_OPERATION_FAILED;
  127. }
  128. return ERROR_NONE;
  129. }
  130. //PP,QPP,Sector Erase,Block Erase, Chip Erase, Write Status Reg, Erase Security Reg
  131. int32_t prvQSPI_IsBusy(QSPI_BusModeTypeDef bus_mode)
  132. {
  133. FLASH_CommandTypeDef sCommand;
  134. sCommand.Instruction = SPIFLASH_CMD_RDSR;
  135. sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_RREG8;
  136. if (QSPI_BUSMODE_444 == bus_mode)
  137. {
  138. sCommand.BusMode = QSPI_BUSMODE_444;
  139. }
  140. else
  141. {
  142. sCommand.BusMode = QSPI_BUSMODE_111;
  143. }
  144. if (prvQSPI_Command(&sCommand, FLASH_QSPI_TIMEOUT_DEFAULT_CNT))
  145. {
  146. return -ERROR_OPERATION_FAILED;
  147. }
  148. if (sCommand.RdData & BIT0)
  149. {
  150. return -ERROR_DEVICE_BUSY;
  151. }
  152. return ERROR_NONE;
  153. }
  154. int32_t Flash_EraseStart(uint32_t Address, uint8_t IsBlock)
  155. {
  156. FLASH_CommandTypeDef sCommand;
  157. Address &= (uint32_t)(0x00FFFFFF);
  158. while (CACHE->CACHE_CS & CACHE_IS_BUSY);
  159. sCommand.BusMode = QSPI_BUSMODE_111;
  160. sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24;
  161. if (prvQSPI_WriteEnable(sCommand.BusMode) != 0)
  162. {
  163. return -ERROR_OPERATION_FAILED;
  164. }
  165. if (IsBlock)
  166. {
  167. sCommand.Instruction = SPIFLASH_CMD_BE;
  168. }
  169. else
  170. {
  171. sCommand.Instruction = SPIFLASH_CMD_SE;
  172. }
  173. sCommand.Address = Address;
  174. if (prvQSPI_Command(&sCommand, FLASH_QSPI_TIMEOUT_DEFAULT_CNT))
  175. {
  176. return -ERROR_OPERATION_FAILED;
  177. }
  178. return ERROR_NONE;
  179. }
  180. int32_t Flash_CheckBusy(void)
  181. {
  182. return prvQSPI_IsBusy(QSPI_BUSMODE_111);
  183. }
  184. #endif
  185. #if 0
  186. int32_t __FUNC_IN_RAM__ Flash_Program(uint32_t Address, const uint8_t *pBuf, uint32_t Len)
  187. {
  188. FLASH_CommandTypeDef sCommand;
  189. uint32_t FinishLen = 0, DummyLen, ProgramLen, i;
  190. int32_t status;
  191. uint32_t PageData[64];
  192. /* Initialize the adress variables */
  193. sCommand.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
  194. sCommand.BusMode = QSPI_BUSMODE_114;
  195. sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
  196. Address &= 0x00ffffff;
  197. while(FinishLen < Len)
  198. {
  199. if (prvQSPI_WriteEnable(QSPI_BUSMODE_111))
  200. {
  201. return -ERROR_OPERATION_FAILED;
  202. }
  203. #if (defined __FLASH_DISABLE_IRQ__)
  204. __disable_irq();
  205. ProgramLen = ((Len - FinishLen) > 4)?4:(Len - FinishLen);
  206. #else
  207. ProgramLen = ((Len - FinishLen) > QSPI_FIFO_NUM)?QSPI_FIFO_NUM:(Len - FinishLen);
  208. #endif
  209. for(i = 0; i < ProgramLen; i+=4)
  210. {
  211. PageData[i >> 2] = BytesGetLe32(pBuf + i);
  212. }
  213. QSPI->FIFO_CNTL |= QUADSPI_FIFO_CNTL_TFFH;
  214. QSPI->BYTE_NUM = (ProgramLen << 16);
  215. sCommand.Address = Address + FinishLen;
  216. DummyLen = 0;
  217. while((DummyLen < ProgramLen) && !(QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_TFFL))
  218. {
  219. QSPI->WR_FIFO = PageData[DummyLen >> 2];
  220. DummyLen += 4;
  221. }
  222. QSPI->ADDRES = (QSPI->ADDRES & ~QUADSPI_ADDRESS_ADR) | (sCommand.Address << 8);
  223. QSPI->FCU_CMD = (QSPI->FCU_CMD & ~(QUADSPI_FCU_CMD_CODE | QUADSPI_FCU_CMD_BUS_MODE | QUADSPI_FCU_CMD_CMD_FORMAT | QUADSPI_FCU_CMD_ACCESS_REQ)) | ((sCommand.Instruction << 24) |((uint32_t)( sCommand.BusMode<< 8)) |((uint32_t)( sCommand.CmdFormat << 4))| (FLASH_QSPI_ACCESS_REQ_ENABLE));
  224. while(DummyLen < ProgramLen)
  225. {
  226. while(QSPI->FIFO_CNTL & QUADSPI_FIFO_CNTL_TFFL)
  227. {
  228. }
  229. QSPI->WR_FIFO = PageData[DummyLen >> 2];
  230. DummyLen += 4;
  231. }
  232. // DBG("%u", DummyLen);
  233. status = -ERROR_OPERATION_FAILED;
  234. for (i = 0; i < FLASH_QSPI_TIMEOUT_DEFAULT_CNT; i += 4)
  235. {
  236. if (QSPI->INT_RAWSTATUS & QUADSPI_INT_RAWSTATUS_DONE_IR)
  237. {
  238. QSPI->INT_CLEAR = QUADSPI_INT_CLEAR_DONE;
  239. status = ERROR_NONE;
  240. break;
  241. }
  242. }
  243. if (status)
  244. {
  245. #if (defined __FLASH_DISABLE_IRQ__)
  246. CACHE_CleanAll(CACHE);
  247. __enable_irq();
  248. #endif
  249. return status;
  250. }
  251. while (prvQSPI_IsBusy(QSPI_BUSMODE_111));
  252. #if (defined __FLASH_DISABLE_IRQ__)
  253. __enable_irq();
  254. #endif
  255. FinishLen += ProgramLen;
  256. }
  257. #if (defined __FLASH_DISABLE_IRQ__)
  258. CACHE_CleanAll(CACHE);
  259. #endif
  260. return ERROR_NONE;
  261. }
  262. #endif
  263. /**
  264. * @brief Flash Erase Sector.
  265. * @param sectorAddress: The sector address to be erased
  266. * @retval FLASH Status: The returned value can be: QSPI_STATUS_ERROR, QSPI_STATUS_OK
  267. */
  268. uint8_t FLASH_EraseSector(uint32_t sectorAddress)
  269. {
  270. uint8_t ret;
  271. __disable_irq();
  272. //__disable_fault_irq();
  273. ret = ROM_QSPI_EraseSector(NULL, sectorAddress);
  274. //__enable_fault_irq();
  275. __enable_irq();
  276. return ret;
  277. }
  278. /**
  279. * @brief Flash Program Interface.
  280. * @param addr: specifies the address to be programmed.
  281. * @param size: specifies the size to be programmed.
  282. * @param buffer: pointer to the data to be programmed, need word aligned
  283. * @retval FLASH Status: The returned value can be: QSPI_STATUS_ERROR, QSPI_STATUS_OK
  284. */
  285. uint8_t FLASH_ProgramPage(uint32_t addr, uint32_t size, uint8_t *buffer)
  286. {
  287. uint8_t ret;
  288. QSPI_CommandTypeDef cmdType;
  289. cmdType.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
  290. cmdType.BusMode = QSPI_BUSMODE_114;
  291. cmdType.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
  292. __disable_irq();
  293. //__disable_fault_irq();
  294. ret = ROM_QSPI_ProgramPage(&cmdType, DMA_Channel_1, addr, size, buffer);
  295. //__enable_fault_irq();
  296. __enable_irq();
  297. return ret;
  298. }
  299. int32_t Flash_Erase(uint32_t Address, uint32_t Length)
  300. {
  301. uint32_t TotalLen = 0;
  302. QSPI_CommandTypeDef sCommand;
  303. sCommand.BusMode = QSPI_BUSMODE_111;
  304. sCommand.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24;
  305. uint32_t FlashAddress, DummyLen;
  306. uint8_t ret;
  307. while (TotalLen < Length)
  308. {
  309. FlashAddress = Address + TotalLen;
  310. DummyLen = Length - TotalLen;
  311. if (!(FlashAddress & SPI_FLASH_BLOCK_MASK) && (DummyLen >= SPI_FLASH_BLOCK_SIZE))
  312. {
  313. sCommand.Instruction = SPIFLASH_CMD_BE;
  314. TotalLen += SPI_FLASH_BLOCK_SIZE;
  315. }
  316. else
  317. {
  318. sCommand.Instruction = SPIFLASH_CMD_SE;
  319. TotalLen += SPI_FLASH_SECTOR_SIZE;
  320. }
  321. __disable_irq();
  322. //__disable_fault_irq();
  323. ret = ROM_QSPI_EraseSector(&sCommand, FlashAddress);
  324. //__enable_fault_irq();
  325. __enable_irq();
  326. }
  327. CACHE_CleanAll(CACHE);
  328. return ERROR_NONE;
  329. }
  330. int32_t Flash_Program(uint32_t Address, const uint8_t *pBuf, uint32_t Len)
  331. {
  332. uint32_t size = (Len + (4 - 1)) & (~(4 - 1));
  333. uint32_t Pos = 0;
  334. uint8_t ret;
  335. QSPI_CommandTypeDef cmdType;
  336. cmdType.Instruction = QUAD_INPUT_PAGE_PROG_CMD;
  337. cmdType.BusMode = QSPI_BUSMODE_114;
  338. cmdType.CmdFormat = QSPI_CMDFORMAT_CMD8_ADDR24_PDAT;
  339. while(Pos < size)
  340. {
  341. if ((size - Pos) > __FLASH_PAGE_SIZE__)
  342. {
  343. __disable_irq();
  344. //__disable_fault_irq();
  345. ret = ROM_QSPI_ProgramPage(&cmdType, DMA_Channel_1, Address + Pos, __FLASH_PAGE_SIZE__, pBuf + Pos);
  346. //__enable_fault_irq();
  347. __enable_irq();
  348. Pos += __FLASH_PAGE_SIZE__;
  349. }
  350. else
  351. {
  352. __disable_irq();
  353. //__disable_fault_irq();
  354. ret = ROM_QSPI_ProgramPage(&cmdType, DMA_Channel_1, Address + Pos, (size - Pos), pBuf + Pos);
  355. //__enable_fault_irq();
  356. __enable_irq();
  357. Pos += (size - Pos);
  358. }
  359. }
  360. CACHE_CleanAll(CACHE);
  361. return ERROR_NONE;
  362. }
  363. #if 0
  364. int Flash_EraseSector(uint32_t address, uint8_t NeedCheck)
  365. {
  366. uint8_t buf[__FLASH_PAGE_SIZE__];
  367. uint32_t i;
  368. uint8_t retry = 1;
  369. void *res;
  370. memset(buf, 0xff, __FLASH_PAGE_SIZE__);
  371. BL_ERASESECTOR_AGAIN:
  372. FLASH_EraseSector(address);
  373. #if (defined __BUILD_OS__) || (defined __BUILD_APP__)
  374. CACHE_CleanAll(CACHE);
  375. #endif
  376. if (!NeedCheck) return ERROR_NONE;
  377. for(i = 0; i < 4096; i+=__FLASH_PAGE_SIZE__)
  378. {
  379. res = memcmp(address + i, buf, __FLASH_PAGE_SIZE__);
  380. if (res)
  381. {
  382. DBG_INFO("%x", res);
  383. if (retry)
  384. {
  385. retry = 0;
  386. goto BL_ERASESECTOR_AGAIN;
  387. }
  388. else
  389. {
  390. return -1;
  391. }
  392. }
  393. }
  394. return 0;
  395. }
  396. int Flash_ProgramData(uint32_t address, uint32_t *Data, uint32_t Len, uint8_t NeedCheck)
  397. {
  398. void *res;
  399. uint32_t size = (Len + (4 - 1)) & (~(4 - 1));
  400. FLASH_ProgramPage(address, size, Data);
  401. #if (defined __BUILD_OS__) || (defined __BUILD_APP__)
  402. CACHE_CleanAll(CACHE);
  403. #endif
  404. if (!NeedCheck) return ERROR_NONE;
  405. res = memcmp(address, Data, Len);
  406. if (res)
  407. {
  408. DBG_INFO("%x", res);
  409. FLASH_ProgramPage(address, size, Data);
  410. #if (defined __BUILD_OS__) || (defined __BUILD_APP__)
  411. CACHE_CleanAll(CACHE);
  412. #endif
  413. res = memcmp(address, Data, size);
  414. if (res)
  415. {
  416. DBG_INFO("%x", res);
  417. return -1;
  418. }
  419. }
  420. return 0;
  421. }
  422. #endif