Giter VIP home page Giter VIP logo

w25qxx's Introduction

English | 简体中文 | 繁體中文 | 日本語 | Deutsch | 한국어

LibDriver W25QXX

MISRA API License

The W25Q25XX Serial Flash memory provides a storage solution for systems with limited space, pins and power. The 25Q series offers flexibility and performance well beyond ordinary Serial Flash devices. They are ideal for code shadowing to RAM, executing code directly from Dual/Quad SPI (XIP) and storing voice, text and data. The device operates on a single 2.7V to 3.6V power supply with current consumption as low as 4mA active and 1μA for power-down. All devices are offered in space-saving packages.

LibDriver W25QXX is the full function driver of W25QXX launched by LibDriver.It provides functions of flash reading,flash writing, etc. LibDriver is MISRA compliant.

Table of Contents

Instruction

/src includes LibDriver W25QXX source files.

/interface includes LibDriver W25QXX SPI or QSPI platform independent template.

/test includes LibDriver W25QXX driver test code and this code can test the chip necessary function simply.

/example includes LibDriver W25QXX sample code.

/doc includes LibDriver W25QXX offline document.

/datasheet includes W25QXX datasheet.

/project includes the common Linux and MCU development board sample code. All projects use the shell script to debug the driver and the detail instruction can be found in each project's README.md.

/misra includes the LibDriver MISRA code scanning results.

Install

Reference /interface SPI or QSPI platform independent template and finish your platform SPI or QSPI driver.

Add the /src directory, the interface driver for your platform, and your own drivers to your project, if you want to use the default example drivers, add the /example directory to your project.

Usage

You can refer to the examples in the /example directory to complete your own driver. If you want to use the default programming examples, here's how to use them.

example basic

#include "driver_w25qxx_basic.h"

uint8_t res;
uint8_t manufacturer;
uint8_t device_id;
uint8_t data[8];

res = w25qxx_basic_init(W25Q128, W25QXX_INTERFACE_SPI, W25QXX_BOOL_TRUE);
if (res != 0)
{
    return 1;
}

...
    
res = w25qxx_basic_get_id((uint8_t *)&manufacturer, (uint8_t *)&device_id);
if (res != 0)
{
    (void)w25qxx_basic_deinit();
    
    return 1;
}
w25qxx_interface_debug_print("w25qxx: manufacturer is 0x%02X device id is 0x%02X.\n", manufacturer, device_id);
    
...    
    
res = w25qxx_basic_write(0x00000000, (uint8_t *)data, 8);
if (res != 0)
{
    (void)w25qxx_basic_deinit();
    
    return 1;
}

...

res = w25qxx_basic_read(0x00000000, (uint8_t *)data, 8);
if (res != 0)
{
    (void)w25qxx_basic_deinit();
    
    return 1;
}

...
    
(void)w25qxx_basic_deinit();

return 0;

example advance

#include "driver_w25qxx_advance.h"

uint8_t res;
uint8_t manufacturer;
uint8_t device_id;
uint8_t data[8];

res = w25qxx_advance_init(W25Q128, W25QXX_INTERFACE_SPI, W25QXX_BOOL_TRUE);
if (res != 0)
{
    return 1;
}

...
    
res = w25qxx_advance_get_id((uint8_t *)&manufacturer, (uint8_t *)&device_id);
if (res != 0)
{
    (void)w25qxx_advance_deinit();
    
    return 1;
}
w25qxx_interface_debug_print("w25qxx: manufacturer is 0x%02X device id is 0x%02X.\n", manufacturer, device_id);
    
...    
    
res = w25qxx_advance_write(0x00000000, (uint8_t *)data, 8);
if (res != 0)
{
    (void)w25qxx_advance_deinit();
    
    return 1;
}

...

res = w25qxx_advance_read(0x00000000, (uint8_t *)data, 8);
if (res != 0)
{
    (void)w25qxx_advance_deinit();
    
    return 1;
}

...
    
(void)w25qxx_advance_deinit();

return 0;

Document

Online documents: https://www.libdriver.com/docs/w25qxx/index.html.

Offline documents: /doc/html/index.html.

Contributing

Please refer to CONTRIBUTING.md.

License

Copyright (c) 2015 - present LibDriver All rights reserved

The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy

of this software and associated documentation files (the "Software"), to deal

in the Software without restriction, including without limitation the rights

to use, copy, modify, merge, publish, distribute, sublicense, and/or sell

copies of the Software, and to permit persons to whom the Software is

furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all

copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE

AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

SOFTWARE.

Contact Us

Please sent an e-mail to [email protected].

w25qxx's People

Contributors

libdriver avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

w25qxx's Issues

What is the difference between W25QXX_INTERFACE_SPI and W25QXX_INTERFACE_QSPI

Please ask your question

Machine translated into English, if you can understand, please read the last Chinese directly :).
It's a great project.
What do the combinations of dual_quad_spi_enable and spi_qspi mean?
I'm using the Microchip code generation tool to generate the qspi code for SAMD51P20A(arm M4) like this:
plib_qspi.zip

