~aleteoryx/muditaos

0422d48f463d06f3f5d4a6a7713e208ac056d321 — Adam 5 years ago 64db7d8
EGD-4178 EINK inverted mode (#915)

* EGD-4178 Added simplistic eink invert mode option
M changelog.md => changelog.md +1 -0
@@ 15,6 15,7 @@
### Changed

* `[appmgr]` Application manager refactored.
* `[GUI]` added dark mode switch

### Fixed


M module-apps/application-settings/ApplicationSettings.cpp => module-apps/application-settings/ApplicationSettings.cpp +5 -0
@@ 4,6 4,7 @@
#include "Application.hpp"

#include "MessageType.hpp"
#include "application-settings/windows/EinkModeWindow.hpp"
#include "windows/BtScanWindow.hpp"
#include "windows/BtWindow.hpp"
#include "windows/DateTimeWindow.hpp"


@@ 148,6 149,10 @@ namespace app
            return std::make_unique<gui::FotaWindow>(app);
        });

        windowsFactory.attach(gui::window::name::eink, [](Application *app, const std::string &name) {
            return std::make_unique<gui::EinkModeWindow>(app);
        });

        if (board == bsp::Board::T4) {
            windowsFactory.attach(gui::window::cellular_passthrough::window_name,
                                  [](Application *app, const std::string &name) {

M module-apps/application-settings/CMakeLists.txt => module-apps/application-settings/CMakeLists.txt +2 -1
@@ 28,7 28,8 @@ target_sources( ${PROJECT_NAME}
        windows/FotaWindow.cpp
        windows/Fota.cpp
        windows/SettingsChange.cpp
		windows/USSDWindow.cpp
        windows/USSDWindow.cpp
        windows/EinkModeWindow.cpp

    PUBLIC
        ApplicationSettings.hpp

A module-apps/application-settings/windows/EinkModeWindow.cpp => module-apps/application-settings/windows/EinkModeWindow.cpp +50 -0
@@ 0,0 1,50 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <memory>
#include <functional>

#include "messages/EinkModeMessage.hpp"
#include "service-appmgr/Controller.hpp"

#include "../ApplicationSettings.hpp"

#include "i18/i18.hpp"

#include "Label.hpp"
#include "Margins.hpp"
#include "EinkModeWindow.hpp"
#include <Style.hpp>

namespace gui
{

    EinkModeWindow::EinkModeWindow(app::Application *app) : AppWindow(app, window::name::eink)
    {
        AppWindow::buildInterface();
        bottomBar->setActive(BottomBar::Side::CENTER, true);
        bottomBar->setActive(BottomBar::Side::RIGHT, true);
        bottomBar->setText(BottomBar::Side::CENTER, utils::localize.get(style::strings::common::select));
        bottomBar->setText(BottomBar::Side::RIGHT, utils::localize.get(style::strings::common::back));
        topBar->setActive(TopBar::Elements::SIGNAL, true);
        topBar->setActive(TopBar::Elements::BATTERY, true);

        setTitle("Change eink mode");
        auto label               = new Label(this, 100, 200, 300, 50, "Change mode on click");
        label->activatedCallback = [this](Item &) -> bool {
            static auto last_mode = seink::EinkModeMessage::Mode::Normal;
            if (last_mode == seink::EinkModeMessage::Mode::Normal) {
                last_mode = seink::EinkModeMessage::Mode::Invert;
            }
            else {
                last_mode = seink::EinkModeMessage::Mode::Normal;
            }

            sys::Bus::SendUnicast(
                std::make_shared<seink::EinkModeMessage>(last_mode), "ServiceEink", this->application, 5000);
            return true;
        };
        setFocusItem(label);
    }

} /* namespace gui */

A module-apps/application-settings/windows/EinkModeWindow.hpp => module-apps/application-settings/windows/EinkModeWindow.hpp +27 -0
@@ 0,0 1,27 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#pragma once

#include <string>
#include <functional>

#include "AppWindow.hpp"
#include "gui/widgets/Label.hpp"
#include "gui/widgets/Image.hpp"
#include "gui/widgets/Window.hpp"
#include "gui/widgets/BottomBar.hpp"
#include "gui/widgets/TopBar.hpp"

namespace gui
{
    namespace window::name
    {
        inline const std::string eink = "EinkModeWindow";
    } // namespace window::name

    class EinkModeWindow : public AppWindow
    {
      public:
        explicit EinkModeWindow(app::Application *app);
    };
} /* namespace gui */

M module-apps/application-settings/windows/SettingsMainWindow.cpp => module-apps/application-settings/windows/SettingsMainWindow.cpp +2 -0
@@ 9,6 9,7 @@
#include "CellularPassthroughWindow.hpp"
#include "FotaWindow.hpp"
#include "USSDWindow.hpp"
#include "EinkModeWindow.hpp"

std::list<gui::Option> mainWindowOptions(app::Application *app)
{


@@ 40,6 41,7 @@ std::list<gui::Option> mainWindowOptions(app::Application *app)
    }
    addMenu(i18("Fota update"), gui::window::name::fota_window);
    addMenu(i18("USSD test"), gui::window::name::ussd_window);
    addMenu("Eink Mode", gui::window::name::eink);
    addMenu(i18("app_settings_display"));
    addMenu(i18("app_settings_phone_modes"));
    addMenu(i18("app_settings_security"));

M module-services/service-eink/ServiceEink.cpp => module-services/service-eink/ServiceEink.cpp +18 -11
@@ 2,6 2,8 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ServiceEink.hpp"
#include "messages/EinkModeMessage.hpp"
#include <time/ScopedTime.hpp>

#include <log/log.hpp>
#include <messages/EinkMessage.hpp>


@@ 26,14 28,22 @@ enum class EinkWorkerCommands
};

ServiceEink::ServiceEink(const std::string &name, std::string parent)
    : sys::Service(name, parent, 4096 + 1024), timerID{0}, selfRefereshTriggerCount{0},
      temperatureMeasurementTriggerCount{0}, powerOffTriggerCount{0},
      powerOffTimer("PwrOffTimer", this, 3000, sys::Timer::Type::SingleShot)
    : sys::Service(name, parent, 4096 + 1024), selfRefereshTriggerCount{0}, temperatureMeasurementTriggerCount{0},
      powerOffTriggerCount{0}, powerOffTimer("PwrOffTimer", this, 3000, sys::Timer::Type::SingleShot)
{
    // initialize initial eink parameters
    memset(&waveformSettings, 0, sizeof(EinkWaveFormSettings_t));
    waveformSettings.mode        = EinkWaveformGC16;
    waveformSettings.temperature = -1000;

    connect(typeid(seink::EinkModeMessage),
            [this](sys::DataMessage *message, sys::ResponseMessage *) -> sys::Message_t {
                auto msg          = static_cast<seink::EinkModeMessage *>(message);
                this->displayMode = msg->getMode() == seink::EinkModeMessage::Mode::Normal
                                        ? EinkDisplayColorMode_e::EinkDisplayColorModeStandard
                                        : EinkDisplayColorMode_e::EinkDisplayColorModeInverted;
                return sys::Message_t();
            });
}

ServiceEink::~ServiceEink()


@@ 73,9 83,7 @@ sys::Message_t ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::Res
        sys::Bus::SendUnicast(msg, this->GetName(), this);
    } break;
    case MessageType::EinkDMATransfer: {

        //			LOG_INFO("[%s] EinkDMATransfer", GetName().c_str());
        //			uint32_t start_tick = xTaskGetTickCount();
        utils::time::Scoped scopedtimming("EinkDMATransfer");

        if (suspended) {
            if (suspendInProgress) {


@@ 101,7 109,7 @@ sys::Message_t ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::Res
                changeWaveform(EinkWaveforms_e::EinkWaveformDU2, temperature);
            }

            ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
            ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
            if (ret != EinkOK)
                LOG_FATAL("Failed to update frame");



@@ 116,7 124,6 @@ sys::Message_t ServiceEink::DataReceivedHandler(sys::DataMessage *msgl, sys::Res

            if (ret != EinkOK)
                LOG_FATAL("Failed to refresh frame");
            //			uint32_t end_tick = xTaskGetTickCount();

            powerOffTimer.reload();



@@ 359,7 366,7 @@ bool ServiceEink::deepClearScreen(int8_t temperature)

    EinkStatus_e ret;
    memset(einkRenderBuffer, 15, 480 * 600);
    ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
    ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
    if (ret != EinkOK)
        LOG_FATAL("Failed to update frame");
    ret = EinkRefreshImage(0, 0, 480, 600, EinkDisplayTimingsFastRefreshMode);


@@ 368,7 375,7 @@ bool ServiceEink::deepClearScreen(int8_t temperature)

    for (uint32_t i = 0; i < 2; i++) {
        memset(einkRenderBuffer, 0, 480 * 600);
        ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
        ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
        if (ret != EinkOK)
            LOG_FATAL("Failed to update frame");
        ret = EinkRefreshImage(0, 0, 480, 600, EinkDisplayTimingsFastRefreshMode);


@@ 376,7 383,7 @@ bool ServiceEink::deepClearScreen(int8_t temperature)
            LOG_FATAL("Failed to refresh frame");

        memset(einkRenderBuffer, 15, 480 * 600);
        ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, EinkDisplayColorModeStandard);
        ret = EinkUpdateFrame(0, 0, 480, 600, einkRenderBuffer, Eink4Bpp, displayMode);
        if (ret != EinkOK)
            LOG_FATAL("Failed to update frame");
        ret = EinkRefreshImage(0, 0, 480, 600, EinkDisplayTimingsFastRefreshMode);

M module-services/service-eink/ServiceEink.hpp => module-services/service-eink/ServiceEink.hpp +2 -3
@@ 15,9 15,6 @@
class ServiceEink : public sys::Service
{
  protected:
    // this is timer that triggers 3 handlers - self refresh, temperature measurement and power off
    uint32_t timerID = 0;

    // counts timer triggers from last self refresh
    uint32_t selfRefereshTriggerCount;
    // counts timer events from last temperature measurement


@@ 35,6 32,8 @@ class ServiceEink : public sys::Service
    // structure with recently loaded waveformdata
    EinkWaveFormSettings_t waveformSettings;

    EinkDisplayColorMode_e displayMode = EinkDisplayColorMode_e::EinkDisplayColorModeStandard;

    bool suspended = false;

    bool suspendInProgress  = false;

M module-services/service-eink/messages/EinkMessage.hpp => module-services/service-eink/messages/EinkMessage.hpp +0 -4
@@ 9,14 9,10 @@
namespace seink
{

    /*
     * @brief Template for all messages that go to gui service
     */
    class EinkMessage : public sys::DataMessage
    {
      public:
        EinkMessage(MessageType messageType) : sys::DataMessage(messageType){};
        virtual ~EinkMessage(){};
    };

} /* namespace seink */

A module-services/service-eink/messages/EinkModeMessage.hpp => module-services/service-eink/messages/EinkModeMessage.hpp +29 -0
@@ 0,0 1,29 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "EinkMessage.hpp"

namespace seink
{
    class EinkModeMessage : public EinkMessage
    {
      public:
        enum class Mode
        {
            Normal,
            Invert
        };
        EinkModeMessage(Mode mode) : EinkMessage(MessageType::EinkMessage), mode(mode)
        {}

        [[nodiscard]] auto getMode() const noexcept
        {
            return mode;
        }

      private:
        Mode mode = Mode::Normal;
    };
} // namespace seink

M source/MessageType.hpp => source/MessageType.hpp +1 -0
@@ 9,6 9,7 @@ enum class MessageType

    MessageTypeUninitialized = 0,
    // eink messages
    EinkMessage,
    EinkStateRequest,      ///< message is used to pull status of the eink. If eink is ready to display image
    EinkImageData,         ///< message with pointer to the image data for displaying
    EinkDMATransfer,       ///< this message is internally sent from wink service to eink service. This will trigger DMA