기존 이솝 임베디드 포럼의 지식인 서비스가 게시판 형태로 변경되었습니다.



필립스 ARM7 칩으로
K9F1G08U0A PCB0를 제어하려고 합니다.

며칠 삽질한 끝에 READID는 했습니다.

void Cmd_Flash(byte cmd)                        //command
{  
        IO1CLR |= FL_WE;
        IO1SET |= FL_CLE;        
        IO1CLR |= FL_ALE;
        IO1SET |= FL_RE;
        delay(1);

        IO0CLR |= 0x00FF0000;
        IO0SET |= (cmd << 16);
        delay(1);
          
        IO1SET |= FL_WE;
        IO1CLR |= FL_CLE;
}

void Adr_Flash(byte adr)                        //address
{        
        IO1CLR |= FL_WE;
        IO1CLR |= FL_CLE;        
        IO1SET |= FL_ALE;
        IO1SET |= FL_RE;
        delay(1);

        IO0CLR |= 0x00FF0000;
        IO0SET |= (adr << 16);
        delay(1);

        IO1SET |= FL_WE;                        
}

dword read_id()
{
        중략....

        IO0CLR |= 0x00FF0000;
        IO1CLR |= FL_CE;                        //flash 활성화  
                          
        Cmd_Flash(0x90);                        //read명령어
        Adr_Flash(0x0);                                //주소                  

        IO0DIR = 0x0700BCF8;                        //IO를 입력으로
                                                //데이터IO는 16-23핀 입니다.
        delay(60);                                //10usec delay        

        IO1CLR |= FL_ALE;

        IO1CLR |= FL_RE;
        m_inpin32 = IO0PIN;                        //IO read
        m_inpin32 = m_inpin32 & 0x00FF0000;                          
        m_inpin16 = m_inpin32 >> 16;
        m_maker = (byte)m_inpin16;                //maker
        IO1SET |= FL_RE;

        IO1CLR |= FL_RE;
        m_inpin32 = IO0PIN;
        m_inpin32 = m_inpin32 & 0x00FF0000;                
        m_inpin16 = m_inpin32 >> 16;
        m_device = (byte)m_inpin16;                //device         
        IO1SET |= FL_RE;  
        
        IO1CLR |= FL_RE;
        m_inpin32 = IO0PIN;
        m_inpin32 = m_inpin32 & 0x00FF0000;                
        m_inpin16 = m_inpin32 >> 16;
        m_spec = (byte)m_inpin16;                //의미없는 데이터
        IO1SET |= FL_RE;
        
        IO1CLR |= FL_RE;
        m_inpin32 = IO0PIN;
        m_inpin32 = m_inpin32 & 0x00FF0000;        
        m_inpin16 = m_inpin32 >> 16;
        m_spec = (byte)m_inpin16;                //spec
        IO1SET |= FL_RE;

        IO1SET |= FL_CE;

        ret_data = (m_maker << 16) + (m_device << 8) + m_spec;
        return ret_data;
}

하니깐

EC F1 15
삼성 , 1G , 나머지정보
를 리턴했습니다.        

그런데

read data는 되는것같은데
erase block
write data
가 되지 않습니다.



byte Read_Flash(word ulColumn , word ulRow)
{  
        word count;
        byte pucData[2048];
        dword m_inpin32;
        word m_inpin16;
        
        for(count=0; count<2048; count++)                        //1page가 2048byte 입니다.
        {        
                pucData[count] = 0;        
        }        
        
        IO0CLR |= 0x00FF0000;                
        IO1CLR |= FL_CE;                                        //flash enable

        Cmd_Flash(0x0);                                                //read 명령어1
        Adr_Flash((unsigned char)(ulColumn & 0xff));                // column address
        Adr_Flash((unsigned char)((ulColumn >> 8 ) & 0x0f));         // column address
        Adr_Flash((unsigned char)(ulRow & 0xff));                // row address
        Adr_Flash((unsigned char)((ulRow >> 8) & 0xff));        // row address        
        Cmd_Flash(0x30);                                          //read 명령어2
        
        NANDWaitTilNotBusy();                                        //다읽을때까지 기다림.

        IO0CLR = 0x00FF0000;
        IO0DIR = 0x0700BCF8;                                        //IO를 입력으로                

        IO1CLR |= FL_CLE;
        IO1CLR |= FL_ALE;
        IO1CLR |= FL_RE;
        IO1SET |= FL_WE;

        for(count=0; count<2048; count++)                        // 2048byte 읽기
        {
                IO1SET |= FL_RE;
                delay(1);
                m_inpin32 = IO0PIN;
                m_inpin32 = m_inpin32 & 0x00FF0000;                          
                m_inpin16 = m_inpin32 >> 16;
                pucData[count] = (byte)m_inpin16;
                IO1CLR |= FL_RE;         
        }

        IO0DIR = 0x07FFBCF8;                                        //다시 IO를 출력으로                
        IO1SET |= FL_CE;                                         //flash disable

        return 0x1;  
}
모두 FF를 리턴합니다.

