cancel
Showing results for 
Search instead for 
Did you mean: 

Read/write from stm32f4 to an external SLC NAND flash - S34ML02G through HAL and FSMC

MLind.5
Associate

Hi,

I am using a custom board equipped with an stm32f417VGT and an external SLC NAND flash (more specifically S34ML02G).

Through reading and writing from GPIOs I successfully "bit-banged" the read and write operations between the MCU and the NAND flash.

However, when I tried to initialize the drive and read the flash ID (which works in the bit-banged version) through the library FSMC / HAL_NAND driver it does neither return the correct ID or the correct data (it actually prints my message "NandFlash Read Write Failed") See 3rd code snippet down below.

What I do want to accomplish is to use the FSMC to read and write data from and to the NAND flash.

In the FSMC driver, I do need to specify the correct read timings.

These calculations are as follow (found in a seprate datasheet):

(SET + 1) x tHCLK ≥ max (tCS, tCLS, tALS, tCLR, tAR) - tWP

(WAIT + 1) x tHCLK ≥ max (tWP, tRP)

(HIZ) x tHCLK ≥ max (tCS, tALS, tCLS) + (tWP - tDS)

(HOLD) x tHCLK ≥ max (tCH, tCLH, tALH)

((WAIT + 1) + (HOLD) + (SET + 1)) x tHCLK ≥ max (tWC/RC)

The time variable taken from the clock frequency I use in the project:

tHCLK = 5,9523480952380952e-9s = (1 / 168000000)

