~aleteoryx/muditaos

2f74db29a6442a9f1b6e78334ea9da72cd0dff2d — Lefucjusz 3 years ago 22819c5
[MOS-608] Fix crash on phone turn off

Fix of the crash that sometimes happened
during system closing.
31 files changed, 333 insertions(+), 457 deletions(-)

M module-bsp/board/linux/light_sensor/light_sensor.cpp
M module-bsp/board/linux/torch/torch.cpp
M module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp
M module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp
M module-bsp/board/rt1051/bsp/headset/headset.cpp
M module-bsp/board/rt1051/bsp/keypad_backlight/keypad_backlight.cpp
M module-bsp/board/rt1051/bsp/light_sensor/light_sensor.cpp
M module-bsp/board/rt1051/bsp/magnetometer/magnetometer.cpp
M module-bsp/board/rt1051/bsp/torch/torch.cpp
M module-bsp/board/rt1051/bsp/vibrator/vibrator.cpp
M module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.cpp
M module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp
M module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.cpp
M module-bsp/board/rt1051/puretx/irq_gpio.cpp
M module-bsp/bsp/eink_frontlight/eink_frontlight.hpp
M module-bsp/bsp/headset/headset.hpp
M module-bsp/bsp/light_sensor/light_sensor.hpp
M module-bsp/bsp/magnetometer/magnetometer.hpp
M module-bsp/bsp/torch/torch.hpp
M module-bsp/bsp/vibrator/vibrator.hpp
M module-services/service-evtmgr/EventManager.cpp
M module-services/service-evtmgr/WorkerEventCommon.cpp
M module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp
M module-services/service-evtmgr/service-evtmgr/WorkerEventCommon.hpp
M products/PurePhone/services/evtmgr/EventManager.cpp
M products/PurePhone/services/evtmgr/WorkerEvent.cpp
M products/PurePhone/services/evtmgr/WorkerEvent.hpp
M products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp
M products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp
M products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp
M pure_changelog.md
M module-bsp/board/linux/light_sensor/light_sensor.cpp => module-bsp/board/linux/light_sensor/light_sensor.cpp +3 -15
@@ 1,25 1,18 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/light_sensor/light_sensor.hpp"

namespace bsp::light_sensor
{
    namespace
    {
        xQueueHandle qHandleIrq = nullptr;
    } // namespace

    std::int32_t init(xQueueHandle qHandle)
    std::int32_t init()
    {
        qHandleIrq = qHandle;
        return 1;
    }

    void deinit()
    {
        qHandleIrq = nullptr;
    }
    {}

    bool standby()
    {


@@ 45,9 38,4 @@ namespace bsp::light_sensor
    {
        return 0.0f;
    }

    BaseType_t IRQHandler()
    {
        return pdFALSE;
    }
} // namespace bsp::light_sensor

M module-bsp/board/linux/torch/torch.cpp => module-bsp/board/linux/torch/torch.cpp +2 -10
@@ 4,28 4,21 @@
#include "bsp/torch/torch.hpp"
#include <log/log.hpp>

static xQueueHandle qHandleIrq = NULL;

namespace bsp
{

    namespace torch
    {
        State state_simulated               = State::off;
        ColourTemperature currentColourTemp = ColourTemperature::warmest;

        int32_t init(xQueueHandle qHandle)
        std::int32_t init()
        {

            qHandleIrq      = qHandle;
            state_simulated = State::off;
            return 1;
        }

        void deinit()
        {
            qHandleIrq = nullptr;
        }
        {}

        bool isPresent(void)
        {


@@ 68,6 61,5 @@ namespace bsp
        {
            return true;
        }

    } // namespace torch
} // namespace bsp

M module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp => module-bsp/board/rt1051/bsp/cellular/rt1051_cellular.cpp +21 -15
@@ 83,7 83,8 @@ namespace bsp
        MSPInit();
        /// to set Store::GSM sim state and to log debug
        Store::GSM::get()->tray =
            GPIO_PinRead(GPIO2, BSP_CELLULAR_SIM_TRAY_INSERTED_PIN) == 0 ? Store::GSM::Tray::IN : Store::GSM::Tray::OUT;
            gpio_2->ReadPin(BSP_CELLULAR_SIM_TRAY_INSERTED_PIN) == 0 ? Store::GSM::Tray::IN : Store::GSM::Tray::OUT;

        DMAInit();

        uartRxBuffer = xMessageBufferCreate(rxMessageBufferLength);


@@ 144,7 145,7 @@ namespace bsp

    RT1051Cellular::~RT1051Cellular()
    {
        if (uartRxBuffer) {
        if (uartRxBuffer != nullptr) {
            vMessageBufferDelete(uartRxBuffer);
            uartRxBuffer = nullptr;
        }


@@ 565,7 566,7 @@ namespace bsp
        LPUART_TransferCreateHandleEDMA(CELLULAR_UART_BASE,
                                        &uartDmaHandle,
                                        uartDMACallback,
                                        NULL,
                                        nullptr,
                                        reinterpret_cast<edma_handle_t *>(txDMAHandle->GetHandle()),
                                        reinterpret_cast<edma_handle_t *>(rxDMAHandle->GetHandle()));
    }


@@ 677,7 678,7 @@ namespace bsp
                                                 DriverGPIOParams{});
                bool state  = gpio_2->ReadPin(magic_enum::enum_integer(BoardDefinitions::CELLULAR_GPIO_2_USB_BOOT_PIN));

                return (state == true ? BootPinState::FIRMWARE_UPGRADE : BootPinState::NORMAL_BOOT);
                return (state ? BootPinState::FIRMWARE_UPGRADE : BootPinState::NORMAL_BOOT);
            }
            PassthroughState getPassthrough()
            {


@@ 685,7 686,7 @@ namespace bsp
                                                 DriverGPIOParams{});
                bool state  = gpio_1->ReadPin(magic_enum::enum_integer(BoardDefinitions::USB_FUNCTION_MUX_SELECT));

                return (state == true ? PassthroughState::ENABLED : PassthroughState::DISABLED);
                return (state ? PassthroughState::ENABLED : PassthroughState::DISABLED);
            }

            // modem needs a reboot to enter DFU (Firmware Upgrade) mode


@@ 722,7 723,7 @@ namespace bsp
            BaseType_t statusIRQhandler()
            {
                BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                if (qhandle != NULL) {
                if (qhandle != nullptr) {
                    std::uint8_t val = static_cast<std::uint8_t>(IRQsource::statusPin);
                    xQueueSendFromISR(qhandle, &val, &xHigherPriorityTaskWoken);
                }


@@ 738,7 739,7 @@ namespace bsp
            {
                BaseType_t xHigherPriorityTaskWoken = pdFALSE;

                if (qhandle) {
                if (qhandle != nullptr) {
                    std::uint8_t val = static_cast<std::uint8_t>(IRQsource::trayPin);
                    xQueueSendFromISR(qhandle, &val, &xHigherPriorityTaskWoken);
                }


@@ 747,23 748,28 @@ namespace bsp

            auto getTray() -> Store::GSM::Tray
            {
                auto state = GPIO_PinRead(GPIO2, BSP_CELLULAR_SIM_TRAY_INSERTED_PIN) == 0 ? Store::GSM::Tray::IN
                                                                                          : Store::GSM::Tray::OUT;
                const auto gpio_2 = DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::CELLULAR_GPIO_2),
                                                       DriverGPIOParams{});
                const auto state  = gpio_2->ReadPin(BSP_CELLULAR_SIM_TRAY_INSERTED_PIN) == 0 ? Store::GSM::Tray::IN
                                                                                             : Store::GSM::Tray::OUT;

                return state;
            }

            void hotSwapTrigger()
            {
                GPIO_PinWrite(BSP_CELLULAR_SIM_CARD_PRESENCE_PORT, BSP_CELLULAR_SIM_CARD_PRESENCE_PIN, 1);
                const auto gpio_2 = DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::CELLULAR_GPIO_2),
                                                       DriverGPIOParams{});
                gpio_2->WritePin(BSP_CELLULAR_SIM_CARD_PRESENCE_PIN, 1);
                vTaskDelay(100); // sleep for 100 ms...
                GPIO_PinWrite(BSP_CELLULAR_SIM_CARD_PRESENCE_PORT, BSP_CELLULAR_SIM_CARD_PRESENCE_PIN, 0);
                gpio_2->WritePin(BSP_CELLULAR_SIM_CARD_PRESENCE_PIN, 0);
            }

            void simSelect()
            {
                GPIO_PinWrite(BSP_CELLULAR_SIM_CARD_PRESENCE_PORT,
                              BSP_CELLULAR_SIMSEL_PIN,
                              static_cast<uint8_t>(Store::GSM::get()->selected));
                const auto gpio_2 = DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::CELLULAR_GPIO_2),
                                                       DriverGPIOParams{});
                gpio_2->WritePin(BSP_CELLULAR_SIMSEL_PIN, static_cast<uint8_t>(Store::GSM::get()->selected));
                LOG_INFO("%s slot selected", magic_enum::enum_name(Store::GSM::get()->selected).data());
            }
        } // namespace sim


