示例#1
0
/**
  * @brief   Program byte, halfword, word or double word at a specified address  with interrupt enabled.
  * @param  TypeProgram  Indicate the way to program at a specified address.
  *                           This parameter can be a value of @ref FLASH_Type_Program
  * @param  Address  specifies the address to be programmed.
  * @param  Data specifies the data to be programmed
  *
  * @retval HAL Status
  */
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));

  /* Enable End of FLASH Operation interrupt */
  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);

  /* Enable Error source interrupt */
  __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);

  /* Clear pending flags (if any) */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
                         FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_ERSERR);

  pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAM;
  pFlash.Address = Address;

  switch(TypeProgram)
  {
    case FLASH_TYPEPROGRAM_BYTE :
    {
      /*Program byte (8-bit) at a specified address.*/
      FLASH_Program_Byte(Address, (uint8_t) Data);
      break;
    }

    case FLASH_TYPEPROGRAM_HALFWORD :
    {
      /*Program halfword (16-bit) at a specified address.*/
      FLASH_Program_HalfWord(Address, (uint16_t) Data);
      break;
    }

    case FLASH_TYPEPROGRAM_WORD :
    {
      /*Program word (32-bit) at a specified address.*/
      FLASH_Program_Word(Address, (uint32_t) Data);
      break;
    }

    case FLASH_TYPEPROGRAM_DOUBLEWORD :
    {
      /*Program double word (64-bit) at a specified address.*/
      FLASH_Program_DoubleWord(Address, Data);
      break;
    }
    default :
      break;
  }
  return status;
}
示例#2
0
/**
  * @brief  Unlocks Flash for write access
  * @param  None
  * @retval None
  */
void FLASH_If_Init(void)
{
  /* Unlock the Program memory */
  HAL_FLASH_Unlock();

  /* Clear all FLASH flags */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  /* Unlock the Program memory */
  HAL_FLASH_Lock();
}
示例#3
0
/**
  * @brief  Set the specific FLASH error flag.
  * @retval None
  */
static void FLASH_SetErrorCode(void)
{ 
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)
  {
   pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
   
   /* Clear FLASH write protection error pending bit */
   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR);
  }
  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET)
  {
   pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
   
   /* Clear FLASH Programming alignment error pending bit */
   __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGAERR);
  }
  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET)
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP;
    
    /* Clear FLASH Programming parallelism error pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGPERR);
  }
  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR) != RESET)
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGS;
    
    /* Clear FLASH Programming sequence error pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_PGSERR);
  }
    
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET)
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION;
    
    /* Clear FLASH Operation error pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR);
  }
}
示例#4
0
/** Fixit functions for bloated STM32 Cube FW
 * =================================================
 */
HAL_StatusTypeDef sub_WaitForLastOperation(ot_long Timeout) {
// Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
// Even if the FLASH operation fails, the BUSY flag will be reset and an error
// flag will be set
    uint16_t tickstart = systim_get_clocker();
    uint32_t flash_sr_errors;
    
    while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET) { 
        Timeout -= (systim_get_clocker() - tickstart);
        if (Timeout <= 0) {
            return HAL_TIMEOUT;
        }
    }

    // Check FLASH End of Operation flag, clear if set
    if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP)) {
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
    }
    
    // Look for errors, and if necessary save the error code to ProcFlash
    // WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
    //           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
    //           as expected. If the user run an application using the first
    //           cut of the STM32L031xx device or the first cut of the STM32L041xx
    //           device, this error should be ignored. The revId of the device
    //           can be retrieved via the HAL_GetREVID() function.
    flash_sr_errors = FLASH->SR & \
                     (FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR \
                    | FLASH_FLAG_OPTVERR | FLASH_FLAG_RDERR | FLASH_FLAG_FWWERR \
                    | FLASH_FLAG_NOTZEROERR);
    if (flash_sr_errors) {
        ProcFlash.ErrorCode = flash_sr_errors;
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR |
                                 FLASH_FLAG_OPTVERR | FLASH_FLAG_RDERR | FLASH_FLAG_FWWERR | 
                                 FLASH_FLAG_NOTZEROERR);
        return HAL_ERROR;
    }

    // There is no error flag set 
    return HAL_OK;  
}
示例#5
0
void flash_erase(uint32_t flash_dest, const uint32_t *src, uint32_t num_word32) {
    // check there is something to write
    if (num_word32 == 0) {
        return;
    }

    // unlock
    HAL_FLASH_Unlock();

    FLASH_EraseInitTypeDef EraseInitStruct;

    #if defined(MCU_SERIES_L4)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);

    // erase the sector(s)
    // The sector returned by flash_get_sector_info can not be used
    // as the flash has on each bank 0/1 pages 0..255
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Banks       = get_bank(flash_dest);
    EraseInitStruct.Page        = get_page(flash_dest);
    EraseInitStruct.NbPages     = get_page(flash_dest + 4 * num_word32 - 1) - EraseInitStruct.Page + 1;;
    #else
    // Clear pending flags (if any)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                           FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

    // erase the sector(s)
    EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
    EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
    EraseInitStruct.Sector = flash_get_sector_info(flash_dest, NULL, NULL);
    EraseInitStruct.NbSectors = flash_get_sector_info(flash_dest + 4 * num_word32 - 1, NULL, NULL) - EraseInitStruct.Sector + 1;
    #endif

    uint32_t SectorError = 0;
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
        // error occurred during sector erase
        HAL_FLASH_Lock(); // lock the flash
        return;
    }
}
示例#6
0
/**
  * @brief  Set the specific FLASH error flag.
  * @retval None
  */
