Beispiel #1
0
/**
  * @brief  Writes/upadtes variable data in EEPROM.
  * @param  VirtAddress: Variable virtual address
  * @param  Data: 16 bit data to be written
  * @retval Success or error status:
  *			- FLASH_COMPLETE: on success
  *			- EEPROM_BAD_ADDRESS: if address = 0xFFFF
  *			- EEPROM_PAGE_FULL: if valid page is full
  *			- EEPROM_NO_VALID_PAGE: if no valid page was found
  *			- EEPROM_OUT_SIZE: if no empty EEPROM variables
  *			- Flash error code: on write Flash error
  */
uint16 EEPROMClass::write(uint16 Address, uint16 Data)
{
	if (Status == EEPROM_NOT_INIT)
		if (init() != EEPROM_OK)
			return Status;

	if (Address == 0xFFFF)
		return EEPROM_BAD_ADDRESS;

	// Write the variable virtual address and value in the EEPROM
	uint16 status = EE_VerifyPageFullWriteVariable(Address, Data);
	return status;
}
Beispiel #2
0
/**
  * @brief  Writes/upadtes variable data in EEPROM.
  * @param  VirtAddress: Variable virtual address
  * @param  Data: 16 bit data to be written
  * @retval Success or error status:
  *           - FLASH_COMPLETE: on success
  *           - PAGE_FULL: if valid page is full
  *           - NO_VALID_PAGE: if no valid page was found
  *           - Flash error code: on write Flash error
  */
uint16_t EE_WriteVariable(uint16_t VirtAddress, uint16_t Data)
{
    uint16_t Status = 0;
    /* Write the variable virtual address and value in the EEPROM */
    Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);

    /* In case the EEPROM active page is full */
    if(Status == PAGE_FULL) {
        /* Perform Page transfer */
        Status = EE_PageTransfer(VirtAddress, Data);
    }

    /* Return last operation status */
    return Status;
}
Beispiel #3
0
static uint16_t EE_TransferVariable(uint16_t VirtAddress, uint32_t BaseAddress)
{
  if (( *(__IO uint16_t*)(BaseAddress + 6)) != VirtAddress)
  {
    /* Read the last variables' updates */
    uint16_t ReadStatus = EE_ReadVariable(VirtAddress, &DataVar);
    /* In case variable corresponding to the virtual address was found */
    if (ReadStatus != 0x1)
    {
      /* Transfer the variable to the new page */
      return EE_VerifyPageFullWriteVariable(VirtAddress, DataVar);
    }
  }

  return FLASH_COMPLETE;
}
Beispiel #4
0
/**
  * @brief  Restore the pages to a known good state in case of page's status
  *   corruption after a power loss.
  * @param  None.
  * @retval - Flash error code: on write Flash error
  *         - FLASH_COMPLETE: on success
  */