byte Erase_Flash(word  ulBlock)
{
            byte ulStats;
        ulStats = 0x1;
        dword m_inpin32;
        word m_inpin16;
        byte pucData;

            IO0CLR |= 0x00FF0000;
            IO1CLR |= FL_CE;                                        //flash enable        
        IO1SET |= (FL_WP);                                         // NAND nWP(Write Protect) Unlock                        

            Cmd_Flash(0x60);                                        //block command1
        Adr_Flash((unsigned char)(ulBlock & 0xff));                 // column address
            Adr_Flash((unsigned char)((ulBlock >> 8 ) & 0xff));         // column address
            Cmd_Flash(0xD0);                                             //block command2
                
        delay(60);            
        
        NANDWaitTilNotBusy();                                        //지울때가지 기다리기 1ms정도 걸린다합니다.

        Cmd_Flash(0x70);                                        //성공여부 읽기 명령어
                
        IO0SET |= 0x00FF0000;
        IO0DIR  = 0x0700BCF8;                                        //IO를 입력으로        

        IO1CLR |= FL_CLE;
        IO1CLR |= FL_ALE;
        IO1SET |= FL_RE;
        IO1SET |= FL_WE;

        IO1CLR |= FL_RE;
        m_inpin32 = IO0PIN;
        m_inpin32 = m_inpin32 & 0x00010000;                        //0번비트 가 0이면 성공 1이면 실패                          
        m_inpin16 = m_inpin32 >> 16;
        ulStats = (byte)m_inpin16;
        IO1SET |= FL_RE;
        
        IO0DIR = 0x07FFBCF8;          
        IO1CLR |= (FL_WP);        
        IO1SET |= FL_CE;

        return ulStats;
}
Erase Flash를 하면 0을 리턴합니다. 실제로 지워졌는지 어떤지 모르겠지만요.

그리고 NANDWaitTilNotBusy(); 이부분에서
오실로 스코프로 파형을 보면 R/B핀이 로로 떨어졌다가 다시 HIGH로 올라 갑니다.
즉 이부분까지는 되는것 같습니다.



byte Write_Flash(word ulColumn , word ulRow)
{
        word count;
        byte pucData[2048];
        byte ulStats;
        ulStats = 0x1;
        dword m_inpin32;
        word m_inpin16;          
        
        for(count=0; count<2048; count++)                        //2048byte에 데이터를 넣습니다.
        {        
                pucData[count] = count % 256;        
        }        

        IO1CLR |= FL_CE;                                        //Flash enable        
        IO1SET |= (FL_WP);                                         // NAND nWP(Write Protect) Unlock                        

            Cmd_Flash(0x80);                                        //쓰기 명령어1
        Adr_Flash((unsigned char)(ulColumn & 0xff));                // column address
        Adr_Flash((unsigned char)((ulColumn >> 8 ) & 0x0f));         // column address
        Adr_Flash((unsigned char)(ulRow & 0xff));                // row address
        Adr_Flash((unsigned char)((ulRow >> 8) & 0xff));        // row address                

        delay(60);

            for(count = 0; count < 2112 ; count++)                        //씁니다.
            {
                IO1CLR |= FL_WE;
                IO0CLR |= 0x00FF0000;
                IO0SET |= (pucData[count] << 16);
                IO1SET |= FL_WE;                  
            }

            Cmd_Flash(0x10);                                        //쓰기명령어2
        delay(60);
            NANDWaitTilNotBusy();                                        //다쓸때까지 기다립니다.
        delay(60);
        Cmd_Flash(0x70);                                        //쓰기 성공여부 확인 명령어
                
        IO0SET |= 0x00FF0000;
        IO0DIR  = 0x0700BCF8;                                        //IO를 입력으로        

        delay(60);

        IO1CLR |= FL_CLE;
        IO1CLR |= FL_ALE;
        IO1SET |= FL_RE;
        IO1SET |= FL_WE;

        IO1CLR |= FL_RE;
        m_inpin32 = IO0PIN;
        m_inpin32 = m_inpin32 & 0x00010000;                        //0번핀이 0이면 성공 1이면 실패                          
        m_inpin16 = m_inpin32 >> 16;
        ulStats = (byte)m_inpin16;
        IO1SET |= FL_RE;

        IO1CLR |= (FL_WP);                                          // NAND nWP(Write Protect) Lock                
        
        IO0DIR = 0x07FFBCF8;          
        IO1SET |= FL_CE;                                         // Flash disable

        return ulStats;
}

리턴값은 0입니다.
즉 성공한것 같긴한데.
쓰기도 NANDWaitTilNotBusy(); 이부분에서 R/B 핀이 하이였다가 로로 떨어졌다가 다시 하이로 올라갑니다.
이부분까지는 정상인것같습니다.

하지만 erase -> write -> read하면 0~255사이의 값이 나와야 하나 계속 FF만 나옵니다.

1. erase를 못해서 쓰지 못했다거나
2. erase는 했는데 쓰지 못했다거나
3. erase / write는 했는데 못읽었다거나

그런것 같습니다.

낸드가 1Gbit인데 block 과 page가

1page는 2048 byte이고
1block 은 64 page이며
1device는 1024 block 입니다.