static void FLASH_SetErrorCode(void)
{
  uint32_t flags = 0;
  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
    flags |= FLASH_FLAG_WRPERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
    flags |= FLASH_FLAG_PGAERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR))
  { 
    pFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE;
    flags |= FLASH_FLAG_SIZERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
  {
    /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
     *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
     *           as expected. If the user run an application using the first
     *           cut of the STM32L031xx device or the first cut of the STM32L041xx
     *           device, this error should be ignored. The revId of the device
     *           can be retrieved via the HAL_GetREVID() function.
     *
     */
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
    flags |= FLASH_FLAG_OPTVERR;
  }

  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
    flags |= FLASH_FLAG_RDERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR))
  { 
    pFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR;
    flags |= HAL_FLASH_ERROR_FWWERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR))
  { 
    pFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO;
    flags |= FLASH_FLAG_NOTZEROERR;
  }

  /* Clear FLASH error pending bits */
  __HAL_FLASH_CLEAR_FLAG(flags);
}  
示例#7
0
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
  uint16_t eeprom_address = (unsigned) pos;

  eeprom_init();

  HAL_FLASH_Unlock();
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

  if (EE_WriteVariable(eeprom_address, (uint16_t) value) != EE_OK)
      for (;;) HAL_Delay(1); // Spin forever until watchdog reset

  HAL_FLASH_Lock();
}
示例#8
0
/**
  * @brief  Wait for a FLASH operation to complete.
  * @param  Timeout  maximum flash operation timeout
  * @retval HAL Status
  */
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
     flag will be set */
     
  uint32_t tickstart = HAL_GetTick();
     
  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) 
  { 
    if (Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
      {
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Check FLASH End of Operation flag  */
  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  }
  
  if( __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)     || 
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR)     || 
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)     || 
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)    || 
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR)      || 
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR)     || 
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR) )
  {
    /*Save the error code*/

    /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
     *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
     *           as expected. If the user run an application using the first
     *           cut of the STM32L031xx device or the first cut of the STM32L041xx
     *           device, this error should be ignored. The revId of the device
     *           can be retrieved via the HAL_GetREVID() function.
     *
     */
    FLASH_SetErrorCode();
    return HAL_ERROR;
  }

  /* There is no error flag set */
  return HAL_OK;
}
示例#9
0
void eeprom_init() {
  if (!eeprom_initialized) {
    HAL_FLASH_Unlock();

    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);

    /* EEPROM Init */
    if (EE_Initialize() != EE_OK)
      for (;;) HAL_Delay(1); // Spin forever until watchdog reset

    HAL_FLASH_Lock();
    eeprom_initialized = true;
  }
}
示例#10
0
文件: flash.c 项目: openmv/openmv
void flash_erase(uint32_t sector)
{
    // unlock
    HAL_FLASH_Unlock();

    #if defined(MCU_SERIES_H7)
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
    #else
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                           FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
    #endif

    // erase the sector(s)
    FLASH_EraseInitTypeDef EraseInitStruct;
    EraseInitStruct.TypeErase    = TYPEERASE_SECTORS;
    EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V
    #if defined(MCU_SERIES_H7)
    EraseInitStruct.Sector = (sector % 8);
    if (sector < 8) {
        EraseInitStruct.Banks = FLASH_BANK_1;
    } else {
        EraseInitStruct.Banks = FLASH_BANK_2;
    }
    #else
    EraseInitStruct.Sector = sector;
    #endif
    EraseInitStruct.NbSectors = 1;

    uint32_t SectorError = 0;
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK) {
        // error occurred during sector erase
        HAL_FLASH_Lock(); // lock the flash
        __fatal_error();
    }

    HAL_FLASH_Lock(); // lock the flash
}
示例#11
0
/**
  * @brief  Set the specific FLASH error flag.
  * @retval None
  */
static void FLASH_SetErrorCode(void)
{ 
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
  {
     pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
  }

  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
  {
     pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
     __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
  }

#if defined(FLASH_SR_RDERR)
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_RDERR);  
  }
#endif /* FLASH_SR_RDERR */