my w25qxx_handle_t.spi_qspi_write_read like this

uint8_t w25qxx_spi_qspi_write_read(uint8_t instruction, uint8_t instruction_line,
uint32_t address, uint8_t address_line, uint8_t address_len,
uint32_t alternate, uint8_t alternate_line, uint8_t alternate_len,
uint8_t dummy, uint8_t *in_buf, uint32_t in_len,
uint8_t *out_buf, uint32_t out_len, uint8_t data_line)
{
	QSPI_LANE_WIDTH width = SINGLE_BIT_SPI; 
	QSPI_ADDRESS_LENGTH addr_len = address_len == 4?ADDRL_32_BIT:ADDRL_24_BIT;
	QSPI_OPTION_LENGTH option_len = 0;
	
	if(instruction_line == 4) width = QUAD_CMD; /* (QSPI_INSTRFRAME) Instruction: Quad SPI / Address-Option: Quad SPI / Data: Quad SPI Position  */
	else if(instruction_line == 2) width = DUAL_CMD; /* (QSPI_INSTRFRAME) Instruction: Dual SPI / Address-Option: Dual SPI / Data: Dual SPI Position  */
	else if(address_line == 4) width = QUAD_IO; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Quad SPI / Data: Quad SPI Position  */
	else if(address_line == 2) width = DUAL_IO; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Dual SPI / Data: Dual SPI Position  */
	else if(data_line == 4) width = QUAD_OUTPUT; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Single-bit SPI / Data: Quad SPI Position  */
	else if(data_line == 2) width = DUAL_OUTPUT; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Single-bit SPI / Data: Dual SPI Position  */
	else width = SINGLE_BIT_SPI; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Single-bit SPI / Data: Single-bit SPI Position  */

	if(alternate_len == 1) option_len = OPTL_1_BIT;
	else if(alternate_len == 2) option_len = OPTL_2_BIT;
	else if(alternate_len == 4) option_len = OPTL_4_BIT;
	else if(alternate_len == 8) option_len = OPTL_8_BIT;
	else option_len = 0;
	
	if(out_buf == NULL && in_buf == NULL)
	{
		qspi_command_xfer_t qspi_command_xfer;
		qspi_command_xfer.instruction = instruction;
		qspi_command_xfer.width = width;
		qspi_command_xfer.addr_len = addr_len;
		qspi_command_xfer.addr_en = address_len != 0;
		return (uint8_t)!QSPI_CommandWrite(&qspi_command_xfer,address);
	}
	if(out_buf != NULL && address_len == 0)
	{
		qspi_register_xfer_t qspi_register_xfer;
		qspi_register_xfer.instruction = instruction;
		qspi_register_xfer.dummy_cycles = dummy;
		qspi_register_xfer.width = width;
		return (uint8_t)!QSPI_RegisterRead(&qspi_register_xfer,(uint32_t*)out_buf,(uint8_t)out_len);
	}
	if(in_buf != NULL && address_len == 0)
	{
		qspi_register_xfer_t qspi_register_xfer;
		qspi_register_xfer.instruction = instruction;
		qspi_register_xfer.dummy_cycles = dummy;
		qspi_register_xfer.width = width;
		return (uint8_t)!QSPI_RegisterWrite(&qspi_register_xfer,(uint32_t*)in_buf,(uint8_t)in_len);
	}
	
	if(out_buf != NULL && address_len != 0)
	{
		qspi_memory_xfer_t qspi_memory_xfer;
		qspi_memory_xfer.instruction = instruction;
		qspi_memory_xfer.dummy_cycles = dummy;
		qspi_memory_xfer.width = width;
		qspi_memory_xfer.addr_len = addr_len;
		qspi_memory_xfer.option = alternate;
		qspi_memory_xfer.option_en = alternate_len != 0;
		qspi_memory_xfer.option_len = option_len;
		return (uint8_t)!QSPI_MemoryRead(&qspi_memory_xfer,(uint32_t*)out_buf,out_len,address);
	}
	if(in_buf != NULL && address_len != 0)
	{
		qspi_memory_xfer_t qspi_memory_xfer;
		qspi_memory_xfer.instruction = instruction;
		qspi_memory_xfer.dummy_cycles = dummy;
		qspi_memory_xfer.width = width;
		qspi_memory_xfer.addr_len = addr_len;
		qspi_memory_xfer.option = alternate;
		qspi_memory_xfer.option_en = alternate_len != 0;
		qspi_memory_xfer.option_len = option_len;
		return (uint8_t)!QSPI_MemoryWrite(&qspi_memory_xfer,(uint32_t*)in_buf,in_len,address);
	}
	return 1;
}

Do you want to achieve a QSPI_LANE_WIDTH like function through a combination of dual_quad_spi_enable and spi_qspi?
If so, can we use the combination of instruction_line , address_len, data_line to switch spi, dspi, qspi in spi_qspi_write_read, because now there are basically three sets of branch codes for switching spi, dspi, and qspi in each function, if they are unified in spi_qspi_write_read switching, Will the compiled binary be more streamlined?
If there is a deviation in my understanding, please correct it, thank you.

