📄 nand_flash.c
字号:
/******************** (C) COPYRIGHT 2005 STMicroelectronics ********************
* File Name : nand_flash.c
* Author : EMR - ARM 32 bit Team
* Date First Issued : 21/Oct/2005
* Description : This file provides all the NANDXXXRW3A NAND FLASH drivers
********************************************************************************
* History:
* 21/10/2005 Filippo Colaianni
*******************************************************************************/
#define NAND256RW3A
#include "nand_flash.h"
volatile u8* baseAddr_ = (volatile u8*)BASEADDR;
/*******************************************************************************
* Function Name : NandCommand
* Description : Send a Command To nand Flash
*******************************************************************************/
void NandCommand(u8 cmd)
{
//Configuration Pins CLE = 1, nCE = 0, ALE = 0
*((u8 *)(BASEADDR | CLE )) = cmd;
}
/*******************************************************************************
* Function Name : Nand_WriteProtect and Nand_WriteUnprotect
* Description : Set Write Protect pin
* Output : None
*******************************************************************************/
void Nand_WriteProtect (void)
{
GPIO_BitWrite(GPIO2, 4, 0);
}
void Nand_WriteUnprotect (void)
{
GPIO_BitWrite(GPIO2, 4, 1);
}
/*******************************************************************************
* Function Name : Nand_CE_Active and Nand_CE_noActive
* Description : Set Memory ChipEnable up and Down
* Output : None
*******************************************************************************/
void Nand_CE_Active (void)
{
GPIO_BitWrite(GPIO2, 3, 0);
}
void Nand_CE_noActive (void)
{
GPIO_BitWrite(GPIO2, 3, 1);
}
/*******************************************************************************
* Function Name : Nand_CE_Active and Nand_CE_noActive
* Description : Set Memory Address Command up and Down
* Output : None
*******************************************************************************/
void Nand_ALE_Active (void)
{
GPIO_BitWrite(GPIO2, 6, 1);
}
void Nand_ALE_noActive (void)
{
GPIO_BitWrite(GPIO2, 6, 0);
}
/*******************************************************************************
* Function Name : Nand_Ready
* Description : Read R/B NAND Flash Busy to Ready Status
* Output : None
*******************************************************************************/
u16 Nand_Ready (void)
{
return GPIO_BitRead(GPIO2, 7);
}
/*******************************************************************************
* Function Name : NandSendAddress
* Description : Nand Send Adrress by I/O bus
* Output : None
*******************************************************************************/
void NandSendAddress(u32 address)
{
//Configuration Pins CLE = 0, nCE = 0, ALE = 1
GPIO_Config (GPIO2, A22_P26, GPIO_OUT_PP);
Nand_ALE_Active();
*(baseAddr_) = (u8) (address & MaskAddr_1Cycle);
*(baseAddr_) = (u8) ((address & MaskAddr_2Cycle) >> (8 + shift_A8));
*(baseAddr_) = (u8) ((address & MaskAddr_3Cycle) >> (16 + shift_A8));
*(baseAddr_) = (u8) (address >> ((24 + shift_A8)) & 0x03);
Nand_ALE_noActive();
}
/*******************************************************************************
* Function Name : NandSendAddress
* Description : Nand Send Adrress by I/O bus
* Output : None
*******************************************************************************/
void NandSendCAddress(u32 address)
{
Nand_ALE_Active();
//Configuration Pins CLE = 0, nCE = 0, ALE = 1
GPIO_Config (GPIO2, A22_P26, GPIO_OUT_PP);
*(baseAddr_) = (u8) ((address & MaskAddr_2Cycle) >> (8 + shift_A8));
*(baseAddr_) = (u8) ((address & MaskAddr_3Cycle) >> (16 + shift_A8));
Nand_ALE_noActive();
}
/*******************************************************************************
* Function Name : NandDataInput
* Description : Write Data Output on I/o bus
* Output : None
*******************************************************************************/
void NandDataInput(u8 data)
{
*baseAddr_ = data;
}
/*******************************************************************************
* Function Name : NandDataOutput
* Description : Read Data Input from I/o bus
* Output : u8 data
*******************************************************************************/
u8 NandDataOutput()
{
return *baseAddr_;
}
/*******************************************************************************
* Function Name : Nand Flash init
* Description : initialize nand flash
* Output : None
*******************************************************************************/
void NandFlashInit (void)
{
// Config EMI Bank
EMI_Config ( 3, EMI_ENABLE | EMI_WAITSTATE(15) | EMI_SIZE_16 ) ;
GPIO_Config (GPIO2, A23_P27 , GPIO_IN_TRI_CMOS); // RnB
GPIO_Config (GPIO2, CS3_P23, GPIO_OUT_PP); // Chip Selecet
GPIO_Config (GPIO2, A21_P25, GPIO_AF_PP); // CLE
GPIO_Config (GPIO2, A22_P26, GPIO_OUT_PP); // ALE
GPIO_Config (GPIO2, A20_P24, GPIO_OUT_PP); // WP
Nand_ALE_noActive(); // Set ALE to 0
Nand_CE_noActive(); // Set CS3 to 0, Enable
Nand_WriteUnprotect();
// Clear the status register
NandCommand (Nand_Reset);
while(!(NandReadStausRegister()&(NandReady|!NandError)));
}
/*******************************************************************************
* Function Name : NandReadStausRegister
* Description : Read the status register of the Nand flash
* Output : None
* Return : The status register value : NandError, NandReady, NandWriteProtect.
SR0 - Generic Error = 1 Error, 0 No Error NandError
SR6 - Controller Bit = 1 Device Ready, 0 Device Busy NandReady
SR7 - Write Protection= 1 Not Protect, 0 Protected NandWriteProtect
SR1,2,3 and 5 are reserved
*******************************************************************************/
u8 NandReadStausRegister(void)
{
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
NandCommand(Nand_ReadStatusReg);
return *baseAddr_;
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandReadEletrocnicSignature
* Description : Read the Nand flash device code
* Output : None
* Return : The device code value
*******************************************************************************/
u16 NandReadEletrocnicSignature(void)
{
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
NandCommand(Nand_ReadElectSign);
return *baseAddr_;
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandReadData
* Description : Read Data at specified address
* Output : None
* Return : Data
* Area A Bytes 0-255
* Area B Bytes 256-511
*******************************************************************************/
u8 NandReadData(u32 address)
{u8 data_;
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
if ( (address % PAGE_DATA_SIZE) >= PAGE_DATA_SIZE/2 )
NandCommand(Nand_AreaB); /* First Half Page - Area B*/
else NandCommand(Nand_AreaA); /* Second Half Page - Area A*/
NandSendAddress(address);
while(!Nand_Ready()); // Read RnB Pin, Wait for Ready State
data_ = NandDataOutput();
Nand_CE_noActive();
return data_;
}
/*******************************************************************************
* Function Name : NandReadNData
* Description : Read Data at specified address
* Output : None
* Return : Data
* Area A Bytes 0-255
* Area B Bytes 256-511
*******************************************************************************/
void NandReadNData(u32 address, u16 N, u8 *Pdata)
{ u8 i;
u16 NByteAdrress;
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
if ( (address % PAGE_DATA_SIZE) >= PAGE_DATA_SIZE/2 )
NandCommand(Nand_AreaB); /* First Half Page - Area B*/
else NandCommand(Nand_AreaA); /* Second Half Page - Area A*/
NandSendAddress(address);
while(!Nand_Ready()); // Read RnB Pin, Wait for Ready State
NByteAdrress = (u8) (address & MaskAddr_1Cycle);
i = 0;
while ((i<N)&&(NByteAdrress<=((PAGE_DATA_SIZE/2)))) {
*(Pdata+i) = NandDataOutput(); // Read Bytes into same Page
i++; NByteAdrress++;
}
i--;
if (i<N-1) { // Jump in Next Page
Nand_CE_noActive();
address = address + i;
NandReadNData(address, N-i, (Pdata+i));
}
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandWriteByte
* Description : Writing a Byte in specified address into memory
* Output : None
*******************************************************************************/
void NandWriteByte (u32 address, u8 data)
{
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
if ( (address % PAGE_DATA_SIZE) >= PAGE_DATA_SIZE/2 )
NandCommand(Nand_AreaB); /* Select Area B*/
else NandCommand(Nand_AreaA); /* Select Area A*/
NandCommand(Nand_PageProgram);
NandSendAddress(address);
NandDataInput(data);
NandCommand(Nand_EndPageProg);
while(!Nand_Ready()); // Read RnB Pin, Wait for Ready State
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandWriteNBytes
* Description : Writing N sequenzially Bytes in specified address into memory
* Output : None
******************************************************************************/
void NandWriteNBytes (u32 address, u16 N, u8 *vectData)
{ u8 i;
u16 NByteAdrress;
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
if ( (address % PAGE_DATA_SIZE) >= PAGE_DATA_SIZE/2 )
NandCommand(Nand_AreaB); /* Select Area B*/
else NandCommand(Nand_AreaA); /* Select Area A*/
NandCommand(Nand_PageProgram);
NandSendAddress(address);
NByteAdrress = (u8) (address & MaskAddr_1Cycle);
i = 0;
while ((i<N)&&(NByteAdrress<=((PAGE_DATA_SIZE/2)))) {
NandDataInput(*(vectData+i));
i++; NByteAdrress++;
}
NandCommand(Nand_EndPageProg);
while(!Nand_Ready()); // Read RnB Pin, Wait for Ready State
i--;
if (i<N-1) { // Jump in Next Page
Nand_CE_noActive();
address = address + i;
NandWriteNBytes(address, N-i, (vectData+i));
}
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandCopyPage
* Description : Copy All
* Output : None
* Return : Data
* Area A Bytes 0-255
* Area B Bytes 256-511
*******************************************************************************/
void NandCopyPage(u32 address, u32 DestAddr)
{ u8 data;
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
if ( (address % PAGE_DATA_SIZE) >= PAGE_DATA_SIZE/2 )
NandCommand(Nand_AreaB); /* First Half Page - Area B*/
else NandCommand(Nand_AreaA); /* Second Half Page - Area A*/
NandSendAddress(address);
while(!Nand_Ready());
data = *baseAddr_;
NandCommand(Nand_CopyBack);
NandSendAddress(DestAddr);
NandCommand(Nand_EndPageProg);
while(!Nand_Ready());
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandBlockErase
* Description : Erase Block Nand Flash
* Output : None
* In : Address Block A14-A24
*******************************************************************************/
void NandBlockErase(u32 address)
{
Nand_CE_Active();
GPIO_Config(GPIO2, A23_P27, GPIO_IN_TRI_CMOS);
NandCommand(Nand_BlockErase);
NandSendCAddress(address);
NandCommand(Nand_ConfirmErase);
while(!Nand_Ready());
while(!(NandReadStausRegister()&(NandReady|!NandError)));
Nand_CE_noActive();
}
/*******************************************************************************
* Function Name : NandErase_All
* Description : Erase All Blocks in Nand Flash
* Output : None
*******************************************************************************/
void NandErase_All()
{ u16 i;
u32 NandAddress = 0x66000000;
for (i=0; i<2048; i++, NandAddress += 0x4000)
NandBlockErase(NandAddress);
}
/*******************************************************************************
* Function Name : Close All
* Description : Reload Standard Configuration for GPIO midified
* Output : None
*******************************************************************************/
void NandClose()
{
Nand_CE_noActive();
GPIO_Config(GPIO2,A23_P27, GPIO_AF_PP);
GPIO_Config (GPIO2, A22_P26, GPIO_AF_PP);
GPIO_Config (GPIO2, A20_P24, GPIO_OUT_PP);
GPIO_Config (GPIO2, CS3_P23, GPIO_AF_PP);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -