~aleteoryx/muditaos

8b3ae7b48c0f5935a07fc6d23b1ada067f4d6d6f — Lefucjusz 2 years ago 4c1118b
[BH-1857] Fix improper PWM module clock frequency computation

* Fix of the issue that source clock for PWM
module was improperly assumed to be derived
from AHB_CLK, while in reality it is
derived from IPG_CLK, what resulted in
module generating signal with 4 times
lower frequency than the configured
one.
* Cleanups.
M harmony_changelog.md => harmony_changelog.md +1 -0
@@ 3,6 3,7 @@
## Unreleased

### Fixed
* Fixed source clock frequency computation for PWM module

### Added


M module-bsp/board/linux/eink_frontlight/eink_frontlight.cpp => module-bsp/board/linux/eink_frontlight/eink_frontlight.cpp +4 -5
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, 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"


@@ 11,7 11,7 @@ namespace bsp::eink_frontlight
    void deinit()
    {}

    void setBrightness(BrightnessPercentage)
    void setBrightness([[maybe_unused]] BrightnessPercentage brightness)
    {}

    void turnOn()


@@ 20,10 20,9 @@ namespace bsp::eink_frontlight
    void turnOff()
    {}

    void setGammaFactor(float)
    void setGammaFactor([[maybe_unused]] float gamma)
    {}

    void updateClockFrequency(CpuFrequencyMHz newFrequency)
    void updateClockFrequency()
    {}

} // namespace bsp::eink_frontlight

M module-bsp/board/linux/torch/torch.cpp => module-bsp/board/linux/torch/torch.cpp +48 -48
@@ 1,65 1,65 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/torch/torch.hpp"
#include <log/log.hpp>

namespace bsp
namespace bsp::torch
{
    namespace torch
    namespace
    {
        State state_simulated               = State::off;
        ColourTemperature currentColourTemp = ColourTemperature::warmest;
        State simulatedState                = State::Off;
        ColourTemperature currentColourTemp = ColourTemperature::Warmest;
    } // namespace

        std::int32_t init()
        {
            state_simulated = State::off;
            return 1;
        }

        void deinit()
        {}
    std::int32_t init()
    {
        simulatedState = State::Off;
        return 1;
    }

        bool isPresent(void)
        {
            return true;
        }
    void deinit()
    {}

        bool turn(State state, ColourTemperature colourTemp)
        {
            state_simulated = state;
            if (colourTemp != ColourTemperature::noChange) {
                currentColourTemp = colourTemp;
            }
    bool isPresent()
    {
        return true;
    }

            if (state == State::on) {
                LOG_INFO("Torch is ON \U0001f526 (%s)",
                         currentColourTemp == ColourTemperature::warmest ? "warm \U0001f987" : "cold \U0001f535");
            }
            else {
                LOG_INFO("Torch is OFF");
            }
            return true;
    bool turn(State state, ColourTemperature colourTemp)
    {
        simulatedState = state;
        if (colourTemp != ColourTemperature::NoChange) {
            currentColourTemp = colourTemp;
        }

        State getState()
        {
            return state_simulated;
        if (state == State::On) {
            LOG_INFO("Torch is ON \U0001f526 (%s)",
                     currentColourTemp == ColourTemperature::Warmest ? "warm \U0001f987" : "cold \U0001f535");
        }

        ColourTemperature getColorTemp()
        {
            return currentColourTemp;
        else {
            LOG_INFO("Torch is OFF");
        }
        return true;
    }

        bool toggle()
        {
            return turn(getState() == State::off ? State::on : State::off);
        };
    State getState()
    {
        return simulatedState;
    }

        bool setCurrent(const unsigned short mA)
        {
            return true;
        }
    } // namespace torch
} // namespace bsp
    ColourTemperature getColorTemp()
    {
        return currentColourTemp;
    }

    bool toggle()
    {
        return turn(getState() == State::Off ? State::On : State::Off);
    };

    bool setCurrent(const unsigned short mA)
    {
        return true;
    }
} // namespace bsp::torch

M module-bsp/board/linux/vibrator/vibrator.cpp => module-bsp/board/linux/vibrator/vibrator.cpp +22 -21
@@ 1,29 1,30 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "bsp/vibrator/vibrator.hpp"
#include <log/log.hpp>

namespace bsp
namespace bsp::vibrator
{
    namespace vibrator
    void enable()
    {
        LOG_DEBUG("Vibration starts\t\U0001f7e2\U0001f4f3");
    }

        void enable()
        {
            LOG_DEBUG("Vibration starts\t\U0001f7e2\U0001f4f3");
        }
        void disable()
        {
            LOG_DEBUG("Vibration ends  \t\U0001f6d1\U0001f4f3");
        }
        void init(std::chrono::milliseconds pulse)
        {}
        void deinit()
        {}
        void updateClockFrequency(CpuFrequencyMHz newFrequency)
        {}
        void setVibrationLevel(unsigned int vibrationLevel)
        {}
    } // namespace vibrator
} // namespace bsp
    void disable()
    {
        LOG_DEBUG("Vibration ends  \t\U0001f6d1\U0001f4f3");
    }

    void init([[maybe_unused]] std::chrono::milliseconds pulse)
    {}

    void deinit()
    {}

    void updateClockFrequency()
    {}

    void setVibrationLevel([[maybe_unused]] unsigned vibrationLevel)
    {}
} // namespace bsp::vibrator

M module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp => module-bsp/board/rt1051/bsp/eink_frontlight/eink_frontlight.cpp +7 -11
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, 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"


