2020-02-20 06:48 AM
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