cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to erase external NOR flash memory while read, write works.

Klassic
Associate III

I am using STM32L496ZG to interface ISSI IS29GL064-70TLET nor flash by using HAL library. I used CUBE MX to generate the code and running code on Keil compiler. I am able to detect device ID, write and read block. But unable to erase data. I have used example code provided in application note AN4761.

Erase code snippet is below:

WRITE_READ_ADDR 0x8000

NOR_BANK_ADDR 0x64000000

HAL_NOR_ReturnToReadMode(&hnor1);

/* Erase the NOR memory block to write on */

HAL_NOR_Erase_Block(&hnor1, WRITE_READ_ADDR, NOR_BANK_ADDR);

/* Return the NOR memory status */

if(HAL_NOR_GetStatus(&hnor1, NOR_BANK_ADDR, NOR_TIMEOUT_VALUE) !=

HAL_NOR_STATUS_SUCCESS)

{

/* Erase Error */

HAL_UART_Transmit(&huart2, (uint8_t *) "Erase error" , 12, 100);

  return NOR_STATUS_ERASE_ERROR;

}

The status returns erase success. But the bits are still the same, they don't turn to ones at all.

Can any one please help me out on this?

1 ACCEPTED SOLUTION

Accepted Solutions
KMINH.1
Associate III

Thanks everyone for your answers.
The erase operation worked when I shortened the long wires I was using between stm board and flash IC. Perhaps the signal transmission was failing or weak signals.

Anyways, am grateful for the support I got from u all.

View solution in original post

29 REPLIES 29
LLily.2
Associate II

I'm not sure if my answer is correct.
You said unable to erase data, maybe you should first erase data -> write data -> read data

More likely the wrong command, block boundary or protected block. Not sure you're going to be able to diagnose at the top-level .

Pull a data-sheet for the part and review the commands, status in context.

Not many will have this board or part combo.

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

I am doing this way Detect -> Erase -> Write -> Read. I am able to write to any location only once. After which, I cannot write different data. After I send erase command, the read cmd does not return FFs but the data that was written first time.
   I am also able to detect device ID correctly.
Thanks for replying. 

RhSilicon
Lead

In both Flash technologies, data can be written to a block only if the block is empty. The already slow erase operation of NOR Flash makes the write operation even slower. In NAND Flash, similar to read, data is often written or programmed in pages (typically 2KB). For example, a page write alone with S34ML04G2 NAND Flash takes 300µS.

https://www.embedded.com/flash-101-nand-flash-vs-nor-flash/

Thanks Tesla for responding. I am still unable to resolve it. I will try my best to follow suggested comments.
I have used sector addresses as 8000h, 18000h, 10000h to erase and write/read operations.
Below is the code I am using;

HAL_StatusTypeDef HAL_NOR_Erase_Block(NOR_HandleTypeDef *hnor, uint32_t BlockAddress, uint32_t Address)
{
  uint32_t deviceaddress;
  HAL_StatusTypeDef status = HAL_OK;

  /* Check the NOR controller state */
  if (hnor->State == HAL_NOR_STATE_BUSY)
  {
    return HAL_BUSY;
  }
  else if (hnor->State == HAL_NOR_STATE_READY)
  {
    /* Process Locked */
    __HAL_LOCK(hnor);
    /* Update the NOR controller state */
    hnor->State = HAL_NOR_STATE_BUSY;
    /* Select the NOR device address */
    if (hnor->Init.NSBank == FMC_NORSRAM_BANK1)
    {
      deviceaddress = NOR_MEMORY_ADRESS1;
    }
    else if (hnor->Init.NSBank == FMC_NORSRAM_BANK2)
    {
			HAL_UART_Transmit(&huart2, (uint8_t *) "\r\nNOR_MEMORY_ADRESS2 in Erase Block" , 34, 100);
      deviceaddress = NOR_MEMORY_ADRESS2;
    }
    else if (hnor->Init.NSBank == FMC_NORSRAM_BANK3)
    {
      deviceaddress = NOR_MEMORY_ADRESS3;
    }
    else /* FMC_NORSRAM_BANK4 */
    {
      deviceaddress = NOR_MEMORY_ADRESS4;
    }
    /* Send block erase command sequence */
   // if (hnor->CommandSet == NOR_AMD_FUJITSU_COMMAND_SET)
   if(1)
    {
    HAL_UART_Transmit(&huart2, (uint8_t *) "\r\nNOR_AMD_FUJITSU_COMMAND_SET in Erase Block" , 44, 100);
      NOR_WRITE(NOR_ADDR_SHIFT(((uint32_t)deviceaddress), uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIRST), NOR_CMD_DATA_FIRST);
      NOR_WRITE(NOR_ADDR_SHIFT(((uint32_t)deviceaddress), uwNORMemoryDataWidth, NOR_CMD_ADDRESS_SECOND), NOR_CMD_DATA_SECOND);
      NOR_WRITE(NOR_ADDR_SHIFT(((uint32_t)deviceaddress), uwNORMemoryDataWidth, NOR_CMD_ADDRESS_THIRD),
                NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD);
      NOR_WRITE(NOR_ADDR_SHIFT(((uint32_t)deviceaddress), uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FOURTH),
                NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH);
      NOR_WRITE(NOR_ADDR_SHIFT(((uint32_t)deviceaddress), uwNORMemoryDataWidth, NOR_CMD_ADDRESS_FIFTH),
                NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH);
      NOR_WRITE((uint32_t)(BlockAddress + (deviceaddress)), NOR_CMD_DATA_BLOCK_ERASE);
    }
    else if (hnor->CommandSet == NOR_INTEL_SHARP_EXT_COMMAND_SET)
    {
      NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_UNLOCK);
      NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
      NOR_WRITE((BlockAddress + Address), NOR_CMD_BLOCK_ERASE);
      NOR_WRITE((BlockAddress + Address), NOR_CMD_CONFIRM);
    }
    else
    {
      /* Primary command set not supported by the driver */
      HAL_UART_Transmit(&huart2, (uint8_t *) "HAL_ERROR in Erase Block" , 24, 100);
      status = HAL_ERROR;
    }
    /* Check the NOR memory status and update the controller state */
    hnor->State = HAL_NOR_STATE_READY;
    /* Process unlocked */
    __HAL_UNLOCK(hnor);
  }
  else
  {
    return HAL_ERROR;
  }
  return status;
}

  I made sure that correct NOR bank address is selected while erasing. 

