From c7e13d21256e25826e42a9286d223770a6a17522 Mon Sep 17 00:00:00 2001 From: Khoi Hoang <57012152+khoih-prog@users.noreply.github.com> Date: Tue, 26 Jan 2021 04:13:12 -0500 Subject: [PATCH] v1.0.0 ### Releases v1.0.0 1. Initial release to support STM32F/L/H/G/WB/MP1 board with / without integrated EEPROM --- .gitignore | 32 ++ CONTRIBUTING.md | 51 +++ LICENSE | 22 + README.md | 381 ++++++++++++++++++ examples/EEPROM_CRC/EEPROM_CRC.ino | 75 ++++ examples/EEPROM_Clear/EEPROM_Clear.ino | 58 +++ examples/EEPROM_get/EEPROM_get.ino | 94 +++++ .../EEPROM_iteration/EEPROM_iteration.ino | 97 +++++ examples/EEPROM_put/EEPROM_put.ino | 82 ++++ examples/EEPROM_read/EEPROM_read.ino | 69 ++++ examples/EEPROM_update/EEPROM_update.ino | 73 ++++ examples/EEPROM_write/EEPROM_write.ino | 67 +++ examples/EmulateEEPROM/EmulateEEPROM.ino | 97 +++++ .../FlashStoreAndRetrieve.ino | 54 +++ .../StoreNameAndSurname.ino | 103 +++++ keywords.txt | 30 ++ library.json | 13 + library.properties | 10 + platformio/platformio.ini | 150 +++++++ src/FlashStorage_STM32.h | 195 +++++++++ 20 files changed, 1753 insertions(+) create mode 100644 .gitignore create mode 100644 CONTRIBUTING.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 examples/EEPROM_CRC/EEPROM_CRC.ino create mode 100644 examples/EEPROM_Clear/EEPROM_Clear.ino create mode 100644 examples/EEPROM_get/EEPROM_get.ino create mode 100644 examples/EEPROM_iteration/EEPROM_iteration.ino create mode 100644 examples/EEPROM_put/EEPROM_put.ino create mode 100644 examples/EEPROM_read/EEPROM_read.ino create mode 100644 examples/EEPROM_update/EEPROM_update.ino create mode 100644 examples/EEPROM_write/EEPROM_write.ino create mode 100644 examples/EmulateEEPROM/EmulateEEPROM.ino create mode 100644 examples/FlashStoreAndRetrieve/FlashStoreAndRetrieve.ino create mode 100644 examples/StoreNameAndSurname/StoreNameAndSurname.ino create mode 100644 keywords.txt create mode 100644 library.json create mode 100644 library.properties create mode 100644 platformio/platformio.ini create mode 100644 src/FlashStorage_STM32.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..259148f --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..9b909a3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,51 @@ +## Contributing to FlashStorage_STM32 + +### Reporting Bugs + +Please report bugs in FlashStorage_STM32 if you find them. + +However, before reporting a bug please check through the following: + +* [Existing Open Issues](https://github.com/khoih-prog/FlashStorage_STM32/issues) - someone might have already encountered this. + +If you don't find anything, please [open a new issue](https://github.com/khoih-prog/FlashStorage_STM32/issues/new). + +### How to submit a bug report + +Please ensure to specify the following: + +* Arduino IDE version (e.g. 1.8.10) or Platform.io version +* `ESP8266` or `ESP32` Core Version (e.g. ESP8266 core v2.6.3 or ESP32 v1.0.4) +* Contextual information (e.g. what you were trying to achieve) +* Simplest possible steps to reproduce +* Anything that might be relevant in your opinion, such as: + * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` + * Network configuration + + +### Example + +``` +Arduino IDE version: 1.8.13 +STM32 Core Version 1.9.0 +OS: Ubuntu 20.04 LTS +Linux Inspiron-3593 5.4.0-64-generic #72-Ubuntu SMP Fri Jan 15 10:27:54 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux + +Context: +The board couldn't autoreconnect to Local Blynk Server after router power recycling. + +Steps to reproduce: +1. ... +2. ... +3. ... +4. ... + +### Sending Feature Requests + +Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. + +There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/FlashStorage_STM32/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. + +### Sending Pull Requests + +Pull Requests with changes and fixes are also welcome! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1b3483d --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2020 Khoi Hoang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..07b287e --- /dev/null +++ b/README.md @@ -0,0 +1,381 @@ +# FlashStorage_STM32 Library + +[![arduino-library-badge](https://www.ardu-badge.com/badge/FlashStorage_STM32.svg?)](https://www.ardu-badge.com/FlashStorage_STM32) +[![GitHub release](https://img.shields.io/github/release/khoih-prog/FlashStorage_STM32.svg)](https://github.com/khoih-prog/FlashStorage_STM32/releases) +[![GitHub](https://img.shields.io/github/license/mashape/apistatus.svg)](https://github.com/khoih-prog/FlashStorage_STM32/blob/main/LICENSE) +[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) +[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/FlashStorage_STM32.svg)](http://github.com/khoih-prog/FlashStorage_STM32/issues) + +--- +--- + +## Table of Contents + +* [Why do we need this FlashStorage_STM32 library](#why-do-we-need-this-FlashStorage_STM32-library) + * [Features](#features) + * [Currently supported Boards](#currently-supported-boards) +* [Changelog](#changelog) + * [Releases v1.0.0](#releases-v100) +* [Prerequisites](#prerequisites) +* [Installation](#installation) + * [Use Arduino Library Manager](#use-arduino-library-manager) + * [Manual Install](#manual-install) + * [VS Code & PlatformIO](#vs-code--platformio) +* [Limited number of writes](#limited-number-of-writes) +* [Usage](#usage) + * [Using the alternative EEPROM-like API](#using-the-alternative-eeprom-like-api) +* [Examples](#examples) + * [ 1. EEPROM_Clear](examples/EEPROM_Clear) + * [ 2. EEPROM_CRC](examples/EEPROM_CRC) + * [ 3. EEPROM_get](examples/EEPROM_get) + * [ 4. EEPROM_iteration](examples/EEPROM_iteration) + * [ 5. EEPROM_put](examples/EEPROM_put) + * [ 6. EEPROM_read](examples/EEPROM_read) + * [ 7. EEPROM_update](examples/EEPROM_update) + * [ 8. EEPROM_write](examples/EEPROM_write) + * [ 9. **EmulateEEPROM**](examples/EmulateEEPROM) + * [ 10. **FlashStoreAndRetrieve**](examples/FlashStoreAndRetrieve) + * [ 11. **StoreNameAndSurname**](examples/StoreNameAndSurname) +* [Example StoreNameAndSurname](#example-storenameandsurname) +* [FAQ](#faq) + * [Can I use a single object to store more stuff?](#can-i-use-a-single-flashstorage-object-to-store-more-stuff) + * [The content of the FlashStorage is erased each time a new sketch is uploaded?](#the-content-of-the-flashstorage-is-erased-each-time-a-new-sketch-is-uploaded) + * [Do you recommend to use FLASH instead of EEPROM?](#do-you-recommend-to-use-flash-instead-of-eeprom) +* [Troubleshooting](#troubleshooting) +* [Releases](#releases) +* [Issues](#issues) +* [TO DO](#to-do) +* [DONE](#done) +* [Contributions and Thanks](#contributions-and-thanks) +* [Contributing](#contributing) +* [License](#license) +* [Copyright](#copyright) + +--- +--- + +### Why do we need this [FlashStorage_STM32 library](https://github.com/khoih-prog/FlashStorage_STM32) + +### Features + +The FlashStorage_STM32 library, inspired from [Cristian Maglie's FlashStorage](https://github.com/cmaglie/FlashStorage), provides a convenient way to store and retrieve user's data using emulated-EEPROM, from the non-volatile flash memory of STM32F/L/H/G/WB/MP1. + +The flash memory, generally used to store the firmware code, can also be used to store / retrieve more user's data and faster than from EEPROM. Thanks to the **buffered data writing and reading**, the flash access time is greatly reduced to **increase the life of the flash**. + +### Currently supported Boards + +1. **STM32F/L/H/G/WB/MP1 boards with / without integrated EEPROM** + +- Nucleo-144 +- Nucleo-64 +- Nucleo-32 +- Discovery +- Generic STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7 +- STM32L0, STM32L1, STM32L4 +- STM32G0, STM32G4 +- STM32H7 +- STM32WB +- STM32MP1 +- LoRa boards +- 3-D printer boards +- Generic Flight Controllers +- Midatronics boards + +--- +--- + +## Changelog + +### Releases v1.0.0 + +1. Initial release to support STM32F/L/H/G/WB/MP1 board with / without integrated EEPROM + + +--- +--- + +## Prerequisites + + 1. [`Arduino IDE 1.8.13+` for Arduino](https://www.arduino.cc/en/Main/Software) + 2. [`Arduino Core for STM32 1.9.0+`](https://github.com/stm32duino/Arduino_Core_STM32) for STM32 (Use Arduino Board Manager) + +--- + +## Installation + +### Use Arduino Library Manager + +The best and easiest way is to use `Arduino Library Manager`. Search for [**FlashStorage_STM32**](https://github.com/khoih-prog/FlashStorage_STM32), then select / install the latest version. +You can also use this link [![arduino-library-badge](https://www.ardu-badge.com/badge/FlashStorage_STM32.svg?)](https://www.ardu-badge.com/FlashStorage_STM32) for more detailed instructions. + +### Manual Install + +Another way to install is to: + +1. Navigate to [**FlashStorage_STM32**](https://github.com/khoih-prog/FlashStorage_STM32) page. +2. Download the latest release `FlashStorage_STM32-main.zip`. +3. Extract the zip file to `FlashStorage_STM32-main` directory +4. Copy whole `FlashStorage_STM32-main` folder to Arduino libraries' directory such as `~/Arduino/libraries/`. + +### VS Code & PlatformIO + +1. Install [VS Code](https://code.visualstudio.com/) +2. Install [PlatformIO](https://platformio.org/platformio-ide) +3. Install [**FlashStorage_STM32** library](https://platformio.org/lib/show/xxxxx/FlashStorage_STM32) by using [Library Manager](https://platformio.org/lib/show/xxxxx/FlashStorage_STM32/installation). Search for **FlashStorage_STM32** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22) +4. Use included [platformio.ini](platformio/platformio.ini) file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at [Project Configuration File](https://docs.platformio.org/page/projectconf.html) + + +--- +--- + +## Limited number of writes + +The flash memory has a limited amount of write cycles. Typical flash memories can perform about 10000 writes cycles to the same flash block before starting to "wear out" and begin to lose the ability to retain data. + +So **BEWARE: IMPROPER USE OF THIS LIBRARY CAN QUICKLY AND PERMANENTLY DESTROY THE FLASH MEMORY OF YOUR MICRO**, in particular you should avoid to call the `put()` or`commit()` functions too often and make sure that in the entire life of the micro the number of calls to `put()` or`commit()` stay well below the above limit of 10000 (it's a good rule-of-thumb to keep that number in mind even if the manufacturer of the micro guarantees a bigger number of cycles). + + +--- +--- + +## Usage + +### Using the alternative EEPROM-like API + +Include `FlashStorage_STM32.h` to get an EEPROM emulation with the internal flash memory. + +See [EmulateEEPROM](examples/EmulateEEPROM) sketch for an example. + +The API is very similar to the well known Arduino EEPROM.h API but with 4 additional functions: + +* `bool isValid()` returns `true` if data in the emulated-EEPROM is valid (the data written to flash at least once by `EEPROM.commit()` or `EEPROM.put()`). Otherwise emulated-EEPROM data is "undefined" and the function returns `false`. +* `void commit()` store the EEPROM data in flash. Use this with care: Every call writes the complete emulated-EEPROM data to flash. This will reduce the remaining flash-write-cycles. Don't call this method in a loop or [you will kill your flash soon](#limited-number-of-writes). +* `void setCommitASAP(bool value = true)` to set or clear the `_commitASAP` private variable (default is `true` to be safe). If _commitASAP is false, the call to `EEPROM.put()` won't force the `EEPROM.commit()` to extend the flash life. You'll have to remember to call `EEPROM.commit()` manually to save the emulated-EEPROM data into flash or data will be lost. +* `bool getCommitASAP()` to return the current value of `_commitASAP`. + +--- +--- + +### Examples + + 1. [EEPROM_Clear](examples/EEPROM_Clear) + 2. [EEPROM_CRC](examples/EEPROM_CRC) + 3. [EEPROM_get](examples/EEPROM_get) + 4. [EEPROM_iteration](examples/EEPROM_iteration) + 5. [EEPROM_put](examples/EEPROM_put) + 6. [EEPROM_read](examples/EEPROM_read) + 7. [EEPROM_update](examples/EEPROM_update) + 8. [EEPROM_write](examples/EEPROM_write) + 9. [EmulateEEPROM](examples/EmulateEEPROM) +10. [FlashStoreAndRetrieve](examples/FlashStoreAndRetrieve) +11. [StoreNameAndSurname](examples/StoreNameAndSurname) + +--- +--- + +### Example [StoreNameAndSurname](examples/StoreNameAndSurname) + + +```cpp +// Demonstrate how to use FlashStorage_STM32 with an API that is similar to the EEPROM library to Store and retrieve structured data. + +#include + +const int WRITTEN_SIGNATURE = 0xBEEFDEED; + +// Create a structure that is big enough to contain a name +// and a surname. The "valid" variable is set to "true" once +// the structure is filled with actual data for the first time. +typedef struct +{ + char name[100]; + char surname[100]; +} Person; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart StoreNameAndSurname on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + // Check signature at address 0 + int signature; + + // Create a "Person" variable and call it "owner" + uint16_t storedAddress = 0; + Person owner; + + EEPROM.get(storedAddress, signature); + + // If the EEPROM is empty then no WRITTEN_SIGNATURE + if (signature == WRITTEN_SIGNATURE) + { + EEPROM.get(storedAddress + sizeof(signature), owner); + + // Say hello to the returning user! + Serial.print("Hi "); Serial.print(owner.name); Serial.print(" "); Serial.print(owner.surname); + Serial.println(", nice to see you again :-)"); + + Serial.println("Clearing WRITTEN_SIGNATURE for next try"); + + EEPROM.put(0, 0); + Serial.println("Done clearing signature in emulated EEPROM. You can reset now"); + } + else + { + Serial.println("EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:"); + + EEPROM.put(storedAddress, WRITTEN_SIGNATURE); + + // ...in this case we ask for user data. + Serial.setTimeout(30000); + Serial.print("Insert your name : "); + String name = Serial.readStringUntil('\n'); + Serial.println(name); + Serial.print("Insert your surname : "); + String surname = Serial.readStringUntil('\n'); + Serial.println(surname); + + // Fill the "owner" structure with the data entered by the user... + name.toCharArray(owner.name, 100); + surname.toCharArray(owner.surname, 100); + + // ...and finally save everything into emulated-EEPROM + EEPROM.put(storedAddress + sizeof(signature), owner); + + // Print a confirmation of the data inserted. + Serial.print("<< Your name: "); Serial.print(owner.name); + Serial.print(". Your surname: "); Serial.print(owner.surname); + Serial.println(" >> have been saved. Thank you!"); + } +} + +void loop() +{ + // Do nothing... +} +``` + +--- +--- + + +## FAQ + +### Can I use a single object to store more stuff? + +Yes, you can declare a `struct` with more fields and call a `EEPROM.put()` to store the entire structure. See the [StoreNameAndSurname](examples/StoreNameAndSurname) for how to do it. + +### The content of the FlashStorage is erased each time a new sketch is uploaded? + +Not with STM32. + +### Do you recommend to use FLASH instead of EEPROM? + +No. If your board provides an integrated-EEPROM, it's advisable to use that because EEPROM has longer lifetime, number of write cycles, etc.). + +In the absence of an integrated-EEPROM or its size is too small for your use-case, you can use this library to use a small portion flash memory as emulated-EEPROM, provided that you keep in mind the limits as in [Limited number of writes](#limited-number-of-writes) + +--- +--- + +### Troubleshooting + +If you get compilation errors, more often than not, you may need to install a newer version of the core for Arduino boards. + +Sometimes, the library will only work if you update the board core to the latest version because I am using newly added functions. + +--- +--- + +## Releases + +### Releases v1.0.0 + +1. Initial release to support STM32F/L/H/G/WB/MP1 board with / without integrated EEPROM + +### Currently supported Boards + +1. **STM32F/L/H/G/WB/MP1 boards with / without integrated EEPROM** + +- Nucleo-144 +- Nucleo-64 +- Nucleo-32 +- Discovery +- Generic STM32F0, STM32F1, STM32F2, STM32F3, STM32F4, STM32F7 +- STM32L0, STM32L1, STM32L4 +- STM32G0, STM32G4 +- STM32H7 +- STM32WB +- STM32MP1 +- LoRa boards +- 3-D printer boards +- Generic Flight Controllers +- Midatronics boards + +--- +--- + +### Issues + +Submit issues to: [FlashStorage_STM32 issues](https://github.com/khoih-prog/FlashStorage_STM32/issues) + +--- + +## TO DO + +1. Search for bug and improvement. +2. Similar features for remaining Arduino boards + +--- + +## DONE + +1. Basic emulated-EEPROM for STM32F/L/H/G/WB/MP1. +2. Similar features for remaining Arduino boards such as SAMD21, SAMD51, etc. +3. Add Table of Contents + +--- +--- + +### Contributions and Thanks + +Many thanks for everyone for bug reporting, new feature suggesting, testing and contributing to the development of this library. + +1. Inspired by [Cristian Maglie's FlashStorage](https://github.com/cmaglie/FlashStorage). + + + + + +
cmaglie
⭐️ Cristian Maglie

