nRF5340 and W25Q512NW Nor Flash R/W problem?

Hello,

I am using W25Q512NW (https://www.winbond.com/resource-files/W25Q512NW%20RevB%2007192021.pdf) in my custom board. I want to store the sensor data in this flash.

My custom board use the nRF5340 MCU and the version of the nrf connect sdk is V2.5.2.

the problem i am facing that i am not able to read the data from the flash.

 

*** Booting nRF Connect SDK v2.5.2 ***
[00:00:00.252,868] <inf> main: iMedrix External flash Application Started.

Device name: w25q512nw@0
Data written. Good!!
23 22 33 44 55 66 77 88 
Data read. Good!!
FF FF FF FF FF FF FF FF 
Data not matched..!!
JEDEC ID : EF  60  20 

In above log, i am writing 8 bytes and also read those 8 bytes. but when i read data from the flash i am getting only FF. 
And when i read the JEDEC id of the flash, i am getting right JEDEC id.

Here is the prj.conf file.

# Logger module
CONFIG_USE_SEGGER_RTT=y
CONFIG_RTT_CONSOLE=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG=y
CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_SPEED=y
CONFIG_UART_CONSOLE=n

CONFIG_DEBUG=y


# spi Configuration
CONFIG_SPI=y

#External flash configuration
CONFIG_FLASH=y
CONFIG_FLASH_JESD216_API=y
CONFIG_FLASH_PAGE_LAYOUT=y


CONFIG_NEWLIB_LIBC=y

Here is the .overlay file below.

 

&qspi {
	status = "okay";
	pinctrl-0 = <&qspi_default>;
	pinctrl-1 = <&qspi_sleep>;
	pinctrl-names = "default", "sleep";
	w25q512: w25q512nw@0 {
		compatible = "nordic,qspi-nor";
		reg = <0>;
		/* MX25R64 supports only pp and pp4io */
		writeoc = "pp4io";
		// writeoc = "pp4o";
		/* MX25R64 supports all readoc options */
		readoc = "read4io";
		sck-frequency = <8000000>;
		// jedec-id = [c2 28 17];
		jedec-id = [EF 60 20];
		sfdp-bfp = [
  			e5 20 fb ff  ff ff ff 1f  44 eb 08 6b  08 3b 42 bb
  			fe ff ff ff  ff ff 00 00  ff ff 40 eb  0c 20 0f 52
  			10 d8 00 00  33 02 a6 00  81 e7 14 d9  e9 63 76 33
  			7a 75 7a 75  f7 bd d5 5c  19 f7 5d ff  e9 70 f9 a5
  		];
		size = <536870912>;
		// address-size-32;
		has-dpd;
		// t-enter-dpd = <10000>;
		// t-exit-dpd = <35000>;
		t-enter-dpd = <3000>;
		t-exit-dpd = <30000>;
	};
};

Please give me your suggestion in this.  

Let me know if any modification is required.

Thank you in advance.

Gautam.

  • Hi

    It seems you're just reading empty data from what I can see here, so can you confirm that you're reading the same addresses as you're writing to in your application? What driver APIs and functions are you using for reading and writing to the external flash exactly here?

    Best regards,

    Simon

  • Hello  ,

    Thanks for the ans.

    so can you confirm that you're reading the same addresses as you're writing to in your application? 

    Yes,   i already confirm that i reading the same addresses as I writing to in my application.

    - I am using flash API.

    /* auto-generated by gen_syscalls.py, don't edit */
    
    #ifndef Z_INCLUDE_SYSCALLS_FLASH_H
    #define Z_INCLUDE_SYSCALLS_FLASH_H
    
    
    #include <zephyr/tracing/tracing_syscall.h>
    
    #ifndef _ASMLANGUAGE
    
    #include <stdarg.h>
    
    #include <syscall_list.h>
    #include <zephyr/syscall.h>
    
    #include <zephyr/linker/sections.h>
    
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    extern int z_impl_flash_read(const struct device * dev, off_t offset, void * data, size_t len);
    
    __pinned_func
    static inline int flash_read(const struct device * dev, off_t offset, void * data, size_t len)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; off_t val; } parm1 = { .val = offset };
    		union { uintptr_t x; void * val; } parm2 = { .val = data };
    		union { uintptr_t x; size_t val; } parm3 = { .val = len };
    		return (int) arch_syscall_invoke4(parm0.x, parm1.x, parm2.x, parm3.x, K_SYSCALL_FLASH_READ);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_read(dev, offset, data, len);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_read(dev, offset, data, len) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_READ, flash_read, dev, offset, data, len); 	syscall__retval = flash_read(dev, offset, data, len); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_READ, flash_read, dev, offset, data, len, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_write(const struct device * dev, off_t offset, const void * data, size_t len);
    
    __pinned_func
    static inline int flash_write(const struct device * dev, off_t offset, const void * data, size_t len)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; off_t val; } parm1 = { .val = offset };
    		union { uintptr_t x; const void * val; } parm2 = { .val = data };
    		union { uintptr_t x; size_t val; } parm3 = { .val = len };
    		return (int) arch_syscall_invoke4(parm0.x, parm1.x, parm2.x, parm3.x, K_SYSCALL_FLASH_WRITE);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_write(dev, offset, data, len);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_write(dev, offset, data, len) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_WRITE, flash_write, dev, offset, data, len); 	syscall__retval = flash_write(dev, offset, data, len); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_WRITE, flash_write, dev, offset, data, len, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_erase(const struct device * dev, off_t offset, size_t size);
    
    __pinned_func
    static inline int flash_erase(const struct device * dev, off_t offset, size_t size)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; off_t val; } parm1 = { .val = offset };
    		union { uintptr_t x; size_t val; } parm2 = { .val = size };
    		return (int) arch_syscall_invoke3(parm0.x, parm1.x, parm2.x, K_SYSCALL_FLASH_ERASE);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_erase(dev, offset, size);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_erase(dev, offset, size) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_ERASE, flash_erase, dev, offset, size); 	syscall__retval = flash_erase(dev, offset, size); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_ERASE, flash_erase, dev, offset, size, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_get_page_info_by_offs(const struct device * dev, off_t offset, struct flash_pages_info * info);
    
    __pinned_func
    static inline int flash_get_page_info_by_offs(const struct device * dev, off_t offset, struct flash_pages_info * info)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; off_t val; } parm1 = { .val = offset };
    		union { uintptr_t x; struct flash_pages_info * val; } parm2 = { .val = info };
    		return (int) arch_syscall_invoke3(parm0.x, parm1.x, parm2.x, K_SYSCALL_FLASH_GET_PAGE_INFO_BY_OFFS);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_get_page_info_by_offs(dev, offset, info);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_get_page_info_by_offs(dev, offset, info) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_GET_PAGE_INFO_BY_OFFS, flash_get_page_info_by_offs, dev, offset, info); 	syscall__retval = flash_get_page_info_by_offs(dev, offset, info); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_GET_PAGE_INFO_BY_OFFS, flash_get_page_info_by_offs, dev, offset, info, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_get_page_info_by_idx(const struct device * dev, uint32_t page_index, struct flash_pages_info * info);
    
    __pinned_func
    static inline int flash_get_page_info_by_idx(const struct device * dev, uint32_t page_index, struct flash_pages_info * info)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; uint32_t val; } parm1 = { .val = page_index };
    		union { uintptr_t x; struct flash_pages_info * val; } parm2 = { .val = info };
    		return (int) arch_syscall_invoke3(parm0.x, parm1.x, parm2.x, K_SYSCALL_FLASH_GET_PAGE_INFO_BY_IDX);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_get_page_info_by_idx(dev, page_index, info);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_get_page_info_by_idx(dev, page_index, info) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_GET_PAGE_INFO_BY_IDX, flash_get_page_info_by_idx, dev, page_index, info); 	syscall__retval = flash_get_page_info_by_idx(dev, page_index, info); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_GET_PAGE_INFO_BY_IDX, flash_get_page_info_by_idx, dev, page_index, info, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern size_t z_impl_flash_get_page_count(const struct device * dev);
    
    __pinned_func
    static inline size_t flash_get_page_count(const struct device * dev)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		return (size_t) arch_syscall_invoke1(parm0.x, K_SYSCALL_FLASH_GET_PAGE_COUNT);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_get_page_count(dev);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_get_page_count(dev) ({ 	size_t syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_GET_PAGE_COUNT, flash_get_page_count, dev); 	syscall__retval = flash_get_page_count(dev); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_GET_PAGE_COUNT, flash_get_page_count, dev, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_sfdp_read(const struct device * dev, off_t offset, void * data, size_t len);
    
    __pinned_func
    static inline int flash_sfdp_read(const struct device * dev, off_t offset, void * data, size_t len)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; off_t val; } parm1 = { .val = offset };
    		union { uintptr_t x; void * val; } parm2 = { .val = data };
    		union { uintptr_t x; size_t val; } parm3 = { .val = len };
    		return (int) arch_syscall_invoke4(parm0.x, parm1.x, parm2.x, parm3.x, K_SYSCALL_FLASH_SFDP_READ);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_sfdp_read(dev, offset, data, len);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_sfdp_read(dev, offset, data, len) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_SFDP_READ, flash_sfdp_read, dev, offset, data, len); 	syscall__retval = flash_sfdp_read(dev, offset, data, len); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_SFDP_READ, flash_sfdp_read, dev, offset, data, len, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_read_jedec_id(const struct device * dev, uint8_t * id);
    
    __pinned_func
    static inline int flash_read_jedec_id(const struct device * dev, uint8_t * id)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; uint8_t * val; } parm1 = { .val = id };
    		return (int) arch_syscall_invoke2(parm0.x, parm1.x, K_SYSCALL_FLASH_READ_JEDEC_ID);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_read_jedec_id(dev, id);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_read_jedec_id(dev, id) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_READ_JEDEC_ID, flash_read_jedec_id, dev, id); 	syscall__retval = flash_read_jedec_id(dev, id); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_READ_JEDEC_ID, flash_read_jedec_id, dev, id, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern size_t z_impl_flash_get_write_block_size(const struct device * dev);
    
    __pinned_func
    static inline size_t flash_get_write_block_size(const struct device * dev)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		return (size_t) arch_syscall_invoke1(parm0.x, K_SYSCALL_FLASH_GET_WRITE_BLOCK_SIZE);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_get_write_block_size(dev);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_get_write_block_size(dev) ({ 	size_t syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_GET_WRITE_BLOCK_SIZE, flash_get_write_block_size, dev); 	syscall__retval = flash_get_write_block_size(dev); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_GET_WRITE_BLOCK_SIZE, flash_get_write_block_size, dev, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern const struct flash_parameters * z_impl_flash_get_parameters(const struct device * dev);
    
    __pinned_func
    static inline const struct flash_parameters * flash_get_parameters(const struct device * dev)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		return (const struct flash_parameters *) arch_syscall_invoke1(parm0.x, K_SYSCALL_FLASH_GET_PARAMETERS);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_get_parameters(dev);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_get_parameters(dev) ({ 	const struct flash_parameters * syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_GET_PARAMETERS, flash_get_parameters, dev); 	syscall__retval = flash_get_parameters(dev); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_GET_PARAMETERS, flash_get_parameters, dev, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    extern int z_impl_flash_ex_op(const struct device * dev, uint16_t code, const uintptr_t in, void * out);
    
    __pinned_func
    static inline int flash_ex_op(const struct device * dev, uint16_t code, const uintptr_t in, void * out)
    {
    #ifdef CONFIG_USERSPACE
    	if (z_syscall_trap()) {
    		union { uintptr_t x; const struct device * val; } parm0 = { .val = dev };
    		union { uintptr_t x; uint16_t val; } parm1 = { .val = code };
    		union { uintptr_t x; const uintptr_t val; } parm2 = { .val = in };
    		union { uintptr_t x; void * val; } parm3 = { .val = out };
    		return (int) arch_syscall_invoke4(parm0.x, parm1.x, parm2.x, parm3.x, K_SYSCALL_FLASH_EX_OP);
    	}
    #endif
    	compiler_barrier();
    	return z_impl_flash_ex_op(dev, code, in, out);
    }
    
    #if defined(CONFIG_TRACING_SYSCALL)
    #ifndef DISABLE_SYSCALL_TRACING
    
    #define flash_ex_op(dev, code, in, out) ({ 	int syscall__retval; 	sys_port_trace_syscall_enter(K_SYSCALL_FLASH_EX_OP, flash_ex_op, dev, code, in, out); 	syscall__retval = flash_ex_op(dev, code, in, out); 	sys_port_trace_syscall_exit(K_SYSCALL_FLASH_EX_OP, flash_ex_op, dev, code, in, out, syscall__retval); 	syscall__retval; })
    #endif
    #endif
    
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    #endif /* include guard */
    

  • Hi

    What API is this exactly? Does it support QSPI, because I think the nrfx_qspi driver should be used for this instead of a generic flash API. I don't see any mentions of QSPI here in the snippet you uploaded.

    Best regards,

    Simon

  • Hi,

    I follow the QSPI Example given in the NRF Connect SDK which is spi_flash (https://github.com/nrfconnect/sdk-zephyr/tree/main/samples/drivers/spi_flash).

    T
    his example works good with the external flash (MX25R6435F) which is placed on nRF5340DK.

    I use the API for qspi which is used in above example code.

    And also I interface my external flash using QSPI with the nrf52840 and nrf5 SDK, And there also result is same.

    Thanks & Regards

    Gautam

  • Hi

    Hmm, okay. What pins are you using for QSPI on your custom nRF5340 board here. How exactly are the nRF5340 and W25Q512NW flash connected here, and what voltage are you supplying the nRF5340 and external flash device wtih.

    Best regards,

    Simon

Related