My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

eeprom_emul.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  1. /**
  2. ******************************************************************************
  3. * @file EEPROM/EEPROM_Emulation/src/eeprom.c
  4. * @author MCD Application Team
  5. * @version V1.2.6
  6. * @date 04-November-2016
  7. * @brief This file provides all the EEPROM emulation firmware functions.
  8. ******************************************************************************
  9. * @attention
  10. *
  11. * <h2><center>&copy; Copyright © 2016 STMicroelectronics International N.V.
  12. * All rights reserved.</center></h2>
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted, provided that the following conditions are met:
  16. *
  17. * 1. Redistribution of source code must retain the above copyright notice,
  18. * this list of conditions and the following disclaimer.
  19. * 2. Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * 3. Neither the name of STMicroelectronics nor the names of other
  23. * contributors to this software may be used to endorse or promote products
  24. * derived from this software without specific written permission.
  25. * 4. This software, including modifications and/or derivative works of this
  26. * software, must execute solely and exclusively on microcontroller or
  27. * microprocessor devices manufactured by or for STMicroelectronics.
  28. * 5. Redistribution and use of this software other than as permitted under
  29. * this license is void and will automatically terminate your rights under
  30. * this license.
  31. *
  32. * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS"
  33. * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
  34. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  35. * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  36. * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
  37. * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  38. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  39. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  40. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  41. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  42. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  43. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. *
  45. ******************************************************************************
  46. */
  47. /** @addtogroup EEPROM_Emulation
  48. * @{
  49. */
  50. #ifdef STM32F7
  51. /* Includes ------------------------------------------------------------------*/
  52. #include "eeprom_emul.h"
  53. /* Private typedef -----------------------------------------------------------*/
  54. /* Private define ------------------------------------------------------------*/
  55. /* Private macro -------------------------------------------------------------*/
  56. /* Private variables ---------------------------------------------------------*/
  57. /* Global variable used to store variable value in read sequence */
  58. uint16_t DataVar = 0;
  59. /* Virtual address defined by the user: 0xFFFF value is prohibited */
  60. uint16_t VirtAddVarTab[NB_OF_VAR];
  61. /* Private function prototypes -----------------------------------------------*/
  62. /* Private functions ---------------------------------------------------------*/
  63. static HAL_StatusTypeDef EE_Format(void);
  64. static uint16_t EE_FindValidPage(uint8_t Operation);
  65. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
  66. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
  67. static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
  68. /**
  69. * @brief Restore the pages to a known good state in case of page's status
  70. * corruption after a power loss.
  71. * @param None.
  72. * @retval - Flash error code: on write Flash error
  73. * - FLASH_COMPLETE: on success
  74. */
  75. uint16_t EE_Initialise(void) {
  76. uint16_t PageStatus0 = 6, PageStatus1 = 6;
  77. uint16_t VarIdx = 0;
  78. uint16_t EepromStatus = 0, ReadStatus = 0;
  79. int16_t x = -1;
  80. HAL_StatusTypeDef FlashStatus;
  81. uint32_t SectorError = 0;
  82. FLASH_EraseInitTypeDef pEraseInit;
  83. /* Get Page0 status */
  84. PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  85. /* Get Page1 status */
  86. PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  87. pEraseInit.TypeErase = TYPEERASE_SECTORS;
  88. pEraseInit.Sector = PAGE0_ID;
  89. pEraseInit.NbSectors = 1;
  90. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  91. /* Check for invalid header states and repair if necessary */
  92. switch (PageStatus0) {
  93. case ERASED:
  94. if (PageStatus1 == VALID_PAGE) { /* Page0 erased, Page1 valid */
  95. /* Erase Page0 */
  96. if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  97. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  98. /* If erase operation was failed, a Flash error code is returned */
  99. if (FlashStatus != HAL_OK) {
  100. return FlashStatus;
  101. }
  102. }
  103. }
  104. else if (PageStatus1 == RECEIVE_DATA) { /* Page0 erased, Page1 receive */
  105. /* Erase Page0 */
  106. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  107. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  108. /* If erase operation was failed, a Flash error code is returned */
  109. if (FlashStatus != HAL_OK) return FlashStatus;
  110. }
  111. /* Mark Page1 as valid */
  112. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
  113. /* If program operation was failed, a Flash error code is returned */
  114. if (FlashStatus != HAL_OK) return FlashStatus;
  115. }
  116. else { /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
  117. /* Erase both Page0 and Page1 and set Page0 as valid page */
  118. FlashStatus = EE_Format();
  119. /* If erase/program operation was failed, a Flash error code is returned */
  120. if (FlashStatus != HAL_OK) return FlashStatus;
  121. }
  122. break;
  123. case RECEIVE_DATA:
  124. if (PageStatus1 == VALID_PAGE) { /* Page0 receive, Page1 valid */
  125. /* Transfer data from Page1 to Page0 */
  126. for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
  127. if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  128. x = VarIdx;
  129. if (VarIdx != x) {
  130. /* Read the last variables' updates */
  131. ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  132. /* In case variable corresponding to the virtual address was found */
  133. if (ReadStatus != 0x1) {
  134. /* Transfer the variable to the Page0 */
  135. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  136. /* If program operation was failed, a Flash error code is returned */
  137. if (EepromStatus != HAL_OK) return EepromStatus;
  138. }
  139. }
  140. }
  141. /* Mark Page0 as valid */
  142. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
  143. /* If program operation was failed, a Flash error code is returned */
  144. if (FlashStatus != HAL_OK) return FlashStatus;
  145. pEraseInit.Sector = PAGE1_ID;
  146. pEraseInit.NbSectors = 1;
  147. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  148. /* Erase Page1 */
  149. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  150. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  151. /* If erase operation was failed, a Flash error code is returned */
  152. if (FlashStatus != HAL_OK) return FlashStatus;
  153. }
  154. }
  155. else if (PageStatus1 == ERASED) { /* Page0 receive, Page1 erased */
  156. pEraseInit.Sector = PAGE1_ID;
  157. pEraseInit.NbSectors = 1;
  158. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  159. /* Erase Page1 */
  160. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  161. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  162. /* If erase operation was failed, a Flash error code is returned */
  163. if (FlashStatus != HAL_OK) return FlashStatus;
  164. }
  165. /* Mark Page0 as valid */
  166. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
  167. /* If program operation was failed, a Flash error code is returned */
  168. if (FlashStatus != HAL_OK) return FlashStatus;
  169. }
  170. else { /* Invalid state -> format eeprom */
  171. /* Erase both Page0 and Page1 and set Page0 as valid page */
  172. FlashStatus = EE_Format();
  173. /* If erase/program operation was failed, a Flash error code is returned */
  174. if (FlashStatus != HAL_OK) return FlashStatus;
  175. }
  176. break;
  177. case VALID_PAGE:
  178. if (PageStatus1 == VALID_PAGE) { /* Invalid state -> format eeprom */
  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 != HAL_OK) return FlashStatus;
  183. }
  184. else if (PageStatus1 == ERASED) { /* Page0 valid, Page1 erased */
  185. pEraseInit.Sector = PAGE1_ID;
  186. pEraseInit.NbSectors = 1;
  187. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  188. /* Erase Page1 */
  189. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  190. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  191. /* If erase operation was failed, a Flash error code is returned */
  192. if (FlashStatus != HAL_OK) return FlashStatus;
  193. }
  194. }
  195. else { /* Page0 valid, Page1 receive */
  196. /* Transfer data from Page0 to Page1 */
  197. for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
  198. if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  199. x = VarIdx;
  200. if (VarIdx != x) {
  201. /* Read the last variables' updates */
  202. ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  203. /* In case variable corresponding to the virtual address was found */
  204. if (ReadStatus != 0x1) {
  205. /* Transfer the variable to the Page1 */
  206. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  207. /* If program operation was failed, a Flash error code is returned */
  208. if (EepromStatus != HAL_OK) return EepromStatus;
  209. }
  210. }
  211. }
  212. /* Mark Page1 as valid */
  213. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
  214. /* If program operation was failed, a Flash error code is returned */
  215. if (FlashStatus != HAL_OK) return FlashStatus;
  216. pEraseInit.Sector = PAGE0_ID;
  217. pEraseInit.NbSectors = 1;
  218. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  219. /* Erase Page0 */
  220. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  221. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  222. /* If erase operation was failed, a Flash error code is returned */
  223. if (FlashStatus != HAL_OK) return FlashStatus;
  224. }
  225. }
  226. break;
  227. default: /* Any other state -> format eeprom */
  228. /* Erase both Page0 and Page1 and set Page0 as valid page */
  229. FlashStatus = EE_Format();
  230. /* If erase/program operation was failed, a Flash error code is returned */
  231. if (FlashStatus != HAL_OK) return FlashStatus;
  232. break;
  233. }
  234. return HAL_OK;
  235. }
  236. /**
  237. * @brief Verify if specified page is fully erased.
  238. * @param Address: page address
  239. * This parameter can be one of the following values:
  240. * @arg PAGE0_BASE_ADDRESS: Page0 base address
  241. * @arg PAGE1_BASE_ADDRESS: Page1 base address
  242. * @retval page fully erased status:
  243. * - 0: if Page not erased
  244. * - 1: if Page erased
  245. */
  246. uint16_t EE_VerifyPageFullyErased(uint32_t Address) {
  247. uint32_t ReadStatus = 1;
  248. uint16_t AddressValue = 0x5555;
  249. /* Check each active page address starting from end */
  250. while (Address <= PAGE0_END_ADDRESS) {
  251. /* Get the current location content to be compared with virtual address */
  252. AddressValue = (*(__IO uint16_t*)Address);
  253. /* Compare the read address with the virtual address */
  254. if (AddressValue != ERASED) {
  255. /* In case variable value is read, reset ReadStatus flag */
  256. ReadStatus = 0;
  257. break;
  258. }
  259. /* Next address location */
  260. Address += 4;
  261. }
  262. /* Return ReadStatus value: (0: Page not erased, 1: Sector erased) */
  263. return ReadStatus;
  264. }
  265. /**
  266. * @brief Returns the last stored variable data, if found, which correspond to
  267. * the passed virtual address
  268. * @param VirtAddress: Variable virtual address
  269. * @param Data: Global variable contains the read variable value
  270. * @retval Success or error status:
  271. * - 0: if variable was found
  272. * - 1: if the variable was not found
  273. * - NO_VALID_PAGE: if no valid page was found.
  274. */
  275. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) {
  276. uint16_t ValidPage = PAGE0;
  277. uint16_t AddressValue = 0x5555, ReadStatus = 1;
  278. uint32_t Address = EEPROM_START_ADDRESS, PageStartAddress = EEPROM_START_ADDRESS;
  279. /* Get active Page for read operation */
  280. ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  281. /* Check if there is no valid page */
  282. if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
  283. /* Get the valid Page start Address */
  284. PageStartAddress = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  285. /* Get the valid Page end Address */
  286. Address = (uint32_t)((EEPROM_START_ADDRESS - 2) + (uint32_t)((1 + ValidPage) * PAGE_SIZE));
  287. /* Check each active page address starting from end */
  288. while (Address > (PageStartAddress + 2)) {
  289. /* Get the current location content to be compared with virtual address */
  290. AddressValue = (*(__IO uint16_t*)Address);
  291. /* Compare the read address with the virtual address */
  292. if (AddressValue == VirtAddress) {
  293. /* Get content of Address-2 which is variable value */
  294. *Data = (*(__IO uint16_t*)(Address - 2));
  295. /* In case variable value is read, reset ReadStatus flag */
  296. ReadStatus = 0;
  297. break;
  298. }
  299. else /* Next address location */
  300. Address -= 4;
  301. }
  302. /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
  303. return ReadStatus;
  304. }
  305. /**
  306. * @brief Writes/upadtes variable data in EEPROM.
  307. * @param VirtAddress: Variable virtual address
  308. * @param Data: 16 bit data to be written
  309. * @retval Success or error status:
  310. * - FLASH_COMPLETE: on success
  311. * - PAGE_FULL: if valid page is full
  312. * - NO_VALID_PAGE: if no valid page was found
  313. * - Flash error code: on write Flash error
  314. */
  315. uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) {
  316. /* Write the variable virtual address and value in the EEPROM */
  317. uint16_t Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  318. /* In case the EEPROM active page is full */
  319. if (Status == PAGE_FULL) /* Perform Page transfer */
  320. Status = EE_PageTransfer(VirtAddress, Data);
  321. /* Return last operation status */
  322. return Status;
  323. }
  324. /**
  325. * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE
  326. * @param None
  327. * @retval Status of the last operation (Flash write or erase) done during
  328. * EEPROM formating
  329. */
  330. static HAL_StatusTypeDef EE_Format(void) {
  331. HAL_StatusTypeDef FlashStatus = HAL_OK;
  332. uint32_t SectorError = 0;
  333. FLASH_EraseInitTypeDef pEraseInit;
  334. pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
  335. pEraseInit.Sector = PAGE0_ID;
  336. pEraseInit.NbSectors = 1;
  337. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  338. /* Erase Page0 */
  339. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  340. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  341. /* If erase operation was failed, a Flash error code is returned */
  342. if (FlashStatus != HAL_OK) return FlashStatus;
  343. }
  344. /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
  345. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
  346. /* If program operation was failed, a Flash error code is returned */
  347. if (FlashStatus != HAL_OK) return FlashStatus;
  348. pEraseInit.Sector = PAGE1_ID;
  349. /* Erase Page1 */
  350. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  351. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  352. /* If erase operation was failed, a Flash error code is returned */
  353. if (FlashStatus != HAL_OK) return FlashStatus;
  354. }
  355. return HAL_OK;
  356. }
  357. /**
  358. * @brief Find valid Page for write or read operation
  359. * @param Operation: operation to achieve on the valid page.
  360. * This parameter can be one of the following values:
  361. * @arg READ_FROM_VALID_PAGE: read operation from valid page
  362. * @arg WRITE_IN_VALID_PAGE: write operation from valid page
  363. * @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case
  364. * of no valid page was found
  365. */
  366. static uint16_t EE_FindValidPage(uint8_t Operation) {
  367. uint16_t PageStatus0 = 6, PageStatus1 = 6;
  368. /* Get Page0 actual status */
  369. PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  370. /* Get Page1 actual status */
  371. PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  372. /* Write or read operation */
  373. switch (Operation) {
  374. case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
  375. if (PageStatus1 == VALID_PAGE) {
  376. /* Page0 receiving data */
  377. if (PageStatus0 == RECEIVE_DATA) return PAGE0; /* Page0 valid */
  378. else return PAGE1; /* Page1 valid */
  379. }
  380. else if (PageStatus0 == VALID_PAGE) {
  381. /* Page1 receiving data */
  382. if (PageStatus1 == RECEIVE_DATA) return PAGE1; /* Page1 valid */
  383. else return PAGE0; /* Page0 valid */
  384. }
  385. else
  386. return NO_VALID_PAGE; /* No valid Page */
  387. case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
  388. if (PageStatus0 == VALID_PAGE)
  389. return PAGE0; /* Page0 valid */
  390. else if (PageStatus1 == VALID_PAGE)
  391. return PAGE1; /* Page1 valid */
  392. else
  393. return NO_VALID_PAGE; /* No valid Page */
  394. default:
  395. return PAGE0; /* Page0 valid */
  396. }
  397. }
  398. /**
  399. * @brief Verify if active page is full and Writes variable in EEPROM.
  400. * @param VirtAddress: 16 bit virtual address of the variable
  401. * @param Data: 16 bit data to be written as variable value
  402. * @retval Success or error status:
  403. * - FLASH_COMPLETE: on success
  404. * - PAGE_FULL: if valid page is full
  405. * - NO_VALID_PAGE: if no valid page was found
  406. * - Flash error code: on write Flash error
  407. */
  408. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) {
  409. HAL_StatusTypeDef FlashStatus = HAL_OK;
  410. uint16_t ValidPage = PAGE0;
  411. uint32_t Address = EEPROM_START_ADDRESS, PageEndAddress = EEPROM_START_ADDRESS+PAGE_SIZE;
  412. /* Get valid Page for write operation */
  413. ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
  414. /* Check if there is no valid page */
  415. if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
  416. /* Get the valid Page start Address */
  417. Address = (uint32_t)(EEPROM_START_ADDRESS + (uint32_t)(ValidPage * PAGE_SIZE));
  418. /* Get the valid Page end Address */
  419. PageEndAddress = (uint32_t)((EEPROM_START_ADDRESS - 1) + (uint32_t)((ValidPage + 1) * PAGE_SIZE));
  420. /* Check each active page address starting from begining */
  421. while (Address < PageEndAddress) {
  422. /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
  423. if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) {
  424. /* Set variable data */
  425. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);
  426. /* If program operation was failed, a Flash error code is returned */
  427. if (FlashStatus != HAL_OK) return FlashStatus;
  428. /* Set variable virtual address */
  429. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress);
  430. /* Return program operation status */
  431. return FlashStatus;
  432. }
  433. else /* Next address location */
  434. Address += 4;
  435. }
  436. /* Return PAGE_FULL in case the valid page is full */
  437. return PAGE_FULL;
  438. }
  439. /**
  440. * @brief Transfers last updated variables data from the full Page to
  441. * an empty one.
  442. * @param VirtAddress: 16 bit virtual address of the variable
  443. * @param Data: 16 bit data to be written as variable value
  444. * @retval Success or error status:
  445. * - FLASH_COMPLETE: on success
  446. * - PAGE_FULL: if valid page is full
  447. * - NO_VALID_PAGE: if no valid page was found
  448. * - Flash error code: on write Flash error
  449. */
  450. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) {
  451. HAL_StatusTypeDef FlashStatus = HAL_OK;
  452. uint32_t NewPageAddress = EEPROM_START_ADDRESS;
  453. uint16_t OldPageId=0;
  454. uint16_t ValidPage = PAGE0, VarIdx = 0;
  455. uint16_t EepromStatus = 0, ReadStatus = 0;
  456. uint32_t SectorError = 0;
  457. FLASH_EraseInitTypeDef pEraseInit;
  458. /* Get active Page for read operation */
  459. ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  460. if (ValidPage == PAGE1) { /* Page1 valid */
  461. /* New page address where variable will be moved to */
  462. NewPageAddress = PAGE0_BASE_ADDRESS;
  463. /* Old page ID where variable will be taken from */
  464. OldPageId = PAGE1_ID;
  465. }
  466. else if (ValidPage == PAGE0) { /* Page0 valid */
  467. /* New page address where variable will be moved to */
  468. NewPageAddress = PAGE1_BASE_ADDRESS;
  469. /* Old page ID where variable will be taken from */
  470. OldPageId = PAGE0_ID;
  471. }
  472. else
  473. return NO_VALID_PAGE; /* No valid Page */
  474. /* Set the new Page status to RECEIVE_DATA status */
  475. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);
  476. /* If program operation was failed, a Flash error code is returned */
  477. if (FlashStatus != HAL_OK) return FlashStatus;
  478. /* Write the variable passed as parameter in the new active page */
  479. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  480. /* If program operation was failed, a Flash error code is returned */
  481. if (EepromStatus != HAL_OK) return EepromStatus;
  482. /* Transfer process: transfer variables from old to the new active page */
  483. for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
  484. if (VirtAddVarTab[VarIdx] != VirtAddress) { /* Check each variable except the one passed as parameter */
  485. /* Read the other last variable updates */
  486. ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  487. /* In case variable corresponding to the virtual address was found */
  488. if (ReadStatus != 0x1) {
  489. /* Transfer the variable to the new active page */
  490. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  491. /* If program operation was failed, a Flash error code is returned */
  492. if (EepromStatus != HAL_OK) return EepromStatus;
  493. }
  494. }
  495. }
  496. pEraseInit.TypeErase = TYPEERASE_SECTORS;
  497. pEraseInit.Sector = OldPageId;
  498. pEraseInit.NbSectors = 1;
  499. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  500. /* Erase the old Page: Set old Page status to ERASED status */
  501. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  502. /* If erase operation was failed, a Flash error code is returned */
  503. if (FlashStatus != HAL_OK) return FlashStatus;
  504. /* Set new Page status to VALID_PAGE status */
  505. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);
  506. /* If program operation was failed, a Flash error code is returned */
  507. if (FlashStatus != HAL_OK) return FlashStatus;
  508. /* Return last operation flash status */
  509. return FlashStatus;
  510. }
  511. #endif // STM32F7
  512. /**
  513. * @}
  514. */
  515. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/