mirror of
https://github.com/No-Chicken/Power-Pico.git
synced 2026-04-03 13:02:36 +08:00
update
This commit is contained in:
299
software/bootloader/Ymodem/flash_if.c
Normal file
299
software/bootloader/Ymodem/flash_if.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file STM32F4xx_IAP/src/flash_if.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 10-October-2011
|
||||
* @brief This file provides all the memory related operation functions.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F4xx_IAP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "flash_if.h"
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static uint32_t GetSector(uint32_t Address);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief Unlocks Flash for write access
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void FLASH_If_Init(void)
|
||||
{
|
||||
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);
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief This function does an erase of all user flash area
|
||||
* @param StartSector: start of user flash area
|
||||
* @retval 0: user flash area successfully erased
|
||||
* 1: error occurred
|
||||
*/
|
||||
uint32_t FLASH_If_Erase(uint32_t StartSector)
|
||||
{
|
||||
uint32_t UserStartSector;
|
||||
uint32_t SectorError;
|
||||
FLASH_EraseInitTypeDef pEraseInit;
|
||||
|
||||
/* Unlock the Flash to enable the flash control register access *************/
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
UserStartSector = GetSector(APPLICATION_ADDRESS);
|
||||
|
||||
pEraseInit.TypeErase = TYPEERASE_SECTORS;
|
||||
pEraseInit.Sector = UserStartSector;
|
||||
pEraseInit.NbSectors = GetSector(USER_FLASH_END_ADDRESS)-UserStartSector+1 ;
|
||||
pEraseInit.VoltageRange = VOLTAGE_RANGE_3;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK)
|
||||
{
|
||||
/* Error occurred while page erase */
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function erase one sector
|
||||
* @param StartSector: start of user flash area
|
||||
* @retval 0: user flash area successfully erased
|
||||
* 1: error occurred
|
||||
*/
|
||||
uint32_t FLASH_If_Erase_One_Sector(uint32_t StartSector)
|
||||
{
|
||||
uint32_t SectorError;
|
||||
FLASH_EraseInitTypeDef pEraseInit;
|
||||
|
||||
pEraseInit.TypeErase = TYPEERASE_SECTORS;
|
||||
pEraseInit.Sector = StartSector;
|
||||
pEraseInit.NbSectors = 1 ;
|
||||
pEraseInit.VoltageRange = VOLTAGE_RANGE_3;
|
||||
|
||||
if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK)
|
||||
{
|
||||
/* Error occurred while page erase */
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function writes a data buffer in flash (data are 32-bit aligned).
|
||||
* @note After writing data buffer, the flash content is checked.
|
||||
* @param FlashAddress: start address for writing data buffer
|
||||
* @param Data: pointer on data buffer
|
||||
* @param DataLength: length of data buffer (unit is 32-bit word)
|
||||
* @retval 0: Data successfully written to Flash memory
|
||||
* 1: Error occurred while writing data in Flash memory
|
||||
* 2: Written Data in flash memory is different from expected one
|
||||
*/
|
||||
uint32_t FLASH_If_Write(__IO uint32_t* FlashAddress, uint32_t* Data ,uint32_t DataLength)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; (i < DataLength) && (*FlashAddress <= (USER_FLASH_END_ADDRESS-4)); i++)
|
||||
{
|
||||
/* Device voltage range supposed to be [2.7V to 3.6V], the operation will
|
||||
be done by word */
|
||||
FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i));
|
||||
/* Check the written value */
|
||||
if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))
|
||||
{
|
||||
/* Flash content doesn't match SRAM content */
|
||||
return(2);
|
||||
}
|
||||
/* Increment FLASH destination address */
|
||||
*FlashAddress += 4;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the write protection status of user flash area.
|
||||
* @param None
|
||||
* @retval 0: No write protected sectors inside the user flash area
|
||||
* 1: Some sectors inside the user flash area are write protected
|
||||
*/
|
||||
uint16_t FLASH_If_GetWriteProtectionStatus(void)
|
||||
{
|
||||
uint32_t UserStartSector = FLASH_SECTOR_1;
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
UserStartSector = GetSector(APPLICATION_ADDRESS);
|
||||
|
||||
/* Check if there are write protected sectors inside the user flash area */
|
||||
if ((*(__IO uint16_t *)(OPTCR_BYTE2_ADDRESS) >> (UserStartSector/8)) == (0xFFF >> (UserStartSector/8)))
|
||||
{ /* No write protected sectors inside the user flash area */
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ /* Some sectors inside the user flash area are write protected */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the write protection of user flash area.
|
||||
* @param None
|
||||
* @retval 1: Write Protection successfully disabled
|
||||
* 2: Error: Flash write unprotection failed
|
||||
*/
|
||||
uint32_t FLASH_If_DisableWriteProtection(void)
|
||||
{
|
||||
__IO uint32_t UserStartSector = FLASH_SECTOR_1, UserWrpSectors = OB_WRP_SECTOR_1;
|
||||
|
||||
/* Get the sector where start the user flash area */
|
||||
UserStartSector = GetSector(APPLICATION_ADDRESS);
|
||||
|
||||
/* Mark all sectors inside the user flash area as non protected */
|
||||
UserWrpSectors = 0xFFF-((1 << (UserStartSector/8))-1);
|
||||
|
||||
/* Unlock the Option Bytes */
|
||||
|
||||
HAL_FLASH_Unlock();
|
||||
/* Disable the write protection for all sectors inside the user flash area */
|
||||
FLASH_OB_DisableWRP(UserWrpSectors, FLASH_BANK_1);
|
||||
|
||||
/* Start the Option Bytes programming process. */
|
||||
if (HAL_FLASH_OB_Launch( ) != HAL_OK)
|
||||
{
|
||||
/* Error: Flash write unprotection failed */
|
||||
return (2);
|
||||
}
|
||||
|
||||
/* Write Protection successfully disabled */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the sector of a given address
|
||||
* @param Address: Flash address
|
||||
* @retval The sector of a given address
|
||||
*/
|
||||
|
||||
static uint32_t GetSector(uint32_t Address)
|
||||
{
|
||||
uint32_t sector = 0;
|
||||
|
||||
if((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0))
|
||||
{
|
||||
sector = FLASH_SECTOR_0;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1))
|
||||
{
|
||||
sector = FLASH_SECTOR_1;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2))
|
||||
{
|
||||
sector = FLASH_SECTOR_2;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3))
|
||||
{
|
||||
sector = FLASH_SECTOR_3;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4))
|
||||
{
|
||||
sector = FLASH_SECTOR_4;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5))
|
||||
{
|
||||
sector = FLASH_SECTOR_5;
|
||||
}
|
||||
else if((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6))
|
||||
{
|
||||
sector = FLASH_SECTOR_6;
|
||||
}
|
||||
else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_7))*/
|
||||
{
|
||||
sector = FLASH_SECTOR_7;
|
||||
}
|
||||
// else if((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_7;
|
||||
// }
|
||||
// else if((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_8;
|
||||
// }
|
||||
// else if((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_9;
|
||||
// }
|
||||
// else if((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10))
|
||||
// {
|
||||
// sector = FLASH_SECTOR_10;
|
||||
// }
|
||||
// else/*(Address < FLASH_END_ADDR) && (Address >= ADDR_FLASH_SECTOR_11))*/
|
||||
// {
|
||||
// sector = FLASH_SECTOR_11;
|
||||
// }
|
||||
return sector;
|
||||
}
|
||||
|
||||
|
||||
HAL_StatusTypeDef FLASH_OB_DisableWRP(uint32_t WRPSector, uint32_t Banks)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_WRP_SECTOR(WRPSector));
|
||||
assert_param(IS_FLASH_BANK(Banks));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(50000);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
*(__IO uint16_t*)OPTCR_BYTE2_ADDRESS |= (uint16_t)WRPSector;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void FLASH_ProgramWord(uint32_t Address, uint32_t Data)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_ADDRESS(Address));
|
||||
|
||||
/* If the previous operation is completed, proceed to program the new data */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
|
||||
FLASH->CR |= FLASH_PSIZE_WORD;
|
||||
FLASH->CR |= FLASH_CR_PG;
|
||||
|
||||
*(__IO uint32_t*)Address = Data;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
Reference in New Issue
Block a user