AT91RM9200 K9K8 NAND FlashLinux驱动程序.docx
《AT91RM9200 K9K8 NAND FlashLinux驱动程序.docx》由会员分享,可在线阅读,更多相关《AT91RM9200 K9K8 NAND FlashLinux驱动程序.docx(28页珍藏版)》请在冰点文库上搜索。
AT91RM9200K9K8NANDFlashLinux驱动程序
AT91RM9200K9K8**NANDFlashLinux驱动程序
CPU:
AT91RM9200
NAND:
K9K8G08
不同容量的NAND需要做相应的调整,同时需要对控制脚相应的进行调整
驱动程序如下,希望对需要的有所帮助,验证通过。
/*********************************************************************************************
FileName:
charK9F1G_statu(void)
description:
writer:
Liuxinmin
version:
1.0
date:
20091020
lastchage:
20091019
*********************************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#include
#include
#include
#include
#include
#include
#include
#include
//#include"can0.h"
#include
#include
/*****************************************************************************************************************/
#defineK9F1G08R0A
#defineFLASH_READ_START 0x00 //read1st.Cycle
#defineFLASH_READ_END 0x30 //read2nd.Cycle
#defineFLASH_READ_FOR_COPY_BANK_START 0x00 //ReadforCopyBack1st.cycle
#defineFLASH_READ_FOR_COPY_BANK_END 0x35 //ReadforCopyBack2nd.cycle
#defineFLASH_READ_ID 0x90 //readdeviceid
#defineFLASH_RESET 0xFF //resetdevice
#defineFLASH_PAGE_PROGRAM_START 0x80 //PageProgram1st.cycle
#defineFLASH_PAGE_PROGRAM_END 0x10 //PageProgram2nd.cycle
#defineFLASH_CACHE_PROGRAM_START 0x80 //CacheProgram1st.cycle
#defineFLASH_CACHE_PROGRAM_END 0x15 //CacheProgram2nd.cycle
#defineFLASH_COPY_BANK_PROGRAM_START 0x00 //Copy-BackProgram1st.cycle
#defineFLASH_COPY_BANK_PROGRAM_END 0x30 //Copy-BackProgram2nd.cycle
#defineFLASH_BLOCK_ERASE_START 0x60 //EraseBlock1st.cycle
#defineFLASH_BLOCK_ERASE_END 0xD0 //EraseBlockendcyc
#defineFLASH_RANDOM_DATA_INPUT 0x85 //RandomDataInput
#defineFLASH_RANDOM_DATA_OUTPUT_START0x05 //RandomDataOutput1st.cycle
#defineFLASH_RANDOM_DATA_OUTPUT_END 0xE0 //RandomDataOutput2nd.cyc
#defineFLASH_READ_STTUS 0x70 //ReadStatus
#defineK9F1G_ADDRESS_ADDRESS (0x40000000|(0x1<<23)|(0x01<<22)) //ADDRESS_ADDRESS
#defineK9F1G_COMMAND_ADDRESS (0x40000000|(0x1<<23)|(0x01<<21)) //COMMAND_ADDRESS
#defineK9F1G_DATA_ADDRESS (0x40000000|(0x1<<23)) //DATA_ADDRESS //DATA_ADDRESS
/*
#defineK9F1G_CE PA0 //needtodefine
#defineK9F1G_WE PC3 //needtodefine
#defineK9F1G_RE PC1 //needtodefine
#defineK9F1G_R/-B PC15
*/
/*****************************************************************************************************************/
/*Use'K'asmagicnumber*/
#defineFLASH_IOC_MAGIC 'K'
#defineFLASH_IO_BLOCK_ERASE _IOW(FLASH_IOC_MAGIC,1,int)
#defineFLASH_IO_WR_ADD _IOW(FLASH_IOC_MAGIC,2,int)
#defineFLASH_IO_RD_ADD _IOW(FLASH_IOC_MAGIC,3,int)
//#defineFLASH_IO_RESET _IO(FLASH_IOC_MAGIC,0)
//#defineFLASH_IO_ERASE _IO(FLASH_IOC_MAGIC,1)
//#defineCF_IOCREADBLOCK0 _IOR(FLASH_IOC_MAGIC,5,512)
//#defineCF_IOCWRITEBLOCK _IO(FLASH_IOC_MAGIC, 6)
//#defineCF_IOCSQSET _IOW(FLASH_IOC_MAGIC, 7,scullp_qset)
//#defineCF_IOCTQSET _IO(FLASH_IOC_MAGIC, 8)
//#defineCF_IOCGQSET _IOR(FLASH_IOC_MAGIC, 9,scullp_qset)
//#defineCF_IOCQQSET _IO(FLASH_IOC_MAGIC, 10)
//#defineCF_IOCXQSET _IOWR(FLASH_IOC_MAGIC,11,scullp_qset)
//#defineCF_IOCHQSET _IO(FLASH_IOC_MAGIC, 12)
//#defineCF_IOCHARDRESET_IO(FLASH_IOC_MAGIC,13)/*debuggingtool*/
#defineFLASH_IOC_MAXNR6
/*****************************************************************************************************************/
#defineK9F1G_WE_HIGH()
#defineK9F1G_WE_LOW()
#defineK9F1G_RE_HIGH()
#defineK9F1G_RE_LOW()
//PC3shouldbehighnow
//#defineK9F1G_WE_HIGH() {AT91_SYS->PIOC_ODSR = AT91C_PIO_PC3;AT91_SYS->PIOC_SODR = AT91C_PIO_PC3;}
//PC3shouldbelownow
//#defineK9F1G_WE_LOW() {AT91_SYS->PIOC_ODSR = 0; AT91_SYS->PIOC_SODR = AT91C_PIO_PC3;}
//PC3shouldbehighnow
//#defineK9F1G_RE_HIGH() {AT91_SYS->PIOC_ODSR = AT91C_PIO_PC1;AT91_SYS->PIOC_SODR = AT91C_PIO_PC1;}
//PC3shouldbelownow
//#defineK9F1G_RE_LOW() {AT91_SYS->PIOC_ODSR = 0; AT91_SYS->PIOC_SODR = AT91C_PIO_PC1;}
/*****************************************************************************************************************/
//declarethevarias
staticunsignedintflash_address_add=0;
staticunsignedintflash_command_add=0;
staticunsignedintflash_data_add=0;
//declarethefunction
staticintflash_ioctl(structinode*,structfile*,unsignedint,unsignedlong);
staticssize_tflash_read(structfile*,char*,size_t,loff_t*);
staticssize_tflash_write(structfile*,constchar*,size_t,loff_t*);
staticintflash_open(structinode*,structfile*);
staticintflash_release(structinode*,structfile*);
structfile_operationsflash_simon_fops={
// owner:
THIS_MODULE,
ioctl:
flash_ioctl,
write:
flash_write,
read:
flash_read,
open:
flash_open,
release:
flash_release
};
staticunsignedintFlashWriteAddress=0;
staticunsignedintFlashReadAddress=0;
staticunsignedintblock_address=0;
/***************************************************************************************************
functionname:
delay_flash(intnb)
functiondescription:
delaytheCPUnottodoanything,justdelay
function.
****************************************************************************************************/
voiddelay_flash(intnb)
{
while(nb--);
}
/*************************************************************************************
Name:
charK9F1G_statu(void)
Function:
gettheK9F1GBusyorReadystatu
return:
1:
ready
0:
busy
writer:
Liuxinmin
date:
20091020
lastchage:
20091020
*************************************************************************************/
unsignedintK9F1G_statu(void){
intstatu;
statu=((AT91_SYS->PIOC_PDSR)&AT91C_PIO_PC15);
returnstatu;
}
void K9F1G_CE_HIGH()
{
#ifdefnewboard
AT91_SYS->PIOC_SODR = AT91C_PIO_PC13;
#else
AT91_SYS->PIOA_SODR = AT91C_PIO_PA0;
#endif
}
voidK9F1G_CE_LOW()
{
#ifdefnewboard
AT91_SYS->PIOC_CODR = AT91C_PIO_PC13; //cleartheoutputreg
#else
AT91_SYS->PIOA_CODR = AT91C_PIO_PA0;
#endif
}
intK9F1G_READ_ID()
{
inti;
unsignedcharid[5];
//outb(FLASH_READ_ID,flash_command_add);
printk("Physicaladdress=%X\r\n",K9F1G_DATA_ADDRESS);
printk("Physicaladdress+1<<31=%X\r\n",(K9F1G_DATA_ADDRESS+(1<<31)));
printk("flash_command_add=%X\r\n",flash_command_add);
printk("flash_address_add=%X\r\n",flash_address_add);
printk("flash_data_add=%X\r\n",flash_data_add);
K9F1G_CE_LOW();
*(volatileunsignedchar*)(flash_command_add)=FLASH_READ_ID;
*(volatileunsignedchar*)(flash_address_add)=0;
while(0==K9F1G_statu());
//delay_flash(500);
for(i=0;i<5;i++)
{
id[i]=*(volatileunsignedchar*)(flash_data_add);
while(0==K9F1G_statu());
}
K9F1G_CE_HIGH();
printk("theNANDflashdeviceid=");
for(i=0;i<5;i++)
{
printk("%X",id[i]);
}
}
/***************************************************************************************************
functionname:
K9F1G_init_CPU(void)
functiondescription:
toinittheCPUregisterstosetthePA0,PC3,PC1intooutput
function.
****************************************************************************************************/
voidK9F1G_init_CPU(void){
AT91_SYS->PIOC_PER =AT91C_PIO_PC13;//enabletheperipheralcontrol
AT91_SYS->PIOC_OER =AT91C_PIO_PC13;//outputenable
AT91_SYS->PIOC_SODR =AT91C_PIO_PC13;
#if0
/*initthePA0*/
AT91_SYS->PIOC_MDDR =AT91C_PIO_PC13;//disabletheMultifunction
AT91_SYS->PIOC_PER =AT91C_PIO_PC13;//enabletheperipheralcontrol
AT91_SYS->PIOC_OER =AT91C_PIO_PC13;//outputenable
AT91_SYS->PIOC_IFDR =AT91C_PIO_PC13;
//AT91_SYS->PIOA_CODR =AT91C_PIO_PA0;
AT91_SYS->PIOC_IDR =AT91C_PIO_PC13;//disabletheinterrupt
//AT91_SYS->PIOC_MDDR =AT91C_PIO_PC13;//disabletheMultifunction
//AT91_SYS->PIOA_PPUER=AT91C_PIO_PA0;
//AT91_SYS->PIOA_OWER =AT91C_PIO_PA0;//enablewritethePIO_ODSRforPA0
AT91_SYS->PIOC_SODR =AT91C_PIO_PC13;
//AT91_SYS->PIOA_ODSR =AT91C_PIO_PA0;
/*initthePC1andPC3for*/
/*shouldinitthePC1andPC3asSMCsignal*/
AT91_SYS->PIOC_PER=AT91_SYS->PIOC_PER|AT91C_PIO_PC1|AT91C_PIO_PC3;//enabletheperipheralcontrol
AT91