移植FATFS的NANDFLASH驱动

合集下载

STM32F407移植FATFS文件系统(版本R0.09b)到SD卡(硬件SPI总线)

STM32F407移植FATFS文件系统(版本R0.09b)到SD卡(硬件SPI总线)

STM32F407移植FATFS⽂件系统(版本R0.09b)到SD卡(硬件SPI总线)⼀、序⾔经常在⽹上、群⾥看到很多⼈问关于STM32的FATFS⽂件系统移植的问题,刚好⾃⼰最近的⼯程项⽬需要使⽤SD卡,为了让⼤家少⾛弯路,我把我的学习过程和⽅法贡献给⼤家。

⼆、SD卡简介安全数字卡(简称SD卡),最初引进应⽤于⼿持式可携带电⼦产品,在⼀个⼩尺⼨产品上可靠的存储数据,如移动电话,数码相机等。

1、SD卡简介请参考如下博⽂2、SD卡种类请参考如下博⽂3、SD卡简介和种类请参考如下博⽂4、MMC、SD、TF、SDIO、SDMMC简介三、SD卡总线协议简介SD卡⽀持2种总线协议,即SDIO总线协议和SPI总线协议。

SDIO总线协议速度快,SPI总线相对SDIO总线速度要慢很多,但是⽬前市⾯上很多单⽚机不⽀持SDIO总线协议,只有中⾼端单⽚机(例如:STM32F407)才⽀持SDIO总线协议。

1、SDIO总线协议利⽤该总线协议,可以使⽤最多四条数据线实现主机与SD卡之间的数据传输,所以速度相对⽽⾔可以达到最⾼,但是需要主机具有SDIO控制器,才可以使⽤该协议。

2、SPI总线协议如果主机不⽀持SDIO协议,那么可以使⽤SPI协议对SD卡进⾏操作。

虽然速度⽐SDIO慢,但是硬件上更加简单,只需要四根线便可以实现与SD卡进⾏通讯。

3、SDIO协议与SPI协议的⽐较SDIO协议与SPI协议相较⽽⾔,SDIO协议读写SD卡的速度更快,再加上其⽀持4线模式,即利⽤4条数据线,同时发送4Bits数据,数据的传输效率就更⾼了,但是由于使⽤的引脚较多,所以也导致了控制相对⽐较困难。

⽽SPI外设只具有两条数据线MISO和MOSI,分别⽤作数据的输⼊和输出,由于引脚较少,所以控制相对较容易。

但是,数据的传输效率相对⽽⾔就⽐较低了。

但是,两中协议的共同之处在于:均是通过命令实现对SD卡的控制,仍然是结合状态机实现编程。

4、SD卡如何⼯作在SPI模式下当SD卡上电之后,只有第⼀次发送的CMD0命令才可以选择SD卡⼯作在SPI模式下。

linux2.6nandflash驱动说明

linux2.6nandflash驱动说明

linux2.6nandflash驱动说明linux2.6.14移植---nandflash--by farsight 一、实验目的本实验是在前面网络芯片驱动实验的基础上,加入了对nandflash的支持,从而进一步完善系统结构,通过移植的过程来了解nandflash的移植方法。

二、实验设备1、虚拟机ubuntu7.042、优龙公司开发板fs2410以及开发板中移植好的u-boot1.1.43、串口线和网线、电源各一根三、实验步骤1、指明分区信息在arch/arm/mach-s3c2410/decs.c文件中:root@farsight:/source/kernel/linux-2.6.14# vim arch/arm/mach-s3c2410/devs.c在文件中添加以下信息:1、建立分区表:#include#include#includestatic struct mtd_partition partition_info[]={{name: "kernel",size: 0x001c0000,offset: 0x00040000,},{name: "root",size: 0x02300000,offset: 0x00200000,},{name: "yaffs",size: 0x01B00000,offset: 0x02500000,}};2、加入nandflash分区struct s3c2410_nand_set nandset={nr_partitions: 4,partitions:partition_info,};3、建立nandflash文件支持:struct s3c2410_platform_nand superlpplatform={tacls:0,twrph0:30,twrph1:0,sets:&nandset,nr_sets:1,};2、加入nand flash芯片支持到nand flash驱动修改此文件中的s3c_device_nand结构体变量,添加对dev成员的赋值:struct platform_device s3c_device_nand = {.name = "s3c2410-nand",.id = -1,.num_resources = ARRAY_SIZE(s3c_nand_resource),.resource = s3c_nand_resource,.dev={.platform_data=&superlpplatform}};3、指定启动时初始化kernel启动时依据我们对分区的设置进行初始配置,修改arch/arm/mach-s3c2410/mach-smdk2410.c文件root@farsight:/source/kernel/linux-2.6.14#vim arch/arm/mach-s3c2410/mach-smdk2410.c 修改smdk2410_devices[].指明初始化时包括我们在前面所设置的flash信息static struct platform_device *smdk2410_devices[] __initdata = {&s3c_device_usb,&s3c_device_lcd,&s3c_device_wdt,&s3c_device_i2c,&s3c_device_iis,&s3c_device_nand, /*added*/};4、配置MTDDevice Drivers --->Memory Technology Devices (MTD) --->[*] MTD partitioning supportNAND Flash Device Drivers ---><*> NAND Device Support<*> NAND Flash support for S3C2410/S3C2440 SoC5、编译内核root@farsight:/source/kernel/linux-2.6.14# make zImageroot@farsight:/source/kernel/linux-2.6.14# cp arch/arm/boot/zImage /tftpboot 启动开发板进行下载。

Nand flash驱动移植及带硬件Ecc的Jffs2文件系统制作

Nand flash驱动移植及带硬件Ecc的Jffs2文件系统制作

Nand flash驱动移植及带硬件Ecc的Jffs2文件系统制作cd /new_disk/weiyan/linux-2.6.25vi arch/arm/mach-s3c2440/mach-smdk2440.c修改板级配置文件,为统一驱动的配置,设备的配置信息一般在此文件中添加。

1)添加头文件#include <linux/mtd/nand.h>#include <linux/mtd/nand_ecc.h>#include <linux/mtd/partitions.h>#include <asm/plat-s3c/nand.h>#include <asm/plat-s3c24xx/pm.h>2)添加nand划分信息static struct mtd_partition wy_nand_part[] = {[0] = { //u-boot及内存存放的分区.name = "BOOT",.size = SZ_2M,.offset = 0,},[1] = { //文件系统存放的分区.name = "ROOTFS",.offset = SZ_2M,.size = SZ_32M,},[2] = { //剩余空间.name = "BACKUP",.offset = SZ_32M + SZ_2M,.size = SZ_32M - SZ_2M,},};static struct s3c2410_nand_set wy_nand_sets[] = {[0] = {.name = "NAND",.nr_chips = 1,.nr_partitions = ARRAY_SIZE(wy_nand_part),.partitions = wy_nand_part,},};3)添加nand flash的读写匹配时间,各时间定义如图static struct s3c2410_platform_nand wy_nand_info = {.tacls = 10,.twrph0 = 25,.twrph1 = 10,.nr_sets = ARRAY_SIZE(wy_nand_sets),.sets = wy_nand_sets,};4)添加nand设备到初始化表static struct platform_device *smdk2440_devices[] __initdata = { ……(此处省略其他设备,添加时请注意。

移植FATFS的NANDFLASH驱动

移植FATFS的NANDFLASH驱动

