STM32H730 with OctalSPI ISSI IS66WVO8M8 PSRAM
Hello community,
I'm looking for some direction on how to setup the OSPI bus to communitcate with an external PSRAM part from ISSI - IS66WVO8M8 (datasheet attached). I've read through application notes and a handful of example projects but am having a hard time getting the logic to sync.
A few things I've done:
- The STM32H7 OSPI bus is set to run at 133MHz with no prescalar (133 because of another OSPI peripheral connected to OSPI1 not shown here)
- The read operation (page 9) and write operation (page 13) show a data ordering D1/D0, so Makronix was selected. Have tried both Makronix and Makronix RAM as the type
- Page 19 shows the register read operation waveform - DQS should be enabled
- Page 8 shows the register command and address values, lengths, etc.
If you look in the MX_OCTOSPI2_Init function, I am trying to read from the ID register to confirm the correct part, run a quick and dirty write/read check, and then use the part as a GUI framebuffer.
static void MX_OCTOSPI2_Init(void)
{
/* USER CODE BEGIN OCTOSPI2_Init 0 */
/* USER CODE END OCTOSPI2_Init 0 */
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
/* USER CODE BEGIN OCTOSPI2_Init 1 */
/* USER CODE END OCTOSPI2_Init 1 */
/* OCTOSPI2 parameter configuration*/
hospi2.Instance = OCTOSPI2;
hospi2.Init.FifoThreshold = 1;
hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_APMEMORY;
hospi2.Init.DeviceSize = 26;
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_32_BYTES;
hospi2.Init.ClockPrescaler = 1;
hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
hospi2.Init.ChipSelectBoundary = 0;
hospi2.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED;
hospi2.Init.MaxTran = 0;
hospi2.Init.Refresh = 0;
if (HAL_OSPI_Init(&hospi2) != HAL_OK)
{
Error_Handler();
}
sOspiManagerCfg.ClkPort = 2;
sOspiManagerCfg.DQSPort = 2;
sOspiManagerCfg.NCSPort = 2;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_2_HIGH;
if (HAL_OSPIM_Config(&hospi2, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI2_Init 2 */
OSPI_RegularCmdTypeDef command = { 0 };
// Read the ID register
command.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
command.FlashId = HAL_OSPI_FLASH_ID_1;
command.Instruction = 0xC000;
command.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
command.InstructionSize = HAL_OSPI_INSTRUCTION_16_BITS;
command.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_ENABLE;
command.Address = 0;
command.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
command.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
command.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
command.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
command.DummyCycles = 2;
command.DataMode = HAL_OSPI_DATA_8_LINES;
command.NbData = 4;
command.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
command.DQSMode = HAL_OSPI_DQS_ENABLE;
if (HAL_OSPI_Command(&hospi2, &command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
//
uint32_t id = 0;
if (HAL_OSPI_Receive(&hospi2, (uint8_t*) &id, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (id == 0)
{
Error_Handler();
}
// Read the config register
command.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
command.Instruction = 0xC000;
command.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;
command.InstructionSize = HAL_OSPI_INSTRUCTION_16_BITS;
command.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_ENABLE;
command.Address = 0x00040000;
command.AddressMode = HAL_OSPI_ADDRESS_8_LINES;
command.AddressSize = HAL_OSPI_ADDRESS_32_BITS;
command.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_ENABLE;
command.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
command.DataMode = HAL_OSPI_DATA_8_LINES;
command.NbData = 4;
command.DataDtrMode = HAL_OSPI_DATA_DTR_ENABLE;
command.DummyCycles = 2;
command.DQSMode = HAL_OSPI_DQS_ENABLE;
if (HAL_OSPI_Command(&hospi2, &command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
uint32_t config = 0;
if (HAL_OSPI_Receive(&hospi2, (uint8_t*) &config, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
if (id == 0)
{
Error_Handler();
}
OSPI_MemoryMappedTypeDef config = {
.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE,
.TimeOutPeriod = 0,
};
if (HAL_OSPI_MemoryMapped(&hospi2, &config) != HAL_OK)
{
Error_Handler();
}
uint8_t* src;
uint32_t errorCount = 0;
// write test
src=(uint8_t*) OCTOSPI2_BASE;
for (uint32_t i = 0; i < 0x0FFFFFFF; i++)
*src++ = i & 0xFF;
// Read test
src=(uint8_t*) OCTOSPI2_BASE;
for (uint32_t i = 0; i < 0x0FFFFFFF; i++)
if (*src++ != (i & 0xFF))
errorCount++;
if (errorCount != 0)
while(1);
/* USER CODE END OCTOSPI2_Init 2 */
}As it is now the read operation will stall if the DQSM is enabled. If I disable DQSM then the read returns `0x88888888` instead of an expected value.
Any feedback and help on this is appreciated. Thanks in advance!
- Taylor
