mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2025-12-18 07:07:41 +03:00
Avoid leaving screens mid-display update
Was leave the EPD in a bad state, blocking further actions
This commit is contained in:
parent
98c8e7e77c
commit
899caab70c
@ -18,7 +18,7 @@ void EpubReaderScreen::onEnter() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sectionMutex = xSemaphoreCreateMutex();
|
renderingMutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
epub->setupCacheDir();
|
epub->setupCacheDir();
|
||||||
|
|
||||||
@ -45,13 +45,14 @@ void EpubReaderScreen::onEnter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EpubReaderScreen::onExit() {
|
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) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
}
|
}
|
||||||
vSemaphoreDelete(sectionMutex);
|
vSemaphoreDelete(renderingMutex);
|
||||||
sectionMutex = nullptr;
|
renderingMutex = nullptr;
|
||||||
delete section;
|
delete section;
|
||||||
section = nullptr;
|
section = nullptr;
|
||||||
delete epub;
|
delete epub;
|
||||||
@ -82,23 +83,25 @@ void EpubReaderScreen::handleInput(const Input input) {
|
|||||||
if (section->currentPage > 0) {
|
if (section->currentPage > 0) {
|
||||||
section->currentPage--;
|
section->currentPage--;
|
||||||
} else {
|
} 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;
|
nextPageNumber = UINT16_MAX;
|
||||||
currentSpineIndex--;
|
currentSpineIndex--;
|
||||||
delete section;
|
delete section;
|
||||||
section = nullptr;
|
section = nullptr;
|
||||||
xSemaphoreGive(sectionMutex);
|
xSemaphoreGive(renderingMutex);
|
||||||
}
|
}
|
||||||
} else if (input.button == VOLUME_DOWN || input.button == RIGHT) {
|
} else if (input.button == VOLUME_DOWN || input.button == RIGHT) {
|
||||||
if (section->currentPage < section->pageCount - 1) {
|
if (section->currentPage < section->pageCount - 1) {
|
||||||
section->currentPage++;
|
section->currentPage++;
|
||||||
} else {
|
} 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;
|
nextPageNumber = 0;
|
||||||
currentSpineIndex++;
|
currentSpineIndex++;
|
||||||
delete section;
|
delete section;
|
||||||
section = nullptr;
|
section = nullptr;
|
||||||
xSemaphoreGive(sectionMutex);
|
xSemaphoreGive(renderingMutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +115,9 @@ void EpubReaderScreen::displayTaskLoop() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
if (updateRequired) {
|
if (updateRequired) {
|
||||||
updateRequired = false;
|
updateRequired = false;
|
||||||
|
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||||
renderPage();
|
renderPage();
|
||||||
|
xSemaphoreGive(renderingMutex);
|
||||||
}
|
}
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
@ -127,7 +132,6 @@ void EpubReaderScreen::renderPage() {
|
|||||||
currentSpineIndex = 0;
|
currentSpineIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
xSemaphoreTake(sectionMutex, portMAX_DELAY);
|
|
||||||
if (!section) {
|
if (!section) {
|
||||||
const auto filepath = epub->getSpineItem(currentSpineIndex);
|
const auto filepath = epub->getSpineItem(currentSpineIndex);
|
||||||
Serial.printf("Loading file: %s, index: %d\n", filepath.c_str(), 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");
|
Serial.println("Failed to persist page data to SD");
|
||||||
delete section;
|
delete section;
|
||||||
section = nullptr;
|
section = nullptr;
|
||||||
xSemaphoreGive(sectionMutex);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -186,8 +189,6 @@ void EpubReaderScreen::renderPage() {
|
|||||||
data[3] = (section->currentPage >> 8) & 0xFF;
|
data[3] = (section->currentPage >> 8) & 0xFF;
|
||||||
f.write(data, 4);
|
f.write(data, 4);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
xSemaphoreGive(sectionMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EpubReaderScreen::renderStatusBar() const {
|
void EpubReaderScreen::renderStatusBar() const {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ class EpubReaderScreen final : public Screen {
|
|||||||
Epub* epub;
|
Epub* epub;
|
||||||
Section* section = nullptr;
|
Section* section = nullptr;
|
||||||
TaskHandle_t displayTaskHandle = nullptr;
|
TaskHandle_t displayTaskHandle = nullptr;
|
||||||
SemaphoreHandle_t sectionMutex = nullptr;
|
SemaphoreHandle_t renderingMutex = nullptr;
|
||||||
int currentSpineIndex = 0;
|
int currentSpineIndex = 0;
|
||||||
int nextPageNumber = 0;
|
int nextPageNumber = 0;
|
||||||
int pagesUntilFullRefresh = 0;
|
int pagesUntilFullRefresh = 0;
|
||||||
|
|||||||
@ -30,6 +30,8 @@ void FileSelectionScreen::loadFiles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FileSelectionScreen::onEnter() {
|
void FileSelectionScreen::onEnter() {
|
||||||
|
renderingMutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
basepath = "/";
|
basepath = "/";
|
||||||
loadFiles();
|
loadFiles();
|
||||||
selectorIndex = 0;
|
selectorIndex = 0;
|
||||||
@ -46,10 +48,14 @@ void FileSelectionScreen::onEnter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void FileSelectionScreen::onExit() {
|
void FileSelectionScreen::onExit() {
|
||||||
|
// Wait until not rendering to delete task to avoid killing mid-instruction to EPD
|
||||||
|
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||||
if (displayTaskHandle) {
|
if (displayTaskHandle) {
|
||||||
vTaskDelete(displayTaskHandle);
|
vTaskDelete(displayTaskHandle);
|
||||||
displayTaskHandle = nullptr;
|
displayTaskHandle = nullptr;
|
||||||
}
|
}
|
||||||
|
vSemaphoreDelete(renderingMutex);
|
||||||
|
renderingMutex = nullptr;
|
||||||
files.clear();
|
files.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +91,9 @@ void FileSelectionScreen::displayTaskLoop() {
|
|||||||
while (true) {
|
while (true) {
|
||||||
if (updateRequired) {
|
if (updateRequired) {
|
||||||
updateRequired = false;
|
updateRequired = false;
|
||||||
|
xSemaphoreTake(renderingMutex, portMAX_DELAY);
|
||||||
render();
|
render();
|
||||||
|
xSemaphoreGive(renderingMutex);
|
||||||
}
|
}
|
||||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <freertos/FreeRTOS.h>
|
#include <freertos/FreeRTOS.h>
|
||||||
#include <freertos/task.h>
|
#include <freertos/task.h>
|
||||||
|
#include <freertos/semphr.h>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -10,6 +11,7 @@
|
|||||||
|
|
||||||
class FileSelectionScreen final : public Screen {
|
class FileSelectionScreen final : public Screen {
|
||||||
TaskHandle_t displayTaskHandle = nullptr;
|
TaskHandle_t displayTaskHandle = nullptr;
|
||||||
|
SemaphoreHandle_t renderingMutex = nullptr;
|
||||||
std::string basepath = "/";
|
std::string basepath = "/";
|
||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
int selectorIndex = 0;
|
int selectorIndex = 0;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user