#if defined(FLASH_SR_OPTVERRUSR)
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTVUSR;
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERRUSR);  
  }
#endif /* FLASH_SR_OPTVERRUSR */

  /* Clear FLASH error pending bits */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR);
}  
示例#12
0
/**
  * @brief  Wait for a FLASH operation to complete.
  * @param  Timeout maximum flash operationtimeout
  * @retval HAL Status
  */
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
  uint32_t tickstart = 0U;

  /* Clear Error Code */
  pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;

  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
     flag will be set */
  /* Get tick */
  tickstart = HAL_GetTick();

  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != RESET)
  {
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        return HAL_TIMEOUT;
      }
    }
  }

  /* Check FLASH End of Operation flag  */
  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  }
#if defined(FLASH_SR_RDERR)
  if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
                           FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
#else
  if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
                           FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR)) != RESET)
#endif /* FLASH_SR_RDERR */
  {
    /*Save the error code*/
    FLASH_SetErrorCode();
    return HAL_ERROR;
  }

  /* If there is no error flag set */
  return HAL_OK;

}
/**
  * @brief  Wait for a FLASH operation to complete.
  * @param  Timeout: maximum flash operation timeout
  * @retval HAL_StatusTypeDef HAL Status
  */
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
     flag will be set */
    
  uint32_t timeout = HAL_GetTick() + Timeout;
     
  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) 
  { 
    if(Timeout != HAL_MAX_DELAY)
    {
      if(HAL_GetTick() >= timeout)
      {
        return HAL_TIMEOUT;
      }
    } 
  }
  
  if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR))  || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || 
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))  || 
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))  ||
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_MISERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_FASTERR)) || 
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))  || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) ||
#if defined (STM32L431xx) || defined (STM32L432xx) || defined (STM32L433xx) || defined (STM32L442xx) || defined (STM32L443xx)
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD))   || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PEMPTY)))
#else
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)))
#endif
  {
    /*Save the error code*/
    FLASH_SetErrorCode();
    
    return HAL_ERROR;
  }

  /* Check FLASH End of Operation flag  */
  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  }
  
  /* If there is an error flag set */
  return HAL_OK;  
}
/**
  * @brief  Set the specific FLASH error flag.
  * @retval HAL Status
  */
static __RAM_FUNC FLASHRAM_SetErrorCode(void)
{  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
  { 
    ProcFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
  { 
    ProcFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR))
  { 
    ProcFlash.ErrorCode |= HAL_FLASH_ERROR_SIZE;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
  { 
    /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
     *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
     *           as expected. If the user run an application using the first
     *           cut of the STM32L031xx device or the first cut of the STM32L041xx
     *           device, this error should be ignored. The revId of the device
     *           can be retrieved via the HAL_GetREVID() function.
     *
     */
    ProcFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
  { 
    ProcFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_FWWERR))
  { 
   ProcFlash.ErrorCode |= HAL_FLASH_ERROR_FWWERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_NOTZEROERR))
  { 
   ProcFlash.ErrorCode |= HAL_FLASH_ERROR_NOTZERO;
  }
  
  /* Errors are now stored, clear errors flags */

  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR |
                         FLASH_FLAG_OPTVERR | FLASH_FLAG_RDERR | FLASH_FLAG_FWWERR | 
                         FLASH_FLAG_NOTZEROERR);
  return HAL_OK;
} 
示例#15
0
/**
  * @brief  Perform a mass erase or erase the specified FLASH memory sectors  with interrupt enabled
  * @param  pEraseInit: pointer to an FLASH_EraseInitTypeDef structure that
  *         contains the configuration information for the erasing.
  * 
  * @retval HAL Status
  */
HAL_StatusTypeDef HAL_FLASHEx_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Process Locked */
  __HAL_LOCK(&pFlash);

  /* Check the parameters */
  assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));

  /* Enable End of FLASH Operation interrupt */
  __HAL_FLASH_ENABLE_IT(FLASH_IT_EOP);
  
  /* Enable Error source interrupt */
  __HAL_FLASH_ENABLE_IT(FLASH_IT_ERR);
  
  /* Clear pending flags (if any) */  
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP    | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |\
                         FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR);  
  
  if(pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
  {
    /*Mass erase to be done*/
    pFlash.ProcedureOnGoing = FLASH_PROC_MASSERASE;
    pFlash.Bank = pEraseInit->Banks;
    FLASH_MassErase((uint8_t) pEraseInit->VoltageRange, pEraseInit->Banks);
  }
  else
  {
    /* Erase by sector to be done*/

    /* Check the parameters */
    assert_param(IS_FLASH_NBSECTORS(pEraseInit->NbSectors + pEraseInit->Sector));

    pFlash.ProcedureOnGoing = FLASH_PROC_SECTERASE;
    pFlash.NbSectorsToErase = pEraseInit->NbSectors;
    pFlash.Sector = pEraseInit->Sector;
    pFlash.VoltageForErase = (uint8_t)pEraseInit->VoltageRange;

    /*Erase 1st sector and wait for IT*/
    FLASH_Erase_Sector(pEraseInit->Sector, pEraseInit->VoltageRange);
  }

  return status;
}
示例#16
0
/**
  * @brief  Wait for a FLASH operation to complete.
  * @param  Timeout  maximum flash operation timeout
  * @retval HAL Status
  */
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
{
  /* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
     Even if the FLASH operation fails, the BUSY flag will be reset and an error
     flag will be set */
     
  uint32_t tickstart = HAL_GetTick();
     
  while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) 
  { 
    if (Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
      {
        return HAL_TIMEOUT;
      }
    }
  }
  
  /* Check FLASH End of Operation flag  */
  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
  }
  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)  || 
     __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) || 