STM32EWARM开发过程简介之五--移植FATFS的NANDFLASH驱动一,建立工程FATFS源码1,在/fsw/ff/00index_e.html上下载ff007c.zip,并把ff007c.zip里面的src文件夹复制到D:\works\EK-STM3210E-UCOSII下,并改名为Fatfs;2,在IDE工程中右击选择“Add Group”建立“FATFS”文件组,并在“FATFS”上右击选择“Add Files”添加D:\works\EK-STM3210E-UCOSII\Fatfs下的C文件;3,把D:\works\EK-STM3210E-UCOSII\Fatfs文件夹目录添加到项目头文件搜索路径中,如:$PROJ_DIR$\..\..\Fatfs二,移植NANDFLASH驱动接口1,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.c复制到D:\works\EK-STM3210E-UCOSII\Drivers下,并加入到工程的DRV文件组;2,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.h复制到D:\works\EK-STM3210E-UCOSII\Include下;3,在fsmc_nand.c前添加上#include"stm32f10x_conf.h",并把系统中的"stm32f10x_conf.h"文件的/*#include"stm32f10x_fsmc.h"*/注释打开;三,修改FATFS的配置文件1,把D:\works\EK-STM3210E-UCOSII\Fatfs下的ff.h中的宏定义:#define_USE_MKFS0#define_CODE_PAGE932#define_FS_RPATH0#define_MAX_SS512修改为:#define_USE_MKFS1#define_CODE_PAGE936#define_MAX_SS2048#define_FS_RPATH12,把D:\works\EK-STM3210E-UCOSII\Fatfs下的integer.h的宏定义:typedef enum{FALSE=0,TRUE}BOOL;修改为:typedef bool BOOL;//typedef enum{FALSE=0,TRUE}BOOL;四,修改FATFS的DISK/IO接口1,把diskio.c复制后改名为nandio.c替换掉工程中的diskio.c,并添加到EWARM的工程中的“FATFS”文件组;2,媒介初始化直接返回正常的0:DSTATUS disk_initialize(BYTE drv){return0;}3,媒介状态查询直接返回正常的0:DSTATUS disk_status(BYTE drv){return0;}4,取系统系统直接返回0(自己可以按格式修改为真实时间):DWORD get_fattime(void){return0;}5,媒介控制接口:DRESULT disk_ioctl(BYTE drv,BYTE ctrl,void*buff){DRESULT res=RES_OK;uint32_t result;if(drv){return RES_PARERR;}switch(ctrl){case CTRL_SYNC:break;case GET_BLOCK_SIZE:*(DWORD*)buff=NAND_BLOCK_SIZE;break;case GET_SECTOR_COUNT:*(DWORD*)buff=(((NAND_MAX_ZONE/2)*NAND_ZONE_SIZE)*NAND_BLOCK_SIZE);break;case GET_SECTOR_SIZE:*(WORD*)buff=NAND_PAGE_SIZE;break;default:res=RES_PARERR;break;}return res;}6,媒介多扇区读接口:DRESULT disk_read(BYTE drv,BYTE*buff,DWORD sector,BYTE count){uint32_t result;if(drv||!count){return RES_PARERR;}result=FSMC_NAND_ReadSmallPage(buff,sector,count);if(result&NAND_READY){return RES_OK;}else{return RES_ERROR;}}7,媒介多扇区写接口:#if_READONLY==0DRESULT disk_write(BYTE drv,const BYTE*buff,DWORD sector,BYTE count) {uint32_t result;uint32_t BackupBlockAddr;uint32_t WriteBlockAddr;uint16_t IndexTmp=0;uint16_t OffsetPage;/*NAND memory write page at block address*/WriteBlockAddr=(sector/NAND_BLOCK_SIZE);/*NAND memory backup block address*/BackupBlockAddr=(WriteBlockAddr+(NAND_MAX_ZONE/2)*NAND_ZONE_SIZE);OffsetPage=sector%NAND_BLOCK_SIZE;if(drv||!count){return RES_PARERR;}/*Erase the NAND backup Block*/result=FSMC_NAND_EraseBlock(BackupBlockAddr*NAND_BLOCK_SIZE);/*Backup the NAND Write Block to High zone*/for(IndexTmp=0;IndexTmp<NAND_BLOCK_SIZE;IndexTmp++){FSMC_NAND_MoveSmallPage (WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp);}/*Erase the NAND Write Block*/result=FSMC_NAND_EraseBlock(WriteBlockAddr*NAND_BLOCK_SIZE);/*return write the block with modify*/for(IndexTmp=0;IndexTmp<NAND_BLOCK_SIZE;IndexTmp++){if((IndexTmp>=OffsetPage)&&(IndexTmp<(OffsetPage+count))){FSMC_NAND_WriteSmallPage((uint8_t*)buff,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,1);buff=(uint8_t*)buff+NAND_PAGE_SIZE;}else{FSMC_NAND_MoveSmallPage (BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp);}}if(result==NAND_READY){return RES_OK;}else{return RES_ERROR;}}#endif/*_READONLY*/五,调用接口及测试代码1,调用接口,先初始化FSMC和NANDFLASH://NANDFLASH HY27UF081G2A-TPCB#define NAND_HY_MakerID0xAD#define NAND_HY_DeviceID0xF1/*Configure the NAND FLASH*/void NAND_Configuration(void){NAND_IDTypeDef NAND_ID;/*Enable the FSMC Clock*/RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);/*FSMC Initialization*/FSMC_NAND_Init();/*NAND read ID command*/FSMC_NAND_ReadID(&NAND_ID);/*Verify the NAND ID*/if((NAND_ID.Maker_ID==NAND_ST_MakerID)&&(NAND_ID.Device_ID==NAND_ST_DeviceID)){printf("ST NANDFLASH");}elseif((NAND_ID.Maker_ID==NAND_HY_MakerID)&&(NAND_ID.Device_ID==NAND_HY_DeviceID)) {printf("HY27UF081G2A-TPCB");}printf("ID=0x%x%x%x%x\n\r",NAND_ID.Maker_ID,NAND_ID.Device_ID,NAND_ID.Third_ID,NAND_ID.Fourth_ID); }2,然后对媒介格式化,创建读写文件:void test_fatfs(void){FATFS fs;FIL fl;FATFS*pfs;DWORD clust;unsigned int r,w,i;FRESULT res;//NF_CHKDSK(0,1024);display_page(0,0);//for mountres=f_mount(0,&fs);printf("f_mount=%x\n\r",res);//for format//res=f_mkfs(0,1,2048);//MUST Format for New NANDFLASH!!! //printf("f_mkfs=%x\n\r",res);//forpfs=&fs;res=f_getfree("/",&clust,&pfs);printf("f_getfree=%x\n\r",res);printf("\n\r%lu MB total drive space.""\n\r%lu MB available.\n\r",(DWORD)(pfs->max_clust-2)*pfs->csize/2/1024,clust*pfs->csize/2/1024);//for readres=f_open(&fl,"/test2.dat",FA_OPEN_EXISTING|FA_READ);printf("f_open=%x\n\r",res);for(i=0;i<2;i++){for(r=0;r<NAND_PAGE_SIZE;r++){RxBuffer[r]=0xff;}res=f_read(&fl,RxBuffer,NAND_PAGE_SIZE,&r);printf("f_read=%x\n\r",res);if(res||r==0)break;for(r=0;r<NAND_PAGE_SIZE;r++){printf("D[%08x]=%02x",(i*NAND_PAGE_SIZE+r),RxBuffer[r]);if((r%8)==7){printf("\n\r");}}}f_close(&fl);//for writeres=f_open(&fl,"/test2.dat",FA_CREATE_ALWAYS|FA_WRITE); printf("f_open=%x\n\r",res);for(i=0;i<2;i++){for(w=0;w<NAND_PAGE_SIZE;w++){TxBuffer[w]=((w<<0)&0xff);}res=f_write(&fl,TxBuffer,NAND_PAGE_SIZE,&w);printf("f_write=%x\n\r",res);if(res||w<NAND_PAGE_SIZE)break;}f_close(&fl);//for umountf_mount(0,NULL);}六,编写NANDFLASH接口1,fsmc_nand.c文件:/*Includes------------------------------------------------------------------*/ #include"fsmc_nand.h"#include"stm32f10x_conf.h"/**@addtogroup StdPeriph_Examples*@{*//**@addtogroup FSMC_NAND*@{*//*Private typedef-----------------------------------------------------------*/ /*Private define------------------------------------------------------------*/#define FSMC_Bank_NAND FSMC_Bank2_NAND#define Bank_NAND_ADDR Bank2_NAND_ADDR#define Bank2_NAND_ADDR((uint32_t)0x70000000)/*Private macro-------------------------------------------------------------*//*Private variables---------------------------------------------------------*//*Private function prototypes-----------------------------------------------*//*Private functions---------------------------------------------------------*//***@brief Configures the FSMC and GPIOs to interface with the NAND memory. *This function must be called before any write/read operation*on the NAND.*@param None*@retval:None*/void FSMC_NAND_Init(void){GPIO_InitTypeDef GPIO_InitStructure;FSMC_NANDInitTypeDef FSMC_NANDInitStructure;FSMC_NAND_PCCARDTimingInitTypeDef p;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE| RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);/*--GPIO Configuration------------------------------------------------------*//*CLE,ALE,D0->D3,NOE,NWE and NCE2NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12|GPIO_Pin_14|GPIO_Pin_15|GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_Init(GPIOD,&GPIO_InitStructure);/*D4->D7NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; GPIO_Init(GPIOE,&GPIO_InitStructure);/*NWAIT NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOD,&GPIO_InitStructure);/*INT2NAND pin configuration*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_Init(GPIOG,&GPIO_InitStructure);/*--FSMC Configuration------------------------------------------------------*/p.FSMC_SetupTime=0x1;p.FSMC_WaitSetupTime=0x3;p.FSMC_HoldSetupTime=0x2;p.FSMC_HiZSetupTime=0x1;FSMC_NANDInitStructure.FSMC_Bank=FSMC_Bank2_NAND;FSMC_NANDInitStructure.FSMC_Waitfeature=FSMC_Waitfeature_Enable;FSMC_NANDInitStructure.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_8b; FSMC_NANDInitStructure.FSMC_ECC=FSMC_ECC_Enable;FSMC_NANDInitStructure.FSMC_ECCPageSize=FSMC_ECCPageSize_512Bytes; FSMC_NANDInitStructure.FSMC_TCLRSetupTime=0x00;FSMC_NANDInitStructure.FSMC_TARSetupTime=0x00;FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct=&p;FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct=&p;FSMC_NANDInit(&FSMC_NANDInitStructure);/*FSMC NAND Bank Cmd Test*/FSMC_NANDCmd(FSMC_Bank2_NAND,ENABLE);}/***@brief Reads NAND memory's ID.*@param NAND_ID:pointer to a NAND_IDTypeDef structure which will hold *the Manufacturer and Device ID.*@retval:None*/void FSMC_NAND_ReadID(NAND_IDTypeDef*NAND_ID){uint32_t data=0;/*Send Command to the command area*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_READID; /*Send Address to the address area*/*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=NAND_CMD_IDADDR;/*Sequence to read ID from NAND flash*/data=*(__IO uint32_t*)(Bank_NAND_ADDR|DATA_AREA);NAND_ID->Maker_ID=DATA_1st_CYCLE(data);NAND_ID->Device_ID=DATA_2nd_CYCLE(data);NAND_ID->Third_ID=DATA_3rd_CYCLE(data);NAND_ID->Fourth_ID=DATA_4th_CYCLE(data);}/***@brief This routine is for move one2048Bytes Page size to an other2048Bytes Page.*the copy-back program is permitted just between odd address pages or even address pages. *@param SourcePageAddress:Source page address*@param TargetPageAddress:Target page address*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*And the new status of the increment address operation.It can be:*-NAND_VALID_ADDRESS:When the new address is valid address*-NAND_INVALID_ADDRESS:When the new address is invalid address*/uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress,uint32_t TargetPageAddress) {uint32_t status=NAND_READY;uint32_t data=0xff;/*Page write command and address*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE0;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(SourcePageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE1;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE2;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(TargetPageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_MOVE3;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Check status for successful operation*/status=FSMC_NAND_GetStatus();data=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);if(!(data&0x1))status=NAND_READY;return(status);}/***@brief This routine is for writing one or several2048Bytes Page size.*@param pBuffer:pointer on the Buffer containing data to be written*@param PageAddress:First page address*@param NumPageToWrite:Number of page to write*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*And the new status of the increment address operation.It can be:*-NAND_VALID_ADDRESS:When the new address is valid address*-NAND_INVALID_ADDRESS:When the new address is invalid address*/uint32_t FSMC_NAND_WriteSmallPage(uint8_t*pBuffer,uint32_t PageAddress,uint32_t NumPageToWrite){uint32_t index=0x00,numpagewritten=0x00,addressstatus=NAND_VALID_ADDRESS;uint32_t status=NAND_READY,size=0x00;uint32_t data=0xff;while((NumPageToWrite!=0x00)&&(addressstatus==NAND_VALID_ADDRESS)&&(status==NAND_READY)) {/*Page write command and address*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_WRITE0;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(PageAddress);/*Calculate the size*/size=NAND_PAGE_SIZE+(NAND_PAGE_SIZE*numpagewritten);/*Write data*/for(;index<size;index++){*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA)=pBuffer[index];}*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_WRITE1;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Check status for successful operation*/status=FSMC_NAND_GetStatus();data=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);if(!(data&0x1))status=NAND_READY;if(status==NAND_READY){numpagewritten++;NumPageToWrite--;/*Calculate Next small page Address*/if(PageAddress++>(NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) {addressstatus=NAND_INVALID_ADDRESS;}}}return(status|addressstatus);}/***@brief This routine is for sequential read from one or several*2048Bytes Page size.*@param pBuffer:pointer on the Buffer to fill*@param PageAddress:First page address*@param NumPageToRead:Number of page to read*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*And the new status of the increment address operation.It can be:*-NAND_VALID_ADDRESS:When the new address is valid address*-NAND_INVALID_ADDRESS:When the new address is invalid address*/uint32_t FSMC_NAND_ReadSmallPage(uint8_t*pBuffer,uint32_t PageAddress,uint32_t NumPageToRead) {uint32_t index=0x00,numpageread=0x00,addressstatus=NAND_VALID_ADDRESS;uint32_t status=NAND_READY,size=0x00;*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_READ1;while((NumPageToRead!=0x0)&&(addressstatus==NAND_VALID_ADDRESS)){/*Page Read command and page address*/*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_1st_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_2nd_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_READ2;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Calculate the size*/size=NAND_PAGE_SIZE+(NAND_PAGE_SIZE*numpageread);/*Get Data into Buffer*/for(;index<size;index++){pBuffer[index]=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);}numpageread++;NumPageToRead--;/*Calculate page address*/if(PageAddress++>(NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) {addressstatus=NAND_INVALID_ADDRESS;}}status=FSMC_NAND_GetStatus();return(status|addressstatus);}/***@brief This routine erase complete block from NAND FLASH*@param PageAddress:Any address into block to be erased*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate*a Timeout error*-NAND_READY:when memory is ready for the next operation*/uint32_t FSMC_NAND_EraseBlock(uint32_t PageAddress){uint32_t data=0xff,status=NAND_ERROR;*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_ERASE0;*(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_3rd_CYCLE(PageAddress); *(__IO uint8_t*)(Bank_NAND_ADDR|ADDR_AREA)=ADDR_4th_CYCLE(PageAddress);*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_ERASE1;while(GPIO_ReadInputDataBit(GPIOG,GPIO_Pin_6)==0);/*Read status operation------------------------------------*/FSMC_NAND_GetStatus();data=*(__IO uint8_t*)(Bank_NAND_ADDR|DATA_AREA);if(!(data&0x1))status=NAND_READY;return(status);}/***@brief This routine reset the NAND FLASH*@param None*@retval:NAND_READY*/uint32_t FSMC_NAND_Reset(void){*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_RESET;return(NAND_READY);}/***@brief Get the NAND operation status*@param None*@retval:New status of the NAND operation.This parameter can be:*-NAND_TIMEOUT_ERROR:when the previous operation generate *a Timeout error*-NAND_READY:when memory is ready for the next operation*/uint32_t FSMC_NAND_GetStatus(void){uint32_t timeout=0x1000000,status=NAND_READY;status=FSMC_NAND_ReadStatus();/*Wait for a NAND operation to complete or a TIMEOUT to occur*/ while((status!=NAND_READY)&&(timeout!=0x00)){status=FSMC_NAND_ReadStatus();timeout--;}if(timeout==0x00){status=NAND_TIMEOUT_ERROR;}/*Return the operation status*/return(status);}/***@brief Reads the NAND memory status using the Read status command *@param None*@retval:The status of the NAND memory.This parameter can be:*-NAND_BUSY:when memory is busy*-NAND_READY:when memory is ready for the next operation *-NAND_ERROR:when the previous operation gererates error*/uint32_t FSMC_NAND_ReadStatus(void){uint32_t data=0x00,status=NAND_BUSY;/*Read status operation------------------------------------*/*(__IO uint8_t*)(Bank_NAND_ADDR|CMD_AREA)=NAND_CMD_STATUS; data=*(__IO uint8_t*)(Bank_NAND_ADDR);if((data&NAND_ERROR)==NAND_ERROR){status=NAND_ERROR;}else if((data&NAND_READY)==NAND_READY){status=NAND_READY;}else{status=NAND_BUSY;}return(status);}2,fsmc_nand.h文件:/*Define to prevent recursive inclusion-------------------------------------*/ #ifndef__FSMC_NAND_H#define__FSMC_NAND_H/*Includes------------------------------------------------------------------*/ #include"stm32f10x.h"/*Exported types------------------------------------------------------------*/ typedef struct{uint8_t Maker_ID;uint8_t Device_ID;uint8_t Third_ID;uint8_t Fourth_ID;}NAND_IDTypeDef;typedef struct{uint16_t Zone;uint16_t Block;uint16_t Page;}NAND_ADDRESS;/*Exported constants--------------------------------------------------------*/ /*NAND Area definition for STM3210E-EVAL Board RevD*/#define CMD_AREA(uint32_t)(1<<16)/*A16=CLE high*/ #define ADDR_AREA(uint32_t)(1<<17)/*A17=ALE high*/#define DATA_AREA((uint32_t)0x00000000)/*FSMC NAND memory command*/#define NAND_CMD_READ1((uint8_t)0x00)#define NAND_CMD_READ2((uint8_t)0x30)#define NAND_CMD_WRITE0((uint8_t)0x80)#define NAND_CMD_WRITE1((uint8_t)0x10)#define NAND_CMD_MOVE0((uint8_t)0x00)#define NAND_CMD_MOVE1((uint8_t)0x35)#define NAND_CMD_MOVE2((uint8_t)0x85)#define NAND_CMD_MOVE3((uint8_t)0x10)#define NAND_CMD_ERASE0((uint8_t)0x60)#define NAND_CMD_ERASE1((uint8_t)0xD0)#define NAND_CMD_READID((uint8_t)0x90)#define NAND_CMD_IDADDR((uint8_t)0x00)#define NAND_CMD_STATUS((uint8_t)0x70)#define NAND_CMD_RESET((uint8_t)0xFF)/*NAND memory status*/#define NAND_VALID_ADDRESS((uint32_t)0x00000100)#define NAND_INVALID_ADDRESS((uint32_t)0x00000200)#define NAND_TIMEOUT_ERROR((uint32_t)0x00000400)#define NAND_BUSY((uint32_t)0x00000000)#define NAND_ERROR((uint32_t)0x00000001)#define NAND_READY((uint32_t)0x00000040)/*FSMC NAND memory parameters*///#define NAND_PAGE_SIZE((uint16_t)0x0200)/*512bytes per page w/o Spare Area*/ //#define NAND_BLOCK_SIZE((uint16_t)0x0020)/*32x512bytes pages per block*///#define NAND_ZONE_SIZE((uint16_t)0x0400)/*1024Block per zone*///#define NAND_SPARE_AREA_SIZE((uint16_t)0x0010)/*last16bytes as spare area*///#define NAND_MAX_ZONE((uint16_t)0x0004)/*4zones of1024block*//*FSMC NAND memory HY27UF081G2A-TPCB parameters*/#define NAND_PAGE_SIZE((uint16_t)0x0800)/*2048bytes per page w/o Spare Area*/ #define NAND_BLOCK_SIZE((uint16_t)0x0040)/*64x2048bytes pages per block*/#define NAND_ZONE_SIZE((uint16_t)0x0200)/*512Block per zone*/#define NAND_SPARE_AREA_SIZE((uint16_t)0x0040)/*last64bytes as spare area*/#define NAND_MAX_ZONE((uint16_t)0x0002)/*2zones of1024block*//*FSMC NAND memory data computation*/#define DATA_1st_CYCLE(DATA)(uint8_t)((DATA)&0xFF)/*1st data cycle*/#define DATA_2nd_CYCLE(DATA)(uint8_t)(((DATA)&0xFF00)>>8)/*2nd data cycle*/#define DATA_3rd_CYCLE(DATA)(uint8_t)(((DATA)&0xFF0000)>>16)/*3rd data cycle*/#define DATA_4th_CYCLE(DATA)(uint8_t)(((DATA)&0xFF000000)>>24)/*4th data cycle*//*FSMC NAND memory HY27UF081G2A-TPCB address computation*/#define ADDR_1st_CYCLE(PADDR)(uint8_t)(0x0)/*1st addressing cycle*/#define ADDR_2nd_CYCLE(PADDR)(uint8_t)(0x0)/*2nd addressing cycle*/#define ADDR_3rd_CYCLE(PADDR)(uint8_t)(PADDR&0xFF)/*3rd addressing cycle*/#define ADDR_4th_CYCLE(PADDR)(uint8_t)((PADDR>>8)&0xFF)/*4th addressing cycle*//*Exported macro------------------------------------------------------------*//*Exported functions-------------------------------------------------------*/void FSMC_NAND_Init(void);void FSMC_NAND_ReadID(NAND_IDTypeDef*NAND_ID);uint32_t FSMC_NAND_WriteSmallPage(uint8_t*pBuffer,uint32_t Address,uint32_t NumPageToWrite); uint32_t FSMC_NAND_ReadSmallPage(uint8_t*pBuffer,uint32_t Address,uint32_t NumPageToRead);uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress,uint32_t TargetPageAddress);//uint32_t FSMC_NAND_WriteSpareArea(uint8_t*pBuffer,NAND_ADDRESS Address,uint32_t NumSpareAreaTowrite); //uint32_t FSMC_NAND_ReadSpareArea(uint8_t*pBuffer,NAND_ADDRESS Address,uint32_t NumSpareAreaToRead); uint32_t FSMC_NAND_EraseBlock(uint32_t Address);uint32_t FSMC_NAND_Reset(void);uint32_t FSMC_NAND_GetStatus(void);uint32_t FSMC_NAND_ReadStatus(void);//uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS*Address);#endif/*__FSMC_NAND_H*/七,NFTL代码层有关NFTL代码,自行处理。

