611 lines
12 KiB
C
611 lines
12 KiB
C
|
|
|
|||
|
|
#include "stflash.h"
|
|||
|
|
#include "trigger.h"
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
#define STM32_FLASH_TIMOUT -1 // <20><>ʱ
|
|||
|
|
#define STM32_FLASH_OK 0 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
#define STM32_FLASH_BUSY 1 // æ
|
|||
|
|
#define STM32_FLASH_ERROR 2 // <20><><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
#define MAX_WAIT_TIME 2000 // <20><><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><CAB1>2<EFBFBD><32>
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// waitms<6D><73><EFBFBD>ȴ<EFBFBD>ʱ<EFBFBD><CAB1>(ms)
|
|||
|
|
int FlashWaitNoBusy(int waitms)
|
|||
|
|
{
|
|||
|
|
int timout = waitms;
|
|||
|
|
u32 timer;
|
|||
|
|
u32 tick = GetMsSoftTimer();
|
|||
|
|
|
|||
|
|
do
|
|||
|
|
{
|
|||
|
|
if (READ_BIT(FLASH->SR, FLASH_SR_BSY) != (FLASH_SR_BSY))
|
|||
|
|
{
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
timer = GetMsSoftTimer();
|
|||
|
|
|
|||
|
|
if ((timer - tick) > timout)
|
|||
|
|
{
|
|||
|
|
return STM32_FLASH_TIMOUT;
|
|||
|
|
}
|
|||
|
|
}while (1);
|
|||
|
|
|
|||
|
|
if ((FLASH->SR & (FLASH_SR_EOP)) != 0)
|
|||
|
|
{
|
|||
|
|
CLEAR_BIT(FLASH->SR, FLASH_SR_EOP);
|
|||
|
|
}
|
|||
|
|
#if (0)
|
|||
|
|
timer = GetMsSoftTimer();
|
|||
|
|
printf("FlashWaitNoBusy time=%d\r\n", timer - tick);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
return STM32_FLASH_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>ȡ״̬
|
|||
|
|
int FLASHGetStatus(void)
|
|||
|
|
{
|
|||
|
|
u32 temp = FLASH->SR;
|
|||
|
|
|
|||
|
|
if ((temp & FLASH_SR_BSY) != 0)
|
|||
|
|
{
|
|||
|
|
return STM32_FLASH_BUSY; // æ
|
|||
|
|
}
|
|||
|
|
#if (__CORTEX_M == 0 || __CORTEX_M == 3)
|
|||
|
|
if ((temp & ( FLASH_SR_WRPRTERR | // д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
FLASH_SR_PGERR | // <20><><EFBFBD>̴<EFBFBD><CCB4><EFBFBD>
|
|||
|
|
0 ) ) != 0)
|
|||
|
|
#elif (__CORTEX_M == 4)
|
|||
|
|
else if ((temp & ( FLASH_SR_WRPERR | // д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
FLASH_SR_PGAERR | // <20><><EFBFBD>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
FLASH_SR_PGPERR | // <20><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
FLASH_SR_PGSERR | // <20><><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// FLASH_SR_RDERR |
|
|||
|
|
0 ) ) != 0)
|
|||
|
|
#endif
|
|||
|
|
{
|
|||
|
|
return STM32_FLASH_ERROR; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return STM32_FLASH_OK; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int GetFlashSectorIdx(u32 faddr)
|
|||
|
|
{
|
|||
|
|
#if (__CORTEX_M == 0 || __CORTEX_M == 3)
|
|||
|
|
if (faddr >= STM32_FLASH_BASE)
|
|||
|
|
{
|
|||
|
|
faddr -= STM32_FLASH_BASE;
|
|||
|
|
if (faddr <= STM32_FLASH_SIZE)
|
|||
|
|
{
|
|||
|
|
faddr /= STM32_FLASH_SEC_SIZE;
|
|||
|
|
if (faddr < STM32_FLASH_SEC_NUM)
|
|||
|
|
{
|
|||
|
|
return faddr;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#elif (__CORTEX_M == 4)
|
|||
|
|
|
|||
|
|
#define FLS_RGCK(ad) \
|
|||
|
|
if (faddr < STM32_FLASH_ADDR_SECTOR_##ad)\
|
|||
|
|
{\
|
|||
|
|
return (ad-1);\
|
|||
|
|
}\
|
|||
|
|
else \
|
|||
|
|
//------
|
|||
|
|
FLS_RGCK(0)
|
|||
|
|
FLS_RGCK(1)
|
|||
|
|
FLS_RGCK(2)
|
|||
|
|
FLS_RGCK(3)
|
|||
|
|
FLS_RGCK(4)
|
|||
|
|
FLS_RGCK(5)
|
|||
|
|
FLS_RGCK(6)
|
|||
|
|
FLS_RGCK(7)
|
|||
|
|
|
|||
|
|
if (faddr < STM32_FLASH_ADDR_SECTOR_7 + STM32_FLASH_SIZE_SECTOR_7)
|
|||
|
|
{
|
|||
|
|
return 7;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
u32 GetFlashSectorBegAddr(u32 sidx)
|
|||
|
|
{
|
|||
|
|
u32 addr = STM32_FLASH_BASE;
|
|||
|
|
|
|||
|
|
#if (__CORTEX_M == 0 || __CORTEX_M == 3)
|
|||
|
|
|
|||
|
|
if (sidx < STM32_FLASH_SEC_NUM)
|
|||
|
|
{
|
|||
|
|
addr += sidx * STM32_FLASH_SEC_SIZE;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
addr += STM32_FLASH_SIZE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#elif (__CORTEX_M == 4)
|
|||
|
|
switch (sidx)
|
|||
|
|
{
|
|||
|
|
case 0:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_0;
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_1;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_2;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_3;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_4;
|
|||
|
|
break;
|
|||
|
|
case 5:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_5;
|
|||
|
|
break;
|
|||
|
|
case 6:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_6;
|
|||
|
|
break;
|
|||
|
|
case 7:
|
|||
|
|
addr = STM32_FLASH_ADDR_SECTOR_7;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
return addr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int GetFlashSectorSize(u32 sidx)
|
|||
|
|
{
|
|||
|
|
int size = 0;
|
|||
|
|
|
|||
|
|
#if (__CORTEX_M == 0 || __CORTEX_M == 3)
|
|||
|
|
|
|||
|
|
size = STM32_FLASH_SEC_SIZE;
|
|||
|
|
#elif (__CORTEX_M == 4)
|
|||
|
|
switch (sidx)
|
|||
|
|
{
|
|||
|
|
case 0:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_0;
|
|||
|
|
break;
|
|||
|
|
case 1:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_1;
|
|||
|
|
break;
|
|||
|
|
case 2:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_2;
|
|||
|
|
break;
|
|||
|
|
case 3:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_3;
|
|||
|
|
break;
|
|||
|
|
case 4:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_4;
|
|||
|
|
break;
|
|||
|
|
case 5:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_5;
|
|||
|
|
break;
|
|||
|
|
case 6:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_6;
|
|||
|
|
break;
|
|||
|
|
case 7:
|
|||
|
|
size = STM32_FLASH_SIZE_SECTOR_7;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
return size;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int GetSecRemainSize(u32 faddr)
|
|||
|
|
{
|
|||
|
|
int sidx = GetFlashSectorIdx(faddr);
|
|||
|
|
int slen = GetFlashSectorSize(sidx);
|
|||
|
|
u32 baddr = GetFlashSectorBegAddr(sidx);
|
|||
|
|
if (sidx < 0 || slen <= 0)
|
|||
|
|
{
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (baddr + slen - faddr);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//--------------------------------------------------------------------
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
|
void FLASHUnlock()
|
|||
|
|
{
|
|||
|
|
// printf("FLASHUnlock beg\r\n");
|
|||
|
|
|
|||
|
|
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET)
|
|||
|
|
{
|
|||
|
|
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
|
|||
|
|
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while((READ_BIT(FLASH->CR, FLASH_CR_LOCK) != RESET))
|
|||
|
|
{}
|
|||
|
|
// printf("FLASHUnlock ok\r\n");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>
|
|||
|
|
void FLASHLock()
|
|||
|
|
{
|
|||
|
|
// printf("FLASHLock\r\n");
|
|||
|
|
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_CR_LOCK); // <20><><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// STM32 flash д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// <20><>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>İ<EFBFBD><C4B0><EFBFBD>
|
|||
|
|
// faddr:<3A><><EFBFBD><EFBFBD>ַ(<28>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ϊ2<CEAA>ı<EFBFBD><C4B1><EFBFBD>)
|
|||
|
|
// data: <20><><EFBFBD><EFBFBD>
|
|||
|
|
void FLASHProgramHalfWord(uint32_t faddr, uint16_t data)
|
|||
|
|
{
|
|||
|
|
#if (__CORTEX_M == 4)
|
|||
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_PSIZE_HALF_WORD); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>
|
|||
|
|
#endif
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_CR_PG); // <20><><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
*(__IO uint16_t*)faddr = data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// STM32 flash <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// <20><>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD>İ<EFBFBD><C4B0><EFBFBD>(16λ<36><CEBB><EFBFBD><EFBFBD>)
|
|||
|
|
// faddr:<3A><><EFBFBD><EFBFBD>ַ(<28>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ϊ2<CEAA>ı<EFBFBD><C4B1><EFBFBD>)
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ֵ:<3A><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
|||
|
|
u16 FlashRDHalfWord(u32 faddr)
|
|||
|
|
{
|
|||
|
|
return *( __IO uint16_t*)faddr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
void FLASHEraseSector(uint32_t secIdx)
|
|||
|
|
{
|
|||
|
|
#if (__CORTEX_M == 0 || __CORTEX_M == 3)
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_CR_PER);
|
|||
|
|
WRITE_REG(FLASH->AR, secIdx * STM32_FLASH_SEC_SIZE + STM32_FLASH_BASE);
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_CR_STRT);
|
|||
|
|
#elif (__CORTEX_M == 4)
|
|||
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_PSIZE_HALF_WORD); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_CR_SER); // <20><><EFBFBD>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>ʽ
|
|||
|
|
|
|||
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_SNB); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|||
|
|
FLASH->CR |= (secIdx << FLASH_CR_SNB_Pos); // <20><><EFBFBD>õ<EFBFBD>ַ
|
|||
|
|
SET_BIT(FLASH->CR, FLASH_CR_STRT); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//-----------------------------------------------
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>
|
|||
|
|
// wrAddr: <20><>ʼ<EFBFBD><CABC>ַ
|
|||
|
|
// pBuffer: <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
|
// hwNumToWrite: <20><><EFBFBD><EFBFBD>(16λ)<29><>
|
|||
|
|
int STMFlashWrNoCheck(u32 wrAddr, u16 *pBuffer, u16 hwNumToWrite)
|
|||
|
|
{
|
|||
|
|
int rslt;
|
|||
|
|
u16 i;
|
|||
|
|
for (i = 0; i < hwNumToWrite; i++)
|
|||
|
|
{
|
|||
|
|
FLASHProgramHalfWord(wrAddr, *pBuffer);
|
|||
|
|
pBuffer++;
|
|||
|
|
wrAddr += 2; // <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>2
|
|||
|
|
|
|||
|
|
// <20>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
rslt = FlashWaitNoBusy(MAX_WAIT_TIME);
|
|||
|
|
if (rslt != STM32_FLASH_OK)
|
|||
|
|
{
|
|||
|
|
rslt = FLASHGetStatus();
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
FLASH->CR &= (~FLASH_CR_PG);
|
|||
|
|
}
|
|||
|
|
return rslt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//-----------------------------------------------
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
int FLASHEraseSectorProc(uint32_t secIdx)
|
|||
|
|
{
|
|||
|
|
int rslt;
|
|||
|
|
|
|||
|
|
if (secIdx < 0 || secIdx >= STM32_FLASH_SEC_NUM)
|
|||
|
|
{
|
|||
|
|
return STM32_FLASH_ERROR;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
rslt = FlashWaitNoBusy(MAX_WAIT_TIME);
|
|||
|
|
if (rslt != STM32_FLASH_OK)
|
|||
|
|
{
|
|||
|
|
rslt = FLASHGetStatus();
|
|||
|
|
return rslt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FLASHEraseSector(secIdx);
|
|||
|
|
|
|||
|
|
rslt = FlashWaitNoBusy(MAX_WAIT_TIME);
|
|||
|
|
if (rslt != STM32_FLASH_OK)
|
|||
|
|
{
|
|||
|
|
rslt = FLASHGetStatus();
|
|||
|
|
return rslt;
|
|||
|
|
}
|
|||
|
|
#if (__CORTEX_M == 0 || __CORTEX_M == 3)
|
|||
|
|
CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
|
|||
|
|
#elif (__CORTEX_M == 4)
|
|||
|
|
CLEAR_BIT(FLASH->CR, (FLASH_CR_SER | FLASH_CR_SNB));
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
return STM32_FLASH_OK;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//-----------------------------------------------
|
|||
|
|
|
|||
|
|
|
|||
|
|
void STMFlashUnlock()
|
|||
|
|
{
|
|||
|
|
FLASHUnlock();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void STMFlashLock()
|
|||
|
|
{
|
|||
|
|
FLASHLock();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int STMFlashErase(u32 secIdx, int secnums)
|
|||
|
|
{
|
|||
|
|
int rslt = 0;
|
|||
|
|
|
|||
|
|
FLASHUnlock();
|
|||
|
|
|
|||
|
|
for (int i = 0; i < secnums; i++)
|
|||
|
|
{
|
|||
|
|
rslt = FLASHEraseSectorProc(secIdx);
|
|||
|
|
if (rslt != STM32_FLASH_OK)
|
|||
|
|
{
|
|||
|
|
printf("STMFlashErase error, rslt=%d\r\n", rslt);
|
|||
|
|
rslt = -1;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
#if (0)
|
|||
|
|
if (STMFlashCheck(secIdx * STM32_FLASH_SEC_SIZE + STM32_FLASH_BASE, 0, STM32_FLASH_SEC_SIZE) != 0)
|
|||
|
|
{
|
|||
|
|
printf("STMFlashErase and STMFlashCheck err, \r\n");
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
secIdx++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FLASHLock(); // <20><><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
return rslt;
|
|||
|
|
}
|
|||
|
|
//-----------------------------------------------
|
|||
|
|
|
|||
|
|
// <20><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// rdAddr: <20><>ʼ<EFBFBD><CABC>ַ
|
|||
|
|
// pBuffer: <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
|
// hwNumOfRead: <20><><EFBFBD><EFBFBD>(16λ)<29><>
|
|||
|
|
int STMFlashRead(u32 rdAddr, u16 * pBuffer, u16 hwNumOfRead)
|
|||
|
|
{
|
|||
|
|
u16 i;
|
|||
|
|
if (pBuffer == NULL ||
|
|||
|
|
rdAddr < STM32_FLASH_BASE ||
|
|||
|
|
rdAddr + hwNumOfRead*2 > STM32_FLASH_BASE+STM32_FLASH_SIZE)
|
|||
|
|
{
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (i = 0; i < hwNumOfRead; i++)
|
|||
|
|
{
|
|||
|
|
*pBuffer = FlashRDHalfWord(rdAddr); // <20><>ȡ2<C8A1><32><EFBFBD>ֽ<EFBFBD>
|
|||
|
|
pBuffer++;
|
|||
|
|
rdAddr += 2; // <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>2
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼ<EFBFBD>Ƚ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>һ<EFBFBD><D2BB>
|
|||
|
|
// ckAddr: <20><>ʼ<EFBFBD><CABC>ַ
|
|||
|
|
// pBuffer: <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
|
// hwNumOfChekc: <20><><EFBFBD><EFBFBD>(16λ)<29><>
|
|||
|
|
// <20><><EFBFBD><EFBFBD>ֵ: 0, ȫ<><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
int STMFlashCheck(u32 ckAddr, u16 * pBuffer, u16 hwNumOfChekc)
|
|||
|
|
{
|
|||
|
|
int i;
|
|||
|
|
u16 tprd, tpdat;
|
|||
|
|
for(i = 0; i < hwNumOfChekc; i++)
|
|||
|
|
{
|
|||
|
|
tprd = FlashRDHalfWord(ckAddr); // <20><>ȡ2<C8A1><32><EFBFBD>ֽ<EFBFBD>
|
|||
|
|
if (pBuffer != NULL)
|
|||
|
|
{
|
|||
|
|
tpdat = *pBuffer;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
tpdat = 0xffff;
|
|||
|
|
}
|
|||
|
|
if (tpdat != tprd)
|
|||
|
|
{
|
|||
|
|
printf("STMFlashCheck error, tpdat=0x%x, tprd=0x%x, i=%d\r\n", tpdat, tprd, i);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (pBuffer != NULL)
|
|||
|
|
{
|
|||
|
|
pBuffer++;
|
|||
|
|
}
|
|||
|
|
ckAddr += 2; // <20><>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>2
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼд<CABC><D0B4>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// wrAddr: <20><>ʼ<EFBFBD><CABC>ַ(<28>˵<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>Ϊ2<CEAA>ı<EFBFBD><C4B1><EFBFBD>)
|
|||
|
|
// pBuffer: <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
|
// hwNumToWrite: <20><><EFBFBD><EFBFBD>(16λ)<29><>(<28><><EFBFBD><EFBFBD>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD>16λ<36><CEBB><EFBFBD>ݵĸ<DDB5><C4B8><EFBFBD>)
|
|||
|
|
// svwhenera == 0, <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// svwhenera == 1, <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// svwhenera == 2, <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
// svwhenera == 3, <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
// ʹ<><CAB9>sdram <20><>һ<EFBFBD>οռ䣨<D5BC><E4A3A8><EFBFBD><EFBFBD>128K<38><4B>
|
|||
|
|
|
|||
|
|
int STMFlashWrite(u32 wrAddr, u16 * pBuffer, u16 hwNumToWrite, int svwhenera)
|
|||
|
|
{
|
|||
|
|
int rslt;
|
|||
|
|
u16 * thiswrbuff;
|
|||
|
|
|
|||
|
|
u32 addr, addrEnd, thiswraddr;
|
|||
|
|
u32 wrlen, thiswrlen;
|
|||
|
|
int thissidx, thisslen;
|
|||
|
|
u32 thisaddr, thislen;
|
|||
|
|
|
|||
|
|
#if (NO_BUFF_WHEN_WT == 0)
|
|||
|
|
u32 i;
|
|||
|
|
|
|||
|
|
u16 tempbuf[STM32_FLASH_SEC_SIZE/2];
|
|||
|
|
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
addr = wrAddr;
|
|||
|
|
wrlen = hwNumToWrite * 2;
|
|||
|
|
addrEnd = wrAddr + wrlen;
|
|||
|
|
|
|||
|
|
if (wrAddr < STM32_FLASH_BASE || (addrEnd > (STM32_FLASH_BASE + STM32_FLASH_SIZE)))
|
|||
|
|
{
|
|||
|
|
return -1; // <20>Ƿ<EFBFBD><C7B7><EFBFBD>ַ
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FLASHUnlock(); // <20><><EFBFBD><EFBFBD>flash
|
|||
|
|
|
|||
|
|
//
|
|||
|
|
while (addr < addrEnd)
|
|||
|
|
{
|
|||
|
|
thisaddr = addr; // <20><>ʼ<EFBFBD><CABC>ַ
|
|||
|
|
|
|||
|
|
thissidx = GetFlashSectorIdx(thisaddr);
|
|||
|
|
thisslen = GetFlashSectorSize(thissidx);
|
|||
|
|
if (thissidx < 0 || thisslen <= 0)
|
|||
|
|
{
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
thislen = GetSecRemainSize(thisaddr); // ʣ<><EFBFBD><E0B3A4>
|
|||
|
|
if (thislen > wrlen)
|
|||
|
|
{
|
|||
|
|
thislen = wrlen;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
rslt = FlashWaitNoBusy(MAX_WAIT_TIME);
|
|||
|
|
if (rslt != STM32_FLASH_OK)
|
|||
|
|
{
|
|||
|
|
rslt = FLASHGetStatus();
|
|||
|
|
printf("STMFlashWrite error, FlashWaitNoBusy=%d\r\n", rslt);
|
|||
|
|
return rslt;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if (NO_BUFF_WHEN_WT == 0)
|
|||
|
|
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
|
STMFlashRead(thisaddr, tempbuf, thislen/2); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
for (i = 0; i < thislen/2; i++) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
#if (1) // st <20>ڲ<EFBFBD> flash <20><>֧<EFBFBD><D6A7>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>flash<73><68>ijЩ1λ<31><CEBB><EFBFBD><EFBFBD>0λ<30><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> flash֧<68>֣<EFBFBD>
|
|||
|
|
if (tempbuf[i] != 0xffff) // ֻҪ<D6BB><D2AA><EFBFBD><EFBFBD>ȫ1, <20>Ͳ<EFBFBD><CDB2><EFBFBD>
|
|||
|
|
#else
|
|||
|
|
if ((tempbuf[i] & pBuffer[i]) != pBuffer[i]) // <20><>֮<EFBFBD><EFBFBD>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
#endif
|
|||
|
|
{
|
|||
|
|
break; // <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (i < thislen/2) // <20><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
u32 secbegaddr;
|
|||
|
|
u8* wrbufaddr;
|
|||
|
|
|
|||
|
|
// printf("\r\nErase sector %d\r\n", thissidx);
|
|||
|
|
secbegaddr = GetFlashSectorBegAddr(thissidx);
|
|||
|
|
|
|||
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (thisaddr != secbegaddr || thislen != thisslen)
|
|||
|
|
{
|
|||
|
|
STMFlashRead(secbegaddr, tempbuf, thisslen/2);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
if (FLASHEraseSectorProc(thissidx) != STM32_FLASH_OK) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
printf("\r\nErase sector %d error\r\n", thissidx);
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// <20><><EFBFBD><EFBFBD>Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
wrbufaddr = (u8*)tempbuf;
|
|||
|
|
wrbufaddr += thisaddr-secbegaddr;
|
|||
|
|
memcpy(wrbufaddr, pBuffer, thislen);
|
|||
|
|
|
|||
|
|
if (svwhenera == 0) // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
thiswraddr = thisaddr;
|
|||
|
|
thiswrbuff = pBuffer;
|
|||
|
|
thiswrlen = thislen;
|
|||
|
|
}
|
|||
|
|
else if (svwhenera == 1) // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
thiswraddr = secbegaddr;
|
|||
|
|
thiswrbuff = tempbuf;
|
|||
|
|
thiswrlen = thislen + (thisaddr - secbegaddr);
|
|||
|
|
}
|
|||
|
|
else if (svwhenera == 2) // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
thiswraddr = thisaddr;
|
|||
|
|
thiswrbuff = (u16*)wrbufaddr;
|
|||
|
|
thiswrlen = thisslen - (thisaddr - secbegaddr);
|
|||
|
|
}
|
|||
|
|
else // if (svwhenera == 3) // <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
{
|
|||
|
|
thiswraddr = secbegaddr;
|
|||
|
|
thiswrbuff = tempbuf;
|
|||
|
|
thiswrlen = thisslen; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
#endif
|
|||
|
|
{
|
|||
|
|
thiswraddr = thisaddr;
|
|||
|
|
thiswrbuff = pBuffer;
|
|||
|
|
thiswrlen = thislen;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
STMFlashWrNoCheck(thiswraddr, thiswrbuff, thiswrlen / 2); // д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
pBuffer += thislen;
|
|||
|
|
addr += thislen;
|
|||
|
|
wrlen -= thislen;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FLASHLock(); // <20><><EFBFBD><EFBFBD>
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|