cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 -

eittinfo
Associate II
Posted on June 03, 2016 at 00:09

Hi

sorry that's just a typing mistake 🙂
5 REPLIES 5
Posted on June 03, 2016 at 03:25

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.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Amel NASRI
ST Employee
Posted on June 03, 2016 at 15:11

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.

Posted on June 03, 2016 at 16:07

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 Problem

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); 
/*-- 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
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

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​ 

  • The read code as follows:
/**
  * @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;
 
}

@Cyril FENARD​ @Khouloud GARSI​ @Community member​ : Looking forward to your reply! Thank you very much�?�?