그렇다면
Erase_Flash(word  ulBlock)                         -->block
Write_Flash(word ulColumn , word ulRow)                -->page , block
Read_Flash(word ulColumn , word ulRow)                -->page , block
이부분이

Erase_Flash(10);
Write_Flash(1 , 10);
Read_Flash(1 , 10);

이런순서대로 하면

10번 블록 지우로 10번블록 1번 페이지에 쓰고 10번블록 1번페이지를 읽으라는것 아닌가요?
그런데 이렇게 하니깐 FF만 나오던데..

뭐가 잘못된건가요?

cycle address는

1cycle-->  A0  / A1   / A2   / A3  / A4  / A5   / A6   / A7  --> Column Address
2cycle-->  A8  / A9   / A10 / A11 /L     /L     /L      /L     --> Column Address
3cycle-->  A12 / A13 / A14 / A15 / A16 / A17 / A18 / A19 --> Row Address
4cycle-->  A20 / A21 / A22 / A23 / A24 / A25 / A26 / A27 --> Row Address

입니다.

한달가까이 삽질하고 있습니다.
알려주심 정말 감사하겠습니다. ^^

고현철

2007.12.11 23:46:41
*.70.26.87

write protect pin 제어는 해 주셨나요?

read는 되고, 다른 부분이 안된다면, 거기를 맨 먼저 의심.....^^

김태현

2007.12.12 17:32:05
*.78.101.219

네, protect 제어는 해주었습니다.
IO1SET |= (FL_WP); // NAND nWP(Write Protect) Unlock
IO1CLR |= (FL_WP); // NAND nWP(Write Protect) Lock
삽질좀 더해봐야겠습니다. ^^

이제현

2007.12.13 22:05:28
*.41.109.34

yaffs2 소스에서 large block NAND쪽을 살펴보세요.
http://www.yaffs.net/

읽기/쓰기가 완료되어도, bad-block 관리나 ECC제어, wear-leveling 등등 할일들이 무진장 기다리고 있습니다.
따라서 yaffs를 포팅하는 것이 여러가지로 편리하실겁니다.

김태현

2007.12.14 20:55:56
*.78.101.219

쓰기 완료되었습니다. ^^

쓰기의
for(count = 0; count < 2112 ; count++) //씁니다.
{
IO1CLR |= FL_WE;
IO0CLR |= 0x00FF0000;
IO0SET |= (pucData[count] << 16);
IO1SET |= FL_WE;
}

이부분전에

IO1CLR |= FL_CLE;
IO1CLR |= FL_ALE;
IO1SET |= FL_RE;
IO1SET |= FL_WE;

이부분을 빼먹었네요. ^^

이제 잘됩니다.
에.. 그런데 bad-block관리가 남았군요.
제현님이 알려주신 yaffs2 좀 봐야겠네요.
감사합니다. 수고하세요. ^^
List of Articles
번호 제목 글쓴이 날짜 조회 수
168 초보적인 Toolchain 문제 [1] 서영태 2008-01-16 1172
167 2G SD카드 인식문제 [9] 문철민 2008-01-12 3176
166 bootloader 에서 usb device 인식( usb ethernet adator ) [3] 황기천 2008-01-10 1502
165 2차 보드와 3차 보드의 차이점을 알고 싶습니다. [1] 김영수 2008-01-07 1143
164 [질문] 하나의 텍스트 파일안에 utf8 과 euc-kr 이 섞여 있을때의... [6] 유형목 2008-01-06 1291
163 [완료]공유기 없이 VMware network 환경 설정 [7] 최재혁 2007-12-24 3694
162 sd card 질문입니다. [7] 박진우 2007-12-21 1273
161 [완료] 프로세서가 먹통되었을 때 리셋버튼 눌러도 반응이 없는 경... [3] 오주열 2007-12-18 1386
» [완료] 삼성 NAND Flash 제어 질문입니다. ^^ [4] 김태현 2007-12-10 1649
159 [완료]LCD - framebuffer 관련 질문 이요 ^^; [1] 박준영 2007-12-09 1693
158 nfs서버 질문입니다. [2] 문철민 2007-12-04 1424
157 [질문]페도라의 ntsysv 와 같은 역활의 명령어 Slackware11에 어떤게... [5] 조준동 2007-11-30 1313
156 회사의 다른컴에서 aesop-embedded.org 접속이 안됩니다. [5] 조준동 2007-11-28 1546
155 nand bad 관련 의문점 [2] 문철민 2007-11-27 1288
154 nand erase error입니다 도움 부탁합니다. [2] 문철민 2007-11-24 2780
153 [완료]레드햇9 리눅스 부팅에러입니다. [2] 문철민 2007-11-21 1789
152 [완료]NAND Flash 제어할때 주소구성이 어떻게 되는지 궁금합니다... [4] 임종환 2007-11-18 2068
151 삼성 2440 I/O Speed [1] 전철웅 2007-11-17 2759
150 [완료]SDL 기본 화면 뛰우기 [3] 윤치호 2007-11-15 2731
149 [완료]QTE vs TinyX+QT/X11 [2] 박준영 2007-11-13 1978

사용자 로그인