cancel
Showing results for 
Search instead for 
Did you mean: 

OCTOSPI memory mapped read failed in SPI MRAM

anercellas
Associate

Hi!

I have a serious problem trying to read in memory-mapped mode a SPI MRAM (MR20H40 from Everspin). I have configured my STM32L4R and I can WRITE in memory-mapped mode without problem, but while reading, I loose control of the MCU and I need to reset it. I have checked what was written in memory-mapped mode by using regular commands for reading, which works. So it seems physically is everything correct since I can communicate with the MRAM with regular commands: WRITE & READ.

To start with, I would like to anticipate that I can configure WRITE in memory-mapped only, and do the WRITE. But I cannot configure READ in memory mapped only, without sending also the command for WRITE configuration. When doing so, the HAL_OSPI_MemoryMapped failed because hospi->state is not HAL_OSPI_STATE_CMD_CFG, but HAL_OSPI_STATE_READ_CMD_CFG...weird:\ Something similar happend to @Leo_Panda​ 

Having said that I post here my code for memory-mapped configuration. I used as reference the AN5050 App Note for OcotSPI on STM32L4+ Series.

First of all, my HAL_OSPI_Init, generated through CubeMX and interrupts enabled.

static void MX_OCTOSPI2_Init(void)
{
  OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0};
  OSPI_AutoPollingTypeDef cfg = {0};
 
  /* OCTOSPI2 parameter configuration*/
  hospi2.Instance = OCTOSPI2;
  hospi2.Init.FifoThreshold = 1;
  hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
  hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_MACRONIX_RAM;
  hospi2.Init.DeviceSize = 19; //524288 bytes
  hospi2.Init.ChipSelectHighTime = 1;
  hospi2.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
  hospi2.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
  hospi2.Init.WrapSize = HAL_OSPI_WRAP_NOT_SUPPORTED;
  hospi2.Init.ClockPrescaler = 6; //SYSCLK = 120 MHz --> 20 MHz
  hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
  hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
  hospi2.Init.ChipSelectBoundary = 1;
  if (HAL_OSPI_Init(&hospi2) != HAL_OK)
  {
    Error_Handler();
  }
  OSPIM_Cfg_Struct.ClkPort = 2;
  OSPIM_Cfg_Struct.NCSPort = 2;
  OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
  if (HAL_OSPIM_Config(&hospi2, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    Error_Handler();
  }
}

Now I define my function

       MRAM_WriteEnable(hospi2);
 
	sCommand.OperationType      = HAL_OSPI_OPTYPE_READ_CFG;
	sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
	sCommand.Instruction        = READ_DATA_CMD;
	sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;
	sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.Address       		= 0;
	sCommand.AddressMode        = HAL_OSPI_ADDRESS_1_LINE;
	sCommand.AddressSize	  	= HAL_OSPI_ADDRESS_24_BITS;
	sCommand.AddressDtrMode 	= HAL_OSPI_ADDRESS_DTR_DISABLE;
	sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode           = HAL_OSPI_DATA_1_LINE;
	sCommand.DataDtrMode		= HAL_OSPI_DATA_DTR_DISABLE;
	sCommand.DummyCycles        = 0;
	sCommand.DQSMode            = HAL_OSPI_DQS_DISABLE;
	sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
	if (HAL_OSPI_Command(hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		Error_Handler();
	}
 
	sCommand.OperationType      = HAL_OSPI_OPTYPE_WRITE_CFG;
	sCommand.Instruction        = WRITE_DATA_CMD;
	sCommand.DummyCycles		= 0;
 
	if (HAL_OSPI_Command(hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
		Error_Handler();
	}
 
	sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
	if (HAL_OSPI_MemoryMapped(hospi2, &sMemMappedCfg) != HAL_OK)
	{
		Error_Handler();
	}
 
	/* Writing Sequence ----------------------------------------------- */
	HAL_Delay(1000);
	HAL_UART_Transmit(huart2, "Memory mapped ready\n\r", sizeof("Memory mapped ready\n\r"), 1000);
 
	for(index = 0; index < sizeof(aTxBuffer); index++)
	{
		*mem_addr = aTxBuffer[index];
		mem_addr++;
	}
	HAL_UART_Transmit(huart2, "Memory mapped write complete\n\r", sizeof("Memory mapped write completed\n\r"), 1000);
 
	/* Reading Sequence ----------------------------------------------- */
	uint8_t rxBuff[10];
	for (index = 0; index < 5; index++)
	{
		rxBuff[index] = *mem_addr;
		mem_addr++;
	}
	HAL_UART_Transmit(huart2, "Memory mapped read complete\n\r", sizeof("Memory mapped read completed\n\r"), 1000);

Note: If I configure here the firs command as READ and do not perform the second command (WRITE), the HAL_OSPI_MemoryMapped fails as I said at the beginning.

My MRAM_WriteEnable function:

static void MRAM_WriteEnable(OSPI_HandleTypeDef *hospi)
{
	OSPI_RegularCmdTypeDef  sCommand;
	uint8_t status_reg = 0;
 
	/* Enable write operations ---------------------------------------- */
	sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
	sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;
	sCommand.Instruction        = WRITE_ENABLE_CMD;
	sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;
	sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
	sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
	sCommand.AddressMode        = HAL_OSPI_ADDRESS_NONE;
	sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
	sCommand.DataMode           = HAL_OSPI_DATA_NONE;
	sCommand.DataDtrMode		= HAL_OSPI_DATA_DTR_DISABLE;
	sCommand.DummyCycles        = 0;
	sCommand.DQSMode            = HAL_OSPI_DQS_DISABLE;
	sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
	if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
	  Error_Handler();
	}
 
	 sCommand.Instruction = READ_STATUS_REG_CMD;
	 sCommand.DataMode    = HAL_OSPI_DATA_1_LINE;
	 sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
	 sCommand.NbData      = 1;
 
	 if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	 {
	   Error_Handler();
	 }
 
	 if (HAL_OSPI_Receive(hospi, &status_reg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	 {
		 Error_Handler();
	 }
//Yes I should be doing polling here, but the the status_reg always return 0x02, meaning the WEL bit is ON.
}

I never get the message of "Memory mapped read completed" and MCU get stuck I don't know where. I would appreciate any help in here.

Thanks

0 REPLIES 0