📄 flash_nand.h
字号:
#ifndef __FLASH_FUNCTION_DEF__#define __FLASH_FUNCTION_DEF__#include <bios/nand.h>#undef DEBUG#ifdef DEBUG#define PRINT(fmt, args...) printf("%s()[%d]: " fmt, __FUNCTION__, \ __LINE__, args)#else#define PRINT(fmt, args...)#endif/* Select flash memory bank bus size */typedef volatile unsigned char fbsize ; /* Now we use 8bit bus size */typedef fbsize * flashptr ;/* define NAND Command */#define Sequential_Data_Input 0x80#define First_Page_Read 0x00#define Second_Page_Read 0x01#define Spare_Read 0x50#define Read_ID 0x90#define NAND_RESET 0xFF#define Page_Program 0x10#define Block_Erase1 0x60#define Block_Erase2 0xD0#define Read_Status 0x70int nand_state_read(void);fbsize Spare[16];static void delay(int cnt){ int i; for (i = 0; i < cnt; i ++) ;}int Address_step;int Page_shift;int Block_shift;int nand_block_size;int nand_page_size;int nand_max_block;int nand_id_read(void){ fbsize m_id, d_id = 0; int ret = -1; CSR_WRITE(NFCONF, CSR_READ(NFCONF) & ~(bNFCE)); CSR_WRITE(NFCMD, Read_ID); /* ID read command : 0x90 */ CSR_WRITE(NFADDR, First_Page_Read); /* address : 0x00 */ delay(0x10); delay(0x6); switch (m_id = CSRB_READ(NFDATA)) { case SAMSUNG: switch (d_id = CSRB_READ(NFDATA)) {#if defined(CONFIG_NAND_BOOT_SIZE_8MB) case K9S6408V0A: nand_block_size = 1024; nand_page_size = 16; ret = 0; break ;#elif defined(CONFIG_NAND_BOOT_SIZE_16MB)#elif defined(CONFIG_NAND_BOOT_SIZE_32MB) case K9S5608V0A: nand_block_size = 2048; nand_page_size = 32; ret = 0; break ;#elif defined(CONFIG_NAND_BOOT_SIZE_64MB) case K9S1208V0M: nand_block_size = 4096; nand_page_size = 32; ret = 0; break ;#elif defined(CONFIG_NAND_BOOT_SIZE_128MB)#endif default : break ; } default: break; } PRINT("NAND Device ID = [%x]\n", d_id); CSR_WRITE(NFCONF, CSR_READ(NFCONF) | (bNFCE)); return ret;}int nand_page_read(int block, int page, int column, fbsize *Buffer, int len){ fbsize ecc0, ecc1, ecc2; int i; page &= 0x1f; block = (block << 5) + page; /* Read Page : 0x0 */ CSR_WRITE(NFCONF, CSR_READ(NFCONF) | (bECC_INIT)); /* Initialize ECC */ CSR_WRITE(NFCONF, CSR_READ(NFCONF) & ~(bNFCE)); CSR_WRITE(NFCMD, First_Page_Read); /* Sequential Raw Read command : 0x00 */ CSR_WRITE(NFADDR, 0x00); /* Column Address(A0~A7) : 0x00 */ CSR_WRITE(NFADDR, block & 0xFF); /* Column Address(A9~A16) */ CSR_WRITE(NFADDR, (block >> 8) & 0xFF); /* Column Address(A17~A22) */ CSR_WRITE(NFADDR, (block >> 16) & 0xFF); /* Column Address(A17~A22) */ delay(0x10); /* Twb(max) : 100ns */ while (!(CSR_READ(NFSTAT) & bRnB)); /* Tr(max) : 7us */ for (i = 0; i < len; i ++) *(Buffer + i) = CSRB_READ(NFDATA); ecc0 = CSRB_READ(NFECC0); ecc1 = CSRB_READ(NFECC1); ecc2 = CSRB_READ(NFECC2); while (len < 512) { CSRB_READ(NFDATA); len ++; } for (i = 0; i < 16; i ++) Spare[i] = CSRB_READ(NFDATA); CSR_WRITE(NFCONF, CSR_READ(NFCONF) | (bNFCE)); if (ecc0 == Spare[0] && ecc1 == Spare[1] && ecc2 == Spare[2]) { PRINT("[ECC OK:%x,%x,%x]\n", Spare[0], Spare[1], Spare[2]); return 1; } else { PRINT("[Block(%d,%d)ECC ERROR(RD):read:%x,%x,%x, reg:%x,%x,%x]\n", block >> 4, page, Spare[0], Spare[1], Spare[2], ecc0, ecc1, ecc2); return 0; }}int nand_page_write(int block, int page, int column, fbsize *Buffer, int len){ int ret, i; page &= 0x1f; block = (block << 5) + page; for (i = 0; i < 16; i ++) Spare[i]=0xFF; /* Write Page : 0x0 */ CSR_WRITE(NFCONF, CSR_READ(NFCONF) | (bECC_INIT)); /* Initialize ECC */ CSR_WRITE(NFCONF, CSR_READ(NFCONF) & ~(bNFCE)); CSR_WRITE(NFCMD, First_Page_Read); /* Pointer Position : 0x00 */ CSR_WRITE(NFCMD, Sequential_Data_Input);/* Page Data Input : 0x80 */ CSR_WRITE(NFADDR, 0x00); /* Column Address(A0~A7) : 0x00 */ CSR_WRITE(NFADDR, block & 0xFF); /* First Page Address(A9~A16) */ CSR_WRITE(NFADDR, (block >> 8) & 0xFF);/* Second Page Address(A17~A22) */ CSR_WRITE(NFADDR, (block >> 16) & 0xFF); delay(0x10); /* Twb(max) : 100ns */ for (i = 0; i < len; i ++) CSRB_WRITE(NFDATA, Buffer[i]); Spare[0] = CSRB_READ(NFECC0); Spare[1] = CSRB_READ(NFECC1); Spare[2] = CSRB_READ(NFECC2); while (len < 512) { CSRB_WRITE(NFDATA, 0xFF); len ++; } for (i = 0; i < 16; i ++) CSRB_WRITE(NFDATA, Spare[i]); CSR_WRITE(NFCMD, Page_Program); /* Page Program command : 0x10 */ delay(0x10); while (!(CSR_READ(NFSTAT) & bRnB)) ; ret = nand_state_read(); CSR_WRITE(NFCONF, CSR_READ(NFCONF) | (bNFCE)); return ret;}int nand_state_read(void){ CSRB_WRITE(NFCMD, Read_Status); /* Read status command : 0x70 */ delay(0x6); /* Twhr(max) : 60ns */ if (CSRB_READ(NFDATA) & 0x1) {/* Check Status */ printf("Error....\n"); return 0; } return 1;}int nand_block_erase(int block){ int ret; block = block << 5; CSR_WRITE(NFCONF, CSR_READ(NFCONF) & ~(bNFCE)); CSR_WRITE(NFCMD, Block_Erase1); /* Block Erase Setup command : 0x60 */ CSR_WRITE(NFADDR, block & 0xFF);/* Block Address(A9~A16) : 0x00 */ CSR_WRITE(NFADDR, (block >> 8) & 0xFF);/* Block Address(A17~A22) : 0x00 */ CSR_WRITE(NFADDR, (block >> 16) & 0xFF);/* Block Address(A17~A22) : 0x00 */ delay(0x8); CSR_WRITE(NFCMD, Block_Erase2); delay(0x10); while (!(CSR_READ(NFSTAT) & bRnB)) ; ret = nand_state_read(); CSR_WRITE(NFCONF, CSR_READ(NFCONF) | (bNFCE)); return ret;}int nand_flash_control(int control, int block, int page, unsigned char *buf, int len){ int i;#ifdef DEBUG nand_id_read(); PRINT("block = [%d], page = [%d]\n", block, page);#endif if (control == nand_read) { for (i = len; i > 0; i -= 512, page ++, buf +=512) { if (page == 32) { block ++; page = 0; } nand_page_read(block, page, 0, buf, (i > 512) ? 512 : i); } } else if (control == nand_write) { for (i = 0; i < len; i += 16384) { nand_block_erase(block + (i >> 14)); } for (i = len; i > 0; i -= 512, page ++, buf += 512) { if (page == 32) { block ++; page = 0; } nand_page_write(block, page, 0, buf, (i > 512) ? 512 : i); } } else if (control == nand_erase) { for (i = 0; i < len; i += 16384) { nand_block_erase(block + (i >> 14)); } } return 0;}#endif /* __FLASH_FUNCTION_DEF__ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -