Showing results for 
Search instead for 
Did you mean: 

Using LevelX NOR OSPI interface with QSPI memory

Associate III

I'm trying to use the Azure FileX with the LevelX NOR OSPI driver to access a QSPI memory.  I'm using an STM32H723 processor an OctoSPI peripheral to try to interface to a Winbond W25Q128JV QSPI NOR memory. Part of my struggle is there are examples of H7 processors with QSPI peripherals interfacing to QSPI memories.  And H7 processors with OSPI peripherals accessing OSPI memories.  But nothing with the OSPI to QSPI memory combination.

I'm currently using a Nucleo-144 H723 board interfaced to a custom IO board that has the QSPI memory on it. I originally started with an F7 nucleo board (with QSPI) but couldn't get the Azure USBX to work with the F7 so changed to the H723 and the OSPI came as a "bonus".

I'm early in the process of trying figure out what I need to do with getting the software configured into my configuration. CubeMX will generate lx_stm32_qspi_driver_glue.c  and lx_stm32_ospi_driver.c code. There is also an option to include an OSPI Macronix memory device.  If the memory device driver is not selected, there is the option to memory device specific commands in lx_stm32_ospi_driver.h.

Before I dig too deep into the generated OSPI code, I wanted to pose the question.  Is is possible to configure the generated QSPI interface code (with what ever user code necessary) to have it access a QSPI memory?  Is it as simple as defining the QSPI memory registers and commands? The OSPI peripheral in the IOC is configured for the IO used by my QSPI memory device.

Or am I effectively going to have to create a custom driver to work with my situation?  There is the QSPI example but I would have to adapt that to the OSPI HAL.

I may also decide to punt and switch to an H7 processor with a QSPI interface or switch to a directly supported OSPI memory. I have not committed to the configuration of the production board. My preference is getting the QSPI memory to work.


Yes QSPI and DUAL-QSPI can be implemented via OSPI / OSPIM.  QSPI on XSPI too

FAT file systems can be implemented on NOR FLASH, for QSPI with WInbond, and others, I'd go with a 4KB sector as that works well with FAT / FATFS implementation, and is the minimum erase size on these QSPI NOR FLASH devices. I've built examples for clients, and could port to any of the supported STM32 families.

I've also built a lot of assorted External Loaders for different chips, and board level pin configurations.

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

Thanks for your response Tesla.  I was able to get it to work.

I will elaborate on how I approached it for those that might face a similar situation. The generated OSPI driver for LevelX NOR does support some customization in a header file but is hard coded in other places to assume an OSPI memory using 16 bit commands.  I was able to use this as a starting point and adapt the implementation to work with a quad memory and adapt to the specifics of the Winbond W25Q128JV memory. I had to modify parts of the code that are auto generated so be sure to take steps to make sure your work is not erased with the next auto generation. My changes were primarily in lx_stm32_qspi_driver_glue.c. I will adapt it to be used as a custom LevelX NOR interface when I finish up so it becomes auto generation safe again.

Something worth noting.  The ST provided driver uses busy waiting for completion which seems power inefficient and not the best for a threaded operating system like Azure RTOS.  Sector erases can take 10's of milliseconds and a whole chip erase is a typical 20 seconds for this chip.  So that would be a bunch of wasted processor cycles.  So I created an implementation that uses a combination so sleeping for part of the long delay and then autopolling with a match interrupt.  I realize there are a number of messages cautioning against using autopolling but it is working well my situation thus far.  The match interrupt sets a semaphore.  I use the timer on a semaphore for the error timeout and then will abort the auto polling if it times out.  If I get a timeout, something pretty bad has probably happened anyway.

A side note on Azure RTOS timeouts. Calling the semaphore with a 1 tick timeout gives a timeout ~0 to 10mS.  The page programing is a maximum 3mS so the timeout was sometimes happening too soon.  Since it was for an error condition, I set the minimum timeout ticks to 2 ticks which will give me a 10 to 20mS time out.  Since this is an unlikely error condition, the longer time doesn't impact execution.

I actually found the OSPI one of the easier peripherals to work with and the HAL straight forward.  I did notice something interesting when I looked at the interface with a logic analyzer.  When doing the command and data read of the status register directly, the data phase was clocked for 8 bits as specified.  But when the same setup was used for autopolling, the data phase was clocked for 16 cycles.  The requested 8 bits of status data showed up in the OSPI data register and the comparison was as expected.  The extra 8 bits just seemed odd but had no effect on my situation.