#if defined(FLASH_SR_RDERR)
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) || 
#endif /* FLASH_SR_RDERR */
#if defined(FLASH_SR_OPTVERRUSR)
      __HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR) || 
#endif /* FLASH_SR_OPTVERRUSR */
     __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
  {
    /*Save the error code*/
    FLASH_SetErrorCode();
    return HAL_ERROR;
  }

  /* There is no error flag set */
  return HAL_OK;
}
示例#17
0
int flash_erase(uint32_t start_addr, uint32_t size)
{
  FLASH_EraseInitTypeDef EraseInitStruct;
  uint32_t FirstPage = 0, NbOfPages = 0, BankNumber = 0, PAGEError = 0;
  uint32_t end_addr = start_addr + size;

  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();

  /* Erase the user Flash area */

  /* Clear OPTVERR bit set on virgin samples */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
  /* Get the 1st page to erase */
  FirstPage = GetPage(start_addr);
  /* Get the number of pages to erase from 1st page */
  NbOfPages = GetPage(end_addr) - FirstPage + 1;
  /* Get the bank */
  BankNumber = GetBank(start_addr);
  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Banks       = BankNumber;
  EraseInitStruct.Page        = FirstPage;
  EraseInitStruct.NbPages     = NbOfPages;

  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
     you have to make sure that these data are rewritten before they are accessed during code
     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
     DCRST and ICRST bits in the FLASH_CR register. */
  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()'
    */
    /* Infinite loop */
    while (1) {
    }
  }
  return 0;
}
示例#18
0
/** Erase one sector starting at defined address
 *
 * The address should be at sector boundary. This function does not do any check for address alignments
 * @param obj The flash object
 * @param address The sector starting address
 * @return 0 for success, -1 for error
 */
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
{
    uint32_t FirstPage = 0, BankNumber = 0;
    uint32_t PAGEError = 0;
    FLASH_EraseInitTypeDef EraseInitStruct;
    int32_t status = 0;

    if ((address >= (FLASH_BASE + FLASH_SIZE)) || (address < FLASH_BASE)) {

        return -1;
    }

    if (flash_unlock() != HAL_OK) {
        return -1;
    }

      /* Clear OPTVERR bit set on virgin samples */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
    /* Get the 1st page to erase */
    FirstPage = GetPage(address);
    /* MBED HAL erases 1 page  / sector at a time */
    /* Get the bank */
    BankNumber = GetBank(address);
    /* Fill EraseInit structure*/
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.Banks       = BankNumber;
    EraseInitStruct.Page        = FirstPage;
    EraseInitStruct.NbPages     = 1;

    /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
     you have to make sure that these data are rewritten before they are accessed during code
     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
     DCRST and ICRST bits in the FLASH_CR register. */

    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
        status = -1;
    }

    flash_lock();

    return status;
}
示例#19
0
/**
  * @brief  Set the specific FLASH error flag.
  * @retval None
  */
static void FLASH_SetErrorCode(void)
{
  uint32_t flags = 0U;
  
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
    flags |= FLASH_FLAG_WRPERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
    flags |= FLASH_FLAG_PGAERR;
  }
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
    flags |= FLASH_FLAG_OPTVERR;
  }

#if defined(FLASH_SR_RDERR)
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
    flags |= FLASH_FLAG_RDERR;
  }
#endif /* FLASH_SR_RDERR */
#if defined(FLASH_SR_OPTVERRUSR)
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERRUSR))
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTVUSR;
    flags |= FLASH_FLAG_OPTVERRUSR;
  }
#endif /* FLASH_SR_OPTVERRUSR */

  /* Clear FLASH error pending bits */
  __HAL_FLASH_CLEAR_FLAG(flags);
}  
示例#20
0
/**
  * @brief  Set the specific FLASH error flag.
  * @retval None
  */
