微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 9G-STM32 EWARM开发过程简介之五

9G-STM32 EWARM开发过程简介之五

时间:11-29 来源:互联网 点击:
9G-STM32 EWARM开发过程简介之五--移植FATFS的NANDFLASH驱动

一,建立工程FATFS源码
1,在http://elm-chan.org/fsw/ff/00index_e.html上下载ff007c.zip,并把ff007c.zip里面的
src文件夹复制到D:worksEK-STM3210E-UCOSII下,并改名为Fatfs;
2,在IDE工程中右击选择“Add Group”建立“FATFS”文件组,并在“FATFS”上右击选择“Add Files”添加
D:worksEK-STM3210E-UCOSIIFatfs下的C文件;
3,把D:worksEK-STM3210E-UCOSIIFatfs文件夹目录添加到项目头文件搜索路径中,如:
$PROJ_DIR$....Fatfs

二,移植NANDFLASH驱动接口
1,把stm32f10x_stdperiph_lib_v3.0.0ProjectExamplesFSMCNAND下的fsmc_nand.c复制到
D:worksEK-STM3210E-UCOSIIDrivers下,并加入到工程的DRV文件组;
2,把stm32f10x_stdperiph_lib_v3.0.0ProjectExamplesFSMCNAND下的fsmc_nand.h复制到
D:worksEK-STM3210E-UCOSIIInclude下;
3,在fsmc_nand.c前添加上#include "stm32f10x_conf.h",并把系统中的 "stm32f10x_conf.h"
文件的/* #include "stm32f10x_fsmc.h" */注释打开;

三,修改FATFS的配置文件
1,把D:worksEK-STM3210E-UCOSIIFatfs下的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_RPATH1
2,把D:worksEK-STM3210E-UCOSIIFatfs下的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 == 0
DRESULT 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");
}
else
if((NAND_ID.Maker_ID == NAND_HY_MakerID) && (NAND_ID.Device_ID == NAND_HY_DeviceID))
{
printf("HY27UF081G2A-TPCB");
}
printf(" ID = 0x%x%x%x%x ",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 mount
res=f_mount(0,&fs);
printf("f_mount=%x ",res);

// for format
//res=f_mkfs(0,1,2048);//MUST Format for New NANDFLASH !!!
//printf("f_mkfs=%x ",res);

// for
pfs=&fs;
res = f_getfree("/", &clust, &pfs);
printf("f_getfree=%x ",res);
printf("%lu MB total drive space."
"%lu MB available.",
(DWORD)(pfs->max_clust - 2) * pfs->csize /2/1024,
clust * pfs->csize /2/1024);

// for read
res=f_open(&fl,"/test2.dat",FA_OPEN_EXISTING | FA_READ);
printf("f_open=%x ",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 ",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("");}
}

}
f_close(&fl);
// for write
res=f_open(&fl,"/test2.dat",FA_CREATE_ALWAYS | FA_WRITE);
printf("f_open=%x ",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 ",res);
if(res || w
}
f_close(&fl);

// for umount
f_mount(0,NULL);
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top