标题:
STM32-移植FATFS的NANDFLASH驱动(4)
[打印本页]
作者:
yuyang911220
时间:
2015-4-28 21:12
标题:
STM32-移植FATFS的NANDFLASH驱动(4)
/**
* @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 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 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);
}
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0