static void FLASH_SetErrorCode(void)
{
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR) != RESET)
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_OPERATION;
  }

  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) != RESET)
  {
   pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
  }

  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR) != RESET)
  {
   pFlash.ErrorCode |= HAL_FLASH_ERROR_PGA;
  }

  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGPERR) != RESET)
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_PGP;
  }

  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_ERSERR) != RESET)
  {
    pFlash.ErrorCode |= HAL_FLASH_ERROR_ERS;
  }

#if defined (FLASH_OPTCR2_PCROP)
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR) != RESET)
  {
   pFlash.ErrorCode |= HAL_FLASH_ERROR_RD;
  }
#endif /* FLASH_OPTCR2_PCROP */

  /* Clear error programming flags */
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
}
示例#21
0
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
{
    uint32_t PAGEError = 0;
    FLASH_EraseInitTypeDef EraseInitStruct;
    int32_t status = 0;

    if (!(IS_FLASH_PROGRAM_ADDRESS(address))) {
        return -1;
    }

    if (flash_unlock() != HAL_OK) {
        return -1;
    }

    // Clear Flash status register's flags
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_OPTVERR);

    /* MBED HAL erases 1 sector at a time */
    /* Fill EraseInit structure*/
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = address;
    EraseInitStruct.NbPages     = 1;

    /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
     you have to make sure that these data are rewritten before they are accessed during code
     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
     DCRST and ICRST bits in the FLASH_CR register. */

    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
        status = -1;
    }

    flash_lock();

    return status;
}
示例#22
0
static int
stm32f4_flash_write(uint32_t address, const void *src, uint32_t num_bytes)
{
    const uint8_t *sptr;
    uint32_t i;
    int rc;

    sptr = src;
    /*
     * Clear status of previous operation.
     */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | \
      FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR| FLASH_FLAG_PGSERR);
    for (i = 0; i < num_bytes; i++) {
        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, address, sptr[i]);
        if (rc != 0) {
            return rc;
        }

        address++;
    }

    return 0;
}
示例#23
0
文件: flash.c 项目: StefanJia/test2
HAL_StatusTypeDef FlashInit(void)
{
  HAL_StatusTypeDef res;
  
  /* Unlock the Flash to enable the flash control register access *************/ 
  res = HAL_FLASH_Unlock();
  
  /* Clear pending flags (if any) */  
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 
                         FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); 
  
  /* Get the number of the start and end sectors */
  StartSector = GetSector(FLASH_USER_START_ADDR);
  EndSector = GetSector(FLASH_USER_END_ADDR);
  
  /* Lock the Flash to disable the flash control register access (recommended
  to protect the FLASH memory against possible unwanted operation) *********/
  if(res == 0)
    printf("flash success!\r\n");
  else
    printf("flash error:%d\r\n",res);
  
  return res;
}
示例#24
0
/**
  * @brief This function handles FLASH interrupt request.
  * @retval None
  */
void HAL_FLASH_IRQHandler(void)
{
  uint32_t addresstmp;
  /* If the operation is completed, disable the PG, PER and MER Bits */
  CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));

  /* Check FLASH End of Operation flag  */
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
    
    if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
    {
      /* Nb of pages to erased can be decreased */
      pFlash.DataRemaining--;

      /* Indicate user which page address has been erased*/
      HAL_FLASH_EndOfOperationCallback(pFlash.Address);

      /* Check if there are still pages to erase*/
      if(pFlash.DataRemaining != 0)
      {
        /* Increment page address to next page */
        pFlash.Address += FLASH_PAGE_SIZE;
        addresstmp = pFlash.Address;
        FLASH_PageErase(addresstmp);
      }
      else
      {
        /*No more pages to Erase*/

        /*Reset Address and stop Erase pages procedure*/
        pFlash.Address = 0xFFFFFFFF;
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
      }
    }
    else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
    {
      /*MassErase ended. Return the selected bank*/
      /* FLASH EOP interrupt user callback */
      HAL_FLASH_EndOfOperationCallback(0);

      /* Stop Mass Erase procedure*/
      pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
    }
    else
    {
      /* Nb of 16-bit data to program can be decreased */
      pFlash.DataRemaining--;
      
      /* Check if there are still 16-bit data to program */
      if(pFlash.DataRemaining != 0)
      {
        /* Increment address to 16-bit */
        pFlash.Address += 2;
        addresstmp = pFlash.Address;

        /* Shift to have next 16-bit data */
        pFlash.Data = (pFlash.Data >> 16);

        /*Program halfword (16-bit) at a specified address.*/
        FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
      }
      else
      {
        /*Program ended. Return the selected address*/
        /* FLASH EOP interrupt user callback */
        if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
        {
          HAL_FLASH_EndOfOperationCallback(pFlash.Address);
        }
        else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
        {
          HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
        }
        else 
        {
          HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
        }

        /* Reset Address and stop Program procedure*/
        pFlash.Address = 0xFFFFFFFF;
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
      }
    }