uint16_t EE_Init(void)
{
    uint16_t PageStatus0 = 6, PageStatus1 = 6;
    uint16_t VarIdx = 0;
    uint16_t EepromStatus = 0, ReadStatus = 0;
    int16_t x = -1;
    uint16_t  FlashStatus;
    /* Get Page0 status */
    PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
    /* Get Page1 status */
    PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);

    /* Check for invalid header states and repair if necessary */
    switch(PageStatus0) {
        case ERASED:
            if(PageStatus1 == VALID_PAGE) {    /* Page0 erased, Page1 valid */
                /* Erase Page0 */
                FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);

                /* If erase operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

            } else if(PageStatus1 == RECEIVE_DATA) {    /* Page0 erased, Page1 receive */
                /* Erase Page0 */
                FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);

                /* If erase operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

                /* Mark Page1 as valid */
                FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);

                /* If program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

            } else { /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
                /* Erase both Page0 and Page1 and set Page0 as valid page */
                FlashStatus = EE_Format();

                /* If erase/program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }
            }

            break;

        case RECEIVE_DATA:
            if(PageStatus1 == VALID_PAGE) {    /* Page0 receive, Page1 valid */
                /* Transfer data from Page1 to Page0 */
                for(VarIdx = 0; VarIdx < NumbOfVar; VarIdx++) {
                    if((*(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) {	
									//前两个字节存PageStatus,随后每4字节为一组,先存数据值(前2字节),再存虚拟地址(后2字节),所以+6,是判断第一个组的虚拟地址:jkl
                        x = VarIdx;
                    }

                    if(VarIdx != x) {
                        /* Read the last variables' updates */
                        ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);

                        /* In case variable corresponding to the virtual address was found */
                        if(ReadStatus != 0x1) {
                            /* Transfer the variable to the Page0 */
                            EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);

                            /* If program operation was failed, a Flash error code is returned */
                            if(EepromStatus != FLASH_COMPLETE) {
                                return EepromStatus;
                            }
                        }
                    }
                }

                /* Mark Page0 as valid */
                FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);

                /* If program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

                /* Erase Page1 */
                FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);

                /* If erase operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

            } else if(PageStatus1 == ERASED) {    /* Page0 receive, Page1 erased */
                /* Erase Page1 */
                FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);

                /* If erase operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

                /* Mark Page0 as valid */
                FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);

                /* If program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

            } else { /* Invalid state -> format eeprom */
                /* Erase both Page0 and Page1 and set Page0 as valid page */
                FlashStatus = EE_Format();

                /* If erase/program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }
            }

            break;

        case VALID_PAGE:
            if(PageStatus1 == VALID_PAGE) {    /* Invalid state -> format eeprom */
                /* Erase both Page0 and Page1 and set Page0 as valid page */
                FlashStatus = EE_Format();

                /* If erase/program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

            } else if(PageStatus1 == ERASED) {    /* Page0 valid, Page1 erased */
                /* Erase Page1 */
                FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);

                /* If erase operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

            } else { /* Page0 valid, Page1 receive */
                /* Transfer data from Page0 to Page1 */
                for(VarIdx = 0; VarIdx < NumbOfVar; VarIdx++) {
                    if((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx]) {
                        x = VarIdx;
                    }

                    if(VarIdx != x) {
                        /* Read the last variables' updates */
                        ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);

                        /* In case variable corresponding to the virtual address was found */
                        if(ReadStatus != 0x1) {
                            /* Transfer the variable to the Page1 */
                            EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);

                            /* If program operation was failed, a Flash error code is returned */
                            if(EepromStatus != FLASH_COMPLETE) {
                                return EepromStatus;
                            }
                        }
                    }
                }

                /* Mark Page1 as valid */
                FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);

                /* If program operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }

                /* Erase Page0 */
                FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);

                /* If erase operation was failed, a Flash error code is returned */
                if(FlashStatus != FLASH_COMPLETE) {
                    return FlashStatus;
                }
            }

            break;

        default:  /* Any other state -> format eeprom */
            /* Erase both Page0 and Page1 and set Page0 as valid page */
            FlashStatus = EE_Format();

            /* If erase/program operation was failed, a Flash error code is returned */
            if(FlashStatus != FLASH_COMPLETE) {
                return FlashStatus;
            }

            break;
    }

    return FLASH_COMPLETE;
}
Beispiel #5
0
/**
  * @brief  Transfers last updated variables data from the full Page to
  *   an empty one.
  * @param  VirtAddress: 16 bit virtual address of the variable
  * @param  Data: 16 bit data to be written as variable value
  * @retval Success or error status:
  *           - FLASH_COMPLETE: on success
  *           - PAGE_FULL: if valid page is full
  *           - NO_VALID_PAGE: if no valid page was found
  *           - Flash error code: on write Flash error
  */
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
    FLASH_Status FlashStatus = FLASH_COMPLETE;
    uint32_t NewPageAddress = 0x00000000, OldPageAddress = 0x00000000;
    uint16_t ValidPage = PAGE0, VarIdx = 0;
    uint16_t EepromStatus = 0, ReadStatus = 0;
    /* Get active Page for read operation */
    ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);

    if(ValidPage == PAGE1) {      /* Page1 valid */
        /* New page address where variable will be moved to */
        NewPageAddress = PAGE0_BASE_ADDRESS;
        /* Old page address where variable will be taken from */
        OldPageAddress = PAGE1_BASE_ADDRESS;

    } else if(ValidPage == PAGE0) {    /* Page0 valid */
        /* New page address where variable will be moved to */
        NewPageAddress = PAGE1_BASE_ADDRESS;
        /* Old page address where variable will be taken from */
        OldPageAddress = PAGE0_BASE_ADDRESS;

    } else {
        return NO_VALID_PAGE;       /* No valid Page */
    }

    /* Set the new Page status to RECEIVE_DATA status */
    FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA);

    /* If program operation was failed, a Flash error code is returned */
    if(FlashStatus != FLASH_COMPLETE) {
        return FlashStatus;
    }

    /* Write the variable passed as parameter in the new active page */
    EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);

    /* If program operation was failed, a Flash error code is returned */
    if(EepromStatus != FLASH_COMPLETE) {
        return EepromStatus;
    }

    /* Transfer process: transfer variables from old to the new active page */
    for(VarIdx = 0; VarIdx < NumbOfVar; VarIdx++) {
        if(VirtAddVarTab[VarIdx] != VirtAddress) {    /* Check each variable except the one passed as parameter */
            /* Read the other last variable updates */
            ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);

            /* In case variable corresponding to the virtual address was found */
            if(ReadStatus != 0x1) {
                /* Transfer the variable to the new active page */
                EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);

                /* If program operation was failed, a Flash error code is returned */
                if(EepromStatus != FLASH_COMPLETE) {
                    return EepromStatus;
                }
            }
        }
    }

    /* Erase the old Page: Set old Page status to ERASED status */
    FlashStatus = FLASH_ErasePage(OldPageAddress);

    /* If erase operation was failed, a Flash error code is returned */
    if(FlashStatus != FLASH_COMPLETE) {
        return FlashStatus;
    }

    /* Set new Page status to VALID_PAGE status */
    FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE);

    /* If program operation was failed, a Flash error code is returned */
    if(FlashStatus != FLASH_COMPLETE) {
        return FlashStatus;
    }

    /* Return last operation flash status */
    return FlashStatus;
}
Beispiel #6
0
/**
  * @brief  Transfers last updated variables data from the full Page to
  *   an empty one.
  * @param  VirtAddress: 16 bit virtual address of the variable
  * @param  Data: 16 bit data to be written as variable value
  * @retval Success or error status:
  *           - FLASH_COMPLETE: on success
  *           - PAGE_FULL: if valid page is full
  *           - NO_VALID_PAGE: if no valid page was found
  *           - Flash error code: on write Flash error
  */
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
  FLASH_Status FlashStatus = FLASH_COMPLETE;
  uint32_t NewPageAddress = 0x080103FF, OldPageAddress = 0x08010000;
  uint16_t ValidPage = PAGE0, VarIdx = 0;
  uint16_t EepromStatus = 0;

  /* Get active Page for read operation */
  ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);

  if (ValidPage == PAGE1)       /* Page1 valid */
  {
    /* New page address where variable will be moved to */
    NewPageAddress = PAGE0_BASE_ADDRESS;

    /* Old page address where variable will be taken from */
    OldPageAddress = PAGE1_BASE_ADDRESS;
  }
  else if (ValidPage == PAGE0)  /* Page0 valid */
  {
    /* New page address where variable will be moved to */
    NewPageAddress = PAGE1_BASE_ADDRESS;

    /* Old page address where variable will be taken from */
    OldPageAddress = PAGE0_BASE_ADDRESS;
  }
  else
  {
    return NO_VALID_PAGE;       /* No valid Page */
  }

  /* Set the new Page status to RECEIVE_DATA status */
  FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA);
  /* If program operation was failed, a Flash error code is returned */
  if (FlashStatus != FLASH_COMPLETE)
  {
    return FlashStatus;
  }

  /* Write the variable passed as parameter in the new active page */
  EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  /* If program operation was failed, a Flash error code is returned */
  if (EepromStatus != FLASH_COMPLETE)
  {
    return EepromStatus;
  }

  /* First transfer the contiguous region of addresses */
  for (VarIdx = 0; VarIdx < EE_MAX_CONTIGUOUS; VarIdx++)
  {
    /* Check each variable except the one passed as parameter */
    if (VarIdx != VirtAddress)
    {
      EepromStatus = EE_TransferVariable(VarIdx, NewPageAddress);
      if (EepromStatus != FLASH_COMPLETE)
          return EepromStatus;
    }
  }

  /* Then the individual addresses in the address table */
  for (VarIdx = 0; VarIdx < EE_NUM_ADDR; VarIdx++)
  {
    if (ee_addr_table[VarIdx] != VirtAddress)
    {
      EepromStatus = EE_TransferVariable(ee_addr_table[VarIdx], NewPageAddress);
      if (EepromStatus != FLASH_COMPLETE)
          return EepromStatus;
    }
  }

  /* Erase the old Page: Set old Page status to ERASED status */
  FlashStatus = FLASH_ErasePage(OldPageAddress);
  /* If erase operation was failed, a Flash error code is returned */
  if (FlashStatus != FLASH_COMPLETE)
  {
    return FlashStatus;
  }

  /* Set new Page status to VALID_PAGE status */
  FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE);
  /* If program operation was failed, a Flash error code is returned */
  if (FlashStatus != FLASH_COMPLETE)
  {
    return FlashStatus;
  }

  /* Return last operation flash status */
  return FlashStatus;
}
Beispiel #7
0
/**
  * @brief  Transfers last updated variables data from the full Page to
  *   an empty one.
  * @param  VirtAddress: 16 bit virtual address of the variable
  * @param  Data: 16 bit data to be written as variable value
  * @retval Success or error status:
  *           - FLASH_COMPLETE: on success
  *           - PAGE_FULL: if valid page is full
  *           - NO_VALID_PAGE: if no valid page was found
  *           - Flash error code: on write Flash error
  */
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
  FLASH_Status FlashStatus = FLASH_COMPLETE;
  uint32_t NewPageAddress = PAGE1_BASE_ADDRESS, OldPageAddress = PAGE0_BASE_ADDRESS;
  uint16_t ValidPage = PAGE0, VarIdx = 0;
  uint16_t EepromStatus = 0, ReadStatus = 0;

  /* Get active Page for read operation */
  ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);

  if (ValidPage == PAGE1)       /* Page1 valid */
  {
    /* New page address where variable will be moved to */
    NewPageAddress = PAGE0_BASE_ADDRESS;

    /* Old page address where variable will be taken from */
    OldPageAddress = PAGE1_BASE_ADDRESS;
  }
  else if (ValidPage == PAGE0)  /* Page0 valid */
  {
    /* New page address where variable will be moved to */
    NewPageAddress = PAGE1_BASE_ADDRESS;

    /* Old page address where variable will be taken from */
    OldPageAddress = PAGE0_BASE_ADDRESS;
  }
  else
  {
    return NO_VALID_PAGE;       /* No valid Page */
  }
  //FLASH_Unlock();

  /* Set the new Page status to RECEIVE_DATA status */
  FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA);
  /* If program operation was failed, a Flash error code is returned */
  if (FlashStatus != FLASH_COMPLETE)
  {
    //FLASH_Lock();
    return FlashStatus;
  }

  /* Write the variable passed as parameter in the new active page */
  EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  /* If program operation was failed, a Flash error code is returned */
  if (EepromStatus != FLASH_COMPLETE)
  {
    //FLASH_Lock();
    return EepromStatus;
  }

  /* Transfer process: transfer variables from old to the new active page */
  for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
  {
    if (VirtAddVarTab[VarIdx] != VirtAddress)  /* Check each variable except the one passed as parameter */
    {
      /* Read the other last variable updates */
      ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
      /* In case variable corresponding to the virtual address was found */
      if (ReadStatus != 0x1)
      {
        /* Transfer the variable to the new active page */
        EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
        /* If program operation was failed, a Flash error code is returned */
        if (EepromStatus != FLASH_COMPLETE)
        {
          //FLASH_Lock();
          return EepromStatus;
        }
      }
    }
  }

  /* Erase the old Page: Set old Page status to ERASED status */
  FlashStatus = eraseHelper(OldPageAddress);
  /* If erase operation was failed, a Flash error code is returned */
  if (FlashStatus != FLASH_COMPLETE)
  {
    //FLASH_Lock();
    return FlashStatus;
  }

  /* Set new Page status to VALID_PAGE status */
  FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE);
  /* If program operation was failed, a Flash error code is returned */
  if (FlashStatus != FLASH_COMPLETE)
  {
    //FLASH_Lock();
    return FlashStatus;
  }

  // FIX from https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FEEPROM%20emulation%20in%20STM32F4x%20family&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=272

  // /* Flush the caches by setting the DCRST and ICRST bits in the FLASH_CR register. Note: The I/D cache should be flushed only when it is disabled (I/DCEN = 0).*/
  // FLASH->ACR &= ~(FLASH_ACR_ICEN |FLASH_ACR_DCEN);
  // FLASH->ACR = (FLASH_ACR_ICRST |FLASH_ACR_DCRST); 
  // /* Now restore ( Enable I/D caches, clear the DCRST and ICRST bits */
  // FLASH->ACR = (FLASH_ACR_ICEN |FLASH_ACR_DCEN);
  // FLASH->ACR = ~(FLASH_ACR_ICRST |FLASH_ACR_DCRST);

  //FLASH_Lock();
  /* Return last operation flash status */
  return FlashStatus;
}
Beispiel #8
0
/**
  * @brief  Restore the pages to a known good state in case of page's status
  *   corruption after a power loss.
  * @param  None.
  * @retval - Flash error code: on write Flash error
  *         - FLASH_COMPLETE: on success
  */
