Zephyr 3.7.0 spi_nor driver assumes 3-byte mode when querying for SFDP #82511
Unanswered
thavelka-cornell
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello Zephyr Team,
I am working on a work related project using Zephyr 3.7.0 LTS, targeting an NXP LPC family MCU. We recently changed an external SPI NOR flash device from a 16MB part to a 32MB part. Now I observe that our application from a cold unpowered start up detects the flash the first time. On successive warm starts, e.g. MCU resets, external flash initialization fails.
The failure at the application level occurs with the call to Zephyr's
device_is_ready()
, to which we pass ourstruct device* flash_dev
pointer.Probing with a Saleae logic analyzer on the SPI bus signals between MCU and flash part reveals that on cold start up, a query for SFDP succeeds as both MCU and flash part are operating in 3-byte mode. The "read SFDP" call happens twice, first with offset 0x000000, then soon after with offset 0x000300. A final single byte command is then sent to put the flash chip into 4-byte addressing modes.
If we had a simple single application, this first power up and run session would work. But we happen to have a secondary bootloader / update manager which runs briefly and then passes control to the start address of a larger separate application. That application is also a Zephyr app which calls the same SPI NOR flash driver to init the flash.
At this run time point the external flash device is now in 4-byte mode, but routine spi_nor_process_sfdp()
at
https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/flash/spi_nor.c#L1135 appears to assume a 3-byte addressing mode. This results in a leading byte coming back in the SFDP data read. The leading byte corrupts the data, and the external flash device does not properly initialize.Now it is possible I have missed a Kconfig setting or similar. While I cannot share all the details of my work related work, I can share the following:
In our design we have an external flash part by Infineon. It is a 32MB SPI NOR flash device with JEDEC ID 0x01 0x60 0x19.
Our application Kconfig settings which relate to SPI and FLASH are, filtered from our application
prj.conf
:CONFIG_SPI=y
CONFIG_SPI_NOR=y
CONFIG_SPI_NOR_SFDP_RUNTIME=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_JESD216_API=y
In a local patch I applied to spi_nor.c I was able to force our external flash part into 3-byte addressing mode near the end of https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/flash/spi_nor.c#L1615, and this solves our problem at least superficially. We can now run our application with secondary bootloader preceding it. We can also actuate the MCU reset line for warm reboots, and flash initialization now works for both power cyclings and warm starts.
Question 1: is spi_nor.c by design making the unconditional call to assume 3-byte addressing mode for JEDEC flash devices which support 3-byte and 4-byte addressing modes?
Question 2: are there Zephyr or SPI NOR configuration flags we can set to overcome this "warm start 4-byte addressing" problem?
The second question goes to how we may best overcome this problem given that we want to use Zephyr 3.7.0 LTS as our RTOS and SDK, without forking or modifying its sources. This supports a small team effort which also entails building with Zephyr's Docker image project, to ease build reproducibility. That container use piece is a big motivation for avoiding changes which complicate our container configurations for project builds.
If by chance this is a driver bug I would be happy to lend a hand fixing it. There would be a bit of a learning curve, and I make no assumption that the "exit 4-byte address mode" command supported by Infineon's S25FL256L flash device is widely supported across other flash part families. But I would like to find the most appropriate solution to this issue.
I don't have this particular JEDEC flash device on a Click board or breakout board, so I'm not able to quickly put together a demo app for a dev board. But I can share code excerpts from an extended "hello world" sample app which calls relevant SPI NOR APIs to reproduce this issue.
Beta Was this translation helpful? Give feedback.
All reactions