@@ 773,7 779,7 @@ namespace bsp
            auto riIRQHandler() -> BaseType_t
            {
                BaseType_t xHigherPriorityTaskWoken = pdFALSE;
                if (qhandle != NULL) {
                if (qhandle != nullptr) {
                    std::uint8_t val = static_cast<std::uint8_t>(IRQsource::ringIndicatorPin);
                    xQueueSendFromISR(qhandle, &val, &xHigherPriorityTaskWoken);
                }

M module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp => module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp +1 -2
@@ 1,10 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/eink_frontlight/eink_frontlight.hpp"
#include "board/BoardDefinitions.hpp"
#include "drivers/pwm/DriverPWM.hpp"
#include "fsl_common.h"
#include <cmath>

namespace bsp::eink_frontlight

M module-bsp/board/rt1051/bsp/headset/headset.cpp => module-bsp/board/rt1051/bsp/headset/headset.cpp +69 -70
@@ 82,66 82,73 @@ namespace bsp
                TypeDontCare
            };

        } // anonymous namespace
            std::shared_ptr<drivers::DriverI2C> i2c;
            std::shared_ptr<drivers::DriverGPIO> gpio;
            drivers::I2CAddress i2cAddr = {.deviceAddress = HEADSET_I2C_ADDR, .subAddress = 0, .subAddressSize = 0x01};
            TimerHandle_t timerHandle;

            xQueueHandle qHandleIrq = nullptr;
            bool HeadsetInserted    = false;
            bool MicrophoneInserted = false;

        static std::shared_ptr<drivers::DriverI2C> i2c;
        static std::shared_ptr<drivers::DriverGPIO> gpio;
        static drivers::I2CAddress i2cAddr = {
            .deviceAddress = HEADSET_I2C_ADDR, .subAddress = 0, .subAddressSize = 0x01};
        static TimerHandle_t timerHandle;
            HeadsetType insertedHeadsetType = HeadsetType::TypeDontCare;

        static xQueueHandle qHandleIrq = nullptr;
        static bool HeadsetInserted    = false;
        static bool MicrophoneInserted = false;
            void readKeyCodeAndEvent(uint8_t &keyEvent, uint8_t &keyCode)
            {
                uint8_t keypress_int = 0;

        static HeadsetType insertedHeadsetType = HeadsetType::TypeDontCare;
                i2cAddr.subAddress = HEADSET_KEY_PRESS_INT_REG;
                i2c->Read(i2cAddr, static_cast<uint8_t *>(&keypress_int), 1);

        static void readKeyCodeAndEvent(uint8_t &keyEvent, uint8_t &keyCode)
        {
            uint8_t keypress_int = 0;

            i2cAddr.subAddress = HEADSET_KEY_PRESS_INT_REG;
            i2c->Read(i2cAddr, static_cast<uint8_t *>(&keypress_int), 1);

            switch (static_cast<HeadsetIQRKeyPressStatus>(keypress_int)) {
            case HeadsetIQRKeyPressStatus::KEY4_RELEASE:
                keyCode  = static_cast<uint8_t>(KeyCode::Key4);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                break;
            case HeadsetIQRKeyPressStatus::KEY4_PRESS:
                keyCode  = static_cast<uint8_t>(KeyCode::Key4);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                break;
            case HeadsetIQRKeyPressStatus::KEY3_RELEASE:
                keyCode  = static_cast<uint8_t>(KeyCode::Key3);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                break;
            case HeadsetIQRKeyPressStatus::KEY3_PRESS:
                keyCode  = static_cast<uint8_t>(KeyCode::Key3);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                break;
            case HeadsetIQRKeyPressStatus::KEY2_RELEASE:
                keyCode  = static_cast<uint8_t>(KeyCode::Key2);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                break;
            case HeadsetIQRKeyPressStatus::KEY2_PRESS:
                keyCode  = static_cast<uint8_t>(KeyCode::Key2);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                break;
            case HeadsetIQRKeyPressStatus::KEY1_RELEASE:
                keyCode  = static_cast<uint8_t>(KeyCode::Key1);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                break;
            case HeadsetIQRKeyPressStatus::KEY1_PRESS:
                keyCode  = static_cast<uint8_t>(KeyCode::Key1);
                keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                break;
            default:
                keyCode  = static_cast<uint8_t>(KeyCode::Error);
                keyEvent = static_cast<uint8_t>(KeyEvent::Error);
                break;
                switch (static_cast<HeadsetIQRKeyPressStatus>(keypress_int)) {
                case HeadsetIQRKeyPressStatus::KEY4_RELEASE:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key4);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                    break;
                case HeadsetIQRKeyPressStatus::KEY4_PRESS:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key4);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                    break;
                case HeadsetIQRKeyPressStatus::KEY3_RELEASE:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key3);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                    break;
                case HeadsetIQRKeyPressStatus::KEY3_PRESS:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key3);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                    break;
                case HeadsetIQRKeyPressStatus::KEY2_RELEASE:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key2);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                    break;
                case HeadsetIQRKeyPressStatus::KEY2_PRESS:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key2);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                    break;
                case HeadsetIQRKeyPressStatus::KEY1_RELEASE:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key1);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyReleased);
                    break;
                case HeadsetIQRKeyPressStatus::KEY1_PRESS:
                    keyCode  = static_cast<uint8_t>(KeyCode::Key1);
                    keyEvent = static_cast<uint8_t>(KeyEvent::KeyPressed);
                    break;
                default:
                    keyCode  = static_cast<uint8_t>(KeyCode::Error);
                    keyEvent = static_cast<uint8_t>(KeyEvent::Error);
                    break;
                }
            }
        }

            void TimerHandler(TimerHandle_t xTimer)
            {
                if (qHandleIrq != nullptr) {
                    uint8_t val = 0x01;
                    xQueueSend(qHandleIrq, &val, 0);
                    xTimerDelete(xTimer, 0);
                }
            }
        } // anonymous namespace

        HeadsetState headset_get_data(bool &headsetState, bool &microphoneState, uint8_t &keyEvent, uint8_t &keyCode)
        {


@@ 159,7 166,7 @@ namespace bsp
            // Check if jack removed event
            if (((acc_status & static_cast<uint8_t>(HeadsetIQRDetectionResult::DETRES_INSERTION_STATUS)) == 0) &&
                HeadsetInserted) {
                HeadsetInserted = false;
                HeadsetInserted    = false;
                MicrophoneInserted = false;

                LOG_INFO("Headset removed");


@@ 183,17 190,17 @@ namespace bsp
                switch (static_cast<HeadsetIQRDetectionResult>(acc_status)) {
                case HeadsetIQRDetectionResult::DETRES_3POLE:
                    LOG_INFO("Headset 3-pole detected");
                    MicrophoneInserted = false;
                    MicrophoneInserted  = false;
                    insertedHeadsetType = HeadsetType::Type3Pole;
                    break;
                case HeadsetIQRDetectionResult::DETRES_OMTP:
                    LOG_INFO("Headset 4-pole OMTP detected");
                    MicrophoneInserted = true;
                    MicrophoneInserted  = true;
                    insertedHeadsetType = HeadsetType::TypeOMTP;
                    break;
                case HeadsetIQRDetectionResult::DETRES_CTIA:
                    LOG_INFO("Headset 4-pole Standard detected");
                    MicrophoneInserted = true;
                    MicrophoneInserted  = true;
                    insertedHeadsetType = HeadsetType::TypeCTIA;
                    break;
                default:


@@ 219,15 226,6 @@ namespace bsp
            return headsetStateChange;
        }

        static void TimerHandler(TimerHandle_t xTimer)
        {
            if (qHandleIrq != nullptr) {
                uint8_t val = 0x01;
                xQueueSend(qHandleIrq, &val, 0);
                xTimerDelete(xTimer, 0);
            }
        }

        BaseType_t headset_IRQHandler()
        {
            BaseType_t xHigherPriorityTaskWoken = pdFALSE;


@@ 324,8 322,8 @@ namespace bsp

        status_t Deinit()
        {
            qHandleIrq      = nullptr;
            HeadsetInserted = false;
            qHandleIrq         = nullptr;
            HeadsetInserted    = false;
            MicrophoneInserted = false;

            uint8_t reg        = HEADSET_DEV_SET_RESET;


@@ 335,6 333,7 @@ namespace bsp

            gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::MIC_BIAS_DRIVER_EN), 0);
            gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::HEADSET_IRQ_PIN));
            gpio.reset();

            return kStatus_Success;
        }

