##include "include.h"
#include "Nand_Flash.h"
void Nand_FSMC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
FSMC_NAND_PCCARDTimingInitTypeDef p;
FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
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);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_Init(GPIOE, &GPIO_InitStructure);
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);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOG, &GPIO_InitStructure);
p.FSMC_SetupTime = 0x1; //建立时间
p.FSMC_WaitSetupTime = 0x3; //等待时间
p.FSMC_HoldSetupTime = 0x2; //保持时间
p.FSMC_HiZSetupTime = 0x1; //高阻建立时间
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND; //使用FSMC BANK2
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable; //使能FSMC的等待功能
FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; //NAND Flash的数据宽度为8位
FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable; //使能ECC特性
FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes; //ECC页大小2048
FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStru ct =
&p;
FSMC_NANDInit(&FSMC_NANDInitStructure);
FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
}
uint8 Nand_GetState(void)
{
NAND_CMD=0x70;
return NAND_DAT8;
}
void Nand_WriteAddr(uint32 RowAddr,uint16 ColAddr)
{
NAND_ADR16=ColAddr;
NAND_ADR=(uint8)RowAddr;
NAND_ADR16=(RowAddr>>8);
}
uint32 Nand_GetID(void)
{
NAND_CMD=0x90;
NAND_ADR=0x00;
return NAND_DAT32;
}
void Nand_ReadPage(uint32 StartPage,uint8 *rBuffer,uint16 ByteOffset,uint16 Length)
{
uint16 *DP=(uint16 *)rBuffer;
NAND_CMD=0x00;
Nand_WriteAddr(StartPage,ByteOffset);
NAND_CMD=0x30;
Tos_TaskDelay(1);
Length>>=1;
do{
*DP++=NAND_DAT16;
}while(--Length);
}
void Nand_ReadPage_Random(uint16 ByteOffset,uint8 *rBuffer,uint16 Length)
{
NAND_CMD=0x05;
NAND_ADR=(uint8)(ByteOffset);
NAND_ADR=(uint8)(ByteOffset>>8); //写入页内偏移地址
NAND_CMD=0xE0;
while(Length--)*rBuffer++=NAND_DAT8;
}
void Nand_FillPage(uint32 StartPage,uint8 Data,uint16 ByteOffset,uint16 Length)
{
uint32 T;
T=Data;T<<=8;T|=Data;T<<=8;T|=Data;T<<=8;T|=Data; // 合并成32Bit数据
NAND_CMD=0x80;
Nand_WriteAddr(StartPage,ByteOffset);
Length>>=2;
do{NAND_DAT32=T;}while(--Length);
NAND_CMD=0x10;
}
void Nand_WritePage(uint32 StartPage,uint8 *wBuffer,uint16 ByteOffset,uint16 Length)
{
NAND_CMD=0x80;
Nand_WriteAddr(StartPage,ByteOffset);
while(Length--)NAND_DAT8=*wBuffer++;
NAND_CMD=0x10;
}
void Nand_WritePage_WriteStart(uint32 StartPage)
{
NAND_CMD=0x80;
Nand_WriteAddr(StartPage,0); // 按照物理页大小进行读取
}
void Nand_WritePage_WriteRandom(uint16 ByteOffset,uint8 *wBuffer,uint16 Length)
{
NAND_CMD=0x85;
NAND_ADR=(uint8)(ByteOffset);
NAND_ADR=(uint8)(ByteOffset>>8);
while(Length--)NAND_DAT8=*wBuffer++;
}
void Nand_WritePage_WriteStop(void)
{
NAND_CMD=0x10;
}
void Nand_CopyBack(uint32 StartPage,uint32 DestPage)
{
NAND_CMD=0x00;
Nand_WriteAddr(StartPage,0);
NAND_CMD=0x35;
NAND_CMD=0x85;
Nand_WriteAddr(DestPage,0);
NAND_CMD=0x10;
}
void Nand_CopyBack_WriteStart(uint32 StartPage,uint32 DestPage)
{
NAND_CMD=0x00;
Nand_WriteAddr(StartPage,0);
NAND_CMD=0x35;
NAND_CMD=0x85;
Nand_WriteAddr(DestPage,0);
}
void Nand_CopyBack_WriteRandom(uint16 ByteOffset,uint8 *wBuffer,uint16 Length)
{
// uint32 *DP=(uint32 *)wBuffer;
NAND_CMD=0x85;
NAND_ADR=(uint8)(ByteOffset);
NAND_ADR=(uint8)(ByteOffset>>8);
while(Length--)NAND_DAT8=*wBuffer++;
// Length>>=2;
// do{NAND_DAT32=*DP++;}while(--Length);
}
void Nand_CopyBack_WriteStop(void)
{
NAND_CMD=0x10;
}
void Nand_EraseBlock(uint32 BlockAddr)
{
NAND_CMD=0x60;
BlockAddr*=NAND_BLOCK_SIZE; //转换到块地址
NAND_ADR=(uint8)BlockAddr;
NAND_ADR=(uint8)(BlockAddr>>8);
NAND_ADR=(uint8)(BlockAddr>>16);
NAND_CMD=0xD0;
}
void NandFlash_Write(void *Addr,void *Data,void *Length)
{
}
void NandFlash_Read(void *Addr,void *Data,void *Length)
{
}
void DeviceMount_NandFlash()
{
_Tos_Device_Tab[DeviceId_NandFlash].DeviceId=DeviceId_NandFlash;
_Tos_Device_Tab[DeviceId_NandFlash].DeviceName="NandFlash";
_Tos_Device_Tab[DeviceId_NandFlash].DeviceOwnerId=Null;
_Tos_Device_Tab[DeviceId_NandFlash].DeviceVirtue=ReadOnly|WriteOnly|CharDerice;
_Tos_Device_Tab[DeviceId_NandFlash].DeviceState=Ready;
_Tos_Device_Tab[DeviceId_NandFlash].Init=Nand_FSMC_Init;
_Tos_Device_Tab[DeviceId_NandFlash].Write=NandFlash_Write;
_Tos_Device_Tab[DeviceId_NandFlash].Read=NandFlash_Read;
_Tos_Device_Tab[DeviceId_NandFlash].Exit=Null;
}
#include "Nand_Flash.h"
void Nand_FSMC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
FSMC_NAND_PCCARDTimingInitTypeDef p;
FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
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);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_Init(GPIOE, &GPIO_InitStructure);
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);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOG, &GPIO_InitStructure);
p.FSMC_SetupTime = 0x1; //建立时间
p.FSMC_WaitSetupTime = 0x3; //等待时间
p.FSMC_HoldSetupTime = 0x2; //保持时间
p.FSMC_HiZSetupTime = 0x1; //高阻建立时间
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND; //使用FSMC BANK2
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable; //使能FSMC的等待功能
FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; //NAND Flash的数据宽度为8位
FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable; //使能ECC特性
FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes; //ECC页大小2048
FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStru
FSMC_NANDInit(&FSMC_NANDInitStructure);
FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
}
uint8 Nand_GetState(void)
{
NAND_CMD=0x70;
return NAND_DAT8;
}
void Nand_WriteAddr(uint32 RowAddr,uint16 ColAddr)
{
NAND_ADR16=ColAddr;
NAND_ADR=(uint8)RowAddr;
NAND_ADR16=(RowAddr>>8);
}
uint32 Nand_GetID(void)
{
NAND_CMD=0x90;
NAND_ADR=0x00;
return NAND_DAT32;
}
void Nand_ReadPage(uint32 StartPage,uint8 *rBuffer,uint16 ByteOffset,uint16 Length)
{
uint16 *DP=(uint16 *)rBuffer;
NAND_CMD=0x00;
Nand_WriteAddr(StartPage,ByteOffset);
NAND_CMD=0x30;
Tos_TaskDelay(1);
Length>>=1;
do{
*DP++=NAND_DAT16;
}while(--Length);
}
void Nand_ReadPage_Random(uint16 ByteOffset,uint8 *rBuffer,uint16 Length)
{
NAND_CMD=0x05;
NAND_ADR=(uint8)(ByteOffset);
NAND_ADR=(uint8)(ByteOffset>>8); //写入页内偏移地址
NAND_CMD=0xE0;
while(Length--)*rBuffer++=NAND_DAT8;
}
void Nand_FillPage(uint32 StartPage,uint8 Data,uint16 ByteOffset,uint16 Length)
{
uint32 T;
T=Data;T<<=8;T|=Data;T<<=8;T|=Data;T<<=8;T|=Data; // 合并成32Bit数据
NAND_CMD=0x80;
Nand_WriteAddr(StartPage,ByteOffset);
Length>>=2;
do{NAND_DAT32=T;}while(--Length);
NAND_CMD=0x10;
}
void Nand_WritePage(uint32 StartPage,uint8 *wBuffer,uint16 ByteOffset,uint16 Length)
{
NAND_CMD=0x80;
Nand_WriteAddr(StartPage,ByteOffset);
while(Length--)NAND_DAT8=*wBuffer++;
NAND_CMD=0x10;
}
void Nand_WritePage_WriteStart(uint32 StartPage)
{
NAND_CMD=0x80;
Nand_WriteAddr(StartPage,0); // 按照物理页大小进行读取
}
void Nand_WritePage_WriteRandom(uint16 ByteOffset,uint8 *wBuffer,uint16 Length)
{
NAND_CMD=0x85;
NAND_ADR=(uint8)(ByteOffset);
NAND_ADR=(uint8)(ByteOffset>>8);
while(Length--)NAND_DAT8=*wBuffer++;
}
void Nand_WritePage_WriteStop(void)
{
NAND_CMD=0x10;
}
void Nand_CopyBack(uint32 StartPage,uint32 DestPage)
{
NAND_CMD=0x00;
Nand_WriteAddr(StartPage,0);
NAND_CMD=0x35;
NAND_CMD=0x85;
Nand_WriteAddr(DestPage,0);
NAND_CMD=0x10;
}
void Nand_CopyBack_WriteStart(uint32 StartPage,uint32 DestPage)
{
NAND_CMD=0x00;
Nand_WriteAddr(StartPage,0);
NAND_CMD=0x35;
NAND_CMD=0x85;
Nand_WriteAddr(DestPage,0);
}
void Nand_CopyBack_WriteRandom(uint16 ByteOffset,uint8 *wBuffer,uint16 Length)
{
// uint32 *DP=(uint32 *)wBuffer;
NAND_CMD=0x85;
NAND_ADR=(uint8)(ByteOffset);
NAND_ADR=(uint8)(ByteOffset>>8);
while(Length--)NAND_DAT8=*wBuffer++;
// Length>>=2;
// do{NAND_DAT32=*DP++;}while(--Length);
}
void Nand_CopyBack_WriteStop(void)
{
NAND_CMD=0x10;
}
void Nand_EraseBlock(uint32 BlockAddr)
{
NAND_CMD=0x60;
BlockAddr*=NAND_BLOCK_SIZE; //转换到块地址
NAND_ADR=(uint8)BlockAddr;
NAND_ADR=(uint8)(BlockAddr>>8);
NAND_ADR=(uint8)(BlockAddr>>16);
NAND_CMD=0xD0;
}
void NandFlash_Write(void *Addr,void *Data,void *Length)
{
}
void NandFlash_Read(void *Addr,void *Data,void *Length)
{
}
void DeviceMount_NandFlash()
{
_Tos_Device_Tab[DeviceId_NandFlash].DeviceId=DeviceId_NandFlash;
_Tos_Device_Tab[DeviceId_NandFlash].DeviceName="NandFlash";
_Tos_Device_Tab[DeviceId_NandFlash].DeviceOwnerId=Null;
_Tos_Device_Tab[DeviceId_NandFlash].DeviceVirtue=ReadOnly|WriteOnly|CharDerice;
_Tos_Device_Tab[DeviceId_NandFlash].DeviceState=Ready;
_Tos_Device_Tab[DeviceId_NandFlash].Init=Nand_FSMC_Init;
_Tos_Device_Tab[DeviceId_NandFlash].Write=NandFlash_Write;
_Tos_Device_Tab[DeviceId_NandFlash].Read=NandFlash_Read;
_Tos_Device_Tab[DeviceId_NandFlash].Exit=Null;
}