Sample SPI drivers for a number of the Adesto Technologies flash devices.
fusion.c
Go to the documentation of this file.
1 /*
2  * The Clear BSD License
3  * Copyright (c) 2018 Adesto Technologies Corporation, Inc
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted (subject to the limitations in the disclaimer below) provided
8  * that the following conditions are met:
9  *
10  * o Redistributions of source code must retain the above copyright notice, this list
11  * of conditions and the following disclaimer.
12  *
13  * o Redistributions in binary form must reproduce the above copyright notice, this
14  * list of conditions and the following disclaimer in the documentation and/or
15  * other materials provided with the distribution.
16  *
17  * o Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
42 #include "fusion.h"
43 
44 #if (PARTNO == AT25XE512C) || \
45  (PARTNO == AT25XE011) || \
46  (PARTNO == AT25XE021A) || \
47  (PARTNO == AT25XE041B) || \
48  (PARTNO == AT25DN256) || \
49  (PARTNO == AT25DN512C) || \
50  (PARTNO == AT25DN011) || \
51  (PARTNO == AT25DF256) || \
52  (PARTNO == AT25DF512C) || \
53  (PARTNO == AT25DF011) || \
54  (PARTNO == AT25DF021A) || \
55  (PARTNO == AT25DF041B) || \
56  (PARTNO == AT25XV021A) || \
57  (PARTNO == AT25XV041B) || \
58  (ALL == 1)
59 
60 static bool DISPLAY_OUTPUT = 0;
61 
62 static void debugOn() {DISPLAY_OUTPUT = 1;};
63 static void debugOff() {DISPLAY_OUTPUT = 0;};
64 
66 
68 {
69  uint8_t SR[2];
70  do
71  {
72  fusionReadSR(SR);
73  SPI_Delay(10);
74  }
75  while(SR[0] & 1);
76 }
77 
79 {
81  fusionWriteSRB1(0x7F);
82 }
83 
85 {
87  fusionWriteSRB1(0x00);
88 }
89 
90 void fusionReadArray(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
91 {
93  SPI_Exchange(txFusionInternalBuffer, 4, rxBuffer, rxNumBytes, 1);
94  if(DISPLAY_OUTPUT)
95  {
96  printSPIExchange(txFusionInternalBuffer, 4, rxBuffer, rxNumBytes);
97  }
98 }
99 
100 void fusionReadArrayLF(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
101 {
103  SPI_Exchange(txFusionInternalBuffer, 4, rxBuffer, rxNumBytes, 0);
104  if(DISPLAY_OUTPUT)
105  {
106  printSPIExchange(txFusionInternalBuffer, 4, rxBuffer, rxNumBytes);
107  }
108 }
109 
110 void fusionDualOutputRead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
111 {
113  SPI_DualExchange(4, txFusionInternalBuffer, 4, rxBuffer, rxNumBytes, 1);
114  if(DISPLAY_OUTPUT)
115  {
116  printSPIExchange(txFusionInternalBuffer, 4, rxBuffer, rxNumBytes);
117  }
118 }
119 
120 void fusionPageErase(uint32_t address)
121 {
123  SPI_Exchange(txFusionInternalBuffer, 4, NULL, 0, 0);
124  if(DISPLAY_OUTPUT)
125  {
127  }
128 }
129 
130 void fusionBlockErase4K(uint32_t address)
131 {
133  SPI_Exchange(txFusionInternalBuffer, 4, NULL, 0, 0);
134  if(DISPLAY_OUTPUT)
135  {
137  }
138 }
139 
141 {
143  SPI_Exchange(txFusionInternalBuffer, 1, NULL, 0, 0);
144  if(DISPLAY_OUTPUT)
145  {
147  }
148 }
149 
150 void fusionProgramArray(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
151 {
153  // Offset the data bytes by 4; opcode+address takes up the first 4 bytes of a transmission.
154  uint32_t totalBytes = txNumBytes + 4;
155 
156  for(uint32_t j = 0; j < txNumBytes; j++)
157  {
158  txFusionInternalBuffer[j+4] = txBuffer[j];
159  }
160  SPI_Exchange(txFusionInternalBuffer, totalBytes, NULL, 0, 0);
161  if(DISPLAY_OUTPUT)
162  {
163  printSPIExchange(txFusionInternalBuffer, totalBytes, NULL, 0);
164  }
165 }
166 
168 {
170  SPI_Exchange(txFusionInternalBuffer, 1, NULL, 0, 0);
171  if(DISPLAY_OUTPUT)
172  {
174  }
175 }
176 
178 {
180  SPI_Exchange(txFusionInternalBuffer, 1, NULL, 0, 0);
181  if(DISPLAY_OUTPUT)
182  {
184  }
185 }
186 
187 void fusionReadSR(uint8_t *rxBuffer)
188 {
190  SPI_Exchange(txFusionInternalBuffer, 1, rxBuffer, 2, 0);
191  if(DISPLAY_OUTPUT)
192  {
193  printSPIExchange(txFusionInternalBuffer, 1, rxBuffer, 2);
194  }
195 }
196 
197 void fusionWriteSRB1(uint8_t data)
198 {
200  txFusionInternalBuffer[1] = data;
201  SPI_Exchange(txFusionInternalBuffer, 2, NULL, 0, 0);
202  if(DISPLAY_OUTPUT)
203  {
205  }
206 }
207 
208 void fusionWriteSRB2(uint8_t data)
209 {
211  txFusionInternalBuffer[1] = data;
212  SPI_Exchange(txFusionInternalBuffer, 2, NULL, 0, 0);
213  if(DISPLAY_OUTPUT)
214  {
216  }
217 }
218 
220 {
223  SPI_Exchange(txFusionInternalBuffer, 2, NULL, 0, 0);
224  if(DISPLAY_OUTPUT)
225  {
227  }
228 }
229 
230 void fusionReadMID(uint8_t *rxBuffer)
231 {
233  SPI_Exchange(txFusionInternalBuffer, 1, rxBuffer, 4, 0);
234  if(DISPLAY_OUTPUT)
235  {
236  printSPIExchange(txFusionInternalBuffer, 1, rxBuffer, 4);
237  }
238 }
239 
241 {
243  SPI_Exchange(txFusionInternalBuffer, 1, NULL, 0, 0);
244  if(DISPLAY_OUTPUT)
245  {
247  }
248 }
249 
251 {
253  SPI_Exchange(txFusionInternalBuffer, 1, NULL, 0, 0);
254  if(DISPLAY_OUTPUT)
255  {
257  }
258 }
259 
261 {
263  SPI_Exchange(txFusionInternalBuffer, 1, NULL, 0, 0);
264  if(DISPLAY_OUTPUT)
265  {
267  }
268 }
269 
270 
271 #if (PARTNO == AT25XE021A) || \
272  (PARTNO == AT25XE041B) || \
273  (PARTNO == AT25DF021A) || \
274  (PARTNO == AT25DF041B) || \
275  (PARTNO == AT25XV021A) || \
276  (PARTNO == AT25XV041B) || \
277  (ALL == 1)
278 void fusionSequentialProgramMode(uint8_t txBuffer)
279 {
281  txFusionInternalBuffer[1] = txBuffer;
282  SPI_Exchange(txFusionInternalBuffer, 2, NULL, 0, 0);
283  if(DISPLAY_OUTPUT)
284  {
286  }
287 }
288 
289 void fusionDualInputProgram(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
290 {
292  // Offset the data bytes by 4; opcode takes up the first 4 bytes of a transmission.
293  uint32_t totalBytes = txNumBytes + 4;
294 
295  for(uint32_t j = 0; j < txNumBytes; j++)
296  {
297  txFusionInternalBuffer[j+4] = txBuffer[j];
298  }
299  SPI_DualExchange(4, txFusionInternalBuffer, totalBytes, NULL, 0, 0);
300  if(DISPLAY_OUTPUT)
301  {
302  printSPIExchange(txFusionInternalBuffer, totalBytes, NULL, 0);
303  }
304 }
305 
306 void fusionProtectSector(uint32_t address)
307 {
309  SPI_Exchange(txFusionInternalBuffer, 4, NULL, 0, 0);
310  if(DISPLAY_OUTPUT)
311  {
313  }
314 }
315 
316 void fusionUnprotectSector(uint32_t address)
317 {
319  SPI_Exchange(txFusionInternalBuffer, 4, NULL, 0, 0);
320  if(DISPLAY_OUTPUT)
321  {
323  }
324 }
325 
326 void fusionReadSectorProtectionRegisters(uint32_t address, uint8_t *rxBuffer)
327 {
329  SPI_Exchange(txFusionInternalBuffer, 4, rxBuffer, 1, 0);
330  if(DISPLAY_OUTPUT)
331  {
332  printSPIExchange(txFusionInternalBuffer, 4, rxBuffer, 1);
333  }
334 }
335 
336 void fusionSequentialProgramModeEnable(uint32_t address, uint8_t txBuffer)
337 {
339  txFusionInternalBuffer[4] = txBuffer;
340  SPI_Exchange(txFusionInternalBuffer, 5, NULL, 0, 0);
341  if(DISPLAY_OUTPUT)
342  {
344  }
345 }
346 #endif
347 
349 {
350  SPI_JEDECReset();
351 }
352 
353 #endif
void fusionUDPDMode()
OPCODE: 0x79 Sends the device into Ultra Deep Power Down Mode. Exit UDPD Mode by toggling CS with c...
Definition: fusion.c:260
void SPI_JEDECReset()
Performs a JEDEC reset on the SPI device.
Definition: spi_driver.c:492
void fusionWriteEnable()
OPCODE: 0x06 Sends opcode to enable writing.
Definition: fusion.c:167
void fusionReadSectorProtectionRegisters(uint32_t address, uint8_t *rxBuffer)
OPCODE: 0x3C Reads the sector protection register at address &#39;address.&#39; 0x00 -> Sector is unprotect...
Definition: fusion.c:326
void fusionReset()
OPCODE: 0xF0 Resets the flash device for immediately, regardless of what current operation is being...
Definition: fusion.c:219
void printSPIExchange(uint8_t *txBuffer, uint32_t txNumBytes, uint8_t *rxBuffer, uint32_t rxNumBytes)
Prints the byte array in hexadecimal with a formatted output. Indicates what bytes were sent...
#define CMD_FUSION_BLOCK_ERASE_4K
Definition: cmd_defs.h:146
void fusionReadMID(uint8_t *rxBuffer)
OPCODE: 0x9F Reads the manufacturer ID and stores the data in rxBuffer.
Definition: fusion.c:230
#define CMD_FUSION_WRITE_SRB1
Definition: cmd_defs.h:155
void fusionResumeFromDeepPowerDown()
OPCODE: 0xAB Wakes the device up from Deep Power Down mode (fusionDeepPowerDown()).
Definition: fusion.c:250
Declarations of Fusion functions.
void fusionHardwareReset()
Performs a hardware (JEDEC) reset on the device.
Definition: fusion.c:348
void fusionWriteSRB1(uint8_t data)
OPCODE: 0x01 Writes the value in data to status register byte 1.
Definition: fusion.c:197
#define CMD_FUSION_DUAL_INPUT_PROGRAM
Definition: cmd_defs.h:171
void fusionDeepPowerDown()
OPCODE: 0xB9 Enters the device into Deep Power Down mode. fusionResumeFromDeepPowerDown() will wake...
Definition: fusion.c:240
void fusionChipErase()
OPCODE: 0x60 Erases the entire chip by setting all bits.
Definition: fusion.c:140
#define CMD_FUSION_READ_SR
Definition: cmd_defs.h:154
#define CMD_FUSION_DEEP_POWER_DOWN
Definition: cmd_defs.h:159
void fusionGlobalUnprotect()
Unprotects all sectors by issuing a WE, then write of 0x00 to status register byte 1...
Definition: fusion.c:84
#define CMD_FUSION_WRITE_SRB2
Definition: cmd_defs.h:156
void fusionWaitOnReady()
: Wait while Read/Busy Status bit in SRB is 1 (device is busy).
Definition: fusion.c:67
#define CMD_FUSION_CHIP_ERASE
Definition: cmd_defs.h:148
#define MAXIMUM_TX_BYTES
Definition: cmd_defs.h:46
#define CMD_FUSION_RESUME_FROM_DPD
Definition: cmd_defs.h:160
void fusionWriteDisable()
OPCODE: 0x04 Sends opcode to disable writing.
Definition: fusion.c:177
void load4BytesToTxBuffer(uint8_t *txBuffer, uint8_t opcode, uint32_t address)
Loads 1 byte of opcode followed by 3 address bytes into the txBuffer. The data is stored at the first...
#define CMD_FUSION_UNPROTECT_SECTOR
Definition: cmd_defs.h:173
void fusionBlockErase4K(uint32_t address)
OPCODE: 0x20 Erases a block of data (4 KBytes) starting from page address &#39;address.&#39;.
Definition: fusion.c:130
#define CMD_FUSION_UDPD_MODE
Definition: cmd_defs.h:161
#define CMD_FUSION_RESET_CONFIRMATION
Fusion Devices and Opcodes AT25XE512C AT25XE011 AT25XE021A AT25XE041B AT25DN256 AT25DN512C AT25DN011 ...
Definition: cmd_defs.h:141
#define CMD_FUSION_READ_ARRAY
Definition: cmd_defs.h:142
void fusionDualInputProgram(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0xA2 Programs &#39;txNumBytes&#39; bytes of data in Dual Input Mode starting at &#39;address&#39; using bot...
Definition: fusion.c:289
void SPI_DualExchange(uint8_t standardSPINumBytes, uint8_t *txBuffer, uint32_t txNumBytes, uint8_t *rxBuffer, uint32_t rxNumBytes, uint32_t dummyNumBytes)
Sends and receives bytes based on the function parameters. MOSI is used for the opcode and address...
Definition: spi_driver.c:355
#define CMD_FUSION_PROTECT_SECTOR
Definition: cmd_defs.h:172
#define CMD_FUSION_WRITE_ENABLE
Definition: cmd_defs.h:150
void fusionGlobalProtect()
Protects all sectors by issuing a WE, then write of 0x7F to status register byte 1. These 2 write are accomplished with fusionWriteEnable() and fusionWriteSRB1().
Definition: fusion.c:78
#define CMD_FUSION_PAGE_ERASE
Definition: cmd_defs.h:145
#define CMD_FUSION_READ_ARRAY_LF
Definition: cmd_defs.h:143
#define CMD_FUSION_READ_MID
Definition: cmd_defs.h:158
#define CMD_FUSION_RESET
Definition: cmd_defs.h:157
void fusionSequentialProgramMode(uint8_t txBuffer)
OPCODE: 0xAD Sends the byte in txBuffer to the flash device for programming. This command should on...
Definition: fusion.c:278
void SPI_Delay(uint32_t delayTime)
Performs a delayTime number of NOPs.
Definition: spi_driver.c:140
uint8_t txFusionInternalBuffer[MAXIMUM_TX_BYTES]
Definition: fusion.c:63
void fusionReadArray(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x0B Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: fusion.c:90
void fusionReadArrayLF(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x03 Reads rxNumBytes starting from location &#39;address&#39; and stores the data in the byte arra...
Definition: fusion.c:100
void fusionProtectSector(uint32_t address)
OPCODE: 0x36 Sends opcode to disable writing.
Definition: fusion.c:306
#define CMD_FUSION_WRITE_DISABLE
Definition: cmd_defs.h:151
void fusionDualOutputRead(uint32_t address, uint8_t *rxBuffer, uint32_t rxNumBytes)
OPCODE: 0x3B Reads &#39;txNumBytes&#39; bytes of data in Dual Output Mode starting at &#39;address&#39; using both ...
Definition: fusion.c:110
void fusionPageErase(uint32_t address)
OPCODE: 0x81 Erases a page of data (256 Bytes) starting from page address &#39;address.&#39;.
Definition: fusion.c:120
void fusionSequentialProgramModeEnable(uint32_t address, uint8_t txBuffer)
OPCODE: 0xAD Enables sequential program mode and loads the starting address into the device...
Definition: fusion.c:336
void fusionWriteSRB2(uint8_t data)
OPCODE: 0x31 Writes the value in data to status register byte 2.
Definition: fusion.c:208
#define CMD_FUSION_PROGRAM_ARRAY
Definition: cmd_defs.h:149
void fusionUnprotectSector(uint32_t address)
OPCODE: 0x39 Sends opcode to enable writing.
Definition: fusion.c:316
void fusionReadSR(uint8_t *rxBuffer)
OPCODE: 0x05 Reads the value in the status register (bytes 1 and 2).
Definition: fusion.c:187
#define CMD_FUSION_DUAL_OUTPUT_READ
Definition: cmd_defs.h:144
#define CMD_FUSION_PROTECTION_REGISTER
Definition: cmd_defs.h:174
#define CMD_FUSION_SQNTL_PROGRAM_MODE
Definition: cmd_defs.h:170
void SPI_Exchange(uint8_t *txBuffer, uint32_t txNumBytes, uint8_t *rxBuffer, uint32_t rxNumBytes, uint32_t dummyNumBytes)
Sends and receives bytes based on the function parameters. MISO and MOSI fill their standard SPI role...
Definition: spi_driver.c:325
void fusionProgramArray(uint32_t address, uint8_t *txBuffer, uint32_t txNumBytes)
OPCODE: 0x02 Programs &#39;txNumBytes&#39; bytes of data starting at the address indicated by address...
Definition: fusion.c:150