cancel
Showing results for 
Search instead for 
Did you mean: 

OSPI in QSPI mode, issue with sending address

TimJones
Associate

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?

1 REPLY 1

OSPI_RegularCmdTypeDef sCommand = {0}; // Ensure the stack buffer is cleared, and not random junk

Nothing is immediately jumping out from the code. Not had much trouble here using QSPI devices on an OSPI peripheral.

Prescaler is ridiculously high

 

  /* OSPI initialization */
  hospi->Init.FifoThreshold         = 1; // 1..32 Interrupt threshold
  hospi->Init.DualQuad              = HAL_OSPI_DUALQUAD_DISABLE;
  hospi->Init.MemoryType            = HAL_OSPI_MEMTYPE_MICRON;
  hospi->Init.DeviceSize            = 27; //OSPI_FLASH_SIZE_SHIFT;
  hospi->Init.ChipSelectHighTime    = 4; // Min 30ns for nonRead
  hospi->Init.FreeRunningClock      = HAL_OSPI_FREERUNCLK_DISABLE;
  hospi->Init.ClockMode             = HAL_OSPI_CLOCK_MODE_0;
  hospi->Init.WrapSize              = HAL_OSPI_WRAP_NOT_SUPPORTED;

#ifdef OSPI_CLK_DIV
  hospi->Init.ClockPrescaler        = OSPI_CLK_DIV;
#else
  hospi->Init.ClockPrescaler        = 1; /* QSPI freq = 64 MHz/(1+1) = 32 Mhz */
#endif

  hospi->Init.SampleShifting        = HAL_OSPI_SAMPLE_SHIFTING_HALFCYCLE;

  hospi->Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;
  hospi->Init.ChipSelectBoundary    = 0;

  if (HAL_OSPI_Init(hospi) != HAL_OK)
  {
    return(OSPI_ERROR);
  }
...
  OSPIM_CfgTypeDef OSPIM_Cfg_Struct = {0};

  /*##-4- Configure the OctoSPI IO Manager ####################################*/
  // P1=1, P2=2?
  OSPIM_Cfg_Struct.NCSPort    = 1;
  OSPIM_Cfg_Struct.ClkPort    = 1; // 1 .. 8
#ifdef OSPI_DQS_PIN
  OSPIM_Cfg_Struct.DQSPort    = 1;
#else
  OSPIM_Cfg_Struct.DQSPort    = 0;
#endif // OSPI_DQS_PIN

  OSPIM_Cfg_Struct.IOHighPort = HAL_OSPIM_IOPORT_NONE; // 1_HIGH; // Not needed?
  OSPIM_Cfg_Struct.IOLowPort  = HAL_OSPIM_IOPORT_1_LOW;

  if (HAL_OSPIM_Config(hospi, &OSPIM_Cfg_Struct, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
  }
...

static uint8_t BSP_OSPI_Read(OSPI_HandleTypeDef *hospi, uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{
  OSPI_RegularCmdTypeDef sCommand = {0};

  sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;
  sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;

  /* Initialize the read command */
  sCommand.Instruction        = 0x3B; // DUAL (MOST COMPATIBLE)
  sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;
  sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
  sCommand.DataMode           = HAL_OSPI_DATA_2_LINES;
  sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_DISABLE;
  sCommand.AddressMode        = HAL_OSPI_ADDRESS_1_LINE;
  sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_DISABLE;
  sCommand.DummyCycles        = 8;

#ifdef USE_ADR32
  sCommand.AddressSize        = HAL_OSPI_ADDRESS_32_BITS;
#else
  sCommand.AddressSize        = HAL_OSPI_ADDRESS_24_BITS;
#endif // USE_ADR32

  sCommand.Address            = ReadAddr & 0x0FFFFFFF; // Ensure Masking
  sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;
  sCommand.NbData             = Size;
  sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;

  /* Configure the command */
  if (HAL_OSPI_Command(hospi, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return(OSPI_ERROR);
  }

  /* Transmission of the data */
  if (HAL_OSPI_Receive(hospi, pData,  HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
  {
    return(OSPI_ERROR);
  }

  return(OSPI_OK);
}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..