diff --git a/src/screens/EpubReaderScreen.cpp b/src/screens/EpubReaderScreen.cpp index a6015b7..df630bb 100644 --- a/src/screens/EpubReaderScreen.cpp +++ b/src/screens/EpubReaderScreen.cpp @@ -18,7 +18,7 @@ void EpubReaderScreen::onEnter() { return; } - sectionMutex = xSemaphoreCreateMutex(); + renderingMutex = xSemaphoreCreateMutex(); epub->setupCacheDir(); @@ -45,13 +45,14 @@ void EpubReaderScreen::onEnter() { } void EpubReaderScreen::onExit() { - xSemaphoreTake(sectionMutex, portMAX_DELAY); + // Wait until not rendering to delete task to avoid killing mid-instruction to EPD + xSemaphoreTake(renderingMutex, portMAX_DELAY); if (displayTaskHandle) { vTaskDelete(displayTaskHandle); displayTaskHandle = nullptr; } - vSemaphoreDelete(sectionMutex); - sectionMutex = nullptr; + vSemaphoreDelete(renderingMutex); + renderingMutex = nullptr; delete section; section = nullptr; delete epub; @@ -82,23 +83,25 @@ void EpubReaderScreen::handleInput(const Input input) { if (section->currentPage > 0) { section->currentPage--; } else { - xSemaphoreTake(sectionMutex, portMAX_DELAY); + // We don't want to delete the section mid-render, so grab the semaphore + xSemaphoreTake(renderingMutex, portMAX_DELAY); nextPageNumber = UINT16_MAX; currentSpineIndex--; delete section; section = nullptr; - xSemaphoreGive(sectionMutex); + xSemaphoreGive(renderingMutex); } } else if (input.button == VOLUME_DOWN || input.button == RIGHT) { if (section->currentPage < section->pageCount - 1) { section->currentPage++; } else { - xSemaphoreTake(sectionMutex, portMAX_DELAY); + // We don't want to delete the section mid-render, so grab the semaphore + xSemaphoreTake(renderingMutex, portMAX_DELAY); nextPageNumber = 0; currentSpineIndex++; delete section; section = nullptr; - xSemaphoreGive(sectionMutex); + xSemaphoreGive(renderingMutex); } } @@ -112,7 +115,9 @@ void EpubReaderScreen::displayTaskLoop() { while (true) { if (updateRequired) { updateRequired = false; + xSemaphoreTake(renderingMutex, portMAX_DELAY); renderPage(); + xSemaphoreGive(renderingMutex); } vTaskDelay(10 / portTICK_PERIOD_MS); } @@ -127,7 +132,6 @@ void EpubReaderScreen::renderPage() { currentSpineIndex = 0; } - xSemaphoreTake(sectionMutex, portMAX_DELAY); if (!section) { const auto filepath = epub->getSpineItem(currentSpineIndex); Serial.printf("Loading file: %s, index: %d\n", filepath.c_str(), currentSpineIndex); @@ -153,7 +157,6 @@ void EpubReaderScreen::renderPage() { Serial.println("Failed to persist page data to SD"); delete section; section = nullptr; - xSemaphoreGive(sectionMutex); return; } } else { @@ -186,8 +189,6 @@ void EpubReaderScreen::renderPage() { data[3] = (section->currentPage >> 8) & 0xFF; f.write(data, 4); f.close(); - - xSemaphoreGive(sectionMutex); } void EpubReaderScreen::renderStatusBar() const { diff --git a/src/screens/EpubReaderScreen.h b/src/screens/EpubReaderScreen.h index d88ad49..ca10479 100644 --- a/src/screens/EpubReaderScreen.h +++ b/src/screens/EpubReaderScreen.h @@ -11,7 +11,7 @@ class EpubReaderScreen final : public Screen { Epub* epub; Section* section = nullptr; TaskHandle_t displayTaskHandle = nullptr; - SemaphoreHandle_t sectionMutex = nullptr; + SemaphoreHandle_t renderingMutex = nullptr; int currentSpineIndex = 0; int nextPageNumber = 0; int pagesUntilFullRefresh = 0; diff --git a/src/screens/FileSelectionScreen.cpp b/src/screens/FileSelectionScreen.cpp index 0869819..15cb363 100644 --- a/src/screens/FileSelectionScreen.cpp +++ b/src/screens/FileSelectionScreen.cpp @@ -30,6 +30,8 @@ void FileSelectionScreen::loadFiles() { } void FileSelectionScreen::onEnter() { + renderingMutex = xSemaphoreCreateMutex(); + basepath = "/"; loadFiles(); selectorIndex = 0; @@ -46,10 +48,14 @@ void FileSelectionScreen::onEnter() { } void FileSelectionScreen::onExit() { + // Wait until not rendering to delete task to avoid killing mid-instruction to EPD + xSemaphoreTake(renderingMutex, portMAX_DELAY); if (displayTaskHandle) { vTaskDelete(displayTaskHandle); displayTaskHandle = nullptr; } + vSemaphoreDelete(renderingMutex); + renderingMutex = nullptr; files.clear(); } @@ -85,7 +91,9 @@ void FileSelectionScreen::displayTaskLoop() { while (true) { if (updateRequired) { updateRequired = false; + xSemaphoreTake(renderingMutex, portMAX_DELAY); render(); + xSemaphoreGive(renderingMutex); } vTaskDelay(10 / portTICK_PERIOD_MS); } diff --git a/src/screens/FileSelectionScreen.h b/src/screens/FileSelectionScreen.h index 84a3f80..f7ff920 100644 --- a/src/screens/FileSelectionScreen.h +++ b/src/screens/FileSelectionScreen.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include @@ -10,6 +11,7 @@ class FileSelectionScreen final : public Screen { TaskHandle_t displayTaskHandle = nullptr; + SemaphoreHandle_t renderingMutex = nullptr; std::string basepath = "/"; std::vector files; int selectorIndex = 0;