机翻英文比较拉跨,补充中文
很棒的项目,啊哈:)
代码中的 dual_quad_spi_enablespi_qspi 的组合怎么理解?
我使用的是Microchip的代码生成器为SAMD51P20A(arm M4)生成的qspi代码,详见上文 附件压缩包plib_qspi.zip。
然后我实现的 w25qxx_handle_t.spi_qspi_write_read 详见上文代码。
你是想通过 dual_quad_spi_enablespi_qspi 的组合来实现类似 QSPI_LANE_WIDTH 的功能吗?
如果是这样,我们是不是可以通过 instruction_line ,address_len, data_line 的组合统一在 spi_qspi_write_read 切换 spi,dspi,qspi, 因为现在每个函数中基本都有三套切换spi,dspi,qspi的分支代码,如果统一在 spi_qspi_write_read 切换,编译之后的二进制是不是会更精简?
如果我理解的有偏差,欢迎指正,谢谢。

Additional context

关键是这里, 我把plib_qspi的注释抄过来了。

	if(instruction_line == 4) width = QUAD_CMD; /* (QSPI_INSTRFRAME) Instruction: Quad SPI / Address-Option: Quad SPI / Data: Quad SPI Position  */
	else if(instruction_line == 2) width = DUAL_CMD; /* (QSPI_INSTRFRAME) Instruction: Dual SPI / Address-Option: Dual SPI / Data: Dual SPI Position  */
	else if(address_line == 4) width = QUAD_IO; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Quad SPI / Data: Quad SPI Position  */
	else if(address_line == 2) width = DUAL_IO; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Dual SPI / Data: Dual SPI Position  */
	else if(data_line == 4) width = QUAD_OUTPUT; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Single-bit SPI / Data: Quad SPI Position  */
	else if(data_line == 2) width = DUAL_OUTPUT; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Single-bit SPI / Data: Dual SPI Position  */
	else width = SINGLE_BIT_SPI; /* (QSPI_INSTRFRAME) Instruction: Single-bit SPI / Address-Option: Single-bit SPI / Data: Single-bit SPI Position  */

Generate tagfile in doxygen

Is your feature request related to a problem? Please describe.

When including the doxygen documentation for this project into my own project the sidebar and header of my html pages are populated with the docs from this driver.

I want to be able to link to the docs for this driver from my own docs without filling up my sidebar with doc links from my submodules.

Describe the idea you'd like

Generate a Tagfile.
See: Linking to external documentation

So I can link to the driver docs without including all off the links.

Describe alternatives you've considered

No response

Additional context

No response

Portability improvements

Is your feature request related to a problem? Please describe.

No response

Describe the idea you'd like

Hello! I think it would be useful to pass a customizable user handle like void* const hwHandle to all SPI interface functions declared in driver_w25qxx_interface.h. This pointer should be assigned by a setter in w25qxx_handle_t structure like that
uint8_t w25qxx_set_hw_handle(w25qxx_handle_t *handle, void *hwHandle). A getter
uint8_t w25qxx_get_hw_handle(w25qxx_handle_t *handle, void **hwHandle) may be useful, too.
image

Rationale: modern MCUs may have several SPI/QSPI hardware interfaces. In this handle approach, we can assign the particular SPI interface to the device. We may simultaneously have several w25qxx devices on the same bus and/or on different buses.
In my opinion, this approach can lead to the significant improvement of the device driver portability for different platforms, because all MCUs chip vendors have incompatible CSP

Describe alternatives you've considered

No response

Additional context

No response

security_register functions Address mode 3 byte, why the register address get's left shifted?

Please ask your question

Hello, I'm using a W25q16 chip and the read test is failing on the security registers test.
In the security_register functions (w25qxx_program_security_register, w25qxx_read_security_register, w25qxx_erase_security_register, etc) when using the quad spi in dula line (handle->spi_qspi == W25QXX_INTERFACE_SPI && handle->dual_quad_spi_enable != 0) the register's addresses are left shifted by 8 bits. This causes the QUAD SPI (on my stm32l475) to set the TEF flag ( Transfer error flag.This bit is set in indirect mode when an invalid address is being accessed in indirect mode).
The failure occurs on registers 2 (W25QXX_SECURITY_REGISTER_2 = 0x2000) and 3 (W25QXX_SECURITY_REGISTER_3 = 0x3000) since the addresses (being shifted) are out of bounds (Valid Address Range: 0x000000 to 0x1FFFFF for a 16 Megabit flash memory).
Can you please provide some explanation ?
Best regards

Additional context

No response

Unlock and Lock

Please ask your question

Hello, Thank you for your works in generic drivers.
I have a question. Why don't we add unlock and lock operation in drivers to ensure mutually exclusive operation?🤔

Additional context

No response

关于初始化验证设备ID的问题

Version

No response

Describe the bug

初始化时验证了设备ID是否等于0xEF17,高8位为厂商ID会有所不同

Reproduce

No response

Expected behavior

No response

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.