M module-bsp/board/rt1051/bsp/keypad_backlight/keypad_backlight.cpp => module-bsp/board/rt1051/bsp/keypad_backlight/keypad_backlight.cpp +6 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/keypad_backlight/keypad_backlight.hpp"


@@ 26,7 26,7 @@ namespace bsp::keypad_backlight
        std::shared_ptr<drivers::DriverI2C> i2c;

        drivers::I2CAddress addr = {
            .deviceAddress = static_cast<uint32_t>(LP55281_DEVICE_ADDR), .subAddress = 0, .subAddressSize = 1};
            .deviceAddress = static_cast<std::uint32_t>(LP55281_DEVICE_ADDR), .subAddress = 0, .subAddressSize = 1};

        constexpr auto rgbChannelsNum = 3;



@@ 106,6 106,10 @@ namespace bsp::keypad_backlight
    void deinit()
    {
        shutdown();

        /* Explicitly release peripherals */
        i2c.reset();
        gpio.reset();
    }

    bool configureDiodes()

M module-bsp/board/rt1051/bsp/light_sensor/light_sensor.cpp => module-bsp/board/rt1051/bsp/light_sensor/light_sensor.cpp +12 -57
@@ 1,11 1,10 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/light_sensor/light_sensor.hpp"
#include "LTR303ALS.hpp"
#include "board/BoardDefinitions.hpp"
#include "drivers/i2c/DriverI2C.hpp"
#include "drivers/gpio/DriverGPIO.hpp"

#include "fsl_common.h"
#include <log/log.hpp>


@@ 14,12 13,12 @@ namespace bsp::light_sensor
{
    namespace
    {
        std::shared_ptr<drivers::DriverGPIO> gpio;
        constexpr auto measurementRegsSize = 4; // bytes

        std::shared_ptr<drivers::DriverI2C> i2c;
        xQueueHandle qHandleIrq = nullptr;

        drivers::I2CAddress addr = {
            .deviceAddress = static_cast<uint32_t>(LTR303ALS_DEVICE_ADDR), .subAddress = 0, .subAddressSize = 1};
            .deviceAddress = static_cast<std::uint32_t>(LTR303ALS_DEVICE_ADDR), .subAddress = 0, .subAddressSize = 1};

        bool writeSingleRegister(std::uint32_t address, std::uint8_t *to_send)
        {


@@ 38,26 37,7 @@ namespace bsp::light_sensor
        ssize_t readMeasurementRegisters(std::uint8_t *readout)
        {
            addr.subAddress = static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_DATA_CH1_0);
            return i2c->Read(addr, readout, 4);
        }

        constexpr inline std::uint16_t irqLevelUp  = 0xffff;
        constexpr inline std::uint16_t irqLevelLow = 0;

        void configureInterrupts() __attribute__((used));
        void configureInterrupts()
        {
            // Has to be done before sensor active mode
            std::uint8_t reg = ENABLE_IRQ;
            writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::INTERRUPT), &reg);
            reg = irqLevelUp & 0xff;
            writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_THRES_UP_0), &reg);
            reg = irqLevelUp >> 8;
            writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_THRES_UP_1), &reg);
            reg = irqLevelLow & 0xff;
            writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_THRES_LOW_0), &reg);
            reg = irqLevelLow >> 8;
            writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_THRES_LOW_1), &reg);
            return i2c->Read(addr, readout, measurementRegsSize);
        }

        void configureMeasurement()


@@ 68,30 48,15 @@ namespace bsp::light_sensor

    } // namespace

    std::int32_t init(xQueueHandle qHandle)
    std::int32_t init()
    {
        qHandleIrq = qHandle;

        drivers::DriverI2CParams i2cParams;
        drivers::DriverI2CParams i2cParams{};
        i2cParams.baudrate = static_cast<std::uint32_t>(BoardDefinitions::LIGHT_SENSOR_I2C_BAUDRATE);
        i2c = drivers::DriverI2C::Create(static_cast<drivers::I2CInstances>(BoardDefinitions::LIGHT_SENSOR_I2C),
                                         i2cParams);

        gpio = drivers::DriverGPIO::Create(static_cast<drivers::GPIOInstances>(BoardDefinitions::LIGHT_SENSOR_IRQ_GPIO),
                                           drivers::DriverGPIOParams{});

        drivers::DriverGPIOPinParams gpioParams;
        gpioParams.dir     = drivers::DriverGPIOPinParams::Direction::Input;
        gpioParams.irqMode = drivers::DriverGPIOPinParams::InterruptMode::IntFallingEdge;
        gpioParams.pin     = static_cast<uint32_t>(BoardDefinitions::LIGHT_SENSOR_IRQ);
        gpio->ConfPin(gpioParams);
        // Uncomment to enable interrupts
        // gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::LIGHT_SENSOR_IRQ));

        reset();
        configureMeasurement();
        // Uncomment to enable interrupts
        // configureInterrupts();
        wakeup();

        return isPresent() ? kStatus_Success : kStatus_Fail;


@@ 99,13 64,14 @@ namespace bsp::light_sensor

    void deinit()
    {
        qHandleIrq = nullptr;
        reset();
        /* Explicitly release I2C peripheral */
        i2c.reset();
    }

    bool standby()
    {
        uint8_t reg = 0;
        std::uint8_t reg = 0;
        return writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_CONTR), &reg);
    }



@@ 117,14 83,14 @@ namespace bsp::light_sensor

    IlluminanceLux readout()
    {
        uint8_t reg[4];
        std::uint8_t reg[measurementRegsSize];
        readMeasurementRegisters(reg);
        return decodeLightMeasurement(reg);
    }

    bool reset()
    {
        uint8_t reg = SW_RESET;
        std::uint8_t reg = SW_RESET;
        return writeSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::ALS_CONTR), &reg);
    }