STM32F429利用CUBEMX移植FATFS文件系统成功!!!

STM32F429利用CUBEMX移植FATFS文件系统成功!!!

STM32F429利⽤CUBEMX移植FATFS⽂件系统成功⽂件系统对于⼀个专业的嵌⼊式系统⽽⾔必不可少,博主这两天利⽤STM32F429成功移植了FATFS,特来分享⼀下学习⼼得,避免新⼈采坑。

我是在SD卡上实现的,因此你需要利⽤SDIO接⼝扩展⼀个SD卡,具体实现如下:进⼊Configuration界⾯,基本参数的不⽤配置,但是需要开启中断和DMA,配置如下:点击OK,关闭Configuration窗⼝。

在MiddleWares下拉列表中打开FATFS,选中SD卡。

进⼊FATFS的Configuration界⾯,配置如下:解释⼀下改动的两个参数,⼀个选择读取中⽂类型的⽂件,另⼀个是使能长字节名称命名(如果不选择,只有8字节,超过8字节会出现Hardware Fault),⽂件系统的磁盘选择3个(⽅便挂载其他内存)最后,再设置选择中,把stack的空间⼤⼩设置为0X1000⼤⼩。

以上,便完成可在CUBEMX中配置FATFS⽂件系统,点击⽣成⼯程⽂件。

