2022-05-17 03:43 AM
Hello, I have a very basic setup of OSPI1 on STM32H730VBT and I am trying to read the 1st Status Register of the Winbond W25Q128JV.
Environment
Hardware
A custom board with STM32H730VBT and Winbond W25Q128JV connected via OSPI1.
Code
Generated OSPI init code
void MX_OCTOSPI1_Init(void)
{
/* USER CODE BEGIN OCTOSPI1_Init 0 */
/* USER CODE END OCTOSPI1_Init 0 */
OSPIM_CfgTypeDef sOspiManagerCfg = {0};
/* USER CODE BEGIN OCTOSPI1_Init 1 */
/* USER CODE END OCTOSPI1_Init 1 */
hospi1.Instance = OCTOSPI1;
hospi1.Init.FifoThreshold = 1;
hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;
hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;
hospi1.Init.DeviceSize = 24;
hospi1.Init.ChipSelectHighTime = 1;
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 = 1; /* HCLK3 is already 65MHz */
hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
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.NCSPort = 1;
sOspiManagerCfg.DQSPort = 0;
sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_NONE;
sOspiManagerCfg.Req2AckTime = 1; /* required when full assert is enabled... */
if (HAL_OSPIM_Config(&hospi1, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN OCTOSPI1_Init 2 */
/* USER CODE END OCTOSPI1_Init 2 */
}
void HAL_OSPI_MspInit(OSPI_HandleTypeDef* ospiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(ospiHandle->Instance==OCTOSPI1)
{
/* USER CODE BEGIN OCTOSPI1_MspInit 0 */
/* USER CODE END OCTOSPI1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInitStruct.OspiClockSelection = RCC_OSPICLKSOURCE_D1HCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/* OCTOSPI1 clock enable */
__HAL_RCC_OCTOSPIM_CLK_ENABLE();
__HAL_RCC_OSPI1_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**OCTOSPI1 GPIO Configuration
PE2 ------> OCTOSPIM_P1_IO2
PB2 ------> OCTOSPIM_P1_CLK
PD11 ------> OCTOSPIM_P1_IO0
PD13 ------> OCTOSPIM_P1_IO3
PC10 ------> OCTOSPIM_P1_IO1
PB6 ------> OCTOSPIM_P1_NCS
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN OCTOSPI1_MspInit 1 */
/* USER CODE END OCTOSPI1_MspInit 1 */
}
}
PS: `sOspiManagerCfg` init is slightly modified to not produce an error when full assert is enabled but `Req2AckTime` is not set by the STM32CubeMX.
Status Register 1 (SR1) read code
uint8_t reg = 0U;
OSPI_RegularCmdTypeDef cmd = {
.Instruction = 0x05,
.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE,
.DataMode = HAL_OSPI_DATA_1_LINE,
.AddressMode = HAL_OSPI_ADDRESS_NONE,
.NbData = 1U,
.DummyCycles = 0U
};
hal_ret = HAL_OSPI_Command(&hospi1, &cmd, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
if (hal_ret != HAL_OK) {
return hal_ret;
}
hal_ret = HAL_OSPI_Receive(&hospi1, ®, HAL_OSPI_TIMEOUT_DEFAULT_VALUE);
if (hal_ret != HAL_OK) {
return hal_ret;
}
return HAL_OK;
Current
Expected
Everything works perfectly when using QSPI on STM32H750 (same board, same clock configuration output [doesn't exceed < Max 133MHz for O/QSPI]). However, when Octo-SPI (OSPI) is used, then nothing is being read. It looks like the CLK signal is not present.
Any ideas what can be tried out?
Solved! Go to Solution.
2022-05-18 12:38 AM
@Andreas Bolsch, @Community member, thank you for the assistance. The issue turned out to be the clock.
2022-05-17 06:16 AM
Do you have a UART available for debug on this board? Which ports/pins?
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_NONE; // ??
Try
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
hospi1.Init.ChipSelectHighTime = 2;
hospi1.Init.ClockPrescaler = 4; // Perhaps shoot for 50-100 MHz
Had Winbond/Macronix parts working on NUCLEO-H723ZG here
2022-05-17 06:58 AM
@Community member ,
sOspiManagerCfg.IOHighPort = HAL_OSPIM_IOPORT_1_HIGH;
why?
Mentioned Winbond NOR-Flash is a Quad Mode (max) flash and OSPI has to be used in Quad Mode (Data[3:0]) - therefore, STM32CubeMX won't even generate `IOHighPort` setting, as it is equal to `0` anyway.
The
HAL_OSPIM_IOPORT_NONE
was added to be explicit here.
hospi1.Init.ClockPrescaler = 4;
The HCLK3 used as OSPI clock source is already 65MHz which is already within propose frequency range.
hospi1.Init.ChipSelectHighTime = 2;
Shouldn't play a big role here. Tried, no difference.
2022-05-17 07:07 AM
@Community member,
U(S)ARTs are off (serial wire debug is enabled),
LDO (STM32H730VBT6 MCU).
STM32CubeMX
OSPI
Clock
2022-05-17 07:18 AM
I don't use CubeMX to program, like I said have QSPI devices working on NUCLEO-H723ZG, and also H7A3
Nevermind, probably high/low bank of pins thru the mux, just scanning code differences.
I can port the test code,need to know external clock source, LDO/SMPS, usable UART
2022-05-17 09:59 AM
Checking with read status register won't be indicative, as 0x00 is a perfectly legal (and expected) value. Try Read ID command 0x9F instead.
Furthermore, inspect all OctoSPI registers after each HAL call and compare their contents against RM, in particular OCTOSPI_SR might give a clue.
2022-05-17 01:51 PM
This should output via SWV, running at 130 MHz
2022-05-18 12:38 AM
@Andreas Bolsch, @Community member, thank you for the assistance. The issue turned out to be the clock.