@@ 134,15 100,4 @@ namespace bsp::light_sensor
        readSingleRegister(static_cast<std::uint32_t>(LTR303ALS_Registers::MANUFAC_ID), &readout);
        return readout == MANUFACTURER_ID;
    }

    BaseType_t IRQHandler()
    {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        if (qHandleIrq != nullptr) {
            std::uint8_t val = 0x01;
            xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
        }
        return xHigherPriorityTaskWoken;
    }

} // namespace bsp::light_sensor

M module-bsp/board/rt1051/bsp/magnetometer/magnetometer.cpp => module-bsp/board/rt1051/bsp/magnetometer/magnetometer.cpp +88 -118
@@ 16,72 16,68 @@
using namespace drivers;
using namespace utils;

static std::shared_ptr<drivers::DriverI2C> i2c;

static I2CAddress addr = {.deviceAddress = als31300::I2C_ADDRESS, .subAddress = 0, .subAddressSize = 1};

union i2c_buf_t
{
    uint8_t buf[sizeof(als31300::whole_reg_t)];
    als31300::whole_reg_t whole_reg;
};

static i2c_buf_t i2c_buf;

static xQueueHandle qHandleIrq = NULL;

namespace bsp
{
    namespace magnetometer
    {
        enum class LPDCM_INACTIVE_TIME
        {
            inactive_500us,
            inactive_1ms,
            inactive_5ms,
            inactive_10ms,
            inactive_50ms,
            inactive_100ms,
            inactive_500ms,
            inactive_1s
        };

        enum class BANDWIDTH_SELECT
        {
            bandwidth_3500Hz = 0,
            bandwidth_7kHz   = 1,
            bandwidth_14kHz  = 2,
            bandwidth_10kHz  = 4,
            bandwidth_20kHz  = 5,
            bandwidth_40kHz  = 6
        };
        namespace
        {
            bool isTimeToCompleteWriteDefinedForRegistry(std::uint8_t address)
            std::shared_ptr<drivers::DriverI2C> i2c;
            I2CAddress addr = {.deviceAddress = als31300::I2C_ADDRESS, .subAddress = 0, .subAddressSize = 1};

            union i2c_buf_t
            {
                const auto it = std::find(als31300::EEPROM_REGS.begin(), als31300::EEPROM_REGS.end(), address);
                return it != als31300::EEPROM_REGS.end();
            }
        } // namespace
                uint8_t buf[sizeof(als31300::whole_reg_t)];
                als31300::whole_reg_t whole_reg;
            };

        std::shared_ptr<DriverGPIO> gpio;
            i2c_buf_t i2c_buf;

        bsp::KeyCodes current_parsed = bsp::KeyCodes::Undefined;
            xQueueHandle qHandleIrq = nullptr;

        Measurements last{};
            bsp::KeyCodes current_parsed = bsp::KeyCodes::Undefined;

        static TimerHandle_t timerHandle;
        static constexpr uint16_t MAGNETOMETER_POLL_INTERVAL_MS = 500;
            Measurements last{};

        static void TimerHandler(TimerHandle_t xTimer)
        {
            if (qHandleIrq != nullptr) {
                uint8_t val = 0x01;
                xQueueSend(qHandleIrq, &val, 0);
            enum class LPDCM_INACTIVE_TIME
            {
                inactive_500us,
                inactive_1ms,
                inactive_5ms,
                inactive_10ms,
                inactive_50ms,
                inactive_100ms,
                inactive_500ms,
                inactive_1s
            };

            enum class BANDWIDTH_SELECT
            {
                bandwidth_3500Hz = 0,
                bandwidth_7kHz   = 1,
                bandwidth_14kHz  = 2,
                bandwidth_10kHz  = 4,
                bandwidth_20kHz  = 5,
                bandwidth_40kHz  = 6
            };

            bool isTimeToCompleteWriteDefinedForRegistry(std::uint8_t address)
            {
                const auto it = std::find(als31300::EEPROM_REGS.begin(), als31300::EEPROM_REGS.end(), address);
                return it != als31300::EEPROM_REGS.end();
            }
        }

        bool setActive(als31300::PWR_REG_SLEEP_MODE sleep_mode);
            TimerHandle_t timerHandle;
            constexpr uint16_t magnetometerPollIntervalMs = 500;

            void TimerHandler(TimerHandle_t xTimer)
            {
                if (qHandleIrq != nullptr) {
                    uint8_t val = 0x01;
                    xQueueSend(qHandleIrq, &val, 0);
                }
            }
        } // namespace

        bool i2cRead(const uint8_t reg_addr, als31300::whole_reg_t &whole_reg)
        {


@@ 113,6 109,27 @@ namespace bsp
            return wrote;
        }

        bool setActive(als31300::PWR_REG_SLEEP_MODE sleep_mode)
        {
            // POWER register
            als31300::whole_reg_t read_reg;

            if (!i2cRead(als31300::PWR_REG, read_reg)) {
                return false;
            }
            als31300::pwr_reg reg_pwr = read_reg;
            reg_pwr.sleep             = sleep_mode;

            if (!i2cWrite(als31300::PWR_REG, reg_pwr)) {
                return false;
            }
            if (sleep_mode == als31300::PWR_REG_SLEEP_MODE::active ||
                sleep_mode == als31300::PWR_REG_SLEEP_MODE::periodic_active) {
                vTaskDelay(pdMS_TO_TICKS(als31300::PWR_ON_DELAY_MS)); // give it some time to wake up
            }
            return true;
        }

