Skip to content

Commit

Permalink
Updated SPI-Flash to support SST25 Series of SPI Flash, which does no…
Browse files Browse the repository at this point in the history
…t support page programming with opcode 0x02, but Automatic Address Increment Word programming with opcode 0xAD. Use #define SPIFLASH_SST25TYPE for SST25 Type Flash Memory and AAI Word Programming.
  • Loading branch information
D-H-R committed May 22, 2016
1 parent 021412f commit d97435a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
49 changes: 47 additions & 2 deletions libraries/MySensors/drivers/SPIFlash/SPIFlash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// > Updated Jan. 5, 2015, TomWS1, modified writeBytes to allow blocks > 256 bytes and handle page misalignment.
// > Updated Feb. 26, 2015 TomWS1, added support for SPI Transactions (Arduino 1.5.8 and above)
// > Selective merge by Felix after testing in IDE 1.0.6, 1.6.4
// > Updated May 19, 2016 D-H-R, added support for SST25/Microchip Flash which does not support Page programming with OPCode 0x02,
// > use #define SPIFLASH_SST25TYPE for SST25 Type Flash Memory
// **********************************************************************************
// License
// **********************************************************************************
Expand Down Expand Up @@ -230,8 +232,50 @@ void SPIFlash::writeByte(uint32_t addr, uint8_t byt) {
/// WARNING: you can only write to previously erased memory locations (see datasheet)
/// use the block erase commands to first clear memory (write 0xFFs)
/// This version handles both page alignment and data blocks larger than 256 bytes.
///
/// SST25 Family Flash does not support programming multiple Bytes with opcode 0x02 SPIFLASH_BYTEPROGRAM,
/// If #define SPIFLASH_SST25TYPE is set and writeBytes is called, it calls writeByte to do the job
/// (i.e. before each bytes the address where it goes to is sent, use writeWords for better performance with SST25.
void SPIFlash::writeBytes(uint32_t addr, const void* buf, uint16_t len) {
#ifdef SPIFLASH_SST25TYPE
//SST25 Type of Flash does not support Page Programming but AAI Word Programming
uint16_t i=0;
uint8_t oddAdr=0;
char s[5];

command(SPIFLASH_AAIWORDPROGRAM, true); // Byte/Page Program
SPI.transfer(addr >> 16);
SPI.transfer(addr >> 8);
SPI.transfer(addr);

if (addr%2){
//start address is not even, i.e. first byte of word must be 0xff
SPI.transfer(0xff);
SPI.transfer(((uint8_t*) buf)[0]);
unselect();
oddAdr=1; //following addresses must all be shifted one off
len--;
if (len > 0) command(SPIFLASH_AAIWORDPROGRAM); //If for loop will run issue Wordprogram command
}

for (i=0;i<(len/2);i++){
//AAI command must be set before every new word
if (i>0) command(SPIFLASH_AAIWORDPROGRAM); //Wordprogram command for first write has been issued before
SPI.transfer(((uint8_t*) buf)[i*2+oddAdr]);
SPI.transfer(((uint8_t*) buf)[i*2+1+oddAdr]);
unselect();
}

if (len-i*2 == 1){
//There is one byte (i.e. half word) left. This happens if len was odd or (len was even and addr odd)
if (i>0) command(SPIFLASH_AAIWORDPROGRAM); //if for loop had not run wordprogram command from before is still valid
SPI.transfer(((uint8_t*) buf)[i*2+oddAdr]);
SPI.transfer(0xff);
unselect();
}

command(SPIFLASH_WRITEDISABLE); //end AAI programming
unselect();
#else
uint16_t n;
uint16_t maxBytes = 256-(addr%256); // force the first set of bytes to stay within the first page
uint16_t offset = 0;
Expand All @@ -244,14 +288,15 @@ void SPIFlash::writeBytes(uint32_t addr, const void* buf, uint16_t len) {
SPI.transfer(addr);

for (uint16_t i = 0; i < n; i++)
SPI.transfer(((uint8_t*) buf)[offset + i]);
SPI.transfer(((uint8_t*) buf)[offset + i]);
unselect();

addr+=n; // adjust the addresses and remaining bytes by what we've just transferred.
offset +=n;
len -= n;
maxBytes = 256; // now we can do up to 256 bytes per loop
}
#endif
}

/// erase entire flash memory array
Expand Down
7 changes: 6 additions & 1 deletion libraries/MySensors/drivers/SPIFlash/SPIFlash.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// > Updated Jan. 5, 2015, TomWS1, modified writeBytes to allow blocks > 256 bytes and handle page misalignment.
// > Updated Feb. 26, 2015 TomWS1, added support for SPI Transactions (Arduino 1.5.8 and above)
// > Selective merge by Felix after testing in IDE 1.0.6, 1.6.4
// > Updated May 19, 2016 D-H-R, added support for SST25/Microchip Flash which does not support Page programming with OPCode 0x02,
// > use #define SPIFLASH_SST25TYPE for SST25 Type Flash Memory
// **********************************************************************************
// License
// **********************************************************************************
Expand Down Expand Up @@ -82,6 +84,9 @@
#define SPIFLASH_SLEEP 0xB9 // deep power down
#define SPIFLASH_WAKE 0xAB // deep power wake up
#define SPIFLASH_BYTEPAGEPROGRAM 0x02 // write (1 to 256bytes)
#define SPIFLASH_AAIWORDPROGRAM 0xAD // Auto Address Increment Programming on Microchip SST Family Devices which do not support page program
// use #define SPIFLASH_SST25TYPE to use AAI prog instead of Bytepageprogram which does not work on SST Family Chips
// tested with SST25PF020B80 http://ww1.microchip.com/downloads/en/DeviceDoc/20005135B.pdf
#define SPIFLASH_IDREAD 0x9F // read JEDEC manufacturer and device ID (2 bytes, specific bytes for each manufacturer and device)
// Example for Atmel-Adesto 4Mbit AT25DF041A: 0x1F44 (page 27: http://www.adestotech.com/sites/default/files/datasheets/doc3668.pdf)
// Example for Winbond 4Mbit W25X40CL: 0xEF30 (page 14: http://www.winbond.com/NR/rdonlyres/6E25084C-0BFE-4B25-903D-AE10221A0929/0/W25X40CL.pdf)
Expand All @@ -98,7 +103,7 @@ class SPIFlash {
uint8_t readByte(uint32_t addr); //!< read 1 byte from flash memory
void readBytes(uint32_t addr, void* buf, uint16_t len); //!< read unlimited # of bytes
void writeByte(uint32_t addr, uint8_t byt); //!< Write 1 byte to flash memory
void writeBytes(uint32_t addr, const void* buf, uint16_t len); //!< write multiple bytes to flash memory (up to 64K)
void writeBytes(uint32_t addr, const void* buf, uint16_t len); //!< write multiple bytes to flash memory (up to 64K), if #define SPIFLASH_SST25TYPE is set AAI Word Programming will be used
boolean busy(); //!< check if the chip is busy erasing/writing
void chipErase(); //!< erase entire flash memory array
void blockErase4K(uint32_t address); //!< erase a 4Kbyte block
Expand Down

0 comments on commit d97435a

Please sign in to comment.