@@ 11,23 11,20 @@ namespace bsp::eink_frontlight
    namespace
    {
        std::shared_ptr<drivers::DriverPWM> pwm;
        constexpr inline auto PWM_FREQUENCY_HZ = 20000;
        float gammaFactor                      = 2.5f;
        constexpr auto pwmOutputFrequencyHz = 5000;
        constexpr auto pwmChannel = static_cast<drivers::PWMChannel>(BoardDefinitions::EINK_FRONTLIGHT_PWM_CHANNEL);
        auto gammaFactor          = 2.5f;

        std::uint8_t gammaCorrection(BrightnessPercentage brightness)
        {
            std::clamp(brightness, 0.0f, 100.0f);
            return static_cast<std::uint8_t>(100 * std::pow((brightness / 100.0f), gammaFactor));
        }
        constexpr auto pwmChannel = static_cast<drivers::PWMChannel>(BoardDefinitions::EINK_FRONTLIGHT_PWM_CHANNEL);

    } // namespace

    void init()
    {
        drivers::DriverPWMParams pwmParams;
        pwmParams.channel   = pwmChannel;
        pwmParams.frequency = PWM_FREQUENCY_HZ;
        const drivers::DriverPWMParams pwmParams{.channel = pwmChannel, .outputFrequency = pwmOutputFrequencyHz};

        pwm = drivers::DriverPWM::Create(
            static_cast<drivers::PWMInstances>(BoardDefinitions::EINK_FRONTLIGHT_PWM_INSTANCE),


@@ 62,9 59,8 @@ namespace bsp::eink_frontlight
        gammaFactor = gamma;
    }

    void updateClockFrequency(CpuFrequencyMHz newFrequency)
    void updateClockFrequency()
    {
        pwm->UpdateClockFrequency(newFrequency);
        pwm->UpdateClockFrequency();
    }

} // namespace bsp::eink_frontlight

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

#include "bsp/torch/torch.hpp"


@@ 12,169 12,165 @@

using namespace drivers;

namespace bsp
namespace bsp::torch
{
    namespace torch
    namespace
    {
        namespace
        {
            std::shared_ptr<drivers::DriverI2C> i2c;
            constexpr auto powerStateTransitionDelayMs = 5;

