#include "Flash.h"
|
#include "HIDO_TypeDef.h"
|
|
|
/* ¸÷¸öÉÈÇøÊ×µØÖ· */
|
#define ADDR_FLASH_SECTOR_0 ((HIDO_UINT32)0x08000000) /* Base @ of Sector 0, 16 Kbyte */
|
#define ADDR_FLASH_SECTOR_1 ((HIDO_UINT32)0x08004000) /* Base @ of Sector 1, 16 Kbyte */
|
#define ADDR_FLASH_SECTOR_2 ((HIDO_UINT32)0x08008000) /* Base @ of Sector 2, 16 Kbyte */
|
#define ADDR_FLASH_SECTOR_3 ((HIDO_UINT32)0x0800C000) /* Base @ of Sector 3, 16 Kbyte */
|
#define ADDR_FLASH_SECTOR_4 ((HIDO_UINT32)0x08010000) /* Base @ of Sector 4, 64 Kbyte */
|
#define ADDR_FLASH_SECTOR_5 ((HIDO_UINT32)0x08020000) /* Base @ of Sector 5, 128 Kbyte */
|
#define ADDR_FLASH_SECTOR_6 ((HIDO_UINT32)0x08040000) /* Base @ of Sector 6, 128 Kbyte */
|
#define ADDR_FLASH_SECTOR_7 ((HIDO_UINT32)0x08060000) /* Base @ of Sector 7, 128 Kbyte */
|
#define ADDR_FLASH_SECTOR_8 ((HIDO_UINT32)0x08080000) /* Base @ of Sector 8, 128 Kbyte */
|
#define ADDR_FLASH_SECTOR_9 ((HIDO_UINT32)0x080A0000) /* Base @ of Sector 9, 128 Kbyte */
|
#define ADDR_FLASH_SECTOR_10 ((HIDO_UINT32)0x080C0000) /* Base @ of Sector 10, 128 Kbyte */
|
#define ADDR_FLASH_SECTOR_11 ((HIDO_UINT32)0x080E0000) /* Base @ of Sector 11, 128 Kbyte */
|
|
|
static HIDO_UINT32 MCUFlash_GetSector(HIDO_UINT32 _u32Address)
|
{
|
HIDO_UINT32 u32Sector = 0;
|
|
if ((_u32Address < ADDR_FLASH_SECTOR_1) && (_u32Address >= ADDR_FLASH_SECTOR_0))
|
{
|
u32Sector = FLASH_SECTOR_0;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_2) && (_u32Address >= ADDR_FLASH_SECTOR_1))
|
{
|
u32Sector = FLASH_SECTOR_1;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_3) && (_u32Address >= ADDR_FLASH_SECTOR_2))
|
{
|
u32Sector = FLASH_SECTOR_2;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_4) && (_u32Address >= ADDR_FLASH_SECTOR_3))
|
{
|
u32Sector = FLASH_SECTOR_3;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_5) && (_u32Address >= ADDR_FLASH_SECTOR_4))
|
{
|
u32Sector = FLASH_SECTOR_4;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_6) && (_u32Address >= ADDR_FLASH_SECTOR_5))
|
{
|
u32Sector = FLASH_SECTOR_5;
|
}
|
|
return u32Sector;
|
}
|
|
static HIDO_UINT32 MCUFlash_GetSectorSize(HIDO_UINT32 _u32Address)
|
{
|
HIDO_UINT32 u32Sector = 0;
|
|
if ((_u32Address < ADDR_FLASH_SECTOR_1) && (_u32Address >= ADDR_FLASH_SECTOR_0))
|
{
|
u32Sector = ADDR_FLASH_SECTOR_1 - ADDR_FLASH_SECTOR_0;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_2) && (_u32Address >= ADDR_FLASH_SECTOR_1))
|
{
|
u32Sector = FLASH_SECTOR_1;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_3) && (_u32Address >= ADDR_FLASH_SECTOR_2))
|
{
|
u32Sector = FLASH_SECTOR_2;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_4) && (_u32Address >= ADDR_FLASH_SECTOR_3))
|
{
|
u32Sector = FLASH_SECTOR_3;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_5) && (_u32Address >= ADDR_FLASH_SECTOR_4))
|
{
|
u32Sector = FLASH_SECTOR_4;
|
}
|
else if ((_u32Address < ADDR_FLASH_SECTOR_6) && (_u32Address >= ADDR_FLASH_SECTOR_5))
|
{
|
u32Sector = FLASH_SECTOR_5;
|
}
|
|
return u32Sector;
|
}
|
|
|
/**
|
* @brief Calculate the number of pages
|
* @param Size: The image size,the units of Size is Byte
|
* @retval The number of pages or error
|
*/
|
unsigned short int STMFLASH_ReadHalfWord(unsigned int faddr)
|
{
|
return *(volatile unsigned short int*)faddr;
|
}
|
|
HIDO_UINT32 FLASH_Pages_Calculate(HIDO_UINT32 Size)
|
{
|
HIDO_UINT32 Flash_Page_Number = 0;
|
|
if( Size % PAGE_SIZE != 0)
|
{
|
Flash_Page_Number = ( Size / PAGE_SIZE) + 1;
|
}
|
else
|
Flash_Page_Number = Size / PAGE_SIZE;
|
|
if( Flash_Page_Number > MAX_FPAGE_NUM)
|
return 0;
|
else
|
return Flash_Page_Number;
|
}
|
|
|
/**
|
* @brief erase the block before write Data
|
* @param Address: the start address to erase
|
Len: the length need to erase,uints is Byte
|
* @retval 0:error; 1:success
|
*/
|
|
|
HIDO_UINT32 FLASH_Prepare(HIDO_UINT32 Address, HIDO_UINT32 Len) //ÆðʼµØÖ·ºÍ×Ö³¤
|
{
|
FLASH_EraseInitTypeDef stEraseInit;
|
HIDO_UINT32 u32EraseError = 0;
|
|
HAL_FLASH_Unlock();
|
|
stEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
|
stEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
stEraseInit.Banks = FLASH_BANK_1;
|
stEraseInit.Sector = MCUFlash_GetSector(Address);
|
stEraseInit.NbSectors = MCUFlash_GetSector(Address + Len - 1) - MCUFlash_GetSector(Address) + 1;
|
|
if(HAL_FLASHEx_Erase(&stEraseInit, &u32EraseError) != HAL_OK)
|
{
|
HAL_FLASH_Lock();
|
return 0;
|
}
|
|
HAL_FLASH_Lock();
|
return 1;
|
}
|
|
/**
|
* @brief read the data from flash
|
* @param Address: the start address to read
|
Len: the length need to read,uints is Byte
|
* @retval
|
*/
|
void FLASH_Read( HIDO_UINT32 Address, HIDO_UINT8* Readbuff, HIDO_UINT32 Len)
|
{
|
HIDO_UINT32 ReadCount = 0;
|
|
for( ; ReadCount < Len; ReadCount++)
|
{
|
Readbuff[ ReadCount ] = ((HIDO_UINT8 *)Address)[ ReadCount ];
|
}
|
}
|
|
/**
|
* @brief write data into flash
|
* @param Address: the start address to write
|
Len: the length need to write,uints is Byte
|
* @retval 0:error ; 1:success
|
*/
|
#define DATA_32 ((HIDO_UINT32)0x12345678)
|
HIDO_UINT32 FLASH_Write( HIDO_UINT32 Address, const HIDO_UINT8* pData, HIDO_UINT32 Len)
|
{
|
uint64_t WriteCount = 0,temp;
|
HIDO_UINT32 FlashDestination = Address;
|
HIDO_UINT32 FlashSource = (HIDO_UINT32)pData;
|
HAL_StatusTypeDef FLASHStatus = HAL_OK;
|
|
HAL_FLASH_Unlock();
|
|
for( ; WriteCount < Len; WriteCount+=1)
|
{temp=*(uint64_t*)FlashSource;
|
FLASHStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, FlashDestination, temp);
|
|
if( FLASHStatus != HAL_OK)
|
{
|
break;
|
}
|
if (*(HIDO_UINT16*)FlashDestination != *(HIDO_UINT16*)FlashSource)
|
{
|
//break;
|
}
|
FlashDestination += 1;
|
FlashSource += 1;
|
}
|
|
HAL_FLASH_Lock();
|
|
if( WriteCount < Len)
|
return 0;
|
else
|
return 1;
|
|
}
|
|
HIDO_INT32 FLASH_EraseEx(HIDO_UINT32 _u32EraseAddr, HIDO_UINT32 _u32EraseLen)
|
{
|
FLASH_EraseInitTypeDef stEraseInit;
|
HIDO_UINT32 u32EraseError = 0;
|
|
stEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
|
stEraseInit.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
stEraseInit.Banks = FLASH_BANK_1;
|
stEraseInit.Sector = MCUFlash_GetSector(_u32EraseAddr);
|
stEraseInit.NbSectors = MCUFlash_GetSector(_u32EraseAddr + _u32EraseLen - 1) - MCUFlash_GetSector(_u32EraseAddr) + 1;
|
|
if(HAL_FLASHEx_Erase(&stEraseInit, &u32EraseError) != HAL_OK)
|
{
|
return HIDO_ERR;
|
}
|
|
return HIDO_OK;
|
}
|
|
HIDO_INT32 FLASH_ReadEx(HIDO_UINT8 *_pu8ReadData, HIDO_UINT32 _u32ReadAddr, HIDO_UINT32 _u32ReadLen)
|
{
|
memcpy(_pu8ReadData, (HIDO_VOID *)_u32ReadAddr, _u32ReadLen);
|
|
return HIDO_OK;
|
}
|
|
HIDO_INT32 FLASH_WriteEx(HIDO_UINT32 _u32WriteAddr, HIDO_UINT8 *_pu8WriteData, HIDO_UINT32 _u32WriteLen)
|
{
|
HIDO_UINT32 i = 0;
|
HIDO_UINT32 u32TmpLen = 0;
|
HIDO_UINT32 u32TmpValue = 0;
|
// HIDO_UINT32 u32RertyCnt = 0;
|
|
while (_u32WriteLen != 0)
|
{
|
if (_u32WriteLen < 4)
|
{
|
u32TmpValue = 0xFFFFFFFF;
|
for(i = 0; i < _u32WriteLen; i++)
|
{
|
((HIDO_UINT8 *)&u32TmpValue)[i] = _pu8WriteData[i];
|
}
|
u32TmpLen = _u32WriteLen;
|
}
|
else
|
{
|
u32TmpValue = *(HIDO_UINT32 *) _pu8WriteData;
|
u32TmpLen = 4;
|
}
|
|
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR | FLASH_FLAG_PGSERR);
|
// rerty:
|
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, _u32WriteAddr, u32TmpValue) != HAL_OK)
|
{
|
// if(u32RertyCnt < 3)
|
// {
|
// u32RertyCnt++;
|
// goto rerty;
|
// }
|
// else
|
// {
|
// return HIDO_ERR;
|
// }
|
return HIDO_ERR;
|
}
|
else
|
{
|
// u32RertyCnt = 0;
|
}
|
|
_u32WriteAddr += u32TmpLen;
|
_pu8WriteData += u32TmpLen;
|
_u32WriteLen -= u32TmpLen;
|
}
|
|
return HIDO_OK;
|
}
|