📄 flashhelper.c
字号:
#include "FlashHelper.h"
#include "gpio.h"
/* address offset of each sector in internal flash memory */
static const struct flash_sector_info {
u32 base, mask;
} FlashSectorInfo[] = {
{0x000000, FLASH_B0F0},
{0x002000, FLASH_B0F1},
{0x004000, FLASH_B0F2},
{0x006000, FLASH_B0F3},
{0x008000, FLASH_B0F4},
{0x010000, FLASH_B0F5},
{0x020000, FLASH_B0F6},
{0x030000, FLASH_B0F7},
{0x040000, ~0},
{0x0C0000, FLASH_B1F0},
{0x0C2000, FLASH_B1F1},
{0x0C4000, ~0},
{~0, ~0},
};
void Flash_Init(void)
{
FLASH_Init();
GPIO_Config(GPIO2, 0x001F, GPIO_AF_PP);
}
int IntFlash_Erase(u32 addr, u32 size)
{
const struct flash_sector_info *p;
u32 limit, mask;
addr -= INT_FLASH_BASE;
limit = addr + size;
p = FlashSectorInfo;
while(addr >= p[1].base)
p++;
mask = p->mask;
while(limit > p[1].base)
mask |= (++p)->mask;
if(mask == ~0)
return -1;
FLASH_WritePrConfig(mask, DISABLE);
FLASH_SectorErase(mask);
return 0;
}
int IntFlash_Program(u32 addr, const void *buf, u32 size)
{
const struct flash_sector_info *p;
u32 limit, mask;
addr -= INT_FLASH_BASE;
limit = addr + size;
p = FlashSectorInfo;
while(addr >= p[1].base)
p++;
mask = p->mask;
while(limit > p[1].base)
mask |= (++p)->mask;
if(mask == ~0)
return -1;
FLASH_WritePrConfig(mask, DISABLE);
FLASH_SectorErase(mask);
FLASH_BlockWrite((u32)buf, addr, size + 3 >> 2);
return 0;
}
#define FLASH_DATA(n) n /*( (n) >> 0 & 0x8000 | */ /* D15 -> D15 */
/* (n) >> 1 & 0x2000 | */ /* D14 -> D13 */
/* (n) >> 2 & 0x0800 | */ /* D13 -> D11 */
/* (n) >> 3 & 0x0200 | */ /* D12 -> D9 */
/* (n) >> 4 & 0x0080 | */ /* D11 -> D7 */
/* (n) >> 5 & 0x0020 | */ /* D10 -> D5 */
/* (n) >> 6 & 0x0008 | */ /* D9 -> D3 */
/* (n) >> 7 & 0x0002 | */ /* D8 -> D1 */
/* (n) << 7 & 0x4000 | */ /* D7 -> D14 */
/* (n) << 6 & 0x1000 | */ /* D6 -> D12 */
/* (n) << 5 & 0x0400 | */ /* D5 -> D10 */
/* (n) << 4 & 0x0100 | */ /* D4 -> D8 */
/* (n) << 3 & 0x0040 | */ /* D3 -> D6 */
/* (n) << 2 & 0x0010 | */ /* D2 -> D4 */
/* (n) << 1 & 0x0004 | */ /* D1 -> D2 */
/* (n) << 0 & 0x0001 ) */ /* D0 -> D0 */
#define FLASH_ADDR(a) ((vu16 *)(EXT_FLASH_BASE + ((a) << 1)))
#define FLASH_WRITE(addr, word) (*FLASH_ADDR(addr) = FLASH_DATA(word))
static void Check_Toggle_Ready(u32 addr)
{
int TimeOut;
int PreData = *FLASH_ADDR(addr) & FLASH_DATA(0x0040);
for(TimeOut = 0; TimeOut < 0x07FFFFFF; TimeOut++)
{
int CurData = *FLASH_ADDR(addr) & FLASH_DATA(0x0040);
if(PreData == CurData)
break;
PreData = CurData;
}
}
void ExtFlash_Command(u32 addr, u32 cmd)
{
FLASH_WRITE(addr, cmd);
}
void ExtFlash_ChipErase(void)
{
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x8080);
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x1010);
Check_Toggle_Ready(0);
}
int ExtFlash_SectorErase(u32 addr)
{
addr = addr - EXT_FLASH_BASE >> 1;
if(addr >= EXT_FLASH_SIZE)
return -1;
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x8080);
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(addr, 0x3030);
Check_Toggle_Ready(addr);
return 0;
}
int ExtFlash_BlockErase(u32 addr)
{
addr = addr - EXT_FLASH_BASE >> 1;
if(addr >= EXT_FLASH_SIZE)
return -1;
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x8080);
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(addr, 0x5050);
Check_Toggle_Ready(addr);
return 0;
}
int ExtFlash_WordWrite(u32 addr, u16 data)
{
vu16 *ptr = (vu16 *)addr;
addr = addr - EXT_FLASH_BASE >> 1;
if(addr >= EXT_FLASH_SIZE)
return -1;
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0xa0a0);
*ptr = data;
Check_Toggle_Ready(addr);
return *ptr;
}
int ExtFlash_Program(u32 addr, const void *buf, u32 size)
{
u32 i, limit = addr + size;
if(addr < EXT_FLASH_BASE || limit >= EXT_FLASH_LIMIT)
return -1;
for(i = addr & ~(SECTOR_SIZE - 1); i < limit; i += SECTOR_SIZE)
ExtFlash_SectorErase(i);
for(i = addr; i < limit; i += 2)
{
int PreData, TimeOut;
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0xa0a0);
*(vu16 *)i = *(u16 *)buf;
PreData = *(vu16 *)i & FLASH_DATA(0x0040);
for(TimeOut = 0; TimeOut < 0x07FFFFFF; TimeOut++)
{
int CurData = *(vu16 *)i & FLASH_DATA(0x0040);
if(PreData == CurData)
break;
PreData = CurData;
}
buf = (u16 *)buf + 1;
}
return 0;
}
/*******************************************************************************
* Function Name : FLASH_WriteBlock
* Description : Writes Data To the Flash
* Input 1 : Address of the Data source
* Input 2 : Address of the Destination
* Input 3 : Nbr of words to be stored
* Return : None
*******************************************************************************/
void FLASH_BlockWrite(u32 XsourceAdd, u32 XtargetAdd, u32 XdataLength)
{
u32 TmpAddrS, TmpAddrD;
u32 NbrW, NbrDW;
u32 TmpData0, TmpData1;
// Get The Source Address
TmpAddrS = XsourceAdd;
// Get The Destination Address
TmpAddrD = XtargetAdd;
// Get Number of Double Words
NbrDW = XdataLength >> 1;
// Get Number of single Words
NbrW = XdataLength & 0x00000001;
// Programming Double Words
while (NbrDW > 0)
{
// Get The First 32 bits
TmpData0 = *(u32 *)TmpAddrS;
// Increment The Source Address
TmpAddrS += 4;
// Get The Second 32 bits
TmpData1 = *(u32 *)TmpAddrS;
// Increment The Source Address
TmpAddrS += 4;
// Use The FLASH_DWordWrite function to program the 64 bits
FLASH_DWordWrite(TmpAddrD, TmpData0, TmpData1);
// Decrease number of Double word
NbrDW--;
// Increment The destination Address
TmpAddrD += 8;
// Waits for the data to be programmed
FLASH_Delay();
}
if (NbrW > 0)
{
// Get The First 32 bits
TmpData1 = *(u32 *)TmpAddrS;
// Use The FLASH_WordWrite function to program the 32 bits
FLASH_WordWrite(TmpAddrD, TmpData1);
// Waits for the data to be programmed
FLASH_Delay();
}
FLASH_WaitForLastTask();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -