My Marlin configs for Fabrikator Mini and CTC i3 Pro B
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  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. * Copyright © 2016 STMicroelectronics International N.V.
  12. * All rights reserved.
  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. #if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
  51. /* Includes ------------------------------------------------------------------*/
  52. #include "eeprom_emul.h"
  53. /* Private variables ---------------------------------------------------------*/
  54. /* Global variable used to store variable value in read sequence */
  55. uint16_t DataVar = 0;
  56. /* Virtual address defined by the user: 0xFFFF value is prohibited */
  57. uint16_t VirtAddVarTab[NB_OF_VAR];
  58. /* Private function prototypes -----------------------------------------------*/
  59. /* Private functions ---------------------------------------------------------*/
  60. static HAL_StatusTypeDef EE_Format();
  61. static uint16_t EE_FindValidPage(uint8_t Operation);
  62. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data);
  63. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data);
  64. static uint16_t EE_VerifyPageFullyErased(uint32_t Address);
  65. /**
  66. * @brief Restore the pages to a known good state in case of page's status
  67. * corruption after a power loss.
  68. * @param None.
  69. * @retval - Flash error code: on write Flash error
  70. * - FLASH_COMPLETE: on success
  71. */
  72. uint16_t EE_Initialize() {
  73. /* Get Page0 and Page1 status */
  74. uint16_t PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS),
  75. PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  76. FLASH_EraseInitTypeDef pEraseInit;
  77. pEraseInit.TypeErase = TYPEERASE_SECTORS;
  78. pEraseInit.Sector = PAGE0_ID;
  79. pEraseInit.NbSectors = 1;
  80. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  81. HAL_StatusTypeDef FlashStatus; // = HAL_OK
  82. /* Check for invalid header states and repair if necessary */
  83. uint32_t SectorError;
  84. switch (PageStatus0) {
  85. case ERASED:
  86. if (PageStatus1 == VALID_PAGE) { /* Page0 erased, Page1 valid */
  87. /* Erase Page0 */
  88. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  89. /* As the last operation, simply return the result */
  90. return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  91. }
  92. }
  93. else if (PageStatus1 == RECEIVE_DATA) { /* Page0 erased, Page1 receive */
  94. /* Erase Page0 */
  95. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  96. HAL_StatusTypeDef fStat = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  97. /* If erase operation was failed, a Flash error code is returned */
  98. if (fStat != HAL_OK) return fStat;
  99. }
  100. /* Mark Page1 as valid */
  101. /* As the last operation, simply return the result */
  102. return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
  103. }
  104. else { /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
  105. /* Erase both Page0 and Page1 and set Page0 as valid page */
  106. /* As the last operation, simply return the result */
  107. return EE_Format();
  108. }
  109. break;
  110. case RECEIVE_DATA:
  111. if (PageStatus1 == VALID_PAGE) { /* Page0 receive, Page1 valid */
  112. /* Transfer data from Page1 to Page0 */
  113. int16_t x = -1;
  114. for (uint16_t VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
  115. if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  116. x = VarIdx;
  117. if (VarIdx != x) {
  118. /* Read the last variables' updates */
  119. uint16_t ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  120. /* In case variable corresponding to the virtual address was found */
  121. if (ReadStatus != 0x1) {
  122. /* Transfer the variable to the Page0 */
  123. uint16_t EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  124. /* If program operation was failed, a Flash error code is returned */
  125. if (EepromStatus != HAL_OK) return EepromStatus;
  126. }
  127. }
  128. }
  129. /* Mark Page0 as valid */
  130. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
  131. /* If program operation was failed, a Flash error code is returned */
  132. if (FlashStatus != HAL_OK) return FlashStatus;
  133. pEraseInit.Sector = PAGE1_ID;
  134. pEraseInit.NbSectors = 1;
  135. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  136. /* Erase Page1 */
  137. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  138. /* As the last operation, simply return the result */
  139. return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  140. }
  141. }
  142. else if (PageStatus1 == ERASED) { /* Page0 receive, Page1 erased */
  143. pEraseInit.Sector = PAGE1_ID;
  144. pEraseInit.NbSectors = 1;
  145. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  146. /* Erase Page1 */
  147. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  148. HAL_StatusTypeDef fStat = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  149. /* If erase operation was failed, a Flash error code is returned */
  150. if (fStat != HAL_OK) return fStat;
  151. }
  152. /* Mark Page0 as valid */
  153. /* As the last operation, simply return the result */
  154. return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
  155. }
  156. else { /* Invalid state -> format eeprom */
  157. /* Erase both Page0 and Page1 and set Page0 as valid page */
  158. /* As the last operation, simply return the result */
  159. return EE_Format();
  160. }
  161. break;
  162. case VALID_PAGE:
  163. if (PageStatus1 == VALID_PAGE) { /* Invalid state -> format eeprom */
  164. /* Erase both Page0 and Page1 and set Page0 as valid page */
  165. FlashStatus = EE_Format();
  166. /* If erase/program operation was failed, a Flash error code is returned */
  167. if (FlashStatus != HAL_OK) return FlashStatus;
  168. }
  169. else if (PageStatus1 == ERASED) { /* Page0 valid, Page1 erased */
  170. pEraseInit.Sector = PAGE1_ID;
  171. pEraseInit.NbSectors = 1;
  172. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  173. /* Erase Page1 */
  174. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  175. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  176. /* If erase operation was failed, a Flash error code is returned */
  177. if (FlashStatus != HAL_OK) return FlashStatus;
  178. }
  179. }
  180. else { /* Page0 valid, Page1 receive */
  181. /* Transfer data from Page0 to Page1 */
  182. int16_t x = -1;
  183. for (uint16_t VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
  184. if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
  185. x = VarIdx;
  186. if (VarIdx != x) {
  187. /* Read the last variables' updates */
  188. uint16_t ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  189. /* In case variable corresponding to the virtual address was found */
  190. if (ReadStatus != 0x1) {
  191. /* Transfer the variable to the Page1 */
  192. uint16_t EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  193. /* If program operation was failed, a Flash error code is returned */
  194. if (EepromStatus != HAL_OK) return EepromStatus;
  195. }
  196. }
  197. }
  198. /* Mark Page1 as valid */
  199. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
  200. /* If program operation was failed, a Flash error code is returned */
  201. if (FlashStatus != HAL_OK) return FlashStatus;
  202. pEraseInit.Sector = PAGE0_ID;
  203. pEraseInit.NbSectors = 1;
  204. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  205. /* Erase Page0 */
  206. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  207. /* As the last operation, simply return the result */
  208. return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  209. }
  210. }
  211. break;
  212. default: /* Any other state -> format eeprom */
  213. /* Erase both Page0 and Page1 and set Page0 as valid page */
  214. /* As the last operation, simply return the result */
  215. return EE_Format();
  216. }
  217. return HAL_OK;
  218. }
  219. /**
  220. * @brief Verify if specified page is fully erased.
  221. * @param Address: page address
  222. * This parameter can be one of the following values:
  223. * @arg PAGE0_BASE_ADDRESS: Page0 base address
  224. * @arg PAGE1_BASE_ADDRESS: Page1 base address
  225. * @retval page fully erased status:
  226. * - 0: if Page not erased
  227. * - 1: if Page erased
  228. */
  229. uint16_t EE_VerifyPageFullyErased(uint32_t Address) {
  230. uint32_t ReadStatus = 1;
  231. /* Check each active page address starting from end */
  232. while (Address <= PAGE0_END_ADDRESS) {
  233. /* Get the current location content to be compared with virtual address */
  234. uint16_t AddressValue = (*(__IO uint16_t*)Address);
  235. /* Compare the read address with the virtual address */
  236. if (AddressValue != ERASED) {
  237. /* In case variable value is read, reset ReadStatus flag */
  238. ReadStatus = 0;
  239. break;
  240. }
  241. /* Next address location */
  242. Address += 4;
  243. }
  244. /* Return ReadStatus value: (0: Page not erased, 1: Sector erased) */
  245. return ReadStatus;
  246. }
  247. /**
  248. * @brief Returns the last stored variable data, if found, which correspond to
  249. * the passed virtual address
  250. * @param VirtAddress: Variable virtual address
  251. * @param Data: Global variable contains the read variable value
  252. * @retval Success or error status:
  253. * - 0: if variable was found
  254. * - 1: if the variable was not found
  255. * - NO_VALID_PAGE: if no valid page was found.
  256. */
  257. uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) {
  258. uint16_t ReadStatus = 1;
  259. /* Get active Page for read operation */
  260. uint16_t ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  261. /* Check if there is no valid page */
  262. if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
  263. /* Get the valid Page start and end Addresses */
  264. uint32_t PageStartAddress = uint32_t(EEPROM_START_ADDRESS) + uint32_t(ValidPage * (PAGE_SIZE)),
  265. Address = PageStartAddress + PAGE_SIZE - 2;
  266. /* Check each active page address starting from end */
  267. while (Address > PageStartAddress + 2) {
  268. /* Get the current location content to be compared with virtual address */
  269. uint16_t AddressValue = (*(__IO uint16_t*)Address);
  270. /* Compare the read address with the virtual address */
  271. if (AddressValue == VirtAddress) {
  272. /* Get content of Address-2 which is variable value */
  273. *Data = (*(__IO uint16_t*)(Address - 2));
  274. /* In case variable value is read, reset ReadStatus flag */
  275. ReadStatus = 0;
  276. break;
  277. }
  278. else /* Next address location */
  279. Address -= 4;
  280. }
  281. /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
  282. return ReadStatus;
  283. }
  284. /**
  285. * @brief Writes/upadtes variable data in EEPROM.
  286. * @param VirtAddress: Variable virtual address
  287. * @param Data: 16 bit data to be written
  288. * @retval Success or error status:
  289. * - FLASH_COMPLETE: on success
  290. * - PAGE_FULL: if valid page is full
  291. * - NO_VALID_PAGE: if no valid page was found
  292. * - Flash error code: on write Flash error
  293. */
  294. uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data) {
  295. /* Write the variable virtual address and value in the EEPROM */
  296. uint16_t Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  297. /* In case the EEPROM active page is full */
  298. if (Status == PAGE_FULL) /* Perform Page transfer */
  299. Status = EE_PageTransfer(VirtAddress, Data);
  300. /* Return last operation status */
  301. return Status;
  302. }
  303. /**
  304. * @brief Erases PAGE and PAGE1 and writes VALID_PAGE header to PAGE
  305. * @param None
  306. * @retval Status of the last operation (Flash write or erase) done during
  307. * EEPROM formating
  308. */
  309. static HAL_StatusTypeDef EE_Format() {
  310. FLASH_EraseInitTypeDef pEraseInit;
  311. pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
  312. pEraseInit.Sector = PAGE0_ID;
  313. pEraseInit.NbSectors = 1;
  314. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  315. HAL_StatusTypeDef FlashStatus; // = HAL_OK
  316. /* Erase Page0 */
  317. if (!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS)) {
  318. uint32_t SectorError;
  319. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  320. /* If erase operation was failed, a Flash error code is returned */
  321. if (FlashStatus != HAL_OK) return FlashStatus;
  322. }
  323. /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
  324. FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
  325. /* If program operation was failed, a Flash error code is returned */
  326. if (FlashStatus != HAL_OK) return FlashStatus;
  327. pEraseInit.Sector = PAGE1_ID;
  328. /* Erase Page1 */
  329. if (!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS)) {
  330. /* As the last operation, just return the result code */
  331. uint32_t SectorError;
  332. return HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  333. }
  334. return HAL_OK;
  335. }
  336. /**
  337. * @brief Find valid Page for write or read operation
  338. * @param Operation: operation to achieve on the valid page.
  339. * This parameter can be one of the following values:
  340. * @arg READ_FROM_VALID_PAGE: read operation from valid page
  341. * @arg WRITE_IN_VALID_PAGE: write operation from valid page
  342. * @retval Valid page number (PAGE or PAGE1) or NO_VALID_PAGE in case
  343. * of no valid page was found
  344. */
  345. static uint16_t EE_FindValidPage(uint8_t Operation) {
  346. /* Get Page0 and Page1 actual status */
  347. uint16_t PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS),
  348. PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);
  349. /* Write or read operation */
  350. switch (Operation) {
  351. case WRITE_IN_VALID_PAGE: /* ---- Write operation ---- */
  352. if (PageStatus1 == VALID_PAGE) {
  353. /* Page0 receiving data */
  354. return (PageStatus0 == RECEIVE_DATA) ? PAGE0 : PAGE1;
  355. }
  356. else if (PageStatus0 == VALID_PAGE) {
  357. /* Page1 receiving data */
  358. return (PageStatus1 == RECEIVE_DATA) ? PAGE1 : PAGE0;
  359. }
  360. else
  361. return NO_VALID_PAGE; /* No valid Page */
  362. case READ_FROM_VALID_PAGE: /* ---- Read operation ---- */
  363. if (PageStatus0 == VALID_PAGE)
  364. return PAGE0; /* Page0 valid */
  365. else if (PageStatus1 == VALID_PAGE)
  366. return PAGE1; /* Page1 valid */
  367. else
  368. return NO_VALID_PAGE; /* No valid Page */
  369. default:
  370. return PAGE0; /* Page0 valid */
  371. }
  372. }
  373. /**
  374. * @brief Verify if active page is full and Writes variable in EEPROM.
  375. * @param VirtAddress: 16 bit virtual address of the variable
  376. * @param Data: 16 bit data to be written as variable value
  377. * @retval Success or error status:
  378. * - FLASH_COMPLETE: on success
  379. * - PAGE_FULL: if valid page is full
  380. * - NO_VALID_PAGE: if no valid page was found
  381. * - Flash error code: on write Flash error
  382. */
  383. static uint16_t EE_VerifyPageFullWriteVariable(uint16_t VirtAddress, uint16_t Data) {
  384. /* Get valid Page for write operation */
  385. uint16_t ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);
  386. /* Check if there is no valid page */
  387. if (ValidPage == NO_VALID_PAGE) return NO_VALID_PAGE;
  388. /* Get the valid Page start and end Addresses */
  389. uint32_t Address = uint32_t(EEPROM_START_ADDRESS) + uint32_t(ValidPage * (PAGE_SIZE)),
  390. PageEndAddress = Address + PAGE_SIZE - 1;
  391. /* Check each active page address starting from begining */
  392. while (Address < PageEndAddress) {
  393. /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
  394. if ((*(__IO uint32_t*)Address) == 0xFFFFFFFF) {
  395. /* Set variable data */
  396. HAL_StatusTypeDef FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address, Data);
  397. /* If program operation was failed, a Flash error code is returned */
  398. if (FlashStatus != HAL_OK) return FlashStatus;
  399. /* Set variable virtual address, return status */
  400. return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, Address + 2, VirtAddress);
  401. }
  402. else /* Next address location */
  403. Address += 4;
  404. }
  405. /* Return PAGE_FULL in case the valid page is full */
  406. return PAGE_FULL;
  407. }
  408. /**
  409. * @brief Transfers last updated variables data from the full Page to
  410. * an empty one.
  411. * @param VirtAddress: 16 bit virtual address of the variable
  412. * @param Data: 16 bit data to be written as variable value
  413. * @retval Success or error status:
  414. * - FLASH_COMPLETE: on success
  415. * - PAGE_FULL: if valid page is full
  416. * - NO_VALID_PAGE: if no valid page was found
  417. * - Flash error code: on write Flash error
  418. */
  419. static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data) {
  420. /* Get active Page for read operation */
  421. uint16_t ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);
  422. uint32_t NewPageAddress = EEPROM_START_ADDRESS;
  423. uint16_t OldPageId = 0;
  424. if (ValidPage == PAGE1) { /* Page1 valid */
  425. /* New page address where variable will be moved to */
  426. NewPageAddress = PAGE0_BASE_ADDRESS;
  427. /* Old page ID where variable will be taken from */
  428. OldPageId = PAGE1_ID;
  429. }
  430. else if (ValidPage == PAGE0) { /* Page0 valid */
  431. /* New page address where variable will be moved to */
  432. NewPageAddress = PAGE1_BASE_ADDRESS;
  433. /* Old page ID where variable will be taken from */
  434. OldPageId = PAGE0_ID;
  435. }
  436. else
  437. return NO_VALID_PAGE; /* No valid Page */
  438. /* Set the new Page status to RECEIVE_DATA status */
  439. HAL_StatusTypeDef FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);
  440. /* If program operation was failed, a Flash error code is returned */
  441. if (FlashStatus != HAL_OK) return FlashStatus;
  442. /* Write the variable passed as parameter in the new active page */
  443. uint16_t EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  444. /* If program operation was failed, a Flash error code is returned */
  445. if (EepromStatus != HAL_OK) return EepromStatus;
  446. /* Transfer process: transfer variables from old to the new active page */
  447. for (uint16_t VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++) {
  448. if (VirtAddVarTab[VarIdx] != VirtAddress) { /* Check each variable except the one passed as parameter */
  449. /* Read the other last variable updates */
  450. uint16_t ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
  451. /* In case variable corresponding to the virtual address was found */
  452. if (ReadStatus != 0x1) {
  453. /* Transfer the variable to the new active page */
  454. EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
  455. /* If program operation was failed, a Flash error code is returned */
  456. if (EepromStatus != HAL_OK) return EepromStatus;
  457. }
  458. }
  459. }
  460. FLASH_EraseInitTypeDef pEraseInit;
  461. pEraseInit.TypeErase = TYPEERASE_SECTORS;
  462. pEraseInit.Sector = OldPageId;
  463. pEraseInit.NbSectors = 1;
  464. pEraseInit.VoltageRange = VOLTAGE_RANGE;
  465. /* Erase the old Page: Set old Page status to ERASED status */
  466. uint32_t SectorError;
  467. FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
  468. /* If erase operation was failed, a Flash error code is returned */
  469. if (FlashStatus != HAL_OK) return FlashStatus;
  470. /* Set new Page status to VALID_PAGE status */
  471. /* As the last operation, just return the result code */
  472. return HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);
  473. }
  474. #endif // STM32GENERIC && (STM32F4 || STM32F7)
  475. /**
  476. * @}
  477. */
  478. /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/