可以看到,在⼯程⽬录下,⽣成了这样⼀些⽂件:具体什么内容先不管,我们需要在main中添加⼀些代码测试我们的⽂件管理系统。

⾸先添加如下所⽰的全局变量:/* USER CODE BEGIN PV *//* Private variables ---------------------------------------------------------*/uint32_t byteswritten; /* File write counts */uint32_t bytesread; /* File read counts */uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */uint8_t rtext[100]; /* File read buffers */char filename[] = "STM32cube.txt";/* USER CODE END PV */在初始化之后,while(1)之前添加如下代码int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_TIM6_Init();MX_FMC_Init();MX_USART1_UART_Init();MX_TIM7_Init();MX_USART3_UART_Init();MX_DMA2D_Init();MX_LTDC_Init();MX_SPI5_Init();MX_SDIO_SD_Init();MX_FATFS_Init();/* Initialize interrupts */MX_NVIC_Init();/* USER CODE BEGIN 2 */delay_init(180);LED_Init();KEY_Init();SDRAM_Init();LCD_Init();ESP8266_Init(); //WIFI ͨѶģ¿éW25QXX_Init(); //Íⲿ SPI FLASH --- 32MBFTL_Init(); //Íⲿ NAND FLASH --- 512MBmy_mem_init(SRAMIN); //½«SRAMÖÐ60KBÄÚ´æÓÃÓÚÄÚ´æ¹ÜÀíϵͳ my_mem_init(SRAMEX); //½«SDRAMÖÐ15MBÄÚ´æÓÃÓÚÄÚ´æ¹ÜÀíϵͳ ITEnable();PeriphInit();GUI_Init();Show_SDcard_Info();LCD_ShowString(400,400,400,24,24,"****** FatFs Example ******");retSD = f_mount(&SDFatFS, "0:", 0);if(retSD){LCD_ShowString(400,440,400,24,24,"****** mount error ******");LCD_ShowNum(800,440,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,440,400,24,24,"****** mount success ******");retSD = f_open(&SDFile, filename, FA_CREATE_ALWAYS | FA_WRITE);if(retSD){LCD_ShowString(400,480,400,24,24,"****** open file error ******");LCD_ShowNum(800,480,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,480,400,24,24,"****** open file success ******");retSD = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten);if(retSD){LCD_ShowString(400,520,400,24,24,"****** write file error ******");LCD_ShowNum(800,520,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,520,400,24,24,"****** write file success ******");retSD = f_close(&SDFile);if(retSD){LCD_ShowString(400,560,400,24,24,"****** close file error ******");LCD_ShowNum(800,560,retSD,2,24);Error_Handler();}elseLCD_ShowString(400,560,400,24,24,"****** close file success ******");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}OK,编译通过,下载程序,运⾏结果如下所⽰:之后你便可以在SD卡中找到你创建的⽂件STM32cube.txt。