        int32_t init(xQueueHandle qHandle)
        {
            i2c = DriverI2C::Create(


@@ 180,22 197,9 @@ namespace bsp
                LOG_DEBUG("INT is fine, sparing a write");
            }

            // INTERRUPT PIN
            gpio =
                DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::MAGNETOMETER_GPIO), DriverGPIOParams{});

            // INTERRUPT PIN
            gpio->ClearPortInterrupts(1 << static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ));
            gpio->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Input,
                                              .irqMode  = DriverGPIOPinParams::InterruptMode::IntFallingEdge,
                                              .defLogic = 0,
                                              .pin      = static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ)});
            // NOTE: irq not yet enabled
            // this version uses timer to poll the sensor
            // the timer requests to read the magnetometer periodically
            if (timerHandle == nullptr) {
                timerHandle = xTimerCreate(
                    "SliderTimer", pdMS_TO_TICKS(MAGNETOMETER_POLL_INTERVAL_MS), true, nullptr, TimerHandler);
                timerHandle =
                    xTimerCreate("SliderTimer", pdMS_TO_TICKS(magnetometerPollIntervalMs), true, nullptr, TimerHandler);
                if (timerHandle == nullptr) {
                    LOG_ERROR("Could not create the timer for magnetometer state change detection!");
                    return kStatus_Fail;


@@ 221,70 225,52 @@ namespace bsp

        void deinit()
        {
            gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ));
            if (timerHandle != nullptr) {
                xTimerStop(timerHandle, 0);
            }
            /* Explicitly release I2C peripheral */
            i2c.reset();
        }

        std::pair<bool, Measurements> getMeasurement()
        std::optional<Measurements> getMeasurement()
        {
            als31300::whole_reg_t read_reg;

            if (!i2cRead(als31300::MEASUREMENTS_MSB_REG, read_reg)) {
                LOG_DEBUG("magneto: CANNOT READ");
                return std::make_pair(false, Measurements()); // todo: nullopt
                return std::nullopt;
            }
            // is there anything new ?
            als31300::measurements_MSB_reg reg_msb = read_reg;

            if (reg_msb.int_flag == true) {
            if (reg_msb.int_flag) {
                LOG_DEBUG("magneto: INT flag in register");
            }

            if (reg_msb.new_data_flag != als31300::MEAS_REG_NEW_DATA_available) {
                return std::make_pair(false, Measurements());
                return std::nullopt;
            }
            else {
                if (reg_msb.int_flag == true) {
                if (reg_msb.int_flag) {
                    // clear INT flag
                    if (!i2cWrite(als31300::MEASUREMENTS_MSB_REG, reg_msb)) {
                        return std::make_pair(false, Measurements()); // todo: null opt
                        LOG_DEBUG("magneto: cannot clear INT flag in register");
                        return std::nullopt;
                    }
                }
                Measurements meas;
                Measurements meas{};

                i2cRead(als31300::MEASUREMENTS_LSB_REG, read_reg);

                als31300::measurements_LSB_reg reg_lsb = read_reg;

                meas.X = als31300::measurement_sign_convert(reg_msb.X_MSB << 4 | reg_lsb.X_LSB);
                meas.Y = als31300::measurement_sign_convert(reg_msb.Y_MSB << 4 | reg_lsb.Z_LSB);
                meas.Y = als31300::measurement_sign_convert(
                    reg_msb.Y_MSB << 4 | reg_lsb.Z_LSB); // TODO here we merge wrong registers - Y with Z
                meas.Z = als31300::measurement_sign_convert(reg_msb.Z_MSB << 4 | reg_lsb.Z_LSB);

                return std::pair(true, meas);
            }
        }

        bool setActive(als31300::PWR_REG_SLEEP_MODE sleep_mode)
        {
            // POWER register
            als31300::whole_reg_t read_reg;

            if (!i2cRead(als31300::PWR_REG, read_reg)) {
                return false;
            }
            als31300::pwr_reg reg_pwr = read_reg;
            reg_pwr.sleep             = sleep_mode;

            if (!i2cWrite(als31300::PWR_REG, reg_pwr)) {
                return false;
                return meas;
            }
            if (sleep_mode == als31300::PWR_REG_SLEEP_MODE::active ||
                sleep_mode == als31300::PWR_REG_SLEEP_MODE::periodic_active) {
                vTaskDelay(pdMS_TO_TICKS(als31300::PWR_ON_DELAY_MS)); // give it some time to wake up
            }
            return true;
        }

        bool isPresent(void)


@@ 303,7 289,7 @@ namespace bsp
            constexpr auto maxNoiseLevel = 45;
            bool result                  = false;

            // We don't check Z axis, because it isn't logic dependend
            // We don't check Z axis, because it isn't logic dependent
            if ((std::abs(current.X - last.X) > maxNoiseLevel) || (std::abs(current.Y - last.Y) > maxNoiseLevel)) {
                result = true;
            }


@@ 350,10 336,10 @@ namespace bsp
        {
            // try to get new data from active magneto
            setActive(als31300::PWR_REG_SLEEP_MODE::active);
            auto [new_data, measurement] = getMeasurement();
            const auto new_measurement = getMeasurement();
            setActive(als31300::PWR_REG_SLEEP_MODE::sleep);
            if (new_data) {
                auto incoming_parsed = parse(measurement);
            if (new_measurement.has_value()) {
                auto incoming_parsed = parse(new_measurement.value());
                if (incoming_parsed != bsp::KeyCodes::Undefined and incoming_parsed != current_parsed) {
                    current_parsed = incoming_parsed;
                    return current_parsed;


@@ 361,21 347,5 @@ namespace bsp
            }
            return std::nullopt;
        }

        BaseType_t IRQHandler()
        {
            gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ));
            BaseType_t xHigherPriorityTaskWoken = pdFALSE;
            if (qHandleIrq != NULL) {
                uint8_t val = 0x01;
                xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
            }
            return xHigherPriorityTaskWoken;
        }

        void enableIRQ()
        {
            gpio->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ));
        }
    } // namespace magnetometer
} // namespace bsp

M module-bsp/board/rt1051/bsp/torch/torch.cpp => module-bsp/board/rt1051/bsp/torch/torch.cpp +43 -42
@@ 12,63 12,61 @@

using namespace drivers;

static std::shared_ptr<drivers::DriverI2C> i2c;

namespace bsp
{

    namespace torch
    {
        static xQueueHandle qHandleIrq = nullptr;
        static constexpr auto delayMs  = 5;
        namespace
        {
            std::shared_ptr<drivers::DriverI2C> i2c;
            constexpr auto powerStateTransitionDelayMs = 5;

        static I2CAddress addr = {.deviceAddress = 0x63, .subAddress = 0, .subAddressSize = 1};
            I2CAddress addr = {.deviceAddress = 0x63, .subAddress = 0, .subAddressSize = 1};

        std::shared_ptr<DriverGPIO> gpio;
        const unsigned short max_current_mA = 150;
        ColourTemperature currentColourTemp = ColourTemperature::warmest;
            std::shared_ptr<DriverGPIO> gpio;
            constexpr unsigned short max_current_mA = 150;
            ColourTemperature currentColourTemp     = ColourTemperature::warmest;

        void powerOnTorch()
        {
            gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_ENABLE);
        }
            void powerOnTorch()
            {
                gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_ENABLE);
            }

        void powerOffTorch()
        {
            gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_DISABLE);
        }
            void powerOffTorch()
            {
                gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_DISABLE);
            }

        void enablePowerSupply()
        {
            // Make sure torch power is supplied to write or read i2c message and wait a bit
            if (getState() == State::off) {
                powerOnTorch();
                vTaskDelay(pdMS_TO_TICKS(delayMs));
            void enablePowerSupply()
            {
                // Make sure torch power is supplied to write or read i2c message and wait a bit
                if (getState() == State::off) {
                    powerOnTorch();
                    vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));
                }
            }
        }

        bool write(const drivers::I2CAddress &addr, const uint8_t *txBuff, const size_t size)
        {
            enablePowerSupply();
            auto writeBytes = i2c->Write(addr, txBuff, size);
            return writeBytes == size;
        }
            bool write(const drivers::I2CAddress &addr, const uint8_t *txBuff, const size_t size)
            {
                enablePowerSupply();
                auto writeBytes = i2c->Write(addr, txBuff, size);
                return writeBytes == size;
            }

        bool read(const drivers::I2CAddress &addr, uint8_t *rxBuff, const size_t size)
        {
            enablePowerSupply();
            auto readBytes = i2c->Read(addr, rxBuff, size);
            return readBytes == size;
        }
            bool read(const drivers::I2CAddress &addr, uint8_t *rxBuff, const size_t size)
            {
                enablePowerSupply();
                auto readBytes = i2c->Read(addr, rxBuff, size);
                return readBytes == size;
            }
        } // namespace

        int32_t init(xQueueHandle qHandle)
        std::int32_t init()
        {
            i2c = DriverI2C::Create(
                static_cast<I2CInstances>(BoardDefinitions::TORCH_DRIVER_I2C),
                DriverI2CParams{.baudrate = static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_I2C_BAUDRATE)});

            qHandleIrq = qHandle;

            gpio =
                DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::TORCH_DRIVER_GPIO), DriverGPIOParams{});



@@ 78,9 76,9 @@ namespace bsp
                                              .defLogic = 0,
                                              .pin = static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN)});
            powerOffTorch();
            vTaskDelay(pdMS_TO_TICKS(delayMs));
            vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));
            powerOnTorch();
            vTaskDelay(pdMS_TO_TICKS(delayMs));
            vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));

            auto present = isPresent();
            turn(State::off);


@@ 90,8 88,11 @@ namespace bsp

        void deinit()
        {
            qHandleIrq = nullptr;
            turn(State::off);

            /* Explicitly release peripherals */
            i2c.reset();
            gpio.reset();
        }

        bool isPresent(void)

M module-bsp/board/rt1051/bsp/vibrator/vibrator.cpp => module-bsp/board/rt1051/bsp/vibrator/vibrator.cpp +1 -2
@@ 1,10 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/vibrator/vibrator.hpp"

#include "board/BoardDefinitions.hpp"
#include <drivers/gpio/DriverGPIO.hpp>
#include <drivers/pwm/DriverPWM.hpp>

namespace bsp

