📄 flash.c
字号:
#include <prkernel.h>
#include <system/uart270.h>
#include <system/osd270.h>
#include "api/app_msg.h"
#include "api/file_mng.h"
#include "api/ui_msg.h"
#include "system_ver.h"
#include "api/file_cache.h"
#define ADDR555 0x0555
#define ADDR2AA 0x02aa
#define FILE_HEADER_SIZE 50
#define SEC_HEADER_SIZE 48
#define SYM_TABLE_SIZE 18
#define REL_ENTRY_SIZE 12
#define FLASH_CE 0x00100000
#define SZFLASH 0x00400000
typedef struct _COFF_HEADER
{
USHORT COFFVer;
USHORT nSection;
LONG Time;
LONG pSymbolTable;
LONG nSymbolTable;
LONG pStringTable;
LONG nStringTable;
USHORT nOpHeader;
USHORT HeaderFlag;
USHORT ID;
/* option header */
SHORT nMagic;
SHORT VerStamp;
LONG sExcutable;
LONG sInitial;
LONG sBSS;
LONG pEntry;
LONG StAddrEx;
LONG StAddrIni;
} COFF_HEADER;
typedef struct _SECTION_HEADER
{
CHAR SecName[64];
LONG SecPhyAddr;
LONG SecVirAddr;
LONG SecSize;
LONG pRawData;
LONG pRelEntry;
LONG pLineEntry;
ULONG nRelEntry;
ULONG nLineEntry;
ULONG SecFlag;
INT valid;
} SECTION_HEADER;
void CF_in(void);
void flash_write(USHORT *ce);
void SD_disable(void);
void printu(CHAR *pString, int nstr);
void disp_comp(int err);
COFF_HEADER fheader;
INT COFFCOPY = 0x01275000;
void fl_reset(USHORT *ce){
*ce = 0x00f0;
}
int erace_all(USHORT *ce){
int i;
USHORT dat;
fl_reset(ce);
for(i = 0; i < 1000; i++);
*(ce + ADDR555) = 0x00aa;
*(ce + ADDR2AA) = 0x0055;
*(ce + ADDR555) = 0x0080;
*(ce + ADDR555) = 0x00aa;
*(ce + ADDR2AA) = 0x0055;
*(ce + ADDR555) = 0x0010;
while(1){
dat = *ce;
if(dat == 0xffff){
for(i = 0; i < 5000; i++);
return 0;
}
if(dat & 0x20)
return -1;
}
}
#define RETRY 100
int fl_write(USHORT *src, USHORT *dst, int size)
{
USHORT *ce, dat1, dat2;
int i, j, k;
ce = (USHORT*)((INT)dst & 0xfff00000);
for(i = 0; i < size/2; i++){
*(ce + ADDR555) = 0x00aa;
*(ce + ADDR2AA) = 0x0055;
*(ce + ADDR555) = 0x00a0;
*dst = *src;
for(j = 0; j < RETRY; j++){
for(k= 0; k< 50; k++);
dat1 = *dst;
dat2 = *dst;
if((dat1 == *src) & (dat2 == *src))
break;
if((dat1 & 0x20) & (dat2 & 0x20))
return -1;
}
if(j < RETRY){
*src++;
*dst++;
}
else
i--;
}
return 0;
}
int fl_verify(USHORT *src, USHORT *dst, int size){
int i;
USHORT *ce;
ce = (USHORT*)((INT)dst & 0xfff00000);
for(i = 0; i < size/2; i++){
if(*src++ != *dst++)
return -1;
}
fl_reset(ce);
for(i = 0; i < 1000; i++);
return 0;
}
void GetCOFFHeader(UCHAR *coff, COFF_HEADER *header)
{
UCHAR *org;
org = coff;
header->COFFVer = *coff++ | *coff++ << 8;
header->nSection = *coff++ | *coff++ << 8;
header->Time = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->pSymbolTable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->nSymbolTable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->nOpHeader = *coff++ | *coff++ << 8;
header->HeaderFlag = *coff++ | *coff++ << 8;
header->ID = *coff++ | *coff++ << 8;
if(header->nOpHeader == 0x1c){
header->nMagic = *coff++ | *coff++ << 8;
header->VerStamp = *coff++ | *coff++ << 8;
header->sExcutable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->sInitial = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->sBSS = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->pEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->StAddrEx = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
header->StAddrIni = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
}
header->pStringTable = header->pSymbolTable + header->nSymbolTable * SYM_TABLE_SIZE;
coff = org + header->pStringTable;
header->nStringTable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
}
void GetSecHeader(UCHAR *coff, int secID, SECTION_HEADER *sheader)
{
int i;
ULONG pString;
UCHAR *org;
org = coff;
coff = org + (secID * SEC_HEADER_SIZE + FILE_HEADER_SIZE);
for(i = 0; i < 8; i++)
sheader->SecName[i] = *coff++;
sheader->SecName[i] = '0';
sheader->SecPhyAddr = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->SecVirAddr = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->SecSize = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->pRawData = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->pRelEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->pLineEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->nRelEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->nLineEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
sheader->SecFlag = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
if((LONG)sheader->SecName[0] == 0){
i = 0;
pString = (UCHAR)sheader->SecName[4] |
(UCHAR)sheader->SecName[5] << 8 |
(UCHAR)sheader->SecName[6] << 16 |
(UCHAR)sheader->SecName[7] << 24;
coff = org + (fheader.pStringTable + pString);
do{
sheader->SecName[i] = *coff++;
}while(sheader->SecName[i++] != 0);
}
sheader->valid = ((sheader->SecFlag & 0x0003) == 0) &
((sheader->SecFlag & 0x0060) != 0) &
((sheader->SecFlag & 0x0010) == 0) &
(sheader->SecSize != 0);
}
void ROM_Util(){
*(unsigned short*) VIDEOWIN_MODE = 0;
*(unsigned short*) SYNCEN = 0;
*(unsigned short*) PVEN = 0;
CF_in();
flash_write((USHORT*)FLASH_CE);
printu("Done", -1);
}
#define ROMCODE "B:\\system.out"
void CF_in(){
FILE *fp;
fp = fopen(ROMCODE, "r");
if(fp)
//DEV_UART_sendString(UART0,"Loading File OK\r\n");
printu("Loading File OK\r\n", -1);
else{
fclose(fp);
//DEV_UART_sendString(UART0,"File cannot open\r\n");
printu("File cannot open\r\n", -1);
while(1){};
}
fread((void*)COFFCOPY, 1, 0xffffffff, fp);
fclose(fp);
}
void flash_write(USHORT *ce){
INT err = 0;
SECTION_HEADER secheader;
int i;
USHORT *src, *dst;
WRITE_REGISTER_USHORT(ICA_MODE, 0);
GetCOFFHeader((UCHAR*)COFFCOPY, &fheader);
if(fheader.COFFVer != 0xc2){
//DEV_UART_sendString(UART0, "Invalid COFF File\r\n");
printu("Invalid COFF File\r\n", -1);
return;
}
if(fheader.ID != 0x97){
//DEV_UART_sendString(UART0, "This is not ARM COFF File\r\n");
printu("This is not ARM COFF File\r\n", -1);
return;
}
SD_disable();
// emif initialization
*(unsigned short*)CS0CTRL1 = 0x668a;
*(unsigned short*)CS3CTRL1 = 0x668a;
*(unsigned short*)CS4CTRL1 = 0x668a;
*(unsigned short*)CS0CTRL2 = 0x2442;
*(unsigned short*)CS3CTRL2 = 0x6442; // CS3 16-bit
*(unsigned short*)CS4CTRL2 = 0x6442; // CS4 16-bit
GetCOFFHeader((UCHAR*)COFFCOPY, &fheader);
// GUI_slideShowPanelClear();
// GUI_slideShowPanelReset();
// GUI_controlPanelMediaNameSet(" Erace....... ");
//DEV_UART_sendString(UART0,"Erace...Start\r\n");
printu("Erace...Start\r\n", -1);
err = erace_all(ce);
//DEV_UART_sendString(UART0,"Erace...End\r\n");
printu("Erace...End\r\n", -1);
disp_comp(err);
// GUI_slideShowPanelClear();
// GUI_slideShowPanelReset();
// GUI_controlPanelMediaNameSet(" Write....... ");
// LOOP # of SECTIONs
//DEV_UART_sendString(UART0,"Write...Start\r\n");
//DEV_UART_sendString(UART0,"Write.");
printu("Write...Start\r\n", -1);
printu("Write.", -1);
for(i = 0; i < fheader.nSection; i++){
GetSecHeader((UCHAR*)COFFCOPY, i, &secheader);
if(secheader.valid){
src = (USHORT*)(COFFCOPY + (ULONG)secheader.pRawData);
dst = (USHORT*)((ULONG)ce + (ULONG)secheader.SecVirAddr - FLASH_CE);
err |= fl_write(src, dst, secheader.SecSize);
}
//DEV_UART_sendString(UART0,".");
printu(".", -1);
}
//DEV_UART_sendString(UART0,"\r\n");
//DEV_UART_sendString(UART0,"Write...End\r\n");
printu("\r\n", -1);
printu("Write...End\r\n", -1);
disp_comp(err);
// GUI_slideShowPanelClear();
// GUI_slideShowPanelReset();
// GUI_controlPanelMediaNameSet(" Verify....... ");
//DEV_UART_sendString(UART0,"Verify...Start\r\n");
//DEV_UART_sendString(UART0,"Verify.");
printu("Verify...Start\r\n", -1);
printu("Verify.", -1);
for(i = 0; i < fheader.nSection; i++){
GetSecHeader((UCHAR*)COFFCOPY, i, &secheader);
if(secheader.valid){
src = (USHORT*)(COFFCOPY + (ULONG)secheader.pRawData);
dst = (USHORT*)((ULONG)ce + (ULONG)secheader.SecVirAddr - FLASH_CE);
err |= fl_verify(src, dst, secheader.SecSize);
}
//DEV_UART_sendString(UART0,".");
printu(".", -1);
}
//DEV_UART_sendString(UART0,"\r\n");
//DEV_UART_sendString(UART0,"Verify...End\r\n");
printu("\r\n", -1);
printu("Verify...End\r\n", -1);
disp_comp(err);
// GUI_slideShowPanelClear();
// GUI_slideShowPanelReset();
// GUI_controlPanelMediaNameSet(" Done ");
//DEV_UART_sendString(UART0,"Done...\r\n");
printu("Done...\r\n", -1);
while(1);
}
void printu(CHAR *pString, int nstr)
{
int i;
USHORT buf;
if(nstr == -1){
// until end of string
while (*pString) {
buf = (*(unsigned short*) SR0) & 0x1;
if(buf != 0)
*(unsigned short*) DTRR0 = *pString++;
}
}
else{
i = 0;
while(i < nstr){
buf = (*(unsigned short*) SR0) & 0x1;
if(buf != 0){
if(*pString)
*(unsigned short*) DTRR0 = *pString++;
else
*(unsigned short*) DTRR0 = ' ';
i++;
}
}
}
}
void SD_disable(void){
xdisable();
*(unsigned short*) EINT0 = 0x0000;
*(unsigned short*) EINT1 = 0x0000;
*(unsigned short*) EINT1 = 0x0000;
*(unsigned short*) VIDEOWIN_MODE = 0;
*(unsigned short*) SYNCEN = 0;
*(unsigned short*) PVEN = 0;
}
void disp_comp(int err){
if(!err){
// GUI_slideShowPanelClear();
// GUI_slideShowPanelReset();
// GUI_controlPanelMediaNameSet(" Complete... !!");
printu("Complete\r\n", -1);
//DEV_UART_sendString(UART0,"Complete...\r\n");
}
else{
// GUI_slideShowPanelClear();
// GUI_slideShowPanelReset();
// GUI_controlPanelMediaNameSet(" Error..shit !!");
//DEV_UART_sendString(UART0,"Error..shit\r\n");
printu("Error\r\n", -1);
while(1);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -