From c3e522553130f93747fe2e1031d719ee2e8b0cfb Mon Sep 17 00:00:00 2001
From: Tanguy Pruvot <tpruvot@users.noreply.github.com>
Date: Tue, 11 Jun 2019 06:30:23 +0200
Subject: [PATCH] Add SPI EEPROM to STM32F1 (#14239)

---
 .../src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp   | 18 ++++-
 .../HAL_STM32F1/persistent_store_eeprom.cpp   | 66 +++++++++++++++++++
 .../HAL_STM32F1/persistent_store_sdcard.cpp   |  2 +-
 3 files changed, 84 insertions(+), 2 deletions(-)
 create mode 100644 Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp

diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp
index cbc6c7fe1a..29713f4c1d 100644
--- a/Marlin/src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/HAL_spi_STM32F1.cpp
@@ -40,9 +40,10 @@
 #include "../shared/HAL_SPI.h"
 #include "pins_arduino.h"
 #include "spi_pins.h"
-#include "../../core/macros.h"
 #include <SPI.h>
 
+#include "../../inc/MarlinConfigPre.h"
+
 // --------------------------------------------------------------------------
 // Public Variables
 // --------------------------------------------------------------------------
@@ -180,6 +181,21 @@ void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode)
   SPI.beginTransaction(spiConfig);
 }
 
+#if ENABLED(SPI_EEPROM)
+
+// Read single byte from specified SPI channel
+uint8_t spiRec(uint32_t chan) { return spiRec(); }
+
+// Write single byte to specified SPI channel
+void spiSend(uint32_t chan, byte b) { spiSend(b); }
+
+// Write buffer to specified SPI channel
+void spiSend(uint32_t chan, const uint8_t* buf, size_t n) {
+  for (size_t p = 0; p < n; p++) spiSend(buf[p]);
+}
+
+#endif // SPI_EEPROM
+
 #endif // SOFTWARE_SPI
 
 #endif // __STM32F1__
diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp b/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp
new file mode 100644
index 0000000000..f3fb2409d0
--- /dev/null
+++ b/Marlin/src/HAL/HAL_STM32F1/persistent_store_eeprom.cpp
@@ -0,0 +1,66 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (C) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifdef __STM32F1__
+
+#include "../../inc/MarlinConfig.h"
+
+#if ENABLED(EEPROM_SETTINGS) && EITHER(SPI_EEPROM, I2C_EEPROM)
+
+#include "../shared/persistent_store_api.h"
+
+bool PersistentStore::access_start() { return true; }
+bool PersistentStore::access_finish() { return true; }
+
+bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+  while (size--) {
+    uint8_t * const p = (uint8_t * const)pos;
+    uint8_t v = *value;
+    // EEPROM has only ~100,000 write cycles,
+    // so only write bytes that have changed!
+    if (v != eeprom_read_byte(p)) {
+      eeprom_write_byte(p, v);
+      if (eeprom_read_byte(p) != v) {
+        SERIAL_ECHO_MSG(MSG_ERR_EEPROM_WRITE);
+        return true;
+      }
+    }
+    crc16(crc, &v, 1);
+    pos++;
+    value++;
+  };
+  return false;
+}
+
+bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool set/*=true*/) {
+  do {
+    uint8_t c = eeprom_read_byte((uint8_t*)pos);
+    if (set && value) *value = c;
+    crc16(crc, &c, 1);
+    pos++;
+    value++;
+  } while (--size);
+  return false;
+}
+
+size_t PersistentStore::capacity() { return E2END + 1; }
+
+#endif // EEPROM_SETTINGS && EITHER(SPI_EEPROM, I2C_EEPROM)
+#endif // __STM32F1__
diff --git a/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp b/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp
index 5ef638263b..5774581865 100644
--- a/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp
+++ b/Marlin/src/HAL/HAL_STM32F1/persistent_store_sdcard.cpp
@@ -28,7 +28,7 @@
 
 #include "../../inc/MarlinConfig.h"
 
-#if ENABLED(EEPROM_SETTINGS) && DISABLED(FLASH_EEPROM_EMULATION)
+#if ENABLED(EEPROM_SETTINGS) && NONE(FLASH_EEPROM_EMULATION, SPI_EEPROM, I2C_EEPROM)
 
 #include "../shared/persistent_store_api.h"