cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with interfacing with S26KL128S flash chip

G_Anastasopoulos
Associate II

Dear All,

I have a board that uses the STM32U599NJH6Q as MCU and the S26KL128S is attached to the OCTOSPI1 peripheral of the said MCU.

I need to be able to erase a sector and/or a page, write data to the device and then be able to read them back.

What I am unsure of at the moment is the initialization code. Specifically, I am not sure if I need to use Octo SPI mode or Hyperbus.

Currently I am going with Octo SPI and my MX_OCTOSPI1_Init looks like this:

void MX_OCTOSPI1_Init(void)
{

  /* USER CODE BEGIN OCTOSPI1_Init 0 */

  /* USER CODE END OCTOSPI1_Init 0 */

  OSPIM_CfgTypeDef sOspiManagerCfg = {0};
  HAL_OSPI_DLYB_CfgTypeDef HAL_OSPI_DLYB_Cfg_Struct = {0};

  /* USER CODE BEGIN OCTOSPI1_Init 1 */

  /* USER CODE END OCTOSPI1_Init 1 */
  hospi1.Instance = OCTOSPI1;
  hospi1.Init.FifoThreshold = 4;
  hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
  hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX;
  hospi1.Init.DeviceSize = 26;
  hospi1.Init.ChipSelectHighTime = 2;
  hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
  hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
  hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
  hospi1.Init.ClockPrescaler = 4;
  hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
  hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
  hospi1.Init.ChipSelectBoundary = 0;
  hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
  hospi1.Init.MaxTran = 0;
  hospi1.Init.Refresh = 0;
  if (HAL_OSPI_Init(&hospi1) != HAL_OK)
  {
    Error_Handler();
  }
  sOspiManagerCfg.ClkPort = 1;
  sOspiManagerCfg.DQSPort = 1;
  sOspiManagerCfg.NCSPort = 1;
  sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
  sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
  if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_OSPI_DLYB_Cfg_Struct.Units = 0;
  HAL_OSPI_DLYB_Cfg_Struct.PhaseSel = 0;
  if (HAL_OSPI_DLYB_SetConfig(&hospi1, &HAL_OSPI_DLYB_Cfg_Struct) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN OCTOSPI1_Init 2 */

  /* USER CODE END OCTOSPI1_Init 2 */

}

 In my main I am doing the following:

uint8_t ofTxBuffer[] = " **OCTOSPI Flash sample**\r\n";
int main(void)
{
  HAL_Init();
....
  MX_OCTOSPI1_Init();
...
// Configure the memory-mapped mode for S26KL128S
	      OSPI_MemoryMappedTypeDef mMemMappedCfg = {0};

	      // Set command to enter memory-mapped mode
	      OSPI_RegularCmdTypeDef mCommand = {0};
	      mCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
	      mCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
	      mCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;
	      mCommand.Instruction        = 0x00; // Enter the appropriate instruction here
	      mCommand.AddressMode        = HAL_OSPI_ADDRESS_1_LINE;
	      mCommand.AddressSize        = HAL_OSPI_ADDRESS_24_BITS;
	      mCommand.Address            = 0x000000; // Start address of the flash memory
	      mCommand.DataMode           = HAL_OSPI_DATA_1_LINE;
	      mCommand.NbData             = 1;
	      mCommand.DummyCycles        = 0;
	      mCommand.DQSMode            = HAL_OSPI_DQS_DISABLE;
	      mCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;

	      if (HAL_OSPI_Command(&hospi1, &mCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK) {
	          // Initialization Error
	          Error_Handler();
	      }

	      // Configure memory-mapped mode
	      mMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;

	      if (HAL_OSPI_MemoryMapped(&hospi1, &mMemMappedCfg) != HAL_OK) {
	          // Initialization Error
	          Error_Handler();
	      }
	  __IO uint8_t *mem_addr;
	  mem_addr = (__IO uint8_t *)(OCTOSPI1_BASE);
	  memcpy(mem_addr, &ofTxBuffer, sizeof(ofTxBuffer));
	  uint8_t octoFLASHData[128] = {0};
	  mem_addr = (__IO uint8_t *)(OCTOSPI1_BASE);
	  memcpy(&octoFLASHData, mem_addr, sizeof(ofTxBuffer));


	printk("String in octo flash: %s\r\n", octoFLASHData);
  while(1){}
}

Once the code hits the memcpy point I am getting a hardfault.
Furthermore it is unclear to me how to proceed with actually erasing the flash.

 

Any help would be great.

2 REPLIES 2
KDJEM.1
ST Employee

Hello @G_Anastasopoulos ,

 

The HyperBus protocol must be used when an external HyperRAM or HyperFlash memory is connected to the STM32. For that, I recommend you to take a look at Table 7. STM32CubeMX - Configuration of OCTOSPI signals and mode IV. HyperFlash and HyperRAM memories with Multiplexed mode example and at in AN5050 and get inspired to configure the memory.

Also, I think STM32CubeU5/Projects/STM32U575I-EV/Examples/OCTOSPI/OSPI_HyperRAM_MemoryMapped at main · STMicroelectronics/STM32CubeU5 · GitHub may help you.

Thank you.

Kaouthar

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.

I have reviewed this example. I am not sure how to bend it to make it work with my chip, as this is meant for a HyperRAM.

I have reviewed several different tickets in the forum as well, including this:

https://community.st.com/t5/stm32-mcus-products/looking-for-sample-code-for-hyperflash-erase-programming-with/td-p/126856 which appears to be the closest to my situation, but I have not managed to make it work yet.

I am not sure what is the exact problem, but based on the code that was provided on your response, I am doing these steps:
Init:

void MX_OCTOSPI1_Init(void)
{

  /* USER CODE BEGIN OCTOSPI1_Init 0 */

  /* USER CODE END OCTOSPI1_Init 0 */

  OSPIM_CfgTypeDef sOspiManagerCfg = {0};
  OSPI_HyperbusCfgTypeDef sHyperBusCfg = {0};
  HAL_OSPI_DLYB_CfgTypeDef HAL_OSPI_DLYB_Cfg_Struct = {0};

  /* USER CODE BEGIN OCTOSPI1_Init 1 */

  /* USER CODE END OCTOSPI1_Init 1 */
  hospi1.Instance = OCTOSPI1;
  hospi1.Init.FifoThreshold = 4;
  hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
  hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
  hospi1.Init.DeviceSize = 26;
  hospi1.Init.ChipSelectHighTime = 2;
  hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
  hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
  hospi1.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
  hospi1.Init.ClockPrescaler = 4;
  hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
  hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
  hospi1.Init.ChipSelectBoundary = 0;
  hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;
  hospi1.Init.MaxTran = 0;
  hospi1.Init.Refresh = 0;
  if (HAL_OSPI_Init(&hospi1) != HAL_OK)
  {
    Error_Handler();
  }
  sOspiManagerCfg.ClkPort = 1;
  sOspiManagerCfg.DQSPort = 1;
  sOspiManagerCfg.NCSPort = 1;
  sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
  sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
  if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  sHyperBusCfg.RWRecoveryTime = 0;
  sHyperBusCfg.AccessTime = 0;
  sHyperBusCfg.WriteZeroLatency = HAL_OSPI_NO_LATENCY_ON_WRITE;
  sHyperBusCfg.LatencyMode = HAL_OSPI_VARIABLE_LATENCY;
  if (HAL_OSPI_HyperbusCfg(&hospi1, &sHyperBusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_OSPI_DLYB_Cfg_Struct.Units = 0;
  HAL_OSPI_DLYB_Cfg_Struct.PhaseSel = 0;
  if (HAL_OSPI_DLYB_SetConfig(&hospi1, &HAL_OSPI_DLYB_Cfg_Struct) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN OCTOSPI1_Init 2 */

  /* USER CODE END OCTOSPI1_Init 2 */

}


Inside the main:

int main(void)
{
...
  MX_OCTOSPI1_Init();
...
  OSPI_HyperbusCmdTypeDef mCommand = {0};
  OSPI_MemoryMappedTypeDef mMemMappedCfg = {0};
  mCommand.AddressSpace = HAL_OSPI_MEMORY_ADDRESS_SPACE;
  mCommand.AddressSize  = HAL_OSPI_ADDRESS_32_BITS;
  mCommand.DQSMode      = HAL_OSPI_DQS_ENABLE;
  mCommand.Address      = 0;
  mCommand.NbData       = 1;

  if (HAL_OSPI_HyperbusCmd(&hospi1, &mCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
  mMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;
  mMemMappedCfg.TimeOutPeriod     = 0x20;
  if (HAL_OSPI_MemoryMapped(&hospi1, &mMemMappedCfg) != HAL_OK)
  {
    Error_Handler();
  }
  __IO uint8_t *mem_addr;
  mem_addr = (__IO uint8_t *)(OCTOSPI1_BASE);
  memcpy(mem_addr, &ofTxBuffer, sizeof(ofTxBuffer));
  uint8_t octoFLASHData[128] = {0};
  memcpy(&octoFLASHData, mem_addr, sizeof(ofTxBuffer));
  printk("String in octo flash: %s\r\n", octoFLASHData);memcpy(mem_addr, &ofTxBuffer, sizeof(ofTxBuffer));
}

When it gets to the point where to write to the flash it hard-faults.

Any ideas?