再次感谢caiyuqing,感谢本站的fly-feiser转载,这些给了我很多的启发。
共三个文件:s3c2410.h, nand_flash.h, nand_flash.c。
1.s3c2410.h
#ifndef _S3C2410_H #define _S3C2410_H // watchdog register #define rWTCON (*(volatile unsigned int *)0x53000000) //interrupt register #define rSRCPND (*(volatile unsigned int *)0x4A000000) #define rSUBSRCPND (*(volatile unsigned int *)0x4A000018) #define rINTMOD (*(volatile unsigned int *)0x4A000004) #define rINTMSK (*(volatile unsigned int *)0x4A000008) #define rINTSUBMSK (*(volatile unsigned int *)0x4A00001C) #define rPRIORITY (*(volatile unsigned int *)0x4A00000C) #define rINTPND (*(volatile unsigned int *)0x4A000010) #define rINTOFFSET (*(volatile unsigned int *)0x4A000014) // bank ctrl register #define rBWSCON (*(volatile unsigned int *)0x48000000) #define rREFRESH (*(volatile unsigned int *)0x48000024) // NAND flash register #define rNFCONF (*(volatile unsigned int *)0x4e000000) //NAND Flash configuration #define rNFCMD (*(volatile unsigned char *)0x4e000004) //NADD Flash command #define rNFADDR (*(volatile unsigned char *)0x4e000008) //NAND Flash address #define rNFDATA (*(volatile unsigned char *)0x4e00000c) //NAND Flash data #define rNFSTAT (*(volatile unsigned int *)0x4e000010) //NAND Flash operation status #define rNFECC (*(volatile unsigned int *)0x4e000014) //NAND Flash ECC #define rNFECC0 (*(volatile unsigned char *)0x4e000014) #define rNFECC1 (*(volatile unsigned char *)0x4e000015) #define rNFECC2 (*(volatile unsigned char *)0x4e000016)
// I/O PORT register #define rGPACON (*(volatile unsigned int *)0x56000000) //Port A control #define rGPADAT (*(volatile unsigned int *)0x56000004) //Port A data #define rGPBCON (*(volatile unsigned int *)0x56000010) //Port B control #define rGPBDAT (*(volatile unsigned int *)0x56000014) //Port B data #define rGPBUP (*(volatile unsigned int *)0x56000018) //Pull-up control B #define rGPCCON (*(volatile unsigned int *)0x56000020) //Port C control #define rGPCDAT (*(volatile unsigned int *)0x56000024) //Port C data #define rGPCUP (*(volatile unsigned int *)0x56000028) //Pull-up control C #define rGPDCON (*(volatile unsigned int *)0x56000030) //Port D control #define rGPDDAT (*(volatile unsigned int *)0x56000034) //Port D data #define rGPDUP (*(volatile unsigned int *)0x56000038) //Pull-up control D #define rGPECON (*(volatile unsigned int *)0x56000040) //Port E control #define rGPEDAT (*(volatile unsigned int *)0x56000044) //Port E data #define rGPEUP (*(volatile unsigned int *)0x56000048) //Pull-up control E #define rGPFCON (*(volatile unsigned int *)0x56000050) //Port F control #define rGPFDAT (*(volatile unsigned int *)0x56000054) //Port F data #define rGPFUP (*(volatile unsigned int *)0x56000058) //Pull-up control F #define rGPGCON (*(volatile unsigned int *)0x56000060) //Port G control #define rGPGDAT (*(volatile unsigned int *)0x56000064) //Port G data #define rGPGUP (*(volatile unsigned int *)0x56000068) //Pull-up control G #define rGPHCON (*(volatile unsigned int *)0x56000070) //Port H control #define rGPHDAT (*(volatile unsigned int *)0x56000074) //Port H data #define rGPHUP (*(volatile unsigned int *)0x56000078) //Pull-up control H
//UART register #define rULCON0 (*(volatile unsigned int *)0x50000000) //UART 0 Line control #define rUCON0 (*(volatile unsigned int *)0x50000004) //UART 0 Control #define rUFCON0 (*(volatile unsigned int *)0x50000008) //UART 0 FIFO control #define rUMCON0 (*(volatile unsigned int *)0x5000000C) //UART 0 Modem control #define rUTRSTAT0 (*(volatile unsigned int *)0x50000010) //UART 0 Tx/Rx status #define rUERSTAT0 (*(volatile unsigned int *)0x50000014) //UART 0 Rx error status #define rUFSTAT0 (*(volatile unsigned int *)0x50000018) //UART 0 FIFO status #define rUMSTAT0 (*(volatile unsigned int *)0x5000001C) //UART 0 Modem status #define rUBRDIV0 (*(volatile unsigned int *)0x50000028) //UART 0 Baud rate divisor
#define rUTXH0 (*(volatile unsigned char *)0x50000020) //UART 0 Transmission Hold #define rURXH0 (*(volatile unsigned char *)0x50000024) //UART 0 Receive buffer #define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch) #define RdURXH0() (*(volatile unsigned char *)0x50000024)
// CLOCK & POWER MANAGEMENT #define rLOCKTIME (*(volatile unsigned int *)0x4c000000) //PLL lock time counter #define rMPLLCON (*(volatile unsigned int *)0x4c000004) //MPLL Control #define rUPLLCON (*(volatile unsigned int *)0x4c000008) //UPLL Control #define rCLKCON (*(volatile unsigned int *)0x4c00000c) //Clock generator control #define rCLKSLOW (*(volatile unsigned int *)0x4c000010) //Slow clock control #define rCLKDIVN (*(volatile unsigned int *)0x4c000014) //Clock divider control
// LCD register #define rLCDCON1 (*(volatile unsigned int *)0x4D000000) #define rLCDCON2 (*(volatile unsigned int *)0x4D000004) #define rLCDCON3 (*(volatile unsigned int *)0x4D000008) #define rLCDCON4 (*(volatile unsigned int *)0x4D00000c) #define rLCDCON5 (*(volatile unsigned int *)0x4D000010) #define rLCDSADDR1 (*(volatile unsigned int *)0x4D000014) #define rLCDSADDR2 (*(volatile unsigned int *)0x4D000018) #define rLCDSADDR3 (*(volatile unsigned int *)0x4D00001c) #define rREDLUT (*(volatile unsigned int *)0x4D000020) #define rGREENLUT (*(volatile unsigned int *)0x4D000024) #define rBLUELUT (*(volatile unsigned int *)0x4D000028) #define rDITHMODE (*(volatile unsigned int *)0x4D00004c) #define rTPAL (*(volatile unsigned int *)0x4D000050) #define rLCDINTPND (*(volatile unsigned int *)0x4D000054) #define rLCDSRCPND (*(volatile unsigned int *)0x4D000058) #define rLCDINTMSK (*(volatile unsigned int *)0x4D00005c) #define rLPCSEL (*(volatile unsigned int *)0x4D000060)
// Timer register #define rTCFG0 (*(volatile unsigned int *)0x51000000) #define rTCFG1 (*(volatile unsigned int *)0x51000004) #define rTCON (*(volatile unsigned int *)0x51000008) #define rTCNTB0 (*(volatile unsigned int *)0x5100000C) #define rTCMPB0 (*(volatile unsigned int *)0x51000010) #define rTCNTO0 (*(volatile unsigned int *)0x51000014) #define rTCNTB1 (*(volatile unsigned int *)0x51000018) #define rTCMPB1 (*(volatile unsigned int *)0x5100001C) #define rTCNTO1 (*(volatile unsigned int *)0x51000020) #define rTCNTB2 (*(volatile unsigned int *)0x51000024) #define rTCMPB2 (*(volatile unsigned int *)0x51000028) #define rTCNTO2 (*(volatile unsigned int *)0x5100002C) #define rTCNTB3 (*(volatile unsigned int *)0x51000030) #define rTCMPB3 (*(volatile unsigned int *)0x51000034) #define rTCNTO3 (*(volatile unsigned int *)0x51000038) #define rTCNTB4 (*(volatile unsigned int *)0x5100003C) #define rTCNTO4 (*(volatile unsigned int *)0x51000040) #endif
2.nand_flash.h
#ifndef _NAND_FLASH_H #define _NAND_FLASH_H
#define TACLS 0 //1clk(0ns) #define TWRPH0 3 //3clk(25ns) #define TWRPH1 0 //1clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns
//send command #define NF_CMD(cmd) {rNFCMD=cmd;} //set address #define NF_ADDR(addr) {rNFADDR=addr;} //NAND Flash Memory chip enable #define NF_nFCE_L() {rNFCONF&=~(1<<11);} //NAND Flash Memory chip disable #define NF_nFCE_H() {rNFCONF|=(1<<11);} //Initialize ECC #define NF_RSTECC() {rNFCONF|=(1<<12);} //read data #define NF_RDDATA() (rNFDATA) //write data #define NF_WRDATA(data) {rNFDATA=data;} //get status #define NF_WAITRB() {while(!(rNFSTAT&(1)));}
#endif
3.nand_flash.c
/* www.another-prj.com author: caiyuqing 本代码只属于交流学习,不得用于商业开发 */ #include "s3c2410.h" #include "nand_flash.h" static unsigned char seBuf[16]={0xff}; //-------------------------------------------------------------------------------------- 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 ; }
|