            I2CAddress addr = {.deviceAddress = 0x63, .subAddress = 0, .subAddressSize = 1};
        std::shared_ptr<drivers::DriverI2C> i2c;
        constexpr auto powerStateTransitionDelayMs = 5;

            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);
            }
        I2CAddress addr = {.deviceAddress = 0x63, .subAddress = 0, .subAddressSize = 1};

            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(powerStateTransitionDelayMs));
                }
            }
        std::shared_ptr<DriverGPIO> gpio;
        constexpr unsigned short max_current_mA = 150;
        ColourTemperature currentColourTemp     = ColourTemperature::Warmest;

            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;
            }
        } // namespace

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

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

            // OUTPUT
            gpio->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Output,
                                              .irqMode  = DriverGPIOPinParams::InterruptMode::NoIntmode,
                                              .defLogic = 0,
                                              .pin = static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN)});
            powerOffTorch();
            vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));
            powerOnTorch();
            vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));

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

            return present ? kStatus_Success : kStatus_Fail;
            gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_ENABLE);
        }

        void deinit()
        void powerOffTorch()
        {
            turn(State::off);

            /* Explicitly release peripherals */
            i2c.reset();
            gpio.reset();
            gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN), AL3644TT_DISABLE);
        }

        bool isPresent(void)
        void enablePowerSupply()
        {
            al3644tt_device_id_reg id;
            addr.subAddress = AL3644TT_DEVICE_ID_REG;
            auto status     = read(addr, reinterpret_cast<std::uint8_t *>(&id), sizeof(al3644tt_device_id_reg));

            if (!status) {
                return false;
            }

            if (id.device_id == AL3644TT_ID && (id.silicon_rev == AL3644TT_REV_1 || id.silicon_rev == AL3644TT_REV_2)) {
                return true;
            // 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));
            }
            LOG_WARN("Something is present at the torch LED driver address (0x%lx), but not the AL3644TT",
                     addr.deviceAddress);
            return false;
        }

        bool setCurrent(const unsigned short mA)
        bool write(const drivers::I2CAddress &addr, const uint8_t *txBuff, const size_t size)
        {
            // set the same current for both channels
            addr.subAddress = AL3644TT_LED1_TORCH_BRIGHTNESS_REG;
            al3644tt_led1_torch_brightness_reg led1_brightness{
                .brightness_code          = al3644tt_current_convert(mA > max_current_mA ? max_current_mA : mA),
                .led2_brightness_override = AL3644TT_LED1_TORCH_BRIGHTNESS_OVERRIDE,
            };
            return write(
                addr, reinterpret_cast<std::uint8_t *>(&led1_brightness), sizeof(al3644tt_led1_torch_brightness_reg));
            enablePowerSupply();
            auto writeBytes = i2c->Write(addr, txBuff, size);
            return writeBytes == size;
        }

        bool turn(State state, ColourTemperature colourTemp)
        bool read(const drivers::I2CAddress &addr, uint8_t *rxBuff, const size_t size)
        {
            if (state == State::on) {
                powerOnTorch();
                setCurrent(max_current_mA);
            }
            enablePowerSupply();
            auto readBytes = i2c->Read(addr, rxBuff, size);
            return readBytes == size;
        }
    } // namespace

            if (colourTemp != ColourTemperature::noChange) {
                currentColourTemp = colourTemp;
            }
    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)});

            addr.subAddress = AL3644TT_ENABLE_REG;
            al3644tt_enable_reg en_reg{
                .led1_en = static_cast<std::uint8_t>(
                    currentColourTemp == ColourTemperature::warmest && state == State::on ? AL3644TT_LED_ENABLED
                                                                                          : AL3644TT_LED_DISABLED),
                .led2_en = static_cast<std::uint8_t>(
                    currentColourTemp == ColourTemperature::coldest && state == State::on ? AL3644TT_LED_ENABLED
                                                                                          : AL3644TT_LED_DISABLED),
                .mode          = 0b10,
                .torch_temp_en = 0,
                .strobe_en     = 0,
                .strobe_type   = 0,
                .tx_pin_en     = 0,
            };

            auto status = write(addr, reinterpret_cast<std::uint8_t *>(&en_reg), sizeof(al3644tt_enable_reg));

            if (state == State::off) {
                powerOffTorch();
            }
        gpio = DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::TORCH_DRIVER_GPIO), DriverGPIOParams{});

        // OUTPUT
        gpio->ConfPin(DriverGPIOPinParams{.dir      = DriverGPIOPinParams::Direction::Output,
                                          .irqMode  = DriverGPIOPinParams::InterruptMode::NoIntmode,
                                          .defLogic = 0,
                                          .pin      = static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN)});
        powerOffTorch();
        vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));
        powerOnTorch();
        vTaskDelay(pdMS_TO_TICKS(powerStateTransitionDelayMs));

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

        return present ? kStatus_Success : kStatus_Fail;
    }

    void deinit()
    {
        turn(State::Off);

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

            return status;
    bool isPresent()
    {
        al3644tt_device_id_reg id;
        addr.subAddress = AL3644TT_DEVICE_ID_REG;
        auto status     = read(addr, reinterpret_cast<std::uint8_t *>(&id), sizeof(al3644tt_device_id_reg));

        if (!status) {
            return false;
        }

        State getState()
        {
            auto read = gpio->ReadPin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN));
            return read ? State::on : State::off;
        if (id.device_id == AL3644TT_ID && (id.silicon_rev == AL3644TT_REV_1 || id.silicon_rev == AL3644TT_REV_2)) {
            return true;
        }
        LOG_WARN("Something is present at the torch LED driver address (0x%lx), but not the AL3644TT",
                 addr.deviceAddress);
        return false;
    }

        ColourTemperature getColorTemp()
        {
            return currentColourTemp;
    bool setCurrent(const unsigned short mA)
    {
        // set the same current for both channels
        addr.subAddress = AL3644TT_LED1_TORCH_BRIGHTNESS_REG;
        al3644tt_led1_torch_brightness_reg led1_brightness{
            .brightness_code          = al3644tt_current_convert(mA > max_current_mA ? max_current_mA : mA),
            .led2_brightness_override = AL3644TT_LED1_TORCH_BRIGHTNESS_OVERRIDE,
        };
        return write(
            addr, reinterpret_cast<std::uint8_t *>(&led1_brightness), sizeof(al3644tt_led1_torch_brightness_reg));
    }

    bool turn(State state, ColourTemperature colourTemp)
    {
        if (state == State::On) {
            powerOnTorch();
            setCurrent(max_current_mA);
        }

        bool toggle()
        {
            auto state = getState();
            return turn(state == State::off ? State::on : State::off);
        if (colourTemp != ColourTemperature::NoChange) {
            currentColourTemp = colourTemp;
        }
    } // namespace torch
} // namespace bsp

        addr.subAddress = AL3644TT_ENABLE_REG;
        al3644tt_enable_reg en_reg{
            .led1_en = static_cast<std::uint8_t>(currentColourTemp == ColourTemperature::Warmest && state == State::On
                                                     ? AL3644TT_LED_ENABLED
                                                     : AL3644TT_LED_DISABLED),
            .led2_en = static_cast<std::uint8_t>(currentColourTemp == ColourTemperature::Coldest && state == State::On
                                                     ? AL3644TT_LED_ENABLED
                                                     : AL3644TT_LED_DISABLED),
            .mode    = 0b10,
            .torch_temp_en = 0,
            .strobe_en     = 0,
            .strobe_type   = 0,
            .tx_pin_en     = 0,
        };

        auto status = write(addr, reinterpret_cast<std::uint8_t *>(&en_reg), sizeof(al3644tt_enable_reg));

        if (state == State::Off) {
            powerOffTorch();
        }

        return status;
    }

    State getState()
    {
        auto read = gpio->ReadPin(static_cast<std::uint32_t>(BoardDefinitions::TORCH_DRIVER_EN));
        return read ? State::On : State::Off;
    }

    ColourTemperature getColorTemp()
    {
        return currentColourTemp;
    }

    bool toggle()
    {
        auto state = getState();
        return turn(state == State::Off ? State::On : State::Off);
    }
} // namespace bsp::torch

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

#include "bsp/vibrator/vibrator.hpp"


@@ 6,57 6,57 @@
#include "board/BoardDefinitions.hpp"
#include <drivers/pwm/DriverPWM.hpp>

namespace bsp
namespace bsp::vibrator
{
    namespace vibrator
    {
        using namespace drivers;
    using namespace drivers;

    namespace
    {
        std::shared_ptr<drivers::DriverPWM> pwm;
        constexpr inline auto PWM_FREQUENCY_HZ = 20000;
        constexpr inline auto levelMultiplier  = 10;