The time variables for S34ML02G are as follow (from the flash's datasheet):

tALH = 5 e-9

tALS = 10e-9 s

tAR = 10e-9 s

tCH = 5 e-9

tCLH = 5 e-9

tCLR = 10e-9 s

tCLS = 10e-9 s

tCS = 20e-9 s

tDS = 10 e-9

tRP = 12 e-9 s

tWP = 12e-9 s

Hence, I get the formulas:

set = max(tcs,tcls,tals,tclr,tar)-twp / thclk - 1

wait = max(tWP, tRP) / tCHLK - 1

HIZ = (max(tCS, tALS, tCLS) + (tWP - tDS)) / tHCLK

HOLD = max(tch, tCLH, tALH) / tHCLK

From the formulas above I get the values:

set = 1/3 e-9 = 0

wait = 12/6 - 1 = 1

HiZ = 20 + (12-10) / 6 = 22/6 = 4,4 = 4

HOLD = 5/6 = 0

At this point I have not got the FSMC to work, therefore I wonder, Am I missing something in my calculations or code?

Am I doing something wrong during the initialization or read/write functions?

Furthermore, do you have any suggestions on how to continue the debugging?

Code for initialization of the pins for FSMC

GPIO_InitTypeDef GPIO_InitStruct ={0};
  if (FSMC_Initialized) {
    return;
  }
  FSMC_Initialized = 1;
 
  /* Peripheral clock enable */
  __HAL_RCC_FSMC_CLK_ENABLE();
 
  /** FSMC GPIO Configuration
  PE7   ------> FSMC_D4
  PE8   ------> FSMC_D5
  PE9   ------> FSMC_D6
  PE10   ------> FSMC_D7
  PD11   ------> FSMC_CLE
  PD12   ------> FSMC_ALE
  PD14   ------> FSMC_D0
  PD15   ------> FSMC_D1
  PD0   ------> FSMC_D2
  PD1   ------> FSMC_D3
  PD4   ------> FSMC_NOE
  PD5   ------> FSMC_NWE
  PD6   ------> FSMC_NWAIT
  PD7   ------> FSMC_NCE2
  */
  GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
  GPIO_InitStruct.Pin =  GPIO_PIN_7|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15
                          |GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5
                          |GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

Code for initialisation of FSMC

FSMC_NAND_PCC_TimingTypeDef ComSpaceTiming = {0};
	FSMC_NAND_PCC_TimingTypeDef AttSpaceTiming = {0};
 
	/** Perform the NAND1 memory initialization sequence
	*/
	hnand1->Instance = FSMC_NAND_DEVICE;
	/* hnand1.Init */
	hnand1->Init.NandBank = FSMC_NAND_BANK2;
	hnand1->Init.Waitfeature = FSMC_NAND_PCC_WAIT_FEATURE_DISABLE;
	hnand1->Init.MemoryDataWidth = FSMC_NAND_PCC_MEM_BUS_WIDTH_8;
	hnand1->Init.EccComputation = FSMC_NAND_ECC_DISABLE;
	hnand1->Init.ECCPageSize = FSMC_NAND_ECC_PAGE_SIZE_256BYTE;
	hnand1->Init.TCLRSetupTime = 0;
	hnand1->Init.TARSetupTime = 0;
	/* hnand1.Config */
	hnand1->Config.PageSize = 2048;
	hnand1->Config.SpareAreaSize = 64;
	hnand1->Config.BlockSize = 128;
	hnand1->Config.BlockNbr = 16;
	hnand1->Config.PlaneNbr = 2;
	hnand1->Config.PlaneSize = 1024;
	hnand1->Config.ExtraCommandEnable = DISABLE;
	/* ComSpaceTiming */
	ComSpaceTiming.SetupTime = 0;
	ComSpaceTiming.WaitSetupTime = 1;
	ComSpaceTiming.HoldSetupTime = 0;
	ComSpaceTiming.HiZSetupTime = 4;
	/* AttSpaceTiming */
	AttSpaceTiming.SetupTime = 0;
	AttSpaceTiming.WaitSetupTime = 1;
	AttSpaceTiming.HoldSetupTime = 0;
	AttSpaceTiming.HiZSetupTime = 4;
 
	if (HAL_NAND_Init(hnand1, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
	{
		printf("Could not initialize flash static memory controller\n");
	}

Code for reading ID and data:

static uint8_t TxBuffer [2048];
static uint8_t RxBuffer [2048];
NAND_HandleTypeDef hnand1;
NAND_IDTypeDef NAND_ReadID_handle = { 0 };
 
	HAL_NAND_Reset(&hnand1);
    HAL_Delay(100);
 
    /* Read the NAND memory ID */
	HAL_NAND_Read_ID(&hnand1,&NAND_ReadID_handle);
    HAL_Delay(100);
 
    /* Fill the buffer to send */
    for (int i = 0; i < 2048; i++ )
    {
        RxBuffer[i] = 0;
    }
 
    /* Fill the buffer to send */
    for (int i = 0; i < 2048; i++ )
    {
        TxBuffer[i] = i;
    }
 
    /* NAND memory address to write to */
    WriteReadAddr.Plane = 0;
    WriteReadAddr.Block = 2;
    WriteReadAddr.Page = 0;
 
    /* Erase the NAND first Block */
    if( HAL_NAND_Erase_Block(&hnand1, &WriteReadAddr) != HAL_OK)
    {
 
        while(1);
    }
    HAL_Delay(100);
 
 
    /* Write data to FMC NAND memory */
    if(HAL_NAND_Write_Page(&hnand1, &WriteReadAddr, TxBuffer, 1) != HAL_OK)
    {
        while(1);
    }
    HAL_Delay(100);
 
    /* Read data from FMC NAND memory */
    if(HAL_NAND_Read_Page(&hnand1, &WriteReadAddr, RxBuffer, 1) != HAL_OK)
    {
        while(1);
    }
 
    /* check data */
    if(memcmp(TxBuffer,RxBuffer,sizeof(TxBuffer)) == 0 )
        printf("\r\n\r\n NandFlash Read Write Test OK\r\n");
    else
    {
        printf("\r\n\r\n NandFlash Read Write Failed \r\n");
        while(1);
    }

Best regards,

ML.

0 REPLIES 0