M module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.cpp => module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.cpp +3 -3
@@ 642,14 642,14 @@ namespace bsp::battery_charger
                drivers::DriverGPIO::Create(static_cast<drivers::GPIOInstances>(BoardDefinitions::BATTERY_CHARGER_GPIO),
                                            drivers::DriverGPIOParams{});

            drivers::DriverGPIOPinParams INTBPinConfig;
            drivers::DriverGPIOPinParams INTBPinConfig{};
            INTBPinConfig.dir      = drivers::DriverGPIOPinParams::Direction::Input;
            INTBPinConfig.irqMode  = drivers::DriverGPIOPinParams::InterruptMode::IntFallingEdge;
            INTBPinConfig.defLogic = 0;
            INTBPinConfig.pin      = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN);
            gpio->ConfPin(INTBPinConfig);

            drivers::DriverGPIOPinParams INOKBPinConfig;
            drivers::DriverGPIOPinParams INOKBPinConfig{};
            INOKBPinConfig.dir      = drivers::DriverGPIOPinParams::Direction::Input;
            INOKBPinConfig.irqMode  = drivers::DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge;
            INOKBPinConfig.defLogic = 0;


@@ 712,7 712,7 @@ namespace bsp::battery_charger

    int init()
    {
        drivers::DriverI2CParams i2cParams;
        drivers::DriverI2CParams i2cParams{};
        i2cParams.baudrate = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_I2C_BAUDRATE);
        i2c = drivers::DriverI2C::Create(static_cast<drivers::I2CInstances>(BoardDefinitions::BATTERY_CHARGER_I2C),
                                         i2cParams);

M module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp => module-bsp/board/rt1051/puretx/bsp/battery_charger/battery_charger.hpp +0 -1
@@ 5,7 5,6 @@

#include "MAX77818.hpp"

#include <cstdint>
#include <optional>
#include <fstream>
#include <Units.hpp>

M module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.cpp => module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.cpp +6 -9
@@ 12,9 12,7 @@
#include <board.h>
#include <log/log.hpp>

#include <stdio.h>
#include <stdint.h>
#include <assert.h>
#include <cstdint>

namespace bsp::keyboard
{


@@ 137,8 135,8 @@ namespace bsp::keyboard
    {
        std::uint32_t reg = 0;
        /* Assemble a mask for row and column registers */
        reg = ~(std::uint32_t(~0) << TCA8418_ROWS_COUNT);
        reg += (~(std::uint32_t(~0) << TCA8418_COL_COUNT)) << 8;
        reg = ~(static_cast<std::uint32_t>(~0) << TCA8418_ROWS_COUNT);
        reg |= (~(static_cast<std::uint32_t>(~0) << TCA8418_COL_COUNT)) << 8;

        /* Set registers to keypad mode */
        i2cAddr.subAddress = REG_KP_GPIO1;


@@ 185,7 183,6 @@ namespace bsp::keyboard

    std::int32_t init(xQueueHandle qHandle)
    {

        i2c = DriverI2C::Create(
            static_cast<I2CInstances>(BoardDefinitions::KEYBOARD_I2C),
            DriverI2CParams{.baudrate = static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_I2C_BAUDRATE)});


@@ 273,7 270,7 @@ namespace bsp::keyboard
                // key release/pressed is stored on the last bit
                rel_pres = (retval & eventTypeRegisterMask) >> 7;

                KeyEvent keyEvent;
                KeyEvent keyEvent{};
                keyEvent.code  = static_cast<KeyCodes>(key);
                keyEvent.event = static_cast<KeyEvents>(rel_pres);
                out.push_back(keyEvent);


@@ 283,14 280,14 @@ namespace bsp::keyboard
        }

        if (notification & static_cast<std::uint8_t>(NotificationSource::rightFnPress)) {
            KeyEvent keyEvent;
            KeyEvent keyEvent{};
            keyEvent.code  = KeyCodes::FnRight;
            keyEvent.event = KeyEvents::Pressed;
            out.push_back(keyEvent);
        }

        if (notification & static_cast<std::uint8_t>(NotificationSource::rightFnRelease)) {
            KeyEvent keyEvent;
            KeyEvent keyEvent{};
            keyEvent.code  = KeyCodes::FnRight;
            keyEvent.event = KeyEvents::Released;
            out.push_back(keyEvent);

M module-bsp/board/rt1051/puretx/irq_gpio.cpp => module-bsp/board/rt1051/puretx/irq_gpio.cpp +0 -11
@@ 79,13 79,6 @@ namespace bsp
            BaseType_t xHigherPriorityTaskWoken = 0;
            uint32_t irq_mask                   = GPIO_GetPinsInterruptFlags(GPIO1);

            if (irq_mask & (1 << static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ))) {
                xHigherPriorityTaskWoken |= bsp::magnetometer::IRQHandler();
                LOG_DEBUG("magneto IRQ! >%s<",
                          GPIO_PinRead(GPIO1, static_cast<uint32_t>(BoardDefinitions::MAGNETOMETER_IRQ)) ? "high"
                                                                                                         : "low");
            }

            if (irq_mask & (1 << BSP_BLUETOOTH_UART_CTS_PIN)) {
                LOG_DEBUG("CTS IRQ!");
            }


@@ 120,10 113,6 @@ namespace bsp
                xHigherPriorityTaskWoken |= bsp::cellular::sim::trayIRQHandler();
            }

            if (irq_mask & (1 << static_cast<uint32_t>(BoardDefinitions::LIGHT_SENSOR_IRQ))) {
                xHigherPriorityTaskWoken |= bsp::light_sensor::IRQHandler();
            }

            // Clear all IRQs
            GPIO_PortClearInterruptFlags(GPIO2, irq_mask);


M module-bsp/bsp/eink_frontlight/eink_frontlight.hpp => module-bsp/bsp/eink_frontlight/eink_frontlight.hpp +0 -2
@@ 3,9 3,7 @@

#pragma once

#include <cstdint>
#include "bsp/common.hpp"
#include <utility>

namespace bsp::eink_frontlight
{

M module-bsp/bsp/headset/headset.hpp => module-bsp/bsp/headset/headset.hpp +30 -29
@@ 7,33 7,34 @@
#include "queue.h"
#include "headset_key_codes.hpp"

namespace bsp {
 namespace headset {

    /**
     * @brief This method is responsible for initializing the headset controller.
     * @param qHandle key code
     */
    int32_t Init(xQueueHandle qHandle);

    /**
     * @brief This method is responsible for reading state of headset and its keys.
     * @param headsetState headset event (1 - connected, 0 - removed)
     * @param microphoneState headset event (1 - present, 0 - absent)
     * @param keyEvent key event (1 - pressed, 0 - released)
     * @param keyCode key code
     * @note Method returns `HeadsetState::Changed` if state of headset changed (connected -> removed)
     */
    HeadsetState headset_get_data(bool &headsetState, bool &microphoneState, uint8_t &keyEvent, uint8_t &keyCode);

    bool IsInserted();

    /**
     * @brief This method is responsible for deinitializing the headset controller.
     * @param qHandle key code
     */
    int32_t Deinit();

    BaseType_t headset_IRQHandler();
 }
namespace bsp
{
    namespace headset
    {
        /**
         * @brief This method is responsible for initializing the headset controller.
         * @param qHandle key code
         */
        int32_t Init(xQueueHandle qHandle);

        /**
         * @brief This method is responsible for reading state of headset and its keys.
         * @param headsetState headset event (1 - connected, 0 - removed)
         * @param microphoneState headset event (1 - present, 0 - absent)
         * @param keyEvent key event (1 - pressed, 0 - released)
         * @param keyCode key code
         * @note Method returns `HeadsetState::Changed` if state of headset changed (connected -> removed)
         */
        HeadsetState headset_get_data(bool &headsetState, bool &microphoneState, uint8_t &keyEvent, uint8_t &keyCode);

        bool IsInserted();