#define NOR_CMD_ADDRESS_FIRST                 (uint16_t)0x0555
#define NOR_CMD_ADDRESS_FIRST_CFI             (uint16_t)0x0055
#define NOR_CMD_ADDRESS_SECOND                (uint16_t)0x02AA
#define NOR_CMD_ADDRESS_THIRD                 (uint16_t)0x0555
#define NOR_CMD_ADDRESS_FOURTH                (uint16_t)0x0555
#define NOR_CMD_ADDRESS_FIFTH                 (uint16_t)0x02AA
#define NOR_CMD_ADDRESS_SIXTH                 (uint16_t)0x0555

/* Constants to define data to program a command */
#define NOR_CMD_DATA_READ_RESET               (uint16_t)0x00F0
#define NOR_CMD_DATA_FIRST                    (uint16_t)0x00AA
#define NOR_CMD_DATA_SECOND                   (uint16_t)0x0055
#define NOR_CMD_DATA_AUTO_SELECT              (uint16_t)0x0090
#define NOR_CMD_DATA_PROGRAM                  (uint16_t)0x00A0
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_THIRD   (uint16_t)0x0080
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FOURTH  (uint16_t)0x00AA
#define NOR_CMD_DATA_CHIP_BLOCK_ERASE_FIFTH   (uint16_t)0x0055

  Also, the commands used match with that of datasheet. I have attached the datasheet.
Thanks

 

If you think that is correct, then you're going to need to look more critically at the hardware side. The pin connectivity, and the FMC peripheral and pin associativity. Perhaps start by going over you schematic and PCB very carefully. And then checking all the initialization code, and registers set into RCC, GPIO and FMC. Perhaps wire up a logic analyzer so you can verify the signal level expectations.

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

I have verified control signals chip select with oscilloscope. Its triggering on time. 
Moreover, detect command returns correct device IDs. Write cmd writes data and reads back correct data (but only first time). So the hardware connections seems to be ok. 

Pavel A.
Evangelist III

Looks like you are using outdated NOR driver. Look at the latest one, the erase code has been changed. 

https://github.com/STMicroelectronics/stm32l4xx_hal_driver/blob/17273a9afa668b1ebd899f611dbfb0460b70ba27/Src/stm32l4xx_hal_nor.c#L1097

/* even then, can't attest that their driver works. I wrote my own, for a different ISSI NOR model */

 

Ok, so perhaps indicative of an issue with the Erase, or waiting for completion of Write / Erase operations.

The part comes in a couple of variants, some with 64KB Erase blocks, other with mostly those, but with a group of 8 8KB blocks at the top / bottom (front, back) of the array. These will need special treatment if present.

Check what changed in the libraries Pavel mentioned. That the JEDEC ID reads properly is very promising, but you might have to write your own code, and trace / analyze the library code vs documentation, to understand specifically where the second go around founders.

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