flash.c
字号:
/*
**************************************************************************************************
*
*
*
*
*
*
*
*
*************************************************************************************************
*/
#include "../inc/s4510b.h"
#include "..inc/serial.h"
#include "../inc/flash.h"
#include "../inc/brd.h"
typedef struct {
INT16U * start;
const INT32U size;
} sector_t;
typedef struct {
const char * name;
const INT32S manufactor;
const INT32S device_id;
volatile INT16U * CMD_ADDR0;
volatile INT16U * CMD_ADDR1;
sector_t sector[6];
} flashTpye;
flashTpye flash_list[] = {
{
"SST39VF160",
0xbf,
0x2782,
(volatile INT16U *)(ROM_BASE + 0x5555*2),
(volatile INT16U *)(ROM_BASE + 0x2aaa*2),
{
{(INT16U *)(ROM_BASE + 0x000000), 0x1000},
{(INT16U *)(ROM_BASE + 0x200000), 0}
}
},
{
"SST39VF1601",
0xbf,
0x234B,
(volatile INT16U *)(ROM_BASE + 0x5555*2),
(volatile INT16U *)(ROM_BASE + 0x2aaa*2),
{
{(INT16U *)ROM_BASE + 0x000000, 0x1000},
{(INT16U *)ROM_BASE + 0x200000, 0}
}
},
{
"MX29LV160T",
0xc2,
0x22c4,
(volatile INT16U *)(ROM_BASE + 0x555*2),
(volatile INT16U *)(ROM_BASE + 0x2aa*2),
{
{ (INT16U *)ROM_BASE + 0x000000, 0x10000 },
{ (INT16U *)ROM_BASE + 0x1f0000, 0x8000 },
{ (INT16U *)ROM_BASE + 0x1f8000, 0x2000 },
{ (INT16U *)ROM_BASE + 0x1fa000, 0x2000 },
{ (INT16U *)ROM_BASE + 0x1fc000, 0x4000 },
{ (INT16U *)ROM_BASE + 0x200000, 0 }
}
},
{
"MX29LV160B",
0xc2,
0x2249,
(volatile INT16U *)(ROM_BASE + 0x555*2),
(volatile INT16U *)(ROM_BASE + 0x2aa*2),
{
{ (INT16U *)ROM_BASE + 0x000000, 0x4000 },
{ (INT16U *)ROM_BASE + 0x004000, 0x2000 },
{ (INT16U *)ROM_BASE + 0x006000, 0x2000 },
{ (INT16U *)ROM_BASE + 0x008000, 0x8000 },
{ (INT16U *)ROM_BASE + 0x010000, 0x10000 },
{ (INT16U *)ROM_BASE + 0x200000, 0 }
}
}
};
flashTpye * currentFlash;
flashTpye * flash_probe()
{
INT32S tmp, i;
for (i=0; i<sizeof(flash_list)/sizeof(flash_list[0]); i++) {
currentFlash = flash_list + i;
*currentFlash->CMD_ADDR0 = 0xaaaa;
*currentFlash->CMD_ADDR1 = 0x5555;
*currentFlash->CMD_ADDR0 = 0x9090;
tmp = *(INT16U *)ROM_BASE; /*modified by hojin*/
if (tmp == currentFlash->manufactor) {
tmp = *(INT16U *)(ROM_BASE + 2); /*modified by hojin*/
*currentFlash->CMD_ADDR0 = 0xf0f0;
if (tmp == currentFlash->device_id)
break;
}
}
if (i == sizeof(flash_list)/sizeof(flash_list[0]))
currentFlash = 0;
return currentFlash;
}
INT32S flash_erase(volatile INT16U * addr)
{
INT32S count = 5000000;
if (!currentFlash)
return 0;
*currentFlash->CMD_ADDR0 = 0xaaaa;
*currentFlash->CMD_ADDR1 = 0x5555;
*currentFlash->CMD_ADDR0 = 0x8080;
*currentFlash->CMD_ADDR0 = 0xaaaa;
*currentFlash->CMD_ADDR1 = 0x5555;
*addr = 0x3030;
while (--count && ((*addr & 0xff) != 0xff));
return count;
}
INT32S flash_write(volatile INT16U * addr, const INT16U * data, INT32U len)
{
INT32S count;
register INT16U tmp, tmp2;
if (!currentFlash)
return 0;
len = (len+1)/2;
while (len--) {
tmp = *data;
*currentFlash->CMD_ADDR0 = 0xaaaa;
*currentFlash->CMD_ADDR1 = 0x5555;
*currentFlash->CMD_ADDR0 = 0xa0a0;
*addr = tmp;
count = 10000;
while (--count && ((tmp2=*addr) != tmp));
if (count == 0)
break;
addr++;
data++;
}
if (count == 0)
urtPrintf("Failed @ 0x%06x, req: 0x%04x, act: 0x%04x, now: 0x%04x\n", addr, (unsigned)*data, (unsigned)tmp2, (unsigned)*addr);
return count;
}
/******************************************************************************
【功能说明】获取Falsh的ID号
******************************************************************************/
INT32U GetFlashID(void)
{
flashTpye * flash;
flash = flash_probe();
if (flash) {
urtPrintf("FLASH Type: %s\n", flash->name);
return (flash->manufactor<<16 | flash->device_id);
}
urtPrintf("Unsupported Flash, ID=0x%08x!\n", flash->manufactor<<16 | flash->device_id);
return 0;
}
/******************************************************************************
【功能说明】从Flash指定地址Readstart开始读取Size个数据到DataPtr
******************************************************************************/
void FlashRead(INT32U ReadStart, INT16U *DataPtr, INT32U Size)
{
INT32S i;
for(i=0; i<Size/2; i++)
DataPtr[i] = ((INT16U *)ReadStart)[i];
}
/******************************************************************************
[Function:] write size data from (*data) to (beging) sector.
note: beginning sectors.
******************************************************************************/
INT32S SectorProg(INT32U begin, INT16U *data, INT32U size)
{
INT32U i, actual_size,tempSize;
urtPrintf("\n Complete");
tempSize = size;
while (size) {
for (i=0; ; i++) {
if (currentFlash->sector[i].size == 0)
return FAIL;
if ((INT32U)currentFlash->sector[i+1].start > begin)
break;
}
if (begin % currentFlash->sector[i].size) {
urtPrintf("Unaligned sector, ignored!\n");
return FAIL;
}
if (size < currentFlash->sector[i].size)
actual_size = size;
else
actual_size = currentFlash->sector[i].size;
/* urtPrintf("Flash Erase 0x%06x ", begin); */
if (flash_erase((INT16U *)begin)){
/* urtPrintf("OK!\n"); */}
else {
urtPrintf("Erase Failed!\n");
return FAIL;
}
/* urtPrintf("Flash Burn 0x%06x ", begin); */
if (flash_write((INT16U *)begin, data, actual_size)){
/* urtPrintf("OK!\n"); */}
else {
urtPrintf("Write Failed!\n");
return FAIL;
}
begin += currentFlash->sector[i].size;
data += currentFlash->sector[i].size/2;
size -= actual_size;
urtPrintf("\r%3d%%",(100-((size *100)/tempSize)) );
}
urtPrintf("\n");
return PASS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -