eeprom.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. /**使用方法
  2. 1,解锁flash
  3. FLASH_Unlock();
  4. 2,初始化
  5. EE_Init();
  6. 测试例子参考
  7. eeprom_test();
  8. **/
  9. /**
  10. ******************************************************************************
  11. * @file EEPROM_Emulation/src/eeprom.c
  12. * @author MCD Application Team
  13. * @version V3.1.0
  14. * @date 07/27/2009
  15. * @brief This file provides all the EEPROM emulation firmware functions.
  16. ******************************************************************************
  17. * @copy
  18. *
  19. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  20. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  21. * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  22. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  23. * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  24. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  25. *
  26. * <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
  27. */
  28. /** @addtogroup EEPROM_Emulation
  29. * @{
  30. */
  31. /* Includes ------------------------------------------------------------------*/
  32. #include "eeprom.h"
  33. /* Private typedef -----------------------------------------------------------*/
  34. /* Private define ------------------------------------------------------------*/
  35. /* Private macro -------------------------------------------------------------*/
  36. /* Private variables ---------------------------------------------------------*/
  37. /* Global variable used to store variable value in read sequence */
  38. uint16_t DataVar = 0;
  39. /* Virtual address defined by the user: 0xFFFF value is prohibited */
  40. uint16_t VirtAddVarTab[]={
  41. CURSET_RESET_TIME,
  42. CURSET_UPDATE_STATE,
  43. CURSET_SET_VER,
  44. CURSET_RESERVED1,
  45. CURSET_RESERVED2,
  46. CURSET_RESERVED3,
  47. CURSET_DEVICE_DevEUI0,
  48. CURSET_DEVICE_DevEUI1,
  49. CURSET_DEVICE_DevEUI2,
  50. CURSET_DEVICE_DevEUI3,
  51. CURSET_DEVICE_DevAddr0,
  52. CURSET_DEVICE_DevAddr1,
  53. CURSET_DEVICE_TYPE,
  54. CURSET_DEVICE_HARD_VER,
  55. CURSET_DEVICE_MFD0,
  56. CURSET_DEVICE_MFD1,
  57. CURSET_GW_ID0,
  58. CURSET_GW_ID1,
  59. CURSET_CHANNELL_NUM,
  60. CURSET_BT_SOFT_VER0,
  61. CURSET_BT_SOFT_VER1,
  62. CURSET_PROTOCOL_VER0,
  63. CURSET_PROTOCOL_VER1,
  64. CURSET_APP1_START_ADDR0,
  65. CURSET_APP1_START_ADDR1,
  66. CURSET_APP1_VER_ADDR0,
  67. CURSET_APP1_VER_ADDR1,
  68. CURSET_APP1_LEN_ADDR0,
  69. CURSET_APP1_LEN_ADDR1,
  70. CURSET_APP1_CRC_ADDR0,
  71. CURSET_APP1_CRC_ADDR1,
  72. CURSET_APP2_START_ADDR0,
  73. CURSET_APP2_START_ADDR1,
  74. CURSET_APP2_VER_ADDR0,
  75. CURSET_APP2_VER_ADDR1,
  76. CURSET_APP2_LEN_ADDR0,
  77. CURSET_APP2_LEN_ADDR1,
  78. CURSET_APP2_CRC_ADDR0,
  79. CURSET_APP2_CRC_ADDR1,
  80. CURSET_APP3_START_ADDR0,
  81. CURSET_APP3_START_ADDR1,
  82. CURSET_APP3_VER_ADDR0,
  83. CURSET_APP3_VER_ADDR1,
  84. CURSET_APP3_LEN_ADDR0,
  85. CURSET_APP3_LEN_ADDR1,
  86. CURSET_APP3_CRC_ADDR0,
  87. CURSET_APP3_CRC_ADDR1,
  88. CURSET_APP3_FIREWARE_TYPE,
  89. CURSET_BASE_KEY0,
  90. CURSET_BASE_KEY1,
  91. CURSET_BASE_KEY2,
  92. CURSET_BASE_KEY3,
  93. CURSET_BASE_KEY4,
  94. CURSET_BASE_KEY5,
  95. CURSET_BASE_KEY6,
  96. CURSET_BASE_KEY7,
  97. CURSET_LORA_CH0_PARM0,
  98. CURSET_LORA_CH0_PARM1,
  99. CURSET_LORA_CH0_PARM2,
  100. CURSET_LORA_CH0_PARM3,
  101. CURSET_LORA_CH0_PARM4,
  102. CURSET_LORA_CH1_PARM0,
  103. CURSET_LORA_CH1_PARM1,
  104. CURSET_LORA_CH1_PARM2,
  105. CURSET_LORA_CH1_PARM3,
  106. CURSET_LORA_CH1_PARM4,
  107. CURSET_YTSF_EN,
  108. CURSET_LOOP_PERIOD,
  109. CURSET_SKK_PORT0,
  110. CURSET_SKK_PORT1,
  111. CURSET_YTSF_PORT0_SN0,
  112. CURSET_YTSF_PORT0_SN1,
  113. CURSET_YTSF_PORT0_SN2,
  114. CURSET_YTSF_PORT1_SN0,
  115. CURSET_YTSF_PORT1_SN1,
  116. CURSET_YTSF_PORT1_SN2,
  117. CURSET_CRC0,
  118. CURSET_CRC1
  119. };
  120. /* Private function prototypes -----------------------------------------------*/
  121. /* Private functions ---------------------------------------------------------*/
  122. static FLASH_Status EE_Format(void);
  123. static uint16_t EE_FindValidPage(uint8_t Operation);
  124. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
  125. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
  126. /**
  127. * @brief Restore the pages to a known good state in case of page's status
  128. * corruption after a power loss.
  129. * @param None.
  130. * @retval - Flash error code: on write Flash error
  131. * - FLASH_COMPLETE: on success
  132. */
  133. uint16_t EE_Init(void)
  134. {
  135. uint16_t PageStatus0 = 6, PageStatus1 = 6;
  136. uint16_t VarIdx = 0;
  137. uint16_t EepromStatus = 0, ReadStatus = 0;
  138. int16_t x = -1;
  139. uint16_t FlashStatus;
  140. /* Get Page0 status */
  141. PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  142. EEPROM_DEBUG("PAGE0_BASE_ADDRESS=0x%08x,PageStatus0=0x%04x\r\n",PAGE0_BASE_ADDRESS,PageStatus0);
  143. /* Get Page1 status */
  144. PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  145. EEPROM_DEBUG("PAGE1_BASE_ADDRESS=0x%08x,PageStatus1=0x%04x\r\n",PAGE1_BASE_ADDRESS,PageStatus1);
  146. /* Check for invalid header states and repair if necessary */
  147. switch (PageStatus0)
  148. {
  149. case ERASED:
  150. if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
  151. {
  152. /* Erase Page0 */
  153. FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
  154. /* If erase operation was failed, a Flash error code is returned */
  155. if (FlashStatus != FLASH_COMPLETE)
  156. {
  157. return FlashStatus;
  158. }
  159. }
  160. else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
  161. {
  162. /* Erase Page0 */
  163. FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
  164. /* If erase operation was failed, a Flash error code is returned */
  165. if (FlashStatus != FLASH_COMPLETE)
  166. {
  167. return FlashStatus;
  168. }
  169. /* Mark Page1 as valid */
  170. FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);
  171. /* If program operation was failed, a Flash error code is returned */
  172. if (FlashStatus != FLASH_COMPLETE)
  173. {
  174. return FlashStatus;
  175. }
  176. }
  177. else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
  178. {
  179. /* Erase both Page0 and Page1 and set Page0 as valid page */
  180. FlashStatus = EE_Format();
  181. /* If erase/program operation was failed, a Flash error code is returned */
  182. if (FlashStatus != FLASH_COMPLETE)
  183. {
  184. return FlashStatus;
  185. }
  186. }
  187. break;
  188. case RECEIVE_DATA:
  189. if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
  190. {
  191. /* Transfer data from Page1 to Page0 */
  192. for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
  193. {
  194. if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  195. {
  196. x = VarIdx;
  197. }
  198. if (VarIdx != x)
  199. {
  200. /* Read the last variables' updates */
  201. ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  202. /* In case variable corresponding to the virtual address was found */
  203. if (ReadStatus != 0x1)
  204. {
  205. /* Transfer the variable to the Page0 */
  206. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  207. /* If program operation was failed, a Flash error code is returned */
  208. if (EepromStatus != FLASH_COMPLETE)
  209. {
  210. return EepromStatus;
  211. }
  212. }
  213. }
  214. }
  215. /* Mark Page0 as valid */
  216. FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
  217. /* If program operation was failed, a Flash error code is returned */
  218. if (FlashStatus != FLASH_COMPLETE)
  219. {
  220. return FlashStatus;
  221. }
  222. /* Erase Page1 */
  223. FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
  224. /* If erase operation was failed, a Flash error code is returned */
  225. if (FlashStatus != FLASH_COMPLETE)
  226. {
  227. return FlashStatus;
  228. }
  229. }
  230. else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
  231. {
  232. /* Erase Page1 */
  233. FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
  234. /* If erase operation was failed, a Flash error code is returned */
  235. if (FlashStatus != FLASH_COMPLETE)
  236. {
  237. return FlashStatus;
  238. }
  239. /* Mark Page0 as valid */
  240. FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
  241. /* If program operation was failed, a Flash error code is returned */
  242. if (FlashStatus != FLASH_COMPLETE)
  243. {
  244. return FlashStatus;
  245. }
  246. }
  247. else /* Invalid state -> format eeprom */
  248. {
  249. /* Erase both Page0 and Page1 and set Page0 as valid page */
  250. FlashStatus = EE_Format();
  251. /* If erase/program operation was failed, a Flash error code is returned */
  252. if (FlashStatus != FLASH_COMPLETE)
  253. {
  254. return FlashStatus;
  255. }
  256. }
  257. break;
  258. case VALID_PAGE:
  259. if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
  260. {
  261. /* Erase both Page0 and Page1 and set Page0 as valid page */
  262. FlashStatus = EE_Format();
  263. /* If erase/program operation was failed, a Flash error code is returned */
  264. if (FlashStatus != FLASH_COMPLETE)
  265. {
  266. return FlashStatus;
  267. }
  268. }
  269. else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
  270. {
  271. /* Erase Page1 */
  272. FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
  273. /* If erase operation was failed, a Flash error code is returned */
  274. if (FlashStatus != FLASH_COMPLETE)
  275. {
  276. return FlashStatus;
  277. }
  278. }
  279. else /* Page0 valid, Page1 receive */
  280. {
  281. /* Transfer data from Page0 to Page1 */
  282. for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
  283. {
  284. if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  285. {
  286. x = VarIdx;
  287. }
  288. if (VarIdx != x)
  289. {
  290. /* Read the last variables' updates */
  291. ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  292. /* In case variable corresponding to the virtual address was found */
  293. if (ReadStatus != 0x1)
  294. {
  295. /* Transfer the variable to the Page1 */
  296. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  297. /* If program operation was failed, a Flash error code is returned */
  298. if (EepromStatus != FLASH_COMPLETE)
  299. {
  300. return EepromStatus;
  301. }
  302. }
  303. }
  304. }
  305. /* Mark Page1 as valid */
  306. FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);
  307. /* If program operation was failed, a Flash error code is returned */
  308. if (FlashStatus != FLASH_COMPLETE)
  309. {
  310. return FlashStatus;
  311. }
  312. /* Erase Page0 */
  313. FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
  314. /* If erase operation was failed, a Flash error code is returned */
  315. if (FlashStatus != FLASH_COMPLETE)
  316. {
  317. return FlashStatus;
  318. }
  319. }
  320. break;
  321. default: /* Any other state -> format eeprom */
  322. /* Erase both Page0 and Page1 and set Page0 as valid page */
  323. FlashStatus = EE_Format();
  324. /* If erase/program operation was failed, a Flash error code is returned */
  325. if (FlashStatus != FLASH_COMPLETE)
  326. {
  327. return FlashStatus;
  328. }
  329. break;
  330. }
  331. return FLASH_COMPLETE;
  332. }
  333. /**
  334. * @brief Returns the last stored variable data, if found, which correspond to
  335. * the passed virtual address
  336. * @param VirtAddress: Variable virtual address
  337. * @param Data: Global variable contains the read variable value
  338. * @retval Success or error status:
  339. * - 0: if variable was found
  340. * - 1: if the variable was not found
  341. * - NO_VALID_PAGE: if no valid page was found.
  342. */
  343. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data)
  344. {
  345. uint16_t ValidPage = PAGE0;
  346. uint16_t AddressValue = 0x5555, ReadStatus = 1;
  347. uint32_t Address = 0x0800F000, PageStartAddress = 0x0800F000;
  348. IWDG_Feed(); //喂狗
  349. /* Get active Page for read operation */
  350. ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  351. //EEPROM_DEBUG("ValidPage=0x%04x\r\n",ValidPage);
  352. /* Check if there is no valid page */
  353. if (ValidPage == NO_VALID_PAGE)
  354. {
  355. return NO_VALID_PAGE;
  356. }
  357. /* Get the valid Page start Address */
  358. PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  359. //EEPROM_DEBUG("PageStartAddress=0x%08x\r\n",PageStartAddress);
  360. /* Get the valid Page end Address */
  361. Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
  362. //EEPROM_DEBUG("Address=0x%08x\r\n",Address);
  363. /* Check each active page address starting from end */
  364. while (Address > (PageStartAddress + 2))
  365. {
  366. /* Get the current location content to be compared with virtual address */
  367. AddressValue = (*(__IO uint16_t*)Address);
  368. /* Compare the read address with the virtual address */
  369. if (AddressValue == VirtAddress)
  370. {
  371. /* Get content of Address-2 which is variable value */
  372. *Data = (*(__IO uint16_t*)(Address - 2));
  373. EEPROM_DEBUG("ValidPage=0x%04x,RealAddress=0x%08x,VirtAddress=0x%04x,Data=0x%04x\r\n",ValidPage,(Address - 2),VirtAddress,*Data);
  374. /* In case variable value is read, reset ReadStatus flag */
  375. ReadStatus = 0;
  376. break;
  377. }
  378. else
  379. {
  380. /* Next address location */
  381. Address = Address - 4;
  382. }
  383. }
  384. /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
  385. return ReadStatus;
  386. }
  387. /**
  388. * @brief Writes/upadtes variable data in EEPROM.
  389. * @param VirtAddress: Variable virtual address
  390. * @param Data: 16 bit data to be written
  391. * @retval Success or error status:
  392. * - FLASH_COMPLETE: on success
  393. * - PAGE_FULL: if valid page is full
  394. * - NO_VALID_PAGE: if no valid page was found
  395. * - Flash error code: on write Flash error
  396. */
  397. uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
  398. {
  399. uint16_t Status = 0;
  400. IWDG_Feed(); //喂狗
  401. /* Write the variable virtual address and value in the EEPROM */
  402. Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  403. /* In case the EEPROM active page is full */
  404. if (Status == PAGE_FULL)
  405. {
  406. /* Perform Page transfer */
  407. EEPROM_DEBUG("Status == PAGE_FULL\r\n");
  408. Status = EE_PageTransfer(VirtAddress, Data);
  409. }
  410. /* Return last operation status */
  411. return Status;
  412. }
  413. /**
  414. * @brief Erases PAGE0 and PAGE1 and writes VALID_PAGE header to PAGE0
  415. * @param None
  416. * @retval Status of the last operation (Flash write or erase) done during
  417. * EEPROM formating
  418. */
  419. static FLASH_Status EE_Format(void)
  420. {
  421. FLASH_Status FlashStatus = FLASH_COMPLETE;
  422. EEPROM_DEBUG("Erases PAGE0 and PAGE1 and writes VALID_PAGE header to PAGE0\r\n");
  423. /* Erase Page0 */
  424. FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
  425. /* If erase operation was failed, a Flash error code is returned */
  426. if (FlashStatus != FLASH_COMPLETE)
  427. {
  428. return FlashStatus;
  429. }
  430. /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
  431. FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
  432. /* If program operation was failed, a Flash error code is returned */
  433. if (FlashStatus != FLASH_COMPLETE)
  434. {
  435. return FlashStatus;
  436. }
  437. /* Erase Page1 */
  438. FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
  439. /* Return Page1 erase operation status */
  440. return FlashStatus;
  441. }
  442. /**
  443. * @brief Find valid Page for write or read operation
  444. * @param Operation: operation to achieve on the valid page.
  445. * This parameter can be one of the following values:
  446. * @arg READ_FROM_VALID_PAGE: read operation from valid page
  447. * @arg WRITE_IN_VALID_PAGE: write operation from valid page
  448. * @retval Valid page number (PAGE0 or PAGE1) or NO_VALID_PAGE in case
  449. * of no valid page was found
  450. */
  451. static uint16_t EE_FindValidPage(uint8_t Operation)
  452. {
  453. uint16_t PageStatus0 = 6, PageStatus1 = 6;
  454. /* Get Page0 actual status */
  455. PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  456. //EEPROM_DEBUG("PageStatus0=0x%04x\r\n",PageStatus0);
  457. /* Get Page1 actual status */
  458. PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  459. //EEPROM_DEBUG("PageStatus1=0x%04x\r\n",PageStatus1);
  460. /* Write or read operation */
  461. switch (Operation)
  462. {
  463. case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
  464. if (PageStatus1 == VALID_PAGE)
  465. {
  466. /* Page0 receiving data */
  467. if (PageStatus0 == RECEIVE_DATA)
  468. {
  469. return PAGE0; /* Page0 valid */
  470. }
  471. else
  472. {
  473. return PAGE1; /* Page1 valid */
  474. }
  475. }
  476. else if (PageStatus0 == VALID_PAGE)
  477. {
  478. /* Page1 receiving data */
  479. if (PageStatus1 == RECEIVE_DATA)
  480. {
  481. return PAGE1; /* Page1 valid */
  482. }
  483. else
  484. {
  485. return PAGE0; /* Page0 valid */
  486. }
  487. }
  488. else
  489. {
  490. return NO_VALID_PAGE; /* No valid Page */
  491. }
  492. case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
  493. if (PageStatus0 == VALID_PAGE)
  494. {
  495. return PAGE0; /* Page0 valid */
  496. }
  497. else if (PageStatus1 == VALID_PAGE)
  498. {
  499. return PAGE1; /* Page1 valid */
  500. }
  501. else
  502. {
  503. return NO_VALID_PAGE ; /* No valid Page */
  504. }
  505. default:
  506. return PAGE0; /* Page0 valid */
  507. }
  508. }
  509. /**
  510. * @brief Verify if active page is full and Writes variable in EEPROM.
  511. * @param VirtAddress: 16 bit virtual address of the variable
  512. * @param Data: 16 bit data to be written as variable value
  513. * @retval Success or error status:
  514. * - FLASH_COMPLETE: on success
  515. * - PAGE_FULL: if valid page is full
  516. * - NO_VALID_PAGE: if no valid page was found
  517. * - Flash error code: on write Flash error
  518. */
  519. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data)
  520. {
  521. FLASH_Status FlashStatus = FLASH_COMPLETE;
  522. uint16_t ValidPage = PAGE0;
  523. uint32_t Address = 0x0800F000, PageEndAddress = 0x0800F7FF;
  524. /* Get valid Page for write operation */
  525. ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
  526. //EEPROM_DEBUG("ValidPage=0x%04x\r\n",ValidPage);
  527. /* Check if there is no valid page */
  528. if (ValidPage == NO_VALID_PAGE)
  529. {
  530. return NO_VALID_PAGE;
  531. }
  532. /* Get the valid Page start Address */
  533. Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  534. //EEPROM_DEBUG("Address=0x%04x\r\n",Address);
  535. /* Get the valid Page end Address */
  536. PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
  537. //EEPROM_DEBUG("PageEndAddress=0x%04x\r\n",PageEndAddress);
  538. /* Check each active page address starting from begining */
  539. while (Address < PageEndAddress)
  540. {
  541. /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
  542. if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF)
  543. {
  544. /* Set variable data */
  545. FlashStatus = FLASH_ProgramHalfWord(Address, Data);
  546. /* If program operation was failed, a Flash error code is returned */
  547. if (FlashStatus != FLASH_COMPLETE)
  548. {
  549. return FlashStatus;
  550. }
  551. /* Set variable virtual address */
  552. FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress);
  553. EEPROM_DEBUG("ValidPage=0x%04x,RealAddress=0x%08x,VirtAddress=0x%04x,Data=0x%04x\r\n",ValidPage,(Address+2),VirtAddress,Data);
  554. /* Return program operation status */
  555. return FlashStatus;
  556. }
  557. else
  558. {
  559. /* Next address location */
  560. Address = Address + 4;
  561. }
  562. }
  563. /* Return PAGE_FULL in case the valid page is full */
  564. return PAGE_FULL;
  565. }
  566. /**
  567. * @brief Transfers last updated variables data from the full Page to
  568. * an empty one.
  569. * @param VirtAddress: 16 bit virtual address of the variable
  570. * @param Data: 16 bit data to be written as variable value
  571. * @retval Success or error status:
  572. * - FLASH_COMPLETE: on success
  573. * - PAGE_FULL: if valid page is full
  574. * - NO_VALID_PAGE: if no valid page was found
  575. * - Flash error code: on write Flash error
  576. */
  577. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
  578. {
  579. FLASH_Status FlashStatus = FLASH_COMPLETE;
  580. uint32_t NewPageAddress = 0x0800F3FF, OldPageAddress = 0x0800F000;
  581. uint16_t ValidPage = PAGE0, VarIdx = 0;
  582. uint16_t EepromStatus = 0, ReadStatus = 0;
  583. /* Get active Page for read operation */
  584. ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  585. if (ValidPage == PAGE1) /* Page1 valid */
  586. {
  587. /* New page address where variable will be moved to */
  588. NewPageAddress = PAGE0_BASE_ADDRESS;
  589. /* Old page address where variable will be taken from */
  590. OldPageAddress = PAGE1_BASE_ADDRESS;
  591. }
  592. else if (ValidPage == PAGE0) /* Page0 valid */
  593. {
  594. /* New page address where variable will be moved to */
  595. NewPageAddress = PAGE1_BASE_ADDRESS;
  596. /* Old page address where variable will be taken from */
  597. OldPageAddress = PAGE0_BASE_ADDRESS;
  598. }
  599. else
  600. {
  601. return NO_VALID_PAGE; /* No valid Page */
  602. }
  603. EEPROM_DEBUG("NewPageAddress=0x%08x,OldPageAddress=0x%08x\r\n",NewPageAddress,OldPageAddress);
  604. /* Set the new Page status to RECEIVE_DATA status */
  605. FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA);
  606. /* If program operation was failed, a Flash error code is returned */
  607. if (FlashStatus != FLASH_COMPLETE)
  608. {
  609. return FlashStatus;
  610. }
  611. /* Write the variable passed as parameter in the new active page */
  612. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  613. /* If program operation was failed, a Flash error code is returned */
  614. if (EepromStatus != FLASH_COMPLETE)
  615. {
  616. return EepromStatus;
  617. }
  618. EEPROM_DEBUG("Transfer process: transfer variables from old to the new active page\r\n");
  619. /* Transfer process: transfer variables from old to the new active page */
  620. for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
  621. {
  622. IWDG_Feed(); //喂狗
  623. if (VirtAddVarTab[VarIdx] != VirtAddress) /* Check each variable except the one passed as parameter */
  624. {
  625. //此时,写是新页地址,读是旧页地址
  626. /* Read the other last variable updates */
  627. ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  628. /* In case variable corresponding to the virtual address was found */
  629. if (ReadStatus != 0x1)
  630. {
  631. //此时,写是新页地址,读是旧页地址
  632. /* Transfer the variable to the new active page */
  633. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  634. /* If program operation was failed, a Flash error code is returned */
  635. if (EepromStatus != FLASH_COMPLETE)
  636. {
  637. return EepromStatus;
  638. }
  639. }
  640. }
  641. }
  642. EEPROM_DEBUG("Erase the old Page: Set old Page status to ERASED status,OldPageAddress=0x%08x\r\n",OldPageAddress);
  643. /* Erase the old Page: Set old Page status to ERASED status */
  644. FlashStatus = FLASH_ErasePage(OldPageAddress);
  645. /* If erase operation was failed, a Flash error code is returned */
  646. if (FlashStatus != FLASH_COMPLETE)
  647. {
  648. return FlashStatus;
  649. }
  650. EEPROM_DEBUG("Set new Page status to VALID_PAGE status,NewPageAddress=0x%08x\r\n",NewPageAddress);
  651. /* Set new Page status to VALID_PAGE status */
  652. FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE);
  653. /* If program operation was failed, a Flash error code is returned */
  654. if (FlashStatus != FLASH_COMPLETE)
  655. {
  656. return FlashStatus;
  657. }
  658. /* Return last operation flash status */
  659. return FlashStatus;
  660. }
  661. /*计算eeprom CRC值*/
  662. uint16_t Calc_Eeprom_CRC32(uint32_t *crcvalue){
  663. uint16_t i=0,ReadStatus =1;
  664. uint16_t EE_h = 0xffff,EE_l = 0xffff;
  665. CRC_ResetDR();
  666. for (i = 0; i < NumbOfVar-4;i+=2)
  667. {
  668. if(EE_ReadVariable(i , &EE_h)!=0)
  669. return ReadStatus;
  670. if(EE_ReadVariable(i+1, &EE_l)!=0)
  671. return ReadStatus;
  672. CRC_CalcCRC((EE_h<<16) & EE_l);
  673. EE_h = 0xffff;
  674. EE_l = 0xffff;
  675. }
  676. if(NumbOfVar%2)
  677. {
  678. if(EE_ReadVariable(i , &EE_h)!=0)
  679. return ReadStatus;
  680. CRC_CalcCRC((EE_h<<16) & EE_l);
  681. }
  682. *crcvalue = CRC_GetCRC();
  683. ReadStatus = 0;
  684. return ReadStatus;
  685. }
  686. /* Virtual address defined by the user: 0xFFFF value is prohibited */
  687. //uint16_t VirtAddVarTab[3] = {0x5555, 0x6666, 0x7777};
  688. uint16_t eeprom_test(void)
  689. {
  690. /* Private typedef -----------------------------------------------------------*/
  691. /* Private define ------------------------------------------------------------*/
  692. /* Private macro -------------------------------------------------------------*/
  693. /* Private variables ---------------------------------------------------------*/
  694. uint16_t VarValue = 0,resultcode = 1;
  695. uint16_t temp=0;
  696. uint32_t CRCValue=0;
  697. EEPROM_DEBUG("\r\nStart EEPROM TEST\r\n");
  698. if(EE_ReadVariable(CURSET_RESET_TIME, &temp)!=0)
  699. {
  700. EE_WriteVariable(CURSET_RESET_TIME, 0x0000);
  701. EE_WriteVariable(CURSET_UPDATE_STATE, 0x0000);
  702. EE_WriteVariable(CURSET_SET_VER, 0x0000);
  703. /*
  704. EE_WriteVariable(CURSET_RESERVED1, 0xFFFF);
  705. EE_WriteVariable(CURSET_RESERVED2, 0xFFFF);
  706. EE_WriteVariable(CURSET_RESERVED3, 0xFFFF);
  707. EE_WriteVariable(CURSET_DEVICE_DevEUI0, 0xFFFF);
  708. EE_WriteVariable(CURSET_DEVICE_DevEUI1, 0xFFFF);
  709. EE_WriteVariable(CURSET_DEVICE_DevEUI2, 0xFFFF);
  710. EE_WriteVariable(CURSET_DEVICE_DevEUI3, 0xFFFF);
  711. EE_WriteVariable(CURSET_DEVICE_DevAddr0, 0xFFFF);
  712. EE_WriteVariable(CURSET_DEVICE_DevAddr1, 0xFFFF);
  713. EE_WriteVariable(CURSET_DEVICE_TYPE, 0x0003);
  714. EE_WriteVariable(CURSET_DEVICE_HARD_VER, 0x0001);
  715. EE_WriteVariable(CURSET_DEVICE_MFD0, 0x2020);
  716. EE_WriteVariable(CURSET_DEVICE_MFD1, 0x0808);
  717. EE_WriteVariable(CURSET_GW_ID0, 0xFFFF);
  718. EE_WriteVariable(CURSET_GW_ID1, 0xFFFF);
  719. EE_WriteVariable(CURSET_CHANNELL_NUM, 0xFFFF);
  720. EE_WriteVariable(CURSET_BT_SOFT_VER0, 0x0001);
  721. EE_WriteVariable(CURSET_BT_SOFT_VER1, 0x6301);
  722. EE_WriteVariable(CURSET_PROTOCOL_VER0, 0x0001);
  723. EE_WriteVariable(CURSET_PROTOCOL_VER1, 0x0000);
  724. EE_WriteVariable(CURSET_APP1_START_ADDR0, 0x0000);
  725. EE_WriteVariable(CURSET_APP1_START_ADDR1, 0x0801);
  726. EE_WriteVariable(CURSET_APP1_VER_ADDR0, 0x0001);
  727. EE_WriteVariable(CURSET_APP1_VER_ADDR1, 0x6301);
  728. EE_WriteVariable(CURSET_APP1_LEN_ADDR0, 0xFFF8);
  729. EE_WriteVariable(CURSET_APP1_LEN_ADDR1, 0x0801);
  730. EE_WriteVariable(CURSET_APP1_CRC_ADDR0, 0xFFFC);
  731. EE_WriteVariable(CURSET_APP1_CRC_ADDR1, 0x0801);
  732. EE_WriteVariable(CURSET_APP2_START_ADDR0, 0x0000);
  733. EE_WriteVariable(CURSET_APP2_START_ADDR1, 0x0802);
  734. EE_WriteVariable(CURSET_APP2_VER_ADDR0, 0xFFF4);
  735. EE_WriteVariable(CURSET_APP2_VER_ADDR1, 0x0802);
  736. EE_WriteVariable(CURSET_APP2_LEN_ADDR0, 0xFFF8);
  737. EE_WriteVariable(CURSET_APP2_LEN_ADDR1, 0x0802);
  738. EE_WriteVariable(CURSET_APP2_CRC_ADDR0, 0xFFFC);
  739. EE_WriteVariable(CURSET_APP2_CRC_ADDR1, 0x0802);
  740. EE_WriteVariable(CURSET_APP3_START_ADDR0, 0x0000);
  741. EE_WriteVariable(CURSET_APP3_START_ADDR1, 0x0803);
  742. EE_WriteVariable(CURSET_APP3_VER_ADDR0, 0x0002);
  743. EE_WriteVariable(CURSET_APP3_VER_ADDR1, 0x6301);
  744. EE_WriteVariable(CURSET_APP3_LEN_ADDR0, 0x494C);
  745. EE_WriteVariable(CURSET_APP3_LEN_ADDR1, 0x0000);
  746. EE_WriteVariable(CURSET_APP3_CRC_ADDR0, 0xFFFC);
  747. EE_WriteVariable(CURSET_APP3_CRC_ADDR1, 0x0803);
  748. EE_WriteVariable(CURSET_APP3_FIREWARE_TYPE, 0x0000);
  749. EE_WriteVariable(CURSET_BASE_KEY0, 0xABAA);
  750. EE_WriteVariable(CURSET_BASE_KEY1, 0xB826);
  751. EE_WriteVariable(CURSET_BASE_KEY2, 0xF479);
  752. EE_WriteVariable(CURSET_BASE_KEY3, 0x7818);
  753. EE_WriteVariable(CURSET_BASE_KEY4, 0x668E);
  754. EE_WriteVariable(CURSET_BASE_KEY5, 0xFF3D);
  755. EE_WriteVariable(CURSET_BASE_KEY6, 0x1CFB);
  756. EE_WriteVariable(CURSET_BASE_KEY7, 0xCF95);
  757. EE_WriteVariable(CURSET_LORA_CH0_PARM0, 0x9488);
  758. EE_WriteVariable(CURSET_LORA_CH0_PARM1, 0x4A4B);
  759. EE_WriteVariable(CURSET_LORA_CH0_PARM2, 0x0907);
  760. EE_WriteVariable(CURSET_LORA_CH0_PARM3, 0x1880);
  761. EE_WriteVariable(CURSET_LORA_CH0_PARM4, 0x6464);
  762. EE_WriteVariable(CURSET_LORA_CH1_PARM0, 0x1488);
  763. EE_WriteVariable(CURSET_LORA_CH1_PARM1, 0x4D68);
  764. EE_WriteVariable(CURSET_LORA_CH1_PARM2, 0x0907);
  765. EE_WriteVariable(CURSET_LORA_CH1_PARM3, 0x1880);
  766. EE_WriteVariable(CURSET_LORA_CH1_PARM4, 0x6464);
  767. EE_WriteVariable(CURSET_YTSF_EN, 0x0000);
  768. EE_WriteVariable(CURSET_LOOP_PERIOD, 0x000A);
  769. EE_WriteVariable(CURSET_SKK_PORT0, 0x0103);
  770. EE_WriteVariable(CURSET_SKK_PORT1, 0x0103);
  771. EE_WriteVariable(CURSET_YTSF_PORT0_SN0, 0xFFFF);
  772. EE_WriteVariable(CURSET_YTSF_PORT0_SN1, 0xFFFF);
  773. EE_WriteVariable(CURSET_YTSF_PORT0_SN2, 0xFFFF);
  774. EE_WriteVariable(CURSET_YTSF_PORT1_SN0, 0xFFFF);
  775. EE_WriteVariable(CURSET_YTSF_PORT1_SN1, 0xFFFF);
  776. EE_WriteVariable(CURSET_YTSF_PORT1_SN2, 0xFFFF);
  777. */
  778. if(Calc_Eeprom_CRC32(&CRCValue)!=0)
  779. return resultcode;
  780. EEPROM_DEBUG("CRCValue=0x%08x\r\n",CRCValue);
  781. EE_WriteVariable(CURSET_CRC0, (uint16_t)((CRCValue >> 0) & 0xffff));
  782. EE_WriteVariable(CURSET_CRC1, (uint16_t)((CRCValue >> 16) & 0xffff));
  783. EE_WriteVariable(CURSET_RESET_TIME, 0x0001);
  784. }
  785. for (VarValue = 0; VarValue < NumbOfVar; VarValue++)
  786. {
  787. EE_ReadVariable(VirtAddVarTab[VarValue], &temp);
  788. EEPROM_DEBUG("VirtAdd=0x%04x,data=0x%04x\r\n",VirtAddVarTab[VarValue],temp);
  789. }
  790. EEPROM_DEBUG("\r\nEnd EEPROM TEST\r\n");
  791. resultcode = 0;
  792. return resultcode;
  793. }
  794. /**
  795. * @}
  796. */
  797. /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/