249 lines
7.4 KiB
C
249 lines
7.4 KiB
C
|
|
/*
|
|||
|
|
*********************************************************************************************************
|
|||
|
|
* IAR Development Kits
|
|||
|
|
* on the
|
|||
|
|
*
|
|||
|
|
* M451
|
|||
|
|
*
|
|||
|
|
* Filename : fmc_flash.h
|
|||
|
|
* Version : V1.00
|
|||
|
|
* Programmer(s) : Qian Xianghong
|
|||
|
|
*********************************************************************************************************
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
*********************************************************************************************************
|
|||
|
|
* INCLUDE FILES
|
|||
|
|
*********************************************************************************************************
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#include "includes.h"
|
|||
|
|
|
|||
|
|
// <20><>Flashȫ<68>ֻ<EFBFBD><D6BB><EFBFBD>
|
|||
|
|
uint8_t Flash_rdBuf[FLASH_ERASE_SIZE];
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>4<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD>
|
|||
|
|
#define ALIGN_DWORD_SIZE(addr) ((addr) & 0xFFFFFFFCul)
|
|||
|
|
|
|||
|
|
/* Base address of the Flash sectors */
|
|||
|
|
|
|||
|
|
#define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base address of Sector 0, 16 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_1 ((uint32_t)0x08004000) /* Base address of Sector 1, 16 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_2 ((uint32_t)0x08008000) /* Base address of Sector 2, 16 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_3 ((uint32_t)0x0800C000) /* Base address of Sector 3, 16 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_4 ((uint32_t)0x08010000) /* Base address of Sector 4, 64 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_5 ((uint32_t)0x08020000) /* Base address of Sector 5, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_6 ((uint32_t)0x08040000) /* Base address of Sector 6, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_7 ((uint32_t)0x08060000) /* Base address of Sector 7, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_8 ((uint32_t)0x08080000) /* Base address of Sector 8, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_9 ((uint32_t)0x080A0000) /* Base address of Sector 9, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_10 ((uint32_t)0x080C0000) /* Base address of Sector10, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_11 ((uint32_t)0x080E0000) /* Base address of Sector11, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_12 ((uint32_t)0x08100000) /* Base address of Sector12, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_13 ((uint32_t)0x08120000) /* Base address of Sector13, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_14 ((uint32_t)0x08140000) /* Base address of Sector14, 128 Kbytes */
|
|||
|
|
#define ADDR_FLASH_SECTOR_15 ((uint32_t)0x08160000) /* Base address of Sector15, 128 Kbytes */
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Gets the sector of a given address
|
|||
|
|
* @param None
|
|||
|
|
* @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;
|
|||
|
|
}
|
|||
|
|
return sector;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Gets sector Size
|
|||
|
|
* @param None
|
|||
|
|
* @retval The size of a given sector
|
|||
|
|
*/
|
|||
|
|
static uint32_t GetSectorSize(uint32_t Sector)
|
|||
|
|
{
|
|||
|
|
uint32_t sectorsize = 0x00;
|
|||
|
|
if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3))
|
|||
|
|
{
|
|||
|
|
sectorsize = 16 * 1024;
|
|||
|
|
}
|
|||
|
|
else if(Sector == FLASH_SECTOR_4)
|
|||
|
|
{
|
|||
|
|
sectorsize = 64 * 1024;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
sectorsize = 128 * 1024;
|
|||
|
|
}
|
|||
|
|
return sectorsize;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief Gets sector start Address
|
|||
|
|
* @param None
|
|||
|
|
* @retval The start address of a given sector
|
|||
|
|
*/
|
|||
|
|
static uint32_t GetSectorAddr(uint32_t Sector)
|
|||
|
|
{
|
|||
|
|
uint32_t sectoraddr = 0x00;
|
|||
|
|
if((Sector == FLASH_SECTOR_0) || (Sector == FLASH_SECTOR_1) || (Sector == FLASH_SECTOR_2) || (Sector == FLASH_SECTOR_3))
|
|||
|
|
{
|
|||
|
|
sectoraddr = ADDR_FLASH_SECTOR_0 + 16 * 1024 * (Sector - FLASH_SECTOR_0);
|
|||
|
|
}
|
|||
|
|
else if(Sector == FLASH_SECTOR_4)
|
|||
|
|
{
|
|||
|
|
sectoraddr = ADDR_FLASH_SECTOR_0 + 64 * 1024;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
sectoraddr = ADDR_FLASH_SECTOR_0 + 128 * 1024 * (Sector - FLASH_SECTOR_5);
|
|||
|
|
}
|
|||
|
|
return sectoraddr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// У<><D0A3>flash<73><68><EFBFBD><EFBFBD>
|
|||
|
|
uint8_t Flash_BufferVerify(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>4<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD>
|
|||
|
|
uint32_t Addr4Start = ALIGN_DWORD_SIZE(Addr);
|
|||
|
|
uint32_t Addr4End = ALIGN_DWORD_SIZE(Addr + nbytes + 3);
|
|||
|
|
uint32_t u32Data, i, j = 0;
|
|||
|
|
|
|||
|
|
for(i = Addr4Start; i < Addr4End; i += 4)
|
|||
|
|
{
|
|||
|
|
u32Data = *(__IO uint32_t *)(i);
|
|||
|
|
if(i >= Addr && i < Addr + nbytes && buf[j++] != (u32Data & 0xFF))
|
|||
|
|
return 0;
|
|||
|
|
if(i + 1 >= Addr && i + 1 < Addr + nbytes && buf[j++] != ((u32Data >> 8) & 0xFF))
|
|||
|
|
return 0;
|
|||
|
|
if(i + 2 >= Addr && i + 2 < Addr + nbytes && buf[j++] != ((u32Data >> 16) & 0xFF))
|
|||
|
|
return 0;
|
|||
|
|
if(i + 3 >= Addr && i + 3 < Addr + nbytes && buf[j++] != (u32Data >> 24))
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>flash<73><68><EFBFBD>ݶ<EFBFBD><DDB6>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD>
|
|||
|
|
void Flash_BufferRead(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>4<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD>
|
|||
|
|
uint32_t Addr4Start = ALIGN_DWORD_SIZE(Addr);
|
|||
|
|
uint32_t Addr4End = ALIGN_DWORD_SIZE(Addr + nbytes + 3);
|
|||
|
|
uint32_t u32Data, i, j = 0;
|
|||
|
|
|
|||
|
|
for(i = Addr4Start; i < Addr4End; i += 4)
|
|||
|
|
{
|
|||
|
|
u32Data = *(__IO uint32_t *)(i);
|
|||
|
|
|
|||
|
|
if(i >= Addr && i < Addr + nbytes)
|
|||
|
|
buf[j++] = (u32Data & 0xFF);
|
|||
|
|
if(i + 1 >= Addr && i + 1 < Addr + nbytes)
|
|||
|
|
buf[j++] = ((u32Data >> 8) & 0xFF);
|
|||
|
|
if(i + 2 >= Addr && i + 2 < Addr + nbytes)
|
|||
|
|
buf[j++] = ((u32Data >> 16) & 0xFF);
|
|||
|
|
if(i + 3 >= Addr && i + 3 < Addr + nbytes)
|
|||
|
|
buf[j++] = (u32Data >> 24);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>һҳ
|
|||
|
|
void Flash_EraseSector(uint32_t Addr)
|
|||
|
|
{
|
|||
|
|
static FLASH_EraseInitTypeDef EraseInitStruct;
|
|||
|
|
uint32_t PAGEError = 0;
|
|||
|
|
|
|||
|
|
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
|
|||
|
|
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
|
|||
|
|
EraseInitStruct.Sector = GetSector(Addr);
|
|||
|
|
EraseInitStruct.NbSectors = 1;
|
|||
|
|
HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// д<><D0B4>һҳ<D2BB><D2B3>AddrΪ<72><EFBFBD>ַ
|
|||
|
|
void Flash_SectorWrite(uint32_t Addr, uint8_t *buf, uint32_t count)
|
|||
|
|
{
|
|||
|
|
unsigned long *buf32 = (unsigned long *) buf;
|
|||
|
|
uint32_t i = 0;
|
|||
|
|
|
|||
|
|
while(i < count)
|
|||
|
|
{
|
|||
|
|
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, Addr + i, *buf32++);
|
|||
|
|
i += 4;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Flash_BufferWrite(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
uint32_t count, offset;
|
|||
|
|
uint32_t sector, sectorSize, sectorAddr;
|
|||
|
|
|
|||
|
|
// <20><>1ҳ<31><D2B3>Bootloader<65><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
static uint8_t sectorErased[16] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|||
|
|
|
|||
|
|
while(nbytes > 0)
|
|||
|
|
{
|
|||
|
|
sector = GetSector(Addr);
|
|||
|
|
sectorSize = GetSectorSize(sector);
|
|||
|
|
sectorAddr = GetSectorAddr(sector);
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>ƫ<EFBFBD>ƣ<EFBFBD>ֻ<EFBFBD>е<EFBFBD>һҳ<D2BB>п<EFBFBD><D0BF>ܷ<EFBFBD>0<EFBFBD><30>
|
|||
|
|
offset = Addr - sectorAddr;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>һҳ<D2BB><D2B3>д<EFBFBD><D0B4><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
|
count = sectorSize - offset;
|
|||
|
|
if(count > nbytes)
|
|||
|
|
count = nbytes;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>д<EFBFBD><D0B4>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if(!sectorErased[sector])
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ
|
|||
|
|
Flash_EraseSector(Addr);
|
|||
|
|
sectorErased[sector] = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// д<>뱾ҳ<EBB1BE><D2B3><EFBFBD><EFBFBD>
|
|||
|
|
Flash_SectorWrite(Addr, buf, count);
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
|
|||
|
|
Addr += count;
|
|||
|
|
buf += count;
|
|||
|
|
nbytes -= count;
|
|||
|
|
}
|
|||
|
|
}
|