diff --git a/Change log.md b/Change log.md new file mode 100644 index 0000000..43e9634 --- /dev/null +++ b/Change log.md @@ -0,0 +1,480 @@ +# SPIMemory +##### Change log +[![Build Status](https://travis-ci.org/Marzogh/SPIMemory.svg?branch=master)](https://travis-ci.org/Marzogh/SPIMemory) [![DOI](https://zenodo.org/badge/35823047.svg)](https://zenodo.org/badge/latestdoi/35823047) +[![GitHub release](https://img.shields.io/github/release/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory) +[![GitHub commits](https://img.shields.io/github/commits-since/Marzogh/SPIMemory/v3.4.0.svg)](https://github.com/Marzogh/SPIMemory/compare/v3.3.0...v3.4.0) +[![GitHub issues](https://img.shields.io/github/issues/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory/issues) +[![GitHub pull requests](https://img.shields.io/github/issues-pr/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory/pulls) +[![license](https://img.shields.io/github/license/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory/blob/master/LICENSE) +[![Join the chat at https://gitter.im/SPIMemory/community](https://badges.gitter.im/SPIMemory/community.svg)](https://gitter.im/SPIMemory/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +>This Arduino library is for use with flash and FRAM memory chips that communicate using the SPI protocol. In its current form it supports identifying the flash/FRAM chip and its various features; automatic address allocation and management; writing and reading a number of different types of data, ranging from 8-bit to 32-bit (signed and unsigned) values, floats, Strings, arrays of bytes/chars and structs to and from various locations; sector, block and chip erase; and powering down for low power operation. + +
+ +## Version 3.4.0 + +#### Release date 03.06.2019 + +###### Bugs squashed: +- FastRead works properly now. All previous versions of the library has a FastRead bug that prevent it from doing what it was supposed to. + +###### Enhancements: +- An alternate version of the constructor +``` +SPIFlash flash(int8_t *SPIPinsArray); +``` +can be used (only with ESP32 boards as of now) to enable the use of custom SPI pins. ```SPIPinsArray``` has to be a 4 element array containing the custom SPI pin numbers (as signed integers - int8_t) in the following order - sck, miso, mosi, ss. Refer to the wiki for more information. Resolves #113 +- Created new error code `NOCHIPSELECTDECLARED` for errors with declaring custom SPI pins. +- Using other SPI ports (HSPI, VSPI, SPI1, SPI2 etc.) is now also supported on ESP32 boards - along with SAMD and STM32 boards (supported since v3.0.0). Resolves #177 +- Formatted and merged pull request #153. This changes the way [setClock()](https://github.com/Marzogh/SPIMemory/wiki/Library-instantiation-functions#setclockclockspeed) works and allows for the definition of clock speed before the SPI Bus is instantiated. Refer to [wiki](https://github.com/Marzogh/SPIMemory/wiki/Library-instantiation-functions#setclockclockspeed) for further details. Thanks @rambo. + +###### New Microcontrollers supported: +- nRF52832 ARM Cortex M4F (Adafruit nRF52 Feather) +- STM32L0 ARM Cortex M0+ (Nucleo-L031K6) + +###### New flash memory chips supported: +- MX25L4005 & MX25L4005 from Macronix + + +
+ +## Version 3.3.0 + +#### Release date 20.04.2019 + +>Library now supports FRAM memory (In BETA). Documentation for this is in progress. + +###### Bugs squashed: +- Fixed a major bug causing issues with page boundaries in writeAnything and writeStr. Thanks for your help @jacky4566 (Issue #151) +- Fixed a major bug with reading Strings (Issue #143) +- @incorvia fixed a bug by initialising the SPIBusState to false +- Fixes bug that causes ballooning of pagesize when SFDP is not read. This is because no default `_pageSize` value was set in this scenario. This has now been fixed +- Fixed a major bug in how SFDP data is used to calculate chip capacity. The previous version of the library returned a wrong value. This has now been fixed. Refer to comments in `_getSFDPFlashParam(void)` for further details. + +###### Enhancements: +- Reduce SRAM footprint when running Diagnostics.ino. Thanks @rambo (PR #157) +- Officially supports the ESP32 (tested on the ESP32 Feather) +- Now supports FRAM memory chips via the `SPIFram` constructor +- Changed Diagnostics output in `_chipID()` to match situation better. +- Fixed `_chipID()` to run more efficiently. + +###### New flash memory chips supported: +- GD25Q16C from Giga devices (Used on the Adafruit ItsyBitsy M0 Express) +- W25Q64JV from Winbond +- SST26VF016B & SST26VF032B from Microchip. (Thanks @mix86) + +###### New FRAM memory chips supported: +- FM25W256 from Cypress + +
+ +## Version 3.2.1 + +#### Release date 13.04.2018 + +###### Bugs squashed +- Fixes issue #135 : The addition of the SFDP checking to `_chipID()` resulted in a sudden (very large) increase in compiled code size. As of the current version (v3.2.1), SFDP checking is an user controlled option. To get the library to work with SFDP compatible flash memory that is not officially supported, the user must uncomment `//#define USES_SFDP` in `SPIMemory.h`. + +- Moved `bool _loopedOver` from being a local variable in `getAddress()` to a global one. Now it actually does what it was meant to do - i.e. prevent looping over data a second time. + +###### Enhancements +- The way the basic functions execute has been modified to keep the function runtime the same (or improved) while reducing their memory footprint. + +| Test sketch | Test platform | +|:-----:|:-----:| +|FlashDiagnostics.ino from v3.2.0
with #RUNDIAGNOSTIC commented out | Arduino Pro Mini 8MHz 3.3V | + + +| Library version | Compiled code size
(Bytes) | SFDP status | Size compared to v3.1.0 | +| :------: | :------: | :------: | :-----: | +| v3.1.0 | 17652 | SFDP discovery not supported | Same size | +| v3.2.0 | 20104 | SFDP discovery supported & on by default | 13.9% larger than v3.1.0 | +| v3.2.1 | 15316 | SFDP discovery turned off | 13.75% smaller than v3.1.0 | +| v3.2.1 | 17854 | SFDP discovery turned on | 1.1% larger than v3.1.0 | + +
+ +## Version 3.2.0 + +#### Release date 24.01.2018 + +- Library name changed to SPIMemory + +- The library now gathers sfdp information through `_chipID()`. SFDP information is collected when available, otherwise the library defaults to the pre v3.2.0 version. + +###### New flash memory chips supported +- All flash memories compatible with the SFDP standard (as at JESD216B) should be compatible with the library + +- LE25U40CMC from ON Semiconductor +- A25L512A0 from AMIC +- M25P40 from Micron +- AT25SF041 from Adesto +- S25FL032P from Cypress/Spansion + +###### New Microcontrollers supported +- ATSAMD51J19 ARM Cortex M4 (Adafruit Metro M4) + +###### Enhancements +The library now does the following - if the flash memory chip is compatible with the SFDP standard: +- Identifies the flash memory chip using the Serial Flash Discoverable Parameters standard. (JESD216B) +- Identifies the following opcodes from the SFDP tables and uses them to read/write data: + - `eraseSector` + - `eraseBlock32K` + - `eraseBlock64K` +- Reads timing information from SFDP to accurately time the following operations: + - `eraseSector` + - `eraseBlock32K` + - `eraseBlock64K` +- Fixes #125 in commit 10c2b86. The library automatically uses the alternate chip erase code (0xC7) as required (only on fully supported chips) + +
+ +## Version 3.1.0 + +#### Release date 24.01.2018 + +>Library name change notice inserted into `flash.begin()`. This notice can be dismissed by commenting out the instance of `#define PRINTNAMECHANGEALERT` in SPIFlash.h. Please refer to the Readme file for further details. + +Bugs squashed +- An error with how `_addressCheck()` works with data that spans the memory boundary - when rolling over from address `_chip.capacity` to address `0x00` - has been fixed. In previous versions this caused issues with writing complex data structures across the memory boundary and led to many `_writeErrorCheck()` failures. Fixes issue #112 + +- An error with how `_writeErrorCheck()` worked has been resolved. Writing structs is now as stable as other functions are. Fixes #106 + +- All compilation-time, non-critical errors have been fixed. + +###### Enhancements: +- A new function - `flash.eraseSection(address, size)` - has been introduced in this version. When a user requires a large and variable (between writes) amount of data to be written to the flash memory on the fly and to have the correct amount of space erased to fit the data, this function will automatically calculate and erase the right amount of space to fit the data. Please note that if the the amount of data being written is consistently the same size, the pre-existing `flash.eraseSector()`, `flash.eraseBlock32K()` and `flash.eraseBlock64K()` functions will operate a lot faster. +- Updated `Diagnostics.ino` to include `eraseSection()`. + +- All I/O functions now check to see if the flash chip is powered down. If it is, they prevent the function from running and returns an error. A new error code 'CHIPISPOWEREDDOWN' will be returned upon calling `flash.error()`. + + +###### New flash memory chips supported: +- S25FL127S + +
+ +## Version 3.0.1 + +#### Release date 10.12.2017 + +###### Bugs squashed: + +- Thanks for catching and fixing the following @hanyazou (PR #101) + - Added missing break statements in `_beginSPI()` because that lacks some essential break statement in switch/case. (commit 1: 1de2c10) + - The library did not wait until the busy bit in SR1 was cleared. Timeout argument of `_notBusy()` must be in micro-second. 500L means 500 micro seconds which is too short to wait for completion of erase command. Added " * 1000" to the arguments. (commit 2: 9633c2f) + - Modified `TestFlash.ino` to check error of erase commands execution. (commit 3: a179306) + +- Fixes a major bug that was causing input Arrays to be overwritten by zeros during the writeByteArray() / writeCharArray() process. Thanks for catching this @hanyazou. (Issue #102) + +###### New flash memory chips supported: +- S25FL127S + + +
+ +## Version 3.0.0 + +#### Release date 09.08.2017 + +###### Bugs Squashed: +- The `writeByteArray()` & `writeCharArray()` bug that occurred when writing arrays that spanned page boundaries (squashed in v2.5.0), stayed around to haunt the other functions. Writing any data larger than a single byte that spanned page boundaries would cause the data to wrap around to the beginning of the page. This has now been squashed in this release. + +###### Deprecations: +- Going forward the ATTiny85 is no longer officially supported. +- The library no longer supports using the page number + offset combination instead of addresses. If your code requires you to use a page number + offset combination, use the following code to help +``` +address = (pagenumber << 8) + offset. +(32 bit) | (16 bit) | (8 bit) +``` +- The constructor no longer takes the pageOverflow variable as an argument. Page overflow is globally enabled by default and can be disabled by including a "#define DISABLEOVERFLOW" at the beginning of SPIFlash.h. + +###### New Boards supported: +- Nucleo-F091RC +- Adafruit Feather M0 + +###### New Flash manufacturers supported: +- Microchip (SST25 & SST26 series) +- Cypress +- Spansion + +###### Enhancements: +- Confirmed to work with SPANSION/CYPRESS & MICROCHIP (Both SST25 & SST26 series). +- If not using an officially supported chip, use the following variation of flash.begin() : +``` +flash.begin(flashChipSize) +``` + + where flashChipSize is indicated in Bytes, Kilobytes or Megabytes. (Refer to the next two items in this change log) + +- Including 'flashChipSize' in flash.begin() compiles more efficiently than in previous versions. +- The way memory size is indicated by the users in flash.begin(flashChipSize) has changed - please refer to defines.h or the wiki for further information. The new method enables users to define any custom size unlike the previous version where only a limited number of predetermined sizes were available to use. +- Library faster than before (Refer to Library speed comparison in the extras folder for timing details): + +> Improvements in speed in v3.0.0 when compared to v2.7.0 (values in percentage of time v3.0.0 is faster than v2.7.0) +> +>| Function | Change in speed | +>| :-----: | :-----: | +>| writeByte | +3% | +>| writeChar | +6% | +>| writeWord | +3% | +>| writeShort | +5% | +>| writeULong | +7% | +>| writeLong | +7% | +>| readLong | +7% | +>| writeFloat | +7% | +>| writeStr | +57% | +>| readStr | +61% | +>| writeAnything
(struct) | +25% | +>| readAnything
(struct) | +20% | +>| writeByteArray
(256 bytes) | +18% | +>| readByteArray
(256 bytes) | +45% | +>| eraseSector | +99% | +>| eraseBlock32K | +99.4% | +>| eraseBlock64K | +99.5% | +>| eraseChip | +12% | + +- Constructor changed to enable user to choose one of multiple SPI ports - if available. Look at wiki for further info +- When `RUNDIAGNOSTIC` is uncommented in SPIFlash.h, users now have access to a new function called `flash.functionRunTime()` which can be called after any library I/O function is run. `flash.functionRunTime()` returns the time taken by the previous function to run, in microseconds (as a float). An example use case can be found when the FlashDiagnostics sketch is run with `RUNDIAGNOSTIC` uncommented. +- `_notBusy()` is faster +- Completely re-written `FlashDiagnostics.ino` - uses fewer resources, compatible with more chips and boards +- All functions except the Byte/Char Array Read/Write functions now call an internal `_write`/`_read` function for increased ease of compilation, execution and troubleshooting +- Restructured the internal `_troubleshoot()` function to be better human readable and faster to compile. +- Added a function `getUniqueID()` which returns the unique ID of the flash memory chip as a 64-bit integer. +- Added an internal `_readStat3()` function to enable 4-byte addressing when using flash memory larger than 128 MB +- 4-byte addressing enabled in flash memory larger than 128 MB. This is currently only supported on the W25Q256 and W25Q512. More chips will be supported on a case-by-case basis +- `getAddress()` function now works anytime it is called - even if there is preexisting data on the chip + +
+ +## Version 2.7.0 + +#### Release date 17.04.2017 + +###### Bugs Squashed: +- ATTiny85 support available again. + +###### New Boards supported: +- Arduino Zero now fully supported. + +###### Enhancements: +- Compatible with the ESP32 core for Arduino as of the current commit [9618eec](https://github.com/espressif/arduino-esp32/tree/9618eec19ea470bb59b9a25ebeb8c0c516ca89cc) on 02.08.2017. For some unknown reason, SPI clock speeds higher than board speed/4 are not stable and so, the clock speed for ESP32 dev boards has currently been throttled to 20MHz. + + _NOTE: ESP32 boards usually have an SPIFlash already attached to their SS pin, so the user has to declare the ChipSelect pin being used when the constructor is declared - for example +`SPIFlash flash(33);`_ + +
+ +## Version 2.6.0 + +#### Release date 16.04.2017 + +###### Bugs Squashed: +- Fixed issue with reading status register 2 and the Suspend operation where the library was not checking the suspend status correctly. + +###### Deletions: +- `flash.getChipName()` has been removed as it is superfluous now that the library is now on its way to multi-chip compatibility. +- Library is not compatible with the ATTiny85 anymore. Currently working on a fix which will hopefully be rolled out in v2.7.0 + +###### New Boards supported: +- RTL8195A compatibility tested and enabled by @boseji on 02.03.17. Code modified to fit with the library structure by Prajwal Bhattaram on 14.04.17. +- Compatible with the ESP32 core for Arduino as of the current commit [7d0968c](https://github.com/espressif/arduino-esp32/tree/7d0968c10dc540709d69a28eab2457075c1e4fa8) as on 16.04.2017. The ESP32 core currently does not support analogRead and so randomSeed(AnalogRead(A0)) cannot be used. + + For an unknown reason, SPI clock speeds higher than board speed/4 are not stable and so, the clock speed for ESP32 dev boards has currently been throttled to 20MHz. +- Added support for the Simblee module. + +###### Enhancements: +- `flash.error()` now takes an optional argument 'VERBOSE'. By default the verbosity argument is set to 'false' and calling `flash.error()` still returns the latest error code as an unsigned byte. However, running `flash.error(VERBOSE)` will not only return the latest error code, but will also print it to serial. This - especially in boards with resources to spare - will result in a detailed error report printed to serial. +- `flash.begin()` now returns a boolean value to indicate establishment of successful comms with the flash chip. Usercode can be made more efficient now by calling ```if (!flash.begin()) { Serial.println(flash.error(VERBOSE)); }``` to identify a problem as soon as the library code is run. +- The internal `_addressCheck()` function now locks up usercode with appropriate error codes if + 1. `flash.begin()` has not been called (or) + 2. There is a possible issue with the wiring - i.e. the flash chip is non-responsive (or) + 3. If the chip's capacity either cannot be identified & the user has not defined a chipSize in `flash.begin()`. +- Fixed `powerDown()`to be more efficient. The chip now powers down much faster than before. +- Added a new error code. Library can now detect non-responsive chips - bad wiring or otherwise. +- Streamlined variables to make code structure better. +- Changed library structure to enable the addition of multi-flash compatibility in the near future. +- moved `#define RUNDIAGNOSTIC` & `#define HIGHSPEED` to `SPIFlash.h` from `SPIFlash.cpp`. +- Now works with other Winbond modules (not in the official supported module list) (beta) by taking the flash memory size in bits as an argument in `flash.begin(_chipSize)`; +- Formatted code to be better human readable. +- Changed the internal `_troubleshoot()` function to use fewer resources. + + +
+ +## Version 2.5.0 + +#### Release date 13.11.2016 + +###### Bugs Squashed: +- Errorchecking on `writeByteArray()` and `writeCharArray()` was broken in 2.4.0 and is fixed now. +- Previous versions (< 2.5.0) suffered from the inability to write datasets that spanned page boundaries. This has now been fixed (Ref. Enhancements section below) + +###### Deletions: +- `flash.writePage()` & `flash.readPage()` have been retired as they can be duplicated - more effectively - by other functions. Refer to `pageDiag()` in `Diagnostics.ino` to see how the same results can be obtained by using `flash.writeByteArray()` & `flash.readByteArray()`. + +###### Enhancements: +- Added support for SPI Transactions. +- Added an upgrade for Arduino Due users to read and write large arrays of data at very high speeds - previously reading 60kb of data would take ~108ms - it now takes ~525uS. In this mode, the time between consecutive reads has been reduced to <12ms (needs more work!). +- Completely re-written `writeByteArray()` and `writeCharArray()` functions. They no longer breakdown when writing arrays that span multiple pages. +- All functions that write more than 1 byte of data now take into account page boundaries when writing across pages. In previous versions writing across a page boundary would cause the remainder of the data to wrap around to the beginning of the page. Now the data is written seamlessly from one page over to the next. +- Calling `flash.begin()` now instantiates the SPI bus. Comms with other SPI slaves do not need to call `SPI.begin()` if `flash.begin()` has already been called first in the user's code. +- Sped up `_beginSPI()`. Code in `_beginSPI()` instantiates the SPI bus if another SPI comms library has shut it down. +- Added function allowing setting SPI clock speeds - call the function `flash.setClock(uint32_t clockSpeed)` straight after `begin()`. +- Made `_beginSPI()` & `_nextByte()` shorter and faster. +- Replaced all calls to `SPI.transfer()` with `xfer()` to make the code more human readable and to enable simplicity when switching platforms. +- Added the ability to change Chip Erase wait times depending on the chip (supported chips only). +- Don't need to `#include ` in user code anymore. Just `#include` will do. Examples are now updated. +- Now supports & uses `SPI.transfer(*buf, count)` along with the standard `SPI.transfer()`, speeding up the read/write of anything larger than an byte (AVR Boards only) +--> Reduces the program storage space in the uC's flash (AVR Boards only) + +
+ +## Version 2.4.0 + +#### Release date 11.09.2016 + +###### Bugs Squashed: +- Fixed bug preventing writing to Address 0x00 +- Fixed bug in `_notPrevWritten()` which did did not perform a thorough enough check to see if a location had been previously written to. +- Fixed errorchecking bug - it now works for all data types - not just byte/char as previously. + +###### Enhancements & Optimizations: +- Added a function 'error()' to enable users to check for errors generated at any point in their program. +- Optimized writePage() so it doesn't depend on other functions and so runs faster than before. +- Diagnostics.ino now outputs time taken for each function as a part of its and provides additional diagnostic data. +- Now have a common set of private functions: + * `_prep()` + * `_beginSPI()` + * `_nextByte()` + * `_endSPI()` + + to replace + + * `_prepWrite()` + * `_prepRead()` + * `_beginRead()` + * `_readNextByte()` + * `_beginWrite()` + * `_writeNextByte()` & + * `_endProcess()` +- Changed the way `_addressCheck()` works. It now checks all addresses involved in writing the data rather than one address block at a time and returns the correct address to write to in case overflow is enabled. Also, this function is now built into `_prep()`. +- Reading and writing using page numbers + offset has been optimised to be faster than before. +- Optimized the way address and error checking is done so its more efficient and uses few system resources and runs faster. +- Using this library with an ESP8266 board defaults to using GPIO15 as the Slave Select - unless something different is explicitly specified in the constructor. + +
+ +## Version 2.3.1 + +#### Release date 19.06.2016 + +- W25Q256FV support added. (Thanks [@Stanislav-Povolotsky](https://github.com/Marzogh/SPIMemory/pull/26)!) +- Cleaned up redundant code in TestFlash.ino and SPIFlash.h + +
+ +## Version 2.3.0 + +#### Release date 04.06.2016 + +- ESP8266 compatibility added +- Compatible with Arduino Fio and Micro +- Now compatible with Arduino IDE v1.6.9 +- Compatible with Arduino-Makefile. (Thanks [@rnestler](https://github.com/Marzogh/SPIMemory/pull/21) !) + +
+ +## Version 2.2.0 + +#### Release date 24.11.2015 + +- When `#RUNDIAGNOSTIC` is uncommented, the `_troubleshoot()` function is now optimised for different µCs +- Added the ability to check if the address has been previously written to before initiating a write + operation. +- Added a `sizeofStr()` function to get sizes of String objects, to use with the `getAddress()` function +- Fixed a bug with `getAddress()` +- Added the ability get the chip's name via `getChipName()` +- `Diagnostics.ino` has been made more and efficient and provides a cleaner Serial output +- Added `getAddressEx.ino` to show how `getAdress()` works. + +
+ +## Version 2.1.1 + +#### Release date 24.10.2015 + +- Fixed bugs that prevented the following functions from working properly + + * `powerDown()` + * `powerUp()` + * `suspendProg()` + * `resumeProg()` + +
+ +## Version 2.1.0 + +#### Release date 18.10.2015 + +- Arduino Due compatible - refer to wiki for further details +- Fixed bug with write/readByteArray +- Added write/readCharArray +- Added a proper error checking function that gets called when #ifdef RUNDIAGNOSTIC is uncommented in SPIFlash.cpp. + This function returns a verbose error message to the Serial console instead of the terse error codes of the previous version. +- The following functions have been changed to enable bug fixes and uniformity in coding style. + + * `writeBytes()` + * `readBytes()` + + They have been replaced with + + * `readByteArray()` + * `writeByteArray()` + + respectively + +
+ +## Version 2.0.0 + +#### Release date 12.10.2015 + +- Sped up all functions atleast 25x +- Compatible with ATTiny85 +- All Read/Write/Erase functions can now take either (page number & offset) or (address) as arguments (Except `readPage()` & `printPage()`) +- `getAddress()` can now return either a 32-bit address or a page number & offset - Refer to Readme.md +- Error codes explained: + 0x00 SUCCESS Operation successful. + 0x01 CALLBEGIN Please make sure `begin()` has been called in `setup()`. + 0x02 UNKNOWNCHIP Unknown chip manufacturer. + 0x03 UNKNOWNCAP Unknown chip capacity. + 0x04 CHIPBUSY Chip busy. + 0x05 OUTOFBOUNDS Address out of bounds. Please check if `begin()` has been called in `setup()`. + 0x06 CANTENWRITE Unable to `_writeEnable()`. Check wiring/chip. + 0x07 OUTOFMEM Pagenumber outside maximum. + 0x08 OUTOFPAGE Offset is outside page. +- The following functions are deprecated to enable compatibility with other AVR chips. + + * `_printPageBytes()` + * `printPage()` + * `printAllPages()` + * `readSerialStr()` + + They can be used by uncommenting them in the SPIFlash.cpp file. However, be warned, this particular block of code has only been tested with the Arduino IDE (1.6.5) and only with 8-bit AVR based Arduino boards and will not be supported any further. + +
+ +## Version 1.3.2 + +#### Release date 09.10.2015 + + +- Added the ability to read and write String objects with a simple high level function `readStr()` & `writeStr()` +- Added the ability to `getAddress()` +- Added the ability to fastRead to every read function as the last boolean argument (defaults to FALSE) +- Changed the example code as given below: + - Modified `TestFlash.ino` to use 25% less memory + - `Struct_writer.ino` now writes struct to a random location on the Flash Memory chip. + - Added instructions for real world data storage to `Struct_writer.ino` + - `Diagnostics.ino` now provides a cleaner diagnostic readout diff --git a/README.md b/README.md index 4fbefcb..f730003 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ # SPIMemory [![Build Status](https://travis-ci.org/Marzogh/SPIMemory.svg?branch=master)](https://travis-ci.org/Marzogh/SPIMemory) [![DOI](https://zenodo.org/badge/35823047.svg)](https://zenodo.org/badge/latestdoi/35823047) [![GitHub release](https://img.shields.io/github/release/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory) -[![GitHub commits](https://img.shields.io/github/commits-since/Marzogh/SPIMemory/v3.2.1.svg)](https://github.com/Marzogh/SPIMemory/compare/v3.2.1...v3.3.0) +[![GitHub commits](https://img.shields.io/github/commits-since/Marzogh/SPIMemory/v3.3.0.svg)](https://github.com/Marzogh/SPIMemory/compare/v3.3.0...v3.4.0) [![GitHub issues](https://img.shields.io/github/issues/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory/issues) [![GitHub pull requests](https://img.shields.io/github/issues-pr/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory/pulls) [![license](https://img.shields.io/github/license/Marzogh/SPIMemory.svg)](https://github.com/Marzogh/SPIMemory/blob/master/LICENSE) +[![Join the chat at https://gitter.im/SPIMemory/community](https://badges.gitter.im/SPIMemory/community.svg)](https://gitter.im/SPIMemory/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ## Arduino library for Flash & FRAM Memory Chips (SPI based only) Download the latest stable release from [here](https://github.com/Marzogh/SPIMemory/releases/latest). Please report any bugs in [issues](https://github.com/Marzogh/SPIMemory/issues/new). @@ -29,8 +30,10 @@ This Arduino library is for use with flash and FRAM memory chips that communicat | ATmega2560 | Arduino Mega | - | | ATSAMD21G18 (ARM Cortex M0+) | Adafruit Feather M0,
Adafruit Feather M0 Express,
Adafruit ItsyBitsy M0 Express | - | | AT91SAM3X8E (ARM Cortex M3) | Arduino Due | - | +| nRF52832 (ARM Cortex M4F) | Adafruit nRF52 Feather | - | | ATSAMD51J19 (ARM Cortex M4) | Adafruit Metro M4 | - | | STM32F091RCT6 | Nucleo-F091RC | | +| STM32L0 | Nucleo-L031K6 | | | ESP8266 | Adafruit ESP8266 Feather,
Sparkfun ESP8266 Thing | - | | ESP32 | Adafruit ESP32 Feather,
Sparkfun ESP32 Thing | Onboard flash memory. Refer to footnote£ below. | | Simblee | Sparkfun Simblee | - | @@ -46,11 +49,13 @@ This Arduino library is for use with flash and FRAM memory chips that communicat | Winbond | W25Q16BV
W25Q64FV
W25Q64JV
W25Q80BV
W25Q256FV | Should work with the W25QXXXBV, W25QXXXFV &
W25QXXXJV families | | Microchip | SST25VF064C
SST26VF016B
SST26VF032B
SST26VF064B | Should work with the SST25 & SST26 families | | Cypress/Spansion | S25FL032P
S25FL116K
S25FL127S | Should work with the S25FL family | -| ON Semiconductor | LE25U40CMC | | -| AMIC| A25L512A0 | | -| Micron| M25P40 | | -| Adesto| AT25SF041 | | -| Giga devices| GD25Q16C | (Used on the Adafruit ItsyBitsy M0 Express) | +| ON Semiconductor | LE25U40CMC | | +| AMIC| A25L512A0 | | +| Micron| M25P40 | | +| Adesto| AT25SF041 | | +| Macronix| MX25L4005
MX25L4005 | | +| Giga devices| GD25Q16C | (Used on the Adafruit ItsyBitsy M0 Express) | + ##### Should work with any flash memory that is compatible with the SFDP standard as defined in JESD216B @@ -88,6 +93,7 @@ This Arduino library is for use with flash and FRAM memory chips that communicat - Every version of the library >= v3.0.0 supports the ability to use any of multiple SPI interfaces (if your micro-controller supports them). Switching to use another SPI interface is done by calling ```SPIFlash flash(csPin, &SPI1);``` (or &SPI2 and so on), instead of ```SPIFlash flash(csPin)```. * NOTE: This is currently only supported on the SAMD and STM32 architectures. +- An alternate version ```SPIFlash flash (SPIPinsArray)``` of the constructor can be used (only with ESP32 board as of now) to enable the use of custom SPI pins. ```SPIPinsArray``` has to be a 4 element array containing the custom SPI pin numbers (as signed integers - int8_t) in the following order - sck, miso, mosi, ss. - Also make sure to include ```flash.begin(CHIPSIZE*)``` in ```void setup()```. This enables the library to detect the type of flash chip installed and load the right parameters. * Optional @@ -103,13 +109,13 @@ As of v3.2.1, SFDP parameter discovery is an user controlled option. To get the #### SPIFram ^ -- The library is called by declaring the```SPIFram fram(csPin*)``` constructor where 'flash' can be replaced by a user constructor of choice and 'csPin' is the Chip Select pin for the flash module. +- The library is called by declaring the```SPIFram fram(csPin*)``` constructor where 'fram' can be replaced by a user constructor of choice and 'csPin' is the Chip Select pin for the fram module. * Optional. Do not include csPin if using the default slave select pin for your board. - Every version of the library >= v3.0.0 supports the ability to use any of multiple SPI interfaces (if your micro-controller supports them). Switching to use another SPI interface is done by calling ```SPIFram fram(csPin, &SPI1);``` (or &SPI2 and so on), instead of ```SPIFram fram(csPin)```. * NOTE: This is currently only officially supported on the SAMD and STM32 architectures. -- Also make sure to include ```fram.begin(CHIPSIZE*)``` in ```void setup()```. This enables the library to detect the type of flash chip installed and load the right parameters. +- Also make sure to include ```fram.begin(CHIPSIZE*)``` in ```void setup()```. This enables the library to detect the type of fram chip installed and load the right parameters. ^ Currently in BETA. The methods in SPIFram are not final and subject to change over the next few revisions. @@ -279,6 +285,7 @@ Note: If you are unable to fix the error/s, please raise an issue [here](http:// | **0x11** | Unable to read Erase Parameters from chip.
Reverting to library defaults. | | **0x12** | Unable to read erase times from flash memory.
Reverting to library defaults. | | **0x13** | Unable to read program times from flash memory.
Reverting to library defaults. | +| **0x14** | No Chip Select pin defined in the custom SPI Array.
Refer to section about Constructor for information on how to use custom SPI pins. | | **0xFE** | Unknown error.
Please raise an issue. |
diff --git a/examples/FlashDiagnostics/Diagnostics_functions.ino b/examples/FlashDiagnostics/Diagnostics_functions.ino index 00b4b1d..6aa3745 100644 --- a/examples/FlashDiagnostics/Diagnostics_functions.ino +++ b/examples/FlashDiagnostics/Diagnostics_functions.ino @@ -556,4 +556,3 @@ void eraseChipTest() { } } - diff --git a/examples/FlashDiagnostics/FlashDiagnostics.ino b/examples/FlashDiagnostics/FlashDiagnostics.ino index 031ba47..973cb71 100644 --- a/examples/FlashDiagnostics/FlashDiagnostics.ino +++ b/examples/FlashDiagnostics/FlashDiagnostics.ino @@ -2,10 +2,10 @@ |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| | FlashDiagnostics.ino | | SPIMemory library | - | v 3.2.0 | + | v 3.4.0 | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| | Marzogh | - | 02.05.2018 | + | 01.06.2019 | |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| | | | For a full diagnostics rundown - with error codes and details of the errors | @@ -37,15 +37,20 @@ #define TRUE 1 #define FALSE 0 +int8_t SPIPins[4] = {-1, -1, -1, 33}; + SPIFlash flash; -//SPIFlash flash(11); +//SPIFlash flash(SPIPins); +//SPIFlash flash(33); //SPIFlash flash(SS1, &SPI1); //Use this constructor if using an SPI bus other than the default SPI. Only works with chips with more than one hardware SPI bus void setup() { + Serial.begin(BAUD_RATE); -#if defined (ARDUINO_ARCH_SAMD) || (__AVR_ATmega32U4__) || defined(ARCH_STM32) || defined(NRF5) +#if defined (ARDUINO_ARCH_SAMD) || defined (__AVR_ATmega32U4__) || defined (ARCH_STM32) || defined (NRF5) || defined (ARDUINO_ARCH_ESP32) while (!Serial) ; // Wait for Serial monitor to open #endif + delay(50); //Time to terminal get connected Serial.print(F("Initialising")); for (uint8_t i = 0; i < 10; ++i) @@ -54,9 +59,14 @@ void setup() { } Serial.println(); randomSeed(analogRead(RANDPIN)); + + if (flash.error()) { + Serial.println(flash.error(VERBOSE)); + } + flash.begin(); //To use a custom flash memory size (if using memory from manufacturers not officially supported by the library) - declare a size variable according to the list in defines.h - //flash.begin(MB(1)); + //flash.begin(MB(32)); if (getID()) { diff --git a/extras/Changes.log b/extras/Changes.log deleted file mode 100644 index a14eebd..0000000 --- a/extras/Changes.log +++ /dev/null @@ -1,391 +0,0 @@ -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// SPIMemory Library // -// Changes log // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 3.3.0 // -// Author: Prajwal Bhattaram // -// 20.04.2019 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Library now supports FRAM memory (In BETA). Documentation for this is in progress. - -Bugs squashed: ---> Fixed a major bug causing issues with page boundaries in writeAnything and writeStr. Thanks for your help @jacky4566 (Issue #151) ---> Fixed a major bug with reading Strings (Issue #143) ---> @incorvia fixed a bug by initialising the SPIBusState to false ---> Fixes bug that causes ballooning of pagesize when SFDP is not read. This is because no default _pageSize value was set in this scenario. This has now been fixed. ---> Fixed a major bug in how SFDP data is used to calculate chip capacity. The previous version of the library returned a wrong value. This has now been fixed. Refer to comments in _getSFDPFlashParam(void) for further details. - -Enhancements: ---> Reduce SRAM footprint when running Diagnostics.ino. Thanks @rambo (PR #157) ---> Officially supports the ESP32 (tested on the ESP32 Feather) ---> Now supports FRAM memory chips via the `SPIFram` constructor ---> Changed Diagnostics output in _chipID() to match situation better. ---> Fixed _chipID() to run more efficiently. - -New flash memory chips supported: ---> GD25Q16C from Giga devices (Used on the Adafruit ItsyBitsy M0 Express) ---> W25Q64JV from Winbond ---> SST26VF016B & SST26VF032B from Microchip. (Thanks @mix86) - -New FRAM memory chips supported: ---> FM25W256 from Cypress -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 3.2.1 // -// Author: Prajwal Bhattaram // -// 13.04.2018 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - -Bugs squashed ---> Fixes issue #135 : The addition of the SFDP checking to _chipID resulted in a sudden (very large) increase in compiled code size. As of the current version (v3.2.1), SFDP checking is an user controlled option. To get the library to work with SFDP compatible flash memory that is not officially supported, the user must uncomment '//#define USES_SFDP' in 'SPIMemory.h'. - ---> Moved `bool _loopedOver` from being a local variable in `getAddress()` to a global one. Now it actually does what it was meant to do - i.e. prevent looping over data a second time. - -Enhancements ---> The way the basic functions execute has been modified to keep the function runtime the same (or improved) while reducing their memory footprint. - - Test sketch - FlashDiagnostics.ino from v3.2.0 with #RUNDIAGNOSTIC commented out - Test platform - Arduino Pro Mini 8MHz 3.3V - Library version: v3.1.0 Compiled code size - 17652 bytes (SFDP discovery not supported) - Library version: v3.2.0 Compiled code size - 20104 bytes (SFDP discovery supported & on by default) (13.9% larger than v3.1.0) - Library version: v3.2.1 Compiled code size - 15316 bytes (SFDP discovery turned off) (13.75% smaller than v3.1.0) - Library version: v3.2.1 Compiled code size - 17854 bytes (SFDP discovery turned on) (1.1% larger than v3.1.0) - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 3.2.0 // -// Author: Prajwal Bhattaram // -// 13.04.2018 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// ---> Library name changed to SPIMemory - ---> The library now gathers sfdp information through _chipID(). SFDP information is collected when available, otherwise the library defaults to the pre v3.2.0 version. - -New flash memory chips supported ---> All flash memories compatible with the SFDP standard (as at JESD216B) should be compatible with the library - ---> LE25U40CMC from ON Semiconductor ---> A25L512A0 from AMIC ---> M25P40 from Micron ---> AT25SF041 from Adesto ---> S25FL032P from Cypress/Spansion - -New Microcontrollers supported ---> ATSAMD51J19 ARM Cortex M4 (Adafruit Metro M4) - -Bugs squashed - -Enhancements -The library now does the following - if the flash memory chip is compatible with the SFDP standard: ---> Identifies the flash memory chip using the Serial Flash Discoverable Parameters standard. (JESD216B) ---> Identifies the following opcodes from the SFDP tables and uses them to read/write data: - - eraseSector, eraseBlock32K, eraseBlock64K ---> Reads timing information from SFDP to accurately time the following operations: - - eraseSector, eraseBlock32K, eraseBlock64K -- Fixes #125 in commit 10c2b86. The library automatically uses the alternate chip erase code (0xC7) as required (only on fully supported chips) - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 3.1.0 // -// Author: Prajwal Bhattaram // -// 24.02.2018 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// ---> Library name change notice inserted into flash.begin(). This notice can be dismissed by commenting out the instance of `#define PRINTNAMECHANGEALERT` in SPIFlash.h. Please refer to the Readme file for further details. - -Bugs squashed ---> An error with how _addressCheck() works with data that spans the memory boundary - when rolling over from address '_chip.capacity' to address '0x00' - has been fixed. In previous versions this caused issues with writing complex data structures across the memory boundary and led to many _writeErrorCheck() failures. Fixes issue #112 - ---> An error with how _writeErrorCheck() worked has been resolved. Writing structs is now as stable as other functions are. Fixes #106 - ---> All compilation-time, non-critical errors have been fixed. - -Enhancements: ---> A new function - 'flash.eraseSection(address, size)' - has been introduced in this version. When a user requires a large and variable (between writes) amount of data to be written to the flash memory on the fly and to have the correct amount of space erased to fit the data, this function will automatically calculate and erase the right amount of space to fit the data. Please note that if the the amount of data being written is consistently the same size, the pre-existing 'flash.eraseSector()', 'flash.eraseBlock32K()' and 'flash.eraseBlock64K()' functions will operate a lot faster. - ---> Updated Diagnostics.ino to include eraseSection(). - ---> All I/O functions now check to see if the flash chip is powered down. If it is, they prevent the function from running and returns an error. A new error code 'CHIPISPOWEREDDOWN' will be returned upon calling flash.error(). - - -New flash memory chips supported: ---> S25FL127S -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 3.0.1 // -// Author: Prajwal Bhattaram // -// 10.12.2017 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Bugs squashed: -**************** -Thanks for catching and fixing the following @hanyazou (PR #101) ---> Added missing break statements in SPIFlash::_beginSPI() because that lacks some essential break statement in switch/case. (commit 1: 1de2c10) ---> The library did not wait until the busy bit in SR1 was cleared. Timeout argument of _notBusy() must be in micro-second. 500L means 500 micro seconds which is too short to wait for completion of erase command. Added " * 1000" to the arguments. (commit 2: 9633c2f) ---> Modified TestFlash.ino to check error of erase commands execution. (commit 3: a179306) -**************** ---> Fixes a major bug that was causing input Arrays to be overwritten by zeros during the writeByteArray() / writeCharArray() process. Thanks for catching this @hanyazou. (Issue #102) - -New flash memory chips supported: ---> S25FL127S -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 3.0.0 // -// Author: Prajwal Bhattaram // -// 09.08.2017 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Bugs Squashed: ---> The writeByteArray() & writeCharArray() bug that occurred when writing arrays that spanned page boundaries (squashed in v2.5.0), stayed around to haunt the other functions. Writing any data larger than a single byte that spanned page boundaries would cause the data to wrap around to the beginning of the page. The likelihood of this occurring was slim - no one has reported it to date. However, just in case, this has now been squashed in this release. - -Deprecations: ---> Going forward the ATTiny85 is no longer officially supported. ---> The library no longer supports using the page number + offset combination instead of addresses. If your code requires you to use a page number + offset combination, use the following code to help - address = (pagenumber << 8) + offset. - _____________________________________ - (32 bit) | (16 bit) | (8 bit) ---> The constructor no longer takes the pageOverflow variable as an argument. Page overflow is globally enabled by default and can be disabled by including a "#define DISABLEOVERFLOW" at the beginning of SPIFlash.h. - -New Boards supported: ---> Nucleo-F091RC ---> Adafruit Feather M0 - -New Flash manufacturers supported: ---> Microchip (SST25 & SST26 series) ---> Cypress ---> Spansion - -Enhancements: ---> Confirmed to work with SPANSION/CYPRESS & MICROCHIP (Both SST25 & SST26 series). ---> If not using an officially supported chip, use the following variation of flash.begin() : - flash.begin(flashChipSize); - - where flashChipSize is indicated in Bytes, Kilobytes or Megabytes. (Refer to the next two items in this change log) ---> Including 'flashChipSize' in flash.begin() compiles more efficiently than in previous versions. ---> The way memory size is indicated by the users in flash.begin(flashChipSize) has changed - please refer to defines.h or the wiki for further information. The new method enables users to define any custom size unlike the previous version where only a limited number of predetermined sizes were available to use. ---> Library faster than before (Refer to Library speed comparison in the extras folder for timing details): - - Improvements in speed in v3.0.0 when compared to v2.7.0 (values in percentage of time v3.0.0 is faster than v2.7.0) - (+) writeByte -> +3% - (+) writeChar -> +6% - (+) writeWord -> +3% - (+) writeShort -> +5% - (+) writeULong -> +7% - (+) writeLong | readLong -> +7% | +7% - (+) writeFloat -> +7% - (+) writeStr | readStr -> +57% | +61% - (+) writeAnything | readAnything (struct) -> +25% | +20% - (+) writeByteArray | readByteArray (256 bytes) -> +18% | +45% - (+) eraseSector -> +99% - (+) eraseBlock32K -> +99.4% - (+) eraseBlock64K -> +99.5% - (+) eraseChip -> +12% - ---> Constructor changed to enable user to choose one of multiple SPI ports - if available. Look at wiki for further info ---> When RUNDIAGNOSTIC is uncommented in SPIFlash.h, users now have access to a new function called flash.functionRunTime() which can be called after any library I/O function is run. flash.functionRunTime() returns the time taken by the previous function to run, in microseconds (as a float). An example use case can be found when the FlashDiagnostics sketch is run with RUNDIAGNOSTIC uncommented. ---> _notBusy() is faster ---> Completely re-written FlashDiagnostics - uses fewer resources, compatible with more chips and boards ---> All functions except the Byte/Char Array Read/Write functions now call an internal _write/_read function for increased ease of compilation, execution and troubleshooting ---> Restructured the internal _troubleshoot() function to be better human readable and faster to compile. ---> Added a function `getUniqueID()` which returns the unique ID of the flash memory chip as a 64-bit integer. ---> Added an internal _readStat3() function to enable 4-byte addressing when using flash memory larger than 128 MB ---> 4-byte addressing enabled in flash memory larger than 128 MB. This is currently only supported on the W25Q256 and W25Q512. More chips will be supported on a case-by-case basis ---> getAddress() function now works anytime it is called - even if there is preexisting data on the chip -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.7.0 // -// Author: Prajwal Bhattaram // -// 17.04.2017 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Bugs Squashed: ---> ATTiny85 support available again. - -Deletions: ---> - -New Boards supported: ---> Arduino Zero now fully supported. - -Enhancements: ---> Compatible with the ESP32 core for Arduino as of the current commit 9618eec on 02.08.2017. For some unknown reason, SPI clock speeds higher than board speed/4 are not stable and so, the clock speed for ESP32 dev boards has currently been throttled to 20MHz. -NOTE: ESP32 boards usually have an SPIFlash already attached to their SS pin, so the user has to declare the ChipSelect pin being used when the constructor is declared - for example -``` -SPIFlash flash(33); -``` -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.6.0 // -// Author: Prajwal Bhattaram // -// 16.04.2017 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Bugs Squashed: ---> Fixed issue with reading status register 2 and the Suspend operation where the library was not checking the suspend status correctly. - -Deletions: ---> flash.getChipName() has been removed as it is superfluous now that the library is now on its way to multi-chip compatibility. ---> Library is not compatible with the ATTiny85 anymore. Currently working on a fix which will hopefully be rolled out in v2.7.0 - -New Boards supported: ---> RTL8195A compatibility tested and enabled by @boseji on 02.03.17. Code modified to fit with the library structure by Prajwal Bhattaram on 14.04.17. ---> Compatible with the ESP32 core for Arduino as of the current commit 7d0968c on 16.04.2017. The ESP32 core currently does not support analogRead and so randomSeed(AnalogRead(A0)) cannot be used. Also, for some unknown reason, SPI clock speeds higher than board speed/4 are not stable and so, the clock speed for ESP32 dev boards has currently been throttled to 20MHz. ---> Added support for the Simblee module. - -Enhancements: ---> flash.error() now takes an optional argument 'VERBOSE'. By default the verbosity argument is set to 'false' and calling flash.error() still returns the latest error code as an unsigned byte. However, running flash.error(VERBOSE) will not only return the latest error code, but will also print it to serial. This - especially in boards with resources to spare - will result in a detailed error report printed to serial. ---> flash.begin() now returns a boolean value to indicate establishment of successful comms with the flash chip. Usercode can be made more efficient now by calling ```if (!flash.begin()) { Serial.println(flash.error(VERBOSE)); }``` to identify a problem as soon as the library code is run. ---> The internal _addressCheck() function now locks up usercode with appropriate error codes if - a) flash.begin() has not been called (or) - b) There is a possible issue with the wiring - i.e. the flash chip is non-responsive (or) - c) If the chip's capacity either cannot be identified & the user has not defined a chipSize in flash.begin(). ---> Fixed powerDown() to be more efficient. The chip now powers down much faster than before. ---> Added a new error code. Library can now detect non-responsive chips - bad wiring or otherwise. ---> Streamlined variables to make code structure better. ---> Changed library structure to enable the addition of multi-flash compatibility in the near future. ---> moved `#define RUNDIAGNOSTIC` & `#define HIGHSPEED` to SPIFlash.h from SPIFlash.cpp. ---> Now works with other Winbond modules (not in the official supported module list) (beta) by taking the flash memory size in bits as an argument in flash.begin(_chipSize); ---> Formatted code to be better human readable. ---> Changed the internal _troubleshoot() function to use fewer resources. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.5.0 // -// Author: Prajwal Bhattaram // -// 13.11.2016 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Bugs Squashed: ---> Errorchecking on writeByteArray() and writeCharArray() was broken in 2.4.0 and is fixed now. ---> Previous versions (< 2.5.0) suffered from the inability to write datasets that spanned page boundaries. This has now been fixed (Ref. Enhancements section below) - -Deletions: ---> flash.writePage() & flash.readPage() have been retired as they can be duplicated - more effectively - by other functions. Refer to pageDiag() in Diagnostics.ino to see how the same results can be obtained by using flash.writeByteArray() & flash.readByteArray(). - -Enhancements: ---> Added support for SPI Transactions. ---> Added an upgrade for Arduino Due users to read and write large arrays of data at very high speeds - previously reading 60kb of data would take ~108ms - it now takes ~525uS. In this mode, the time between consecutive reads has been reduced to <12ms (needs more work!). ---> Completely re-written writeByteArray() and writeCharArray() functions. They no longer breakdown when writing arrays that span multiple pages. ---> All functions that write more than 1 byte of data now take into account page boundaries when writing across pages. In previous versions writing across a page boundary would cause the remainder of the data to wrap around to the beginning of the page. Now the data is written seamlessly from one page over to the next. ---> Calling flash.begin() now instantiates the SPI bus. Comms with other SPI slaves do not need to call SPI.begin() if flash.begin() has already been called first in the user's code. ---> Sped up _beginSPI(). Code in _beginSPI() instantiates the SPI bus if another SPI comms library has shut it down. ---> Added function allowing setting SPI clock speeds - call the function ```flash.setClock(uint32_t clockSpeed);``` straight after ```begin();```. ---> Made _beginSPI() & _nextByte() shorter and faster. ---> Replaced all calls to SPI.transfer() with xfer() to make the code more human readable and to enable simplicity when switching platforms. ---> Added the ability to change Chip Erase wait times depending on the chip (supported chips only). ---> Don't need to ```#include ``` in user code anymore. Just ```#include``` will do. Examples are now updated. ---> Now supports & uses SPI.transfer(*buf, count) along with the standard SPI.transfer(), speeding up the read/write of anything larger than an byte (AVR Boards only) ---> Reduces the program storage space in the uC's flash (AVR Boards) - -To-do ---> Need to find a way to better identify _notPrevWritten(); ---> Need to fix up eraseBlock32K, eraseBlock64K and eraseSector times -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.4.0 // -// Author: Prajwal Bhattaram // -// 11.09.2016 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -Bugs Squashed: ---> Fixed bug preventing writing to Address 0x00 ---> Fixed bug in _notPrevWritten() which did did not perform a thorough enough check to see if a location had been previously written to. ---> Fixed errorchecking bug - it now works for all data types - not just byte/char as previously. -Enhancements & Optimizations: ---> Added a function 'error()' to enable users to check for errors generated at any point in their program. ---> Optimized writePage() so it doesn't depend on other functions and so runs faster than before. ---> Diagnostics.ino now outputs time taken for each function as a part of its and provides additional diagnostic data. ---> Now have a common set of private functions - _prep(), _beginSPI(), _nextByte() & _endSPI() - to replace _prepWrite(), _prepRead(), _beginRead(), _readNextByte(), _beginWrite(), _writeNextByte() & _endProcess(); ---> Changed the way _addressCheck() works. It now checks all addresses involved in writing the data rather than one address block at a time and returns the correct address to write to in case overflow is enabled. Also, this function is now built into _prep(). ---> Reading and writing using page numbers + offset has been optimised to be faster than before. ---> Optimized the way address and error checking is done so its more efficient and uses few system resources and runs faster. ---> Using this library with an ESP8266 board defaults to using GPIO15 as the Slave Select - unless something different is explicitly specified in the constructor. -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.3.1 // -// Author: Prajwal Bhattaram // -// 19.06.2016 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> W25Q256FV support added. (Thanks Stanislav-Povolotsky!) ---> Cleaned up redundant code in TestFlash.ino and SPIFlash.h -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.3.0 // -// Author: Prajwal Bhattaram // -// 04.06.2016 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> ESP8266 compatibility added ---> Compatible with Arduino Fio and Micro ---> Now compatible with Arduino IDE v1.6.9 ---> Compatible with Arduino-Makefile. (Thanks Raphael!) -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.2.0 // -// Author: Prajwal Bhattaram // -// 24.11.2015 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> When #RUNDIAGNOSTIC is uncommented, the _troubleshoot() function is now optimised for different µCs ---> Added the ability to check if the address has been previously written to before initiating a write - operation. ---> Added a sizeofStr() function to get sizes of String objects, to use with the getAddress() function ---> Fixed a bug with getAddress() ---> Added the ability get the chip's name via getChipName() ---> Diagnostics.ino has been made more and efficient and provides a cleaner Serial output ---> Added getAddressEx.ino to show how getAdress() works. - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.1.1 // -// Author: Prajwal Bhattaram // -// 24.10.2015 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> Fixed bugs that prevented the following functions from working properly - A. powerDown() - B. powerUp() - C. suspendProg() - D. resumeProg() - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.1.0 // -// Author: Prajwal Bhattaram // -// 18.10.2015 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> Arduino Due compatible - refer to wiki for further details ---> Fixed bug with write/readByteArray ---> Added write/readCharArray ---> Added a proper error checking function that gets called when #ifdef RUNDIAGNOSTIC is uncommented in SPIFlash.cpp. - This function returns a verbose error message to the Serial console instead of the terse error codes of the previous version. ---> The following functions have been changed to enable bug fixes and uniformity in coding style. - A. writeBytes() - B. readBytes() - They have been replaced with readByteArray() and writeByteArray(). - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 2.0.0 // -// Author: Prajwal Bhattaram // -// 12.10.2015 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> Sped up all functions atleast 25x ---> Compatible with ATTiny85 ---> All Read/Write/Erase functions can now take either (page number & offset) or (address) as arguments - (Except readPage() & printPage()) ---> getAddress() can now return either a 32-bit address or a page number & offset - Refer to Readme.md ---> Error codes explained: - 0x00 SUCCESS Operation successful. - 0x01 CALLBEGIN Please make sure .begin() has been called in setup(). - 0x02 UNKNOWNCHIP Unknown chip manufacturer. - 0x03 UNKNOWNCAP Unknown chip capacity. - 0x04 CHIPBUSY Chip busy. - 0x05 OUTOFBOUNDS Address out of bounds. Please check if .begin() has been called in setup(). - 0x06 CANTENWRITE Unable to _writeEnable. Check wiring/chip. - 0x07 OUTOFMEM Pagenumber outside maximum. - 0x08 OUTOFPAGE Offset is outside page. ---> The following functions are deprecated to enable compatibility with other AVR chips. - - A. _printPageBytes() - B. printPage() - C. printAllPages() - D. readSerialStr() - - They can be used by uncommenting them in the SPIFlash.cpp file. However, be warned, this particular block of code has only - been tested with the Arduino IDE (1.6.5) and only with 8-bit AVR based Arduino boards and will not be supported any further. - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// -// Version 1.3.2 // -// Author: Prajwal Bhattaram // -// 09.10.2015 // -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - ---> Added the ability to read and write String objects with a simple high level function readStr() & writeStr() ---> Added the ability to getAddress() ---> Added the ability to fastRead to every read function as the last boolean argument (defaults to FALSE) ---> Changed the example code as given below: - --> Modified TestFlash.ino to use 25% less memory - --> Struct_writer.ino now writes struct to a random location on the Flash Memory chip. - --> Added instructions for real world data storage to Struct_writer.ino - --> Diagnostics.ino now provides a cleaner diagnostic readout diff --git a/extras/Library speed comparisons.xlsx b/extras/Library speed comparisons.xlsx index 902eda6..30d2b76 100644 Binary files a/extras/Library speed comparisons.xlsx and b/extras/Library speed comparisons.xlsx differ diff --git a/library.properties b/library.properties index f4aa52a..25391af 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ name=SPIMemory -version=3.3.0 +version=3.4.0 author=Prajwal Bhattaram maintainer=Prajwal Bhattaram sentence=SPI Memory library for Arduino. (Formerly SPIFlash) paragraph=This library enables read, write, erase and power functions on number of compatible flash and fram memory chips. Refer to change log for further information about this release. To download any version of this library pre v3.2.0 (pre name-change from SPIFlash please visit https://github.com/Marzogh/SPIMemory/releases?after=v3.2.0 ) category=Data Storage url=https://github.com/Marzogh/SPIMemory -architectures=avr,sam,samd,esp8266,esp32,Simblee,stm32 +architectures=avr,sam,samd,esp8266,esp32,Simblee,stm32,nrf52 includes=SPIMemory.h diff --git a/src/DMASAM.cpp b/src/DMASAM.cpp index 98c2e2d..8aa7f05 100644 --- a/src/DMASAM.cpp +++ b/src/DMASAM.cpp @@ -1,4 +1,4 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 30/09/2016 * Original code from @manitou48 diff --git a/src/DMASAM.h b/src/DMASAM.h index 3f26a64..3ec9f88 100644 --- a/src/DMASAM.h +++ b/src/DMASAM.h @@ -1,4 +1,4 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/04/2018 * Modified by Prajwal Bhattaram - 19/06/2018 diff --git a/src/SPIFlash.cpp b/src/SPIFlash.cpp index cc0e663..94a5e91 100644 --- a/src/SPIFlash.cpp +++ b/src/SPIFlash.cpp @@ -1,8 +1,8 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 20/05/2015 * Modified by @boseji - 02/03/2017 - * Modified by Prajwal Bhattaram - 20/04/2019 + * Modified by Prajwal Bhattaram - 03/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -27,36 +27,75 @@ #include "SPIFlash.h" // Constructor -//If board has multiple SPI interfaces, this constructor lets the user choose between them // Adding Low level HAL API to initialize the Chip select pinMode on RTL8195A - @boseji 2nd March 2017 #if defined (ARDUINO_ARCH_AVR) SPIFlash::SPIFlash(uint8_t cs) { + _SPIInUse = STDSPI; csPin = cs; cs_mask = digitalPinToBitMask(csPin); pinMode(csPin, OUTPUT); CHIP_DESELECT } -#elif defined (ARDUINO_ARCH_SAMD) || defined (ARCH_STM32) +#elif defined (ARDUINO_ARCH_SAMD) || defined (ARCH_STM32) || defined(ARDUINO_ARCH_ESP32) SPIFlash::SPIFlash(uint8_t cs, SPIClass *spiinterface) { _spi = spiinterface; //Sets SPI interface - if no user selection is made, this defaults to SPI + if (_spi == &SPI) { + _SPIInUse = STDSPI; + } + else { + _SPIInUse = ALTSPI; + } csPin = cs; pinMode(csPin, OUTPUT); CHIP_DESELECT } + #elif defined (BOARD_RTL8195A) SPIFlash::SPIFlash(PinName cs) { + _SPIInUse = STDSPI; gpio_init(&csPin, cs); gpio_dir(&csPin, PIN_OUTPUT); gpio_mode(&csPin, PullNone); gpio_write(&csPin, 1); CHIP_DESELECT } + #else +//#elif defined (ALTSPI) +//If board has multiple SPI interfaces, this overloaded constructor lets the user choose between them. Currently only works with ESP32 +SPIFlash::SPIFlash(int8_t *SPIPinsArray) { + _nonStdSPI.sck = SPIPinsArray[0]; + _nonStdSPI.miso = SPIPinsArray[1]; + _nonStdSPI.mosi = SPIPinsArray[2]; + _nonStdSPI.ss = SPIPinsArray[3]; + if (_nonStdSPI.ss == -1) + { + _troubleshoot(NOCHIPSELECTDECLARED, PRINTOVERRIDE); + return; + } + else { + csPin = _nonStdSPI.ss; + } + + if (_nonStdSPI.sck == -1 || _nonStdSPI.sck == -1 || _nonStdSPI.sck == -1) { + _SPIInUse = STDSPI; + } + else { + _SPIInUse = ALTSPI; + } + + pinMode(csPin, OUTPUT); + CHIP_DESELECT +} + +//#else SPIFlash::SPIFlash(uint8_t cs) { + _SPIInUse = STDSPI; csPin = cs; pinMode(csPin, OUTPUT); CHIP_DESELECT } + #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// @@ -73,10 +112,24 @@ bool SPIFlash::begin(uint32_t flashChipSize) { Serial.println(F("Highspeed mode initiated.")); Serial.println(); #endif - BEGIN_SPI + if (_SPIInUse == ALTSPI) { + #if defined (ARDUINO_ARCH_ESP32) + SPI.begin(_nonStdSPI.sck, _nonStdSPI.miso, _nonStdSPI.mosi, _nonStdSPI.ss); + #endif + } + else { + BEGIN_SPI + } + #ifdef SPI_HAS_TRANSACTION //Define the settings to be used by the SPI bus - _settings = SPISettings(SPI_CLK, MSBFIRST, SPI_MODE0); + if (!_SPISettingsSet) { + _settings = SPISettings(SPI_CLK, MSBFIRST, SPI_MODE0); + } +#else + if (!_clockdiv) { + _clockdiv = SPI_CLOCK_DIV2; + } #endif bool retVal = _chipID(flashChipSize); _endSPI(); @@ -90,6 +143,11 @@ bool SPIFlash::begin(uint32_t flashChipSize) { #ifdef SPI_HAS_TRANSACTION void SPIFlash::setClock(uint32_t clockSpeed) { _settings = SPISettings(clockSpeed, MSBFIRST, SPI_MODE0); + _SPISettingsSet = true; +} +#else +void SPIFlash::setClock(uint8_t clockdiv) { + _clockdiv = clockdiv; } #endif @@ -125,9 +183,9 @@ float SPIFlash::functionRunTime(void) { //Returns the library version as three bytes bool SPIFlash::libver(uint8_t *b1, uint8_t *b2, uint8_t *b3) { - *b1 = LIBVER; - *b2 = LIBSUBVER; - *b3 = BUGFIXVER; + *b1 = SPIFLASH_LIBVER; + *b2 = SPIFLASH_LIBSUBVER; + *b3 = SPIFLASH_REVVER; return true; } diff --git a/src/SPIFlash.h b/src/SPIFlash.h index d3ba888..3a0c380 100644 --- a/src/SPIFlash.h +++ b/src/SPIFlash.h @@ -1,8 +1,8 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/05/2015 * Modified by @boseji - 02/03/2017 - * Modified by Prajwal Bhattaram - 20/04/2019 + * Modified by Prajwal Bhattaram - 03/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -33,16 +33,21 @@ class SPIFlash { public: //------------------------------------ Constructor ------------------------------------// //New Constructor to Accept the PinNames as a Chip select Parameter - @boseji 02.03.17 - #if defined (ARDUINO_ARCH_SAMD) || defined(ARCH_STM32) + #if defined (ARDUINO_ARCH_SAMD) || defined(ARCH_STM32) || defined(ARDUINO_ARCH_ESP32) SPIFlash(uint8_t cs = CS, SPIClass *spiinterface=&SPI); #elif defined (BOARD_RTL8195A) SPIFlash(PinName cs = CS); #else SPIFlash(uint8_t cs = CS); + SPIFlash(int8_t *SPIPinsArray); #endif //----------------------------- Initial / Chip Functions ------------------------------// bool begin(uint32_t flashChipSize = 0); + #ifdef SPI_HAS_TRANSACTION void setClock(uint32_t clockSpeed); + #else + void setClock(uint8_t clockdiv); + #endif bool libver(uint8_t *b1, uint8_t *b2, uint8_t *b3); bool sfdpPresent(void); uint8_t error(bool verbosity = false); @@ -152,15 +157,32 @@ class SPIFlash { //-------------------------------- Private variables ----------------------------------// #ifdef SPI_HAS_TRANSACTION SPISettings _settings; + bool _SPISettingsSet = false; + #else + uint8_t _clockdiv; #endif + //If multiple SPI ports are available this variable is used to choose between them (SPI, SPI1, SPI2 etc.) SPIClass *_spi; + #if !defined (BOARD_RTL8195A) uint8_t csPin; #else // Object declaration for the GPIO HAL type for csPin - @boseji 02.03.17 gpio_t csPin; #endif + + // Variables specific to using non-standard SPI (currently only tested with ESP32) + struct _SPIPins { + int8_t sck = -1; + int8_t miso = -1; + int8_t mosi = -1; + int8_t ss = -1; + }; + _SPIPins _nonStdSPI; + //_SPIPins _stdSPI; + uint8_t _SPIInUse; + volatile uint8_t *cs_port; bool pageOverflow; bool SPIBusState = false; @@ -200,7 +222,7 @@ class SPIFlash { {KB(64), KB(128), KB(256), KB(512), MB(1), MB(2), MB(4), MB(8), MB(16), MB(32), MB(2), MB(4), MB(8), MB(8), KB(256), KB(512), MB(4), KB(512)}; // To understand the _memSize definitions check defines.h - const uint8_t _supportedManID[8] = {WINBOND_MANID, MICROCHIP_MANID, CYPRESS_MANID, ADESTO_MANID, MICRON_MANID, ON_MANID, GIGA_MANID, AMIC_MANID}; + const uint8_t _supportedManID[9] = {WINBOND_MANID, MICROCHIP_MANID, CYPRESS_MANID, ADESTO_MANID, MICRON_MANID, ON_MANID, GIGA_MANID, AMIC_MANID, MACRONIX_MANID}; const uint8_t _altChipEraseReq[3] = {A25L512, M25P40, SST26}; }; diff --git a/src/SPIFlashIO.cpp b/src/SPIFlashIO.cpp index 2bf7121..083ed29 100644 --- a/src/SPIFlashIO.cpp +++ b/src/SPIFlashIO.cpp @@ -1,8 +1,8 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/05/2015 * Modified by @boseji - 02/03/2017 - * Modified by Prajwal Bhattaram - 20/04/2019 + * Modified by Prajwal Bhattaram - 03/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -174,7 +174,7 @@ #ifdef SPI_HAS_TRANSACTION SPI.beginTransaction(_settings); #else - SPI.setClockDivider(SPI_CLOCK_DIV4); + SPI.setClockDivider(_clockdiv); SPI.setDataMode(SPI_MODE0); SPI.setBitOrder(MSBFIRST); #endif @@ -202,8 +202,8 @@ case FASTREAD: _nextByte(WRITE, opcode); - _nextByte(WRITE, DUMMYBYTE); _transferAddress(); + _nextByte(WRITE, DUMMYBYTE); break; case SECTORERASE: @@ -259,7 +259,10 @@ //Reads/Writes next data buffer. Should be called after _beginSPI() void SPIFlash::_nextBuf(uint8_t opcode, uint8_t *data_buffer, uint32_t size) { + #if !defined(ARDUINO_ARCH_SAM) && !defined(ARDUINO_ARCH_SAMD) && !defined(ARDUINO_ARCH_AVR) uint8_t *_dataAddr = &(*data_buffer); + #endif + switch (opcode) { case READDATA: #if defined (ARDUINO_ARCH_SAM) @@ -562,6 +565,22 @@ Serial.println(F("No Chip size defined by user. Checking library support.")); #endif //Identify capacity + if(_chip.manufacturerID == MACRONIX_MANID) + { + switch(_chip.capacityID) + { + case MX25L4005: + _chip.capacity = MB(4); + break; + + case MX25L8005: + _chip.capacity = MB(8); + break; + + default: + _troubleshoot(UNKNOWNCHIP); //Error code for unidentified capacity + } //TODO - Set up other manufaturerIDs in a similar pattern. + } for (uint8_t j = 0; j < sizeof(_capID); j++) { if (_chip.capacityID == _capID[j]) { _chip.capacity = (_memSize[j]); @@ -576,7 +595,7 @@ else { if (_chip.sfdpAvailable) { #ifdef RUNDIAGNOSTIC - Serial.println("SFDP ID finished."); + Serial.println(F("SFDP ID finished.")); #endif return true; } @@ -588,7 +607,9 @@ } if (!_chip.capacity) { - + #ifdef RUNDIAGNOSTIC + Serial.println(F("Chip capacity cannot be identified")); + #endif if (flashChipSize) { // If a custom chip size is defined #ifdef RUNDIAGNOSTIC diff --git a/src/SPIFlashSFDP.cpp b/src/SPIFlashSFDP.cpp index 1f22d83..0184db8 100644 --- a/src/SPIFlashSFDP.cpp +++ b/src/SPIFlashSFDP.cpp @@ -1,4 +1,4 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 18/04/2018 * Modified by Prajwal Bhattaram - 19/06/2018 diff --git a/src/SPIFram.cpp b/src/SPIFram.cpp index 947cdff..ea164c3 100644 --- a/src/SPIFram.cpp +++ b/src/SPIFram.cpp @@ -1,6 +1,7 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/06/2018 + * Modified by Prajwal Bhattaram - 03/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -117,9 +118,9 @@ float SPIFram::functionRunTime(void) { //Returns the library version as three bytes bool SPIFram::libver(uint8_t *b1, uint8_t *b2, uint8_t *b3) { - *b1 = LIBVER; - *b2 = LIBSUBVER; - *b3 = BUGFIXVER; + *b1 = SPIFRAM_LIBVER; + *b2 = SPIFRAM_LIBSUBVER; + *b3 = SPIFRAM_REVVER; return true; } diff --git a/src/SPIFram.h b/src/SPIFram.h index 4eb6669..ee900f8 100644 --- a/src/SPIFram.h +++ b/src/SPIFram.h @@ -1,4 +1,4 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/06/2018 * diff --git a/src/SPIFramIO.cpp b/src/SPIFramIO.cpp index 60dd4b4..859301c 100644 --- a/src/SPIFramIO.cpp +++ b/src/SPIFramIO.cpp @@ -1,4 +1,4 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/06/2018 * diff --git a/src/SPIMemory.cpp b/src/SPIMemory.cpp index 7788c42..92ddfaf 100644 --- a/src/SPIMemory.cpp +++ b/src/SPIMemory.cpp @@ -1,4 +1,4 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/05/2015 * Modified by @boseji - 02/03/2017 diff --git a/src/SPIMemory.h b/src/SPIMemory.h index 89bb45d..cd1fcd9 100644 --- a/src/SPIMemory.h +++ b/src/SPIMemory.h @@ -1,7 +1,7 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2017 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 18/04/2018 - * Modified by Prajwal Bhattaram - 02/04/2019 + * Modified by Prajwal Bhattaram - 03/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -103,20 +103,24 @@ #endif #ifndef ARCH_STM32 - #if defined(ARDUINO_ARCH_STM32) || defined(__STM32F1__) || defined(STM32F1) || defined(STM32F3) || defined(STM32F4) || defined(STM32F0xx) + #if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32L0) || defined(__STM32F1__) || defined(STM32F1) || defined(STM32F3) || defined(STM32F4) || defined(STM32F0xx) #define ARCH_STM32 #endif #endif -#if defined (ARDUINO_ARCH_SAM) || defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_ESP8266) || defined (SIMBLEE) || defined (ARDUINO_ARCH_ESP32) || defined (BOARD_RTL8195A) || defined(ARCH_STM32) || defined(ESP32) || defined(NRF5) +#if defined (ARDUINO_ARCH_SAM) || defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_ESP8266) || defined (SIMBLEE) || defined (ARDUINO_ARCH_ESP32) || defined (BOARD_RTL8195A) || defined(ARCH_STM32) || defined(ESP32) || defined(NRF52) // RTL8195A included - @boseji 02.03.17 #define _delay_us(us) delayMicroseconds(us) #else #include #endif -#define LIBVER 3 -#define LIBSUBVER 3 -#define BUGFIXVER 0 +#define SPIFLASH_LIBVER 3 +#define SPIFLASH_LIBSUBVER 4 +#define SPIFLASH_REVVER 0 + +#define SPIFRAM_LIBVER 0 +#define SPIFRAM_LIBSUBVER 0 +#define SPIFRAM_REVVER 1 class SPIMemory { public: diff --git a/src/defines.h b/src/defines.h index 253be62..7d8ee19 100644 --- a/src/defines.h +++ b/src/defines.h @@ -1,7 +1,7 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/05/2015 - * Modified by Prajwal Bhattaram - 20/04/2019 + * Modified by Prajwal Bhattaram - 03/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -42,11 +42,13 @@ #define BEGIN_SPI SPI.begin(); // Defines and variables specific to SAMD architecture - #elif defined (ARDUINO_ARCH_SAMD) || defined(ARCH_STM32) + #elif defined (ARDUINO_ARCH_SAMD) || defined(ARCH_STM32)|| defined(ARDUINO_ARCH_ESP32) #define CHIP_SELECT digitalWrite(csPin, LOW); #define CHIP_DESELECT digitalWrite(csPin, HIGH); #define xfer(n) _spi->transfer(n) #define BEGIN_SPI _spi->begin(); + + // Defines and variables not specific to any architecture #else #define CHIP_SELECT digitalWrite(csPin, LOW); #define CHIP_DESELECT digitalWrite(csPin, HIGH); @@ -54,6 +56,12 @@ #define BEGIN_SPI SPI.begin(); #endif + #ifdef RUNDIAGNOSTIC + #if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL) + #define Serial SERIAL_PORT_USBVIRTUAL + #endif + #endif + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // Common Instructions // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// @@ -154,31 +162,38 @@ #define RAMTRON_FRAM_MANID 0xC2 //~~~~~~~~~~~~~~~~~~~~~~~~ Adesto ~~~~~~~~~~~~~~~~~~~~~~~~// - #define ADESTO_MANID 0x1F + #define ADESTO_MANID 0x1F //~~~~~~~~~~~~~~~~~~~~~~~~ Micron ~~~~~~~~~~~~~~~~~~~~~~~~// - #define MICRON_MANID 0x20 - #define M25P40 0x20 + #define MICRON_MANID 0x20 + #define M25P40 0x20 //~~~~~~~~~~~~~~~~~~~~~~~~ ON ~~~~~~~~~~~~~~~~~~~~~~~~// - #define ON_MANID 0x62 + #define ON_MANID 0x62 //~~~~~~~~~~~~~~~~~~~~~~~~ Giga ~~~~~~~~~~~~~~~~~~~~~~~~// #define GIGA_MANID 0xC8 //~~~~~~~~~~~~~~~~~~~~~~~~ AMIC ~~~~~~~~~~~~~~~~~~~~~~~~// - #define AMIC_MANID 0x37 - #define A25L512 0x30 + #define AMIC_MANID 0x37 + #define A25L512 0x30 +//~~~~~~~~~~~~~~~~~~~~~~~~ AMIC ~~~~~~~~~~~~~~~~~~~~~~~~// + #define MACRONIX_MANID 0xC2 + #define MX25L4005 0x13 + #define MX25L8005 0x14 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// // Definitions // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// #define BUSY 0x01 +#define STDSPI 0x0A +#define ALTSPI 0x0B #if defined (ARDUINO_ARCH_ESP32) #define SPI_CLK 20000000 //Hz equivalent of 20MHz #else #define SPI_CLK 104000000 //Hz equivalent of 104MHz #endif +#define ENFASTREAD 0x01 #define WRTEN 0x02 #define SUS 0x80 #define WSE 0x04 @@ -189,11 +204,11 @@ #define NULLINT 0x0000 #define NO_CONTINUE 0x00 #define NOVERBOSE 0x00 +#define VERBOSE 0x01 #define PASS 0x01 #define FAIL 0x00 #define NOOVERFLOW false #define NOERRCHK false -#define VERBOSE true #define PRINTOVERRIDE true #define ERASEFUNC 0xEF #define BUSY_TIMEOUT 1000000000L diff --git a/src/diagnostics.cpp b/src/diagnostics.cpp index e15fe0b..2dfe86f 100644 --- a/src/diagnostics.cpp +++ b/src/diagnostics.cpp @@ -1,7 +1,7 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 14/11/2016 - * Modified by Prajwal Bhattaram - 19/06/2018 + * Modified by Prajwal Bhattaram - 03/06/2018 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -144,6 +144,10 @@ void Diagnostics::troubleshoot(uint8_t _code, bool printoverride) { Serial.println(F("Unable to read program times from flash memory. Reverting to library defaults.")); break; + case NOCHIPSELECTDECLARED: + Serial.println(F("No Chip Select pin defined in the custom SPI Array.")); + break; + default: Serial.println(F("Unknown error")); break; diff --git a/src/diagnostics.h b/src/diagnostics.h index b22db91..85d0601 100644 --- a/src/diagnostics.h +++ b/src/diagnostics.h @@ -1,7 +1,7 @@ -/* Arduino SPIMemory Library v.3.3.0 +/* Arduino SPIMemory Library v.3.4.0 * Copyright (C) 2019 by Prajwal Bhattaram * Created by Prajwal Bhattaram - 19/05/2015 - * Modified by Prajwal Bhattaram - 20/04/2019 + * Modified by Prajwal Bhattaram - 02/06/2019 * * This file is part of the Arduino SPIMemory Library. This library is for * Flash and FRAM memory modules. In its current form it enables reading, @@ -51,6 +51,7 @@ #define NOSFDPERASEPARAM 0x11 #define NOSFDPERASETIME 0x12 #define NOSFDPPROGRAMTIMEPARAM 0x13 + #define NOCHIPSELECTDECLARED 0x14 #define UNKNOWNERROR 0xFE //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//