fixed bug: no release uffs_object_handler in dfs_uffs.c
function:dfs_uffs_open() git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1363 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
ccf7d67918
commit
8d77fe70dc
|
@ -10,6 +10,7 @@
|
||||||
* \file nand flash interface example
|
* \file nand flash interface example
|
||||||
* \brief example for using nand flash driver and multiple partitions, with system memory allocator.
|
* \brief example for using nand flash driver and multiple partitions, with system memory allocator.
|
||||||
* \author Ricky Zheng, created at 27 Nov, 2007
|
* \author Ricky Zheng, created at 27 Nov, 2007
|
||||||
|
* \modify amsl, at 17 Jan, 2010 iamyhw@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <rtthread.h>
|
#include <rtthread.h>
|
||||||
|
@ -88,40 +89,42 @@ static int nand_is_badblock(uffs_Device *dev,u32 block)
|
||||||
return K9F2G08_Check_badblk(block);
|
return K9F2G08_Check_badblk(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The only uffs v1.3.2-4 can used. */
|
||||||
static uffs_FlashOps nand_driver_ops =
|
static uffs_FlashOps nand_driver_ops =
|
||||||
{
|
{
|
||||||
nand_read_page_data, //ReadPageData
|
nand_read_page_data, /* ReadPageData */
|
||||||
nand_read_page_spare, //ReadPageSpare
|
nand_read_page_spare, /* ReadPageSpare */
|
||||||
NULL, //ReadPageSpareWithLayout
|
NULL, /* ReadPageSpareWithLayout */
|
||||||
nand_write_page_data, //WritePageData
|
nand_write_page_data, /* WritePageData */
|
||||||
nand_write_page_spare, //WritePageSpare
|
nand_write_page_spare, /* WritePageSpare */
|
||||||
NULL, //WriteFullPage
|
NULL, /* WriteFullPage */
|
||||||
nand_is_badblock, //IsBadBlock
|
nand_is_badblock, /* IsBadBlock */
|
||||||
nand_mark_badblock, //MarkBadBlock
|
nand_mark_badblock, /* MarkBadBlock */
|
||||||
nand_erase_block, //EraseBlock
|
nand_erase_block, /* EraseBlock */
|
||||||
};
|
};
|
||||||
|
|
||||||
//change these parameters to fit your nand flash specification
|
|
||||||
//#define MAN_ID MAN_ID_SAMSUNG // simulate Samsung's NAND flash
|
|
||||||
|
|
||||||
static struct uffs_StorageAttrSt flash_storage = {0};
|
static struct uffs_StorageAttrSt flash_storage = {0};
|
||||||
|
|
||||||
static int initDevice(uffs_Device *dev)
|
static int initDevice(uffs_Device *dev)
|
||||||
{
|
{
|
||||||
dev->ops = &nand_driver_ops;
|
dev->ops = &nand_driver_ops;
|
||||||
return RT_EOK;
|
return U_SUCC;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int releaseDevice(uffs_Device *dev)
|
static int releaseDevice(uffs_Device *dev)
|
||||||
{
|
{
|
||||||
return RT_EOK;
|
return U_SUCC;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <dfs_uffs.h>
|
#include <dfs_uffs.h>
|
||||||
|
|
||||||
static uffs_Device uffs_device = {0};
|
static uffs_Device uffs_device = {0};
|
||||||
/* define mount table,UFFS FS private data */
|
|
||||||
/* it is absolute accessing for uffs.*/
|
/*
|
||||||
|
* define mount table,UFFS FS private data
|
||||||
|
* it is absolute accessing for uffs.
|
||||||
|
* set struct data on the RT-Thread device
|
||||||
|
*/
|
||||||
static uffs_MountTable uffs_mount_table =
|
static uffs_MountTable uffs_mount_table =
|
||||||
{
|
{
|
||||||
&uffs_device,
|
&uffs_device,
|
||||||
|
@ -175,40 +178,42 @@ struct nand_flash_dev* nand_init(u8* buf)
|
||||||
return RT_NULL;
|
return RT_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RT-Thread Device Driver Interface */
|
/*
|
||||||
/* UFFS FileSystem NandFlash InterFace */
|
* RT-Thread Device Driver Interface
|
||||||
/* we don't use entity, let uffs autarky */
|
* UFFS FileSystem NandFlash InterFace
|
||||||
|
* we don't use entity, let uffs autarky
|
||||||
|
*/
|
||||||
|
|
||||||
struct rt_device nand_device;
|
struct rt_device nand_device;
|
||||||
|
|
||||||
static rt_err_t rt_nand_init(rt_device_t dev)
|
static rt_err_t rt_nand_init(rt_device_t dev)
|
||||||
{
|
{
|
||||||
return 0;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_err_t rt_nand_open(rt_device_t dev, u16 oflag)
|
static rt_err_t rt_nand_open(rt_device_t dev, u16 oflag)
|
||||||
{
|
{
|
||||||
return 0;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_err_t rt_nand_close(rt_device_t dev)
|
static rt_err_t rt_nand_close(rt_device_t dev)
|
||||||
{
|
{
|
||||||
return 0;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_err_t rt_nand_control(rt_device_t dev, u8 cmd, void *args)
|
static rt_err_t rt_nand_control(rt_device_t dev, u8 cmd, void *args)
|
||||||
{
|
{
|
||||||
return 0;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_size_t rt_nand_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
static rt_size_t rt_nand_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
||||||
{
|
{
|
||||||
return 0;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static rt_size_t rt_nand_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
static rt_size_t rt_nand_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
||||||
{
|
{
|
||||||
return 0;
|
return RT_EOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rt_hw_nand_init(void)
|
void rt_hw_nand_init(void)
|
||||||
|
@ -236,7 +241,7 @@ void rt_hw_nand_init(void)
|
||||||
|
|
||||||
/* about uffs codes */
|
/* about uffs codes */
|
||||||
entry = &uffs_mount_table;
|
entry = &uffs_mount_table;
|
||||||
//entry->lock = rt_sem_create("sem_nand0", 1, RT_IPC_FLAG_FIFO);//??it's lonely!how to do?
|
/* entry->lock = rt_sem_create("sem_nand0", 1, RT_IPC_FLAG_FIFO); */ /* it's lonely!how to do? */
|
||||||
|
|
||||||
uffs_MemSetupSystemAllocator(&(entry->dev->mem));
|
uffs_MemSetupSystemAllocator(&(entry->dev->mem));
|
||||||
entry->dev->Init = initDevice;
|
entry->dev->Init = initDevice;
|
||||||
|
@ -261,7 +266,7 @@ void rt_hw_nand_init(void)
|
||||||
extid >>= 2;
|
extid >>= 2;
|
||||||
/* Calc blocksize. Blocksize is multiples of 64KiB */
|
/* Calc blocksize. Blocksize is multiples of 64KiB */
|
||||||
chip->pages_per_block = ((64*1024)<<(extid & 0x03))/(chip->page_data_size);
|
chip->pages_per_block = ((64*1024)<<(extid & 0x03))/(chip->page_data_size);
|
||||||
/* The 5th id byte */
|
/* The 5th id byte,it is no use */
|
||||||
chip->total_blocks = (type->chipsize*1024*1024) /
|
chip->total_blocks = (type->chipsize*1024*1024) /
|
||||||
chip->page_data_size / chip->pages_per_block;
|
chip->page_data_size / chip->pages_per_block;
|
||||||
|
|
||||||
|
@ -279,7 +284,7 @@ void rt_hw_nand_init(void)
|
||||||
chip->block_status_offs = NAND_SMALL_BADBLOCK_POS;
|
chip->block_status_offs = NAND_SMALL_BADBLOCK_POS;
|
||||||
chip->ecc_opt = UFFS_ECC_SOFT; /* ecc option, do not use ECC,debug */
|
chip->ecc_opt = UFFS_ECC_SOFT; /* ecc option, do not use ECC,debug */
|
||||||
chip->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
|
chip->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */
|
||||||
#if (0) //DEBUG trace facility
|
#if (0) /* DEBUG trace facility */
|
||||||
rt_kprintf("page_data_size = %d\n",chip->page_data_size);
|
rt_kprintf("page_data_size = %d\n",chip->page_data_size);
|
||||||
rt_kprintf("pages_per_block = %d\n",chip->pages_per_block);
|
rt_kprintf("pages_per_block = %d\n",chip->pages_per_block);
|
||||||
rt_kprintf("spare_size = %d\n",chip->spare_size);
|
rt_kprintf("spare_size = %d\n",chip->spare_size);
|
||||||
|
@ -289,5 +294,5 @@ void rt_hw_nand_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//end of file
|
/* end of file */
|
||||||
|
|
||||||
|
|
|
@ -38,35 +38,45 @@ int dfs_uffs_statfs(struct dfs_filesystem* fs, struct statfs *buf)
|
||||||
|
|
||||||
int dfs_uffs_open(struct dfs_fd* fd)
|
int dfs_uffs_open(struct dfs_fd* fd)
|
||||||
{
|
{
|
||||||
int ret=U_SUCC;
|
|
||||||
|
|
||||||
if (fd->flags & DFS_O_DIRECTORY)
|
if (fd->flags & DFS_O_DIRECTORY)
|
||||||
{//Îļþ¼Ð
|
{ /* directory */
|
||||||
uffs_DIR *dirp;
|
uffs_DIR* dirp;
|
||||||
/* open directory */
|
int oflag = UO_DIR;
|
||||||
|
|
||||||
if (fd->flags & DFS_O_CREAT)
|
if (fd->flags & DFS_O_CREAT) oflag |= UO_CREATE;
|
||||||
{//´´½¨
|
if (fd->flags & DFS_O_RDONLY) oflag |= UO_RDONLY;
|
||||||
ret = uffs_open(fd->path,UO_CREATE|UO_DIR);
|
if (fd->flags & DFS_O_WRONLY) oflag |= UO_WRONLY;
|
||||||
if(ret != U_SUCC)
|
|
||||||
|
if (oflag & UO_CREATE)
|
||||||
|
{ /* create directory right now */
|
||||||
|
uffs_Object* fp = uffs_GetObject();
|
||||||
|
if(fp == NULL)
|
||||||
|
{
|
||||||
|
uffs_set_error(-UEMFILE);
|
||||||
|
return U_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uffs_OpenObject(fp, fd->path, oflag) != U_SUCC)
|
||||||
{
|
{
|
||||||
return U_FAIL;
|
return U_FAIL;
|
||||||
}
|
}
|
||||||
|
/* release object hander */
|
||||||
|
uffs_PutObject(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* use directory handler */
|
||||||
dirp = uffs_opendir(fd->path);
|
dirp = uffs_opendir(fd->path);
|
||||||
if(dirp == NULL)
|
if(dirp == NULL)
|
||||||
{
|
{
|
||||||
uffs_set_error(-UEMFILE);
|
uffs_set_error(-UEMFILE);
|
||||||
ret = U_FAIL;
|
return U_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd->data = dirp;
|
fd->data = dirp;
|
||||||
|
|
||||||
return U_SUCC;
|
return U_SUCC;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{//Îļþ
|
{/* file */
|
||||||
uffs_Object *fp;
|
uffs_Object *fp;
|
||||||
|
|
||||||
int mode = UO_RDONLY;
|
int mode = UO_RDONLY;
|
||||||
|
@ -80,17 +90,15 @@ int dfs_uffs_open(struct dfs_fd* fd)
|
||||||
/* Creates a new file. The function fails if the file is already existing. */
|
/* Creates a new file. The function fails if the file is already existing. */
|
||||||
if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL;
|
if (fd->flags & DFS_O_EXCL) mode |= UO_EXCL;
|
||||||
|
|
||||||
/* allocate a fd */
|
/* get an object hander */
|
||||||
|
|
||||||
/* open directory */
|
|
||||||
fp = uffs_GetObject();
|
fp = uffs_GetObject();
|
||||||
if(fp == NULL)
|
if(fp == NULL)
|
||||||
{
|
{
|
||||||
uffs_set_error(-UEMFILE);
|
uffs_set_error(-UEMFILE);
|
||||||
ret = U_FAIL;
|
return U_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uffs_OpenObject(fp, fd->path, mode) == RT_EOK)
|
if(uffs_OpenObject(fp, fd->path, mode) == U_SUCC)
|
||||||
{
|
{
|
||||||
struct uffs_stat stat_buf;
|
struct uffs_stat stat_buf;
|
||||||
|
|
||||||
|
@ -104,20 +112,20 @@ int dfs_uffs_open(struct dfs_fd* fd)
|
||||||
{
|
{
|
||||||
fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
|
fd->pos = uffs_SeekObject(fp, 0, USEEK_END);
|
||||||
}
|
}
|
||||||
ret = U_SUCC;
|
return U_SUCC;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* open failed, return */
|
/* open failed, return */
|
||||||
uffs_set_error(-uffs_GetObjectErr(fp));
|
uffs_set_error(-uffs_GetObjectErr(fp));
|
||||||
|
/* release object hander */
|
||||||
uffs_PutObject(fp);
|
uffs_PutObject(fp);
|
||||||
return U_FAIL;
|
return U_FAIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dfs_uffs_close(struct dfs_fd* fd)
|
int dfs_uffs_close(struct dfs_fd* fd)
|
||||||
{
|
{
|
||||||
int ret=U_SUCC;
|
int ret=U_SUCC;
|
||||||
|
@ -125,21 +133,18 @@ int dfs_uffs_close(struct dfs_fd* fd)
|
||||||
if (fd->type == FT_DIRECTORY)
|
if (fd->type == FT_DIRECTORY)
|
||||||
{
|
{
|
||||||
uffs_DIR* dirp;
|
uffs_DIR* dirp;
|
||||||
|
|
||||||
dirp = (uffs_DIR*)(fd->data);
|
dirp = (uffs_DIR*)(fd->data);
|
||||||
RT_ASSERT(dirp != RT_NULL);
|
RT_ASSERT(dirp != RT_NULL);
|
||||||
|
|
||||||
uffs_closedir(dirp);
|
ret = uffs_closedir(dirp);
|
||||||
}
|
}
|
||||||
else if (fd->type == FT_REGULAR)
|
else if (fd->type == FT_REGULAR)
|
||||||
{
|
{
|
||||||
uffs_Object* fp;
|
uffs_Object* fp = (uffs_Object*)(fd->data);
|
||||||
|
|
||||||
fp = (uffs_Object*)(fd->data);
|
|
||||||
|
|
||||||
RT_ASSERT(fd != RT_NULL);
|
RT_ASSERT(fd != RT_NULL);
|
||||||
|
|
||||||
ret = uffs_CloseObject(fp);
|
ret = uffs_CloseObject(fp);
|
||||||
|
/* release object hander */
|
||||||
uffs_PutObject(fp);
|
uffs_PutObject(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +174,7 @@ int dfs_uffs_read(struct dfs_fd* fd, void* buf, rt_size_t count)
|
||||||
RT_ASSERT(fd != RT_NULL);
|
RT_ASSERT(fd != RT_NULL);
|
||||||
|
|
||||||
/* update position */
|
/* update position */
|
||||||
fd->pos = fp->pos;
|
fp->pos = fd->pos;
|
||||||
|
|
||||||
return uffs_ReadObject(fp, buf, count);
|
return uffs_ReadObject(fp, buf, count);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +184,7 @@ int dfs_uffs_write(struct dfs_fd* fd, const void* buf, rt_size_t count)
|
||||||
uffs_Object* fp;
|
uffs_Object* fp;
|
||||||
u32 byte_write;
|
u32 byte_write;
|
||||||
struct uffs_stat stat_buf;
|
struct uffs_stat stat_buf;
|
||||||
|
rt_kprintf("count=%d\n",count);
|
||||||
if(fd->type == FT_DIRECTORY)
|
if(fd->type == FT_DIRECTORY)
|
||||||
{
|
{
|
||||||
return -DFS_STATUS_EISDIR;
|
return -DFS_STATUS_EISDIR;
|
||||||
|
@ -226,6 +231,11 @@ int dfs_uffs_getdents(struct dfs_fd* fd, struct dirent* dir, rt_uint32_t count)
|
||||||
rt_uint32_t index;
|
rt_uint32_t index;
|
||||||
struct dirent* d;
|
struct dirent* d;
|
||||||
|
|
||||||
|
if(fd->type != FT_DIRECTORY)
|
||||||
|
{
|
||||||
|
return -DFS_STATUS_EISDIR;
|
||||||
|
}
|
||||||
|
|
||||||
dirp = (uffs_DIR*)(fd->data);
|
dirp = (uffs_DIR*)(fd->data);
|
||||||
RT_ASSERT(dirp != RT_NULL);
|
RT_ASSERT(dirp != RT_NULL);
|
||||||
|
|
||||||
|
@ -276,18 +286,25 @@ int dfs_uffs_stat(struct dfs_filesystem* fs, const char* path, struct stat* st)
|
||||||
|
|
||||||
if (ret == U_SUCC)
|
if (ret == U_SUCC)
|
||||||
{
|
{
|
||||||
|
rt_uint32_t mode=0;
|
||||||
st->st_dev = 0;
|
st->st_dev = 0;
|
||||||
//st->st_mode = stat_buf.st_mode;
|
|
||||||
|
|
||||||
st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
|
if(stat_buf.st_mode & US_IFREG) mode |= DFS_S_IFREG;
|
||||||
DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
|
if(stat_buf.st_mode & US_IFDIR) mode |= DFS_S_IFDIR;
|
||||||
if (stat_buf.st_mode & US_IFDIR)
|
if(stat_buf.st_mode & US_IRWXU) mode |= DFS_S_IRWXU;
|
||||||
{
|
if(stat_buf.st_mode & US_IRUSR) mode |= DFS_S_IRUSR;
|
||||||
st->st_mode &= ~DFS_S_IFREG;
|
if(stat_buf.st_mode & US_IWUSR) mode |= DFS_S_IWUSR;
|
||||||
st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
|
if(stat_buf.st_mode & US_IXUSR) mode |= DFS_S_IXUSR;
|
||||||
}
|
if(stat_buf.st_mode & US_IRWXG) mode |= DFS_S_IRWXG;
|
||||||
if (stat_buf.st_mode & US_IREAD)
|
if(stat_buf.st_mode & US_IRGRP) mode |= DFS_S_IRGRP;
|
||||||
st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);
|
if(stat_buf.st_mode & US_IWGRP) mode |= DFS_S_IWGRP;
|
||||||
|
if(stat_buf.st_mode & US_IXGRP) mode |= DFS_S_IXGRP;
|
||||||
|
if(stat_buf.st_mode & US_IRWXO) mode |= DFS_S_IRWXO;
|
||||||
|
if(stat_buf.st_mode & US_IROTH) mode |= DFS_S_IROTH;
|
||||||
|
if(stat_buf.st_mode & US_IWOTH) mode |= DFS_S_IWOTH;
|
||||||
|
if(stat_buf.st_mode & US_IXOTH) mode |= DFS_S_IXOTH;
|
||||||
|
|
||||||
|
st->st_mode = mode;
|
||||||
st->st_size = stat_buf.st_size;
|
st->st_size = stat_buf.st_size;
|
||||||
st->st_mtime= stat_buf.st_mtime;
|
st->st_mtime= stat_buf.st_mtime;
|
||||||
st->st_blksize= stat_buf.st_blksize;
|
st->st_blksize= stat_buf.st_blksize;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define __K9F2G08_H__
|
#define __K9F2G08_H__
|
||||||
|
|
||||||
#include <rtdef.h>
|
#include <rtdef.h>
|
||||||
|
#include <s3c24x0.h>
|
||||||
#include <nand.h>
|
#include <nand.h>
|
||||||
|
|
||||||
void K9F2G08_Program(u32 blockIndex, u32 srcAddress, u32 fileSize);
|
void K9F2G08_Program(u32 blockIndex, u32 srcAddress, u32 fileSize);
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
/**
|
/*
|
||||||
* 用户要自己实现这个文件中的接口函数,不一样的芯片会有不同的访问命令
|
* uffs/flash/k9f2g08.c
|
||||||
* 这个例程文件是关于Samsung k9f2g08芯片的,属于大页nandflash
|
*
|
||||||
|
* COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
|
||||||
|
*
|
||||||
|
* The license and distribution terms for this file may be
|
||||||
|
* found in the file LICENSE in this distribution or at
|
||||||
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
|
*
|
||||||
|
* Info:
|
||||||
|
* Low hardware driver for samsung nandflash.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* XXX UFFS XXX */
|
||||||
|
#include <uffs/uffs_types.h>
|
||||||
|
|
||||||
#include <nand.h>
|
#include <nand.h>
|
||||||
#include "s3c24x0.h"
|
#include "s3c24x0.h"
|
||||||
|
|
||||||
#include <k9f2g08.h>
|
#include <k9f2g08.h>
|
||||||
|
|
||||||
#define nand_write_cmd(cmd) (NFCMD = (cmd))
|
#define nand_write_cmd(cmd) (NFCMD = (cmd))
|
||||||
|
@ -17,51 +28,34 @@
|
||||||
|
|
||||||
#define nand_wait() {while(!(NFSTAT&(1<<0)));} //wait tWB and check F_RNB pin.
|
#define nand_wait() {while(!(NFSTAT&(1<<0)));} //wait tWB and check F_RNB pin.
|
||||||
|
|
||||||
//NAND Flash Command.support K9F2G08
|
/*
|
||||||
#define K9F2G08_CMD_READ0 0x00 // Read0
|
*************************************************
|
||||||
//#define K9F2G08_CMD_READ1 1 // Read1,K9F2G08 don't support the command.
|
** H/W dependent functions **
|
||||||
#define K9F2G08_CMD_RANDOM_DATA_OUT 0x05 // Random data output
|
*************************************************
|
||||||
#define K9F2G08_CMD_PAGEPROG 0x10 // Write phase 2
|
*/
|
||||||
#define K9F2G08_CMD_READ30 0x30 // Read30
|
|
||||||
#define K9F2G08_CMD_READ35 0x35 // Read35
|
|
||||||
//#define K9F2G08_CMD_READOOB 0x50 // Read oob
|
|
||||||
#define K9F2G08_CMD_ERASE1 0x60 // Erase phase 1
|
|
||||||
#define K9F2G08_CMD_STATUS 0x70 // Status read
|
|
||||||
#define K9F2G08_CMD_READ_EDC 0x7b // Read EDC Status
|
|
||||||
#define K9F2G08_CMD_SEQIN 0x80 // Write phase 1
|
|
||||||
#define K9F2G08_CMD_RANDOM_DATA_IN 0x85 // Random data input Copy-Back Program(0x85,0x10)
|
|
||||||
#define K9F2G08_CMD_READID 0x90 // ReadID,all-purpose command
|
|
||||||
#define K9F2G08_CMD_ERASE2 0xd0 // Erase phase 2
|
|
||||||
#define K9F2G08_CMD_RESET 0xff // Reset
|
|
||||||
|
|
||||||
#define BAD_CHECK (0)
|
/* HCLK=100Mhz */
|
||||||
#define ECC_CHECK (0)
|
#define TACLS 1 /* 1clk(0ns) */
|
||||||
|
#define TWRPH0 4 /* 3clk(25ns) */
|
||||||
|
#define TWRPH1 0 /* 1clk(10ns) */ /* TACLS+TWRPH0+TWRPH1>=50ns */
|
||||||
|
|
||||||
|
int read_nand_stats(void) /* R/B is fixed? */
|
||||||
//*************************************************
|
|
||||||
//** H/W dependent functions **
|
|
||||||
//*************************************************
|
|
||||||
|
|
||||||
// HCLK=100Mhz
|
|
||||||
#define TACLS 1 //1clk(0ns)
|
|
||||||
#define TWRPH0 4 //3clk(25ns)
|
|
||||||
#define TWRPH1 0 //1clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns
|
|
||||||
|
|
||||||
int read_nand_stats(void) // R/B 未接好?
|
|
||||||
{
|
{
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_STATUS);//0x70
|
nand_write_cmd(NAND_CMD_STATUS);
|
||||||
|
|
||||||
stat = nand_read();//读出返回的数据
|
stat = nand_read();/* read byte */
|
||||||
|
|
||||||
if(stat&1) return 1; // I/O0=1失败
|
if(stat&1) return 1; /* I/O0=1 successful */
|
||||||
else return 0; // I/O0=0成功
|
else return 0; /* I/O0=0 unsuccessful */
|
||||||
}
|
}
|
||||||
|
|
||||||
//擦除一个块
|
/*
|
||||||
//返回0,successful
|
*erase a block
|
||||||
//返回1,error
|
*return 0,successful
|
||||||
|
*return 1,error
|
||||||
|
*/
|
||||||
int K9F2G08_EraseBlock(u32 block)
|
int K9F2G08_EraseBlock(u32 block)
|
||||||
{
|
{
|
||||||
int stat;
|
int stat;
|
||||||
|
@ -69,50 +63,55 @@ int K9F2G08_EraseBlock(u32 block)
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_ERASE1); // Erase one block 1st command
|
nand_write_cmd(NAND_CMD_ERASE1); /* Erase one block 1st command */
|
||||||
|
|
||||||
nand_write_addr(_page&0xff); // Page number=0
|
nand_write_addr(_page&0xff); /* Page number=0 */
|
||||||
nand_write_addr((_page>>8)&0xff);
|
nand_write_addr((_page>>8)&0xff);
|
||||||
nand_write_addr((_page>>16)&0xff);
|
nand_write_addr((_page>>16)&0xff);
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_ERASE2); // Erase one blcok 2nd command
|
nand_write_cmd(NAND_CMD_ERASE2); /* Erase one blcok 2nd command */
|
||||||
|
|
||||||
nand_wait(); // Wait tBERS max 3ms.
|
nand_wait(); /* Wait tBERS max 3ms. */
|
||||||
|
|
||||||
stat = read_nand_stats();
|
stat = read_nand_stats();
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
//return 1 if it's a bad block, 0 if it's good.
|
/*
|
||||||
int K9F2G08_Check_badblk(u32 block) //0:bad,1:good
|
* check block is bad?
|
||||||
|
* return 1 if it's a bad block, 0 if it's good.
|
||||||
|
*/
|
||||||
|
int K9F2G08_Check_badblk(u32 block)
|
||||||
{
|
{
|
||||||
u8 data;
|
u8 data;
|
||||||
u32 _page;//块的首页地址
|
u32 _page;/* frist page in block */
|
||||||
|
|
||||||
_page = block*PAGES_PER_BLOCK; // For 2'nd cycle I/O[7:5]
|
_page = block*PAGES_PER_BLOCK; /* For 2'nd cycle I/O[7:5] */
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READ0); // Spare array read command
|
nand_write_cmd(NAND_CMD_READ0); /* Spare array read command */
|
||||||
nand_write_addr(PAGE_DATA_SIZE&0xff); // Read the mark of bad block in spare array(M addr=5)
|
nand_write_addr(PAGE_DATA_SIZE&0xff); /* Read the mark of bad block in spare array(M addr=5) */
|
||||||
nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
|
nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
|
||||||
nand_write_addr(_page&0xff); // The mark of bad block is in 0 page
|
nand_write_addr(_page&0xff); /* The mark of bad block is in 0 page */
|
||||||
nand_write_addr((_page>>8)&0xff); // For block number A[24:17]
|
nand_write_addr((_page>>8)&0xff); /* For block number A[24:17] */
|
||||||
nand_write_addr((_page>>16)&0xff); // For block number A[25]
|
nand_write_addr((_page>>16)&0xff); /* For block number A[25] */
|
||||||
nand_write_cmd(K9F2G08_CMD_READ30);
|
nand_write_cmd(NAND_CMD_READSTART);
|
||||||
|
|
||||||
nand_wait(); // Wait tR(max 12us)
|
nand_wait(); /* Wait tR(max 12us) */
|
||||||
|
|
||||||
data=nand_read();
|
data=nand_read();
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
if(data==0x00)
|
if(data==0x00)
|
||||||
return 1;//坏块
|
return 1;/* bad */
|
||||||
else
|
else
|
||||||
return 0;//好块
|
return 0;/* good */
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
//return 0 if ok, 1:fail
|
* mark a block is bad
|
||||||
|
* return 0 if ok, 1:fail
|
||||||
|
*/
|
||||||
int K9F2G08_Mark_badblk(u32 block)
|
int K9F2G08_Mark_badblk(u32 block)
|
||||||
{
|
{
|
||||||
u8 stat;
|
u8 stat;
|
||||||
|
@ -120,20 +119,20 @@ int K9F2G08_Mark_badblk(u32 block)
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_SEQIN); // Write 1st command
|
nand_write_cmd(NAND_CMD_SEQIN); /* Write 1st command */
|
||||||
|
|
||||||
nand_write_addr(PAGE_DATA_SIZE & 0xff); // The mark of bad block
|
nand_write_addr(PAGE_DATA_SIZE & 0xff);/* The mark of bad block */
|
||||||
nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
|
nand_write_addr((PAGE_DATA_SIZE>>8)&0xff);
|
||||||
nand_write_addr(_page&0xff); // marked 5th spare array
|
nand_write_addr(_page&0xff); /* marked 1th spare array */
|
||||||
nand_write_addr((_page>>8)&0xff); // in the 1st page.
|
nand_write_addr((_page>>8)&0xff); /* in the 1st page. */
|
||||||
nand_write_addr((_page>>16)&0xff); //
|
nand_write_addr((_page>>16)&0xff);
|
||||||
|
|
||||||
nand_write(0x00); //坏块标记
|
nand_write(0x00); /* 0x00 is commendatory make of the bad block. */
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_PAGEPROG); // Write 2nd command
|
nand_write_cmd(NAND_CMD_PAGEPROG); /* Write 2nd command */
|
||||||
|
|
||||||
nand_wait(); // Wait tPROG(200~500us)
|
nand_wait(); /* Wait tPROG(200~500us) */
|
||||||
stat = read_nand_stats();//查询是否成功
|
stat = read_nand_stats();
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
|
||||||
return stat;
|
return stat;
|
||||||
|
@ -145,23 +144,23 @@ int K9F2G08_ReadPage(u32 block, u32 page, u8 *buffer, int len, u8 *ecc)
|
||||||
int i;
|
int i;
|
||||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||||
|
|
||||||
// NF_RSTECC(); // Initialize ECC
|
/* NF_RSTECC(); */ /* Initialize ECC*/
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READ0); // Read command
|
nand_write_cmd(NAND_CMD_READ0); /* Read command */
|
||||||
nand_write_addr(0x00); // Column = 0
|
nand_write_addr(0x00); /* Column = 0 */
|
||||||
nand_write_addr(0x00);
|
nand_write_addr(0x00);
|
||||||
nand_write_addr(_page&0xff); //
|
nand_write_addr(_page&0xff);
|
||||||
nand_write_addr((_page>>8)&0xff); // Block & Page num.
|
nand_write_addr((_page>>8)&0xff);
|
||||||
nand_write_addr((_page>>16)&0xff); //
|
nand_write_addr((_page>>16)&0xff);
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READ30);
|
nand_write_cmd(NAND_CMD_READSTART);
|
||||||
|
|
||||||
nand_wait(); // Wait tR(max 12us)
|
nand_wait(); /* Wait tR(max 12us) */
|
||||||
for(i=0;i<len;i++)
|
for(i=0;i<len;i++)
|
||||||
{
|
{
|
||||||
buffer[i] = nand_read(); // Read one page
|
buffer[i] = nand_read(); /* Read one page */
|
||||||
}
|
}
|
||||||
|
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
@ -175,23 +174,23 @@ int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len)
|
||||||
|
|
||||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||||
|
|
||||||
// NF_RSTECC(); // Initialize ECC
|
/* NF_RSTECC(); */ /* Initialize ECC */
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READ0); // Read command
|
nand_write_cmd(NAND_CMD_READ0);
|
||||||
nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff); // Column = 0
|
nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
|
||||||
nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
|
nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
|
||||||
nand_write_addr(_page&0xff); //
|
nand_write_addr(_page&0xff);
|
||||||
nand_write_addr((_page>>8)&0xff); // Block & Page num.
|
nand_write_addr((_page>>8)&0xff);
|
||||||
nand_write_addr((_page>>16)&0xff); //
|
nand_write_addr((_page>>16)&0xff);
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READ30);
|
nand_write_cmd(NAND_CMD_READSTART);
|
||||||
|
|
||||||
nand_wait(); // Wait tR(max 12us)
|
nand_wait(); /* Wait tR(max 12us) */
|
||||||
for(i=0;i<len;i++)
|
for(i=0;i<len;i++)
|
||||||
{
|
{
|
||||||
spare[i] = nand_read(); // Read one page
|
spare[i] = nand_read(); /* Read one page */
|
||||||
}
|
}
|
||||||
|
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
@ -199,34 +198,36 @@ int K9F2G08_ReadTags(u32 block, u32 page, u8 *spare, int ofs, int len)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//写一页数据
|
/*
|
||||||
//返回0,successful
|
* write one page data
|
||||||
//返回1,error
|
* return 0,successful
|
||||||
|
* return 1,error
|
||||||
|
*/
|
||||||
int K9F2G08_WritePage(u32 block, u32 page, const u8 *buffer, int len, const u8 *ecc)
|
int K9F2G08_WritePage(u32 block, u32 page, const u8 *buffer, int len, const u8 *ecc)
|
||||||
{
|
{
|
||||||
int i,stat;
|
int i,stat;
|
||||||
|
|
||||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||||
|
|
||||||
//nand_Init_ECC(); // Initialize ECC
|
/* nand_Init_ECC(); */ /* nitialize ECC */
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_SEQIN); //0x80 Write 1st command
|
nand_write_cmd(NAND_CMD_SEQIN);
|
||||||
for(i=0;i<10;i++);
|
for(i=0;i<10;i++);
|
||||||
nand_write_addr(0x00); // Column 0
|
nand_write_addr(0x00); /* Column 0 */
|
||||||
nand_write_addr(0x00);
|
nand_write_addr(0x00);
|
||||||
nand_write_addr(_page&0xff); //
|
nand_write_addr(_page&0xff);
|
||||||
nand_write_addr((_page>>8)&0xff); // Block & page num.
|
nand_write_addr((_page>>8)&0xff);
|
||||||
nand_write_addr((_page>>16)&0xff); //
|
nand_write_addr((_page>>16)&0xff);
|
||||||
|
|
||||||
for(i=0;i<len;i++)
|
for(i=0;i<len;i++)
|
||||||
{
|
{
|
||||||
nand_write(*buffer++); // Write one page to NFM from buffer
|
nand_write(*buffer++);
|
||||||
}
|
}
|
||||||
nand_write_cmd(K9F2G08_CMD_PAGEPROG); //0x10 Write 2nd command
|
nand_write_cmd(NAND_CMD_PAGEPROG);
|
||||||
|
|
||||||
nand_wait(); //wait tPROG 200~500us;
|
nand_wait(); /* wait tPROG 200~500us; */
|
||||||
|
|
||||||
stat = read_nand_stats();
|
stat = read_nand_stats();
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
@ -239,29 +240,29 @@ int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
|
||||||
int i,stat;
|
int i,stat;
|
||||||
u32 _page = block*PAGES_PER_BLOCK + page;
|
u32 _page = block*PAGES_PER_BLOCK + page;
|
||||||
|
|
||||||
//nand_Init_ECC(); // Initialize ECC
|
/* nand_Init_ECC(); */ /* Initialize ECC */
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_SEQIN); //0x80 Write 1st command
|
nand_write_cmd(NAND_CMD_SEQIN);
|
||||||
for(i=0;i<10;i++);
|
for(i=0;i<10;i++);
|
||||||
nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff); // Column 0
|
nand_write_addr((PAGE_DATA_SIZE+ofs)&0xff);
|
||||||
nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
|
nand_write_addr(((PAGE_DATA_SIZE+ofs)>>8)&0xff);
|
||||||
nand_write_addr(_page&0xff); //
|
nand_write_addr(_page&0xff);
|
||||||
nand_write_addr((_page>>8)&0xff); // Block & page num.
|
nand_write_addr((_page>>8)&0xff);
|
||||||
nand_write_addr((_page>>16)&0xff); //
|
nand_write_addr((_page>>16)&0xff);
|
||||||
|
|
||||||
for(i=0;i<len;i++)
|
for(i=0;i<len;i++)
|
||||||
{
|
{
|
||||||
nand_write(*spare++); // Write one page to NFM from buffer
|
nand_write(*spare++);
|
||||||
}
|
}
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_PAGEPROG); //0x10 Write 2nd command
|
nand_write_cmd(NAND_CMD_PAGEPROG);
|
||||||
|
|
||||||
nand_wait(); //wait tPROG 200~500us;
|
nand_wait(); /* wait tPROG 200~500us; */
|
||||||
|
|
||||||
stat = read_nand_stats();
|
stat = read_nand_stats();
|
||||||
if(!stat) // Page write error
|
if(!stat) /* Page write error */
|
||||||
{
|
{
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -273,38 +274,21 @@ int K9F2G08_WriteTags(u32 block, u32 page, const u8 *spare, int ofs, int len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//find frist shift bit
|
|
||||||
//rt_inline int generic_ffs(int x)
|
|
||||||
//{
|
|
||||||
// int r = 1;
|
|
||||||
//
|
|
||||||
// if(!x)
|
|
||||||
// return 0;
|
|
||||||
//
|
|
||||||
// if(!(x & 0xffff)) {x >>= 16;r += 16;}
|
|
||||||
// if(!(x & 0xff)) {x >>= 8;r += 8;}
|
|
||||||
// if(!(x & 0xf)) {x >>= 4;r += 4;}
|
|
||||||
// if(!(x & 3)) {x >>= 2;r += 2;}
|
|
||||||
// if(!(x & 1)) {x >>= 1;r += 1;}
|
|
||||||
//
|
|
||||||
// return r;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/* when all is true,read all byte */
|
/* when all is true,read all byte */
|
||||||
void K9F2G08_ReadChipID(u8* buf, UBOOL all)
|
void K9F2G08_ReadChipID(u8* buf, UBOOL all)
|
||||||
{
|
{
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READID); //0x90
|
nand_write_cmd(NAND_CMD_READID);
|
||||||
nand_write_addr(K9F2G08_CMD_READ0);
|
nand_write_addr(NAND_CMD_READ0);
|
||||||
|
|
||||||
buf[0] = nand_read();//制造商ID
|
buf[0] = nand_read();/* manufacturer ID */
|
||||||
buf[1] = nand_read();//芯片ID
|
buf[1] = nand_read();/* physical chip ID */
|
||||||
if(all)
|
if(all)
|
||||||
{
|
{
|
||||||
buf[2] = nand_read();
|
buf[2] = nand_read();
|
||||||
buf[3] = nand_read();
|
buf[3] = nand_read();
|
||||||
//buf[4] = nand_read(); //有的芯片没有第5个字节
|
/* buf[4] = nand_read(); */ /* Some chips have no 5th byte */
|
||||||
}
|
}
|
||||||
|
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
@ -315,17 +299,17 @@ void K9F2G08_Init(void)
|
||||||
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
|
NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4)|(0<<0);
|
||||||
NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
|
NFCONT = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0);
|
||||||
NFSTAT = 0;
|
NFSTAT = 0;
|
||||||
// 1 1 1 1, 1 xxx, r xxx, r xxx
|
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
|
||||||
// En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1
|
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
|
||||||
}
|
}
|
||||||
|
|
||||||
void K9F2G08_Reset(void)
|
void K9F2G08_Reset(void)
|
||||||
{
|
{
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(0xFF); //reset command
|
nand_write_cmd(0xFF); /* reset command */
|
||||||
|
|
||||||
nand_wait(); //wait 200~500us;
|
nand_wait(); /* wait 200~500us */
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
|
||||||
K9F2G08_Init();
|
K9F2G08_Init();
|
||||||
|
@ -338,24 +322,24 @@ int K9F2G08_ReadChunk(u32 chunk, u8 *data, u8 *tags)
|
||||||
|
|
||||||
nand_cs_en();
|
nand_cs_en();
|
||||||
|
|
||||||
nand_write_cmd(K9F2G08_CMD_READ0); // Read command
|
nand_write_cmd(NAND_CMD_READ0);
|
||||||
nand_write_addr(0x00);
|
nand_write_addr(0x00);
|
||||||
nand_write_addr(0x00);
|
nand_write_addr(0x00);
|
||||||
nand_write_addr(chunk & 0xff); //
|
nand_write_addr(chunk & 0xff);
|
||||||
nand_write_addr((chunk >> 8) & 0xff); // Block & Page num.
|
nand_write_addr((chunk >> 8) & 0xff);
|
||||||
nand_write_addr((chunk >> 16) & 0xff); //
|
nand_write_addr((chunk >> 16) & 0xff); //
|
||||||
//nand_Init_ECC();
|
/* nand_Init_ECC(); */
|
||||||
nand_write_cmd(K9F2G08_CMD_READ30); // Read command
|
nand_write_cmd(NAND_CMD_READ30);
|
||||||
|
|
||||||
nand_wait(); // Wait tR(max 12us)
|
nand_wait(); /* Wait tR(max 12us) */
|
||||||
|
|
||||||
for(i = 0; i < PAGE_DATA_SIZE; i++)
|
for(i = 0; i < PAGE_DATA_SIZE; i++)
|
||||||
{
|
{
|
||||||
data[i] = nand_read(); // Read one page
|
data[i] = nand_read(); /* Read page data */
|
||||||
}
|
}
|
||||||
for(i = 0; i < PAGE_SPARE_SIZE; i++)
|
for(i = 0; i < PAGE_SPARE_SIZE; i++)
|
||||||
{
|
{
|
||||||
tags[i] = nand_read(); // Read spare array
|
tags[i] = nand_read(); /* Read spare array */
|
||||||
}
|
}
|
||||||
|
|
||||||
nand_cs_ds();
|
nand_cs_ds();
|
||||||
|
|
|
@ -1,24 +1,40 @@
|
||||||
//
|
/*
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
* uffs/flash/nand.h
|
||||||
//
|
*
|
||||||
//
|
* COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
|
||||||
// Use of this source code is subject to the terms of the Microsoft end-user
|
*
|
||||||
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
|
* The license and distribution terms for this file may be
|
||||||
// If you did not accept the terms of the EULA, you are not authorized to use
|
* found in the file LICENSE in this distribution or at
|
||||||
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
|
* http://www.rt-thread.org/license/LICENSE
|
||||||
// install media.
|
*
|
||||||
//
|
* Info:
|
||||||
/*++
|
* Contains standard defines and IDs for NAND flash devices
|
||||||
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
*/
|
||||||
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
#ifndef __RTT_DFS_NAND_H__
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
#define __RTT_DFS_NAND_H__
|
||||||
PARTICULAR PURPOSE.
|
|
||||||
--*/
|
|
||||||
#ifndef __NAND_H__
|
|
||||||
#define __NAND_H__
|
|
||||||
|
|
||||||
#include <s3c24x0.h>
|
/*
|
||||||
#include <uffs/uffs_types.h>
|
* Standard NAND flash commands
|
||||||
|
*/
|
||||||
|
#define NAND_CMD_READ0 0 /* Read0 */
|
||||||
|
#define NAND_CMD_READ1 1 /* Read1 */
|
||||||
|
#define NAND_CMD_RNDOUT 5 /* Random data output */
|
||||||
|
#define NAND_CMD_PAGEPROG 0x10 /* Write phase 2 */
|
||||||
|
#define NAND_CMD_READOOB 0x50 /* Read oob */
|
||||||
|
#define NAND_CMD_ERASE1 0x60 /* Erase phase 1 */
|
||||||
|
#define NAND_CMD_STATUS 0x70 /* Status read */
|
||||||
|
#define NAND_CMD_STATUS_MULTI 0x71
|
||||||
|
#define NAND_CMD_SEQIN 0x80 /* Write phase 1 */
|
||||||
|
#define NAND_CMD_RNDIN 0x85 /* Random data input */
|
||||||
|
#define NAND_CMD_READID 0x90 /* ReadID,all-purpose command */
|
||||||
|
#define NAND_CMD_ERASE2 0xd0 /* Erase phase 2 */
|
||||||
|
#define NAND_CMD_RESET 0xff /* Reset */
|
||||||
|
|
||||||
|
/* Extended commands for large page devices */
|
||||||
|
#define NAND_CMD_READSTART 0x30
|
||||||
|
#define NAND_CMD_RNDOUTSTART 0xE0
|
||||||
|
#define NAND_CMD_CACHEDPROG 0x15
|
||||||
|
#define NAND_CMD_READ_EDC 0x7b
|
||||||
|
|
||||||
/* define low accessing value */
|
/* define low accessing value */
|
||||||
#define TOTAL_BLOCKS 2048 /* total block of whole chip */
|
#define TOTAL_BLOCKS 2048 /* total block of whole chip */
|
||||||
|
@ -28,9 +44,9 @@ PARTICULAR PURPOSE.
|
||||||
#define PAGE_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE)/* max size per whole page */
|
#define PAGE_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE)/* max size per whole page */
|
||||||
#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE*PAGES_PER_BLOCK)/* max size per block' */
|
#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE*PAGES_PER_BLOCK)/* max size per block' */
|
||||||
|
|
||||||
//bad flags offset in the oob area.
|
/* bad flags offset in the oob area. */
|
||||||
#define NAND_SMALL_BADBLOCK_POS 5 //small page FLASH
|
#define NAND_SMALL_BADBLOCK_POS 5 /* small page FLASH */
|
||||||
#define NAND_LARGE_BADBLOCK_POS 0 //large page FLASH
|
#define NAND_LARGE_BADBLOCK_POS 0 /* large page FLASH */
|
||||||
|
|
||||||
/* Option constants for bizarre disfunctionality and real
|
/* Option constants for bizarre disfunctionality and real
|
||||||
* features
|
* features
|
||||||
|
@ -56,16 +72,14 @@ PARTICULAR PURPOSE.
|
||||||
#define NAND_SAMSUNG_LP_OPTIONS \
|
#define NAND_SAMSUNG_LP_OPTIONS \
|
||||||
(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
|
(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
|
||||||
|
|
||||||
|
|
||||||
struct nand_flash_dev
|
struct nand_flash_dev
|
||||||
|
|
||||||
{
|
{
|
||||||
char *name; //chip name
|
char *name; /* chip name */
|
||||||
int id; //chip ID
|
int id; /* chip ID */
|
||||||
unsigned long pagesize; //max pages
|
unsigned long pagesize; /* max pages */
|
||||||
unsigned long chipsize; //size of whole chip iMB
|
unsigned long chipsize; /* size of whole chip iMB */
|
||||||
unsigned long blocksize;//size of block
|
unsigned long blocksize;/* size of block */
|
||||||
unsigned long options; //option
|
unsigned long options; /* option */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nand_manufacturers
|
struct nand_manufacturers
|
||||||
|
@ -74,4 +88,4 @@ struct nand_manufacturers
|
||||||
char * name;
|
char * name;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*__NAND_H__*/
|
#endif /*__RTT_DFS_NAND_H__*/
|
||||||
|
|
|
@ -37,25 +37,25 @@
|
||||||
|
|
||||||
#ifndef _UFFS_H_
|
#ifndef _UFFS_H_
|
||||||
#define _UFFS_H_
|
#define _UFFS_H_
|
||||||
#include <dfs_def.h>
|
#include <rtthread.h>
|
||||||
#include "uffs/uffs_types.h"
|
#include "uffs/uffs_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"{
|
extern "C"{
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UO_RDONLY DFS_O_RDONLY /** read only */
|
#define UO_RDONLY 0x0000 /** read only */
|
||||||
#define UO_WRONLY DFS_O_WRONLY /** write only */
|
#define UO_WRONLY 0x0001 /** write only */
|
||||||
#define UO_RDWR DFS_O_RDWR /** read and write */
|
#define UO_RDWR 0x0002 /** read and write */
|
||||||
#define UO_APPEND DFS_O_APPEND /** append */
|
#define UO_APPEND 0x0008 /** append */
|
||||||
|
|
||||||
#define UO_BINARY 0x0000 /** no used in uffs */
|
#define UO_BINARY 0x0000 /** no used in uffs */
|
||||||
|
|
||||||
#define UO_CREATE DFS_O_CREAT
|
#define UO_CREATE 0x0100
|
||||||
#define UO_TRUNC DFS_O_TRUNC
|
#define UO_TRUNC 0x0200
|
||||||
#define UO_EXCL DFS_O_EXCL
|
#define UO_EXCL 0x0400
|
||||||
|
|
||||||
#define UO_DIR DFS_O_DIRECTORY /** open a directory */
|
#define UO_DIR 0x1000 /** open a directory */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,9 +85,9 @@ extern "C"{
|
||||||
#define _SEEK_SET 1 /** seek from beginning of file */
|
#define _SEEK_SET 1 /** seek from beginning of file */
|
||||||
#define _SEEK_END 2 /** seek from end of file */
|
#define _SEEK_END 2 /** seek from end of file */
|
||||||
|
|
||||||
#define USEEK_SET DFS_SEEK_SET /*0* 从当前点寻找 */
|
#define USEEK_CUR _SEEK_CUR
|
||||||
#define USEEK_CUR DFS_SEEK_CUR /*1* 从文件的开始寻找 */
|
#define USEEK_SET _SEEK_SET
|
||||||
#define USEEK_END DFS_SEEK_END /*2* 从文件的结尾寻找 */
|
#define USEEK_END _SEEK_END
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,15 +30,16 @@
|
||||||
on this file might be covered by the GNU General Public License.
|
on this file might be covered by the GNU General Public License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file uffs_fd.c
|
||||||
|
* \brief POSIX like, hight level file operations
|
||||||
|
* \author Ricky Zheng, created 8th Jun, 2005
|
||||||
|
*/
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "uffs/uffs_config.h"
|
#include "uffs/uffs_config.h"
|
||||||
#include "uffs/uffs_device.h"
|
|
||||||
#include "uffs/uffs_mtb.h"
|
|
||||||
#include "uffs/uffs_utils.h"
|
|
||||||
#include "uffs/uffs_fs.h"
|
#include "uffs/uffs_fs.h"
|
||||||
#include "uffs/uffs_fd.h"
|
#include "uffs/uffs_fd.h"
|
||||||
|
|
||||||
|
|
||||||
#define PFX "fd: "
|
#define PFX "fd: "
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ static int _uffs_errno = 0;
|
||||||
/**
|
/**
|
||||||
* initialise uffs_DIR buffers, called by UFFS internal
|
* initialise uffs_DIR buffers, called by UFFS internal
|
||||||
*/
|
*/
|
||||||
int uffs_InitDirEntryBuf(void)
|
URET uffs_InitDirEntryBuf(void)
|
||||||
{
|
{
|
||||||
return uffs_PoolInit(&_dir_pool, _dir_pool_data, sizeof(_dir_pool_data),
|
return uffs_PoolInit(&_dir_pool, _dir_pool_data, sizeof(_dir_pool_data),
|
||||||
sizeof(uffs_DIR), MAX_DIR_HANDLE);
|
sizeof(uffs_DIR), MAX_DIR_HANDLE);
|
||||||
|
@ -91,7 +92,7 @@ int uffs_InitDirEntryBuf(void)
|
||||||
/**
|
/**
|
||||||
* Release uffs_DIR buffers, called by UFFS internal
|
* Release uffs_DIR buffers, called by UFFS internal
|
||||||
*/
|
*/
|
||||||
int uffs_ReleaseDirEntryBuf(void)
|
URET uffs_ReleaseDirEntryBuf(void)
|
||||||
{
|
{
|
||||||
return uffs_PoolRelease(&_dir_pool);
|
return uffs_PoolRelease(&_dir_pool);
|
||||||
}
|
}
|
||||||
|
@ -105,7 +106,7 @@ static uffs_DIR * GetDirEntry(void)
|
||||||
{
|
{
|
||||||
uffs_DIR *dirp = (uffs_DIR *) uffs_PoolGet(&_dir_pool);
|
uffs_DIR *dirp = (uffs_DIR *) uffs_PoolGet(&_dir_pool);
|
||||||
|
|
||||||
if(dirp)
|
if (dirp)
|
||||||
memset(dirp, 0, sizeof(uffs_DIR));
|
memset(dirp, 0, sizeof(uffs_DIR));
|
||||||
|
|
||||||
return dirp;
|
return dirp;
|
||||||
|
@ -291,7 +292,6 @@ int uffs_remove(const char *name)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uffs_truncate(int fd, long remain)
|
int uffs_truncate(int fd, long remain)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -436,16 +436,14 @@ ext:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct uffs_dirent* uffs_readdir(uffs_DIR *dirp)
|
struct uffs_dirent * uffs_readdir(uffs_DIR *dirp)
|
||||||
{
|
{
|
||||||
struct uffs_dirent *ent = &dirp->dirent;
|
struct uffs_dirent *ent;
|
||||||
|
|
||||||
//CHK_DIR(dirp, NULL);
|
CHK_DIR(dirp, NULL);
|
||||||
if(dirp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(uffs_FindObjectNext(&dirp->info, &dirp->f) == RT_EOK)
|
if (uffs_FindObjectNext(&dirp->info, &dirp->f) == U_SUCC) {
|
||||||
{
|
ent = &dirp->dirent;
|
||||||
ent->d_ino = dirp->info.serial;
|
ent->d_ino = dirp->info.serial;
|
||||||
ent->d_namelen = dirp->info.info.name_len;
|
ent->d_namelen = dirp->info.info.name_len;
|
||||||
memcpy(ent->d_name, dirp->info.info.name, ent->d_namelen);
|
memcpy(ent->d_name, dirp->info.info.name, ent->d_namelen);
|
||||||
|
@ -464,14 +462,10 @@ void uffs_rewinddir(uffs_DIR *dirp)
|
||||||
{
|
{
|
||||||
CHK_DIR_VOID(dirp);
|
CHK_DIR_VOID(dirp);
|
||||||
|
|
||||||
uffs_FindObjectRewind(&dirp->f); //fi(=)find info
|
uffs_FindObjectRewind(&dirp->f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 函数功能: 创建一个文件夹
|
|
||||||
* 输入参数: 文件夹名称,参数
|
|
||||||
* 返回参数:
|
|
||||||
*/
|
|
||||||
int uffs_mkdir(const char *name, ...)
|
int uffs_mkdir(const char *name, ...)
|
||||||
{
|
{
|
||||||
uffs_Object *obj;
|
uffs_Object *obj;
|
||||||
|
@ -499,11 +493,6 @@ int uffs_mkdir(const char *name, ...)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 函数功能: 移除一个文件夹
|
|
||||||
* 输入参数: 文件夹名称
|
|
||||||
* 返回参数:
|
|
||||||
*/
|
|
||||||
int uffs_rmdir(const char *name)
|
int uffs_rmdir(const char *name)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -529,3 +518,15 @@ int uffs_rmdir(const char *name)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void uffs_seekdir(uffs_DIR *dirp, long loc)
|
||||||
|
{
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
long uffs_telldir(uffs_DIR *dirp)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "uffs_ext.h"
|
#include "uffs_ext.h"
|
||||||
|
|
||||||
#include <dfs_posix.h>
|
#include <dfs_posix.h>
|
||||||
#include <filerw.h>
|
#include <rtgui/filerw.h>
|
||||||
|
|
||||||
#ifdef RT_USING_FINSH
|
#ifdef RT_USING_FINSH
|
||||||
#include <finsh.h>
|
#include <finsh.h>
|
||||||
|
|
Loading…
Reference in New Issue