        constexpr auto pwmOutputFrequencyHz = 5000;
        constexpr auto levelMultiplier      = 10;
        constexpr auto pwmChannel = static_cast<drivers::PWMChannel>(BoardDefinitions::VIBRATOR_PWM_CHANNEL);
    } // namespace

        void init(std::chrono::milliseconds pulse)
        {
            drivers::DriverPWMParams pwmParams;
            pwmParams.channel   = pwmChannel;
            pwmParams.frequency = PWM_FREQUENCY_HZ;

            pwm =
                drivers::DriverPWM::Create(static_cast<drivers::PWMInstances>(BoardDefinitions::VIBRATOR_PWM_INSTANCE),
                                           static_cast<drivers::PWMModules>(BoardDefinitions::VIBRATOR_PWM_MODULE),
                                           pwmParams);
            disable();
        }
    void init(std::chrono::milliseconds pulse)
    {
        drivers::DriverPWMParams pwmParams;
        pwmParams.channel         = pwmChannel;
        pwmParams.outputFrequency = pwmOutputFrequencyHz;

        void deinit()
        {
            disable();
        }
        pwm = drivers::DriverPWM::Create(static_cast<drivers::PWMInstances>(BoardDefinitions::VIBRATOR_PWM_INSTANCE),
                                         static_cast<drivers::PWMModules>(BoardDefinitions::VIBRATOR_PWM_MODULE),
                                         pwmParams);
        disable();
    }

        void enable()
        {
            pwm->Start(pwmChannel);
        }
    void deinit()
    {
        disable();
    }

        void disable()
        {
            pwm->Stop(pwmChannel);
        }
    void enable()
    {
        pwm->Start(pwmChannel);
    }

        void updateClockFrequency(CpuFrequencyMHz newFrequency)
        {
            if (pwm) {
                pwm->UpdateClockFrequency(newFrequency);
            }
    void disable()
    {
        pwm->Stop(pwmChannel);
    }

    void updateClockFrequency()
    {
        if (pwm) {
            pwm->UpdateClockFrequency();
        }
    }

        void setVibrationLevel(unsigned int vibrationLevel)
        {
            if (pwm) {
                pwm->SetDutyCycle(vibrationLevel * levelMultiplier, pwmChannel);
            }
    void setVibrationLevel(unsigned vibrationLevel)
    {
        if (pwm) {
            pwm->SetDutyCycle(vibrationLevel * levelMultiplier, pwmChannel);
        }
    } // namespace vibrator
} // namespace bsp
    }
} // namespace bsp::vibrator

M module-bsp/board/rt1051/drivers/RT1051DriverPWM.cpp => module-bsp/board/rt1051/drivers/RT1051DriverPWM.cpp +67 -54
@@ 1,24 1,31 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "RT1051DriverPWM.hpp"
#include "RT1051DriverPWMhelper.hpp"
#include <log/log.hpp>
#include <magic_enum.hpp>
#include <algorithm>

namespace drivers
{
    namespace
    {
        constexpr pwm_mode_t pwmMode = kPWM_SignedCenterAligned;
        constexpr auto pwmMode = kPWM_SignedCenterAligned;

        inline bool isPwmGeneratorEnabled(PWM_Type *base, std::uint8_t pwmModuleToCheck)
        {
            return ((base->MCTRL & PWM_MCTRL_RUN(pwmModuleToCheck)) != 0);
        }

        inline std::uint32_t getCurrentPwmSourceFrequency()
        {
            return CLOCK_GetFreq(kCLOCK_IpgClk);
        }
    }

