cancel
Showing results for 
Search instead for 
Did you mean: 

Hello guys. before all, I appreciated your Hint and Help. I use STM32L4R9Z microcontroller to Drive a QuadSPI NAND-Flash(Winbond). I configured OctaSPI of microcontroller as QuadSPI, and tried to write on NAND-Flash at Auto Polling mode.

HBita.1
Associate

After the Write-Enable command has been executed, the "HAL_OSPI_AutoPolling()" function will be called but, at the line of :

status = OSPI_WaitFlagStateUntilTimeout(hospi, HAL_OSPI_FLAG_SM, SET, tickstart, Timeout);

time out event will be accrued and so, call the error handler routine.

Question is here, why time out? is there any miss configuration? and how can I solved it?

OctaSPI initisation for Quad NAND-Flash:MX_OCTOSPI1_Init()

static 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 */

 /* OCTOSPI1 parameter configuration*/

 hospi1.Instance = OCTOSPI1;

 hospi1.Init.FifoThreshold = 4;

 hospi1.Init.DualQuad = HAL_OSPI_DUALQUAD_DISABLE;

 hospi1.Init.MemoryType = HAL_OSPI_MEMTYPE_MICRON;

 hospi1.Init.DeviceSize = 27;

 hospi1.Init.ChipSelectHighTime = 1;

 hospi1.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE;

 hospi1.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0;

 hospi1.Init.ClockPrescaler = 1;

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

 OSPIM_Cfg_Struct.NCSPort = 2;

 OSPIM_Cfg_Struct.IOLowPort = HAL_OSPIM_IOPORT_2_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 */

Write Enable Function:

static uint8_t W25M_OCTOSPI_WriteEnable(OSPI_HandleTypeDef OCTOSPIHandle)

{

 OSPI_RegularCmdTypeDef   s_command;

 OSPI_AutoPollingTypeDef s_config;

uint8_t pData[1] ;

 /* Enable write operations */

s_command.OperationType  = HAL_OSPI_OPTYPE_COMMON_CFG ;

s_command.InstructionMode  = HAL_OSPI_INSTRUCTION_1_LINE;

 s_command.Instruction    = W25M_WRITE_ENABLE_CMD;

s_command.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;

s_command.InstructionDtrMode  = HAL_OSPI_INSTRUCTION_DTR_DISABLE; // Hosbital

s_command.AddressDtrMode    = HAL_OSPI_ADDRESS_DTR_DISABLE; // Hosbital

 s_command.AddressMode    = HAL_OSPI_ADDRESS_NONE;

 s_command.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

s_command.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; //Hosbital

s_command.DQSMode = HAL_OSPI_DQS_DISABLE; //Hosbital

 s_command.DataMode     = HAL_OSPI_DATA_NONE;

 s_command.DummyCycles    = 0;

 s_command.DataDtrMode    = HAL_OSPI_DATA_DTR_DISABLE;

 s_command.SIOOMode     = HAL_OSPI_SIOO_INST_EVERY_CMD;

  

 if (HAL_OSPI_Command(&OCTOSPIHandle, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE) != HAL_OK)

 {

  return 0;

 }

  

s_config.Match = WRITE_ENABLE_MATCH_VALUE;

s_config.Mask = WRITE_ENABLE_MASK_VALUE;

s_config.MatchMode = HAL_OSPI_MATCH_MODE_AND;

s_config.Interval = AUTO_POLLING_INTERVAL;

s_config.AutomaticStop = HAL_OSPI_AUTOMATIC_STOP_ENABLE;

s_command.OperationType  = HAL_OSPI_OPTYPE_READ_CFG ;

s_command.InstructionMode  = HAL_OSPI_INSTRUCTION_1_LINE;

 s_command.Instruction    = W25M_READ_STATUS_REG_CMD;

s_command.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;

s_command.InstructionDtrMode  = HAL_OSPI_INSTRUCTION_DTR_DISABLE; // Hosbital

s_command.AddressDtrMode    = HAL_OSPI_ADDRESS_DTR_DISABLE; // Hosbital

s_command.AddressMode    = HAL_OSPI_ADDRESS_1_LINE;

 s_command.AddressSize    = HAL_OSPI_ADDRESS_8_BITS;

 s_command.Address      = W25M_STATUS_REG3_ADR;

s_command.AlternateBytesMode = HAL_OSPI_ALTERNATE_BYTES_NONE;

s_command.AlternateBytesDtrMode = HAL_OSPI_ALTERNATE_BYTES_DTR_DISABLE; //Hosbital

s_command.DQSMode = HAL_OSPI_DQS_DISABLE; //Hosbital

 s_command.DataMode     = HAL_OSPI_DATA_1_LINE;

 s_command.DummyCycles    = 0;

 s_command.NbData      = 1;

 s_command.DataDtrMode    = HAL_OSPI_DATA_DTR_DISABLE;

 s_command.SIOOMode     = HAL_OSPI_SIOO_INST_EVERY_CMD;

  

if (HAL_OSPI_Command(&OCTOSPIHandle, &s_command, HAL_OSPI_TIMEOUT_DEFAULT_VALUE ) != HAL_OK)

 {

  return 0;

 }

if (HAL_QSPI_AutoPolling(&hospi1,&s_command, &s_config, HAL_OSPI_TIMEOUT_DEFAULT_VALUE))

 {

  return 0;

 }

 return 1;

}

