OCTOSPI interface for communication with a FPGA
Hi All
I have created a PCB where I want to use the OCTOSPI to communicate with a FPGA.
I have difficulty finding accurate information on how the different memory types work. I already have a Hyperram running so I started there, that did also seem straight forward.
I do currently only have FPGA code listening and is focusing on getting write to work.
I slowed down the clk quite a bit to only fucus on functionality. Pre scale of 30 ~9.6Mhz
I would much like to have the FPGA memory mapped, so that's what I'm testing.
When I write to address 0x91234568 (0x90000000) is octospi1 base
with the data of 0x87654321 then i get following sequence in hex:
20 12 34 56 00 04 43 21 87 65
The Data is easy, that's just different order 43 21 87 65 instead of 87 65 43 21
The 20 seems to be CMD
The Address (in correct order) 12 34 56 (but then always 00 00 or 00 04) as the last, I seem to lack the last nibble of the Address. The RWDS Seems a bit early.

if I Change to 0x91234560 then the same 20 12 34 56 00 00 43 21 87 65, just with out the 04

If I write at 0x91234564 I get 4 extra bytes before RWDS.
20 12 34 56 00 00 00 00 00 00 43 21 87 65, But now the RWDS is accurate

If I write at 0x9123456C I also get the 4 extra bytes before RWDS, now with 04.
20 12 34 56 00 04 00 00 00 00 43 21 87 65, and the RWDS is accurate
If I write at 0x91234566 I also get the 6 extra bytes before RWDS, now with 00.
if I write on uneven addresses then bytes a masked with RWDS.
There seems to be a quite clear pattern, that I first discovered while writing this message, but again, it is a bit difficult.
- Where can I fin accurate information on how this works?
- Are there a better memory type to chose instead of HYPERBUS.
- e.g. APMEMORY That I not yest has got to work in memory mapped mode
My config currently looks like this:
static 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};
/* USER CODE BEGIN OCTOSPI1_Init 1 */
/* USER CODE END OCTOSPI1_Init 1 */
/* OCTOSPI1 parameter configuration*/
hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 4;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_HYPERBUS;
hospi1.Init.DeviceSize = 28;
hospi1.Init.ChipSelectHighTime = 8;
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 = 30;
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
hospi1.Init.ChipSelectBoundary = 23;
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_FIXED_LATENCY;
if (HAL_OSPI_HyperbusCfg(&hospi1, &sHyperBusCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI1_Init 2 */
OSPI_HyperbusCmdTypeDef sCommand;
OSPI_MemoryMappedTypeDef sMemMappedCfg;
/* Memory-mapped mode configuration --------------------------------------- */
sCommand.AddressSpace = HAL_OSPI_MEMORY_ADDRESS_SPACE;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
sCommand.DQSMode = HAL_OSPI_DQS_ENABLE; //Test
sCommand.Address = 0;
sCommand.NbData = 1;
if (HAL_OSPI_HyperbusCmd(&hospi1, &sCommand, 0) != HAL_OK)
{
Error_Handler();
}
sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
if (HAL_OSPI_MemoryMapped(&hospi1, &sMemMappedCfg) != HAL_OK)
{
Error_Handler();
}
//Enable FREERUNCLK
//SET_BIT(hospi1.Instance->DCR1, OCTOSPI_DCR1_FRCK);
/* USER CODE END OCTOSPI1_Init 2 */
}
Thanks in advance
Kristian Vang
