Hi,
I'm having trouble configuring the NAND K9F5608U in FlashFS. The File_Config.c file has no configuration options for this memory. If I am not wrong, the setting should be:
Page size = 16384 + 512 bytes Block size = 32 pages Devise size = 2048 blocks
I have done work NAND K9F1G08U but my hardware requires K9F5608U (I'm using a LPC2478).
Some help?
You are right! Yhank you!
But still does not work! I am unable to adjust the read commands, because this memory is divided into two regions and requires two different commands.
K9F1G08:
/* Write command 1 */ WrCmd (NAND_CMD_READ1ST); // 0x00 /* Set address */ SetPgAddr (cfg->AddrCycles, row, cfg->PageSize); /* Write command 2 */ WrCmd (NAND_CMD_READ2ND); // 0x30
K9F5608:
if(row <= 255) { /* Write command 1º half array */ WrCmd (NAND_CMD_READ1HALF); // 0x00 } else if(row <= 511) { /* Write command 2º half array */ WrCmd (NAND_CMD_READ2HALF); // 0x01 } else { /* Write command 2º spare array */ WrCmd (NAND_CMD_READSPARE); // 0x50 } /* Set address */ SetPgAddr (cfg->AddrCycles, row, cfg->PageSize);
Can you read the ID of the IC? Does your 'Read ID' Command execute?
Check the interfacing connections:
Controller Pins Connected to Nand Flash Driver D0 - D7 IO0 – IO7 A24 ALE //this connections would be different A25 CLE // for your circuit (may be A19 & A20 are used) GPIO P2.21 R/!B CS1 CE
The Nand flash memory structure is different from the previous generation 8-bit sequential memories. understanding the architecture is more important to write the driver correctly. once the basic driver code (read id, read data, write data) works, file system mounting would become easier.
Right! Thanks for help! I'm doing tests and really have problems..
k9f5608_init(); //Ok k9f5608_wr_cmd(K9F5608_CMD_ID); EMC_ADDR8 = 0; id1 = EMC_DATA8; id2 = EMC_DATA8; id3 = EMC_DATA8; id4 = EMC_DATA8; id = ((id1 << 24) | (id2 << 16) | (id3 << 8) | id4); if((id & 0xFFFF0000) != K9F5608_ID) //Ok, id == 0xEC75xxxx return 0;
After the ID, any reading data comes 0xEC and the other always 0xFF.
printf("read.. "); k9f5608_wr_cmd(K9F5608_CMD_READ1HALF); EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x01; if(k9f5608_wait_read() != K9F5608_BUSY) { for(i = 0; i < 16; i++) { byte = EMC_DATA8; printf("%02X ", byte); } printf("\n"); } else { printf("error busy\n"); } //printf output: read.. EC FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF printf("erase.. "); k9f5608_wr_cmd(K9F5608_CMD_ERASE1ST); EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x01; k9f5608_wr_cmd(K9F5608_CMD_ERASE2ND); if(k9f5608_wait_read() != K9F5608_BUSY) { if(!k9f5608_check_status(K9F5608_STATUS_FAIL)) printf("ok\n"); else printf("error status\n"); } else { printf("error busy\n"); } //printf output: erase.. ok printf("read.. "); k9f5608_wr_cmd(K9F5608_CMD_READ1HALF); EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x01; if(k9f5608_wait_read() != K9F5608_BUSY) { for(i = 0; i < 16; i++) { byte = EMC_DATA8; printf("%02X ", byte); } printf("\n"); } else { printf("error busy\n"); } //printf output: read.. FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF printf("read id.. "); k9f5608_wr_cmd(K9F5608_CMD_ID); EMC_ADDR8 = 0; for(i = 0; i < 4; i++) { byte = EMC_DATA8; printf("%02X ", byte); } printf("\n"); //printf output: read id.. EC 75 A5 BD printf("read.. "); k9f5608_wr_cmd(K9F5608_CMD_READ1HALF); EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x00; EMC_ADDR8 = 0x01; if(k9f5608_wait_read() != K9F5608_BUSY) { for(i = 0; i < 16; i++) { byte = EMC_DATA8; printf("%02X ", byte); } printf("\n"); } else { printf("error busy\n"); } //printf output: read.. EC FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
Hardware configuration is ok, any ideas?
...the other always 0xFF. Thats good. Read the flowchart on page 9 of datasheet. which says: check 0xff. if not 0xff, then its a bad block.
In Nand flash memory, good memory blocks read 0xff (i.e. all bits of memory locations of good blocks are high)
Read cycle sequence:
wr_cmd(read1_cmd) set_pageaddr(/* variables*/); wr_cmd(read2_cmd); //i cant see this in your code
refer to the timing diagrams given in the datasheet.
what are EMC_ADDR8, EMC_DATA8? what address does it point to?
The second read command does not exist on the command table (page 4). I found it strange, but it seems that the sequence of reading is just cmd and addr
EMC defs:
#define K9F5608_HDW_CS 0x01 #define EMC_NAND_BASE (0x80000000 + 0x1000000 * K9F5608_HDW_CS) #define EMC_ALE_ADDR 0x00080000 #define EMC_CLE_ADDR 0x00100000 #define EMC_DATA8 *((volatile U8 *)(EMC_NAND_BASE)) #define EMC_ADDR8 *((volatile U8 *)(EMC_NAND_BASE + EMC_ALE_ADDR)) #define EMC_CMD8 *((volatile U8 *)(EMC_NAND_BASE + EMC_CLE_ADDR))
The second read command does not exist on the command table obviously there is. Check and recheck (refer the datasheet of the link)
and follow the timing diagram of the read sequence.
Still nothing.. What I found was 0x00 or 0x01 and 3 cycles of address.. RB wait and read the data..
on page 13 of datasheet watch the IO 0-7 lines. it shows that you have to send 4 address cycles (irrespective of whether the 1st cycle is 0x00 or 0x01).
WrCmd (NAND_CMD_READ1ST); // Write Read command Byte1 SetPgAddr (AddrCycles, row, PageSize); // Set address WrCmd (NAND_CMD_READ2ND); // Write Read command Byte2 EMC_ADDR8 = 0; for(i=1000;i;i--); if( WaitReady() == NAND_BUSY) // Wait until NAND ready { return ERR_NAND_HW_TOUT; } ...//read data
Dont you have example codes for nand flash interface with LPC2478? have you tried executing those codes?
For memory K9F1G08 has examples and works. This memory has 2 commands for reading and 4 address cycles.
WrCmd (NAND_CMD_READ1ST); // 0x00 SetPgAddr (cfg->AddrCycles, row, cfg->PageSize); // 4 cycles WrCmd (NAND_CMD_READ2ND); // 0x30 WaitReady(); // busy
The memory I'm using is K9F5608, this does not have specific examples for LPC2478. This memory has only 1 read command and 3 address cycles.
WrCmd (NAND_CMD_READ1HALF); // 0x00 or 0x01 (1º half or 2º half) SetPgAddr (cfg->AddrCycles, row, cfg->PageSize); // 3 cycles WaitReady(); // busy
I can run the commands read id, read status, reset.. However the commands for reading and writing the page does not work correctly. For example, in reading the page the first byte read is always equal to the last data byte from the previous command, the others are always 0xFF.
The write command can not say it works because it does not work the command to read the data..
Finally the functions read() and write() are working. The problem is that this memory for the CS pin was not well controlled by EMC. Needed a CS manual control in the two functions:
static void xk9f5608_cs_0(void) { #if XK9F5608_CS == XNAND_CS0 /* Chip enable 0: P4.30 - CS0 [nCE] */ PINSEL9 &= ~(3UL << 28); FIO4DIR |= (1UL << 30); FIO4CLR |= (1UL << 30); #elif XK9F5608_CS == XNAND_CS1 /* Chip enable 1: P4.31 - CS1 [nCE] */ PINSEL9 &= ~(3UL << 30); FIO4DIR |= (1UL << 31); FIO4CLR |= (1UL << 31); #elif XK9F5608_CS == XNAND_CS2 /* Chip enable 2: P2.14 - CS2 [nCE] */ PINSEL4 &= ~(3UL << 30); FIO2DIR |= (1UL << 14); FIO2CLR |= (1UL << 14); #elif XK9F5608_CS == XNAND_CS3 /* Chip enable 3: P2.15 - CS3 [nCE] */ PINSEL4 &= ~(3UL << 30); FIO2DIR |= (1UL << 15); FIO2CLR |= (1UL << 15); #endif } static void xk9f5608_cs_1(void) { #if XK9F5608_CS == XNAND_CS0 /* Chip enable 0: P4.30 - CS0 [nCE] */ FIO4SET |= (1UL << 30); PINSEL9 = (PINSEL9 & ~(3UL << 28)) | (1UL << 28); #elif XK9F5608_CS == XNAND_CS1 /* Chip enable 1: P4.31 - CS1 [nCE] */ FIO4SET |= (1UL << 31); PINSEL9 = (PINSEL9 & ~(3UL << 30)) | (1UL << 30); #elif XK9F5608_CS == XNAND_CS2 /* Chip enable 2: P2.14 - CS2 [nCE] */ FIO2SET |= (1UL << 14); PINSEL4 = (PINSEL4 & ~(3UL << 28)) | (1UL << 28); #elif XK9F5608_CS == XNAND_CS3 /* Chip enable 3: P2.15 - CS3 [nCE] */ FIO2SET |= (1UL << 15); PINSEL4 = (PINSEL4 & ~(3UL << 30)) | (1UL << 30); #endif }
read() and write():
int xk9f5608_read_page(uint32_t block, uint32_t page, uint8_t *buf) { uint32_t addr; uint32_t i; int ret; if (buf == NULL) return XNAND_INVALID_PARAM; addr = (block << 5) + page; xk9f5608_cs_0(); // CS -> GPIO xk9f5608_wr_cmd(XK9F5608_CMD_READ1HALF); XK9F5608_EMC_ADDR8 = 0; XK9F5608_EMC_ADDR8 = (addr & 0xFF); XK9F5608_EMC_ADDR8 = ((addr >> 8) & 0xFF); if (xk9f5608_wait_busy() == XNAND_OK) { for (i = XK9F5608_PAGE_SIZE; i; i--) *buf++ = XK9F5608_EMC_DATA8; if (xk9f5608_wait_busy() == XNAND_OK) ret = XNAND_OK; else ret = XNAND_BUSY; } else { ret = XNAND_BUSY; } xk9f5608_cs_1(); // CS -> EMC return ret; } int xk9f5608_write_page(uint32_t block, uint32_t page, const uint8_t *buf) { uint32_t addr; uint32_t i; if (buf == NULL) return XNAND_INVALID_PARAM; addr = (block << 5) + page; xk9f5608_cs_0(); // CS -> GPIO xk9f5608_wr_cmd(XK9F5608_CMD_READ1HALF); xk9f5608_wr_cmd(XK9F5608_CMD_PROGRAM1ST); XK9F5608_EMC_ADDR8 = 0; XK9F5608_EMC_ADDR8 = (addr & 0xFF); XK9F5608_EMC_ADDR8 = ((addr >> 8) & 0xFF); for (i = XK9F5608_PAGE_SIZE; i; i--) XK9F5608_EMC_DATA8 = *buf++; xk9f5608_wr_cmd(XK9F5608_CMD_PROGRAM2ND); xk9f5608_cs_1(); // CS -> EMC if (xk9f5608_wait_busy() == XNAND_BUSY) return XNAND_BUSY; return xk9f5608_wait_status(); }
Now I'm able to use the FileSystem with EBS format. Fat32 is not working, always returns 2 in finit().
Look..
finit("N0:"); // return 2 (Volume Error) fformat("N0:"); // return 0 (EFS) finit("N0:"); // return 0 ... finit("N0:"); // return 2 (Volume Error) fformat("N0: /FAT32"); // return 1 finit("N0:"); // return 2 (Volume Error) ... finit("N0:"); // return 2 (Volume Error) fformat("N0: /FAT32 /WIPE"); // return 1 finit("N0:"); // return 2 (Volume Error) ... finit("N0:"); // return 2 (Volume Error) fformat("N0: /FAT32 /WIPE /LOW_EB"); // return 1 finit("N0:"); // return 2 (Volume Error)
file_lib.c for FAT32
nand0_UnInit: return 1 nand0_RdSect: return __TRUE (ftl_ReadSect return RTV_NOERR) nand0_WrSect: return __TRUE (ftl_WriteSect return RTV_NOERR) nand0_RdInfo: return 1 nand0_DevCtrl: return M_NOCHKMEDIA (code == DC_CHKMEDIA) nand0_DevCtrl: return 1 (code == DC_FORMAT) nand0_dev->PgLay.Pos_LSN = 0x00 nand0_dev->PgLay.Pos_COR = 0x04 nand0_dev->PgLay.Pos_BBM = 0x05 nand0_dev->PgLay.Pos_ECC = 0x06 nand0_dev->PgLay.SecInc = 0x0210 nand0_dev->PgLay.SpareOfs = 0x0200 nand0_dev->PgLay.SpareInc = 0x0210
Found the problem..
finit("N0: /FAT32"); // Error finit("N0: /fat32"); // Ok
File system working!
NAND drive can only be formatted with FAT12, FAT16 or FAT32 file system. You cannot format your device with FAT32 because it is to small (FAT32 volume requires at least 65,527 clusters of space).
if (fformat("N0:") == 0) { /* NAND drive formatted with FAT12 or FAT16 or FAT32 (depends on its size) */ } if (fformat("N0: /fat32") = 0) { /* NAND drive formatted with FAT12 or FAT16 (depends on its size) */ /* because FlashFS does not detect lowercase switch */ } if (fformat("N0: /FAT32") == 0) { /* NAND drive formatted with FAT32 */ }
Since size of your device is 32MB, it was most likely formatted using FAT16 ;)