158 lines
4.2 KiB
C
158 lines
4.2 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];
|
|||
|
|
// дFlash<73><68><EFBFBD><EFBFBD>
|
|||
|
|
uint8_t Flash_wtBuf[FLASH_ERASE_SIZE];
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>4<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD>
|
|||
|
|
#define ALIGN_DWORD_SIZE(addr) ((addr) & 0xFFFFFFFCul)
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>FLASH_ERASE_SIZE<5A>ֽڶ<D6BD><DAB6><EFBFBD>
|
|||
|
|
#define ALIGN_PAGE_SIZE(addr) ((addr) & 0xFFFFF800ul)
|
|||
|
|
|
|||
|
|
static uint32_t GetPage(uint32_t Addr)
|
|||
|
|
{
|
|||
|
|
uint32_t page = 0;
|
|||
|
|
|
|||
|
|
if (Addr < (FLASH_BASE + FLASH_BANK_SIZE))
|
|||
|
|
{
|
|||
|
|
/* Bank 1 */
|
|||
|
|
page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* Bank 2 */
|
|||
|
|
page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return page;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// У<><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_ErasePage(uint32_t Addr)
|
|||
|
|
{
|
|||
|
|
static FLASH_EraseInitTypeDef EraseInitStruct;
|
|||
|
|
uint32_t PAGEError = 0;
|
|||
|
|
|
|||
|
|
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
|
|||
|
|
EraseInitStruct.Banks = FLASH_BANK_1;
|
|||
|
|
EraseInitStruct.Page = GetPage(ALIGN_PAGE_SIZE(Addr));
|
|||
|
|
EraseInitStruct.NbPages = 1;
|
|||
|
|
HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// д<><D0B4>һҳ<D2BB><D2B3>AddrΪҳ<CEAA><EFBFBD>ַ
|
|||
|
|
void Flash_PageWrite(uint32_t Addr, uint8_t *buf)
|
|||
|
|
{
|
|||
|
|
unsigned long long *buf64 = (unsigned long long *) buf;
|
|||
|
|
uint32_t i = Addr;
|
|||
|
|
|
|||
|
|
while(i < Addr + FLASH_ERASE_SIZE)
|
|||
|
|
{
|
|||
|
|
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, i, *buf64++);
|
|||
|
|
i += 8;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void Flash_BufferWrite(uint32_t Addr, uint8_t *buf, uint32_t nbytes)
|
|||
|
|
{
|
|||
|
|
uint32_t count, offset;
|
|||
|
|
|
|||
|
|
while(nbytes > 0)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>ƫ<EFBFBD>ƣ<EFBFBD>ֻ<EFBFBD>е<EFBFBD>һҳ<D2BB>п<EFBFBD><D0BF>ܷ<EFBFBD>0<EFBFBD><30>
|
|||
|
|
offset = Addr % FLASH_ERASE_SIZE;
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>һҳ<D2BB><D2B3>д<EFBFBD><D0B4><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
|
count = FLASH_ERASE_SIZE - offset;
|
|||
|
|
if(count > nbytes)
|
|||
|
|
count = nbytes;
|
|||
|
|
|
|||
|
|
// ҳ<><D2B3><EFBFBD><EFBFBD>
|
|||
|
|
Addr = ALIGN_PAGE_SIZE(Addr);
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
Flash_BufferRead(Addr, Flash_wtBuf, FLASH_ERASE_SIZE);
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD>д
|
|||
|
|
if(memcmp(Flash_wtBuf + offset, buf, count) != 0)
|
|||
|
|
{
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҳ
|
|||
|
|
Flash_ErasePage(Addr);
|
|||
|
|
// <20><EFBFBD><DEB8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
memcpy(Flash_wtBuf + offset, buf, count);
|
|||
|
|
// д<>뱾ҳ<EBB1BE><D2B3><EFBFBD><EFBFBD>
|
|||
|
|
Flash_PageWrite(Addr, Flash_wtBuf);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һҳ
|
|||
|
|
Addr += FLASH_ERASE_SIZE;
|
|||
|
|
buf += count;
|
|||
|
|
nbytes -= count;
|
|||
|
|
}
|
|||
|
|
}
|