cancel
Showing results for 
Search instead for 
Did you mean: 

Question and comments about NAND driver

Steven Burck
Associate III

I am using STM32CubeMX version 4.26.1 - haven't upgraded to 5.0 because my customer won't agree to yet, as there is some stable code produced by the older version which they don't want to regression test right now. The device is the STM32H743IITX, library 1.3.0.

I have some questions about setting up the FMC driver for NAND flash, specifically the MX30LF1G18AC. The timing parameters given to set up don't seem to correspond to any of the timings given in the datasheet. Is there someone with knowledge of NAND who could assist me? My HCLK is 200MHz.

Also, I see my code is hanging in calls to HAL_NAND_Write_Page_8b. In the strange while loop in lines 831-841 of stm32h7xx_hal_nand.c, which looks like this:

  /* Read status until NAND is ready */

  while(HAL_NAND_Read_Status(hnand) != NAND_READY)

  {

   /* Get tick */

   tickstart = HAL_GetTick();

   

   if((HAL_GetTick() - tickstart ) > NAND_WRITE_TIMEOUT)

   {

    return HAL_TIMEOUT; 

   } 

  }   

The placement of the call to HAL_GetTick makes me pretty certain this will never time out. However, when I stop with a breakpoint and look into HAL_NAND_Read_Status, the status at that point (and only at that point, while running it doesn't happen), becomes ready and the function exits cleanly. If I leave it running, it does not complete and does not time out.

2 REPLIES 2

>>The placement of the call to HAL_GetTick makes me pretty certain this will never time out. 

Yes this is a bug, occurs at several points within the file, and has been fixed in subsequent release candidates. Basically pulling the line outside the loop to where it should be. I would suggest talking with an ST FAE about getting access to those.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Steven Burck
Associate III

Thanks Clive, but this is only the tip of my issue. In the meantime I've manually patched the misplace call to HAL_GetTick, but the issue is deeper. Let me try to explain what I'm seeing:

Here are some lines of sample testing code:

HAL_NAND_Read_ID(&hnand1, &NAND_ID);

NAND_AddressTypeDef addr;

addr.Plane = 0;

addr.Page = 0;

addr.Block = 0;

  HAL_NAND_Erase_Block(&hnand1, &addr);

memset(buffer, '*', sizeof(buffer));

memset(rbuffer, 'x', sizeof(rbuffer));

HAL_NAND_Write_Page_8b(&hnand1, &addr, buffer, 1);

HAL_NAND_Read_Page_8b(&hnand1, &addr, rbuffer, 1);

I check under the debugger the call to HAL_NAND_Read_ID works. I then do "step over" up until the call to HAL_NAND_Write_Page_8b, and everything is fine. When I try to step over HAL_NAND_Write_Page_8b, the software hangs. I place a breakpoint while the sofware is running at line 1830 of stm32h7xx_hal_nand.c, which looks like this:

 /* Read status register data */

 data = *(__IO uint8_t *)DeviceAddress;

 /* Return the status */

 if((data & NAND_ERROR) == NAND_ERROR) << breakpoint goes here

 {

  return NAND_ERROR;

 } 

 else if((data & NAND_READY) == NAND_READY)

 {

  return NAND_READY;

 }

 return NAND_BUSY; 

I figured, assuming that some error was occurring, that I would see the contents of the status register which was causing the error. However, the status of the value of data was always 0xE0 - meaning, as far as the bits being checked are, that it is ready.

I made two test modifications to the function HAL_NAND_Read_Status - first, I made "data" volatile. Second, I modified it, I believe correctly from uint32_t to uint8_t (look at the cast in the line where the data is being read). Neither made a difference. The breakpoint, when it hits, always show that up until now the value has been "ready".

I made a test on the HAL_NAND_Read_Status function, which looks like this:

uint8_t lastdataread = 0;

uint32_t HAL_NAND_Read_Status(NAND_HandleTypeDef *hnand)

{

 volatile uint8_t data = 0;

 uint32_t DeviceAddress = 0;

  

 /* Identify the device address */

  DeviceAddress = NAND_DEVICE;

 /* Send Read status operation command */

 *(__IO uint8_t *)((uint32_t)(DeviceAddress | CMD_AREA)) = NAND_CMD_STATUS;

  

 /* Read status register data */

 data = *(__IO uint8_t *)DeviceAddress;

 /* Return the status */

 if((data & NAND_ERROR) == NAND_ERROR)

 {

lastdataread = data;

  return NAND_ERROR;

 } 

 else if((data & NAND_READY) == NAND_READY)

 {

  return NAND_READY;

 }

 lastdataread = data;

 return NAND_BUSY; 

}

To see the current value of data which was always good, and the last values, which must have failed. In that case, I was seeing 0xFF in lastdataread.

Any ideas?