示例#1
0
/*******************************************************************************
* Function Name  : FLASH_If_Erase
* Description    : Erase sector
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
uint16_t FLASH_If_Erase(uint32_t Add)
{
  /* Unlock the internal flash */
  FLASH_Unlock();

  FLASH_ClearFlags();

#if defined (STM32F2XX) || defined (STM32F4XX)
  /* Disable sector write protection if it's already protected */
  uint16_t OB_WRP_Sector = FLASH_SectorToWriteProtect(FLASH_INTERNAL, Add);
  FLASH_WriteProtection_Disable(OB_WRP_Sector);

  /* Check which sector has to be erased */
  uint16_t FLASH_Sector = FLASH_SectorToErase(FLASH_INTERNAL, Add);
  FLASH_Status status = FLASH_EraseSector(FLASH_Sector, VoltageRange_3);

#elif defined(STM32F10X_CL)
  /* Call the standard Flash erase function */
  FLASH_ErasePage(Add);
#endif /* STM32F2XX */

  /* Lock the internal flash */
  FLASH_Lock();

  if (status != FLASH_COMPLETE) return MAL_FAIL;

  return MAL_OK;
}
示例#2
0
/**
  * @brief  FLASH_If_Write
  *         Memory write routine.
  * @param  Add: Address to be written to.
  * @param  Len: Number of data to be written (in bytes).
  * @retval MAL_OK if operation is successeful, MAL_FAIL else.
  */
uint16_t FLASH_If_Write(uint32_t Add, uint32_t Len)
{
  uint32_t idx = 0;

  if  (Len & 0x3) /* Not an aligned data */
  {
    for (idx = Len; idx < ((Len & 0xFFFC) + 4); idx++)
    {
      MAL_Buffer[idx] = 0xFF;
    }
  }

  /* Unlock the internal flash */
  FLASH_Unlock();

  FLASH_ClearFlags();

  /* Data received are Word multiple */
  FLASH_Status status = FLASH_COMPLETE;
  for (idx = 0; idx < Len && status == FLASH_COMPLETE; idx = idx + 4)
  {
    status = FLASH_ProgramWord(Add, *(uint32_t *)(MAL_Buffer + idx));
    Add += 4;
  }

  /* Lock the internal flash */
  FLASH_Lock();

  if (status != FLASH_COMPLETE) return MAL_FAIL;

  return MAL_OK;
}
示例#3
0
/**
 * @brief  Writes/updates variable data in EEPROM.
 * @param  EepromAddress: Variable virtual address
 * @param  EepromData: 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
 */
static uint16_t EEPROM_WriteVariable(uint16_t EepromAddress, uint16_t EepromData)
{
    uint16_t Status = 0;

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

    /* Calling this is here is critical on STM32F2 Devices Else Flash Operation Fails */
    FLASH_ClearFlags();

    /* Write the variable virtual address and value in the EEPROM */
    Status = EEPROM_VerifyPageFullWriteVariable(EepromAddress, EepromData);

    /* In case the EEPROM active page is full */
    if (Status == PAGE_FULL)
    {
        /* Perform Page transfer */
        Status = EEPROM_PageTransfer(EepromAddress, EepromData);
    }

    /* Return last operation status */
    return Status;
}
示例#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
 */
