新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > S3C2440-Nandflash

        S3C2440-Nandflash

        作者: 時間:2016-12-02 來源:網絡 收藏
        void NF_Init(){
        //GPA 17~22接在nandflash上
        rGPACON = rGPACON & ("(0x3f<<17)) | (0x3f<<17);
        //TACLS為CLE/ALE有效到nWE有效之間的持續時間,TWRPH0為nWE的有效持續時間,TWRPH1為nWE無效到CLE/ALE無效之間的持續時間,這些時間都是以HCLK為單位的(本文程序中的HCLK=100MHz)
        rNFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
        //非鎖定,屏蔽nandflash中斷,初始化ECC及鎖定main區和spare區ECC,使能nandflash片選及控制器
        rNFCONT = (0<<13)|(0<<12)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
        }
        void NF_Reset(){
        NF_CE_L();
        NF_WAITRB();
        NF_CMMD(CMD_RESET);
        NF_DETECT();
        NF_CE_H();
        }
        void NF_ReadID(){
        char MID, DID, cyc3, cyc4, cyc5;
        NF_CE_L();
        NF_CLEARRB();
        NF_CMMD(CMD_READID);
        NF_ADDR(0x00);
        MID = NF_RDDATA8(); //廠商ID
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = MID;
        DID = NF_RDDATA8(); //設備ID
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = DID;
        cyc3 = NF_RDDATA8(); //其他信息
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = cyc3;
        cyc4 = NF_RDDATA8();
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = cyc4;
        cyc5 = NF_RDDATA8();
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = cyc5;
        NF_CE_H();
        }
        U8 NF_RandomWrite(U32 pagenumber, U32 add, U8 data){ //根據時序來就行
        U8 state;
        NF_CE_L();
        NF_CMMD(CMD_WRITE1);
        NF_ADDR(0x00);
        NF_ADDR(0x00);
        NF_ADDR(pagenumber&0xff);
        NF_ADDR((pagenumber>>8)&0xff);
        NF_ADDR((pagenumber>>16)&0xff);
        NF_CMMD(CMD_RANDOMWRITE);
        NF_ADDR(add&0xff); //確定頁內地址
        NF_ADDR((add>>8)&0xff);
        NF_WRDATA8(data); //寫數據
        NF_CMMD(CMD_WRITE2);
        NF_WAITRB();
        NF_CMMD(CMD_READSTATE);
        do{
        state = NF_RDDATA8();
        }while(!(state&0x40));
        if(state&0x1){
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0x44;
        return 0x44; //0x44隨機寫失敗
        }
        else{
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0x66;
        return 0x66; //0x66隨機寫成功
        }
        }
        U8 NF_RandomRead(U32 pagenumber, U32 add){ //根據時序來就行
        char ch;
        NF_CE_L();
        NF_CMMD(CMD_READ1);
        NF_ADDR(0x00);
        NF_ADDR(0x00);
        NF_ADDR(pagenumber&0xff);
        NF_ADDR((pagenumber>>8)&0xff);
        NF_ADDR((pagenumber>>16)&0xff);
        NF_CMMD(CMD_READ2);
        NF_WAITRB();
        NF_CMMD(CMD_RANDOMREAD1);
        NF_ADDR(add&0xff);
        NF_ADDR((add>>8)&0xff);
        NF_CMMD(CMD_RANDOMREAD2);
        ch = NF_RDDATA8(); //讀數據
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = ch;
        NF_CE_H();
        return ch;
        }
        U8 NF_IsBadBlock(U32 block){
        U8 result;
        result = NF_RandomRead(block*64, 2054); //0"2047是main區數據,2048"2051是main區的ECC校驗,2052"2053是spare區的ECC校驗
        if(result == 0x33){
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0x62;
        return 0x62; //0x62是壞塊
        }
        else{
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0x42;
        return 0x42; //0x42不是壞塊
        }
        }
        U8 NF_MarkBadblock(U32 block){
        U8 result;
        result = NF_RandomWrite(block*64, 2054, 0x33); //0x33標記壞塊 block*64得到的是block塊第一個頁的地址
        if(result == 0x66){
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0x61;
        return 0x61; //0x61標記壞塊成功
        }
        else{
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0x41;
        return 0x41; //0x41標記壞塊失敗
        }
        }
        void __irq UART0_ISR(void){
        U8 ch;
        rSRCPND |= (0x1<<28);
        rINTPND |= (0x1<<28);
        rSUBSRCPND |= 0x1<<0;
        if(rUTRSTAT0 & 0x1){
        ch = rURXH0;
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = ch;
        cmd = ch;
        }
        }
        int Main(){
        count = 0;
        rULCON0 = 0x3;
        rUCON0 = (1<<11)|(1<<2)|(1<<0);
        rUBRDIV0 = 26;
        rSRCPND = 0x1<<28;
        rINTPND = 0x1<<28;
        rSUBSRCPND = 0x1<<0;
        rINTMSK &= "(0x1<<28);
        rINTSUBMSK &= "(0x1<<0);
        pISR_UART0 = (U32)UART0_ISR;
        NF_Init();
        while(1){
        switch(cmd){
        case 0x11:
        NF_Reset();
        break;
        case 0x22:
        NF_ReadID();
        break;
        case 0x33:
        NF_RandomRead(2001*64,0x3);
        break;
        case 0x44:
        NF_RandomWrite(2001*64,2052,0xbc);
        break;
        case 0x55:
        NF_PageRead(2001*64);
        break;
        case 0x66:
        while(!(rUTRSTAT0&0x4));
        rUTXH0 = 0xba;
        NF_PageWrite(2001*64);
        break;
        case 0x77:
        NF_BlockErase(2001);
        break;
        case 0x88:
        NF_IsBadBlock(2001);
        break;
        case 0x99:
        NF_MarkBadblock(2001);
        break;
        }
        cmd = 0;
        }
        return 0;
        }
        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 房山区| 边坝县| 平武县| 郯城县| 孝义市| 广东省| 吉安县| 凤庆县| 云霄县| 左权县| 中山市| 万宁市| 太保市| 临澧县| 三台县| 鹤峰县| 沈丘县| 孝昌县| 吴江市| 平泉县| 大关县| 龙岩市| 钟祥市| 巴林右旗| 花莲市| 靖边县| 东兴市| 衡阳市| 墨竹工卡县| 门头沟区| 绿春县| 安徽省| 库尔勒市| 东乡族自治县| 湘潭县| 凯里市| 普陀区| 凌云县| 衡阳县| 庆云县| 南充市|