    RT1051DriverPWM::RT1051DriverPWM(PWMInstances inst, PWMModules mod, const DriverPWMParams &params)
        : DriverPWM(inst, mod, params)
    {

        pwm_config_t pwmConfig = {};

        switch (instance) {
        case PWMInstances::PWM_1:
            base = PWM1;


@@ 61,7 68,12 @@ namespace drivers
            break;
        }

        /* Set PWM clock to IPG_CLK / 2 -> 500kHz@4MHz AHB to 66MHz@528MHz AHB */
        pwm_config_t pwmConfig{};
        PWM_GetDefaultConfig(&pwmConfig);
        pwmConfig.clockSource = kPWM_BusClock; // Use IPG_CLK to clock PWM module
        pwmConfig.prescale    = kPWM_Prescale_Divide_2;

        PWM_Init(base, pwmModule, &pwmConfig);

        SetupPWMChannel(parameters.channel);


@@ 83,10 95,10 @@ namespace drivers

    void RT1051DriverPWM::SetDutyCycle(std::uint8_t dutyCyclePercent, PWMChannel channel)
    {
        std::uint8_t dutyCycle =
        const auto dutyCycle =
            std::clamp(dutyCyclePercent, static_cast<std::uint8_t>(0), static_cast<std::uint8_t>(100));
        const auto pwmChannel = getChannelMask(channel);

        auto pwmChannel = getChannelMask(channel);
        for (unsigned i = 0; i < enabledChannels.size(); ++i) {
            if (pwmSignalsConfig[i].pwmChannel == pwmChannel) {
                pwmSignalsConfig[i].dutyCyclePercent = dutyCycle;


@@ 101,14 113,14 @@ namespace drivers
    {
        pwmChannelState[channel] = RT1051DriverPWM::PwmState::On;
        RestorePwmOutput(channel);
        if (not otherChannelRunning(channel)) {
        if (!otherChannelRunning(channel)) {
            PWM_StartTimer(base, 1 << pwmModule);
        }
    }

    void RT1051DriverPWM::Stop(PWMChannel channel)
    {
        if (not otherChannelRunning(channel)) {
        if (!otherChannelRunning(channel)) {
            PWM_StopTimer(base, 1 << pwmModule);
        }
        ForceLowOutput(channel);


@@ 117,72 129,74 @@ namespace drivers

    RT1051DriverPWM::PwmState RT1051DriverPWM::GetPwmState()
    {
        if (PWM_GetPwmGeneratorState(base, 1 << pwmModule)) {
        if (isPwmGeneratorEnabled(base, 1 << pwmModule)) {
            return PwmState::On;
        }
        else {
            return PwmState::Off;
        }
        return PwmState::Off;
    }

    void RT1051DriverPWM::SetupPWMChannel(PWMChannel channel)
    {
        if (channelNotEnabled(channel)) {
            auto currentInstance = enabledChannels.size();
            auto pwmChannel      = getChannelMask(channel);
        if (channelEnabled(channel)) {
            return;
        }

            pwmSignalsConfig[currentInstance].pwmChannel       = pwmChannel;
            pwmSignalsConfig[currentInstance].dutyCyclePercent = 0;
            pwmSignalsConfig[currentInstance].level            = kPWM_HighTrue;
            pwmSignalsConfig[currentInstance].deadtimeValue    = 0;
            pwmSignalsConfig[currentInstance].faultState       = kPWM_PwmFaultState0;
        const auto currentInstance = enabledChannels.size();
        const auto pwmChannel      = getChannelMask(channel);

            clockFrequency = DEFAULT_SYSTEM_CLOCK;
            SetupPWMInstance(&pwmSignalsConfig[currentInstance], 1, clockFrequency);
        pwmSignalsConfig[currentInstance].pwmChannel       = pwmChannel;
        pwmSignalsConfig[currentInstance].dutyCyclePercent = 0;
        pwmSignalsConfig[currentInstance].level            = kPWM_HighTrue;
        pwmSignalsConfig[currentInstance].deadtimeValue    = 0;
        pwmSignalsConfig[currentInstance].faultState       = kPWM_PwmFaultState0;

            PWM_SetupFaultDisableMap(base, pwmModule, pwmChannel, kPWM_faultchannel_0, 0);
        pwmModuleClockFrequency = getCurrentPwmSourceFrequency();
        SetupPWMInstance(&pwmSignalsConfig[currentInstance], 1, pwmModuleClockFrequency);

            // Force logic config
            PWM_SetupSwCtrlOut(base, pwmModule, pwmChannel, false);
            base->SM[pwmModule].CTRL2 |= PWM_CTRL2_FRCEN(1U);
        PWM_SetupFaultDisableMap(base, pwmModule, pwmChannel, kPWM_faultchannel_0, 0);

            enabledChannels.push_back(channel);
        }
        // Force logic config
        PWM_SetupSwCtrlOut(base, pwmModule, pwmChannel, false);
        base->SM[pwmModule].CTRL2 |= PWM_CTRL2_FRCEN_MASK;

        enabledChannels.push_back(channel);
    }

    void RT1051DriverPWM::SetupPWMInstance(pwm_signal_param_t *config,
                                           unsigned numOfChannels,
                                           std::uint32_t _clockFrequency)
                                           std::uint32_t moduleClockFrequency)
    {
        PWM_SetupPwm(base, pwmModule, config, numOfChannels, pwmMode, parameters.frequency, _clockFrequency);
        PWM_SetupPwm(base, pwmModule, config, numOfChannels, pwmMode, parameters.outputFrequency, moduleClockFrequency);
    }

    void RT1051DriverPWM::ForceLowOutput(PWMChannel channel)
    {
        PWM_SetupForceSignal(base, pwmModule, getChannelMask(channel), kPWM_SoftwareControl);
        base->SM[pwmModule].CTRL2 |= PWM_CTRL2_FORCE(1U);
        base->SM[pwmModule].CTRL2 |= PWM_CTRL2_FORCE_MASK;
    }

    void RT1051DriverPWM::RestorePwmOutput(PWMChannel channel)
    {
        PWM_SetupForceSignal(base, pwmModule, getChannelMask(channel), kPWM_UsePwm);
        base->SM[pwmModule].CTRL2 |= PWM_CTRL2_FORCE(1U);
        base->SM[pwmModule].CTRL2 |= PWM_CTRL2_FORCE_MASK;
    }

    void RT1051DriverPWM::UpdateClockFrequency(bsp::CpuFrequencyMHz newFrequency)
    void RT1051DriverPWM::UpdateClockFrequency()
    {
        cpp_freertos::LockGuard lock(frequencyChangeMutex);
        const auto convertedFrequency = static_cast<std::uint32_t>(newFrequency) * bsp::HzPerMHz;

        if (clockFrequency != convertedFrequency) {
            SetupPWMInstance(pwmSignalsConfig.data(), enabledChannels.size(), convertedFrequency);
            if (GetPwmState() == PwmState::On) {
                stopAll();
                restoreDutyCycle();
                startAll();
            }
            clockFrequency = convertedFrequency;

        const auto newSourceFrequency = getCurrentPwmSourceFrequency();
        if (pwmModuleClockFrequency == newSourceFrequency) {
            return;
        }

        SetupPWMInstance(pwmSignalsConfig.data(), enabledChannels.size(), newSourceFrequency);
        if (GetPwmState() == PwmState::On) {
            stopAll();
            restoreDutyCycle();
            startAll();
        }
        pwmModuleClockFrequency = newSourceFrequency;
    }

    pwm_channels_t RT1051DriverPWM::getChannelMask(PWMChannel channel)


@@ 195,25 209,25 @@ namespace drivers
        case PWMChannel::X:
            return kPWM_PwmX;
        }
        LOG_FATAL("No mask for given PWM channel!");
        LOG_ERROR("No mask for given PWM channel!");
        return kPWM_PwmB;
    }

    bool RT1051DriverPWM::channelNotEnabled(PWMChannel channel)
    bool RT1051DriverPWM::channelEnabled(PWMChannel channel)
    {
        for (const auto &chan : enabledChannels) {
            if (chan == channel || chan == PWMChannel::X) {
                LOG_FATAL("PWM Channel already enabled!");
                return false;
            if ((chan == channel) || (chan == PWMChannel::X)) {
                LOG_WARN("PWM channel %s already enabled!", magic_enum::enum_name(chan).data());
                return true;
            }
        }
        return true;
        return false;
    }

    bool RT1051DriverPWM::otherChannelRunning(PWMChannel channel)
    {
        for (const auto &[otherChannel, state] : pwmChannelState) {
            if (channel != otherChannel && state == RT1051DriverPWM::PwmState::On) {
            if ((channel != otherChannel) && (state == RT1051DriverPWM::PwmState::On)) {
                return true;
            }
        }


@@ 242,11 256,10 @@ namespace drivers

    void RT1051DriverPWM::restoreDutyCycle()
    {
        for (unsigned i = 0; i < enabledChannels.size(); ++i) {
        for (auto i = 0; i < enabledChannels.size(); ++i) {
            PWM_UpdatePwmDutycycle(
                base, pwmModule, pwmSignalsConfig[i].pwmChannel, pwmMode, pwmSignalsConfig[i].dutyCyclePercent);
            PWM_SetPwmLdok(base, 1 << pwmModule, true);
        }
    }

} // namespace drivers

M module-bsp/board/rt1051/drivers/RT1051DriverPWM.hpp => module-bsp/board/rt1051/drivers/RT1051DriverPWM.hpp +13 -14
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 13,29 13,30 @@
#include <vector>
#include <map>
#include <array>

namespace drivers
{
    class RT1051DriverPWM : public DriverPWM
    class RT1051DriverPWM final : public DriverPWM
    {
      public:
        RT1051DriverPWM(PWMInstances inst, PWMModules mod, const DriverPWMParams &params);

        ~RT1051DriverPWM() final;
        ~RT1051DriverPWM();

        void InitNextChannel(const DriverPWMParams &params) final;
        void InitNextChannel(const DriverPWMParams &params);

        void SetDutyCycle(std::uint8_t dutyCyclePercent, PWMChannel channel) final;
        void SetDutyCycle(std::uint8_t dutyCyclePercent, PWMChannel channel);

        void Start(PWMChannel channel) final;
        void Start(PWMChannel channel);

        void Stop(PWMChannel channel) final;
        void Stop(PWMChannel channel);

        void UpdateClockFrequency(bsp::CpuFrequencyMHz newFrequency) final;
        void UpdateClockFrequency();

        enum class PwmState
        {
            Off,
            On,
            On
        };

      private:


@@ 43,7 44,7 @@ namespace drivers

        void SetupPWMChannel(PWMChannel channel);

        void SetupPWMInstance(pwm_signal_param_t *config, unsigned numOfChannels, std::uint32_t clockFrequency);
        void SetupPWMInstance(pwm_signal_param_t *config, unsigned numOfChannels, std::uint32_t moduleClockFrequency);

        void ForceLowOutput(PWMChannel channel);



@@ 51,7 52,7 @@ namespace drivers

        pwm_channels_t getChannelMask(PWMChannel channel);

        bool channelNotEnabled(PWMChannel channel);
        bool channelEnabled(PWMChannel channel);

        bool otherChannelRunning(PWMChannel channel);



@@ 65,8 66,6 @@ namespace drivers

        pwm_submodule_t pwmModule = kPWM_Module_0;

        std::uint8_t lastDutyCycle = 0;

        std::array<pwm_signal_param_t, 2> pwmSignalsConfig;

        std::vector<PWMChannel> enabledChannels;


@@ 75,7 74,7 @@ namespace drivers

        cpp_freertos::MutexStandard frequencyChangeMutex;

        std::uint32_t clockFrequency = 0;
        std::uint32_t pwmModuleClockFrequency = 0;
    };

} // namespace drivers

D module-bsp/board/rt1051/drivers/RT1051DriverPWMhelper.hpp => module-bsp/board/rt1051/drivers/RT1051DriverPWMhelper.hpp +0 -11
@@ 1,11 0,0 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "module-bsp/board/rt1051/common/fsl_drivers/fsl_common.h"

static inline bool PWM_GetPwmGeneratorState(PWM_Type *base, uint8_t subModulesToStop)
{
    return (base->MCTRL & PWM_MCTRL_RUN(subModulesToStop)) != 0;
}

M module-bsp/bsp/common.hpp => module-bsp/bsp/common.hpp +1 -3
@@ 30,11 30,9 @@ namespace bsp
    {
        RT1051,
        Linux,
        none
        None
    };

    constexpr auto HzPerMHz = 1000000U;

    [[nodiscard]] std::uint8_t CpuMHZToLevel(CpuFrequencyMHz val);
    [[nodiscard]] const char *c_str(Board board);
}

M module-bsp/bsp/eink_frontlight/eink_frontlight.hpp => module-bsp/bsp/eink_frontlight/eink_frontlight.hpp +6 -9
@@ 9,24 9,21 @@ namespace bsp::eink_frontlight
{
    enum class Action
    {
        turnOn,
        turnOff,
        setBrightness,
        TurnOn,
        TurnOff,
        SetBrightness,
    };

    using BrightnessPercentage = float;

    void init();

    void deinit();

    void setBrightness(BrightnessPercentage brightness);

    void turnOn();
    
    void turnOff();

    void setBrightness(BrightnessPercentage brightness);
    void setGammaFactor(float gamma);

    void updateClockFrequency(CpuFrequencyMHz newFrequency);
} // namespace bsp::eink_frontlight
    void updateClockFrequency();
}

M module-bsp/bsp/torch/torch.hpp => module-bsp/bsp/torch/torch.hpp +7 -7
@@ 15,23 15,23 @@ namespace bsp::torch
{
    enum class State
    {
        on,
        off,
        On,
        Off
    };

    enum class ColourTemperature // Kelvin
    {
        noChange = 0,
        warmest = 1800,
        coldest = 6500,
        NoChange = 0,
        Warmest = 1800,
        Coldest = 6500
    };

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

    bool isPresent(void);
    bool isPresent();

    bool turn(State state, ColourTemperature = ColourTemperature::noChange);
    bool turn(State state, ColourTemperature = ColourTemperature::NoChange);
    State getState();
    ColourTemperature getColorTemp();
    bool toggle();

M module-bsp/bsp/vibrator/vibrator.hpp => module-bsp/bsp/vibrator/vibrator.hpp +17 -21
@@ 3,27 3,23 @@
#include <bsp/common.hpp>
#include <chrono>

namespace bsp
namespace bsp::vibrator
{
    namespace vibrator
    {
        inline constexpr auto defaultVibraPulseMs = 1000; /// default: 1000 ms vibra pulse
        inline constexpr auto defaultVibraPauseMs = 1000; /// default: 1000 ms vibra pause between pulses

        enum class Action
        {
            pulse,
            pulseRepeat,
            pulseRepeatInfinite,
            stop,
        };
    inline constexpr auto defaultVibraPulseMs = 1000; /// default: 1000 ms vibra pulse
    inline constexpr auto defaultVibraPauseMs = 1000; /// default: 1000 ms vibra pause between pulses

        void init(std::chrono::milliseconds pulse = std::chrono::milliseconds{defaultVibraPulseMs});
        void deinit();
        void enable();
        void disable();
        void updateClockFrequency(CpuFrequencyMHz newFrequency);
        void setVibrationLevel(unsigned int vibrationLevel);
    enum class Action
    {
        Pulse,
        PulseRepeat,
        PulseRepeatInfinite,
        Stop
    };

    } // namespace vibrator
} // namespace bsp
    void init(std::chrono::milliseconds pulse = std::chrono::milliseconds{defaultVibraPulseMs});
    void deinit();
    void enable();
    void disable();
    void updateClockFrequency();
    void setVibrationLevel(unsigned vibrationLevel);
}

M module-bsp/drivers/pwm/DriverPWM.hpp => module-bsp/drivers/pwm/DriverPWM.hpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 38,7 38,7 @@ namespace drivers
    struct DriverPWMParams
    {
        PWMChannel channel;
        std::uint32_t frequency;
        std::uint32_t outputFrequency;
    };

    class DriverPWM


@@ 61,7 61,7 @@ namespace drivers

        virtual void Stop(PWMChannel channel) = 0;

        virtual void UpdateClockFrequency(bsp::CpuFrequencyMHz newFrequency) = 0;
        virtual void UpdateClockFrequency() = 0;

      protected:
        PWMInstances instance;

M module-services/service-cellular/ServiceCellular.cpp => module-services/service-cellular/ServiceCellular.cpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "endpoints/developerMode/event/ATRequest.hpp"


@@ 742,7 742,7 @@ bool ServiceCellular::handle_power_up_request()
    case bsp::Board::Linux:
        priv->state->set(State::ST::PowerUpProcedure);
        break;
    case bsp::Board::none:
    case bsp::Board::None:
        return false;
        break;
    }


@@ 778,7 778,7 @@ bool ServiceCellular::handle_power_up_procedure()
            break;
        }
    }
    case bsp::Board::none:
    case bsp::Board::None:
    default:
        LOG_FATAL("Unknown board!");
        assert(0);

M module-services/service-cellular/service-cellular/ServiceCellular.hpp => module-services/service-cellular/service-cellular/ServiceCellular.hpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 129,7 129,7 @@ class ServiceCellular : public sys::Service
    std::unique_ptr<packet_data::PacketData> packetData;
    std::unique_ptr<sys::phone_modes::Observer> phoneModeObserver;
    std::unique_ptr<ConnectionManager> connectionManager;
    bsp::Board board = bsp::Board::none;
    bsp::Board board = bsp::Board::None;

    /// URC GSM notification handler
    std::optional<std::shared_ptr<sys::Message>> identifyNotification(const std::string &data);

M module-services/service-evtmgr/WorkerEventCommon.cpp => module-services/service-evtmgr/WorkerEventCommon.cpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "service-evtmgr/EVMessages.hpp"


@@ 189,6 189,6 @@ void WorkerEventCommon::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code

void WorkerEventCommon::updateResourcesAfterCpuFrequencyChange(bsp::CpuFrequencyMHz newFrequency)
{
    bsp::eink_frontlight::updateClockFrequency(newFrequency);
    bsp::vibrator::updateClockFrequency(newFrequency);
    bsp::eink_frontlight::updateClockFrequency();
    bsp::vibrator::updateClockFrequency();
}

M module-services/service-evtmgr/api/EventManagerServiceAPI.cpp => module-services/service-evtmgr/api/EventManagerServiceAPI.cpp +5 -10
@@ 1,15 1,10 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <service-evtmgr/EventManagerServiceAPI.hpp>
#include <service-evtmgr/EVMessages.hpp>
#include <service-evtmgr/ServiceEventManagerName.hpp>

#include <MessageType.hpp>
#include <system/Common.hpp>
#include <Service/Message.hpp>

#include <cstdint>
#include <memory>

namespace sys


@@ 19,25 14,25 @@ namespace sys

void EventManagerServiceAPI::vibrationPulseOnce(sys::Service *serv)
{
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::pulse),
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::Pulse),
                          service::name::evt_manager);
}

void EventManagerServiceAPI::vibrationStop(sys::Service *serv)
{
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::stop),
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::Stop),
                          service::name::evt_manager);
}