static uint16_t EEPROM_Init(void)
{
    uint16_t PageStatus0 = 6, PageStatus1 = 6;
    uint16_t virtualAddress = 0;
    uint16_t EepromStatus = 0, ReadStatus = 0;
    int16_t x = -1;
    uint16_t  FlashStatus;
    uint16_t EepromDataVar = 0;

    /* Calling this is here is critical on STM32F2 Devices Else Flash Operation Fails */
    FLASH_ClearFlags();

    /* 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 */
            {
                /* Normal valid state -> nothing to do */
            }
            else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
            {
                /* Erase Page0 */
                FlashStatus = FLASH_EraseSector(PAGE0_ID, 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 = EEPROM_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 (virtualAddress = 0; virtualAddress < EEPROM_SIZE; virtualAddress++)
                {
                    if (( *(__IO uint16_t*)(PAGE0_BASE_ADDRESS + 6)) == virtualAddress)
                    {
                        x = virtualAddress;
                    }
                    if (virtualAddress != x)
                    {
                        /* Read the last variables' updates */
                        ReadStatus = EEPROM_ReadVariable(virtualAddress, &EepromDataVar);
                        /* In case variable corresponding to the virtual address was found */
                        if (ReadStatus != 0x1)
                        {
                            /* Transfer the variable to the Page0 */
                            EepromStatus = EEPROM_VerifyPageFullWriteVariable(virtualAddress, EepromDataVar);
                            /* 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, 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, 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 = EEPROM_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) /* Harmless invalid state -> pick one page and format the other */
            {
                /* Erase Page0 */
                FlashStatus = FLASH_EraseSector(PAGE0_ID, VOLTAGE_RANGE);
                /* 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 */
            {
                /* Normal valid state -> nothing to do */
            }
            else /* Page0 valid, Page1 receive */
            {
                /* Transfer data from Page0 to Page1 */
                for (virtualAddress = 0; virtualAddress < EEPROM_SIZE; virtualAddress++)
                {
                    if ((*(__IO uint16_t*)(PAGE1_BASE_ADDRESS + 6)) == virtualAddress)
                    {
                        x = virtualAddress;
                    }
                    if (virtualAddress != x)
                    {
                        /* Read the last variables' updates */
                        ReadStatus = EEPROM_ReadVariable(virtualAddress, &EepromDataVar);
                        /* In case variable corresponding to the virtual address was found */
                        if (ReadStatus != 0x1)
                        {
                            /* Transfer the variable to the Page1 */
                            EepromStatus = EEPROM_VerifyPageFullWriteVariable(virtualAddress, EepromDataVar);
                            /* 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, 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 = EEPROM_Format();
            /* If erase/program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
            break;
    }

    return FLASH_COMPLETE;
}
示例#5
0
bool FLASH_EraseMemory(flash_device_t flashDeviceID, uint32_t startAddress, uint32_t length)
{
    uint32_t eraseCounter = 0;
    uint32_t numPages = 0;

    if (FLASH_CheckValidAddressRange(flashDeviceID, startAddress, length) != true)
    {
        return false;
    }

    if (flashDeviceID == FLASH_INTERNAL)
    {
        /* Check which sector has to be erased */
        uint16_t flashSector = FLASH_SectorToErase(FLASH_INTERNAL, startAddress);

        if (flashSector > FLASH_Sector_11)
        {
            return false;
        }

        /* Disable memory write protection if any */
        FLASH_WriteProtectMemory(FLASH_INTERNAL, startAddress, length, false);

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

        /* Define the number of Internal Flash pages to be erased */
        numPages = FLASH_PagesMask(length, INTERNAL_FLASH_PAGE_SIZE);

        /* Clear All pending flags */
        FLASH_ClearFlags();

        /* Erase the Internal Flash pages */
        for (eraseCounter = 0; (eraseCounter < numPages); eraseCounter++)
        {
            FLASH_Status status = FLASH_EraseSector(flashSector + (8 * eraseCounter), VoltageRange_3);

            /* If erase operation fails, return Failure */
            if (status != FLASH_COMPLETE)
            {
                return false;
            }
        }

        /* Locks the FLASH Program Erase Controller */
        FLASH_Lock();

        return true;
    }
    else if (flashDeviceID == FLASH_SERIAL)
    {
#ifdef USE_SERIAL_FLASH
        /* Initialize SPI Flash */
        sFLASH_Init();

        /* Define the number of External Flash pages to be erased */
        numPages = FLASH_PagesMask(length, sFLASH_PAGESIZE);

        /* Erase the SPI Flash pages */
        for (eraseCounter = 0; (eraseCounter < numPages); eraseCounter++)
        {
            sFLASH_EraseSector(startAddress + (sFLASH_PAGESIZE * eraseCounter));
        }

        /* Return Success */
        return true;
#endif
    }

    /* Return Failure */
    return false;
}