From 75a708dd4dfa07a4586fa46b6f940ff7cc981ed7 Mon Sep 17 00:00:00 2001
From: David Gauchard <gauchard@laas.fr>
Date: Thu, 15 Jun 2023 14:58:41 +0200
Subject: [PATCH] fix FS: computeNewSpeed() out from interrupt, added locks for
 FS operations

---
 cli.cpp                    |  5 ----
 fs.cpp                     | 47 ++++++++++++++++++++++----------------
 fs.h                       |  2 +-
 motor.h                    | 20 +++++++++-------
 pousseseringue-arduino.cpp | 47 ++++++++++++++++++++++++++++----------
 5 files changed, 75 insertions(+), 46 deletions(-)

diff --git a/cli.cpp b/cli.cpp
index a8d0e90..5d76226 100644
--- a/cli.cpp
+++ b/cli.cpp
@@ -340,11 +340,6 @@ void Cli::loop (Stream& input)
             ls(&Serial);
             answer(true);
         }
-        else if (kw(F("FS-FORMAT")))
-        {
-            format(&Serial);
-            answer(true);
-        }
         else if (kw(F("FS-CAT")))
         {
             copyNextToTemp();
diff --git a/fs.cpp b/fs.cpp
index 16592cd..a02b429 100644
--- a/fs.cpp
+++ b/fs.cpp
@@ -3,53 +3,58 @@
 #include <ESPWebDAV.h>
 #include <LittleFS.h>
 #include <StreamString.h>
+#include <interrupts.h> // InterruptLock
 
 #include "fs.h"
+#include "syringe.h"
+
+using InterruptLock = esp8266::InterruptLock;
+
+extern Syringe syringe;
 
 ESPWebDAVCore* dav = nullptr;
 ESP8266WebServer* http = nullptr;
 FS* filesystem = nullptr;
 const char* fsMsgHeader = nullptr;
 
-bool fs_init (const char* msgHeader)
+bool fs_init (const char* msgHeader, Print* out)
 {
     fsMsgHeader = msgHeader;
     filesystem = &LittleFS;
+
     if (!filesystem->begin() && (!filesystem->format() || !filesystem->begin()))
+    {
+        out->printf("%sFS: mount/format/mount: failed\n", fsMsgHeader);
         return false;
+    }
+
     http = new (std::nothrow) ESP8266WebServer(HTTPORT);
     if (!http)
+    {
+        out->printf("#%sFS: http server start: failed\n", fsMsgHeader);
         return false;
+    }
+
     dav = new (std::nothrow) ESPWebDAVCore;
     if (!dav)
     {
+        out->printf("%sFS: webdav allocation: failed\n", fsMsgHeader);
         delete http;
         return false;
     }
+
     dav->begin(filesystem);
     http->addHook(hookWebDAVForWebserver(DAVROOT, *dav));
+
     return true;
 }
 
-
 void ls (Print* out)
 {
     if (dav)
     {
-        out->printf("#%sLS:\n", fsMsgHeader);
-        dav->dir("/", out);
-    }
-}
-
-void format (Print* out)
-{
-    if (filesystem)
-    {
-        out->printf("%sformatting\n", fsMsgHeader);
-        out->flush();
-        filesystem->format();
-        out->printf("%smkdir %s\n", fsMsgHeader, DAVROOT);
-        filesystem->mkdir(DAVROOT);
+        out->printf("%sLS:\n", fsMsgHeader);
+        { InterruptLock lock; dav->dir("/", out); }
     }
 }
 
@@ -57,14 +62,15 @@ void cat (const char* filename, Stream* out)
 {
     if (filesystem)
     {
-        File f = filesystem->open(filename, "r");
+        File f = ({ InterruptLock lock; filesystem->open(filename, "r"); });
         if (!f)
             out->printf("%scat: '%s' not found\n", fsMsgHeader, filename);
         else
         {
             out->printf("%s>>>>FILE name:'%s' fullname:'%s' size=%zd\n", fsMsgHeader, f.name(), f.fullName(), f.size());
-            f.sendSize(out, f.size());
+            { InterruptLock lock; f.sendSize(out, f.size()); }
             out->printf("%s<<<<FILE\n", fsMsgHeader);
+            { InterruptLock lock; f.close(); }
         }
     }
 }
@@ -73,13 +79,14 @@ void testw (const char* filename, Stream* out)
 {
     if (filesystem)
     {
-        File f = filesystem->open(filename, "w");
+        File f = ({ InterruptLock lock; filesystem->open(filename, "w"); });
         if (!f)
             out->printf("%stest: '%s' can't write\n", fsMsgHeader, filename);
         else
         {
             StreamString blah = "blah";
-            blah.sendAll(f);
+            { InterruptLock lock; blah.sendAll(f); }
+            { InterruptLock lock; f.close(); }
         }
     }
 }
diff --git a/fs.h b/fs.h
index 1c690dc..958e722 100644
--- a/fs.h
+++ b/fs.h
@@ -12,7 +12,7 @@
 #define HTTPORT 80
 #endif
 
-bool fs_init (const char* msgHeader);
+bool fs_init (const char* msgHeader, Print* out);
 void ls (Print* out);
 void format (Print* out);
 void cat (const char* filename, Stream* out);
diff --git a/motor.h b/motor.h
index c7a8d48..9aaf403 100644
--- a/motor.h
+++ b/motor.h
@@ -13,22 +13,27 @@ class AccelStepper
 #include <AccelStepper.h>
 #endif
 
+class isrStepper: public AccelStepper
+{
+    // usefulness: make computeNewSpeed() public to be called outside from interrupt
+public:
+    isrStepper(uint8_t interface = AccelStepper::FULL4WIRE, uint8_t pin1 = 2, uint8_t pin2 = 3, uint8_t pin3 = 4, uint8_t pin4 = 5, bool enable = true):
+        AccelStepper(interface, pin1, pin2, pin3, pin4, enable) { }
+    inline unsigned long computeNewSpeed () { return AccelStepper::computeNewSpeed(); }
+};
+
 class Motor
 {
 public:
 
-    using MotorHardware_t = AccelStepper;
+    using MotorHardware_t = isrStepper;
 
-    Motor (AccelStepper& stepper): stepper(stepper)
+    Motor (isrStepper& stepper): stepper(stepper)
     {
         setSpeedMmPerSec(1);
         setAccelMmPerSecPerSec(0.5); //  <----- this is not yet configured by user
     }
 
-    void setLock (bool locked) { _locked = locked; }
-
-    bool locked () const { return _locked; }
-
     void setMmPerRev (float mmPerRevolution)
     {
         _mmPerRevolution = mmPerRevolution;
@@ -167,11 +172,10 @@ public:
 
 protected:
 
-    bool _locked = false;
     int _stepsPerRevolution = -1;
     float _mmPerRevolution = -1;
     float _retainAccel = -1;
     bool _forwardClockwise;
 
-    AccelStepper& stepper;
+    isrStepper& stepper;
 };
diff --git a/pousseseringue-arduino.cpp b/pousseseringue-arduino.cpp
index 16b7547..14b00b6 100644
--- a/pousseseringue-arduino.cpp
+++ b/pousseseringue-arduino.cpp
@@ -41,6 +41,9 @@
 #include <ESP8266WiFi.h>        // internal, wifi library
 #include <DNSServer.h>          // internal, access point mode
 #include <Schedule.h>
+#include <interrupts.h> // InterruptLock
+
+using InterruptLock = esp8266::InterruptLock;
 
 #if !CORE_MOCK
 #include <SSD1306AsciiWire.h>   // https://github.com/greiman/SSD1306Ascii
@@ -50,9 +53,9 @@ SSD1306AsciiWire oled;
 
 #include "motor.h"
 #if CORE_MOCK
-AccelStepper stepper;
+isrStepper stepper;
 #else
-AccelStepper stepper(AccelStepper::DRIVER, STEP, DIR);
+isrStepper stepper(AccelStepper::DRIVER, STEP, DIR);
 #endif
 
 
@@ -62,8 +65,6 @@ AccelStepper stepper(AccelStepper::DRIVER, STEP, DIR);
 #include "common.h"
 #include "fs.h"
 
-
-
 enum class Modes { TURN, TURNSetup, RPM, RPMSetup, INFO };
 
 const char* msgHeader = MSGHEADER;
@@ -245,16 +246,26 @@ void buttons (int shortp, int longp)
 #if !CORE_MOCK
 
 IRAM_ATTR
-void stepperRun ()
+void stepperRunOLD ()
 {
-    if (syringe.locked())
-        return;
-    cli();
+//    if (syringe.locked())
+//        return;
+//    cli();
+#if 0
     if (rpming)
         stepperMoving = stepper.runSpeed();
     else
         stepperMoving = stepper.run();
-    sei();
+#else
+    stepperMoving = stepper.runSpeed();
+#endif
+//    sei();
+}
+
+IRAM_ATTR
+void stepperRun ()
+{
+    stepperMoving = stepper.runSpeed();
 }
 
 #endif // !CORE_MOCK
@@ -263,6 +274,9 @@ void setup()
 {
     Serial.begin(BAUDRATE);
     Serial.setDebugOutput(true);
+    Serial.println();
+    Serial.println("Booting");
+
 #if !CORE_MOCK
     Wire.begin();
     Wire.setClock(400000L);
@@ -285,6 +299,8 @@ void setup()
     digitalWrite(SLEEP, 0);
 #endif // !CORE_MOCK
 
+#if 0
+
     uint8_t mac[6];
     WiFi.macAddress(mac);
     sprintf(ssid, NAME "-%02x%02x%02x", mac[3], mac[4], mac[5]);
@@ -311,6 +327,10 @@ void setup()
 
     webSetup();
 
+
+#endif //0
+
+
     pinMode(BTNA, INPUT_PULLUP);
     pinMode(BTNB, INPUT_PULLUP);
     pinMode(BTNC, INPUT_PULLUP);
@@ -318,25 +338,29 @@ void setup()
 
     oledRedisplay();
 
+#if 1
+
 #if !CORE_MOCK
 #ifdef ISR_ATTR
     timer1_isr_init();
     timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
     timer1_attachInterrupt(stepperRun);
     timer1_write(microsecondsToClockCycles(100));
+    schedule_recurrent_function_us([](){ if (stepperMoving) { InterruptLock lock; stepper.computeNewSpeed(); } return true; }, 1);
 #else
     #warning ===================================================================================================
     #warning "Please use the ISR version of AccelStepper (git clone -b isr https://github.com/d-a-v/AccelStepper)"
     #warning ===================================================================================================
     schedule_recurrent_function_us([](){ stepperRun(); return true; }, 1);
 #endif
+#endif
+
 #endif
 
     // check if emergency button is pressed at boot time
     syringe.setEmergency(digitalRead(COURSE));
 
-#if 0
-    if (fs_init(msgHeader))
+    if (fs_init(msgHeader, &Serial))
     {
         Serial.printf("FS initialized, dav http server started\n");
     }
@@ -344,7 +368,6 @@ void setup()
     {
         Serial.printf("FS: could not be started\n");
     }
-#endif
 }
 
 
-- 
GitLab