uint16_t EE_Init(void)
{
  uint16_t PageStatus0 = 6, PageStatus1 = 6;
  uint16_t VarIdx = 0;
  uint16_t EepromStatus = 0, ReadStatus = 0;
  int16_t x = -1;
  HAL_StatusTypeDef  FlashStatus;
  uint32_t SectorError = 0;
  FLASH_EraseInitTypeDef pEraseInit;


  /* Get Page0 status */
  PageStatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  /* Get Page1 status */
  PageStatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);

  pEraseInit.TypeErase = TYPEERASE_SECTORS;
  pEraseInit.Sector = PAGE0_ID;
  pEraseInit.NbSectors = 1;
  pEraseInit.VoltageRange = VOLTAGE_RANGE;
  
  /* Check for invalid header states and repair if necessary */
  switch (PageStatus0)
  {
    case ERASED:
      if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
      {
          /* Erase Page0 */
        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
        {
          FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
          /* If erase operation was failed, a Flash error code is returned */
          if (FlashStatus != HAL_OK)
          {
            return FlashStatus;
          }
        }
      }
      else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
      {
        /* Erase Page0 */
        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
        { 
          FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
          /* If erase operation was failed, a Flash error code is returned */
          if (FlashStatus != HAL_OK)
          {
            return FlashStatus;
          }
        }
        /* Mark Page1 as valid */
        FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
      }
      else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        FlashStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
      }
      break;

    case RECEIVE_DATA:
      if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
      {
        /* Transfer data from Page1 to Page0 */
        for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
        {
          if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
          {
            x = VarIdx;
          }
          if (VarIdx != x)
          {
            /* Read the last variables' updates */
            ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
            /* In case variable corresponding to the virtual address was found */
            if (ReadStatus != 0x1)
            {
              /* Transfer the variable to the Page0 */
              EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
              /* If program operation was failed, a Flash error code is returned */
              if (EepromStatus != HAL_OK)
              {
                return EepromStatus;
              }
            }
          }
        }
        /* Mark Page0 as valid */
        FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
        pEraseInit.Sector = PAGE1_ID;
        pEraseInit.NbSectors = 1;
        pEraseInit.VoltageRange = VOLTAGE_RANGE;
        /* Erase Page1 */
        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
        { 
          FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
          /* If erase operation was failed, a Flash error code is returned */
          if (FlashStatus != HAL_OK)
          {
            return FlashStatus;
          }
        }
      }
      else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
      {
        pEraseInit.Sector = PAGE1_ID;
        pEraseInit.NbSectors = 1;
        pEraseInit.VoltageRange = VOLTAGE_RANGE;
        /* Erase Page1 */
        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
        { 
          FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
          /* If erase operation was failed, a Flash error code is returned */
          if (FlashStatus != HAL_OK)
          {
            return FlashStatus;
          }
        }
        /* Mark Page0 as valid */
        FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
      }
      else /* Invalid state -> format eeprom */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        FlashStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
      }
      break;

    case VALID_PAGE:
      if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        FlashStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
      }
      else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
      {
        pEraseInit.Sector = PAGE1_ID;
        pEraseInit.NbSectors = 1;
        pEraseInit.VoltageRange = VOLTAGE_RANGE;
        /* Erase Page1 */
        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
        { 
          FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
          /* If erase operation was failed, a Flash error code is returned */
          if (FlashStatus != HAL_OK)
          {
            return FlashStatus;
          }
        }
      }
      else /* Page0 valid, Page1 receive */
      {
        /* Transfer data from Page0 to Page1 */
        for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
        {
          if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
          {
            x = VarIdx;
          }
          if (VarIdx != x)
          {
            /* Read the last variables' updates */
            ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
            /* In case variable corresponding to the virtual address was found */
            if (ReadStatus != 0x1)
            {
              /* Transfer the variable to the Page1 */
              EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
              /* If program operation was failed, a Flash error code is returned */
              if (EepromStatus != HAL_OK)
              {
                return EepromStatus;
              }
            }
          }
        }
        /* Mark Page1 as valid */
        FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);        
        /* If program operation was failed, a Flash error code is returned */
        if (FlashStatus != HAL_OK)
        {
          return FlashStatus;
        }
        pEraseInit.Sector = PAGE0_ID;
        pEraseInit.NbSectors = 1;
        pEraseInit.VoltageRange = VOLTAGE_RANGE;
        /* Erase Page0 */
        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
        { 
          FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);
          /* If erase operation was failed, a Flash error code is returned */
          if (FlashStatus != HAL_OK)
          {
            return FlashStatus;
          }
        }
      }
      break;

    default:  /* Any other state -> format eeprom */
      /* Erase both Page0 and Page1 and set Page0 as valid page */
      FlashStatus = EE_Format();
      /* If erase/program operation was failed, a Flash error code is returned */
      if (FlashStatus != HAL_OK)
      {
        return FlashStatus;
      }
      break;
  }

  return HAL_OK;
}
Beispiel #9
0
/**
  * @brief  Transfers last updated variables data from the full Page to
  *   an empty one.
  * @param  VirtAddress: 16 bit virtual address of the variable
  * @param  Data: 16 bit data to be written as variable value
  * @retval Success or error status:
  *           - FLASH_COMPLETE: on success
  *           - PAGE_FULL: if valid page is full
  *           - NO_VALID_PAGE: if no valid page was found
  *           - Flash error code: on write Flash error
  */
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
  HAL_StatusTypeDef FlashStatus = HAL_OK;
  uint32_t NewPageAddress = EEPROM_START_ADDRESS;
  uint16_t OldPageId=0;
  uint16_t ValidPage = PAGE0, VarIdx = 0;
  uint16_t EepromStatus = 0, ReadStatus = 0;
  uint32_t SectorError = 0;
  FLASH_EraseInitTypeDef pEraseInit;

  /* Get active Page for read operation */
  ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);

  if (ValidPage == PAGE1)       /* Page1 valid */
  {
    /* New page address where variable will be moved to */
    NewPageAddress = PAGE0_BASE_ADDRESS;

    /* Old page ID where variable will be taken from */
    OldPageId = PAGE1_ID;
  }
  else if (ValidPage == PAGE0)  /* Page0 valid */
  {
    /* New page address  where variable will be moved to */
    NewPageAddress = PAGE1_BASE_ADDRESS;

    /* Old page ID where variable will be taken from */
    OldPageId = PAGE0_ID;
  }
  else
  {
    return NO_VALID_PAGE;       /* No valid Page */
  }

  /* Set the new Page status to RECEIVE_DATA status */
  FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, RECEIVE_DATA);  
  /* If program operation was failed, a Flash error code is returned */
  if (FlashStatus != HAL_OK)
  {
    return FlashStatus;
  }
  
  /* Write the variable passed as parameter in the new active page */
  EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  /* If program operation was failed, a Flash error code is returned */
  if (EepromStatus != HAL_OK)
  {
    return EepromStatus;
  }

  /* Transfer process: transfer variables from old to the new active page */
  for (VarIdx = 0; VarIdx < NB_OF_VAR; VarIdx++)
  {
    if (VirtAddVarTab[VarIdx] != VirtAddress)  /* Check each variable except the one passed as parameter */
    {
      /* Read the other last variable updates */
      ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
      /* In case variable corresponding to the virtual address was found */
      if (ReadStatus != 0x1)
      {
        /* Transfer the variable to the new active page */
        EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
        /* If program operation was failed, a Flash error code is returned */
        if (EepromStatus != HAL_OK)
        {
          return EepromStatus;
        }
      }
    }
  }

  pEraseInit.TypeErase = TYPEERASE_SECTORS;
  pEraseInit.Sector = OldPageId;
  pEraseInit.NbSectors = 1;
  pEraseInit.VoltageRange = VOLTAGE_RANGE;
  
  /* Erase the old Page: Set old Page status to ERASED status */
  FlashStatus = HAL_FLASHEx_Erase(&pEraseInit, &SectorError);  
  /* If erase operation was failed, a Flash error code is returned */
  if (FlashStatus != HAL_OK)
  {
    return FlashStatus;
  }

  /* Set new Page status to VALID_PAGE status */
  FlashStatus = HAL_FLASH_Program(TYPEPROGRAM_HALFWORD, NewPageAddress, VALID_PAGE);   
  /* If program operation was failed, a Flash error code is returned */
  if (FlashStatus != HAL_OK)
  {
    return FlashStatus;
  }

  /* Return last operation flash status */
  return FlashStatus;
}
/**
 * @brief  Restore the pages to a known good state in case of page's status
 *   corruption after a power loss.
 * @param  None.
 * @retval - Flash error code: on write Flash error
 *         - FLASH_COMPLETE: on success
 */
