Skip to content

Commit

Permalink
Final v 1.3.0
Browse files Browse the repository at this point in the history
Golden Master
  • Loading branch information
Marzogh committed Aug 30, 2015
1 parent a324b2b commit 846d36b
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 111 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# SPIFlash
### Arduino library for Winbond Flash W25Q80BV
<sup> Download the latest stable release (v1.2.1) from <a href = "https://github.com/Marzogh/SPIFlash/releases/tag/v1.2.1">here</a>. Please report any bugs in issues.</sup>
### Arduino library for Winbond Flash Memory Chips
<sup> Download the latest stable release (v1.3.0) from <a href = "https://github.com/Marzogh/SPIFlash/releases/tag/v1.3.0">here</a>. Please report any bugs in issues.</sup>

This library is for the W25Q80BV serial flash memory chip. In its current form it enables reading and writing bytes from and to various locations; reading and writing pages of bytes; continous reading/writing of data from/to arrays of bytes; sector, block and chip erase; and powering down for low power operation.
This library is for a the Winbond serial flash memory chips. In its current form it enables reading and writing bytes from and to various locations; reading and writing pages of bytes; continous reading/writing of data from/to arrays of bytes; sector, block and chip erase; and powering down for low power operation.

- The W25Q80BV has a capacity of 64 Mbits (1 Megabyte) which consists of 4096 pages of 256 bytes each.
- Its memory registers are arranged in 16 blocks of 64KB each
- Byte addresses are 24 bit and range from 0x00000 to 0xFFFFF (00000 to 1048575 - decimal)
- For details of the Winbond Flash chips compatible with this library please refer to the Excel spreadsheet in the Extras folder.

#### Installation
- Click on the 'Download zip' button to the right.
Expand All @@ -17,6 +15,7 @@ This library is for the W25Q80BV serial flash memory chip. In its current form i

The library is called by declaring the```SPIFLASH flash(csPin)``` constructor where 'flash' can be replaced by a user constructor of choice and 'csPin' is the Chip Select pin for the flash module.
Make sure to include ```#include<SPI.H>``` when you include ```#include<SPIFlash.h>```.
Also make sure to include ```flash.begin()``` in ```void setup()```. This enables the library to detect the type of flash chip installed and load the right parameters.

###### Notes on Address overflow and Error checking
- The library has Address overflow enabled by default - i.e. if the last address read/written from/to, in any function, is 0xFFFFF then, the next address read/written from/to is 0x00000. This can be disabled by setting the optional last 'overflow' argument in the constructor to false - For eg. call the constructor ```SPIFlash(csPin, false)``` instead of ```SPIFlash(csPin)```.
Expand Down
37 changes: 15 additions & 22 deletions SPIFlash.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Arduino SPIFlash Library v.1.3.0
* Copyright (C) 2015 by Prajwal Bhattaram
* Modified by Prajwal Bhattaram - 29/08/2015
* Modified by Prajwal Bhattaram - 30/08/2015
*
* This file is part of the Arduino SPIFlash Library. This library is for
* W25Q80BV serial flash memory. In its current form it enables reading
Expand Down Expand Up @@ -255,7 +255,7 @@ bool SPIFlash::_getManId(uint8_t *b1, uint8_t *b2) {
return true;
}