        /**
         * @brief This method is responsible for deinitializing the headset controller.
         * @param qHandle key code
         */
        int32_t Deinit();

        BaseType_t headset_IRQHandler();
    }
}

M module-bsp/bsp/light_sensor/light_sensor.hpp => module-bsp/bsp/light_sensor/light_sensor.hpp +1 -3
@@ 16,7 16,7 @@ namespace bsp::light_sensor
{
    using IlluminanceLux = float;

    std::int32_t init(xQueueHandle qHandle);
    std::int32_t init();

    void deinit();



@@ 29,6 29,4 @@ namespace bsp::light_sensor
    bool isPresent();

    IlluminanceLux readout();

    BaseType_t IRQHandler();
} // namespace bsp::light_sensor

M module-bsp/bsp/magnetometer/magnetometer.hpp => module-bsp/bsp/magnetometer/magnetometer.hpp +2 -8
@@ 16,10 16,8 @@ extern "C"

namespace bsp
{

    namespace magnetometer
    {

        int32_t init(xQueueHandle qHandle);
        void deinit();



@@ 33,15 31,11 @@ namespace bsp
            int16_t Z;
        };

        /// returns a pair of <new_data_read?, values>
        std::pair<bool, Measurements> getMeasurement();
        /// returns new data readout if it is available
        std::optional<Measurements> getMeasurement();

        bsp::KeyCodes parse(const Measurements &measurements);
        std::optional<bsp::KeyCodes> WorkerEventHandler();
        void resetCurrentParsedValue();

        BaseType_t IRQHandler();
        void enableIRQ();
    } // namespace magnetometer

} // namespace bsp

M module-bsp/bsp/torch/torch.hpp => module-bsp/bsp/torch/torch.hpp +1 -2
@@ 10,7 10,6 @@ extern "C"
}

#include "bsp/common.hpp"
#include <utility>

namespace bsp::torch
{


@@ 27,7 26,7 @@ namespace bsp::torch
        coldest = 6500,
    };

    int32_t init(xQueueHandle qHandle);
    std::int32_t init();
    void deinit();

    bool isPresent(void);

M module-bsp/bsp/vibrator/vibrator.hpp => module-bsp/bsp/vibrator/vibrator.hpp +0 -3
@@ 1,10 1,7 @@
#pragma once

#include <Utils.hpp>
#include <bsp/common.hpp>

#include <chrono>
#include <memory>

namespace bsp
{

M module-services/service-evtmgr/EventManager.cpp => module-services/service-evtmgr/EventManager.cpp +1 -1
@@ 222,8 222,8 @@ sys::ReturnCodes EventManagerCommon::DeinitHandler()

void EventManagerCommon::ProcessCloseReasonHandler(sys::CloseReason closeReason)
{
    EventWorker->deinitProductHardware();
    ProcessCloseReason(closeReason);
    EventWorker->deinitProductHardware();
    sendCloseReadyMessage(this);
}


M module-services/service-evtmgr/WorkerEventCommon.cpp => module-services/service-evtmgr/WorkerEventCommon.cpp +2 -3
@@ 18,15 18,14 @@
#include <SystemManager/SystemManagerCommon.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>

#include "FreeRTOS.h"
#include "projdefs.h"
#include "queue.h"
#include "task.h"

#include <sys/types.h>
#include <memory>
#include <optional>

#include <log/log.hpp>

WorkerEventCommon::WorkerEventCommon(sys::Service *service)
    : sys::Worker(service, stackDepthBytes),
      service(service), keyInput{hal::key_input::AbstractKeyInput::Factory::create()}

M module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp => module-services/service-evtmgr/service-evtmgr/EventManagerCommon.hpp +1 -1
@@ 49,7 49,7 @@ class EventManagerCommon : public sys::Service
    static bool messageSetApplication(sys::Service *sender, const std::string &applicationName);

  private:
    static constexpr auto stackDepth = 4096;
    static constexpr auto stackDepth = 1024 * 4;
    void handleMinuteUpdate(time_t timestamp);

    void processRTCFromTmRequest(struct tm &newTime);

M module-services/service-evtmgr/service-evtmgr/WorkerEventCommon.hpp => module-services/service-evtmgr/service-evtmgr/WorkerEventCommon.hpp +1 -3
@@ 49,7 49,7 @@ class WorkerEventCommon : public sys::Worker
    sys::Service *service = nullptr;

  private:
    static constexpr auto stackDepthBytes = 3072;
    static constexpr auto stackDepthBytes = 1024 * 4;

    static constexpr auto keyboardQueueName = "qIrq";
    static constexpr auto batteryQueueName  = "qBatteryCtrl";


@@ 57,7 57,6 @@ class WorkerEventCommon : public sys::Worker

    static constexpr auto keyboardQueueSize = 10;
    static constexpr auto batteryQueueSize  = 10;
    static constexpr auto chargerQueueSize  = 5;
    static constexpr auto rtcQueueSize      = 20;

    /**


@@ 75,7 74,6 @@ class WorkerEventCommon : public sys::Worker
     * @brief list of keys with long press enabled. First item is key code, second is long press time.
     */
    std::map<uint32_t, uint32_t> longPressParamsList;
    bool longPressTaskEnabled = false;
    bsp::KeyEvents lastState  = bsp::KeyEvents::Released;
    bsp::KeyCodes lastPressed = static_cast<bsp::KeyCodes>(0);
    std::shared_ptr<sys::CpuSentinel> cpuSentinel;

M products/PurePhone/services/evtmgr/EventManager.cpp => products/PurePhone/services/evtmgr/EventManager.cpp +4 -2
@@ 128,8 128,10 @@ void EventManager::toggleTorchColor()
    }
}

void EventManager::ProcessCloseReason(sys::CloseReason closeReason)
{}
void EventManager::ProcessCloseReason([[maybe_unused]] sys::CloseReason closeReason)
{
    backlightHandler.turnOffScreenLight();
}

sys::MessagePointer EventManager::DataReceivedHandler(sys::DataMessage *msgl, sys::ResponseMessage *resp)
{

M products/PurePhone/services/evtmgr/WorkerEvent.cpp => products/PurePhone/services/evtmgr/WorkerEvent.cpp +24 -33
@@ 26,17 26,15 @@ void WorkerEvent::addProductQueues(std::list<sys::WorkerQueueInfo> &queuesList)
    queuesList.emplace_back(simNotifyQueueName, elementSize, simNotifyQueueSize);
    queuesList.emplace_back(magnetometerQueueName, elementSize, magnetometerQueueSize);
    queuesList.emplace_back(magnetometerNotifyQueueName, elementSize, magnetometerNotifyQueueSize);
    queuesList.emplace_back(torchQueueName, elementSize, torchQueueSize);
    queuesList.emplace_back(lightSensorQueueName, elementSize, lightSensorQueueSize);
}