uint16_t EE_Init(void) {

	/* Unlock the Flash Program Erase controller */
	FLASH_Unlock();

	/* We use a uint16_t counter here because that is the width of the address field, thus that many are supported. */
	for (uint16_t i = 0; i < NUM_EEPROM_ADDRESSES; ++i) {
		EEPROM_ADDRESSES[i] = i; /* We will always do them sequentially */
	}

	uint16_t PageStatus0 = 6, PageStatus1 = 6;
	uint16_t VarIdx = 0;
	uint16_t EepromStatus = 0, ReadStatus = 0;
	int16_t x = -1;
	uint16_t FlashStatus;

	/* Get Page0 status */
	PageStatus0 = (*(__IO uint16_t*) PAGE0_BASE_ADDRESS );
	/* Get Page1 status */
	PageStatus1 = (*(__IO uint16_t*) PAGE1_BASE_ADDRESS );

	/* Check for invalid header states and repair if necessary */
	switch (PageStatus0) {
	case ERASED :
		if (PageStatus1 == VALID_PAGE ) /* Page0 erased, Page1 valid */
		{
			/* Erase Page0 */
			FlashStatus = FLASH_EraseSector(PAGE0_ID, FLASH_VOLTAGE_RANGE );
			/* If erase operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		} else if (PageStatus1 == RECEIVE_DATA ) /* Page0 erased, Page1 receive */
		{
			/* Erase Page0 */
			FlashStatus = FLASH_EraseSector(PAGE0_ID, FLASH_VOLTAGE_RANGE );
			/* If erase operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
			/* Mark Page1 as valid */
			FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE );
			/* If program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		} else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
		{
			/* Erase both Page0 and Page1 and set Page0 as valid page */
			FlashStatus = EE_Format();
			/* If erase/program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		}
		break;

	case RECEIVE_DATA :
		if (PageStatus1 == VALID_PAGE ) /* Page0 receive, Page1 valid */
		{
			/* Transfer data from Page1 to Page0 */
			for (VarIdx = 0; VarIdx < NUM_EEPROM_ADDRESSES ; VarIdx++) {
				if ((*(__IO uint16_t*) (PAGE0_BASE_ADDRESS + 6)) == EEPROM_ADDRESSES[VarIdx]) {
					x = VarIdx;
				}
				if (VarIdx != x) {
					/* Read the last variables' updates */
					ReadStatus = EE_ReadVariable(EEPROM_ADDRESSES[VarIdx], &DataVar);
					/* In case variable corresponding to the virtual address was found */
					if (ReadStatus != 0x1) {
						/* Transfer the variable to the Page0 */
						EepromStatus = EE_VerifyPageFullWriteVariable(EEPROM_ADDRESSES[VarIdx], DataVar);
						/* If program operation was failed, a Flash error code is returned */
						if (EepromStatus != FLASH_COMPLETE) {
							return EepromStatus;
						}
					}
				}
			}
			/* Mark Page0 as valid */
			FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE );
			/* If program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
			/* Erase Page1 */
			FlashStatus = FLASH_EraseSector(PAGE1_ID, FLASH_VOLTAGE_RANGE );
			/* If erase operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		} else if (PageStatus1 == ERASED ) /* Page0 receive, Page1 erased */
		{
			/* Erase Page1 */
			FlashStatus = FLASH_EraseSector(PAGE1_ID, FLASH_VOLTAGE_RANGE );
			/* If erase operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
			/* Mark Page0 as valid */
			FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE );
			/* If program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		} else /* Invalid state -> format eeprom */
		{
			/* Erase both Page0 and Page1 and set Page0 as valid page */
			FlashStatus = EE_Format();
			/* If erase/program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		}
		break;

	case VALID_PAGE :
		if (PageStatus1 == VALID_PAGE ) /* Invalid state -> format eeprom */
		{
			/* Erase both Page0 and Page1 and set Page0 as valid page */
			FlashStatus = EE_Format();
			/* If erase/program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		} else if (PageStatus1 == ERASED ) /* Page0 valid, Page1 erased */
		{
			/* Erase Page1 */
			FlashStatus = FLASH_EraseSector(PAGE1_ID, FLASH_VOLTAGE_RANGE );
			/* If erase operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		} else /* Page0 valid, Page1 receive */
		{
			/* Transfer data from Page0 to Page1 */
			for (VarIdx = 0; VarIdx < NUM_EEPROM_ADDRESSES ; VarIdx++) {
				if ((*(__IO uint16_t*) (PAGE1_BASE_ADDRESS + 6)) == EEPROM_ADDRESSES[VarIdx]) {
					x = VarIdx;
				}
				if (VarIdx != x) {
					/* Read the last variables' updates */
					ReadStatus = EE_ReadVariable(EEPROM_ADDRESSES[VarIdx], &DataVar);
					/* In case variable corresponding to the virtual address was found */
					if (ReadStatus != 0x1) {
						/* Transfer the variable to the Page1 */
						EepromStatus = EE_VerifyPageFullWriteVariable(EEPROM_ADDRESSES[VarIdx], DataVar);
						/* If program operation was failed, a Flash error code is returned */
						if (EepromStatus != FLASH_COMPLETE) {
							return EepromStatus;
						}
					}
				}
			}
			/* Mark Page1 as valid */
			FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE );
			/* If program operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
			/* Erase Page0 */
			FlashStatus = FLASH_EraseSector(PAGE0_ID, FLASH_VOLTAGE_RANGE );
			/* If erase operation was failed, a Flash error code is returned */
			if (FlashStatus != FLASH_COMPLETE) {
				return FlashStatus;
			}
		}
		break;

	default: /* Any other state -> format eeprom */
		/* Erase both Page0 and Page1 and set Page0 as valid page */
		FlashStatus = EE_Format();
		/* If erase/program operation was failed, a Flash error code is returned */
		if (FlashStatus != FLASH_COMPLETE) {
			return FlashStatus;
		}
		break;
	}

	/* Lock the Flash Program Erase controller */
	//FLASH_Lock();

	return FLASH_COMPLETE;
}
Beispiel #11
0
/**
  * @brief  Restore the pages to a known good state in case of page's status
  *   corruption after a power loss.
  * @param  None.
  * @retval - Flash error code: on write Flash error
  *         - FLASH_COMPLETE: on success
  */
uint16_t EE_Init(void)
{
  uint16_t pagestatus0 = 6, pagestatus1 = 6;
  uint16_t varidx = 0;
  uint16_t eepromstatus = 0, readstatus = 0;
  int16_t x = -1;
  HAL_StatusTypeDef  flashstatus;
  uint32_t page_error = 0;
  FLASH_EraseInitTypeDef s_eraseinit;


  /* Get Page0 status */
  pagestatus0 = (*(__IO uint16_t*)PAGE0_BASE_ADDRESS);
  /* Get Page1 status */
  pagestatus1 = (*(__IO uint16_t*)PAGE1_BASE_ADDRESS);

  /* Fill EraseInit structure*/
  s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
  s_eraseinit.PageAddress = PAGE0_ID;
  s_eraseinit.NbPages     = 1;
  
  /* Check for invalid header states and repair if necessary */
  switch (pagestatus0)
  {
    case ERASED:
      if (pagestatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
      {
          /* Erase Page0 */
        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
        {
          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
          /* If erase operation was failed, a Flash error code is returned */
          if (flashstatus != HAL_OK)
          {
            return flashstatus;
          }
        }
      }
      else if (pagestatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
      {
        /* Erase Page0 */
        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
        { 
          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
          /* If erase operation was failed, a Flash error code is returned */
          if (flashstatus != HAL_OK)
          {
            return flashstatus;
          }
        }
        /* Mark Page1 as valid */
        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
      }
      else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        flashstatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
      }
      break;

    case RECEIVE_DATA:
      if (pagestatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
      {
        /* Transfer data from Page1 to Page0 */
        for (varidx = 0; varidx < NB_OF_VAR; varidx++)
        {
          if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[varidx])
          {
            x = varidx;
          }
          if (varidx != x)
          {
            /* Read the last variables' updates */
            readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar);
            /* In case variable corresponding to the virtual address was found */
            if (readstatus != 0x1)
            {
              /* Transfer the variable to the Page0 */
              eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar);
              /* If program operation was failed, a Flash error code is returned */
              if (eepromstatus != HAL_OK)
              {
                return eepromstatus;
              }
            }
          }
        }
        /* Mark Page0 as valid */
        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
        s_eraseinit.PageAddress = PAGE1_ID;
        s_eraseinit.NbPages     = 1;
        /* Erase Page1 */
        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
        { 
          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
          /* If erase operation was failed, a Flash error code is returned */
          if (flashstatus != HAL_OK)
          {
            return flashstatus;
          }
        }
      }
      else if (pagestatus1 == ERASED) /* Page0 receive, Page1 erased */
      {
        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
        s_eraseinit.PageAddress = PAGE1_ID;
        s_eraseinit.NbPages     = 1;
        /* Erase Page1 */
        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
        { 
          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
          /* If erase operation was failed, a Flash error code is returned */
          if (flashstatus != HAL_OK)
          {
            return flashstatus;
          }
        }
        /* Mark Page0 as valid */
        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
      }
      else /* Invalid state -> format eeprom */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        flashstatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
      }
      break;

    case VALID_PAGE:
      if (pagestatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        flashstatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
      }
      else if (pagestatus1 == ERASED) /* Page0 valid, Page1 erased */
      {
        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
        s_eraseinit.PageAddress = PAGE1_ID;
        s_eraseinit.NbPages     = 1;
        /* Erase Page1 */
        if(!EE_VerifyPageFullyErased(PAGE1_BASE_ADDRESS))
        { 
          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
          /* If erase operation was failed, a Flash error code is returned */
          if (flashstatus != HAL_OK)
          {
            return flashstatus;
          }
        }
      }
      else /* Page0 valid, Page1 receive */
      {
        /* Transfer data from Page0 to Page1 */
        for (varidx = 0; varidx < NB_OF_VAR; varidx++)
        {
          if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[varidx])
          {
            x = varidx;
          }
          if (varidx != x)
          {
            /* Read the last variables' updates */
            readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar);
            /* In case variable corresponding to the virtual address was found */
            if (readstatus != 0x1)
            {
              /* Transfer the variable to the Page1 */
              eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar);
              /* If program operation was failed, a Flash error code is returned */
              if (eepromstatus != HAL_OK)
              {
                return eepromstatus;
              }
            }
          }
        }
        /* Mark Page1 as valid */
        flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);        
        /* If program operation was failed, a Flash error code is returned */
        if (flashstatus != HAL_OK)
        {
          return flashstatus;
        }
        s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
        s_eraseinit.PageAddress = PAGE0_ID;
        s_eraseinit.NbPages     = 1;
        /* Erase Page0 */
        if(!EE_VerifyPageFullyErased(PAGE0_BASE_ADDRESS))
        { 
          flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);
          /* If erase operation was failed, a Flash error code is returned */
          if (flashstatus != HAL_OK)
          {
            return flashstatus;
          }
        }
      }
      break;

    default:  /* Any other state -> format eeprom */
      /* Erase both Page0 and Page1 and set Page0 as valid page */
      flashstatus = EE_Format();
      /* If erase/program operation was failed, a Flash error code is returned */
      if (flashstatus != HAL_OK)
      {
        return flashstatus;
      }
      break;
  }

  return HAL_OK;
}
Beispiel #12
0
/**
  * @brief  Transfers last updated variables data from the full Page to
  *   an empty one.
  * @param  VirtAddress: 16 bit virtual address of the variable
  * @param  Data: 16 bit data to be written as variable value
  * @retval Success or error status:
  *           - FLASH_COMPLETE: on success
  *           - PAGE_FULL: if valid page is full
  *           - NO_VALID_PAGE: if no valid page was found
  *           - Flash error code: on write Flash error
  */
