M module-bsp/board/linux/eink/ED028TC1.c => module-bsp/board/linux/eink/ED028TC1.c +1 -1
@@ 129,7 129,7 @@ EinkStatus_e EinkResetAndInitialize()
return EinkOK;
}
-EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings)
+EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings)
{
return EinkOK;
}
M module-bsp/board/linux/eink/ED028TC1.h => module-bsp/board/linux/eink/ED028TC1.h +4 -2
@@ 297,6 297,8 @@ extern "C"
EinkWaveforms_e mode;
// temperature of surrounding
int32_t temperature;
+ // use counter to keep track if need to change
+ uint32_t useCounter;
// pointer to lookup table for lut c
uint8_t *LUTCData;
// sizeo of lutc data
@@ 305,7 307,7 @@ extern "C"
uint8_t *LUTDData;
// size of lutd data
uint32_t LUTDSize;
- } EinkWaveFormSettings_t;
+ } EinkWaveformSettings_t;
/* Exported constants --------------------------------------------------------*/
@@ 419,7 421,7 @@ extern "C"
* @param LUTCData [in] - Data
* @return
*/
- EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings);
+ EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings);
/**
* This function converts the ARGB image to the L4 format
M module-bsp/board/rt1051/bsp/eink/ED028TC1.cpp => module-bsp/board/rt1051/bsp/eink/ED028TC1.cpp +8 -17
@@ 65,8 65,6 @@
#define _delay_ms(ms) vTaskDelay(pdMS_TO_TICKS(ms))
-#define EINK_SUSPEND_TASK_TILL_EPD_BUSY() BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(1000))
-
//#define EINK_DEBUG_LOG 1
//
//#if EINK_DEBUG_LOG == 1
@@ 81,14 79,11 @@ using namespace magic_enum;
static std::shared_ptr<drivers::DriverDMA> dma;
static std::shared_ptr<drivers::DriverDMAMux> dmamux;
-#define EINK_LUTS_FILE_PATH "/Luts.bin"
-
/* Internal variable definitions */
static uint8_t s_einkIsPoweredOn = false; // Variable which contains the state of the power of the EPD display
static EinkWaveforms_e s_einkConfiguredWaveform =
EinkWaveformGC16; // This variable contains the current waveform set in the display
-static int8_t s_einkPreviousTemperature = 127; // This variable contains the last measured temperature of the ambient
static CACHEABLE_SECTION_SDRAM(uint8_t s_einkServiceRotatedBuf[BOARD_EINK_DISPLAY_RES_X * BOARD_EINK_DISPLAY_RES_Y / 2 +
2]); // Plus 2 for the EPD command and BPP config
@@ 548,7 543,7 @@ void EinkPowerOn()
return;
}
- EINK_SUSPEND_TASK_TILL_EPD_BUSY();
+ BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
s_einkIsPoweredOn = true;
}
}
@@ 563,7 558,7 @@ void EinkPowerOff()
return;
}
- EINK_SUSPEND_TASK_TILL_EPD_BUSY();
+ BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
s_einkIsPoweredOn = false;
}
}
@@ 590,7 585,7 @@ int16_t EinkGetTemperatureInternal()
return -1;
}
- EINK_SUSPEND_TASK_TILL_EPD_BUSY();
+ BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
if (BSP_EinkReadData(temp, sizeof(temp), SPI_MANUAL_CS) != 0) {
// LOG_ERROR("Requesting the temperature FAILED");
@@ 641,8 636,8 @@ static void s_EinkSetInitialConfig()
}
tmpbuf[0] = EinkPanelSetting; // 0x00
- tmpbuf[1] = LUT_SEL | SHL | RST_N; // 0x25 -> _XON _RES0 LUT_SEL _DM - SHL _SPIWM RST_N // If 0x35 (DM - 1 is used
- // (2bpp)) the SPI speed can be 25MHz
+ tmpbuf[1] = LUT_SEL | SHL | RST_N; // 0x25 -> _XON _RES0 LUT_SEL _DM - SHL _SPIWM RST_N
+ // If 0x35 (DM - 1 is used (2bpp)) the SPI speed can be 25MHz
tmpbuf[2] = 0x00;
if (BSP_EinkWriteData(tmpbuf, 3, SPI_AUTOMATIC_CS) != 0) {
// LOG_ERROR("Setting the initial configuration for the Eink failed");
@@ 747,13 742,9 @@ EinkStatus_e EinkResetAndInitialize()
return EinkOK;
}
-EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings)
+EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings)
{
- // If neither the temperature nor the waveform has changed - do nothing
- if ((settings->temperature == s_einkPreviousTemperature) && (settings->mode == s_einkConfiguredWaveform)) {
- return EinkOK;
- }
-
+ /// LUTD
if (BSP_EinkWriteData(settings->LUTDData, settings->LUTDSize, SPI_AUTOMATIC_CS) != 0) {
EinkResetAndInitialize();
return EinkSPIErr;
@@ 1015,7 1006,7 @@ EinkStatus_e EinkRefreshImage(
return EinkSPIErr;
}
- EINK_SUSPEND_TASK_TILL_EPD_BUSY();
+ BSP_EinkWaitUntilDisplayBusy(pdMS_TO_TICKS(BSP_EinkBusyTimeout));
return EinkOK;
}
M module-bsp/board/rt1051/bsp/eink/ED028TC1.h => module-bsp/board/rt1051/bsp/eink/ED028TC1.h +4 -2
@@ 297,6 297,8 @@ extern "C"
EinkWaveforms_e mode;
// temperature of surrounding
int32_t temperature;
+ // counts usage of this waveform (display refreshes)
+ uint32_t useCounter;
// pointer to lookup table for lut c
uint8_t *LUTCData;
// sizeo of lutc data
@@ 305,7 307,7 @@ extern "C"
uint8_t *LUTDData;
// size of lutd data
uint32_t LUTDSize;
- } EinkWaveFormSettings_t;
+ } EinkWaveformSettings_t;
/* Exported constants --------------------------------------------------------*/
@@ 419,7 421,7 @@ extern "C"
* @param LUTCData [in] - Data
* @return
*/
- EinkStatus_e EinkUpdateWaveform(const EinkWaveFormSettings_t *settings);
+ EinkStatus_e EinkUpdateWaveform(const EinkWaveformSettings_t *settings);
/**
* This function converts the ARGB image to the L4 format
M module-bsp/board/rt1051/bsp/eink/bsp_eink.h => module-bsp/board/rt1051/bsp/eink/bsp_eink.h +1 -1
@@ 33,7 33,7 @@ extern "C"
typedef void (*bsp_eink_BusyEvent)(void);
-#define BSP_EINK_TRANSFER_TIMEOUT_MS 1000
+ inline constexpr auto BSP_EinkBusyTimeout = 3000U;
status_t BSP_EinkInit(bsp_eink_BusyEvent event);
void BSP_EinkDeinit(void);
M module-services/service-eink/CMakeLists.txt => module-services/service-eink/CMakeLists.txt +1 -1
@@ 16,7 16,7 @@ set(SOURCES
ServiceEink.cpp
EinkDisplay.cpp
messages/ImageMessage.cpp
- messages/PrepareDisplayRequest.cpp
+ messages/PrepareDisplayEarlyRequest.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES})
M module-services/service-eink/EinkDisplay.cpp => module-services/service-eink/EinkDisplay.cpp +102 -47
@@ 17,17 17,23 @@ namespace service::eink
constexpr auto LutsFileName = "Luts.bin";
constexpr auto LUTDSize = 16385;
constexpr auto LUTCSize = 64;
- constexpr auto LUTRSize = 256; ///< Needed due to \ref EINK_LUTS_FILE_PATH structure
+ constexpr auto LUTRSize = 256; ///< Needed due to \ref LutsFileName structure
constexpr auto LUTSTotalSize = LUTDSize + LUTCSize + LUTRSize;
- constexpr auto LUTVersionInterval = 3;
- constexpr auto LUTSubcritical = 12;
- constexpr auto LUTCritical = 13;
- EinkWaveFormSettings_t createDefaultWaveFormSettings(EinkWaveforms_e waveformMode)
+ constexpr auto LUTTemperatureMinimal = 0;
+ constexpr auto LUTTemperatureSubcritical = 38;
+ constexpr auto LUTTemperatureCritical = 43;
+
+ constexpr auto LUTTemperatureOffsetInterval = 3;
+ constexpr auto LUTTemperatureOffsetSubcritical = 12;
+ constexpr auto LUTTemperatureOffsetCritical = 13;
+
+ EinkWaveformSettings_t createDefaultWaveFormSettings(EinkWaveforms_e waveformMode)
{
- EinkWaveFormSettings_t settings{};
+ EinkWaveformSettings_t settings{};
settings.mode = waveformMode;
settings.temperature = DefaultSurroundingTemperature;
+ settings.useCounter = 0;
settings.LUTCData = nullptr;
settings.LUTCSize = 0;
settings.LUTDData = nullptr;
@@ 37,14 43,14 @@ namespace service::eink
} // namespace
EinkDisplay::EinkDisplay(::gui::Size screenSize)
- : size{screenSize}, waveformSettings{createDefaultWaveFormSettings(EinkWaveformGC16)},
+ : size{screenSize}, currentWaveform{createDefaultWaveFormSettings(EinkWaveformGC16)},
displayMode{EinkDisplayColorMode_e::EinkDisplayColorModeStandard}
{}
EinkDisplay::~EinkDisplay() noexcept
{
- delete[] waveformSettings.LUTCData;
- delete[] waveformSettings.LUTDData;
+ delete[] currentWaveform.LUTCData;
+ delete[] currentWaveform.LUTDData;
}
EinkStatus_e EinkDisplay::resetAndInit()
@@ 85,27 91,68 @@ namespace service::eink
EinkBpp_e EinkDisplay::getCurrentBitsPerPixelFormat() const noexcept
{
- if ((waveformSettings.mode == EinkWaveformA2) || (waveformSettings.mode == EinkWaveformDU2)) {
- return Eink4Bpp; /// this should be 1Bpp, but the OS is not ready for this
+ if ((currentWaveform.mode == EinkWaveformA2) || (currentWaveform.mode == EinkWaveformDU2)) {
+ return Eink4Bpp; // this should be 1Bpp, but the OS is not ready for this (in 1Bpp → halftones disappear)
}
return Eink4Bpp;
}
EinkStatus_e EinkDisplay::refresh(EinkDisplayTimingsMode_e refreshMode)
{
+ currentWaveform.useCounter += 1;
return EinkRefreshImage(pointTopLeft.x, pointTopLeft.y, size.width, size.height, refreshMode);
}
- bool EinkDisplay::changeWaveform(EinkWaveforms_e mode, std::int32_t temperature)
+ bool EinkDisplay::isNewWaveformNeeded(EinkWaveforms_e newMode, std::int32_t newTemperature) const
+ {
+ constexpr auto lenientTemperatureUseCounter = 50; // arbitrary. not documented
+ auto alloweLenientTemperature = currentWaveform.useCounter < lenientTemperatureUseCounter;
+
+ // at least: modes cannot differ
+ if (alloweLenientTemperature && newMode == currentWaveform.mode) {
+ bool temperatureFine = false;
+
+ switch (currentWaveform.mode) {
+ case EinkWaveformA2:
+ [[fallthrough]];
+ case EinkWaveformDU2:
+ temperatureFine = abs(newTemperature - currentWaveform.temperature) <= 3;
+ break;
+ case EinkWaveformINIT:
+ [[fallthrough]];
+ case EinkWaveformGLD16:
+ [[fallthrough]];
+ case EinkWaveformGC16:
+ temperatureFine = abs(newTemperature - currentWaveform.temperature) <= 2;
+ break;
+ }
+
+ if (temperatureFine) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool EinkDisplay::setWaveform(EinkWaveforms_e mode, std::int32_t temperature)
{
- if (temperature == waveformSettings.temperature && mode == waveformSettings.mode) {
- return EinkOK;
+ if (!isNewWaveformNeeded(mode, temperature)) {
+ return true;
}
- waveformSettings.temperature = temperature;
- waveformSettings.mode = mode;
- const auto segment = calculateWaveFormSegment(temperature);
- auto offset = calculateWaveFormOffset(mode, segment);
+ auto currentOffset =
+ toWaveformOffset(currentWaveform.mode, toWaveformTemperatureOffset(currentWaveform.temperature));
+ // assume it is changed
+ currentWaveform.useCounter = 0;
+ currentWaveform.temperature = temperature;
+ currentWaveform.mode = mode;
+
+ auto offset = toWaveformOffset(mode, toWaveformTemperatureOffset(temperature));
+
+ if (offset == currentOffset) {
+ // current waveform is still the best fit
+ return true;
+ }
auto file = std::fopen(LutsFileName, "rb");
if (file == nullptr) {
@@ 114,62 161,70 @@ namespace service::eink
}
auto fileHandlerCleanup = gsl::finally([&file]() { std::fclose(file); });
- resetWaveFormSettings();
+ resetWaveformSettings();
std::fseek(file, offset, SEEK_SET);
- std::fread(&waveformSettings.LUTDData[1], 1, LUTDSize, file);
+ std::fread(¤tWaveform.LUTDData[1], 1, LUTDSize, file);
// 0x00 - 1 frame, ... , 0x0F - 16 frames
- const uint8_t frameCount = waveformSettings.LUTDData[1] + 1;
+ const uint8_t waveformFrameCount = currentWaveform.LUTDData[1] + 1;
// (frameCount * 64) - size of actual LUT; (+1) - the byte containing frameCount; (+1) - EinkLUTD command
- waveformSettings.LUTDSize = (frameCount * 64) + 1 + 1;
+ currentWaveform.LUTDSize = (waveformFrameCount * 64) + 1 + 1;
offset += LUTDSize;
std::fseek(file, offset, SEEK_SET);
- std::fread(&waveformSettings.LUTCData[1], 1, LUTCSize, file);
+ std::fread(¤tWaveform.LUTCData[1], 1, LUTCSize, file);
- EinkUpdateWaveform(&waveformSettings);
+ EinkUpdateWaveform(¤tWaveform);
return true;
}
- unsigned int EinkDisplay::calculateWaveFormSegment(std::int32_t temperature) const
+ unsigned int EinkDisplay::toWaveformTemperatureOffset(std::int32_t temperature) noexcept
{
- if (temperature < 38) {
- return temperature / LUTVersionInterval;
- }
- if (temperature < 43) {
- return LUTSubcritical;
+ if (temperature >= LUTTemperatureCritical)
+ return LUTTemperatureOffsetCritical;
+ if (temperature >= LUTTemperatureSubcritical)
+ return LUTTemperatureOffsetSubcritical;
+ if (temperature < LUTTemperatureMinimal) {
+ temperature = 0;
}
- return LUTCritical;
+ return temperature / LUTTemperatureOffsetInterval;
+ }
+
+ unsigned int EinkDisplay::toWaveformOffset(unsigned short LUTbank, unsigned int temperatureOffset) noexcept
+ {
+ constexpr auto singleLUTOffset = (LUTTemperatureOffsetCritical + 1);
+ return LUTSTotalSize * (singleLUTOffset * LUTbank + temperatureOffset);
}
- unsigned int EinkDisplay::calculateWaveFormOffset(EinkWaveforms_e mode, unsigned int segment) const
+ unsigned int EinkDisplay::toWaveformOffset(EinkWaveforms_e mode, unsigned int temperatureOffset)
{
switch (mode) {
case EinkWaveformINIT:
- return LUTSTotalSize * segment;
+ return toWaveformOffset(0, temperatureOffset);
case EinkWaveformA2:
- return LUTSTotalSize * (14 + segment);
+ return toWaveformOffset(1, temperatureOffset);
case EinkWaveformDU2:
- return LUTSTotalSize * (28 + segment);
+ return toWaveformOffset(2, temperatureOffset);
case EinkWaveformGLD16:
- return LUTSTotalSize * (42 + segment);
+ return toWaveformOffset(3, temperatureOffset);
case EinkWaveformGC16:
- return LUTSTotalSize * (56 + segment);
+ return toWaveformOffset(4, temperatureOffset);
+ default:
+ throw std::invalid_argument{"Invalid waveform mode."};
}
- throw std::invalid_argument{"Invalid waveform mode."};
}
- void EinkDisplay::resetWaveFormSettings()
+ void EinkDisplay::resetWaveformSettings()
{
- delete[] waveformSettings.LUTDData;
- waveformSettings.LUTDSize = 0;
- waveformSettings.LUTDData = new std::uint8_t[LUTDSize + 1];
- waveformSettings.LUTDData[0] = EinkLUTD;
+ delete[] currentWaveform.LUTDData;
+ currentWaveform.LUTDSize = 0;
+ currentWaveform.LUTDData = new std::uint8_t[LUTDSize + 1];
+ currentWaveform.LUTDData[0] = EinkLUTD;
- delete[] waveformSettings.LUTCData;
- waveformSettings.LUTCSize = LUTCSize;
- waveformSettings.LUTCData = new std::uint8_t[LUTCSize + 1];
- waveformSettings.LUTCData[0] = EinkLUTC;
+ delete[] currentWaveform.LUTCData;
+ currentWaveform.LUTCSize = LUTCSize;
+ currentWaveform.LUTCData = new std::uint8_t[LUTCSize + 1];
+ currentWaveform.LUTCData[0] = EinkLUTC;
}
void EinkDisplay::setMode(EinkDisplayColorMode_e mode) noexcept
M module-services/service-eink/EinkDisplay.hpp => module-services/service-eink/EinkDisplay.hpp +8 -6
@@ 32,20 32,22 @@ namespace service::eink
void powerOff();
void shutdown();
- bool changeWaveform(EinkWaveforms_e mode, std::int32_t temperature);
+ bool setWaveform(EinkWaveforms_e mode, std::int32_t temperature);
void setMode(EinkDisplayColorMode_e mode) noexcept;
::gui::Size getSize() const noexcept;
private:
- unsigned int calculateWaveFormSegment(std::int32_t temperature) const;
- unsigned int calculateWaveFormOffset(EinkWaveforms_e mode, unsigned int segment) const;
- void resetWaveFormSettings();
- EinkBpp_e getCurrentBitsPerPixelFormat() const noexcept;
+ static unsigned int toWaveformTemperatureOffset(std::int32_t temperature) noexcept;
+ static unsigned int toWaveformOffset(unsigned short LUTbank, unsigned int temperatureOffset) noexcept;
+ static unsigned int toWaveformOffset(EinkWaveforms_e mode, unsigned int temperatureOffset);
+ bool isNewWaveformNeeded(EinkWaveforms_e newMode, int32_t newTemperature) const;
+ void resetWaveformSettings();
+ EinkBpp_e getCurrentBitsPerPixelFormat() const noexcept;
static constexpr ::gui::Point pointTopLeft{0, 0};
const ::gui::Size size;
- EinkWaveFormSettings_t waveformSettings;
+ EinkWaveformSettings_t currentWaveform;
EinkDisplayColorMode_e displayMode;
};
} // namespace service::eink
M module-services/service-eink/ServiceEink.cpp => module-services/service-eink/ServiceEink.cpp +11 -11
@@ 3,9 3,9 @@
#include "ServiceEink.hpp"
#include "messages/EinkModeMessage.hpp"
-#include "messages/PrepareDisplayRequest.hpp"
+#include "messages/PrepareDisplayEarlyRequest.hpp"
#include <service-gui/Common.hpp>
-#include <service-gui/messages/EinkReady.hpp>
+#include <service-gui/messages/EinkInitialized.hpp>
#include <time/ScopedTime.hpp>
#include <log/log.hpp>
@@ 32,8 32,8 @@ namespace service::eink
connect(typeid(ImageMessage),
[this](sys::Message *request) -> sys::MessagePointer { return handleImageMessage(request); });
- connect(typeid(PrepareDisplayRequest),
- [this](sys::Message *request) -> sys::MessagePointer { return handlePrepareRequest(request); });
+ connect(typeid(PrepareDisplayEarlyRequest),
+ [this](sys::Message *request) -> sys::MessagePointer { return handlePrepareEarlyRequest(request); });
}
sys::MessagePointer ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *response)
@@ 51,7 51,7 @@ namespace service::eink
display.powerOn();
- auto msg = std::make_shared<service::gui::EinkReady>(display.getSize());
+ auto msg = std::make_shared<service::gui::EinkInitialized>(display.getSize());
sys::Bus::SendUnicast(msg, service::name::gui, this);
return sys::ReturnCodes::Success;
@@ 139,19 139,19 @@ namespace service::eink
{
display.powerOn();
- const auto isDeepRefresh = refreshMode == ::gui::RefreshModes::GUI_REFRESH_DEEP;
- if (const auto temperature = EinkGetTemperatureInternal(); isDeepRefresh) {
- display.changeWaveform(EinkWaveforms_e::EinkWaveformGC16, temperature);
+ const auto temperature = EinkGetTemperatureInternal();
+ if (refreshMode == ::gui::RefreshModes::GUI_REFRESH_DEEP) {
+ display.setWaveform(EinkWaveforms_e::EinkWaveformGC16, temperature);
display.dither();
}
else {
- display.changeWaveform(EinkWaveforms_e::EinkWaveformDU2, temperature);
+ display.setWaveform(EinkWaveforms_e::EinkWaveformDU2, temperature);
}
}
- sys::MessagePointer ServiceEink::handlePrepareRequest(sys::Message *message)
+ sys::MessagePointer ServiceEink::handlePrepareEarlyRequest(sys::Message *message)
{
- const auto waveformUpdateMsg = static_cast<service::eink::PrepareDisplayRequest *>(message);
+ const auto waveformUpdateMsg = static_cast<service::eink::PrepareDisplayEarlyRequest *>(message);
prepareDisplay(waveformUpdateMsg->getRefreshMode());
return sys::MessageNone{};
}
M module-services/service-eink/ServiceEink.hpp => module-services/service-eink/ServiceEink.hpp +1 -1
@@ 41,7 41,7 @@ namespace service::eink
sys::MessagePointer handleEinkModeChangedMessage(sys::Message *message);
sys::MessagePointer handleImageMessage(sys::Message *message);
- sys::MessagePointer handlePrepareRequest(sys::Message *message);
+ sys::MessagePointer handlePrepareEarlyRequest(sys::Message *message);
EinkDisplay display;
State currentState;
R module-services/service-eink/messages/PrepareDisplayRequest.cpp => module-services/service-eink/messages/PrepareDisplayEarlyRequest.cpp +3 -3
@@ 1,14 1,14 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "PrepareDisplayRequest.hpp"
+#include "PrepareDisplayEarlyRequest.hpp"
namespace service::eink
{
- PrepareDisplayRequest::PrepareDisplayRequest(::gui::RefreshModes refreshMode) : refreshMode{refreshMode}
+ PrepareDisplayEarlyRequest::PrepareDisplayEarlyRequest(::gui::RefreshModes refreshMode) : refreshMode{refreshMode}
{}
- auto PrepareDisplayRequest::getRefreshMode() const noexcept -> ::gui::RefreshModes
+ auto PrepareDisplayEarlyRequest::getRefreshMode() const noexcept -> ::gui::RefreshModes
{
return refreshMode;
}
R module-services/service-eink/messages/PrepareDisplayRequest.hpp => module-services/service-eink/messages/PrepareDisplayEarlyRequest.hpp +2 -2
@@ 9,10 9,10 @@
namespace service::eink
{
- class PrepareDisplayRequest : public EinkMessage
+ class PrepareDisplayEarlyRequest : public EinkMessage
{
public:
- explicit PrepareDisplayRequest(::gui::RefreshModes refreshMode);
+ explicit PrepareDisplayEarlyRequest(::gui::RefreshModes refreshMode);
[[nodiscard]] auto getRefreshMode() const noexcept -> ::gui::RefreshModes;
M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +16 -12
@@ 1,11 1,11 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ServiceGUI.hpp"
#include "WorkerGUI.hpp"
#include "messages/DrawMessage.hpp"
-#include "messages/EinkReady.hpp"
+#include "messages/EinkInitialized.hpp"
#include <DrawCommand.hpp>
#include <FontManager.hpp>
@@ 14,7 14,7 @@
#include <service-eink/Common.hpp>
#include <service-eink/messages/ImageMessage.hpp>
#include <service-eink/messages/EinkMessage.hpp>
-#include <service-eink/messages/PrepareDisplayRequest.hpp>
+#include <service-eink/messages/PrepareDisplayEarlyRequest.hpp>
#include <SystemManager/SystemManager.hpp>
#include <gsl/gsl_util>
@@ 27,7 27,9 @@ namespace service::gui
constexpr auto ServiceGuiStackDepth = 4096U;
constexpr auto ContextsCount = 2;
constexpr auto CommandsQueueCapacity = 3;
- constexpr std::chrono::milliseconds ContextReleaseTimeout{1000};
+ constexpr std::chrono::milliseconds BSPEinkBusyTimeout{3000}; ///< sync with \ref BSP_EinkBusyTimeout
+ constexpr std::chrono::milliseconds RTOSMessageRoundtripTimeout{1000};
+ constexpr std::chrono::milliseconds ContextReleaseTimeout{BSPEinkBusyTimeout + RTOSMessageRoundtripTimeout};
} // namespace
ServiceGUI::ServiceGUI(const std::string &name, std::string parent)
@@ 52,8 54,8 @@ namespace service::gui
void ServiceGUI::registerMessageHandlers()
{
- connect(typeid(EinkReady),
- [this](sys::Message *request) -> sys::MessagePointer { return handleEinkReady(request); });
+ connect(typeid(EinkInitialized),
+ [this](sys::Message *request) -> sys::MessagePointer { return handleEinkInitialized(request); });
connect(typeid(DrawMessage),
[this](sys::Message *request) -> sys::MessagePointer { return handleDrawMessage(request); });
@@ 119,15 121,17 @@ namespace service::gui
setState(State::Suspended);
}
- prepareDisplay(drawMsg->mode);
+ if (!contextPool->isAnyContextLocked()) {
+ prepareDisplayEarly(drawMsg->mode);
+ }
notifyRenderer(std::move(drawMsg->commands), drawMsg->mode);
}
return sys::MessageNone{};
}
- void ServiceGUI::prepareDisplay(::gui::RefreshModes refreshMode)
+ void ServiceGUI::prepareDisplayEarly(::gui::RefreshModes refreshMode)
{
- auto msg = std::make_shared<service::eink::PrepareDisplayRequest>(refreshMode);
+ auto msg = std::make_shared<service::eink::PrepareDisplayEarlyRequest>(refreshMode);
sys::Bus::SendUnicast(msg, service::name::eink, this);
}
@@ 199,9 203,9 @@ namespace service::gui
cachedRender = std::nullopt;
}
- sys::MessagePointer ServiceGUI::handleEinkReady(sys::Message *message)
+ sys::MessagePointer ServiceGUI::handleEinkInitialized(sys::Message *message)
{
- const auto msg = static_cast<service::gui::EinkReady *>(message);
+ const auto msg = static_cast<service::gui::EinkInitialized *>(message);
contextPool = std::make_unique<ContextPool>(msg->getDisplaySize(), ContextsCount);
setState(State::Idle);
return sys::MessageNone{};
@@ 246,4 250,4 @@ namespace service::gui
{
return currentState == state;
}
-} /* namespace sgui */
+} // namespace service::gui
M module-services/service-gui/ServiceGUI.hpp => module-services/service-gui/ServiceGUI.hpp +2 -2
@@ 61,7 61,7 @@ namespace service::gui
void cacheRender(int contextId, ::gui::RefreshModes refreshMode);
void invalidateCache();
- void prepareDisplay(::gui::RefreshModes refreshMode);
+ void prepareDisplayEarly(::gui::RefreshModes refreshMode);
void notifyRenderer(std::list<std::unique_ptr<::gui::DrawCommand>> &&commands, ::gui::RefreshModes refreshMode);
void enqueueDrawCommands(DrawCommandsQueue::QueueItem &&item);
void sendOnDisplay(::gui::Context *context, int contextId, ::gui::RefreshModes refreshMode);
@@ 74,7 74,7 @@ namespace service::gui
sys::MessagePointer handleDrawMessage(sys::Message *message);
sys::MessagePointer handleGUIRenderingFinished(sys::Message *message);
- sys::MessagePointer handleEinkReady(sys::Message *message);
+ sys::MessagePointer handleEinkInitialized(sys::Message *message);
sys::MessagePointer handleImageDisplayedNotification(sys::Message *message);
std::unique_ptr<ContextPool> contextPool;
R module-services/service-gui/messages/EinkReady.hpp => module-services/service-gui/messages/EinkInitialized.hpp +2 -2
@@ 9,10 9,10 @@
namespace service::gui
{
- class EinkReady : public GUIMessage
+ class EinkInitialized : public GUIMessage
{
public:
- explicit EinkReady(::gui::Size displaySize) : einkDisplaySize{displaySize}
+ explicit EinkInitialized(::gui::Size displaySize) : einkDisplaySize{displaySize}
{}
[[nodiscard]] auto getDisplaySize() const noexcept -> ::gui::Size