필립스 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
입니다.
한달가까이 삽질하고 있습니다.
알려주심 정말 감사하겠습니다. ^^
read는 되고, 다른 부분이 안된다면, 거기를 맨 먼저 의심.....^^