OSPI in QSPI mode, issue with sending address
I'm importing some QSPI code we've been using a few years from an SMT32F7xx project to a new project using an STM32L4xx. Both projects use the same target device. I'm having an issue where the majority of messages don't seem to be sent. After debugging with a logic analyzer the behavior I'm seeing is that if I send a message where
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;then it sends correctly. For any other value of AddressMode, none of the signals change at all when the command is executed.
For example the following message sends correctly:
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ;//8;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.Instruction = 0x35;
sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.DataMode = HAL_OSPI_DATA_NONE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
if (HAL_OSPI_Command(OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT) != HAL_OK)
{
DEBUG("OSPI QuadModeCfg FAIL\r\n");
if(0==InErrorHandler) {
OSPI_Error_Handler();
}
}The following message does not send anything at all, unless I change AddressMode to none.
OSPI_RegularCmdTypeDef sCommand;
uint8_t cr1v = 0;
sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;;
sCommand.FlashId = HAL_OSPI_FLASH_ID_1;
sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
sCommand.AddressSize = HAL_OSPI_ADDRESS_24_BITS;
sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
sCommand.Instruction = READ_ANY_REG_CMD;//0x65
sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
//sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
sCommand.DataMode = HAL_OSPI_DATA_1_LINE;
sCommand.DummyCycles = DUMMY_CLOCK_CYCLES_READ;//8
sCommand.Address = 2;
sCommand.NbData = 1;
if (HAL_OSPI_Command(OSPIHandle, &sCommand, HAL_OSPI_TIMEOUT) != HAL_OK)
{
DEBUG("OSPI QuadModeCfg FAIL\r\n");
}
if (HAL_OSPI_Receive(OSPIHandle, &cr1v, HAL_OSPI_TIMEOUT) != HAL_OK)
{
DEBUG("OSPI QuadModeCfg Receive FAIL\r\n");
}The HAL_OSPI_Command function returns HAL_OK even though it does not send the command, and then HAL_OSPI_Receive fails with a timeout.
The octospi.c initialization is below. I'm not completely sure what all the values do but I tried to match it to the original project since that one works.
/* OCTOSPI1 init function */
void MX_OCTOSPI1_Init(void)
{
/* USER CODE BEGIN OCTOSPI1_Init 0 */
/* USER CODE END OCTOSPI1_Init 0 */
OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {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 = 1;
hospi1.Init.ChipSelectHighTime = 1;
hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;
hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;
hospi1.Init.ClockPrescaler = 255;
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;
if (HAL_OSPI_Init(&hospi1) != HAL_OK)
{
Error_Handler();
}
OSPIM_Cfg_Struct.ClkPort = 1;
OSPIM_Cfg_Struct.NCSPort = 1;
OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
if (HAL_OSPIM_Config(&hospi1, &OSPIM_Cfg_Struct, 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 PeriphClkInit = {0};
if(ospiHandle->Instance==OCTOSPI1)
{
/* USER CODE BEGIN OCTOSPI1_MspInit 0 */
/* USER CODE END OCTOSPI1_MspInit 0 */
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
PeriphClkInit.OspiClockSelection = RCC_OSPICLKSOURCE_MSI;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/* OCTOSPI1 clock enable */
__HAL_RCC_OSPIM_CLK_ENABLE();
__HAL_RCC_OSPI1_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**OCTOSPI1 GPIO Configuration
PE13 ------> OCTOSPIM_P1_IO1
PE15 ------> OCTOSPIM_P1_IO3
PB11 ------> OCTOSPIM_P1_NCS
PB10 ------> OCTOSPIM_P1_CLK
PE12 ------> OCTOSPIM_P1_IO0
PE14 ------> OCTOSPIM_P1_IO2
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_15|GPIO_PIN_12|GPIO_PIN_14;
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(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11|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_AF10_OCTOSPIM_P1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* OCTOSPI1 DMA Init */
/* OCTOSPI1 Init */
hdma_octospi1.Instance = DMA1_Channel1;
hdma_octospi1.Init.Request = DMA_REQUEST_OCTOSPI1;
hdma_octospi1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_octospi1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_octospi1.Init.MemInc = DMA_MINC_ENABLE;
hdma_octospi1.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_octospi1.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_octospi1.Init.Mode = DMA_NORMAL;
hdma_octospi1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_octospi1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(ospiHandle,hdma,hdma_octospi1);
/* OCTOSPI1 interrupt Init */
HAL_NVIC_SetPriority(OCTOSPI1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(OCTOSPI1_IRQn);
/* USER CODE BEGIN OCTOSPI1_MspInit 1 */
/* USER CODE END OCTOSPI1_MspInit 1 */
}
}
Is there any way to figure out what the issue is, or things I should try?