// Checks for presence of chip by requesting JEDEC ID
//Checks for presence of chip by requesting JEDEC ID
bool SPIFlash::_getJedecId(uint8_t *b1, uint8_t *b2, uint8_t *b3) {
if(!_notBusy())
return false;
Expand Down Expand Up @@ -313,10 +313,10 @@ uint8_t SPIFlash::_readNextByte(void) {
return xfer(0);
}

// Reads a byte of data from a specific location in a page. Takes one argument -
// 1. address --> address to read from
// WARNING: You can only write to previously erased memory locations (see datasheet).
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
//Reads a byte of data from a specific location in a page. Takes one argument -
// 1. address --> address to read from
// WARNING: You can only write to previously erased memory locations (see datasheet).
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
uint8_t SPIFlash::_readByte(uint32_t address) {
uint8_t data;
if(!_notBusy()||!_addressCheck(address))
Expand Down Expand Up @@ -358,12 +358,12 @@ bool SPIFlash::_writeNextByte(uint8_t c) {
}

// Writes a byte of data to a specific location in a page. Takes three arguments -
// 1. address --> address to write to
// 2. data --> One byte of data to be written to a particular location on a page
// 3. errorCheck --> Turned on by default. Checks for writing errors
// WARNING: You can only write to previously erased memory locations (see datasheet).
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
bool SPIFlash::_writeByte(uint32_t address, uint8_t data, bool errorCheck) {
// 1. address --> address to write to
// 2. data --> One byte of data to be written to a particular location on a page
// 3. errorCheck --> Turned on by default. Checks for writing errors
// WARNING: You can only write to previously erased memory locations (see datasheet).
// Use the eraseSector()/eraseBlock32K/eraseBlock64K commands to first clear memory (write 0xFFs)
bool SPIFlash::_writeByte(uint32_t address, uint8_t data, bool errorCheck) {

if(!_notBusy()||!_writeEnable()||!_addressCheck(address))
return false;
Expand Down Expand Up @@ -455,11 +455,10 @@ void SPIFlash::begin() {

maxPage = capacity/PAGESIZE;

/*char buffer[64];
#ifdef RUNDIAGNOSTIC
char buffer[64];
sprintf(buffer, "Manufacturer ID: %02xh\nMemory Type: %02xh\nCapacity: %lu\nmaxPage: %d", manID, devID, capacity, maxPage);
Serial.println(buffer);*/

#ifdef RUNDIAGNOSTIC
Serial.println(buffer);
errorcode = SUCCESS; //Successful chip detect
_errorCodeCheck();
#endif
Expand All @@ -470,9 +469,6 @@ void SPIFlash::begin() {
uint16_t SPIFlash::getManID() {
uint8_t b1, b2;
_getManId(&b1, &b2);
/*char buffer[64];
sprintf(buffer, "Manufacturer ID: %02xh\nMemory Type: %02xh\nCapacity: %02xh", b1, b2, b3);
Serial.println(buffer);*/
uint32_t id = b1;
id = (id << 8)|(b2 << 0);
return id;
Expand All @@ -482,9 +478,6 @@ uint16_t SPIFlash::getManID() {
uint32_t SPIFlash::getJEDECID() {
uint8_t b1, b2, b3;
_getJedecId(&b1, &b2, &b3);
/*char buffer[64];
sprintf(buffer, "Manufacturer ID: %02xh\nMemory Type: %02xh\nCapacity: %02xh", b1, b2, b3);
Serial.println(buffer);*/
uint32_t id = b1;
id = (id << 8)|(b2 << 0);
id = (id << 8)|(b3 << 0);
Expand Down
96 changes: 47 additions & 49 deletions SPIFlash.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Arduino SPIFlash Library v.1.3.0
* Copyright (C) 2015 by Prajwal Bhattaram
* Modified by Prajwal Bhattaram - 29/08/2015
* Modified by Prajwal Bhattaram - 30/08/2015
*
* This file is part of the Arduino SPIFlash Library. This library is for
* W25Q80BV serial flash memory. In its current form it enables reading
Expand Down Expand Up @@ -32,29 +32,29 @@ class SPIFlash {
SPIFlash(uint8_t cs = 10, bool overflow = true);
uint16_t getManID();
uint32_t getJEDECID();
bool readByte(uint16_t page_number, uint8_t offset, uint8_t data),
writeByte(uint16_t page_number, uint8_t offset, uint8_t data, bool errorCheck = true),
writeBytes(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, bool errorCheck = true),
writeChar(uint16_t page_number, uint8_t offset, int8_t data, bool errorCheck = true),
writeShort(uint16_t page_number, uint8_t offset, int16_t data, bool errorCheck = true),
writeWord(uint16_t page_number, uint8_t offset, uint16_t data, bool errorCheck = true),
writeLong(uint16_t page_number, uint8_t offset, int32_t data, bool errorCheck = true),
writeULong(uint16_t page_number, uint8_t offset, uint32_t data, bool errorCheck = true),
writeFloat(uint16_t page_number, uint8_t offset, float data, bool errorCheck = true),
writePage(uint16_t page_number, uint8_t *data_buffer, bool errorCheck = true),
eraseSector(uint16_t page_number),
eraseBlock32K(uint16_t page_number),
eraseBlock64K(uint16_t page_number),
eraseChip(void),
suspendProg(void),
resumeProg(void),
powerDown(void),
powerUp(void);
void begin(),
readBytes(uint16_t page_number, uint8_t offset, uint8_t *data_buffer),
readPage(uint16_t page_number, uint8_t *data_buffer),
printPage(uint16_t page_number, uint8_t outputType),
printAllPages(uint8_t outputType);
bool readByte(uint16_t page_number, uint8_t offset, uint8_t data);
bool writeByte(uint16_t page_number, uint8_t offset, uint8_t data, bool errorCheck = true);
bool writeBytes(uint16_t page_number, uint8_t offset, uint8_t *data_buffer, bool errorCheck = true);
bool writeChar(uint16_t page_number, uint8_t offset, int8_t data, bool errorCheck = true);
bool writeShort(uint16_t page_number, uint8_t offset, int16_t data, bool errorCheck = true);
bool writeWord(uint16_t page_number, uint8_t offset, uint16_t data, bool errorCheck = true);
bool writeLong(uint16_t page_number, uint8_t offset, int32_t data, bool errorCheck = true);
bool writeULong(uint16_t page_number, uint8_t offset, uint32_t data, bool errorCheck = true);
bool writeFloat(uint16_t page_number, uint8_t offset, float data, bool errorCheck = true);
bool writePage(uint16_t page_number, uint8_t *data_buffer, bool errorCheck = true);
bool eraseSector(uint16_t page_number);
bool eraseBlock32K(uint16_t page_number);
bool eraseBlock64K(uint16_t page_number);
bool eraseChip(void);
bool suspendProg(void);
bool resumeProg(void);
bool powerDown(void);
bool powerUp(void);
void begin();
void readBytes(uint16_t page_number, uint8_t offset, uint8_t *data_buffer);
void readPage(uint16_t page_number, uint8_t *data_buffer);
void printPage(uint16_t page_number, uint8_t outputType);
void printAllPages(uint8_t outputType);
int8_t readChar(uint16_t page_number, uint8_t offset);
uint8_t readByte(uint16_t page_number, uint8_t offset);
int16_t readShort(uint16_t page_number, uint8_t offset);
Expand All @@ -67,29 +67,29 @@ class SPIFlash {


private:
void _chipSelect(void),
_chipDeselect(void),
_cmd(uint8_t c),
_endProcess(void),
_errorCodeCheck(void),
_empty(uint8_t *array),
_beginRead(uint32_t address),
_printPageBytes(uint8_t *data_buffer, uint8_t outputType);
bool _notBusy(uint32_t timeout = 10L),
_addressCheck(uint32_t address),
_beginWrite(uint32_t address),
_readPage(uint16_t page_number, uint8_t *page_buffer),
_writeNextByte(uint8_t c),
_writeEnable(void),
_writeDisable(void),
_getJedecId(uint8_t *b1, uint8_t *b2, uint8_t *b3),
_getManId(uint8_t *b1, uint8_t *b2),
_writeByte(uint32_t address, uint8_t data, bool errorCheck = true);
uint8_t _readNextByte(void),
_readByte(uint32_t address);
uint32_t _getAddress(uint16_t page_number, uint8_t offset = 0),
_prepRead(uint16_t page_number, uint8_t offset = 0),
_prepWrite(uint16_t page_number, uint8_t offset = 0);
void _chipSelect(void);
void _chipDeselect(void);
void _cmd(uint8_t c);
void _endProcess(void);
void _errorCodeCheck(void);
void _empty(uint8_t *array);
void _beginRead(uint32_t address);
void _printPageBytes(uint8_t *data_buffer, uint8_t outputType);
bool _notBusy(uint32_t timeout = 10L);
bool _addressCheck(uint32_t address);
bool _beginWrite(uint32_t address);
bool _readPage(uint16_t page_number, uint8_t *page_buffer);
bool _writeNextByte(uint8_t c);
bool _writeEnable(void);
bool _writeDisable(void);
bool _getJedecId(uint8_t *b1, uint8_t *b2, uint8_t *b3);
bool _getManId(uint8_t *b1, uint8_t *b2);
bool _writeByte(uint32_t address, uint8_t data, bool errorCheck = true);
uint8_t _readNextByte(void);
uint8_t _readByte(uint32_t address);
uint32_t _getAddress(uint16_t page_number, uint8_t offset = 0);
uint32_t _prepRead(uint16_t page_number, uint8_t offset = 0);
uint32_t _prepWrite(uint16_t page_number, uint8_t offset = 0);
template <class T> bool _writeErrorCheck(uint32_t address, const T& value);

volatile uint8_t *cs_port;
Expand All @@ -100,8 +100,6 @@ class SPIFlash {
const uint8_t devType[10] = {0x5, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
const uint32_t memSize[10] = {64L * 1024L, 128L * 1024L, 256L * 1024L, 512L * 1024L, 1L * 1024L * 1024L,
2L * 1024L * 1024L, 4L * 1024L * 1024L, 8L * 1024L * 1024L, 16L * 1024L * 1024L};
const uint16_t KB = 1024L;
const uint32_t MB = 1024L * 1024L;
};

template <class T> uint32_t SPIFlash::writeAnything(uint16_t page_number, uint8_t offset, const T& value)
Expand Down
Loading

0 comments on commit 846d36b

Please sign in to comment.