NAND Flash驱动程序结构

NAND Flash驱动程序结构

NAND Flash驱动程序1、NAND Flash驱动程序框架FAT文件系统下的NAND Flash驱动程序采用了分层结构。

驱动程序的上层是Flash抽象层,是物理操作无关层,该层对NAND Flash的操作进行抽象,并采用一定的策略平衡了NAND Flash的擦写。

NAND Flash驱动程序的结构如图5.5所示。

图5.5 FAT下NAND Flash驱动结构在图中:File System即文件系统。

在这里,采用的是FAT文件系统。

FAT文件系统是一种采用链式分配方式的文件系统。

并没有对NAND Flash的特点优化,因此需要在下层的驱动程序做优化。

Flash Driver即NAND Flash驱动程序。

对上层的文件系统提供以DSK为前缀的流驱动接口。

该层驱动程序本身分为两层:FAL层、F MD层。

(1)、FAL层即Flash Abstraction Layer,Flash抽象层。

该层主要提供三个功能:A、将物理的Flash抽象成统一的接口提供给上层的文件系统。

B、将逻辑扇区地址转换成物理扇区地址。

上层的FAT文件系统使用的是逻辑扇区地址,并不是真正的物理扇区,其转换由FAL实现。

C、对Flash实现损耗平衡("Wear-level")。

为了避免反复的擦写Flash的同一个块,需要一种策略来减少反复的擦写块。

(2)、FMD层即Flash Media Driver,Flash介质驱动层。

该层实现FAL层的请求,对Flash物理扇区进行操作。

Flash Hardware即NAND Flash物理芯片。

2、FAL层(Flash Abstraction Layer)1)函数接口定义FAL层对上的函数接口也就是整个NAND Flash驱动程序的对外接口,由于NAND Flash 是块设备,Windows CE中块设备采用的是流驱动接口,流驱动接口是一个标准的统一接口,只是各个驱动的前缀不同,在这里NAND Flash函数接口的前缀为“DSK”,这个前缀也使得Windows CE将“DSKxx:”的文件名看作为设备,使得我们能够通过Windows CE标准的Win32 API,如CreateFile、DeviceIOControl等来对设备进行打开、读写等操作。

在pc机上移植fatfs文件系统(windowslinux)(一)

在pc机上移植fatfs文件系统(windowslinux)(一)

在pc机上移植fatfs⽂件系统(windowslinux)(⼀)开始我的技术⽣涯~哈哈,⽼⼤给我分配了⼀个以前都没接触到的任务。

在PC机上移植fatfs⽂件系统。

以前我认为的移植是调⽤底层提供的API接⼝,在PC机上模拟,测试通过后再移植到⽬标板上。

这次的移植竟然是移植到PC机上。

我的开始考虑到的硬件基础:⽂件系统要在硬件存储介质上运⾏,例如u盘啊、SD卡啊。

那这次没有硬件设备,怎么模拟呢。

diskio.c是和底层硬件相关的⽂件。

解决⽅案是⽤创建⼀个具有⼀定⼤⼩的⽂件来作为存储载体。

开始有了⼀点思路。

我就开始了⼈⽣的第⼀次移植。

我⽤的是fatfs 0.08b 最新版。

0.08b版本多了⼏个API接⼝。

并且前辈们反映移植遇到的问题解决了。

下到了源代码有2个⽂件夹。

doc ⾥⾯我没仔细看。

src⾥⾯就是源代码了。

diskio.c是⾃⼰写的。

是⼀些贴近底层硬件的函数。

我看了CSDN⾥⾯⼀些前辈关于移植fatfs的资料。

⾸先第⼀步就是配置ffconf.hfatfs有2个版本。

⼀个是tiny版本。

这个版本适合⽐较⼩的RAM,eg:单⽚机。

我⽤的是正常版。

#define_FS_TINY0/* 0:Normal or 1:Tiny */因为移植后要测试读与写是否匹配,所以设置为读写功能。

#define _FS_READONLY 0/* 0:Read/Write or 1:Read only */#define _FS_MINIMIZE3/* 0 to 3 */ 我⽤了全部功能,因为没要求要裁剪。

这个具体实现以后再慢慢琢磨。

#define_USE_MKFS1/* 0:Disable or 1:Enable */ 如果是在PC机上模拟,这个必须设置成1.因为这个参数,我搞了1天。

下⾯再详述。

#define _CODE_PAGE936 简体中⽂#define_MAX_SS512/* 512, 1024, 2048 or 4096 */ ⼀个扇区512字节#define_USE_ERASE1/* 0:Disable or 1:Enable */ 具备擦除功能,这个功能我⽬前还没测试过。

第12章 NandFlash驱动移植 Linux系统移植(第2版) 教学课件

