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.

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