示例#25
0
/**
  * @brief Handle FLASH interrupt request.
  * @retval None
  */
void HAL_FLASH_IRQHandler(void)
{
  uint32_t tmp_page;

  /* If the operation is completed, disable the PG, PNB, MER1, MER2 and PER Bit */
  CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_MER2 | FLASH_CR_PER | FLASH_CR_PNB));
  
  /* Disable the FSTPG Bit only if it is the last row programmed */
  if(pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST)
  {
    CLEAR_BIT(FLASH->CR, FLASH_CR_FSTPG);
  }

  /* Check FLASH operation error flags */
  if((__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPERR))  || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PROGERR)) || 
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGAERR))  || 
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_SIZERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGSERR))  ||
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_MISERR)) || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_FASTERR)) || 
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_RDERR))  || (__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR)) ||
     (__HAL_FLASH_GET_FLAG(FLASH_FLAG_ECCD)))
  {
    /*Save the error code*/
    FLASH_SetErrorCode();
    
    /* FLASH error interrupt user callback */
    if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE)
    {
       HAL_FLASH_EndOfOperationCallback(pFlash.Page);
    }
    else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASS_ERASE)
    {
        HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
    }
    else if((pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) || 
            (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST))
    {
       HAL_FLASH_OperationErrorCallback(pFlash.Address);
    }

    HAL_FLASH_OperationErrorCallback(pFlash.Address);

    /*Stop the procedure ongoing*/
    pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
  }

  /* Check FLASH End of Operation flag  */
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);

    if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGE_ERASE)
    {
      /* Nb of pages to erased can be decreased */
      pFlash.NbPagesToErase--;

      /* Check if there are still pages to erase*/
      if(pFlash.NbPagesToErase != 0)
      {
        /* Indicate user which page has been erased*/
        HAL_FLASH_EndOfOperationCallback(pFlash.Page);

        /* Increment page number */
        pFlash.Page++;
        tmp_page = pFlash.Page;
        FLASH_PageErase(tmp_page, pFlash.Bank);
      }
      else
      {
        /* No more pages to Erase */
        /* Reset Address and stop Erase pages procedure */
        pFlash.Page = 0xFFFFFFFF;
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;

        /* Flush the caches to be sure of the data consistency */
        FLASH_FlushCaches() ;
        
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Page);
      }
    }
    else
    {
      if(pFlash.ProcedureOnGoing == FLASH_PROC_MASS_ERASE)
      {
        /* MassErase ended. Return the selected bank */
        /* Flush the caches to be sure of the data consistency */
        FLASH_FlushCaches() ;

        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
      }
      else if((pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM) || 
              (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAM_LAST))
      {
        /* Program ended. Return the selected address */
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Address);
      }

      /*Clear the procedure ongoing*/
      pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
    }
  }

  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
  {
    /* Disable End of Operation and Error interrupts */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);

    /* Process Unlocked */
    __HAL_UNLOCK(&pFlash);
  }
}
示例#26
0
/**
  * @brief This function handles FLASH interrupt request.
  * @retval None
  */
