#include "flash.h"
|
#include "bootloader_iap.h"
|
|
void FlashInit(void)
|
{
|
CMU_PERCLK_SetableEx(FLASHCLK, ENABLE);
|
}
|
/******************************************
|
* func: FlashPageErase
|
* desc: ÄÚ²¿FlashÒ³£¨512 Bytes£©²Á
|
* input: address£ºFlash¿Õ¼äµØÖ·
|
* output: none
|
* return: PASS£º³É¹¦ FAIL£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus FlashPageErase(uint32_t address)
|
{
|
#define FLS_PAGE_ERASE_KEY0 0x96969696
|
#define FLS_PAGE_ERASE_KEY1 0xEAEAEAEA
|
#define FLS_PAGE_ERASE_DATA 0x1234ABCD
|
|
uint16_t i;
|
|
CMU_OPCCR2_NVMCKE_Setable(ENABLE);
|
|
FLS_EPCR_ERTYPE_Set(FLS_EPCR_ERTYPE_PAGE);
|
|
FLS_EPCR_EREQ_Set(FLS_EPCR_EREQ_Msk);
|
FLS_KEY_Write(FLS_PAGE_ERASE_KEY0);
|
FLS_KEY_Write(FLS_PAGE_ERASE_KEY1);
|
*(uint32_t *)address = FLS_PAGE_ERASE_DATA;
|
|
while (SET != FLS_ISR_ERD_Chk()) { __NOP(); }
|
FLS_ISR_ERD_Clr();
|
|
FLS_KEY_Write(0x00000000);
|
|
CMU_OPCCR2_NVMCKE_Setable(DISABLE);
|
|
for (i = 0; i < 128; i++ )
|
{
|
if (*(uint32_t *)address != 0xFFFFFFFF)
|
{
|
return FAIL;
|
}
|
}
|
return PASS;
|
|
#undef FLS_PAGE_ERASE_KEY0
|
#undef FLS_PAGE_ERASE_KEY1
|
#undef FLS_PAGE_ERASE_DATA
|
}
|
|
|
/******************************************
|
* func: LL_FLASH_Program_Word
|
* desc: ÄÚ²¿Flash×Ö£¨32 Bits£©Ð´
|
* input: address£ºFlash¿Õ¼äµØÖ·
|
data£ºÊý¾Ý
|
* output: none
|
* return: PASS£º³É¹¦
|
*****************************************/
|
ErrorStatus LL_FLASH_Program_Word(uint32_t address, uint32_t data)
|
{
|
#define FLS_PROG_KEY0 0xA5A5A5A5
|
#define FLS_PROG_KEY1 0xF1F1F1F1
|
|
CMU_OPCCR2_NVMCKE_Setable(ENABLE);
|
|
FLS_EPCR_PREQ_Set(FLS_EPCR_PREQ_Msk);
|
FLS_KEY_Write(FLS_PROG_KEY0); // дÈëflash±à³Ìkey0
|
FLS_KEY_Write(FLS_PROG_KEY1); // дÈëflash±à³Ìkey1
|
*(uint32_t *)address = data;
|
|
while (FLS_ISR_PRD_Chk() == RESET); // µÈ´ýд²Ù×÷Íê³É
|
FLS_ISR_PRD_Clr(); // Çå³ýдÍê³ÉÖжϱêÖ¾
|
FLS_KEY_Write(0x00000000);
|
|
CMU_OPCCR2_NVMCKE_Setable(DISABLE);
|
|
#undef FLS_PROG_KEY0
|
#undef FLS_PROG_KEY1
|
return PASS;
|
}
|
|
/******************************************
|
* func: LL_FLASH_Program_String
|
* desc: ÄÚ²¿Flash×Ö£¨4 bytes£©Ð´¶à´Î
|
* input: address£ºFlash¿Õ¼äµØÖ·
|
*data£ºÊý¾Ý
|
Length£ºÐ´µÄ³¤¶È
|
* output: none
|
* return: PASS£º³É¹¦ FAIL£ºÊ§°Ü
|
*****************************************/
|
//ErrorStatus LL_FLASH_Program_String(uint32_t Address, uint32_t *data,uint32_t Length)
|
//{
|
// uint32_t i;
|
// ErrorStatus ret;
|
// for(i=0; i<Length; i++)
|
// {
|
// if(((Address + i * 4) & 3) == 0) //µØÖ·Ò»¶¨ÒªÊÇ4µÄ±¶Êý
|
// {
|
// ret = LL_FLASH_Program_Word( Address + i * 4, data[i]);
|
// if(ret == FAIL)
|
// return FAIL;
|
// }
|
// else
|
// return FAIL;
|
// }
|
// return PASS;
|
//}
|
|
/******************************************
|
* func: Flash_App_Write_String
|
* desc: ÄÚ²¿Flash_APP£¨Ó¦ÓóÌÐò£©µØÖ·Á¬Ðø×Ö£¨4 bytes£©Ð´
|
* input: prog_addr£º±»Ð´flashÊ×µØÖ·
|
prog_data ´ýдÊý¾Ý»º³åÇø
|
Len дÈ볤¶È(Ò»´Î²»ÒªÐ´ÈëÌ«¶à£¬ÒÔÃâ¿´ÃŹ·Òç³ö)
|
* output: none
|
* return: SUCCESS_0£º³É¹¦ ERROR_1£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus_STM32 Flash_App_Write_String( uint32_t prog_addr,uint32_t* prog_data, uint16_t Len)
|
{
|
uint16_t i;
|
uint32_t *PFlash;
|
PFlash = (uint32_t*)prog_addr;
|
uint16_t len_word = Len >> 2; // µÈ¼ÛÓÚ / 4
|
|
if(prog_addr < BOOTLOAD_DIFF_SECTOR_MAP_ADDRESS) return ERROR_1;//½ûֹдbootloaderÇø
|
for(i=0; i< len_word; i++)
|
{
|
if(((prog_addr + i * 4) & 3) == 0) //µØÖ·Ò»¶¨ÒªÊÇ4µÄ±¶Êý
|
LL_FLASH_Program_Word( prog_addr + i * 4, prog_data[i]);
|
else
|
return ERROR_1;
|
if (PFlash[i] != prog_data[i])
|
return ERROR_1;
|
}
|
return SUCCESS_0;
|
}
|
|
/******************************************
|
* func: Flash_AppErasePage£¨×îСµ¥Î»£©
|
* desc: ÄÚ²¿Flash_APP£¨Ó¦ÓóÌÐò£©Ò³²Á³ý
|
* input: EraseAddr£º²Á³ýµÄµØÖ·
|
* output: none
|
* return: SUCCESS_0£º³É¹¦ ERROR_1£ºÊ§°Ü
|
*****************************************/
|
ErrorStatus_STM32 Flash_AppPageErase( uint32_t EraseAddr )
|
{
|
uint16_t i;
|
uint32_t PageNum = EraseAddr / BOOTLOAD_PAGE_SIZE;//µ±Ç°µÚ¼¸Ò³
|
uint32_t *PFlash = (uint32_t *)(uint32)(PageNum * BOOTLOAD_PAGE_SIZE);
|
|
if(EraseAddr < BOOTLOAD_DIFF_SECTOR_MAP_ADDRESS) return ERROR_1;//½ûÖ¹²Á³ýbootÇø
|
/*ΪʲôҪÏȳýÒÔ512ÔÙ³ËÒÔ512£¬ÊÇÒòΪFM33A0µÄFlash²Á³ýÊÇÒÔÒ³£¨512×Ö½Ú£©Îª×îСµ¥Î»
|
Èç¹ûµØÖ·Îª1ÄÇô¾ÍÊǵÚÒ»Ò³£¨0~511£©£¬µØÖ·Îª530ÄǾÍÊǵڶþÒ³£¨512~1023£©*/
|
FlashPageErase(PageNum * BOOTLOAD_PAGE_SIZE);//²Á³ýAPPÖ¸¶¨Ò³
|
for (i = 0; i < 128; i++ )
|
{
|
if (PFlash[i] != 0xFFFFFFFF )
|
{
|
return ERROR_1;
|
}
|
}
|
return SUCCESS_0;
|
}
|