ztg0021
驱动小牛
驱动小牛
  • 注册日期2007-02-09
  • 最后登录2016-02-18
  • 粉丝1
  • 关注0
  • 积分141分
  • 威望223点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:3605回复:3

UBOOT+WINCE+2440的SD卡升级程序,WINCE的都可以

楼主#
更多 发布于:2010-03-05 22:01
自从我用了超级BOOT后这个就不用了,这种方式的优点就是简单
/************************************************************************/
/*    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;        
}
WINCE/EVC/VS2005群:18219722
ztg0021
驱动小牛
驱动小牛
  • 注册日期2007-02-09
  • 最后登录2016-02-18
  • 粉丝1
  • 关注0
  • 积分141分
  • 威望223点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-03-05 22:02
//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);
    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!=buf) {
                //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 =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();
}
WINCE/EVC/VS2005群:18219722
ztg0021
驱动小牛
驱动小牛
  • 注册日期2007-02-09
  • 最后登录2016-02-18
  • 粉丝1
  • 关注0
  • 积分141分
  • 威望223点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-03-05 22:19
论坛不如以前热闹了,出来活动一下
WINCE/EVC/VS2005群:18219722
lStoneCN
驱动牛犊
驱动牛犊
  • 注册日期2004-08-11
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分334分
  • 威望321点
  • 贡献值1点
  • 好评度28点
  • 原创分0分
  • 专家分0分
地板#
发布于:2010-03-11 20:42
这是一个MFC的程序吧?没有看到你的uboot ?
寻zigbee/CC2430高手合作!
游客

返回顶部