void HAL_FLASH_IRQHandler(void)
{
  uint32_t temp;

  /* Check FLASH operation error flags */

  /* WARNING : On the first cut of STM32L031xx and STM32L041xx devices,
   *           (RefID = 0x1000) the FLASH_FLAG_OPTVERR bit was not behaving
   *           as expected. If the user run an application using the first
   *           cut of the STM32L031xx device or the first cut of the STM32L041xx
   *           device, the check on the FLASH_FLAG_OPTVERR bit should be ignored.
   *
   *           Note :The revId of the device can be retrieved via the HAL_GetREVID()
   *           function.
   *
   */

  if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_SIZERR | FLASH_FLAG_OPTVERR | \
                           FLASH_FLAG_RDERR  | FLASH_FLAG_FWWERR | FLASH_FLAG_NOTZEROERR) != RESET)
  {
    if(ProcFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
    {
      /* Return the faulty sector */
      temp = ProcFlash.Page;
      ProcFlash.Page = 0xFFFFFFFFU;
    }
    else
    {
      /* Return the faulty address */
      temp = ProcFlash.Address;
    }
    
    /* Save the Error code */
    FLASH_SetErrorCode();

    /* FLASH error interrupt user callback */
    HAL_FLASH_OperationErrorCallback(temp);

    /* Stop the procedure ongoing */
    ProcFlash.ProcedureOnGoing = FLASH_PROC_NONE;
  }
  
  /* Check FLASH End of Operation flag */
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);

    /* Process can continue only if no error detected */
    if(ProcFlash.ProcedureOnGoing != FLASH_PROC_NONE)
    {
      if(ProcFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
      {
        /* Nb of sector to erased can be decreased */
        ProcFlash.NbPagesToErase--;
  
        /* Check if there are still sectors to erase */
        if(ProcFlash.NbPagesToErase != 0U)
        {
          temp = ProcFlash.Page;
          /* Indicate user which sector has been erased */
          HAL_FLASH_EndOfOperationCallback(temp);
  
          /* Increment sector number */
          temp = ProcFlash.Page + FLASH_PAGE_SIZE;
          ProcFlash.Page = ProcFlash.Page + FLASH_PAGE_SIZE;
          
          /* If the erase operation is completed, disable the ERASE Bit */
          CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE);
  
          FLASH_ErasePage(temp);
        }
        else
        {
          /* No more sectors to Erase, user callback can be called */
          /* Reset Sector and stop Erase sectors procedure */
          ProcFlash.Page = temp = 0xFFFFFFFFU;
          ProcFlash.ProcedureOnGoing = FLASH_PROC_NONE;
          /* FLASH EOP interrupt user callback */
          HAL_FLASH_EndOfOperationCallback(temp);
        }
      }
      else 
      {
        if(ProcFlash.ProcedureOnGoing  == FLASH_PROC_PROGRAM)
        {
          /* If the program operation is completed, disable the PROG Bit */
          CLEAR_BIT(FLASH->PECR, FLASH_PECR_PROG);
          /* Program ended. Return the selected address */
          /* FLASH EOP interrupt user callback */
          HAL_FLASH_EndOfOperationCallback(ProcFlash.Address);
        }
        ProcFlash.ProcedureOnGoing = FLASH_PROC_NONE;
      }
    }
  }

  if(ProcFlash.ProcedureOnGoing == FLASH_PROC_NONE)
  {
    /* Operation is completed, disable the PG and PER Bits */
    CLEAR_BIT(FLASH->PECR, FLASH_PECR_ERASE | FLASH_PECR_PROG);

    /* Disable End of FLASH Operation interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);

    /* Disable Error source interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);

    /* Process Unlocked */
    __HAL_UNLOCK(&ProcFlash);
  }
    
} 
/**
  * @brief This function handles FLASH interrupt request.
  * @retval None
  */
void HAL_FLASH_IRQHandler(void)
{
  uint32_t addresstmp = 0U;
  
  /* Check FLASH operation error flags */
  if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | \
    FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR | FLASH_FLAG_RDERR)) != RESET)
  {
    if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
    {
      /*return the faulty sector*/
      addresstmp = pFlash.Sector;
      pFlash.Sector = 0xFFFFFFFFU;
    }
    else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
    {
      /*return the faulty bank*/
      addresstmp = pFlash.Bank;
    }
    else
    {
      /*return the faulty address*/
      addresstmp = pFlash.Address;
    }
    
    /*Save the Error code*/
    FLASH_SetErrorCode();
    
    /* FLASH error interrupt user callback */
    HAL_FLASH_OperationErrorCallback(addresstmp);
    
    /*Stop the procedure ongoing*/
    pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
  }
  
  /* Check FLASH End of Operation flag  */
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
  {
    /* Clear FLASH End of Operation pending bit */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
    
    if(pFlash.ProcedureOnGoing == FLASH_PROC_SECTERASE)
    {
      /*Nb of sector to erased can be decreased*/
      pFlash.NbSectorsToErase--;
      
      /* Check if there are still sectors to erase*/
      if(pFlash.NbSectorsToErase != 0U)
      {
        addresstmp = pFlash.Sector;
        /*Indicate user which sector has been erased*/
        HAL_FLASH_EndOfOperationCallback(addresstmp);
        
        /*Increment sector number*/
        pFlash.Sector++;
        addresstmp = pFlash.Sector;
        FLASH_Erase_Sector(addresstmp, pFlash.VoltageForErase);
      }
      else
      {
        /*No more sectors to Erase, user callback can be called.*/
        /*Reset Sector and stop Erase sectors procedure*/
        pFlash.Sector = addresstmp = 0xFFFFFFFFU;
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
        
        /* Flush the caches to be sure of the data consistency */
        FLASH_FlushCaches() ;
                
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(addresstmp);
      }
    }
    else 
    {
      if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE) 
      {
        /* MassErase ended. Return the selected bank */
        /* Flush the caches to be sure of the data consistency */
        FLASH_FlushCaches() ;

        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Bank);
      }
      else
      {
        /*Program ended. Return the selected address*/
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Address);
      }
      pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
    }
  }
  
  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
  {
    /* Operation is completed, disable the PG, SER, SNB and MER Bits */
    CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_SER | FLASH_CR_SNB | FLASH_MER_BIT));

    /* Disable End of FLASH Operation interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);
    
    /* Disable Error source interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);
    
    /* Process Unlocked */
    __HAL_UNLOCK(&pFlash);
  }
}
/**
  * @brief This function handles FLASH interrupt request.
  * @retval None
  */
