예제 #1
0
파일: flash.c 프로젝트: ajithat/lk
static ssize_t stm32_flash_bdev_erase(struct bdev *bdev, off_t offset, size_t len)
{
    LTRACEF("dev %p, offset 0x%llx, len 0x%zx\n", bdev, offset, len);

    ssize_t total_erased = 0;

    HAL_FLASH_Unlock();

    while (len > 0) {
        uint32_t sector = 0;
        off_t sector_offset = 0;
        off_t next_offset = 0;

        if (offset_to_sector(offset, &sector, &sector_offset, &next_offset) < 0)
            return ERR_INVALID_ARGS;

        FLASH_EraseInitTypeDef erase;
        erase.TypeErase = FLASH_TYPEERASE_SECTORS;
        erase.Sector = sector;
        erase.NbSectors = 1;
        erase.VoltageRange = FLASH_VOLTAGE_RANGE_3; // XXX

        LTRACEF("erase params: sector %u, num_sectors %u, next_offset 0x%llx\n", erase.Sector, erase.NbSectors, next_offset);

        if (1) {
            uint32_t sector_error;
            HAL_StatusTypeDef err = HAL_FLASHEx_Erase(&erase, &sector_error);
            if (err != HAL_OK) {
                TRACEF("error starting erase operation, sector error %u\n", sector_error);
                total_erased = ERR_IO;
                break;
            }

            err = FLASH_WaitForLastOperation(HAL_MAX_DELAY);
            if (err != HAL_OK) {
                TRACEF("error waiting for erase operation to end, hal error %u\n", HAL_FLASH_GetError());
                total_erased = ERR_IO;
                break;
            }

            // invalidate the cache on this region
            arch_invalidate_cache_range(FLASHAXI_BASE + sector_offset, next_offset - sector_offset);
        }

        // move to the next erase boundary
        total_erased += next_offset - sector_offset;
        off_t erased_bytes = next_offset - offset;
        if (erased_bytes >= len)
            break;
        len -= erased_bytes;
        offset = next_offset;
    }

    HAL_FLASH_Lock();

    return total_erased;
}
예제 #2
0
/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /* STM32F0xx HAL library initialization:
       - Configure the Flash prefetch
       - Systick timer is configured by default as source of time base, but user 
         can eventually implement his proper time base source (a general purpose 
         timer for example or other time source), keeping in mind that Time base 
         duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and 
         handled in milliseconds basis.
       - Low Level Initialization
     */
  HAL_Init();

  /* Configure the system clock to 48 MHz */
  SystemClock_Config();

  /* Initialize LED1, LED2 and LED3 */
  BSP_LED_Init(LED1);
  BSP_LED_Init(LED2);
  BSP_LED_Init(LED3);
  
  /* Initialize test status */
  MemoryProgramStatus = PASSED;
  
  /* Unlock the Flash to enable the flash control register access *************/ 
  HAL_FLASH_Unlock();

  /* Unlock the Options Bytes *************************************************/
  HAL_FLASH_OB_Unlock();

  /* Get pages write protection status ****************************************/
  HAL_FLASHEx_OBGetConfig(&OptionsBytesStruct);

#ifdef WRITE_PROTECTION_DISABLE
  /* Check if desired pages are already write protected ***********************/
  if((OptionsBytesStruct.WRPPage & FLASH_PAGE_TO_BE_PROTECTED) != FLASH_PAGE_TO_BE_PROTECTED)
  {
    /* Restore write protected pages */
    OptionsBytesStruct.OptionType   = OPTIONBYTE_WRP;
    OptionsBytesStruct.WRPState     = OB_WRPSTATE_DISABLE;
    OptionsBytesStruct.WRPPage = FLASH_PAGE_TO_BE_PROTECTED;
    if(HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK)
    {
      /* Error occurred while options bytes programming. **********************/
      while (1)
      {
        BSP_LED_On(LED3);
      }
    }

    /* Generate System Reset to load the new option byte values ***************/
    HAL_FLASH_OB_Launch();
  }
#elif defined WRITE_PROTECTION_ENABLE
  /* Check if desired pages are not yet write protected ***********************/
  if(((~OptionsBytesStruct.WRPPage) & FLASH_PAGE_TO_BE_PROTECTED )!= FLASH_PAGE_TO_BE_PROTECTED)
  {
    /* Enable the pages write protection **************************************/
    OptionsBytesStruct.OptionType = OPTIONBYTE_WRP;
    OptionsBytesStruct.WRPState   = OB_WRPSTATE_ENABLE;
    OptionsBytesStruct.WRPPage    = FLASH_PAGE_TO_BE_PROTECTED;
    if(HAL_FLASHEx_OBProgram(&OptionsBytesStruct) != HAL_OK)
    {
      /* Error occurred while options bytes programming. **********************/
      while (1)
      {
        BSP_LED_On(LED3);
      }
    }

    /* Generate System Reset to load the new option byte values ***************/
    HAL_FLASH_OB_Launch();
  }
#endif /* WRITE_PROTECTION_DISABLE */

  /* Lock the Options Bytes *************************************************/
  HAL_FLASH_OB_Lock();

