9160dk external flash operation address length issue

The default setting for the external flash chip of 9160dk appears to be 64m, but when used, the log display only shows 8m, and only the part within 8m can be used,

mx25r64: mx25r6435f@1 {
		compatible = "jedec,spi-nor";
		status = "disabled";
		reg = <1>; 
		spi-max-frequency = <8000000>;
		jedec-id = [c2 28 17];
		sfdp-bfp = [
			e5 20 f1 ff  ff ff ff 03  44 eb 08 6b  08 3b 04 bb
			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 48 44
			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
		];
		size = <67108864>;
		has-dpd;
		t-enter-dpd = <10000>;
		t-exit-dpd = <35000>;
	};
	
	<inf> spi_nor: mx25r6435f@1: 8 MiBy flash

Then I set the chip size to 8 times that of 64m in order to use all 64m of flash properly

&mx25r64 {
    status = "okay";
	size = <0x20000000>;
    sfdp-bfp = [
			e5 20 f1 ff  ff ff ff 1f  44 eb 08 6b  08 3b 04 bb
			ee ff ff ff  ff ff 00 ff  ff ff 00 ff  0c 20 0f 52
			10 d8 00 ff  23 72 f5 00  82 ed 04 cc  44 83 48 44
			30 b0 30 b0  f7 c4 d5 5c  00 be 29 ff  f0 d0 ff ff
		];
};

<inf> spi_nor: mx25r6435f@1: 64 MiBy flash

But when I want to read and write data in the 16-64m area (i.e. the address exceeds 3 bytes), it cannot correctly recognize the 4-byte address, but instead truncates the lower 24 bits as the address for reading and writing, resulting in the actual read and write address being different from the one I want to read and write,just like this

char test_data[20];
memset(test_data, 0, sizeof(test_data));
strcpy(test_data, "aaabbbccdd987");

flash_write(flash_dev, 0x1800012, test_data, sizeof(test_data));

I found several variables related to 4-byte addresses in spi_nor.c, but did not find where the problem lies

Parents
  • Hi llly,

    Why are you using the Flash Driver directly instead of a higher layer module/subsystem, such as Settings or NVS?

    Could you please run the Partition Manager report and share the result?

    Please also share the compiled Kconfig file (<build folder>/zephyr/.config).

    Hieu

  • Hi Hieu

    I am currently debugging the external flash in order to use other external flash chips on our product. I thought using the flash driver directly would also work properly.

    This is the partition report and config file

    .config.rar

    What you said about NVS, I took a look and it's a file system similar to LFS, right? If I use NVS, I should mount it to an external flash and use NVS just like using LFS, so I don't need to use a flash driver, right?

  • I have a new discovery.

    After loading LFS from an external flash, I used a logic analyzer to capture SPI data and printed SPI addresses through serial ports in the code. Upon comparison, I found that the addresses in the code were 4 bytes, but the SPI data still showed 3 bytes. It seems that even with the use of a file system, there is still an address length issue

  • I have determined that the issue comes from loading the external flash device's capability into the driver.

    I am honestly not an expert in it, and this is just my rough understanding. I will try to only write about what I am relatively sure of, but I hope you can help me test something to see if it works.

    The external flash capability is stored in Serial Flash Discoverable Parameters (SFDP). There are two Kconfigs that are relevant to the way the flash driver loads the SFDP: CONFIG_FLASH_JESD216_API and CONFIG_SPI_NOR_SFDP.

    CONFIG_FLASH_JESD216_API enable some Flash APIs, one of which is flash_sfdp_read(). It loads the SFDP from the external flash device when called. By default, this is disabled.
    --> Solution 1: enable CONFIG_FLASH_JESD216_API and call flash_sfdp_read() during initialization.


    As for CONFIG_SPI_NOR_SFDP, by default, it is set to CONFIG_SPI_NOR_SFDP_MINIMAL, synthesize a SFDP based on just the jedec-id and size property of the external flash node on the Devicetree (DT). However, this also defaults the flash address mode to 24-bit, and expects that if 32-bit is needed, then the external flash node has to have the property enter-4byte-addr set properly. I haven't looked into how the value should be derived though...

    --> Solution 2: set the enter-4byte-addr property in the external flash node.


    CONFIG_SPI_NOR_SFDP can also be set to CONFIG_SPI_NOR_SFDP_DEVICETREE, which loads the SFDP from the sfdp-bfp of the external flash DT node. This property is already set for the external flash on the nRF9160 DK board file, so it should work.

    --> Solution 3: Disable CONFIG_SPI_NOR_SFDP_MINIMAL and enable CONFIG_SPI_NOR_SFDP_DEVICETREE.


    Finally, CONFIG_SPI_NOR_SFDP can also be set to CONFIG_SPI_NOR_SFDP_RUNTIME, which loads SFDP from the external flash device itself during runtime. 

    --> Solution 4Disable CONFIG_SPI_NOR_SFDP_MINIMAL and enable CONFIG_SPI_NOR_SFDP_RUNTIME.

    I realize that I am violating the Occam's Razor principle a lot here, but I figure the information might come in handy eventually for readers with different external flash device, and another reason is that I couldn't test any of them at the moment.

    Please consider which solution best suit you.

    Hieu

  • Hi Hieu

    I am currently using Solution 3, and I have tested Solution 4. The information it reads from the flash shows that it is an 8m flash, so I cannot test the 4-byte address. For Solution 2, I couldn't find a way to set a 4-byte address. For Solution 1, I did not conduct any testing and I believe the result should be the same as Solution 4.

    I think Solution 4 is the most convenient solution because it directly reads information from the flash, and replacing the flash chip does not require much modification. But I don't know why the code in spi_nor. c sets the flash size to one eighth of the read size. The flash on 9160dk has 64m, but can only use 8m. I connected a 32m flash externally, which shows that only 4m can be used

  • Hi llly,

    Interesting findings. Were you able to capture what the external flash device sent back to the nRF9160? In particular, is the SFDP data the same as the sfdp-bfp property in the Devicetree?

    It might be necessary to raise this issue on the Zephyr RTOS GitHub repository, because this part of the SDK is inherited from Zephyr and not NCS specific.

  • Hi Hieu

    This is the BFP parameter I printed out, and you can see that it is exactly the same as the one in the device tree

    Can you help me ask them how to solve this problem?

Reply Children
No Data
Related