void HAL_FLASH_IRQHandler(void)
{
  uint32_t temp = 0;
  
  /* If the program operation is completed, disable the PG Bit */
  FLASH->CR &= (~FLASH_CR_PG);

  /* If the erase operation is completed, disable the SER Bit */
  FLASH->CR &= (~FLASH_CR_SER);
  FLASH->CR &= SECTOR_MASK; 

  /* if the erase operation is completed, disable the MER Bit */
  FLASH->CR &= (~FLASH_MER_BIT);

  /* Check FLASH End of Operation flag  */
  if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != RESET)
  {
    switch (pFlash.ProcedureOnGoing)
    {
      case FLASH_PROC_SECTERASE :
      {
        /* Nb of sector to erased can be decreased */
        pFlash.NbSectorsToErase--;

        /* Check if there are still sectors to erase */
        if(pFlash.NbSectorsToErase != 0)
        {
          temp = pFlash.Sector;
          /* Indicate user which sector has been erased */
          HAL_FLASH_EndOfOperationCallback(temp);

          /* Clear pending flags (if any) */  
          __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);  

          /* Increment sector number */
          temp = ++pFlash.Sector;
          FLASH_Erase_Sector(temp, pFlash.VoltageForErase);
        }
        else
        {
          /* No more sectors to Erase, user callback can be called.*/
          /* Reset Sector and stop Erase sectors procedure */
          pFlash.Sector = temp = 0xFFFFFFFF;
          /* FLASH EOP interrupt user callback */
          HAL_FLASH_EndOfOperationCallback(temp);
          /* Sector Erase procedure is completed */
          pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
          /* Clear FLASH End of Operation pending bit */
          __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
        }
        break;
      }
    
      case FLASH_PROC_MASSERASE :
      {
        /* MassErase ended. Return the selected bank : in this product we don't have Banks */
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(0);
        /* MAss Erase procedure is completed */
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
        /* Clear FLASH End of Operation pending bit */
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
        break;
      }

      case FLASH_PROC_PROGRAM :
      {
        /*Program ended. Return the selected address*/
        /* FLASH EOP interrupt user callback */
        HAL_FLASH_EndOfOperationCallback(pFlash.Address);
        /* Programming procedure is completed */
        pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
        /* Clear FLASH End of Operation pending bit */
        __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
        break;
      }
      default :
        break;
    }
  }
  
  /* Check FLASH operation error flags */
  if(__HAL_FLASH_GET_FLAG((FLASH_FLAG_OPERR  | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR )) != RESET)
  {
    switch (pFlash.ProcedureOnGoing)
    {
      case FLASH_PROC_SECTERASE :
      {
        /* return the faulty sector */
        temp = pFlash.Sector;
        pFlash.Sector = 0xFFFFFFFF;
        break;
      }
      case FLASH_PROC_MASSERASE :
      {
        /* No return in case of Mass Erase */
        temp = 0;
        break;
      }
      case FLASH_PROC_PROGRAM :
      {
        /*return the faulty address*/
        temp = pFlash.Address;
        break;
      }
    default :
      break;
    }
    /*Save the Error code*/
    FLASH_SetErrorCode();

    /* FLASH error interrupt user callback */
    HAL_FLASH_OperationErrorCallback(temp);
    /* Clear FLASH error pending bits */
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPERR  | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_ERSERR );

    /*Stop the procedure ongoing */
    pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
  }
  
  if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
  {
    /* Disable End of FLASH Operation interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_EOP);

    /* Disable Error source interrupt */
    __HAL_FLASH_DISABLE_IT(FLASH_IT_ERR);

    /* Process Unlocked */
    __HAL_UNLOCK(&pFlash);
  }
  
}
示例#29
-1
文件: flash.c 项目: StefanJia/test2
HAL_StatusTypeDef WriteFlash(int32_t* table, uint32_t Address, uint32_t lenth)  
{
  HAL_StatusTypeDef res;
  HAL_FLASH_Unlock();
  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 
                         FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); 
    /* Erase the user Flash area
  (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
  EraseFlash(Address);
  
  for(int i=0;i<lenth;i++)
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,Address+4*i,*(table+i));
  res = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,Address+4*lenth-4,table[lenth-1]);
  HAL_FLASH_Lock(); 
  return res;
}
static int
stm32f3_flash_write(const struct hal_flash *dev, uint32_t address,
        const void *src, uint32_t num_bytes)
{
    const uint16_t *sptr;
    uint32_t i, half_words;
    int rc;

    sptr = src;
    half_words = (num_bytes + 1) / 2;

    HAL_FLASH_Unlock();
    __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);

    for (i = 0, rc = HAL_OK; i < half_words && rc == HAL_OK; ++i) {
        rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, sptr[i]);
        address += 2;
    }
    HAL_FLASH_Lock();

    return rc == HAL_OK ? 0 : rc;
}