#ifdef FLASH_PAGE_PROGRAM  
  /* The selected pages are not write protected *******************************/
  if ((OptionsBytesStruct.WRPPage & FLASH_PAGE_TO_BE_PROTECTED) != 0x00)
  {
    /* Fill EraseInit structure************************************************/
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;
    EraseInitStruct.NbPages     = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR)/FLASH_PAGE_SIZE;

    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
    {
      /* 
        Error occurred while page erase. 
        User can add here some code to deal with this error. 
        PageError will contain the faulty page and then to know the code error on this page,
        user can call function 'HAL_FLASH_GetError()'
      */
      while (1)
      {
        BSP_LED_On(LED3);
      }
    }

    /* FLASH Word program of DATA_32 at addresses defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR */
    Address = FLASH_USER_START_ADDR;
    while (Address < FLASH_USER_END_ADDR)
    {
      if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) == HAL_OK)
      {
        Address = Address + 4;
      }
      else
      {
        /* Error occurred while writing data in Flash memory. 
           User can add here some code to deal with this error */
        while (1)
        {
          BSP_LED_On(LED3);
        }
      }
    }

    /* Check the correctness of written data */
    Address = FLASH_USER_START_ADDR;

    while (Address < FLASH_USER_END_ADDR)
    {
      if((*(__IO uint32_t*) Address) != DATA_32)
      {
        MemoryProgramStatus = FAILED;
      }
      Address += 4;
    }
  }
  else
  { 
    /* The desired pages are write protected */ 
    /* Check that it is not allowed to write in this page */
    Address = FLASH_USER_START_ADDR;
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Address, DATA_32) != HAL_OK)
    {
      /* Error returned during programmation. */
      /* Check that WRPERR flag is well set */
      if (HAL_FLASH_GetError() == HAL_FLASH_ERROR_WRP) 
      {
        MemoryProgramStatus = FAILED;
      }
      else
      {
        /* Another error occurred.
           User can add here some code to deal with this error */
        while (1)
        {
          BSP_LED_On(LED3);
        }
      }
    }
    else
    {
      /* Write operation is successful. Should not occur
         User can add here some code to deal with this error */
      while (1)
      {
        BSP_LED_On(LED3);
      }
    }
  }
#endif /* FLASH_PAGE_PROGRAM */

  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();

  /*Check if there is an issue to program data*/
  if (MemoryProgramStatus == PASSED)
  {
    /* No error detected. Switch on LED1*/
    BSP_LED_On(LED1);
  }
  else
  {
    /* Error detected. Switch on LED2*/
    BSP_LED_On(LED2);
  }

  /* Infinite loop */
  while (1)
  {
  }
}
예제 #3
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
  */
uint32_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 OperationStatus;

  /* 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 */
        FLASH_Erase_Sector(PAGE0_ID,VOLTAGE_RANGE);

        OperationStatus = FLASH_WaitForLastOperation(1000);
        if(OperationStatus == HAL_ERROR)
        {
        	return HAL_FLASH_GetError();
        }
      }
      else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
      {
        /* Erase Page0 */
        FLASH_Erase_Sector(PAGE0_ID,VOLTAGE_RANGE);
        /* If erase operation was failed, a Flash error code is returned */
        OperationStatus = FLASH_WaitForLastOperation(1000);
        if(OperationStatus == HAL_ERROR)
        {
        	return HAL_FLASH_GetError();
        }
        /* Mark Page1 as valid */
        OperationStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,PAGE1_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if(OperationStatus == HAL_ERROR)
		{
			return HAL_FLASH_GetError();
		}
      }
      else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
    	  OperationStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (OperationStatus == HAL_ERROR)
        {
        	return HAL_FLASH_GetError();
        }
      }
      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 HAL_FLASH_GetError();
              }
            }
          }
        }
        /* Mark Page0 as valid */
        OperationStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (OperationStatus != HAL_OK)
        {
          return HAL_FLASH_GetError();;
        }
        /* Erase Page1 */
        FLASH_Erase_Sector(PAGE1_ID, VOLTAGE_RANGE);
        /* If erase operation was failed, a Flash error code is returned */
        OperationStatus = FLASH_WaitForLastOperation(1000);
        if(OperationStatus == HAL_ERROR)
        {
        	return HAL_FLASH_GetError();
        }
      }
      else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
      {
        /* Erase Page1 */
		FLASH_Erase_Sector(PAGE1_ID, VOLTAGE_RANGE);
		/* If erase operation was failed, a Flash error code is returned */
		OperationStatus = FLASH_WaitForLastOperation(1000);
		if(OperationStatus == HAL_ERROR)
		{
			return HAL_FLASH_GetError();
		}
        /* Mark Page0 as valid */
		OperationStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE0_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
        if (OperationStatus != HAL_OK)
        {
          return HAL_FLASH_GetError();
        }
      }
      else /* Invalid state -> format eeprom */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
    	OperationStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (OperationStatus != HAL_OK)
        {
        	return HAL_FLASH_GetError();
        }
      }
      break;

    case VALID_PAGE:
      if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
      {
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        OperationStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (OperationStatus != HAL_OK)
        {
        	return HAL_FLASH_GetError();
        }
      }
      else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
      {
        /* Erase Page1 */
        FLASH_Erase_Sector(PAGE1_ID, VOLTAGE_RANGE);
        /* If erase operation was failed, a Flash error code is returned */
		OperationStatus = FLASH_WaitForLastOperation(1000);
		if(OperationStatus == HAL_ERROR)
		{
			return HAL_FLASH_GetError();
		}
      }
      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 HAL_FLASH_GetError();
              }
            }
          }
        }
        /* Mark Page1 as valid */
        OperationStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, PAGE1_BASE_ADDRESS, VALID_PAGE);
        /* If program operation was failed, a Flash error code is returned */
		if(OperationStatus == HAL_ERROR)
		{
			return HAL_FLASH_GetError();
		}
        /* Erase Page0 */
        FLASH_Erase_Sector(PAGE0_ID, VOLTAGE_RANGE);
        /* If erase operation was failed, a Flash error code is returned */
		OperationStatus = FLASH_WaitForLastOperation(1000);
		if(OperationStatus == HAL_ERROR)
		{
			return HAL_FLASH_GetError();
		}
      }
      break;

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

  return HAL_OK;
}