2016-06-02 03:09 PM
Hi
sorry that's just a typing mistake :)2016-06-02 06:25 PM
for
(index=0; index < size; index++)
pBuffer[index-2]= *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
index-2 !!!!
That is why your buffer is all messed up, pBuffer[-2] is problematic too.
2016-06-03 06:11 AM
Hisoheili.mehdi,
Please keep your initial post content. It is more helpful for other users to know how you fixed it. -Mayla- Title:STM32F4 NandFlash Timing Problem Description: Hi i have a big problem with nandflash nWait signal! i use this code to init fsmc for nandflash. i use K9f2g08u0c ,256Mbyte nand flash./* nWait->PD6 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6 , GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF ;
//GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-06-03 07:07 AM
Removing content and damaging thread integrity is likely to result in being black-listed.
From: soheili.mehdi Posted: Friday, June 03, 2016 12:09 AM Subject: STM32F4 NandFlash Timing ProblemHi
i have a big problem with nandflash nWait signal! i use this code to init fsmc for nandflash. i use K9f2g08u0c ,256Mbyte nand flash./* nWait->PD6 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6 , GPIO_AF_FSMC);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF ;
//GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/*-- FSMC Configuration ------------------------------------------------------*/
p.FSMC_SetupTime = 0xf2;
p.FSMC_WaitSetupTime = 0xf3;
p.FSMC_HoldSetupTime = 0xf2;
p.FSMC_HiZSetupTime = 0xf1;
FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;
FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes;
FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0xf1;
FSMC_NANDInitStructure.FSMC_TARSetupTime = 0xf3;
FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
FSMC_NANDInit(&FSMC_NANDInitStructure);
i have a big problem with writing and reading routine.
data is not same when reading back!
Nand Flash ID = EC,DA,10,95 Type = Unknow
Written to the number of£؛
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
Read several£؛
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 0 0
if i disable
FSMC_Waitfeature
:FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;
and use this routin for wait for nand ready signal
void
NandWaitForReady()
{
while
( GPIOD->IDR & (1 << 6) );
/* from high to low once */
while
( !(GPIOD->IDR & (1 << 6)) );
/* from low to high once */
return
;
}
i give same result!!! some first data loss!!!
i use this routine for reading and writing nandflash page data
/******************************************************************************
* Function Name : FSMC_NAND_WriteSmallPage
* Description : This routine is for writing one or several 512 Bytes Page size.
* Input : - pBuffer: pointer on the Buffer containing data to be written
* - Address: First page address
* - NumPageToWrite: Number of page to write
* Output : None
* Return : 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
* Attention : None
*******************************************************************************/
uint32_t FSMC_NAND_WriteSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite)
{
uint32_t index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
uint32_t status = NAND_READY, size = 0x00;
u8 i=0;
while
((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
{
/* Page write command and address */
*(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM;
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00;
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0X00;
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
/* Calculate the size */
size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
/* Write data */
for
(index=0; index < size; index++)
{
*(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA) = pBuffer[index];
}
*(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM_TRUE;
//for(index=0; index < 0x300; index++);//ÑÓʱ
NandWaitForReady();
/* Check status for successful operation */
status = FSMC_NAND_GetStatus();
if
(status == NAND_READY)
{
numpagewritten++;
NumPageToWrite--;
/* Calculate Next small page Address */
addressstatus = FSMC_NAND_AddressIncrement(&Address);
}
}
return
(status | addressstatus);
}
/******************************************************************************
* Function Name : FSMC_NAND_ReadSmallPage
* Description : This routine is for sequential read from one or several
* 512 Bytes Page size.
* Input : - pBuffer: pointer on the Buffer to fill
* - Address: First page address
* - NumPageToRead: Number of page to read
* Output : None
* Return : 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
* Attention : None
*******************************************************************************/
uint32_t FSMC_NAND_ReadSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToRead)
{
uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
uint32_t status = NAND_READY, size = 0x00;
u8 i=0;
while
((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
{
/* Page Read command and page address */
*(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READ_1;
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00;
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0X00;
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
*(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READ_TRUE;
NandWaitForReady();
/* Calculate the size */
size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
//
/* Get Data into Buffer */
for
(index=0; index < size; index++)
{
pBuffer[index-2]= *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
}
numpageread++;
NumPageToRead--;
/* Calculate page address */
addressstatus = FSMC_NAND_AddressIncrement(&Address);
}
status = FSMC_NAND_GetStatus();
return
(status | addressstatus);
}
if i use a loop for make delay for nand ready state ,finally i could give correct data!!!!
ready and writing bytes from nandpage is same!!!
for
(index=0; index < 0x450; index++);
i confused about it really.
why waitfeature is not correct work when i enable it?
i don't know how must calculate correct timing for fsmc nand flash.
thanks alot for your attention.
pls help me
2018-11-28 10:30 PM
Hello,I also encountered a similar problem on the STM32F765VIT6 (flash: K9F4G08U0M),
But my Driver code is stm32f7xx_hal_nand.c, AND Just occasionally this problem�?
have you solved this problem? How to solve it? Looking forward to your reply! Thank you very much�?�? @Community member @Cyril FENARD @Khouloud GARSI
/**
* @brief Read Page(s) from NAND memory block (8-bits addressing)
* @param hnand pointer to a NAND_HandleTypeDef structure that contains
* the configuration information for NAND module.
* @param pAddress pointer to NAND address structure
* @param pBuffer pointer to destination read buffer
* @param NumPageToRead number of pages to read from block
* @retval HAL status
*/
HAL_StatusTypeDef HAL_NAND_Read_Page_8b(NAND_HandleTypeDef *hnand, NAND_AddressTypeDef *pAddress, uint8_t *pBuffer, uint32_t NumPageToRead)
{
__IO uint32_t index = 0;
uint32_t tickstart = 0U;
uint32_t deviceAddress = 0, size = 0, numPagesRead = 0, nandAddress = 0;
/* Process Locked */
__HAL_LOCK(hnand);
/* Check the NAND controller state */
if(hnand->State == HAL_NAND_STATE_BUSY)
{
return HAL_BUSY;
}
/* Identify the device address */
deviceAddress = NAND_DEVICE;
/* Update the NAND controller state */
hnand->State = HAL_NAND_STATE_BUSY;
/* NAND raw address calculation */
nandAddress = ARRAY_ADDRESS(pAddress, hnand);
/* Page(s) read loop */
while((NumPageToRead != 0) && (nandAddress < ((hnand->Config.BlockSize) * (hnand->Config.BlockNbr))))
{
/* update the buffer size */
size = (hnand->Config.PageSize) + ((hnand->Config.PageSize) * numPagesRead);
/* Send read page command sequence */
*(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_A;
__DSB();
/* Cards with page size <= 512 bytes */
if((hnand->Config.PageSize) <= 512)
{
if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
{
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
__DSB();
}
else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
{
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
__DSB();
}
}
else /* (hnand->Config.PageSize) > 512 */
{
if (((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) <= 65535)
{
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
__DSB();
}
else /* ((hnand->Config.BlockSize)*(hnand->Config.BlockNbr)) > 65535 */
{
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = 0x00;
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_1ST_CYCLE(nandAddress);
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_2ND_CYCLE(nandAddress);
__DSB();
*(__IO uint8_t *)((uint32_t)(deviceAddress | ADDR_AREA)) = ADDR_3RD_CYCLE(nandAddress);
__DSB();
}
}
*(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = NAND_CMD_AREA_TRUE1;
__DSB();
if(hnand->Config.ExtraCommandEnable == ENABLE)
{
/* Get tick */
tickstart = HAL_GetTick();
/* Read status until NAND is ready */
while(HAL_NAND_Read_Status(hnand) != NAND_READY)
{
if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)
{
return HAL_TIMEOUT;
}
}
/* Go back to read mode */
*(__IO uint8_t *)((uint32_t)(deviceAddress | CMD_AREA)) = ((uint8_t)0x00U);
__DSB();
}
/* Get Data into Buffer */
for(; index < size; index++)
{
*(uint8_t *)pBuffer++ = *(uint8_t *)deviceAddress;
}
/* Increment read pages number */
numPagesRead++;
/* Decrement pages to read */
NumPageToRead--;
/* Increment the NAND address */
nandAddress = (uint32_t)(nandAddress + 1);
}
/* Update the NAND controller state */
hnand->State = HAL_NAND_STATE_READY;
/* Process unlocked */
__HAL_UNLOCK(hnand);
return HAL_OK;
}
2018-11-28 10:37 PM
@Cyril FENARD @Khouloud GARSI @Community member : Looking forward to your reply! Thank you very much�?�?