cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H723 wrong data when interfacing QuadSPI & OctoSPI RAM

franckngatcha
Associate

Starting from a working application based on the STM32U585A microcontroller, we changed the CPU to have the ETHERNET peripheral available. The flash is connected via quadSPI to the microcontroller, while the RAM is connected via octospi .

Microcontroller Model: STM32H723ZGT6 FLASH MODEL: S25FL064L DRAM MODEL: APS6408L

Regarding the configuration operations of both the flash and the RAM, everything seems to work, but when it comes to reading or writing, we receive incorrect data once out of 10 attempts. Note that we have a working application with the STM32U5 microcontroller using the same flash and RAM.

Any idea on what I’m I missing?

Flash initializzation

void MX_OCTOSPI2_Init(void)

{



  /* USER CODE BEGIN OCTOSPI2_Init 0 */



  /* USER CODE END OCTOSPI2_Init 0 */



  OSPIM_CfgTypeDef sOspiManagerCfg = {0};



  /* USER CODE BEGIN OCTOSPI2_Init 1 */



  /* USER CODE END OCTOSPI2_Init 1 */

  hospi2.Instance = OCTOSPI2;

  hospi2.Init.FifoThreshold = 1;

  hospi2.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;

  hospi2.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;

  hospi2.Init.DeviceSize = 23;

  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 = 4;

  hospi2.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;

  hospi2.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_DISABLE;

  hospi2.Init.ChipSelectBoundary = 0;

  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 = 2;

  sOspiManagerCfg.NCSPort = 2;

  sOspiManagerCfg.IOLowPort = HAL_OSPIM_IOPORT_2_LOW;

  if (HAL_OSPIM_Config(&hospi2, &sOspiManagerCfg, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

  {

    Error_Handler();

  }

  /* USER CODE BEGIN OCTOSPI2_Init 2 */



  /* USER CODE END OCTOSPI2_Init 2 */



}



Funzione per leggere la flash

uint8_t bsp_ospi_flash_Read       (uint8_t* pData, uint32_t ReadAddr, uint32_t Size)

{

               OSPI_RegularCmdTypeDef     sCommand;

               /* Initialize the read command */

               sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;

               sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;

               sCommand.Instruction        = 0x6B;

               sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;

               sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;

               sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

               sCommand.AddressMode        = HAL_OSPI_ADDRESS_1_LINE;

               sCommand.AddressSize        = HAL_OSPI_ADDRESS_24_BITS;

               sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_DISABLE;

               sCommand.Address            = ReadAddr;

               sCommand.DataMode           = HAL_OSPI_DATA_4_LINES;

               sCommand.DummyCycles        = 8;

               sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

               sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_DISABLE;

               sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;

               sCommand.NbData             = Size;



               /* Configure the command */

               if (HAL_OSPI_Command(&hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

               {

                              return OSPI_ERROR;

               }



               /* Reception of the data */

               if (HAL_OSPI_Receive(&hospi2, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

               {

                              return OSPI_ERROR;

               }



               return OSPI_OK;

}



Flash write

uint8_t bsp_ospi_flash_WriteMemory      (uint8_t* pData, uint32_t WriteAddr, uint32_t Size)

{

               OSPI_RegularCmdTypeDef     sCommand;

               uint32_t end_addr, current_size, current_addr;



               /* Calculation of the size between the write address and the end of the page */

               current_size = S25FL064_PAGE_SIZE - (WriteAddr % S25FL064_PAGE_SIZE);



               /* Check if the size of the data is less than the remaining place in the page */

               if (current_size > Size)

               {

                              current_size = Size;

               }



               /* Initialize the adress variables */

               current_addr = WriteAddr;

               end_addr = WriteAddr + Size;



               /* Initialize the program command */

               sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;

               sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;

               sCommand.Instruction        = 0x32;

               sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;

               sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;

               sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

               sCommand.AddressMode        = HAL_OSPI_ADDRESS_1_LINE;

               sCommand.Address            = WriteAddr;

               sCommand.AddressSize        = HAL_OSPI_ADDRESS_24_BITS;

               sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_DISABLE;

               sCommand.DataMode           = HAL_OSPI_DATA_4_LINES;

               sCommand.DummyCycles        = 0;

               //           sCommand.DQSMode            = HAL_OSPI_DQS_ENABLE;

               sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

               sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_DISABLE;

               sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;

               sCommand.NbData             = 0;



               /* Perform the write page by page */

               do

               {

                              sCommand.Address = current_addr;

                              sCommand.NbData  = current_size;



                              /* Enable write operations */

                              if (OSPI_WriteEnable(&hospi2) != OSPI_OK)

                              {

                                            return OSPI_ERROR;

                              }



                              /* Configure the command */

                              if (HAL_OSPI_Command(&hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

                              {

                                            return OSPI_ERROR;

                              }



                              /* Transmission of the data */

                              if (HAL_OSPI_Transmit(&hospi2, pData, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

                              {

                                            return OSPI_ERROR;

                              }



                              /* Configure automatic polling mode to wait for end of program */

                              if (OSPI_AutoPollingMemReady(&hospi2, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != OSPI_OK)

                              {

                                            return OSPI_ERROR;

                              }

                              /* Update the address and size variables for next page programming */

                              current_addr += current_size;

                              pData += current_size;

                              current_size = ((current_addr + S25FL064_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : S25FL064_PAGE_SIZE;

               }

               while (current_addr < end_addr);



               return OSPI_OK;

}

uint8_t bsp_ospi_flash_EnableMemoryMappedMode(void)

{

               uint8_t ret=OSPI_OK;

               OSPI_RegularCmdTypeDef     sCommand;

               OSPI_MemoryMappedTypeDef sMemMappedCfg;



               sCommand.OperationType      = HAL_OSPI_OPTYPE_COMMON_CFG;

               sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;

               sCommand.Instruction        = 0xEB;

               sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_1_LINE;

               sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_8_BITS;

               sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_DISABLE;

               sCommand.AddressMode        = HAL_OSPI_ADDRESS_4_LINES;

               sCommand.AddressSize        = HAL_OSPI_ADDRESS_24_BITS;

               sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_DISABLE;

               sCommand.DataMode           = HAL_OSPI_DATA_4_LINES;

               sCommand.DummyCycles        = S25FL064_DUMMY_CYCLES_READ;

               sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_4_LINES;

               sCommand.AlternateBytes     = 0x2;

               sCommand.AlternateBytesSize = HAL_OSPI_ALTERNATE_BYTES_8_BITS;

               sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_DISABLE;

               sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;



               if (HAL_OSPI_Command(&hospi2, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

               {

                              return OSPI_ERROR;

               }

               sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;

               sMemMappedCfg.TimeOutPeriod     = 0x34;

               if (HAL_OSPI_MemoryMapped(&hospi2, &sMemMappedCfg) != HAL_OK)

               {

                              return OSPI_ERROR;

               }



               return ret;

}





RAM OCTOSPI INIT

/* OCTOSPI1 init function */

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_APMEMORY;

  hospi1.Init.DeviceSize = 23;

  hospi1.Init.ChipSelectHighTime = 2;

  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 = 2;

  hospi1.Init.SampleShifting = HAL_OSPI_SAMPLE_SHIFTING_NONE;

  hospi1.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE;

  hospi1.Init.ChipSelectBoundary = 0;

  hospi1.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_USED;

  hospi1.Init.MaxTran = 10;

  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();

  }

  /* USER CODE BEGIN OCTOSPI1_Init 2 */



  /* USER CODE END OCTOSPI1_Init 2 */



}



static void Configure_APMemory(void)

{

               /* MR0 register for read and write */

               uint8_t regW_MR0[2]={0x24,0x0D}; /* To configure AP memory Latency Type and drive Strength */

               uint8_t regR_MR0[2]={0};



               /* MR8 register for read and write */

               uint8_t regW_MR8[2]={0x0B,0x08}; /* To configure AP memory Burst Type */

               uint8_t regR_MR8[2]={0};



               /*Read Latency */

               uint8_t latency=6;



               /* Configure Read Latency and drive Strength */

               if (APS6408_WriteReg(&hospi1, MR0, regW_MR0) != HAL_OK)

               {

                              Error_Handler();

               }



               /* Check MR0 configuration */

               if (APS6408_ReadReg(&hospi1, MR0, regR_MR0, latency ) != HAL_OK)

               {

                              Error_Handler();

               }



               /* Check MR0 configuration */

               if (regR_MR0 [0] != regW_MR0 [0])

               {

                              Error_Handler() ;

               }



               /* Configure Burst Length */

               if (APS6408_WriteReg(&hospi1, MR8, regW_MR8) != HAL_OK)

               {

                              Error_Handler();

               }



               /* Check MR8 configuration */

               if (APS6408_ReadReg(&hospi1, MR8, regR_MR8, 6) != HAL_OK)

               {

                              Error_Handler();

               }



               if (regR_MR8[0] != regW_MR8[0])

               {

                              Error_Handler() ;

               }

}

Meory mapped mode



uint8_t bsp_ospi_ram_EnableMemoryMappedMode(void)

{

               OSPI_RegularCmdTypeDef sCommand = {0};

               OSPI_MemoryMappedTypeDef sMemMappedCfg;

               /*Configure Memory Mapped mode*/

               sCommand.OperationType      = HAL_OSPI_OPTYPE_WRITE_CFG;

               sCommand.FlashId            = HAL_OSPI_FLASH_ID_1;

               sCommand.Instruction        = WRITE_CMD;

               sCommand.InstructionMode    = HAL_OSPI_INSTRUCTION_8_LINES;

               sCommand.InstructionSize    = HAL_OSPI_INSTRUCTION_16_BITS;

               sCommand.InstructionDtrMode = HAL_OSPI_INSTRUCTION_DTR_ENABLE;

               sCommand.AddressMode        = HAL_OSPI_ADDRESS_8_LINES;

               sCommand.AddressSize        = HAL_OSPI_ADDRESS_32_BITS;

               sCommand.AddressDtrMode     = HAL_OSPI_ADDRESS_DTR_ENABLE;

               sCommand.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

               sCommand.DataMode           = HAL_OSPI_DATA_8_LINES;

               sCommand.DataDtrMode        = HAL_OSPI_DATA_DTR_ENABLE;

               sCommand.DummyCycles        = DUMMY_CLOCK_CYCLES_WRITE;

               sCommand.DQSMode            = HAL_OSPI_DQS_ENABLE;

               sCommand.SIOOMode           = HAL_OSPI_SIOO_INST_EVERY_CMD;



               if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

               {

                              Error_Handler();

               }



               sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;

               sCommand.Instruction   = READ_CMD;

               sCommand.DummyCycles   = DUMMY_CLOCK_CYCLES_READ;



               if (HAL_OSPI_Command(&hospi1, &sCommand, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

               {

                              Error_Handler();

               }



               sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_ENABLE;

               sMemMappedCfg.TimeOutPeriod     = 0x34;



               if (HAL_OSPI_MemoryMapped(&hospi1, &sMemMappedCfg) != HAL_OK)

               {

                              Error_Handler();

               }

               return 0;

}

 


Edited to apply source code formatting - please see How to insert source code for future reference.

 

0 REPLIES 0