diff --git a/include/UpdateServer.h b/include/UpdateServer.h index c94c448..1912209 100644 --- a/include/UpdateServer.h +++ b/include/UpdateServer.h @@ -2,6 +2,9 @@ #include +#include +#include + #include "ChallengeResponse.h" class UpdateServer @@ -12,7 +15,7 @@ class UpdateServer UT_SPIFFS = 1 }; - UpdateServer(const std::string &pw); + UpdateServer(const std::string &pw, SemaphoreHandle_t *ledLockoutMutex); void start(void); @@ -20,4 +23,5 @@ class UpdateServer static void updateTask(void *arg); ChallengeResponse m_cr; + SemaphoreHandle_t *m_ledLockoutMutex; }; diff --git a/include/WebServer.h b/include/WebServer.h index e41543f..6c3a08e 100644 --- a/include/WebServer.h +++ b/include/WebServer.h @@ -4,6 +4,9 @@ #include #include +#include +#include + #include "ChallengeResponse.h" class Fader; @@ -16,6 +19,7 @@ class WebServer void setFader(Fader *fader) { m_fader = fader;} void setAnimationController(AnimationController *controller) { m_animController = controller;} + void setLedLockoutMutex(SemaphoreHandle_t *ledLockoutMutex) { m_ledLockoutMutex = ledLockoutMutex; } static WebServer &instance(void) { @@ -30,6 +34,8 @@ class WebServer Fader *m_fader; AnimationController *m_animController; + SemaphoreHandle_t *m_ledLockoutMutex; + WebServer(void); static void serverTask(void *arg); diff --git a/src/UpdateServer.cpp b/src/UpdateServer.cpp index 5edf711..1390144 100644 --- a/src/UpdateServer.cpp +++ b/src/UpdateServer.cpp @@ -8,8 +8,8 @@ #include "coreids.h" -UpdateServer::UpdateServer(const std::string &pw) - : m_cr(pw) +UpdateServer::UpdateServer(const std::string &pw, SemaphoreHandle_t *ledLockoutMutex) + : m_cr(pw), m_ledLockoutMutex(ledLockoutMutex) {} void UpdateServer::start(void) @@ -177,7 +177,11 @@ void UpdateServer::updateTask(void *arg) if(client.available()) { size_t bytes_read = client.read(buf, 1024); + + // block LED updates while writing flash + xSemaphoreTake(*obj->m_ledLockoutMutex, portMAX_DELAY); Update.write(buf, bytes_read); + xSemaphoreGive(*obj->m_ledLockoutMutex); bytes_processed += bytes_read; } diff --git a/src/WebServer.cpp b/src/WebServer.cpp index a0443ca..68ffc21 100644 --- a/src/WebServer.cpp +++ b/src/WebServer.cpp @@ -22,11 +22,17 @@ bool WebServer::serveFile(String filename, httpsserver::HTTPResponse *res) { uint8_t buf[1024]; - if(!SPIFFS.exists(filename)) { + xSemaphoreTake(*instance().m_ledLockoutMutex, portMAX_DELAY); + bool exists = SPIFFS.exists(filename); + xSemaphoreGive(*instance().m_ledLockoutMutex); + + if(!exists) { return false; } + xSemaphoreTake(*instance().m_ledLockoutMutex, portMAX_DELAY); File f = SPIFFS.open(filename.c_str(), "r"); + xSemaphoreGive(*instance().m_ledLockoutMutex); if(!f) { return false; @@ -36,7 +42,10 @@ bool WebServer::serveFile(String filename, httpsserver::HTTPResponse *res) size_t nread = 1; while(nread > 0) { + xSemaphoreTake(*instance().m_ledLockoutMutex, portMAX_DELAY); nread = f.readBytes(reinterpret_cast(buf), 1024); + xSemaphoreGive(*instance().m_ledLockoutMutex); + if(nread <= 0) { break; } @@ -44,7 +53,9 @@ bool WebServer::serveFile(String filename, httpsserver::HTTPResponse *res) res->write(buf, nread); } + xSemaphoreTake(*instance().m_ledLockoutMutex, portMAX_DELAY); f.close(); + xSemaphoreGive(*instance().m_ledLockoutMutex); return true; } diff --git a/src/main.cpp b/src/main.cpp index 86bc8ee..9a8280a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,6 +6,9 @@ #include #include +#include +#include + #include "WebServer.h" #include "Fader.h" #include "UDPProto.h" @@ -34,6 +37,11 @@ bool led_on = false; size_t led_idx; WiFiMulti wiFiMulti; +// this mutex is locked while LEDs are written and must be also locked +// by any task accessing the flash, as (probably) the interrupts +// from the flash cause the LED update to be unreliable. +SemaphoreHandle_t ledLockoutMutex; + Fader ledFader(NUM_STRIPS, NUM_LEDS, 1, FLIP_STRIPS_MASK); UDPProto udpProto(&ledFader); UpdateServer *updateServer; @@ -207,9 +215,11 @@ static void ledTask( void * parameter ) const Fader::Color &c = colors[i]; STRANDS[0].pixels[i] = pixelFromRGBW(c.r, c.g, c.b, c.w); } - } - digitalLeds_drawPixels(strands, 1); + xSemaphoreTake(ledLockoutMutex, portMAX_DELAY); + digitalLeds_drawPixels(strands, 1); + xSemaphoreGive(ledLockoutMutex); + } frame++; @@ -278,6 +288,9 @@ void setup() Serial.begin(115200); delay(10); + // initalize the semaphores before anything else + ledLockoutMutex = xSemaphoreCreateMutex(); + if(!initLEDs()) { Serial.println("LED setup failed!"); while(true) { @@ -326,11 +339,12 @@ void setup() // start the web server WebServer::instance().setFader(&ledFader); + WebServer::instance().setLedLockoutMutex(&ledLockoutMutex); WebServer::instance().setAnimationController(&animController); WebServer::instance().start(); // start the update server - updateServer = new UpdateServer(Config::instance().getCRPassword()); + updateServer = new UpdateServer(Config::instance().getCRPassword(), &ledLockoutMutex); updateServer->start(); }