+ +--- + +### Contributing + +If you want to contribute to this project: +- Report bugs and errors +- Ask for enhancements +- Create issues and pull requests +- Tell other people about this library + +--- + +### License + +- The library is licensed under [MIT](https://github.com/khoih-prog/FlashStorage_STM32/blob/main/LICENSE) + +--- + +### Copyright + +Copyright 2020- Khoi Hoang + diff --git a/examples/EEPROM_CRC/EEPROM_CRC.ino b/examples/EEPROM_CRC/EEPROM_CRC.ino new file mode 100644 index 0000000..3bdecbf --- /dev/null +++ b/examples/EEPROM_CRC/EEPROM_CRC.ino @@ -0,0 +1,75 @@ +/****************************************************************************************************************************************** + EEPROM_CRC.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/*** + Written by Christopher Andrews. + CRC algorithm generated by pycrc, MIT licence ( https://github.com/tpircher/pycrc ) + + A CRC is a simple way of checking whether data has changed or become corrupted. + This example calculates a CRC value directly on the EEPROM values. + The purpose of this example is to highlight how the EEPROM object can be used just like an array. +***/ + +#include + +unsigned long eeprom_crc() +{ + const unsigned long crc_table[16] = + { + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, + 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, + 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + }; + + unsigned long crc = ~0L; + + for (int index = 0 ; index < EEPROM.length() ; ++index) + { + crc = crc_table[(crc ^ EEPROM.read(index)) & 0x0f] ^ (crc >> 4); + crc = crc_table[(crc ^ (EEPROM.read(index) >> 4)) & 0x0f] ^ (crc >> 4); + crc = ~crc; + } + + return crc; +} + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_CRC on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + //Print length of data to run CRC on. + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + //Print the result of calling eeprom_crc() + Serial.print("CRC32 of EEPROM data: 0x"); + Serial.println(eeprom_crc(), HEX); + Serial.print("Done!"); +} + +void loop() +{ + /* Empty loop */ +} diff --git a/examples/EEPROM_Clear/EEPROM_Clear.ino b/examples/EEPROM_Clear/EEPROM_Clear.ino new file mode 100644 index 0000000..51c0027 --- /dev/null +++ b/examples/EEPROM_Clear/EEPROM_Clear.ino @@ -0,0 +1,58 @@ +/****************************************************************************************************************************************** + EEPROM_Clear.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ + +#include + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_Clear on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + // initialize the LED pin as an output. + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, LOW); + + Serial.print("Emulated EEPROM length (bytes) = "); Serial.println(EEPROM.length()); + + unsigned long startMillis = millis(); + + for (int i = 0 ; i < EEPROM.length() ; i++) + { + EEPROM.write(i, 0); + } + + EEPROM.commit(); + + // The time spent can be very short (4-5ms) if the EEPROM is not dirty. + // For F767ZI, the time is around 1.1s for 16384 bytes of emulated-EEPROM + Serial.print("Done clearing emulated EEPROM. Time spent (ms) = "); Serial.println(millis() - startMillis); + + // turn the LED on when we're done + digitalWrite(LED_BUILTIN, HIGH); +} + +void loop() +{ + /** Empty loop. **/ +} diff --git a/examples/EEPROM_get/EEPROM_get.ino b/examples/EEPROM_get/EEPROM_get.ino new file mode 100644 index 0000000..e054108 --- /dev/null +++ b/examples/EEPROM_get/EEPROM_get.ino @@ -0,0 +1,94 @@ +/****************************************************************************************************************************************** + EEPROM_CRC.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/*** + eeprom_get example. + + This shows how to use the EEPROM.get() method. + + To pre-set the EEPROM data, run the example sketch eeprom_put. This sketch will run without it. + However, the values shown will be shown from what ever is already on the EEPROM. + + This may cause the serial object to print out a large string of garbage if there is no null character + inside one of the strings loaded. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +struct MyObject +{ + float field1; + byte field2; + char name[10]; +}; + +void secondTest() +{ + int eeAddress = sizeof(float); //Move address to the next byte after float 'f'. + + MyObject customVar; //Variable to store custom object read from EEPROM. + EEPROM.get(eeAddress, customVar); + + Serial.println("Read custom object from EEPROM: "); + Serial.println(customVar.field1, 5); + Serial.println(customVar.field2); + Serial.println(customVar.name); +} + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_get on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + float f = 0.00f; //Variable to store data read from EEPROM. + int eeAddress = 0; //EEPROM address to start reading from + + Serial.print("Read float from EEPROM: "); + + //Get the float data from the EEPROM at position 'eeAddress' + EEPROM.get(eeAddress, f); + Serial.println(f, 3); //This may print 'ovf, nan' if the data inside the EEPROM is not a valid float. + + /*** + As get also returns a reference to 'f', you can use it inline. + E.g: Serial.print( EEPROM.get( eeAddress, f ) ); + ***/ + + /*** + Get can be used with custom structures too. + I have separated this into an extra function. + ***/ + + secondTest(); //Run the next test. +} + +void loop() +{ + /* Empty loop */ +} diff --git a/examples/EEPROM_iteration/EEPROM_iteration.ino b/examples/EEPROM_iteration/EEPROM_iteration.ino new file mode 100644 index 0000000..ee343a4 --- /dev/null +++ b/examples/EEPROM_iteration/EEPROM_iteration.ino @@ -0,0 +1,97 @@ +/****************************************************************************************************************************************** + EEPROM_iteration.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/*** + eeprom_iteration example. + + A set of example snippets highlighting the simplest methods for traversing the EEPROM. + + Running this sketch is not necessary, this is simply highlighting certain programming methods. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_iteration on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + /*** + Iterate the EEPROM using a for loop. + ***/ + + for (int index = 0 ; index < EEPROM.length() ; index++) + { + // Add one to each cell in the EEPROM + EEPROM.write(index, EEPROM.read(index) + 1); + } + + EEPROM.commit(); + + Serial.println("Done for loop"); + + /*** + Iterate the EEPROM using a while loop. + ***/ + + int index = 0; + + while (index < EEPROM.length()) + { + //Add one to each cell in the EEPROM + // Add one to each cell in the EEPROM + EEPROM.write(index, EEPROM.read(index) + 1); + index++; + } + + EEPROM.commit(); + + Serial.println("Done while loop"); + + /*** + Iterate the EEPROM using a do-while loop. + ***/ + + int idx = 0; //Used 'idx' to avoid name conflict with 'index' above. + + do + { + //Add one to each cell in the EEPROM + // Add one to each cell in the EEPROM + EEPROM.write(index, EEPROM.read(index) + 1); + idx++; + } while (idx < EEPROM.length()); + + EEPROM.commit(); + + Serial.println("Done do-while loop"); + +} //End of setup function. + +void loop() {} diff --git a/examples/EEPROM_put/EEPROM_put.ino b/examples/EEPROM_put/EEPROM_put.ino new file mode 100644 index 0000000..8ece25a --- /dev/null +++ b/examples/EEPROM_put/EEPROM_put.ino @@ -0,0 +1,82 @@ +/****************************************************************************************************************************************** + EEPROM_put.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/*** + eeprom_put example. + + This shows how to use the EEPROM.put() method. Also, this sketch will pre-set the EEPROM data + for the example sketch eeprom_get. + + Note, unlike the single byte version EEPROM.write(), the put method will use update semantics. As in a byte + will only be written to the EEPROM if the data is actually different. + + Written by Christopher Andrews 2015 + Released under MIT licence. +***/ + +#include + +struct MyObject +{ + float field1; + byte field2; + char name[10]; +}; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_put on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + float f = 123.456f; //Variable to store in EEPROM. + int eeAddress = 0; //Location we want the data to be put. + + + //One simple call, with the address first and the object second. + EEPROM.put(eeAddress, f); + + Serial.println("Written float data type!"); + + /** Put is designed for use with custom structures also. **/ + + //Data to store. + MyObject customVar = + { + 3.14159f, + 65, + "Working!" + }; + + eeAddress += sizeof(float); //Move address to the next byte after float 'f'. + + EEPROM.put(eeAddress, customVar); + Serial.print("Written custom data type! \n\nView the example sketch EEPROM_get to see how you can retrieve the values!"); +} + +void loop() +{ + /* Empty loop */ +} diff --git a/examples/EEPROM_read/EEPROM_read.ino b/examples/EEPROM_read/EEPROM_read.ino new file mode 100644 index 0000000..0efa9db --- /dev/null +++ b/examples/EEPROM_read/EEPROM_read.ino @@ -0,0 +1,69 @@ +/****************************************************************************************************************************************** + EEPROM_read.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/* + EEPROM Read + + Reads the value of each byte of the EEPROM and prints it to the computer. + This example code is in the public domain. +*/ + +#include + +// start reading from the first byte (address 0) of the EEPROM +int address = 0; +byte value; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_read on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); +} + +void loop() +{ + // read a byte from the current address of the EEPROM + value = EEPROM.read(address); + + Serial.print(address); + Serial.print("\t"); + Serial.print(value, DEC); + Serial.println(); + + if (++address == EEPROM.length()) + { + address = 0; + } + + /*** + As the EEPROM sizes are powers of two, wrapping (preventing overflow) of an + EEPROM address is also doable by a bitwise and of the length - 1. + + ++address &= EEPROM.length() - 1; + ***/ + + delay(500); +} diff --git a/examples/EEPROM_update/EEPROM_update.ino b/examples/EEPROM_update/EEPROM_update.ino new file mode 100644 index 0000000..237fe5c --- /dev/null +++ b/examples/EEPROM_update/EEPROM_update.ino @@ -0,0 +1,73 @@ +/****************************************************************************************************************************************** + EEPROM_update.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/*** + EEPROM Update method + + Stores values read from analog input 0 into the EEPROM. + These values will stay in the EEPROM when the board is + turned off and may be retrieved later by another sketch. + + If a value has not changed in the EEPROM, it is not overwritten + which would reduce the life span of the EEPROM unnecessarily. + + Released using MIT licence. + ***/ + +#include + +/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/ +int address = 0; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_read on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); +} + +void loop() +{ + unsigned long startMillis = millis(); + + for (int i = 0 ; i < EEPROM.length() ; i++) + { + /*** + The function EEPROM.update(address, val) is equivalent to the following: + + if( EEPROM.read(address) != val ) + { + EEPROM.write(address, val); + } + ***/ + EEPROM.update(i, (uint8_t) analogRead(0)); + } + + EEPROM.commit(); + + Serial.print("Done updating emulated EEPROM. Time spent (ms) = "); Serial.println(millis() - startMillis); + + delay(60000); +} diff --git a/examples/EEPROM_write/EEPROM_write.ino b/examples/EEPROM_write/EEPROM_write.ino new file mode 100644 index 0000000..4733a5b --- /dev/null +++ b/examples/EEPROM_write/EEPROM_write.ino @@ -0,0 +1,67 @@ +/****************************************************************************************************************************************** + EEPROM_write.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ +/* + EEPROM Write + + Stores values read from analog input 0 into the EEPROM. These values will stay in the EEPROM + when the board is turned off and may be retrieved later by another sketch. +*/ + +#include + +// start reading from the first byte (address 0) of the EEPROM +int address = 0; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EEPROM_write on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); +} + +void loop() +{ + unsigned long startMillis = millis(); + + for (int i = 0 ; i < EEPROM.length() ; i++) + { + /*** + The function EEPROM.update(address, val) is equivalent to the following: + + if( EEPROM.read(address) != val ) + { + EEPROM.write(address, val); + } + ***/ + EEPROM.write(i, (uint8_t) analogRead(0)); + } + + EEPROM.commit(); + + Serial.print("Done writing emulated EEPROM. Time spent (ms) = "); Serial.println(millis() - startMillis); + + delay(60000); +} diff --git a/examples/EmulateEEPROM/EmulateEEPROM.ino b/examples/EmulateEEPROM/EmulateEEPROM.ino new file mode 100644 index 0000000..7c949ad --- /dev/null +++ b/examples/EmulateEEPROM/EmulateEEPROM.ino @@ -0,0 +1,97 @@ +/****************************************************************************************************************************************** + EmulatedEEPROM.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ + +// Demonstrate how to use FlashStorage_STM32 with an API that is similar to the EEPROM library. + +#include + +const int WRITTEN_SIGNATURE = 0xBEEFDEED; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart EmulatedEEPROM on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + // Check signature at address 0 + int signature; + + EEPROM.get(0, signature); + + // If the EEPROM is empty then no WRITTEN_SIGNATURE + if (signature != WRITTEN_SIGNATURE) + { + Serial.println("EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:"); + + EEPROM.put(0, WRITTEN_SIGNATURE); + + Serial.print("->"); + + for (int i = sizeof(WRITTEN_SIGNATURE); i < 20; i++) + { + EEPROM.write(i, 100 + i); + Serial.print(" "); + Serial.print(100 + i); + } + + // commit() saves all the changes to EEPROM, it must be called + // every time the content of virtual EEPROM is changed to make + // the change permanent. + // This operation burns Flash write cycles and should not be + // done too often. See readme for details: + // https://github.com/khoih-prog/FlashStorage_SAMD#limited-number-of-writes + + EEPROM.commit(); + Serial.println("\nDone writing to emulated EEPROM. You can reset now to test"); + } + else + { + EEPROM.get(0, signature); + + Serial.print("EEPROM has been written.Signature = 0x"); Serial.println(signature, HEX); + + Serial.println("Here is the content of the next 16 bytes:"); + + Serial.print("->"); + + for (int i = sizeof(WRITTEN_SIGNATURE); i < 20; i++) + { + Serial.print(" "); + Serial.print(EEPROM.read(i)); + } + + Serial.println("\nClearing WRITTEN_SIGNATURE for next try"); + + EEPROM.put(0, 0); + + //EEPROM.commit(); + Serial.println("Done clearing signature in emulated EEPROM. You can reset now"); + } +} + +void loop() +{ +} diff --git a/examples/FlashStoreAndRetrieve/FlashStoreAndRetrieve.ino b/examples/FlashStoreAndRetrieve/FlashStoreAndRetrieve.ino new file mode 100644 index 0000000..52b9766 --- /dev/null +++ b/examples/FlashStoreAndRetrieve/FlashStoreAndRetrieve.ino @@ -0,0 +1,54 @@ +/****************************************************************************************************************************************** + FlashStoreAndRetrieve.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ + +#include + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart FlashStoreAndRetrieve on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + uint16_t address = 0; + int number; + + // Read the content of emulated-EEPROM + EEPROM.get(address, number); + + // Print the current number on the serial monitor + Serial.print("Number = 0x"); Serial.println(number, HEX); + + // Save into emulated-EEPROM the number increased by 1 for the next run of the sketch + EEPROM.put(address, (int) (number + 1)); + EEPROM.commit(); + + Serial.println("Done writing to emulated EEPROM. You can reset now"); +} + +void loop() +{ + // Do nothing... +} diff --git a/examples/StoreNameAndSurname/StoreNameAndSurname.ino b/examples/StoreNameAndSurname/StoreNameAndSurname.ino new file mode 100644 index 0000000..5ff7d47 --- /dev/null +++ b/examples/StoreNameAndSurname/StoreNameAndSurname.ino @@ -0,0 +1,103 @@ +/****************************************************************************************************************************************** + StoreNameAndSurname.ino + For STM32 using Flash emulated-EEPROM + + The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory + of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. + It now supports writing and reading the whole object, not just byte-and-byte. + + Inspired by Cristian Maglie's FlashStorage (https://github.com/cmaglie/FlashStorage) + + Built by Khoi Hoang https://github.com/khoih-prog/FlashStorage_STM32 + Licensed under MIT license + Version: 1.0.0 + + Version Modified By Date Comments + ------- ----------- ---------- ----------- + 1.0.0 K Hoang 26/01/2021 Initial coding to support STM32F/L/H/G/WB/MP1 using emulated-EEPROM + ******************************************************************************************************************************************/ + +// Demonstrate how to use FlashStorage_STM32 with an API that is similar to the EEPROM library to Store and retrieve structured data. + +#include + +const int WRITTEN_SIGNATURE = 0xBEEFDEED; + +// Create a structure that is big enough to contain a name +// and a surname. The "valid" variable is set to "true" once +// the structure is filled with actual data for the first time. +typedef struct +{ + char name[100]; + char surname[100]; +} Person; + +void setup() +{ + Serial.begin(115200); + while (!Serial); + + delay(200); + + Serial.print(F("\nStart StoreNameAndSurname on ")); Serial.println(BOARD_NAME); + Serial.println(FLASH_STORAGE_STM32_VERSION); + + Serial.print("EEPROM length: "); + Serial.println(EEPROM.length()); + + // Check signature at address 0 + int signature; + + // Create a "Person" variable and call it "owner" + uint16_t storedAddress = 0; + Person owner; + + EEPROM.get(storedAddress, signature); + + // If the EEPROM is empty then no WRITTEN_SIGNATURE + if (signature == WRITTEN_SIGNATURE) + { + EEPROM.get(storedAddress + sizeof(signature), owner); + + // Say hello to the returning user! + Serial.print("Hi "); Serial.print(owner.name); Serial.print(" "); Serial.print(owner.surname); + Serial.println(", nice to see you again :-)"); + + Serial.println("Clearing WRITTEN_SIGNATURE for next try"); + + EEPROM.put(0, 0); + Serial.println("Done clearing signature in emulated EEPROM. You can reset now"); + } + else + { + Serial.println("EEPROM is empty, writing WRITTEN_SIGNATURE and some example data:"); + + EEPROM.put(storedAddress, WRITTEN_SIGNATURE); + + // ...in this case we ask for user data. + Serial.setTimeout(30000); + Serial.print("Insert your name : "); + String name = Serial.readStringUntil('\n'); + Serial.println(name); + Serial.print("Insert your surname : "); + String surname = Serial.readStringUntil('\n'); + Serial.println(surname); + + // Fill the "owner" structure with the data entered by the user... + name.toCharArray(owner.name, 100); + surname.toCharArray(owner.surname, 100); + + // ...and finally save everything into emulated-EEPROM + EEPROM.put(storedAddress + sizeof(signature), owner); + + // Print a confirmation of the data inserted. + Serial.print("<< Your name: "); Serial.print(owner.name); + Serial.print(". Your surname: "); Serial.print(owner.surname); + Serial.println(" >> have been saved. Thank you!"); + } +} + +void loop() +{ + // Do nothing... +} diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..29383d2 --- /dev/null +++ b/keywords.txt @@ -0,0 +1,30 @@ +############################################ +# Syntax Coloring Map For FlashStorage_SAMD +############################################ + +####################################### +# Datatypes (KEYWORD1) +####################################### + +EEPROMClass KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +write KEYWORD2 +read KEYWORD2 +update KEYWORD2 +get KEYWORD2 +put KEYWORD2 +isValid KEYWORD2 +commit KEYWORD2 +length KEYWORD2 +setCommitASAP KEYWORD2 +getCommitASAP KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + + diff --git a/library.json b/library.json new file mode 100644 index 0000000..716f560 --- /dev/null +++ b/library.json @@ -0,0 +1,13 @@ +{ + "name": "FlashStorage_STM32", + "keywords": "storage,data,flash,flashstorage,flash-storage,eeprom,emulated-eeprom", + "description": "The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. It now supports writing and reading the whole object, not just byte-and-byte.", + "repository": + { + "type": "git", + "url": "https://github.com/khoih-prog/FlashStorage_STM32" + }, + "version": "1.0.0", + "frameworks": "arduino", + "platforms": "stm32" +} diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..bd0e9c3 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=FlashStorage_STM32 +version=1.0.0 +author=Khoi Hoang +maintainer=Khoi Hoang +license=MIT +sentence=The FlashStorage_STM32 library aims to provide a convenient way to store and retrieve user's data using the non-volatile flash memory of STM32F/L/H/G/WB/MP1. It's using the buffered read and write to minimize the access to Flash. It now supports writing and reading the whole object, not just byte-and-byte. +paragraph=Useful if the EEPROM is not available or too small. Currently, STM32F/L/H/G/WB/MP1 are supported. +url=https://github.com/khoih-prog/FlashStorage_STM32 +architectures=stm32 +category=Data Storage diff --git a/platformio/platformio.ini b/platformio/platformio.ini new file mode 100644 index 0000000..f3a17b2 --- /dev/null +++ b/platformio/platformio.ini @@ -0,0 +1,150 @@ +;PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[platformio] +; ============================================================ +; chose environment: +; STM32 + +; ============================================================ +default_envs = STM32 + +[env] +; ============================================================ +; Serial configuration +; choose upload speed, serial-monitor speed +; ============================================================ +upload_speed = 921600 +;upload_port = COM11 +;monitor_speed = 9600 +;monitor_port = COM11 + +lib_deps = +; PlatformIO 4.x + +; PlatformIO 5.x + + + +build_flags = +; set your build_flags + +[env:STM32] +platform = ststm32 +framework = arduino + +; ============================================================ +; Choose your board by uncommenting one of the following lines +; ============================================================ + +; ============================================================ +; Board configuration Nucleo-144 +; ============================================================ + +;board = nucleo_f207zg +;board = nucleo_f429zi +;board = nucleo_f746zg +;board = nucleo_f756zg +board = nucleo_f767zi +;board = nucleo_h743zi +;board = nucleo_l496zg +;board = nucleo_l496zg-p +;board = nucleo_l4r5zi +;board = nucleo_l4r5zi-p + +; ============================================================ +; Board configuration Nucleo-64 +; ============================================================ + +;board = nucleo_f030r8 +;board = nucleo_f072rb + +;board = nucleo_f091rc +;board = nucleo_f103rb +;board = nucleo_f302r8 +;board = nucleo_f303re +;board = nucleo_f401re +;board = nucleo_f411re +;board = nucleo_f446re +;board = nucleo_g071rb +;board = nucleo_g431rb +;board = nucleo_g474re +;board = nucleo_l053r8 +;board = nucleo_l073rz +;board = nucleo_l152re +;board = nucleo_l433rc_p +;board = nucleo_l452re +;board = nucleo_l452re-p +;board = nucleo_l476rg +;board = pnucleo_wb55rg + +; ============================================================ +; Board configuration Nucleo-32 +; ============================================================ + +;board = nucleo_f031k6 +;board = nucleo_l031k6 +;board = nucleo_l412kb +;board = nucleo_l432lc +;board = nucleo_f303k8 +;board = nucleo_g431kb + +; ============================================================ +; Board configuration Discovery Boards +; ============================================================ + +;board = disco_f030r8 +;board = disco_f072rb +;board = disco_f030r8 +;board = disco_f100rb +;board = disco_f407vg +;board = disco_f413zh +;board = disco_f746ng +;board = disco_g0316 +;board = disco_l475vg_iot +;board = disco_f072cz-lrwan1 + +; ============================================================ +; Board configuration STM32MP1 Boards +; ============================================================ + +;board = stm32mp157a-dk1 +;board = stm32mp157c-dk2 + +; ============================================================ +; Board configuration Generic Boards +; ============================================================ + +;board = bluepill_f103c6 +;board = bluepill_f103c8 +;board = blackpill_f103c8 +;board = stm32f103cx +;board = stm32f103rx +;board = stm32f103tx +;board = stm32f103vx +;board = stm32f103zx +;board = stm32f103zet6 +;board = maplemini_f103cb +;board = blackpill_f303cc +;board = black_f407ve +;board = black_f407vg +;board = black_f407ze +;board = black_f407zg +;board = blue_f407ve_mini +;board = blackpill_f401cc +;board = blackpill_f411ce +;board = coreboard_f401rc +;board = feather_f405 + +; ============================================================ +; Board configuration Many more Boards to be filled +; ============================================================ + + diff --git a/src/FlashStorage_STM32.h b/src/FlashStorage_STM32.h new file mode 100644 index 0000000..12a5152 --- /dev/null +++ b/src/FlashStorage_STM32.h @@ -0,0 +1,195 @@ +/* + EEPROM like API that uses Arduino Zero's flash memory. + Written by A. Christian + + Copyright (c) 2015-2016 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#ifndef FlashAsEEPROM_STM32_h +#define FlashAsEEPROM_STM32_h + +#if !( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \ + defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \ + defined(STM32WB) || defined(STM32MP1) ) + #error This code is intended to run on STM32 platform! Please check your Tools->Board setting. +#endif + +#define FLASH_STORAGE_STM32_VERSION "FlashStorage_STM32 v1.0.0" + +// Only use this with emulated EEPROM, without integrated EEPROM +#if !defined(DATA_EEPROM_BASE) + + class EEPROMClass + { + public: + + EEPROMClass() : _initialized(false), _dirtyBuffer(false), _commitASAP(true) , _validEEPROM(true) {} + + /** + * Read an eeprom cell + * @param index + * @return value + */ + uint8_t read(int address) + { + if (!_initialized) + init(); + + return eeprom_buffered_read_byte(address); + } + + /** + * Update an eeprom cell + * @param index + * @param value + */ + void update(int address, uint8_t value) + { + if (!_initialized) + init(); + + if (eeprom_buffered_read_byte(address) != value) + { + _dirtyBuffer = true; + eeprom_buffered_write_byte(address, value); + } + } + + /** + * Write value to an eeprom cell + * @param index + * @param value + */ + void write(int address, uint8_t value) + { + update(address, value); + } + + /** + * Update eeprom cells from an object + * @param index + * @param value + */ + //Functionality to 'get' and 'put' objects to and from EEPROM. + template< typename T > T &get( int idx, T &t ) + { + // Copy the data from the flash to the buffer if not yet + if (!_initialized) + init(); + + uint16_t offset = idx; + uint8_t* _pointer = (uint8_t *) &t; + + for ( uint16_t count = sizeof(T) ; count ; --count, ++offset ) + { + *_pointer++ = eeprom_buffered_read_byte(offset); + } + + return t; + } + + template< typename T > const T &put( int idx, const T &t ) + { + // Copy the data from the flash to the buffer if not yet + if (!_initialized) + init(); + + uint16_t offset = idx; + + const uint8_t* _pointer = (const uint8_t *) &t; + + for ( uint16_t count = sizeof(T) ; count ; --count, ++offset ) + { + eeprom_buffered_write_byte(offset, *_pointer++); + } + + if (_commitASAP) + { + // Save the data from the buffer to the flash right away + eeprom_buffer_flush(); + + _dirtyBuffer = false; + _validEEPROM = true; + } + else + { + // Delay saving the data from the buffer to the flash. Just flag and wait for commit() later + _dirtyBuffer = true; + } + + return t; + } + + /** + * Check whether the eeprom data is valid + * @return true, if eeprom data is valid (has been written at least once), false if not + */ + bool isValid() + { + return _validEEPROM; + } + + /** + * Write previously made eeprom changes to the underlying flash storage + * Use this with care: Each and every commit will harm the flash and reduce it's lifetime (like with every flash memory) + */ + void commit() + { + if (!_initialized) + init(); + + if (_dirtyBuffer) + { + // Save the data from the buffer to the flash + eeprom_buffer_flush(); + + _dirtyBuffer = false; + _validEEPROM = true; + } + } + + uint16_t length() { return E2END + 1; } + + void setCommitASAP(bool value = true) { _commitASAP = value; } + bool getCommitASAP() { return _commitASAP; } + + private: + + void init() + { + // Copy the data from the flash to the buffer + eeprom_buffer_fill(); + _initialized = true; + } + + bool _initialized; + bool _validEEPROM; + bool _dirtyBuffer; + bool _commitASAP; + }; + + EEPROMClass EEPROM; + +#else + + #include "EEPROM.h" + +#endif // #if !defined(DATA_EEPROM_BASE) + +#endif //#ifndef FlashAsEEPROM_SAMD_h