static uint16_t EE_PageTransfer(uint16_t VirtAddress, uint16_t Data)
{
  HAL_StatusTypeDef flashstatus = HAL_OK;
  uint32_t newpageaddress = EEPROM_START_ADDRESS;
  uint32_t oldpageid = 0;
  uint16_t validpage = PAGE0, varidx = 0;
  uint16_t eepromstatus = 0, readstatus = 0;
  uint32_t page_error = 0;
  FLASH_EraseInitTypeDef s_eraseinit;

  /* Get active Page for read operation */
  validpage = EE_FindValidPage(READ_FROM_VALID_PAGE);

  if (validpage == PAGE1)       /* Page1 valid */
  {
    /* New page address where variable will be moved to */
    newpageaddress = PAGE0_BASE_ADDRESS;

    /* Old page ID where variable will be taken from */
    oldpageid = PAGE1_ID;
  }
  else if (validpage == PAGE0)  /* Page0 valid */
  {
    /* New page address  where variable will be moved to */
    newpageaddress = PAGE1_BASE_ADDRESS;

    /* Old page ID where variable will be taken from */
    oldpageid = PAGE0_ID;
  }
  else
  {
    return NO_VALID_PAGE;       /* No valid Page */
  }

  /* Set the new Page status to RECEIVE_DATA status */
  flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, RECEIVE_DATA);  
  /* If program operation was failed, a Flash error code is returned */
  if (flashstatus != HAL_OK)
  {
    return flashstatus;
  }
  
  /* Write the variable passed as parameter in the new active page */
  eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
  /* If program operation was failed, a Flash error code is returned */
  if (eepromstatus != HAL_OK)
  {
    return eepromstatus;
  }

  /* Transfer process: transfer variables from old to the new active page */
  for (varidx = 0; varidx < NB_OF_VAR; varidx++)
  {
    if (VirtAddVarTab[varidx] != VirtAddress)  /* Check each variable except the one passed as parameter */
    {
      /* Read the other last variable updates */
      readstatus = EE_ReadVariable(VirtAddVarTab[varidx], &DataVar);
      /* In case variable corresponding to the virtual address was found */
      if (readstatus != 0x1)
      {
        /* Transfer the variable to the new active page */
        eepromstatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[varidx], DataVar);
        /* If program operation was failed, a Flash error code is returned */
        if (eepromstatus != HAL_OK)
        {
          return eepromstatus;
        }
      }
    }
  }

  s_eraseinit.TypeErase   = FLASH_TYPEERASE_PAGES;
  s_eraseinit.PageAddress = oldpageid;
  s_eraseinit.NbPages     = 1;
  
  /* Erase the old Page: Set old Page status to ERASED status */
  flashstatus = HAL_FLASHEx_Erase(&s_eraseinit, &page_error);  
  /* If erase operation was failed, a Flash error code is returned */
  if (flashstatus != HAL_OK)
  {
    return flashstatus;
  }

  /* Set new Page status to VALID_PAGE status */
  flashstatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, newpageaddress, VALID_PAGE);   
  /* If program operation was failed, a Flash error code is returned */
  if (flashstatus != HAL_OK)
  {
    return flashstatus;
  }
  
  

  /* Return last operation flash status */
  return flashstatus;
}