/************************************************************************/
/* Copyright(c) ?, ? */
/* Created By ztg */
/* File: efDlg.cpp */
/* Ver: 1.0.1 */
/* Project: */
/* Description: */
/************************************************************************/
#include "stdafx.h"
#include "ef.h"
#include "efDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
volatile NANDreg *s2440NAND = (NANDreg *)NAND_BASE;
volatile CLKPWRreg *s2440CLKPWR = (CLKPWRreg *)CLKPWR_BASE;
//#define NFChipEn() (s2440NAND->rNFCONT &= ~(1<<1))
#define EnNandFlash() (s2440NAND->rNFCONT |= 1)
#define DsNandFlash() (s2440NAND->rNFCONT &= ~1)
#define NFChipEn() (s2440NAND->rNFCONT &= ~(1<<1))
#define NFChipDs() (s2440NAND->rNFCONT |= (1<<1))
#define InitEcc() (s2440NAND->rNFCONT |= (1<<4))
#define MEccUnlock() (s2440NAND->rNFCONT &= ~(1<<5))
#define MEccLock() (s2440NAND->rNFCONT |= (1<<5))
#define SEccUnlock() (s2440NAND->rNFCONT &= ~(1<<6))
#define SEccLock() (s2440NAND->rNFCONT |= (1<<6))
//#define WrNFDat8(dat) (s2440NAND->rNFDATA = (dat))//rNFDATA8
#define WrNFDat8(dat) (s2440NAND->rNFDATA8 = (dat))
//#define WrNFDat32(dat) (s2440NAND->rNFDATA = (dat))
//#define RdNFDat8() (s2440NAND->rNFDATA) //byte access//rNFDATA8
#define RdNFDat8() (s2440NAND->rNFDATA8) //byte access
//#define RdNFDat32() (s2440NAND->rNFDATA) //word access
#define WrNFCmd(cmd) (s2440NAND->rNFCMMD = (cmd))
#define WrNFAddr(addr) (s2440NAND->rNFADDR = (addr))
#define WrNFDat(dat) WrNFDat8(dat)
#define RdNFDat() RdNFDat8() //for 8 bit nand flash, use byte access
#define RdNFMEcc() (s2440NAND->rNFMECC0) //for 8 bit nand flash, only use NFMECC0
#define RdNFSEcc() (s2440NAND->rNFSECC) //for 8 bit nand flash, only use low 16 bits
#define RdNFStat() (s2440NAND->rNFSTAT)
#define NFIsBusy() (!(s2440NAND->rNFSTAT&1))
#define NFIsReady() (s2440NAND->rNFSTAT&1)
#define READCMD0 0
#define READCMD1 1
#define READCMD2 0x50
#define ERASECMD0 0x60
#define ERASECMD1 0xd0
#define PROGCMD0 0x80
#define PROGCMD1 0x10
#define QUERYCMD 0x70
#define RdIDCMD 0x90
static U16 NandAddr;
// CefDlg 对话框
CefDlg::CefDlg(CWnd* pParent /*=NULL*/)
: CDialog(CefDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CefDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CefDlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_UpData, &CefDlg::OnBnClickedUpdata)
ON_BN_CLICKED(IDC_BUTTON1, &CefDlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_UpDateWINCE, &CefDlg::OnBnClickedUpdatewince)
ON_BN_CLICKED(IDOK, &CefDlg::OnBnClickedOk)
ON_BN_CLICKED(IDC_AUTO, &CefDlg::OnBnClickedAuto)
END_MESSAGE_MAP()
// CefDlg 消息处理程序
CProgressCtrl myCtrl;
BOOL CefDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
this->SetWindowPos(&CWnd::wndBottom, 0, 0, 315, 190,SWP_SHOWWINDOW);
this->SetWindowText(_T("UpData"));
CenterWindow(GetDesktopWindow()); // center to the hpc screen
volatile NANDreg *s2440NAND = (NANDreg *)NAND_BASE;
volatile CLKPWRreg *s2440CLKPWR = (CLKPWRreg *)CLKPWR_BASE;
s2440NAND = (volatile NANDreg *)VirtualAlloc(0, sizeof(NANDreg), MEM_RESERVE, PAGE_NOACCESS);
s2440CLKPWR = (volatile CLKPWRreg *)VirtualAlloc(0, sizeof(CLKPWRreg), MEM_RESERVE, PAGE_NOACCESS);
InitNandFlash(1);
//VirtualFree((PVOID) s2440NAND, 0, MEM_RELEASE);
//VirtualFree((PVOID) s2440CLKPWR, 0, MEM_RELEASE);
myCtrl.Create(WS_CHILD|WS_VISIBLE,CRect(10,90,303,110),this,1);
// TODO: 在此添加额外的初始化代码
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CefDlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
DRA::RelayoutDialog(
AfxGetInstanceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_EF_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_EF_DIALOG));
}
#endif
int pri=1;
void CefDlg::OnBnClickedButton1()//update bootloader
{
// TODO: 在此添加控件通知处理程序代码
WrFileToNF(0);
s2440NAND->rNFCONT &= ~1; //disable nand flash interface
AfxMessageBox(L"UpDate BootLoader Ok");
myCtrl.SetPos(0);
}
void CefDlg::OnBnClickedUpdatewince()//update wince
{
// TODO: 在此添加控件通知处理程序代码
WrFileToNF(1);
s2440NAND->rNFCONT &= ~1; //disable nand flash interface
AfxMessageBox(L"UpDate Wince Ok");
myCtrl.SetPos(0);
}
void CefDlg::OnBnClickedUpdata()//update logo
{
WrFileToNF(2);
s2440NAND->rNFCONT &= ~1; //disable nand flash interface
AfxMessageBox(L"UpDate Logo Ok");
myCtrl.SetPos(0);
}
/************************************************************/
static int have_nandflash;
void InitNandFlash(int info)
{
U32 i;
//RETAILMSG(1, (_T("SALCD2: DisplayInit: can't open '%s'/r/n"), gszBaseInstance));
//RETAILMSG(1, (_T("NandFlash Init+/r/n")));
InitNandCfg();
i = ReadChipId();//Read chip id = ec76
//if(info)
//RETAILMSG(1, (_T("Read chip id = %x/n"), i));
if((i==0x9873)||(i==0xec75))
NandAddr = 0;
else if(i==0xec76)
NandAddr = 1;
else {
if(info)
//puts("Chip id error!!!/n");
have_nandflash = 0;
return;
}
have_nandflash = 1;
//if(info)
//RETAILMSG(1, (_T("Nand flash status = %x/n"), ReadStatus()));
}
static void InitNandCfg(void)
{
s2440CLKPWR->rCLKCON |= (1<<4);
s2440NAND->rNFCONF = (0<<12)|(6<<8)|(0<<4)|(0<<0);
s2440NAND->rNFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
s2440NAND->rNFSTAT = 0;
}
static U32 ReadChipId(void)
{
U32 id;
NFChipEn();
WrNFCmd(RdIDCMD);
WrNFAddr(0);
while(NFIsBusy());
id = RdNFDat()<<8;
id |= RdNFDat();
NFChipDs();
return id;
}
static U16 ReadStatus(void)
{
U16 stat;
NFChipEn();
WrNFCmd(QUERYCMD);
stat = RdNFDat();
NFChipDs();
return stat;
}
//0xAEC00000
U32 downloadAddress=0xAE200000, downloadFileSize=0x0;//(B0000000-AE00000=2000000~~~32M)
static U32 StartPage1;
static U32 BlockCnt;
static int NandSelPart(int update)
{
// U16 i, max_sel;
struct Partition *ptr = NandPart;
if(0==update)
{
//printf("Write to nand flash part_3: offset 0x%-8x, size 0x%-8x [%s]/n", ptr->offset, ptr->size, ptr->name);
StartPage1 = NandPart[0].offset>>9;
BlockCnt = NandPart[0].size>>14;
return 0;
}
if(1==update)
{
ptr+=1;
//printf("Write to nand flash part_3: offset 0x%-8x, size 0x%-8x [%s]/n", ptr->offset, ptr->size, ptr->name);
StartPage1 = NandPart[1].offset>>9;
BlockCnt = NandPart[1].size>>14;
return 1;
}
if(2==update)
{
ptr+=3;
//printf("Write to nand flash part_3: offset 0x%-8x, size 0x%-8x [%s]/n", ptr->offset, ptr->size, ptr->name);
StartPage1 = NandPart[3].offset>>9;
BlockCnt = NandPart[3].size>>14;
return 3;
}
return -1;
}
//update:0--Update bootloader
//update:1--Update WINCE
//update:2--Update LOGO
void WrFileToNF(int update)
{
int nf_part, i ,size, skip_blks;
int retval;
U32 ram_addr;
char cpath[80];
char* szFilePath;
nf_part = NandSelPart(update);
if(nf_part<0)
return;
if(0==update)
{
szFilePath = "//SDMEM//UpData//Uboot.bin/0";
myCtrl.SetRange(1,10);
}
if(1==update)
{
szFilePath = "//SDMEM//UpData//NK.nb0/0";
myCtrl.SetRange(1,293);
}
if(2==update)
{
szFilePath = "//SDMEM//UpData//LOGO480234.bin/0";
myCtrl.SetRange(1,10);
}
//downloadFileSize=NandPart[nf_part].size -= 32<<9;;
downloadFileSize=NandPart[nf_part].size -= 32<<9;;
strcpy(cpath,szFilePath);
FILE * fp1;
fp1 = fopen(cpath, "rb" );
if(!fp1)
{
//printf("fopen flase[%x]/n",fp1);
AfxMessageBox(L"fopen flase");
return;
}
retval = fread((void*)downloadAddress, 1 , downloadFileSize, fp1);
fclose(fp1);
if(downloadFileSize>NandPart[nf_part].size) {
//puts("Download file size is more large than selected partition size!!!/n");
;//return;
}
//printf("Now write nand flash page 0x%x from ram address 0x%x, filesize = %d/n", StartPage1, downloadAddress, downloadFileSize);
skip_blks = 0;
ram_addr = downloadAddress;
size = downloadFileSize;//0x187b6e0;//
//printf("size=[%d],part[%d]/n",size,nf_part);
for(i=0; size>0; ) {
if(!(i&0x1f)) {
if(EraseBlock(i+StartPage1)) {
NandPart[nf_part].size -= 32<<9; //partition available size - 1 block size
if(downloadFileSize>NandPart[nf_part].size) {
//puts("Program nand flash fail/n");
;//return;
}
MarkBadBlk(i+StartPage1);
skip_blks++;
i += 32;
continue;
}
}
//*
if(WritePage(i+StartPage1, (U8 *)ram_addr)) {
ram_addr -= (i&0x1f)<<9;
size += (i&0x1f)<<9;
i &= ~0x1f;
NandPart[nf_part].size -= 32<<9; //partition available size - 1 block size
if(downloadFileSize>NandPart[nf_part].size) {
//puts("Program nand flash fail/n");
;//return;
}
MarkBadBlk(i+StartPage1);
skip_blks++;
i += 32;
continue;
}
//*/
ram_addr += 512;
size -= 512;
i++;
}
//puts("Program nand flash partition success/n");
//if(skip_blks)
//printf("Skiped %d bad block(s)/n", skip_blks);
}
static U32 EraseBlock(U32 addr)
{
U8 stat;
//printf("EraseBlock+/n");
addr &= ~0x1f;
NFChipEn();
WrNFCmd(ERASECMD0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
if(NandAddr)
WrNFAddr(addr>>16);
WrNFCmd(ERASECMD1);
stat = WaitNFBusy();
NFChipDs();
//putch(".");
//printf(".");
pri++;
if(pri>290)pri=1;
{
myCtrl.SetPos(pri);
//Sleep(10);
}
//printf("Erase block 0x%x %s/n", addr, stat?"fail":"ok");
//printf("EraseBlock-/n");
return stat;
}
static U32 WaitNFBusy(void) // R/B 未接好?
{
U8 stat;
WrNFCmd(QUERYCMD);
do {
stat = RdNFDat();
//printf("%x/n", stat);
}while(!(stat&0x40));
WrNFCmd(READCMD0);
return stat&1;
}
static U32 WritePage(U32 addr, U8 *buf)
{
U32 i, mecc;
U8 stat, tmp[7];
//volatile NANDreg *s2440NAND= (NANDreg *)NAND_BASE; ;
//printf("WritePage+/n");
NFChipEn();
WrNFCmd(PROGCMD0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
//printf("WritePage+1/n");
if(NandAddr)
WrNFAddr(addr>>16);
InitEcc(); //reset mecc and secc
MEccUnlock();
//printf("WritePage+2/n");
for(i=0; i<512; i++)
WrNFDat((U32)buf[i]);
MEccLock();
mecc = RdNFMEcc();
tmp[0] = mecc&0xff;
tmp[1] = (mecc>>8)&0xff;
tmp[2] = (mecc>>16)&0xff;
tmp[3] = (mecc>>24)&0xff;
tmp[5] = 0xff; //mark good block
//printf("WritePage+3/n");
SEccUnlock();
WrNFDat(tmp[0]);
WrNFDat(tmp[1]);
WrNFDat(tmp[2]);
WrNFDat(tmp[3]);
SEccLock();
WrNFDat(tmp[4]);
WrNFDat(tmp[5]);
WrNFCmd(PROGCMD1);
stat = WaitNFBusy();
NFChipDs();
if(stat)
//printf("Write nand flash 0x%x fail/n", addr);
AfxMessageBox(L"Write nand flash 0x%x fail");
else {
U8 RdDat[512];
ReadPage(addr, RdDat);
for(i=0; i<512; i++)
if(RdDat[i]!=buf[i]) {
//printf("Check data at page 0x%x, offset 0x%x fail/n", addr, i);
stat = 1;
break;
}
}
//printf("WritePage-/n");
return stat;
}
//addr = page address
static void ReadPage(U32 addr, U8 *buf)
{
U16 i;
//printf("ReadPage+/n");
NFChipEn();
WrNFCmd(READCMD0);
WrNFAddr(0);
WrNFAddr(addr);
WrNFAddr(addr>>8);
if(NandAddr)
WrNFAddr(addr>>16);
InitEcc();
WaitNFBusy();
//printf("ReadPage++/n");
for(i=0; i<512; i++)
{
buf[i] =RdNFDat();
}
NFChipDs();
//printf("ReadPage-");
}
static void MarkBadBlk(U32 addr)
{
addr &= ~0x1f;
NFChipEn();
WrNFCmd(READCMD2); //point to area c
WrNFCmd(PROGCMD0);
WrNFAddr(4); //mark offset 4,5,6,7
WrNFAddr(addr);
WrNFAddr(addr>>8);
if(NandAddr)
WrNFAddr(addr>>16);
WrNFDat(0); //mark with 0
WrNFDat(0);
WrNFDat(0); //mark with 0
WrNFDat(0);
WrNFCmd(PROGCMD1);
WaitNFBusy(); //needn't check return status
WrNFCmd(READCMD0); //point to area a
NFChipDs();
}
void CefDlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
}
void CefDlg::OnBnClickedAuto()
{
// TODO: 在此添加控件通知处理程序代码
WrFileToNF(0);
myCtrl.SetPos(0);
WrFileToNF(1);
myCtrl.SetPos(0);
WrFileToNF(2);
VirtualFree((PVOID) s2440NAND, 0, MEM_RELEASE);
VirtualFree((PVOID) s2440CLKPWR, 0, MEM_RELEASE);
AfxMessageBox(L"UpDate Ok");
myCtrl.SetPos(0);
}
void CefDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
OnOK();
}