Skip to main content
SGUIG.1
Associate II
January 18, 2022
Question

OctoSPI not working on STM32U5

  • January 18, 2022
  • 2 replies
  • 1456 views

Hello, i am trying to communicate with an MRAM memory (Micron) via octoSPI but i can't manage to make it work! i already looked at the ST code examples and i got the same configuration as the examples but it just doesn't work. Please help!

PS: i am using OSPI1 on a Flash memory and the OSPI2 on my MRAM.

You will find my code bellow:

MX_OCTOSPI2_Init(void)

static void MX_OCTOSPI2_Init(void)
{
 
 /* USER CODE BEGIN OCTOSPI2_Init 0 */
 
 /* USER CODE END OCTOSPI2_Init 0 */
 
 OSPIM_CfgTypeDef sOspiManagerCfg = {0};
 HAL_OSPI_DLYB_CfgTypeDef HAL_OSPI_DLYB_Cfg_Struct = {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_MICRON;
 hospi2.Init.DeviceSize = 32;
 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_NOT_SUPPORTED;
 hospi2.Init.ClockPrescaler = 1;
 hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;
 hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;
 hospi2.Init.ChipSelectBoundary = 1;
 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 = 1;
 sOspiManagerCfg.NCSPort = 2;
 sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_1_LOW;
 sOspiManagerCfg.Req2AckTime = 1;
 if (HAL_OSPIM_Config(&hospi2, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_OSPI_DLYB_Cfg_Struct.Units = 0;
 HAL_OSPI_DLYB_Cfg_Struct.PhaseSel = 0;
 if (HAL_OSPI_DLYB_SetConfig(&hospi2, &HAL_OSPI_DLYB_Cfg_Struct) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN OCTOSPI2_Init 2 */
 
 /* USER CODE END OCTOSPI2_Init 2 */
 
}

ENABLE write command and write the buffer:

uint32_t NVRAM_WriteReg(OSPI_HandleTypeDef *hospi2, uint8_t *Value, OSPI_RegularCmdTypeDef sCommand)
{
 /* Initialize the write register command */
 sCommand.AddressMode = HAL_OSPI_ADDRESS_NONE;
 sCommand.AddressSize = HAL_OSPI_ADDRESS_8_BITS;
 sCommand.Address = 0;
 sCommand.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
 sCommand.AlternateBytesMode = 0;
 sCommand.AlternateBytesSize = 0;
 sCommand.Instruction = 0x06;
 sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
 sCommand.DataMode = HAL_OSPI_DATA_NONE;
 sCommand.DummyCycles = 0;
 sCommand.NbData = 0;
 
 sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
 sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
 sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
 sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
 sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
 // Configure the command
 if (HAL_OSPI_Command(hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }
 
 /* Initialize the write register command */
 sCommand.AddressMode = HAL_OSPI_ADDRESS_1_LINE;
 sCommand.AddressSize = HAL_OSPI_ADDRESS_8_BITS;
 sCommand.Address = 0;
 sCommand.AlternateBytes = HAL_OSPI_ALTERNATE_BYTES_NONE;
 sCommand.AlternateBytesMode = 0;
 sCommand.AlternateBytesSize = 0;
 sCommand.Instruction = 0x87;//0x01;
 sCommand.InstructionMode = HAL_OSPI_INSTRUCTION_1_LINE;
 sCommand.DataMode = HAL_OSPI_DATA_1_LINE;
 sCommand.DummyCycles = 0;
 sCommand.NbData = 10;
 
 sCommand.OperationType = HAL_OSPI_OPTYPE_COMMON_CFG;
 sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;
 sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
 sCommand.AddressDtrMode = HAL_OSPI_ADDRESS_DTR_DISABLE;
 sCommand.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
 sCommand.DataDtrMode = HAL_OSPI_DATA_DTR_DISABLE;
 sCommand.DQSMode = HAL_OSPI_DQS_DISABLE;
 sCommand.SIOOMode = HAL_OSPI_SIOO_INST_EVERY_CMD;
 
 if (HAL_OSPI_Command(hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }
 /* Transmission of the data */
 if (HAL_OSPI_Transmit(hospi2, (uint8_t *)(Value), HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
 {
 return HAL_ERROR;
 }
 
 return HAL_OK;
}

HAL_OSPI_MspInit:

void HAL_OSPI_MspInit(OSPI_HandleTypeDef* hospi)
{
 GPIO_InitTypeDef GPIO_InitStruct = {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 if(hospi->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_SYSCLK;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
 {
 Error_Handler();
 }
 
 /* Peripheral clock enable */
 __HAL_RCC_OSPI1_CLK_ENABLE();
 
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_GPIOE_CLK_ENABLE();
 /**OCTOSPI1 GPIO Configuration
 PB0 ------> OCTOSPIM_P1_IO1
 PB1 ------> OCTOSPIM_P1_IO0
 PE10 ------> OCTOSPIM_P1_CLK
 PE11 ------> OCTOSPIM_P1_NCS
 */
 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
 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_OCTOSPI1;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
 GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
 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_OCTOSPI1;
 HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
 /* USER CODE BEGIN OCTOSPI1_MspInit 1 */
 
 /* USER CODE END OCTOSPI1_MspInit 1 */
 }
 else if(hospi->Instance==OCTOSPI2)
 {
 /* USER CODE BEGIN OCTOSPI2_MspInit 0 */
 
 /* USER CODE END OCTOSPI2_MspInit 0 */
 
 /** Initializes the peripherals clock
 */
 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_OSPI;
 PeriphClkInit.OspiClockSelection = RCC_OSPICLKSOURCE_SYSCLK;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
 {
 Error_Handler();
 }
 
 /* Peripheral clock enable */
 __HAL_RCC_OSPI2_CLK_ENABLE();
 
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOE_CLK_ENABLE();
 /**OCTOSPI2 GPIO Configuration
 PD3 ------> OCTOSPIM_P2_NCS
 */
 GPIO_InitStruct.Pin = GPIO_PIN_3;
 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_OCTOSPI2;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
 HAL_GPIO_WritePin( NVSRAM_WP_GPIO_Port, NVSRAM_WP_Pin, ( GPIO_PinState )( 1 ) );
 HAL_GPIO_WritePin( GPIOE, GPIO_PIN_11, ( GPIO_PinState )( 1 ) ); // CS FLASH
 HAL_GPIO_WritePin( GPIOD, GPIO_PIN_3, ( GPIO_PinState )( 0 ) ); // CS NVRAM
 //HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, ( GPIO_PinState )( 0 ) ); // SO1
 
 /* OCTOSPI2 interrupt Init */
 HAL_NVIC_SetPriority(OCTOSPI2_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(OCTOSPI2_IRQn);
 
 /* USER CODE BEGIN OCTOSPI2_MspInit 1 */
 
 /* USER CODE END OCTOSPI2_MspInit 1 */
 }
 
}

This topic has been closed for replies.

2 replies

ChahinezC
Associate II
February 11, 2022

Hello @SGUIG.1​,

Can you please specify the board and the memory you are using?

Chahinez.

Tesla DeLorean
Guru
February 11, 2022

Not sure, but only the first instance initializes any pins, and then only two data pins.

Can you bring up both chips and probe the READ IDs?​

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