void WorkerEvent::initProductHardware()
{
    bsp::headset::Init(queues[static_cast<int32_t>(EventQueues::queueHeadsetIRQ)]->GetQueueHandle());
    bsp::cellular::init(queues[static_cast<int32_t>(EventQueues::queueCellular)]->GetQueueHandle());
    bsp::magnetometer::init(queues[static_cast<int32_t>(EventQueues::queueMagnetometerIRQ)]->GetQueueHandle());
    bsp::torch::init(queues[static_cast<int32_t>(EventQueues::queueTorch)]->GetQueueHandle());
    bsp::light_sensor::init(queues[static_cast<int32_t>(EventQueues::queueLightSensor)]->GetQueueHandle());
    bsp::cellular::init(queues[static_cast<std::int32_t>(EventQueues::queueCellular)]->GetQueueHandle());
    bsp::headset::Init(queues[static_cast<std::int32_t>(EventQueues::queueHeadsetIRQ)]->GetQueueHandle());
    bsp::magnetometer::init(queues[static_cast<std::int32_t>(EventQueues::queueMagnetometerIRQ)]->GetQueueHandle());
    bsp::torch::init();
    bsp::light_sensor::init();
    bsp::keypad_backlight::init();
    bsp::eink_frontlight::init();
    bsp::vibrator::init();


@@ 46,13 44,13 @@ bool WorkerEvent::handleMessage(std::uint32_t queueID)
{
    auto &queue = queues[queueID];

    if (queueID == static_cast<uint32_t>(EventQueues::queueHeadsetIRQ)) {
        uint8_t notification;
    if (queueID == static_cast<std::uint32_t>(EventQueues::queueHeadsetIRQ)) {
        std::uint8_t notification;
        if (!queue->Dequeue(&notification, 0)) {
            return false;
        }
        bool headsetState, microphoneState;
        uint8_t headsetKeyEvent, headsetKeyCode;
        std::uint8_t headsetKeyEvent, headsetKeyCode;

        if (bsp::headset::headset_get_data(headsetState, microphoneState, headsetKeyEvent, headsetKeyCode) ==
            bsp::headset::HeadsetState::Changed) {


@@ 72,8 70,8 @@ bool WorkerEvent::handleMessage(std::uint32_t queueID)
        }
    }

    if (queueID == static_cast<uint32_t>(EventQueues::queueCellular)) {
        uint8_t notification;
    if (queueID == static_cast<std::uint32_t>(EventQueues::queueCellular)) {
        std::uint8_t notification;
        if (!queue->Dequeue(&notification, 0)) {
            return false;
        }


@@ 100,8 98,8 @@ bool WorkerEvent::handleMessage(std::uint32_t queueID)
        }
    }

    if (queueID == static_cast<uint32_t>(EventQueues::queueMagnetometerNotify)) {
        uint8_t notification;
    if (queueID == static_cast<std::uint32_t>(EventQueues::queueMagnetometerNotify)) {
        std::uint8_t notification;
        if (!queue->Dequeue(&notification, 0)) {
            return false;
        }


@@ 111,8 109,8 @@ bool WorkerEvent::handleMessage(std::uint32_t queueID)
        handleMagnetometerEvent();
    }

    if (queueID == static_cast<uint32_t>(EventQueues::queueMagnetometerIRQ)) {
        uint8_t notification;
    if (queueID == static_cast<std::uint32_t>(EventQueues::queueMagnetometerIRQ)) {
        std::uint8_t notification;
        if (!queue->Dequeue(&notification, 0)) {
            return false;
        }


@@ 120,31 118,24 @@ bool WorkerEvent::handleMessage(std::uint32_t queueID)
        handleMagnetometerEvent();
    }

    if (queueID == static_cast<uint32_t>(EventQueues::queueLightSensor)) {
        uint8_t notification;
        if (!queue->Dequeue(&notification, 0)) {
            return false;
        }
        LOG_DEBUG("Light sensor IRQ");
    }

    return WorkerEventCommon::handleMessage(queueID);
}

void WorkerEvent::deinitProductHardware()
{
    bsp::headset::Deinit();
    bsp::torch::deinit();
    bsp::keypad_backlight::deinit();
    /* Deinitialize in reverse order */
    bsp::vibrator::deinit();
    bsp::eink_frontlight::deinit();
    bsp::keypad_backlight::deinit();
    bsp::light_sensor::deinit();
    bsp::vibrator::deinit();
    bsp::torch::deinit();
    bsp::magnetometer::deinit();
    bsp::headset::Deinit();
}

void WorkerEvent::requestSliderPositionRead()
{
    uint8_t request = 1;
    std::uint8_t request = 1;
    if (auto queue = getQueueByName(WorkerEvent::magnetometerNotifyQueueName); !queue->Overwrite(&request)) {
        LOG_ERROR("Unable to overwrite the request.");
    }


@@ 158,16 149,16 @@ void WorkerEvent::handleMagnetometerEvent()
    }
}

bsp::KeyCodes WorkerEvent::headsetKeyToKeyboardKey(uint8_t headsetKeyCode)
bsp::KeyCodes WorkerEvent::headsetKeyToKeyboardKey(std::uint8_t headsetKeyCode)
{
    switch (headsetKeyCode) {
    case static_cast<uint8_t>(bsp::headset::KeyCode::Key1):
    case static_cast<std::uint8_t>(bsp::headset::KeyCode::Key1):
        return bsp::KeyCodes::HeadsetOk;

    case static_cast<uint8_t>(bsp::headset::KeyCode::Key3):
    case static_cast<std::uint8_t>(bsp::headset::KeyCode::Key3):
        return bsp::KeyCodes::HeadsetVolUp;

    case static_cast<uint8_t>(bsp::headset::KeyCode::Key4):
    case static_cast<std::uint8_t>(bsp::headset::KeyCode::Key4):
        return bsp::KeyCodes::HeadsetVolDown;
    }
    return bsp::KeyCodes::Undefined;

M products/PurePhone/services/evtmgr/WorkerEvent.hpp => products/PurePhone/services/evtmgr/WorkerEvent.hpp +0 -6
@@ 20,15 20,11 @@ namespace purephone
        static constexpr auto simNotifyQueueName          = "qSIM";
        static constexpr auto magnetometerQueueName       = "qMagnetometer";
        static constexpr auto magnetometerNotifyQueueName = "qMagnetometerNotify";
        static constexpr auto torchQueueName              = "qTorch";
        static constexpr auto lightSensorQueueName        = "qLightSensor";

        static constexpr auto headsetQueueSize            = 10;
        static constexpr auto simNotifyQueueSize          = 5;
        static constexpr auto magnetometerQueueSize       = 5;
        static constexpr auto magnetometerNotifyQueueSize = 1;
        static constexpr auto torchQueueSize              = 5;
        static constexpr auto lightSensorQueueSize        = 5;

        void addProductQueues(std::list<sys::WorkerQueueInfo> &queuesList) final;
        void initProductHardware() final;


@@ 48,8 44,6 @@ namespace purephone
            queueCellular,
            queueMagnetometerIRQ,
            queueMagnetometerNotify,
            queueTorch,
            queueLightSensor,
        };
    };
} // namespace purephone

M products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp => products/PurePhone/services/evtmgr/backlight-handler/BacklightHandler.cpp +6 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <evtmgr/BacklightHandler.hpp>


@@ 85,6 85,11 @@ namespace backlight
        });
    }

    void Handler::turnOffScreenLight()
    {
        screenLightController->processRequest(screen_light_control::Action::turnOff);
    }

    void Handler::handleKeyPressed(bsp::KeyCodes key)
    {
        if (!isKeyOnExclusionList(key)) {

M products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp => products/PurePhone/services/evtmgr/include/evtmgr/BacklightHandler.hpp +2 -1
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 24,6 24,7 @@ namespace backlight
        Handler(std::shared_ptr<settings::Settings> settings, sys::Service *parent);

        void init() override;
        void turnOffScreenLight();
        void handleKeyPressed(bsp::KeyCodes key = bsp::KeyCodes::Undefined);
        /// Process request of the keypad light control
        /// @keypad_backlight::action an action to perform

M products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp => products/PurePhone/services/evtmgr/screen-light-control/ScreenLightControl.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "ScreenLightControl.hpp"


@@ 177,8 177,8 @@ namespace pure::screen_light_control
    {
        bsp::eink_frontlight::turnOff();
        stashedReadout = bsp::light_sensor::readout();
        bsp::light_sensor::standby();
        disableTimers();
        bsp::light_sensor::standby();
        lightOn = false;
        fadeOut = false;
    }

M pure_changelog.md => pure_changelog.md +1 -0
@@ 7,6 7,7 @@
* Separated system volume from Bluetooth device volume for A2DP

### Fixed
* Fixed crash during phone turn off
* Fixed improper duration of the rejected outgoing call shown in calls log
* Fixed Bluetooth volume control issues
* Fixed turning on loudspeaker before outgoing call is answered