void EventManagerServiceAPI::vibrationPulseRepeat(sys::Service *serv, std::chrono::milliseconds time)
{
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::pulseRepeat, time),
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::PulseRepeat, time),
                          service::name::evt_manager);
}

void EventManagerServiceAPI::vibrationPulseRepeatUntilStop(sys::Service *serv)
{
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::pulseRepeatInfinite),
    serv->bus.sendUnicast(std::make_shared<sevm::VibratorMessage>(bsp::vibrator::Action::PulseRepeatInfinite),
                          service::name::evt_manager);
}


M module-services/service-evtmgr/api/torch.cpp => module-services/service-evtmgr/api/torch.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "service-evtmgr/torch.hpp"


@@ 11,6 11,6 @@ namespace event::service::api
    bool isTorchOn()
    {
        auto isOn = bsp::torch::getState();
        return isOn == bsp::torch::State::on;
        return isOn == bsp::torch::State::On;
    }
} // namespace event::service::api

M products/PurePhone/services/evtmgr/EventManager.cpp => products/PurePhone/services/evtmgr/EventManager.cpp +13 -13
@@ 1,4 1,4 @@
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <evtmgr/EventManager.hpp>


@@ 108,23 108,23 @@ void EventManager::initProductEvents()
void EventManager::toggleTorchOnOff()
{
    auto state    = bsp::torch::getState();
    auto newState = (state == bsp::torch::State::off) ? bsp::torch::State::on : bsp::torch::State::off;
    bsp::torch::turn(newState, bsp::torch::ColourTemperature::coldest);
    auto newState = (state == bsp::torch::State::Off) ? bsp::torch::State::On : bsp::torch::State::Off;
    bsp::torch::turn(newState, bsp::torch::ColourTemperature::Coldest);
}

