{"id":2142,"date":"2023-11-26T05:15:26","date_gmt":"2023-11-26T05:15:26","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2142"},"modified":"2023-11-26T05:15:30","modified_gmt":"2023-11-26T05:15:30","slug":"working-with-stm32-and-external-flash-w25qxx-part1-reading-id","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2142","title":{"rendered":"Working with STM32 and External Flash W25QXX Part1: Reading ID"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"600\" height=\"436\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/145104325.png.webp\" alt=\"\" class=\"wp-image-2143\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/145104325.png.webp 600w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/145104325.png-300x218.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/145104325.png-400x291.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/145104325.png-250x182.webp 250w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/figure><\/div>\n\n\n\n<p>In this new guide series, we shall see how to interface W25QXX External flash memory with STM32F4xx using SPI.<\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>W25Qxx Feature.<\/li><li>Developing the SPI driver.<\/li><li>Developing the delay driver.<\/li><li>Connection with STM32F4xx<\/li><li>Developing the W25QXX driver.<\/li><li>Main code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. W25QXX Features:<\/h2>\n\n\n\n<p>The W25Q32JV (32M-bit) 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 2.7V to 3.6V power supply with current consumption as low as 1\u00b5A for power-down.<\/p>\n\n\n\n<p>The W25Q32JV array is organized into 16,384 programmable pages of 256-bytes each. Up to 256 bytes can be programmed at a time. Pages can be erased in groups of 16 (4KB sector erase), groups of 128 (32KB block erase), groups of 256 (64KB block erase) or the entire chip (chip erase). The W25Q32JV has 1,024 erasable sectors and 64 erasable blocks respectively. The small 4KB sectors allow for greater flexibility in applications that require data and parameter storage. (See Figure 2.)<\/p>\n\n\n\n<p>The W25Q32JV supports the standard Serial Peripheral Interface (SPI), and a high performance Dual\/Quad output as well as Dual\/Quad I\/O SPI: Serial Clock, Chip Select, Serial Data I\/O0 (DI), I\/O1 (DO), I\/O2, and I\/O3. SPI clock frequencies of up to 133MHz are supported allowing equivalent clock rates of 266MHz (133MHz x 2) for Dual I\/O and 532MHz (133MHz x 4) for Quad I\/O when using the Fast Read Dual\/Quad I\/O instructions. These transfer rates can outperform standard Asynchronous 8 and 16-bit Parallel Flash memories.<\/p>\n\n\n\n<p>Additionally, the device supports JEDEC standard manufacturer and device ID and SFDP Register, a 64bit Unique Serial Number and three 256-bytes Security Registers.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>FEATURES<\/p>\n\n\n\n<p> New Family of SpiFlash Memories<\/p>\n\n\n\n<p>\u2013 W25Q32JV: 32M-bit \/ 4M-byte<\/p>\n\n\n\n<p>\u2013 Standard SPI: CLK, \/CS, DI, DO<\/p>\n\n\n\n<p> Flexible Architecture with 4KB sectors<\/p>\n\n\n\n<p>\u2013 Uniform Sector\/Block Erase (4K\/32K\/64K-Byte)<\/p>\n\n\n\n<p>\u2013 Program 1 to 256 byte per programmable page<\/p>\n\n\n\n<p>\u2013 Dual SPI: CLK, \/CS, IO0 , IO1<\/p>\n\n\n\n<p>\u2013 Quad SPI: CLK, \/CS, IO0 , IO1 , IO2 , IO3<\/p>\n\n\n\n<p>\u2013 Software &amp; Hardware Reset(1)<\/p>\n\n\n\n<p> Highest Performance Serial Flash<\/p>\n\n\n\n<p>\u2013 133MHz Single, Dual\/Quad SPI clocks<\/p>\n\n\n\n<p>\u2013 266\/532MHz equivalent Dual\/Quad SPI<\/p>\n\n\n\n<p>\u2013 66MB\/S continuous data transfer rate<\/p>\n\n\n\n<p>\u2013 Min. 100K Program-Erase cycles per sector<\/p>\n\n\n\n<p>\u2013 More than 20-year data retention <\/p>\n\n\n\n<p> Efficient \u201cContinuous Read\u201d<\/p>\n\n\n\n<p>\u2013 Continuous Read with 8\/16\/32\/64-Byte Wrap<\/p>\n\n\n\n<p>\u2013 As few as 8 clocks to address memory<\/p>\n\n\n\n<p>\u2013 Allows true XIP (execute in place) operation<\/p>\n\n\n\n<p>\u2013 Outperforms X16 Parallel Flash<\/p>\n\n\n\n<p> Low Power, Wide Temperature Range<\/p>\n\n\n\n<p>\u2013 Single 2.7V to 3.6V supply<\/p>\n\n\n\n<p>\u2013 &lt;1\u00b5A Power-down (typ.)<\/p>\n\n\n\n<p>\u2013 -40\u00b0C to +85\u00b0C operating range<\/p>\n\n\n\n<p>\u2013 Erase\/Program Suspend &amp; Resume <\/p>\n\n\n\n<p> Advanced Security Features<\/p>\n\n\n\n<p>\u2013 Software and Hardware Write-Protect<\/p>\n\n\n\n<p>\u2013 Special OTP protection(2)<\/p>\n\n\n\n<p>\u2013 Top\/Bottom, Complement array protection<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>\u2013 Individual Block\/Sector array protection<\/p>\n\n\n\n<p>\u2013 64-Bit Unique ID for each device<\/p>\n\n\n\n<p>\u2013 Discoverable Parameters (SFDP) Register<\/p>\n\n\n\n<p>\u2013 3X256-Bytes Security Registers<\/p>\n\n\n\n<p>\u2013 Volatile &amp; Non-volatile Status Register Bits<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Pin out:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"332\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-1024x332.png\" alt=\"\" class=\"wp-image-2144\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-1024x332.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-300x97.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-768x249.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-1536x499.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-2048x665.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-1150x373.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-750x243.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-400x130.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.04.28\u202fAM-250x81.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Developing SPI Driver:<\/h2>\n\n\n\n<p>Before we start with drivers, take a look <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=466\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=466\" target=\"_blank\">here<\/a> what is SPI and how to enable clock access etc and related pins.<\/p>\n\n\n\n<p>Also, check <\/p>\n\n\n\n<p>We start off by creating new header file with name of SPI1.h.<\/p>\n\n\n\n<p>Within the header file, include header guard as following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef SPI1_H_\n#define SPI1_H_\n\n\n\n#endif \/* SPI1_H_ *\/<\/pre><\/div>\n\n\n\n<p>Within the header guard, in the stdint library as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the following functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Pins_Init(void);<\/pre><\/div>\n\n\n\n<p>This function will initialize the SPI1 related pins (PA5, PA6 and PA7) and take no argument and returns nothing.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_CS_Pins_Init(void);<\/pre><\/div>\n\n\n\n<p>This function will initialize the CS pin (PA0) and set to default state of high, it takes no argument and returns nothing.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Config(void);<\/pre><\/div>\n\n\n\n<p>This will configure the SPI, it takes no argument and returns nothing.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Transmit(uint8_t *data,uint32_t size);<\/pre><\/div>\n\n\n\n<p>This function will transmit data over the SPI bus, it takes pointer to array that holds the data to be written and size of the array and returns nothing.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Receive(uint8_t *data,uint32_t size);<\/pre><\/div>\n\n\n\n<p>This function will receive bytes from the SPI bus, it takes pointer to array to store the received data and size of the data to be received.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_CS_LOW(void);\n\nvoid W25QXX_CS_HIGH(void);<\/pre><\/div>\n\n\n\n<p>These two functions will set\/reset the CS pin according to the SPI requirements. Both functions take no argument and return nothing.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, create new source file with name of SPI1.c.<\/p>\n\n\n\n<p>Within the source file, include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &lt;SPI1.h&gt;\n#include &quot;stm32f4xx.h&quot;<\/pre><\/div>\n\n\n\n<p>Include the SPI1 header file and main STM32F4xx header file.<\/p>\n\n\n\n<p>For SPI GPIO initialization function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Pins_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; \/\/enable clock for GPIOA\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1; \/\/set PA5, PA6 and PA7 to alternate function mode\n\tGPIOA-&gt;MODER &amp;=~(GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);\n\n\tGPIOA-&gt;OSPEEDR|=GPIO_OSPEEDER_OSPEEDR5|GPIO_OSPEEDER_OSPEEDR6|GPIO_OSPEEDER_OSPEEDR7;\n\n\tGPIOA-&gt;AFR[0]|=(0x05&lt;&lt;20)|(0x05&lt;&lt;24)|(0x05&lt;&lt;28);\n}<\/pre><\/div>\n\n\n\n<p>For the CS pin:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_CS_Pins_Init(void)\n{\n\tRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN; \/\/enable clock for GPIOA\n\t\/*Set PA0 as output*\/\n\tGPIOA-&gt;MODER|=GPIO_MODER_MODE0_0;\n\tGPIOA-&gt;MODER&amp;=~GPIO_MODER_MODE0_1;\n\n\t\/*Set pin high as initial state*\/\n\tGPIOA-&gt;BSRR =GPIO_BSRR_BS0;\n}\n<\/pre><\/div>\n\n\n\n<p>The SPI shall be configured with the following parameters:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>CPOL and CPHA 0 (Mode0).<\/li><li>Master mode.<\/li><li>Software slave management.<\/li><li>MSB first.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"252\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-1024x252.webp\" alt=\"\" class=\"wp-image-2145\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-1024x252.webp 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-300x74.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-768x189.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-1150x283.webp 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-750x185.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-400x98.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6-250x62.webp 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/w25q1-6.webp 1321w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Config(void)\n{\n\t\/*Enable clock access to SPI1 module*\/\n\tRCC-&gt;APB2ENR |= RCC_APB2ENR_SPI1EN;\n\t\n\t\/*Set clock to fPCLK\/2*\/\n\tSPI1-&gt;CR1 &amp;=~SPI_CR1_BR_0;\n\tSPI1-&gt;CR1 &amp;=~SPI_CR1_BR_1;\n\tSPI1-&gt;CR1 &amp;=~SPI_CR1_BR_2;\n\t\n\t\/*Set CPOL to 0 and CPHA to 0 (MODE0)*\/\n\tSPI1-&gt;CR1 &amp;=~(SPI_CR1_CPOL);\n\tSPI1-&gt;CR1 &amp;=~(SPI_CR1_CPHA);\n\t\n\t\/*Enable full duplex*\/\n\tSPI1-&gt;CR1 &amp;=~(SPI_CR1_RXONLY);\n\t\n\t\/*Set MSB first*\/\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_LSBFIRST);\n\t\n\t\/*Set mode to MASTER*\/\n\tSPI1-&gt;CR1 |= (SPI_CR1_MSTR);\n\t\n\t\/*Set 8 bit data mode*\/\n\tSPI1-&gt;CR1 &amp;= ~(SPI_CR1_DFF);\n\t\n\t\/*Select software slave management by\n\t* setting SSM=1 and SSI=1*\/\n\tSPI1-&gt;CR1 |= (SPI_CR1_SSM);\n\tSPI1-&gt;CR1 |= (SPI_CR1_SSI);\n\t\n\t\/*Enable SPI module*\/\n\tSPI1-&gt;CR1 |= (SPI_CR1_SPE);\n}\n<\/pre><\/div>\n\n\n\n<p>For SPI transmit:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;C&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Transmit(uint8_t *data,uint32_t size)\n{\n\tuint32_t i=0;\n\n\twhile(i&lt;size)\n\t{\n\t\t\/*Wait until TXE is set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\t\/*Write the data to the data register*\/\n\t\tSPI1-&gt;DR = data[i];\n\t\ti++;\n\t}\n\t\/*Wait until TXE is set*\/\n\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_TXE))){}\n\n\t\/*Wait for BUSY flag to reset*\/\n\twhile((SPI1-&gt;SR &amp; (SPI_SR_BSY))){}\n\n\t\/*Clear OVR flag*\/\n\t(void)SPI1-&gt;DR;\n\t(void)SPI1-&gt;SR;\n}\n<\/pre><\/div>\n\n\n\n<p>For SPI receive:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void SPI1_Receive(uint8_t *data,uint32_t size)\n{\n\twhile(size)\n\t{\n\t\t\/*Send dummy data*\/\n\t\tSPI1-&gt;DR =0;\n\n\t\t\/*Wait for RXNE flag to be set*\/\n\t\twhile(!(SPI1-&gt;SR &amp; (SPI_SR_RXNE))){}\n\n\t\t\/*Read data from data register*\/\n\t\t*data++ = (SPI1-&gt;DR);\n\t\tsize--;\n\t}\n}\n<\/pre><\/div>\n\n\n\n<p>CS state:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_CS_LOW(void)\n{\n\tGPIOA-&gt;BSRR =GPIO_BSRR_BR0;\n\n}\n\n\/*Pull high to disable*\/\nvoid W25QXX_CS_HIGH(void)\n{\n\tGPIOA-&gt;BSRR =GPIO_BSRR_BS0;\n}\n<\/pre><\/div>\n\n\n\n<p>Thats all for the SPI part.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Developing the Delay Driver:<\/h2>\n\n\n\n<p>With delay, we shall use SysTick to generate interrupt each 1 milliseconds.<\/p>\n\n\n\n<p>Check <a href=\"https:\/\/blog.embeddedexpert.io\/?p=1644\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=1644\" target=\"_blank\" rel=\"noreferrer noopener\">this guide<\/a> for how to generate interrupt using systick.<\/p>\n\n\n\n<p>Create new header file with name of delay.h.<\/p>\n\n\n\n<p>The header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef __delay__H__\n#define __delay__H__\n\n#include &quot;stdint.h&quot;\n\nvoid delay_init(uint32_t freq);\nuint64_t millis();\nvoid delay(uint32_t time);\n\n\n#endif<\/pre><\/div>\n\n\n\n<p>Create new source file with name of delay.c.<\/p>\n\n\n\n<p>The content of delay as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;delay.h&quot;\n#include &quot;stm32f4xx.h&quot;\n\n\n\n#define\tCTRL_ENABLE\t\t\t\t\t(1U&lt;&lt;0)\n#define CTRL_CLKSRC\t\t\t\t\t(1U&lt;&lt;2)\n#define CTRL_COUNTFLAG\t\t\t\t(1U&lt;&lt;16)\n#define CTRL_TICKINT\t\t\t\t(1U&lt;&lt;1)\n\n\nvolatile uint64_t mil;\n\nvoid delay_init(uint32_t freq)\n{\n\n\tSysTick-&gt;LOAD  = (freq\/1000) - 1;\n\n\t\/*Clear systick current value register *\/\n\tSysTick-&gt;VAL = 0;\n\n\t\/*Enable systick and select internal clk src*\/\n\tSysTick-&gt;CTRL = CTRL_ENABLE | CTRL_CLKSRC ;\n\n\t\/*Enable systick interrupt*\/\n\tSysTick-&gt;CTRL  |= CTRL_TICKINT;\n\n}\n\n\n\nuint64_t millis()\n\t{\n\t__disable_irq();\n\tuint64_t ml=mil;\n\t__enable_irq();\n\treturn ml;\n\t}\n\n\n\nvoid delay(uint32_t time)\n{\n\n\tuint64_t start=millis();\n\twhile((millis() - start) &lt; (time+1));\n}\n\nvoid SysTick_Handler(void)\n{\n\n\tmil++;\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Connection with STM32F4xx:<\/h2>\n\n\n\n<p>The connection as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"897\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-1024x897.png\" alt=\"\" class=\"wp-image-2146\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-1024x897.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-300x263.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-768x673.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-1536x1345.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-1150x1007.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-750x657.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-400x350.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM-250x219.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-25-at-8.29.36\u202fAM.png 1754w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>STM32F411-Nucleo64<\/td><td>W25QXX<\/td><\/tr><tr><td>3V3<\/td><td>Vcc<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>PA0<\/td><td>CS<\/td><\/tr><tr><td>PA5<\/td><td>CLK<\/td><\/tr><tr><td>PA6<\/td><td>DO<\/td><\/tr><tr><td>PA7<\/td><td>DI<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Note: Chip only supports 3v3, powering it from 5V will destroy it.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Developing W25QXX driver:<\/h2>\n\n\n\n<p>Create new header file with name of W25QXX.h<\/p>\n\n\n\n<p>Within the header file, include the header guard:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef W25QXX_H_\n#define W25QXX_H_\n\n\n\n#endif \/* W25QXX_H_ *\/<\/pre><\/div>\n\n\n\n<p>Within the header guard, include the stdint:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the following functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_Reset(void);<\/pre><\/div>\n\n\n\n<p>This function will soft reset the flash and takes no argument and returns nothing.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint32_t W25QXX_ReadID (void);<\/pre><\/div>\n\n\n\n<p>This function will read the ID of the chip and takes no argument and return the ID as uint32_t value.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef W25QXX_H_\n#define W25QXX_H_\n\n#include &quot;stdint.h&quot;\n\nvoid W25QXX_Reset(void);\n\nuint32_t W25QXX_ReadID (void);\n\n\n\n\n#endif \/* W25QXX_H_ *\/<\/pre><\/div>\n\n\n\n<p>Create new source file with name of W25QXX.c.<\/p>\n\n\n\n<p>Within the source file, include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;W25QXX.h&quot;\n\n#include &quot;SPI1.h&quot;<\/pre><\/div>\n\n\n\n<p>For the reset, we need to send two commands one after the another as mentioned in the datasheet:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"327\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-1024x327.png\" alt=\"\" class=\"wp-image-2147\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-1024x327.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-300x96.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-768x245.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-1536x491.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-2048x655.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-1150x368.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-750x240.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-400x128.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-7.50.37\u202fAM-250x80.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Hence, the reset function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_Reset(void)\n{<\/pre><\/div>\n\n\n\n<p>declare an array that hold two variable:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t tData[2];<\/pre><\/div>\n\n\n\n<p>Define the two values for reset enable and reset:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">tData[0] = 0x66;  \/\/ enable Reset\ntData[1] = 0x99;  \/\/ Reset<\/pre><\/div>\n\n\n\n<p>Transmit the data:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\tW25QXX_CS_LOW();\n\tSPI1_Transmit(tData, 2);\n\tW25QXX_CS_HIGH();<\/pre><\/div>\n\n\n\n<p>Hence the function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void W25QXX_Reset(void)\n{\n\tuint8_t tData[2];\n\n\ttData[0] = 0x66;  \/\/ enable Reset\n\ttData[1] = 0x99;  \/\/ Reset\n\tW25QXX_CS_LOW();\n\tSPI1_Transmit(tData, 2);\n\tW25QXX_CS_HIGH();\n}\n<\/pre><\/div>\n\n\n\n<p>To read the ID, we simply send 0x9F and receive the three bytes that contain the ID and size as following:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"327\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-1024x327.png\" alt=\"\" class=\"wp-image-2148\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-1024x327.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-300x96.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-768x245.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-1536x491.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-2048x655.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-1150x368.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-750x240.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-400x128.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-8.07.20\u202fAM-250x80.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint32_t W25QXX_ReadID (void)\n{<\/pre><\/div>\n\n\n\n<p>Declare a variable to hold the read command as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t tData = 0x9f;  \/\/ Read ID<\/pre><\/div>\n\n\n\n<p>Declare an array to hold the ID as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint8_t rData[3];<\/pre><\/div>\n\n\n\n<p>Transmit and receive data as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\tW25QXX_CS_LOW();\n\tSPI1_Transmit(&amp;tData,1);\n\tSPI1_Receive(rData, 3);\n\tW25QXX_CS_HIGH();<\/pre><\/div>\n\n\n\n<p>Return the data:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">return ((rData[0]&lt;&lt;16)|(rData[1]&lt;&lt;8)|rData[2]); \/\/ MFN ID : MEM ID : CAPACITY ID<\/pre><\/div>\n\n\n\n<p>Hence the function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">uint32_t W25QXX_ReadID (void)\n{\n\tuint8_t tData = 0x9f;  \/\/ Read ID\n\tuint8_t rData[3];\n\tW25QXX_CS_LOW();\n\tSPI1_Transmit(&amp;tData,1);\n\tSPI1_Receive(rData, 3);\n\tW25QXX_CS_HIGH();\n\n\treturn ((rData[0]&lt;&lt;16)|(rData[1]&lt;&lt;8)|rData[2]); \/\/ MFN ID : MEM ID : CAPACITY ID\n}\n<\/pre><\/div>\n\n\n\n<p>The source file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;W25QXX.h&quot;\n\n#include &quot;SPI1.h&quot;\n\n\n\nvoid W25QXX_Reset(void)\n{\n\tuint8_t tData[2];\n\n\ttData[0] = 0x66;  \/\/ enable Reset\n\ttData[1] = 0x99;  \/\/ Reset\n\tW25QXX_CS_LOW();\n\tSPI1_Transmit(tData, 2);\n\tW25QXX_CS_HIGH();\n}\n\nuint32_t W25QXX_ReadID (void)\n{\n\tuint8_t tData = 0x9f;  \/\/ Read ID\n\tuint8_t rData[3];\n\tW25QXX_CS_LOW();\n\tSPI1_Transmit(&amp;tData,1);\n\tSPI1_Receive(rData, 3);\n\tW25QXX_CS_HIGH();\n\n\treturn ((rData[0]&lt;&lt;16)|(rData[1]&lt;&lt;8)|rData[2]); \/\/ MFN ID : MEM ID : CAPACITY ID\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Main.c code:<\/h2>\n\n\n\n<p>The code within main.c:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;delay.h&quot;\n#include &quot;SPI1.h&quot;\n#include &quot;W25QXX.h&quot;\n\nuint32_t W25QXX_ID;\n\n\nint main(void)\n{\tdelay_init(16000000);\n\n\tSPI1_Pins_Init();\n\tW25QXX_CS_Pins_Init();\n\tSPI1_Config();\n\n\tW25QXX_Reset();\n\tdelay(10);\n\n\tW25QXX_ID=W25QXX_ReadID();\n\n\n\n\twhile(1)\n\t{\n\n\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Results:<\/h2>\n\n\n\n<p>Upload the code to your MCU and open a debugging session and add W25QXX_ID to expression value and run the code. You should get the EF for winbond serial flash and model number (W25Q32 in this case)<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"536\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-1024x536.png\" alt=\"\" class=\"wp-image-2149\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-1024x536.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-300x157.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-768x402.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-1536x805.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-2048x1073.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-1150x602.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-750x393.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-400x210.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/11\/Screenshot-2023-11-26-at-6.47.04\u202fAM-250x131.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this new guide series, we shall see how to interface W25QXX External flash memory with STM32F4xx using SPI. In this guide, we shall cover the following: W25Qxx Feature. Developing the SPI driver. Developing the delay driver. Connection with STM32F4xx Developing the W25QXX driver. Main code. Results. 1. W25QXX Features: The W25Q32JV (32M-bit) Serial Flash [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2142","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2142"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2142"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2142\/revisions"}],"predecessor-version":[{"id":2150,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2142\/revisions\/2150"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}