📄 nandread.c
字号:
/* * vivi/s3c2410/nand_read.c: Simple NAND read functions for booting from NAND * * Copyright (C) 2002 MIZI Research, Inc. * * Author: Hwang, Chideok <hwang@mizi.com> * Date : $Date: 2004/02/04 06:22:24 $ * * $Revision: 1.1.1.1 $ * $Id: param.c,v 1.9 2002/07/11 06:17:20 nandy Exp * * History * * 2002-05-xx: Hwang, Chideok <hwang@mizi.com> * * 2002-05-xx: Chan Gyun Jeong <cgjeong@mizi.com> * * 2002-08-10: Yong-iL Joh <tolkien@mizi.com> * */#include "..\inc\nand.h"#include "..\inc\2410addr.h"#include "..\inc\def.h"#define __REGb(x) (*(volatile unsigned char *)(x))#define __REGi(x) (*(volatile unsigned int *)(x))#define NF_BASE 0x4e000000#define NFCONF __REGi(NF_BASE + 0x0)#define NFCMD __REGb(NF_BASE + 0x4)#define NFADDR __REGb(NF_BASE + 0x8)#define NFDATA __REGb(NF_BASE + 0xc)#define NFSTAT __REGb(NF_BASE + 0x10)//#define GPDAT __REGi(GPIO_CTL_BASE+oGPIO_F+oGPIO_DAT)#define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))#define NAND_CHIP_DISABLE (NFCONT |= (1<<1))#define NAND_CLEAR_RB (NFSTAT |= (1<<2))#define NAND_DETECT_RB { while(! (NFSTAT&(1<<2)) );}#define BUSY 1static unsigned char seBuf[16]={0xff};void wait_idle(void) { int i; while(!(NFSTAT & BUSY)) for(i=0; i<10; i++);}#define NAND_CMD_READ0 0#define NAND_SECTOR_SIZE 512#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)/* low level nand read function */int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size){ int i, j; if (start_addr & NAND_BLOCK_MASK) { return -1; /* invalid alignment */ } /* chip Enable */ NFCONF &= ~0x800; for(i=0; i<10; i++); for(i=start_addr; i < (start_addr + size);) { /* READ0 */ NFCMD = NAND_CMD_READ0; /* Write Address */ NFADDR = i & 0xff; NFADDR = (i >> 9) & 0xff; NFADDR = (i >> 17) & 0xff; NFADDR = (i >> 25) & 0xff; wait_idle(); for(j=0; j < NAND_SECTOR_SIZE; j++) { *buf = (NFDATA & 0xff); buf++; } i += NAND_SECTOR_SIZE; } /* chip Disable */ NFCONF |= 0x800; /* chip disable */ return 0;}//--------------------------------------------------------------------------------------unsigned short nf_checkId(void){ int i; unsigned short id; NF_nFCE_L(); //chip enable NF_CMD(0x90); //Read ID NF_ADDR(0x0); for(i=0;i<10;i++); //wait tWB(100ns) id=NF_RDDATA()<<8; // Maker code(K9S1208V:0xec) id|=NF_RDDATA(); // Devide code(K9S1208V:0x76) NF_nFCE_H(); //chip enable return id;}//--------------------------------------------------------------------------------------static void nf_reset(void){ int i; NF_nFCE_L(); //chip enable NF_CMD(0xFF); //reset command for(i=0;i<10;i++); //tWB = 100ns. NF_WAITRB(); //wait 200~500us; NF_nFCE_H(); //chip disable}//--------------------------------------------------------------------------------------void nf_init(void){ rNFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); // 1 1 1 1 1 xxx r xxx, r xxx // En r r ECCR nFCE=H tACLS tWRPH0 tWRPH1 nf_reset();}//--------------------------------------------------------------------------------------void nf_read(unsigned int src_addr,unsigned char *desc_addr,int size){ int i; unsigned int column_addr=src_addr%512; // column address unsigned int page_address=(src_addr>>9); // page addrress unsigned char *buf=desc_addr; while((unsigned int)buf<(unsigned int)(desc_addr)+size) { NF_nFCE_L(); // enable chip if(column_addr>255) // 2end halft { NF_CMD(0x01); // Read2 command. cmd 0x01: Read command(start from 2end half page) } else { NF_CMD(0x00); // 1st halft? } NF_ADDR(column_addr&0xff); // Column Address NF_ADDR(page_address&0xff); // Page Address NF_ADDR((page_address>>8)&0xff); // ... NF_ADDR((page_address>>16)&0xff); // .. for(i=0;i<10;i++); // wait tWB(100ns)/////?????? NF_WAITRB(); // Wait tR(max 12us) // Read from main area for(i=column_addr;i<512;i++) { *buf++=NF_RDDATA(); } NF_nFCE_H(); // disable chip column_addr=0; page_address++; } return ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -