cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H563ZI + APS6404L QSPI Memory Mapped Reads Failing

theAE
Associate II

Hello, 

I am using a STM32H563ZI with an external PSRAM QSPI device, the APS6404L. I am using Quad-SPI through the OCTOSPI interface and have been successfully able to get into memory mapped mode. However, every time I go to read, I read out only 0 data. Has anyone ran into this same issue? I have pasted my code for transitioning the device to memory mapped mode and a subsequent test write/read. Thanks! 

 

int main(void)
{

  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ICACHE_Init();
  MX_OCTOSPI1_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */

  HAL_Delay(100);
	uint8_t reset_enable[1] = {0x66}; 
	uint8_t rst[1] = {}; 
	uint8_t buff[3]; 
	uint8_t buffer[128], dato;
	
	APS6404_RESET_ENABLE(&hospi1);	

	PSRAM_ReadID(&hospi1); 
	
	APS6404_ENTER_QUAD_MODE(&hospi1);
		
	uint8_t myData[] = {0xD, 0xE, 0xA, 0xD};
	APS6404L_QuadWrite(&hospi1, OCTOSPI1_BASE, myData, sizeof(myData));
	
	uint8_t rxData[32]; 
	APS6404L_QuadRead(&hospi1, OCTOSPI1_BASE, rxData, sizeof(rxData));
	
	/* MEM MAPPED MODE */
	
	XSPI_RegularCmdTypeDef sCommand;
  XSPI_MemoryMappedTypeDef sMemMappedCfg;
	
  sCommand.OperationType      = HAL_XSPI_OPTYPE_WRITE_CFG;
  sCommand.Instruction        = 0x38;
  sCommand.InstructionMode    = HAL_XSPI_INSTRUCTION_4_LINES;
  sCommand.InstructionWidth   = HAL_XSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;

  sCommand.Address            = 0x00000000;
  sCommand.AddressMode        = HAL_XSPI_ADDRESS_4_LINES;
  sCommand.AddressWidth       = HAL_XSPI_ADDRESS_24_BITS;
  sCommand.AddressDTRMode     = HAL_XSPI_ADDRESS_DTR_DISABLE;

  sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;

  sCommand.DataMode           = HAL_XSPI_DATA_4_LINES;
  sCommand.DataDTRMode        = HAL_XSPI_DATA_DTR_DISABLE;

  sCommand.DummyCycles        = 0; // for reads only 
  sCommand.DQSMode            = HAL_XSPI_DQS_ENABLE;
  sCommand.SIOOMode           = HAL_XSPI_SIOO_INST_EVERY_CMD;
	
	sCommand.OperationType      = HAL_XSPI_OPTYPE_WRITE_CFG;
  sCommand.Instruction        = 0x38;
	sCommand.DummyCycles = 6;
	
	if (HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
			Error_Handler();
	}
	
	sCommand.OperationType = HAL_XSPI_OPTYPE_READ_CFG;
	sCommand.Instruction = 0xEB;
	sCommand.DummyCycles = 0;
	sCommand.DQSMode = HAL_XSPI_DQS_DISABLE; 
	
	if (HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
			Error_Handler();
	}
	
	/* Enable Memory Mapped Mode */
	sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
	//sMemMappedCfg.TimeoutPeriodClock = 0x34;

		if (HAL_XSPI_MemoryMapped(&hospi1, &sMemMappedCfg))
		{
			Error_Handler();
		}
		
  /* Insert delay 100 ms */
  HAL_Delay(100);
		
  volatile __IO uint8_t *mem_addr_byte;

  // Writing Sequence (8-bit, unaligned pattern)
  mem_addr_byte = (uint8_t *)(OCTOSPI1_BASE);
	
	mem_addr_byte[0] = 0xDE; 
	if (mem_addr_byte[0] != 0xDE)
	{
		Error_Handler();
	}

 

6 REPLIES 6
Saket_Om
ST Employee

Hello @theAE 

Please refer to the example XSPI_PSRAM_MemoryMapped.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om

Hello, 

Thank you for posting this link. I have seen this and my current code matches this implementation nearly besides of enabling DQS during reads. I still am unable to see any non zero data being read from the APS6404L still even with matching every setting from the example (for quad spi, 24 bits of address). 

 

MHoll.2
Senior III

This seems strange to me:

When switching to memory maped mode You have to:

1. configure the READ function (0xEB is read, but you are using 0x38!), according to the datasheet this need 6 dummy cycles.

Then configure the WRITE function (0x38), according to the datasheet this has 0 dummy cycles.

It seems You have inverted the two commands.

Why did You enable DQS, the chip has no DQS pin.

You have not posted Your MX_OCTOSPI1_Init() function, so I can not comment on this. 

 

 This is what i'm using on a STM32U575:

int32_t APSBusSwitchMemoryMode( OSPI_HandleTypeDef *hospi )
{
  OSPI_MemoryMappedTypeDef sMemMappedCfg = {0};
  OSPI_RegularCmdTypeDef   sCommand;

  APSSetQuadMode(hospi);

  /* Memory-mapped mode configuration ------------------------------- */
  sCommand.OperationType          = HAL_OSPI_OPTYPE_READ_CFG;
  sCommand.FlashId                = HAL_OSPI_FLASH_ID_1;
  sCommand.Instruction            = APS_CMD_FAST_READ_QIO; ;
  sCommand.InstructionMode        = HAL_OSPI_INSTRUCTION_4_LINES;
  sCommand.InstructionSize        = HAL_OSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDtrMode     = HAL_OSPI_INSTRUCTION_DTR_DISABLE;
  sCommand.Address                = 0;
  sCommand.AddressMode            = HAL_OSPI_ADDRESS_4_LINES;
  sCommand.AddressSize            = HAL_OSPI_ADDRESS_24_BITS;
  sCommand.AddressDtrMode         = HAL_OSPI_ADDRESS_DTR_DISABLE;
  sCommand.AlternateBytes         = 0;
  sCommand.AlternateBytesMode     = HAL_OSPI_ALTERNATE_BYTES_NONE;
  sCommand.AlternateBytesSize     = HAL_OSPI_ALTERNATE_BYTES_8_BITS;
  sCommand.AlternateBytesDtrMode  = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE;
  sCommand.DataMode               = HAL_OSPI_DATA_4_LINES;
  sCommand.NbData                 = 1;
  sCommand.DataDtrMode            = HAL_OSPI_DATA_DTR_DISABLE;
  sCommand.DummyCycles            = 6;
  sCommand.DQSMode                = HAL_OSPI_DQS_DISABLE;
  sCommand.SIOOMode               = HAL_OSPI_SIOO_INST_EVERY_CMD;

  if (HAL_OSPI_Command(hospi, &sCommand, 5) != HAL_OK)
  {
    return(HAL_ERROR);
  }

  sCommand.OperationType          = HAL_OSPI_OPTYPE_WRITE_CFG;
  sCommand.Instruction            = APS_CMD_WRITE_QIO;
  sCommand.DummyCycles            = 0;
  sCommand.DQSMode                = HAL_OSPI_DQS_ENABLE;

  if (HAL_OSPI_Command(hospi, &sCommand, 5) != HAL_OK)
  {
    return(HAL_ERROR);
  }

  sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;
  if (HAL_OSPI_MemoryMapped(hospi, &sMemMappedCfg) != HAL_OK)
  {
    return(HAL_ERROR);
  }
  return(HAL_OK);
}

 

Thank you for your input @MHoll.2 

I enabled DQS for writes because I read in the errata on page 18 of the STM32H5 errata sheet: "Memory-mapped write error response when DQS output is disabled"

I revised the code to match yours but have the same result. So perhaps there is something else wrong with my config. I pasted my revised code and associated MX_OCTOSPI1_Init() function. 

 

	/* MEM MAPPED MODE */
	
	XSPI_RegularCmdTypeDef sCommand;
  XSPI_MemoryMappedTypeDef sMemMappedCfg;
	
	sCommand.OperationType      = HAL_XSPI_OPTYPE_READ_CFG;
  sCommand.Instruction        = 0xEB;
  sCommand.InstructionMode    = HAL_XSPI_INSTRUCTION_4_LINES;
  sCommand.InstructionWidth   = HAL_XSPI_INSTRUCTION_8_BITS;
  sCommand.InstructionDTRMode = HAL_XSPI_INSTRUCTION_DTR_DISABLE;

  sCommand.Address            = 0x00000000;
  sCommand.AddressMode        = HAL_XSPI_ADDRESS_4_LINES;
  sCommand.AddressWidth       = HAL_XSPI_ADDRESS_24_BITS;
  sCommand.AddressDTRMode     = HAL_XSPI_ADDRESS_DTR_ENABLE; // changed

  sCommand.AlternateBytesMode = HAL_XSPI_ALT_BYTES_NONE;
	sCommand.AlternateBytes 		= 0; 

  sCommand.DataMode           = HAL_XSPI_DATA_4_LINES;
  sCommand.DataDTRMode        = HAL_XSPI_DATA_DTR_ENABLE; // changed

  sCommand.DummyCycles        = 6; // for reads only 
  sCommand.DQSMode            = HAL_XSPI_DQS_DISABLE;
  sCommand.SIOOMode           = HAL_XSPI_SIOO_INST_EVERY_CMD;
	
	
	if (HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
			Error_Handler();
	}
	
	sCommand.OperationType = HAL_XSPI_OPTYPE_WRITE_CFG;
	sCommand.Instruction = 0x38;
	sCommand.DummyCycles = 0; 
	sCommand.DQSMode = HAL_XSPI_DQS_ENABLE; 
	
	if (HAL_XSPI_Command(&hospi1, &sCommand, HAL_XSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)
	{
			Error_Handler();
	}
	
	/* Enable Memory Mapped Mode */
	sMemMappedCfg.TimeOutActivation = HAL_XSPI_TIMEOUT_COUNTER_DISABLE;
	sMemMappedCfg.TimeoutPeriodClock = 0x34;

		if (HAL_XSPI_MemoryMapped(&hospi1, &sMemMappedCfg))
		{
			Error_Handler();
		}
		
  /* Insert delay 100 ms */
  HAL_Delay(100);
		
  volatile __IO uint8_t *mem_addr_byte;

  // Writing Sequence (8-bit, unaligned pattern)
  mem_addr_byte = (uint8_t *)(OCTOSPI1_BASE);
		
	HAL_GPIO_WritePin(GPIOG, GPIO_PIN_12, GPIO_PIN_SET);
	
	mem_addr_byte[0] = 0xDE; 
	if (mem_addr_byte[0] != 0xDE)
	{
		Error_Handler();
	}

 

static void MX_OCTOSPI1_Init(void)
{

  /* USER CODE BEGIN OCTOSPI1_Init 0 */

  /* USER CODE END OCTOSPI1_Init 0 */

  /* USER CODE BEGIN OCTOSPI1_Init 1 */

  /* USER CODE END OCTOSPI1_Init 1 */
  /* OCTOSPI1 parameter configuration*/
  hospi1.Instance = OCTOSPI1;
  hospi1.Init.FifoThresholdByte = 1;
  hospi1.Init.MemoryMode = HAL_XSPI_SINGLE_MEM;
  hospi1.Init.MemoryType = HAL_XSPI_MEMTYPE_APMEM;
  hospi1.Init.MemorySize = HAL_XSPI_SIZE_64MB;
  hospi1.Init.ChipSelectHighTimeCycle = 1;
  hospi1.Init.FreeRunningClock = HAL_XSPI_FREERUNCLK_DISABLE;
  hospi1.Init.ClockMode = HAL_XSPI_CLOCK_MODE_0;
  hospi1.Init.WrapSize = HAL_XSPI_WRAP_32_BYTES;
  hospi1.Init.ClockPrescaler = 3;
  hospi1.Init.SampleShifting = HAL_XSPI_SAMPLE_SHIFT_NONE;
  hospi1.Init.DelayHoldQuarterCycle = HAL_XSPI_DHQC_DISABLE;
  hospi1.Init.ChipSelectBoundary = HAL_XSPI_BONDARYOF_NONE;
  hospi1.Init.DelayBlockBypass = HAL_XSPI_DELAY_BLOCK_BYPASS;
  hospi1.Init.Refresh = 0;
  if (HAL_XSPI_Init(&hospi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN OCTOSPI1_Init 2 */

  /* USER CODE END OCTOSPI1_Init 2 */

}

 

The only difference I have in the Init (on a different CORE, so this may be irelevant):

ChipSelectHighTme = 2

DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE

Refresh = 240

Thank you for taking a look @MHoll.2 - I appreciate it.