void EventManager::toggleTorchOff()
{
    bsp::torch::turn(bsp::torch::State::off, bsp::torch::ColourTemperature::coldest);
    bsp::torch::turn(bsp::torch::State::Off, bsp::torch::ColourTemperature::Coldest);
}

void EventManager::toggleTorchColor()
{
    auto state = bsp::torch::getState();
    if (state == bsp::torch::State::on) {
    if (state == bsp::torch::State::On) {
        auto color    = bsp::torch::getColorTemp();
        auto newColor = (color == bsp::torch::ColourTemperature::coldest) ? bsp::torch::ColourTemperature::warmest
                                                                          : bsp::torch::ColourTemperature::coldest;
        bsp::torch::turn(bsp::torch::State::on, newColor);
        auto newColor = (color == bsp::torch::ColourTemperature::Coldest) ? bsp::torch::ColourTemperature::Warmest
                                                                          : bsp::torch::ColourTemperature::Coldest;
        bsp::torch::turn(bsp::torch::State::On, newColor);
    }
}



@@ 197,22 197,22 @@ void EventManager::handleKeyMoveEvent(RawKey key)
void EventManager::processVibratorRequest(bsp::vibrator::Action act, std::chrono::milliseconds RepetitionTime)
{
    switch (act) {
    case bsp::vibrator::Action::pulse:
    case bsp::vibrator::Action::Pulse:
        vibrator->Pulse();
        break;
    case bsp::vibrator::Action::pulseRepeat:
    case bsp::vibrator::Action::PulseRepeat:
        vibrator->PulseRepeat(RepetitionTime);
        break;
    case bsp::vibrator::Action::pulseRepeatInfinite:
    case bsp::vibrator::Action::PulseRepeatInfinite:
        vibrator->PulseRepeat();
        break;
    case bsp::vibrator::Action::stop:
    case bsp::vibrator::Action::Stop:
        vibrator->PulseRepeatStop();
        break;
    }
}

void EventManager::processVibratorLevel(unsigned int vibrationLevel)
void EventManager::processVibratorLevel(unsigned vibrationLevel)
{
    vibrator->SetVibrationLevel(vibrationLevel);
}

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

#pragma once


@@ 36,7 36,7 @@ class EventManager : public EventManagerCommon

    void processVibratorRequest(bsp::vibrator::Action act,
                                std::chrono::milliseconds RepetitionTime = std::chrono::milliseconds{1000});
    void processVibratorLevel(unsigned int vibrationLevel);
    void processVibratorLevel(unsigned vibrationLevel);

    void initProductEvents() final;
    auto createEventWorker() -> std::unique_ptr<WorkerEventCommon> final;