9 REPLIES 9
WDobb.1
Associate II

I have the same problem at the same spot with a STM32H723ZGTX talking to a Macronix MX25L3233F.

Pretty sure the MX25L3233F is a NOR Flash, and only support 4-bit wide operations.

If it is failing in the Auto-Polling, you need to look very carefully if the part is responsive at all, that you're using the right command/width settings, and that the memory has been enabled for the level of connectivity/commands being submitted.

Start with simple things like JEDEC READ ID at 1-bit, and confirm you're actually communicating properly, and then look at the status and configuration registers in the memory.

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

Is there a PDF or video explaining how to set up a QSPI part in the STMCubeIDE?

I can't seem to get the example code in dm00407776-octospi-interface-on-stm32-microcontrollers-stmicroelectronics.pdf to work. It fails with a timeout in WriteEnable().

I'm using Keil + HAL predominantly.

Under CubeH7 there should be various QSPI/OSPI examples for the assorted DISCO/EVAL boards as root projects one could clone or modify

Much of the code for the QSPI Flash parts being under the BSP Drivers, with the board/project specific pin stuff often in MSP files.

Like I said, WriteEnable has complexity (write, reads, waiting for bits to change/toggle), if you're not sure the device is working at a bus level you want to do the simpler read operations first. Reading the JEDEC ID or single bit read type command, where the code is linear and you only need to look at a handful of pins on a scope or logic analyzer.

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

I looked at the pins used for the OSPI1 port while running the example code in dm00407776-octospi-interface-on-stm32-microcontrollers-stmicroelectronics.pdf in a loop. There was no electrical activity at all. It doesn't appear to be a wiring problem as much as it is an example code problem. What am I missing here?

The WriteEnable() function fails at waiting for Transfer complete flag to clear. Why would that be an issue? I am at a loss as to how to resolve this.

>>I am at a loss as to how to resolve this.

Yeah, not sure how I'm going to figure it out either.

For the third, and final time

Are you able to initialize the interface to the chip (not the width, or dummy cycles configuration) and read the JEDEC ID? A simple YES/NO will suffice.

OCTOSPI and OCTOSPIM clocks enabled?

Involved GPIO clocks enabled?

All involved pins configured to AF mode, and with the correct AF Mux settings?

I understand WriteEnable() is not working for you, but in order for that to work several other things need to be working and checked first. Then perhaps you can focus on what's actually wrong/broken.

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

I did manage to get a 4-bit QSPI Winbond W25Q256FV running off the OCTOSPI/OSPI interface of a NUCLEO H7A3ZI-Q.

Got Read ID working

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

please share...​