第12章  NandFlash驱动移植 Linux系统移植(第2版) 教学课件

void __iomem
*IO_ADDR_R;
/*读地址*/
void __iomem
*IO_ADDR_W;
/*写地址*/
/*对字节的操作函数声明*/
uint8_t (*read_byte)(struct mtd_info *mtd);
/*读一个字节*/
u16
(*read_word)(struct mtd_info *mtd);
命令功能:表示对块擦除操作。 命令代码:首先写入60h进入擦写模式;
再输入块地址,即将要擦除的块;接着写 入D0h表示擦写结束。
7.Read Status
命令功能:表示读取内部状态寄存器值的 命令。
命令代码:70h。
12.1.2 NandFlash控制器
对于2440的NandFlash控制器中,寄存器有以下12种,与2410相比 寄存器的设置有些变换,具体寄存器中每个bit的设置可以参考 2440文档。
2.Read2
命令功能:表示将要读取NandFlash存储 空间中一页的后半部分,且将内置指针定 位到后半部分的第一个字节。
命令代码:01h。
3.Read ID
命令功能:表示读取NandFlash芯片的ID 号。
命令代码:90h。
4.Reset
命令功能:表示重新启动NandFlash芯片。 命令代码:FFh。
(*scan_bbt)(struct mtd_info *mtd);
/*进行附加错误状态检查操作*/
int
(*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

STM32 EWARM开发过程简介之五--移植FATFS的NANDFLASH驱动一,建立工程FATFS源码1,在/fsw/ff/00index_e.html上下载ff007c.zip,并把ff007c.zip里面的src文件夹复制到D:\works\EK-STM3210E-UCOSII下,并改名为Fatfs;2,在IDE工程中右击选择“Add Group”建立“FATFS”文件组,并在“FATFS”上右击选择“Add Files”添加D:\works\EK-STM3210E-UCOSII\Fatfs下的C文件;3,把D:\works\EK-STM3210E-UCOSII\Fatfs文件夹目录添加到项目头文件搜索路径中,如:$PROJ_DIR$\..\..\Fatfs二,移植NANDFLASH驱动接口1,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.c复制到D:\works\EK-STM3210E-UCOSII\Drivers下,并加入到工程的DRV文件组;2,把stm32f10x_stdperiph_lib_v3.0.0\Project\Examples\FSMC\NAND下的fsmc_nand.h复制到D:\works\EK-STM3210E-UCOSII\Include下;3,在fsmc_nand.c前添加上#include "stm32f10x_conf.h",并把系统中的"stm32f10x_conf.h"文件的/* #include "stm32f10x_fsmc.h" */注释打开;三,修改FATFS的配置文件1,把D:\works\EK-STM3210E-UCOSII\Fatfs下的ff.h中的宏定义:#define _USE_MKFS 0#define _CODE_PAGE 932#define _FS_RPATH 0#define _MAX_SS 512修改为:#define _USE_MKFS 1#define _CODE_PAGE 936#define _MAX_SS 2048#define _FS_RPATH 12,把D:\works\EK-STM3210E-UCOSII\Fatfs下的integer.h的宏定义:typedef enum { FALSE = 0, TRUE } BOOL;修改为:typedef bool BOOL;//typedef enum { FALSE = 0, TRUE } BOOL;四,修改FATFS的DISK/IO接口1,把diskio.c复制后改名为nandio.c替换掉工程中的diskio.c,并添加到EWARM的工程中的“FATFS”文件组;2,媒介初始化直接返回正常的0:DSTATUS disk_initialize (BYTE drv){ return 0;}3,媒介状态查询直接返回正常的0:DSTATUS disk_status (BYTE drv){ return 0;}4,取系统系统直接返回0(自己可以按格式修改为真实时间):DWORD get_fattime (void){ return 0;}5,媒介控制接口:DRESULT disk_ioctl (BYTE drv,BYTE ctrl, void *buff){DRESULT res = RES_OK;uint32_t result;if (drv){ return RES_PARERR;}switch(ctrl){case CTRL_SYNC:break;case GET_BLOCK_SIZE:*(DWORD*)buff = NAND_BLOCK_SIZE;break;case GET_SECTOR_COUNT:*(DWORD*)buff = (((NAND_MAX_ZONE/2) * NAND_ZONE_SIZE) * NAND_BLOCK_SIZE);break;case GET_SECTOR_SIZE:*(WORD*)buff = NAND_PAGE_SIZE;break;default:res = RES_PARERR;break;}return res;}6,媒介多扇区读接口:DRESULT disk_read (BYTE drv,BYTE *buff,DWORD sector,BYTE count){uint32_t result;if (drv || !count){ return RES_PARERR;}result = FSMC_NAND_ReadSmallPage(buff, sector, count);if(result & NAND_READY){ return RES_OK; }else { return RES_ERROR; }}7,媒介多扇区写接口:#if _READONLY == 0DRESULT disk_write (BYTE drv,const BYTE *buff,DWORD sector,BYTE count) {uint32_t result;uint32_t BackupBlockAddr;uint32_t WriteBlockAddr;uint16_t IndexTmp = 0;uint16_t OffsetPage;/* NAND memory write page at block address*/WriteBlockAddr = (sector/NAND_BLOCK_SIZE);/* NAND memory backup block address*/BackupBlockAddr = (WriteBlockAddr + (NAND_MAX_ZONE/2)*NAND_ZONE_SIZE);OffsetPage = sector%NAND_BLOCK_SIZE;if (drv || !count){ return RES_PARERR;}/* Erase the NAND backup Block */result = FSMC_NAND_EraseBlock(BackupBlockAddr*NAND_BLOCK_SIZE);/* Backup the NAND Write Block to High zone*/for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ ){FSMC_NAND_MoveSmallPage (WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp,BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp);}/* Erase the NAND Write Block */result = FSMC_NAND_EraseBlock(WriteBlockAddr*NAND_BLOCK_SIZE);/*return write the block with modify*/for (IndexTmp = 0; IndexTmp < NAND_BLOCK_SIZE; IndexTmp++ ){if((IndexTmp>=OffsetPage)&&(IndexTmp < (OffsetPage+count))){FSMC_NAND_WriteSmallPage((uint8_t *)buff, WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp, 1);buff = (uint8_t *)buff + NAND_PAGE_SIZE;}else{FSMC_NAND_MoveSmallPage (BackupBlockAddr*NAND_BLOCK_SIZE+IndexTmp,WriteBlockAddr*NAND_BLOCK_SIZE+IndexTmp);}}if(result == NAND_READY){ return RES_OK;}else { return RES_ERROR;}}#endif /* _READONLY */五,调用接口及测试代码1,调用接口,先初始化FSMC和NANDFLASH://NANDFLASH HY27UF081G2A-TPCB#define NAND_HY_MakerID 0xAD#define NAND_HY_DeviceID 0xF1/* Configure the NAND FLASH */void NAND_Configuration(void){NAND_IDTypeDef NAND_ID;/* Enable the FSMC Clock */RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);/* FSMC Initialization */FSMC_NAND_Init();/* NAND read ID command */FSMC_NAND_ReadID(&NAND_ID);/* Verify the NAND ID */if((NAND_ID.Maker_ID == NAND_ST_MakerID) && (NAND_ID.Device_ID == NAND_ST_DeviceID)){printf("ST NANDFLASH");}elseif((NAND_ID.Maker_ID == NAND_HY_MakerID) && (NAND_ID.Device_ID == NAND_HY_DeviceID)){printf("HY27UF081G2A-TPCB");}printf(" ID = 0x%x%x%x%x \n\r",NAND_ID.Maker_ID,NAND_ID.Device_ID,NAND_ID.Third_ID,NAND_ID.Fourth_ID); }2,然后对媒介格式化,创建读写文件:void test_fatfs(void){FATFS fs;FIL fl;FATFS *pfs;DWORD clust;unsigned int r,w,i;FRESULT res;// NF_CHKDSK(0,1024);display_page(0,0);// for mountres=f_mount(0,&fs);printf("f_mount=%x \n\r",res);// for format//res=f_mkfs(0,1,2048); //MUST Format for New NANDFLASH !!! //printf("f_mkfs=%x \n\r",res);// forpfs=&fs;res = f_getfree("/", &clust, &pfs);printf("f_getfree=%x \n\r",res);printf("\n\r%lu MB total drive space.""\n\r%lu MB available.\n\r",(DWORD)(pfs->max_clust - 2) * pfs->csize /2/1024,clust * pfs->csize /2/1024);// for readres=f_open(&fl,"/test2.dat",FA_OPEN_EXISTING | FA_READ);printf("f_open=%x \n\r",res);for(i=0;i<2;i++){for(r = 0; r < NAND_PAGE_SIZE; r++){RxBuffer[r]= 0xff;}res=f_read(&fl,RxBuffer,NAND_PAGE_SIZE,&r);printf("f_read=%x \n\r",res);if(res || r == 0)break;for(r = 0; r < NAND_PAGE_SIZE; r++){printf("D[%08x]=%02x ",(i*NAND_PAGE_SIZE+r),RxBuffer[r]);if((r%8)==7){printf("\n\r");}}}f_close(&fl);// for writeres=f_open(&fl,"/test2.dat",FA_CREATE_ALWAYS | FA_WRITE); printf("f_open=%x \n\r",res);for(i=0;i<2;i++){for(w = 0; w < NAND_PAGE_SIZE; w++){TxBuffer[w]=((w<<0)&0xff);}res=f_write(&fl,TxBuffer,NAND_PAGE_SIZE,&w);printf("f_write=%x \n\r",res);if(res || w<NAND_PAGE_SIZE)break;}f_close(&fl);// for umountf_mount(0,NULL);}六,编写NANDFLASH接口1,fsmc_nand.c文件:/* Includes ------------------------------------------------------------------*/ #include "fsmc_nand.h"#include "stm32f10x_conf.h"/** @addtogroup StdPeriph_Examples* @{*//** @addtogroup FSMC_NAND* @{*//* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/#define FSMC_Bank_NAND FSMC_Bank2_NAND#define Bank_NAND_ADDR Bank2_NAND_ADDR#define Bank2_NAND_ADDR ((uint32_t)0x70000000)/* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//*** @brief Configures the FSMC and GPIOs to interface with the NAND memory.* This function must be called before any write/read operation* on the NAND.* @param None* @retval : None*/void FSMC_NAND_Init(void){GPIO_InitTypeDef GPIO_InitStructure;FSMC_NANDInitTypeDef FSMC_NANDInitStructure;FSMC_NAND_PCCARDTimingInitTypeDef p;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);/*-- GPIO Configuration ------------------------------------------------------*//* CLE, ALE, D0->D3, NOE, NWE and NCE2 NAND pin configuration */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOD, &GPIO_InitStructure);/* D4->D7 NAND pin configuration */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;GPIO_Init(GPIOE, &GPIO_InitStructure);/* NWAIT NAND pin configuration */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOD, &GPIO_InitStructure);/* INT2 NAND pin configuration */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_Init(GPIOG, &GPIO_InitStructure);/*-- FSMC Configuration ------------------------------------------------------*/p.FSMC_SetupTime = 0x1;p.FSMC_WaitSetupTime = 0x3;p.FSMC_HoldSetupTime = 0x2;p.FSMC_HiZSetupTime = 0x1;FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;FSMC_NANDInit(&FSMC_NANDInitStructure);/* FSMC NAND Bank Cmd Test */FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);}/*** @brief Reads NAND memory's ID.* @param NAND_ID: pointer to a NAND_IDTypeDef structure which will hold * the Manufacturer and Device ID.* @retval : None*/void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID){uint32_t data = 0;/* Send Command to the command area */*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READID;/* Send Address to the address area */*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = NAND_CMD_IDADDR;/* Sequence to read ID from NAND flash */data = *(__IO uint32_t *)(Bank_NAND_ADDR | DATA_AREA);NAND_ID->Maker_ID = DATA_1st_CYCLE (data);NAND_ID->Device_ID = DATA_2nd_CYCLE (data);NAND_ID->Third_ID = DATA_3rd_CYCLE (data);NAND_ID->Fourth_ID = DATA_4th_CYCLE (data);}/*** @brief This routine is for move one 2048 Bytes Page size to an other 2048 Bytes Page.* the copy-back program is permitted just between odd address pages or even address pages.* @param SourcePageAddress: Source page address* @param T argetPageAddress: T arget page address* @retval : New status of the NAND operation. This parameter can be:* - NAND_TIMEOUT_ERROR: when the previous operation generate* a Timeout error* - NAND_READY: when memory is ready for the next operation* And the new status of the increment address operation. It can be:* - NAND_VALID_ADDRESS: When the new address is valid address* - NAND_INVALID_ADDRESS: When the new address is invalid address*/uint32_t FSMC_NAND_MoveSmallPage(uint32_t SourcePageAddress, uint32_t TargetPageAddress){uint32_t status = NAND_READY ;uint32_t data = 0xff;/* Page write command and address */*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE0;*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(SourcePageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(SourcePageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(SourcePageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(SourcePageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE1;while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE2;*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(TargetPageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(TargetPageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(TargetPageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(TargetPageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_MOVE3;while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );/* Check status for successful operation */status = FSMC_NAND_GetStatus();data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);if(!(data&0x1)) status = NAND_READY;return (status);}/*** @brief This routine is for writing one or several 2048 Bytes Page size.* @param pBuffer: pointer on the Buffer containing data to be written* @param PageAddress: First page address* @param NumPageToWrite: Number of page to write* @retval : New status of the NAND operation. This parameter can be:* - NAND_TIMEOUT_ERROR: when the previous operation generate* a Timeout error* - NAND_READY: when memory is ready for the next operation* And the new status of the increment address operation. It can be:* - NAND_VALID_ADDRESS: When the new address is valid address* - NAND_INVALID_ADDRESS: When the new address is invalid address*/uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, uint32_t PageAddress, uint32_t NumPageToWrite){uint32_t index = 0x00, numpagewritten = 0x00,addressstatus = NAND_VALID_ADDRESS;uint32_t status = NAND_READY, size = 0x00;uint32_t data = 0xff;while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY)) {/* Page write command and address */*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(PageAddress); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(PageAddress); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);/* Calculate the size */size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);/* Write data */for(; index < size; index++){*(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];}*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE1;while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );/* Check status for successful operation */status = FSMC_NAND_GetStatus();data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);if(!(data&0x1)) status = NAND_READY;if(status == NAND_READY){numpagewritten++; NumPageToWrite--;/* Calculate Next small page Address */if(PageAddress++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) { addressstatus = NAND_INVALID_ADDRESS;}}}return (status | addressstatus);}/*** @brief This routine is for sequential read from one or several* 2048 Bytes Page size.* @param pBuffer: pointer on the Buffer to fill* @param PageAddress: First page address* @param NumPageToRead: Number of page to read* @retval : New status of the NAND operation. This parameter can be:* - NAND_TIMEOUT_ERROR: when the previous operation generate* a Timeout error* - NAND_READY: when memory is ready for the next operation* And the new status of the increment address operation. It can be:* - NAND_VALID_ADDRESS: When the new address is valid address* - NAND_INVALID_ADDRESS: When the new address is invalid address*/uint32_t FSMC_NAND_ReadSmallPage(uint8_t *pBuffer, uint32_t PageAddress, uint32_t NumPageToRead) {uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;uint32_t status = NAND_READY, size = 0x00;*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ1;while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS)){/* Page Read command and page address */*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(PageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(PageAddress); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress); *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ2;while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );/* Calculate the size */size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);/* Get Data into Buffer */for(; index < size; index++){pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);}numpageread++; NumPageToRead--;/* Calculate page address */if(PageAddress++ > (NAND_MAX_ZONE*NAND_ZONE_SIZE*NAND_BLOCK_SIZE)) { addressstatus = NAND_INVALID_ADDRESS;}}status = FSMC_NAND_GetStatus();return (status | addressstatus);}/*** @brief This routine erase complete block from NAND FLASH* @param PageAddress: Any address into block to be erased* @retval :New status of the NAND operation. This parameter can be:* - NAND_TIMEOUT_ERROR: when the previous operation generate * a Timeout error* - NAND_READY: when memory is ready for the next operation*/uint32_t FSMC_NAND_EraseBlock(uint32_t PageAddress){uint32_t data = 0xff, status = NAND_ERROR;*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(PageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(PageAddress);*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );/* Read status operation ------------------------------------ */FSMC_NAND_GetStatus();data = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);if(!(data&0x1)) status = NAND_READY;return (status);}/*** @brief This routine reset the NAND FLASH* @param None* @retval :NAND_READY*/uint32_t FSMC_NAND_Reset(void){*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;return (NAND_READY);}/*** @brief Get the NAND operation status* @param None* @retval :New status of the NAND operation. This parameter can be:* - NAND_TIMEOUT_ERROR: when the previous operation generate * a Timeout error* - NAND_READY: when memory is ready for the next operation */uint32_t FSMC_NAND_GetStatus(void){uint32_t timeout = 0x1000000, status = NAND_READY;status = FSMC_NAND_ReadStatus();/* Wait for a NAND operation to complete or a TIMEOUT to occur */ while ((status != NAND_READY) &&( timeout != 0x00)){status = FSMC_NAND_ReadStatus();timeout --;}if(timeout == 0x00){status = NAND_TIMEOUT_ERROR;}/* Return the operation status */return (status);}/*** @brief Reads the NAND memory status using the Read status command * @param None* @retval :The status of the NAND memory. This parameter can be:* - NAND_BUSY: when memory is busy* - NAND_READY: when memory is ready for the next operation * - NAND_ERROR: when the previous operation gererates error */uint32_t FSMC_NAND_ReadStatus(void){uint32_t data = 0x00, status = NAND_BUSY;/* Read status operation ------------------------------------ */*(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;data = *(__IO uint8_t *)(Bank_NAND_ADDR);if((data & NAND_ERROR) == NAND_ERROR){status = NAND_ERROR;}else if((data & NAND_READY) == NAND_READY){status = NAND_READY;}else{status = NAND_BUSY;}return (status);}2,fsmc_nand.h文件:/* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __FSMC_NAND_H#define __FSMC_NAND_H/* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h"/* Exported types ------------------------------------------------------------*/ typedef struct{uint8_t Maker_ID;uint8_t Device_ID;uint8_t Third_ID;uint8_t Fourth_ID;}NAND_IDTypeDef;typedef struct{uint16_t Zone;uint16_t Block;uint16_t Page;} NAND_ADDRESS;/* Exported constants --------------------------------------------------------*/ /* NAND Area definition for STM3210E-EVAL Board RevD */#define CMD_AREA (uint32_t)(1<<16) /* A16 = CLE high */ #define ADDR_AREA (uint32_t)(1<<17) /* A17 = ALE high */#define DATA_AREA ((uint32_t)0x00000000)/* FSMC NAND memory command */#define NAND_CMD_READ1 ((uint8_t)0x00)#define NAND_CMD_READ2 ((uint8_t)0x30)#define NAND_CMD_WRITE0 ((uint8_t)0x80)#define NAND_CMD_WRITE1 ((uint8_t)0x10)#define NAND_CMD_MOVE0 ((uint8_t)0x00)#define NAND_CMD_MOVE1 ((uint8_t)0x35)#define NAND_CMD_MOVE2 ((uint8_t)0x85)#define NAND_CMD_MOVE3 ((uint8_t)0x10)#define NAND_CMD_ERASE0 ((uint8_t)0x60)#define NAND_CMD_ERASE1 ((uint8_t)0xD0)#define NAND_CMD_READID ((uint8_t)0x90)#define NAND_CMD_IDADDR ((uint8_t)0x00)#define NAND_CMD_STATUS ((uint8_t)0x70)#define NAND_CMD_RESET ((uint8_t)0xFF)/* NAND memory status */#define NAND_VALID_ADDRESS ((uint32_t)0x00000100)#define NAND_INVALID_ADDRESS ((uint32_t)0x00000200)#define NAND_TIMEOUT_ERROR ((uint32_t)0x00000400)#define NAND_BUSY ((uint32_t)0x00000000)#define NAND_ERROR ((uint32_t)0x00000001)#define NAND_READY ((uint32_t)0x00000040)/* FSMC NAND memory parameters *///#define NAND_PAGE_SIZE ((uint16_t)0x0200) /* 512 bytes per page w/o Spare Area */ //#define NAND_BLOCK_SIZE ((uint16_t)0x0020) /* 32x512 bytes pages per block *///#define NAND_ZONE_SIZE ((uint16_t)0x0400) /* 1024 Block per zone *///#define NAND_SPARE_AREA_SIZE ((uint16_t)0x0010) /* last 16 bytes as spare area *///#define NAND_MAX_ZONE ((uint16_t)0x0004) /* 4 zones of 1024 block *//* FSMC NAND memory HY27UF081G2A-TPCB parameters */#define NAND_PAGE_SIZE ((uint16_t)0x0800) /* 2048 bytes per page w/o Spare Area */ #define NAND_BLOCK_SIZE ((uint16_t)0x0040) /* 64x2048 bytes pages per block */#define NAND_ZONE_SIZE ((uint16_t)0x0200) /* 512 Block per zone */#define NAND_SPARE_AREA_SIZE ((uint16_t)0x0040) /* last 64 bytes as spare area */#define NAND_MAX_ZONE ((uint16_t)0x0002) /* 2 zones of 1024 block *//* FSMC NAND memory data computation */#define DATA_1st_CYCLE(DATA) (uint8_t)((DATA)& 0xFF) /* 1st data cycle */#define DATA_2nd_CYCLE(DATA) (uint8_t)(((DATA)& 0xFF00) >> 8) /* 2nd data cycle */#define DATA_3rd_CYCLE(DATA) (uint8_t)(((DATA)& 0xFF0000) >> 16) /* 3rd data cycle */#define DATA_4th_CYCLE(DATA) (uint8_t)(((DATA)& 0xFF000000) >> 24) /* 4th data cycle *//* FSMC NAND memory HY27UF081G2A-TPCB address computation */#define ADDR_1st_CYCLE(PADDR) (uint8_t)(0x0) /* 1st addressing cycle */#define ADDR_2nd_CYCLE(PADDR) (uint8_t)(0x0) /* 2nd addressing cycle */#define ADDR_3rd_CYCLE(PADDR) (uint8_t)(PADDR & 0xFF) /* 3rd addressing cycle */#define ADDR_4th_CYCLE(PADDR) (uint8_t)((PADDR>>8) & 0xFF) /* 4th addressing cycle *//* Exported macro ------------------------------------------------------------*//* Exported functions ------------------------------------------------------- */void FSMC_NAND_Init(void);void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID);uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, uint32_t Address, uint32_t NumPageToWrite); uint32_t FSMC_NAND_ReadSmallPage (uint8_t *pBuffer, uint32_t Address, uint32_t NumPageToRead);uint32_t FSMC_NAND_MoveSmallPage (uint32_t SourcePageAddress, uint32_t T argetPageAddress);//uint32_t FSMC_NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite); //uint32_t FSMC_NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead); uint32_t FSMC_NAND_EraseBlock(uint32_t Address);uint32_t FSMC_NAND_Reset(void);uint32_t FSMC_NAND_GetStatus(void);uint32_t FSMC_NAND_ReadStatus(void);//uint32_t FSMC_NAND_AddressIncrement(NAND_ADDRESS* Address);#endif /* __FSMC_NAND_H */七,NFTL代码层有关NFTL代码,自行处理。

相关文档
最新文档