~aleteoryx/muditaos

f7980fea6d737c9d2362e81e2fa2c4503af4480a — Dawid Wojtas 2 years ago 3934e71
[BH-1649] Reimplement I2C communication attempts

The CW2015 driver should avoid any logic.
Thus I2C communication attempts were moved
to the BatteryCharger which is product specific.
M module-bsp/board/linux/hal/battery_charger/BatteryCharger.cpp => module-bsp/board/linux/hal/battery_charger/BatteryCharger.cpp +3 -3
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <hal/battery_charger/AbstractBatteryCharger.hpp>


@@ 36,7 36,7 @@ namespace hal::battery
        explicit BatteryCharger(xQueueHandle irqQueueHandle);
        ~BatteryCharger();

        Voltage getBatteryVoltage() const final;
        std::optional<Voltage> getBatteryVoltage() const final;
        std::optional<SOC> getSOC() const final;
        ChargingStatus getChargingStatus() const final;
        ChargerPresence getChargerPresence() const final;


@@ 74,7 74,7 @@ namespace hal::battery
        vTaskDelay(taskDelay * 2);
    }

    AbstractBatteryCharger::Voltage BatteryCharger::getBatteryVoltage() const
    std::optional<AbstractBatteryCharger::Voltage> BatteryCharger::getBatteryVoltage() const
    {
        return dummyBatteryVoltageLevel;
    }

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

#include "BatteryChargerIRQ.hpp"


@@ 55,7 55,7 @@ namespace hal::battery
        explicit BellBatteryCharger(xQueueHandle irqQueueHandle);
        ~BellBatteryCharger();

        Voltage getBatteryVoltage() const final;
        std::optional<Voltage> getBatteryVoltage() const final;
        std::optional<SOC> getSOC() const final;
        ChargingStatus getChargingStatus() const final;
        ChargerPresence getChargerPresence() const final;


@@ 63,8 63,10 @@ namespace hal::battery
        static BatteryWorkerQueue &getWorkerQueueHandle();

      private:
        template <typename Invokable, typename... Params>
        auto attemptToGetData(Invokable &&invokable, Params &&...params) const;

        void sendNotification(Events event);
        std::optional<SOC> fetchBatterySOC() const;
        void pollFuelGauge();
        bool tryEnableCharging();



@@ 135,20 137,30 @@ namespace hal::battery
        fuel_gauge.init_irq_pin(fuel_gauge_gpio, fuel_gauge_irq_pin);
    }

    AbstractBatteryCharger::Voltage BellBatteryCharger::getBatteryVoltage() const
    template <typename Invokable, typename... Params>
    auto BellBatteryCharger::attemptToGetData(Invokable &&invokable, Params &&...params) const
    {
        if (const auto result = fuel_gauge.get_battery_voltage()) {
            return *result;
        }
        else {
            LOG_ERROR("Error during fetching battery voltage");
            return 0;
        constexpr std::uint8_t maxAttempts = 5;
        for (std::uint8_t i = 0; i < maxAttempts; ++i) {
            if (const auto result = std::invoke(invokable, std::forward<Params>(params)...)) {
                return result;
            }
            i2c->ReInit();
            LOG_INFO("Attempting to get I2C data: %d", i);
            vTaskDelay(pdMS_TO_TICKS(i * 10));
        }
        LOG_ERROR("Error during fetching I2C data");
        return std::result_of_t<Invokable(Params...)>{};
    }

    std::optional<AbstractBatteryCharger::Voltage> BellBatteryCharger::getBatteryVoltage() const
    {
        return attemptToGetData(&bsp::devices::power::CW2015::get_battery_voltage, fuel_gauge);
    }

    std::optional<AbstractBatteryCharger::SOC> BellBatteryCharger::getSOC() const
    {
        return fetchBatterySOC();
        return attemptToGetData(&bsp::devices::power::CW2015::get_battery_soc, fuel_gauge);
    }

    AbstractBatteryCharger::ChargingStatus BellBatteryCharger::getChargingStatus() const


@@ 158,7 170,7 @@ namespace hal::battery
        /// the current state of SOC.

        const auto charger_status = charger.get_charge_status();
        const auto current_soc    = fetchBatterySOC();
        const auto current_soc    = getSOC();

        if (charger_status == MP2639B::ChargingStatus::Complete && current_soc >= 100) {
            return ChargingStatus::ChargingDone;


@@ 187,16 199,6 @@ namespace hal::battery
                                                                  : AbstractBatteryCharger::ChargerPresence::PluggedIn;
    }

    std::optional<AbstractBatteryCharger::SOC> BellBatteryCharger::fetchBatterySOC() const
    {
        if (const auto soc = fuel_gauge.get_battery_soc(); const auto scaled_soc = scale_soc(*soc)) {
            return scaled_soc;
        }
        else {
            LOG_ERROR("Error during fetching battery level");
            return std::nullopt;
        }
    }
    BellBatteryCharger::BatteryWorkerQueue &BellBatteryCharger::getWorkerQueueHandle()
    {
        return *worker_queue;

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

#include "BatteryChargerIRQ.hpp"


@@ 82,7 82,7 @@ namespace hal::battery
        explicit PureBatteryCharger(xQueueHandle irqQueueHandle);
        ~PureBatteryCharger();

        Voltage getBatteryVoltage() const final;
        std::optional<Voltage> getBatteryVoltage() const final;
        std::optional<SOC> getSOC() const final;
        ChargingStatus getChargingStatus() const final;
        ChargerPresence getChargerPresence() const final;


@@ 151,7 151,7 @@ namespace hal::battery
            break;
        }
    }
    AbstractBatteryCharger::Voltage PureBatteryCharger::getBatteryVoltage() const
    std::optional<AbstractBatteryCharger::Voltage> PureBatteryCharger::getBatteryVoltage() const
    {
        return bsp::battery_charger::getVoltageFilteredMeasurement();
    }

M module-bsp/devices/power/CW2015.cpp => module-bsp/devices/power/CW2015.cpp +4 -19
@@ 317,34 317,19 @@ namespace bsp::devices::power

    std::optional<std::uint8_t> CW2015::read(const std::uint8_t reg)
    {
        constexpr std::uint8_t maxAttemps          = 5;
        const drivers::I2CAddress fuelGaugeAddress = {ADDRESS, reg, i2c_subaddr_size};
        std::uint8_t ret_val{};

        for (std::uint8_t i = 0; i < maxAttemps; ++i) {
            if (const auto result = i2c.Read(fuelGaugeAddress, &ret_val, i2c_subaddr_size);
                result == i2c_subaddr_size) {
                return ret_val;
            }
            i2c.ReInit();
            LOG_INFO("Attempting to read I2C data: %d", i);
            vTaskDelay(pdMS_TO_TICKS(i * 10));
        if (const auto result = i2c.Read(fuelGaugeAddress, &ret_val, i2c_subaddr_size); result == i2c_subaddr_size) {
            return ret_val;
        }
        return std::nullopt;
    }

    bool CW2015::write(const std::uint8_t reg, const std::uint8_t value)
    {
        constexpr std::uint8_t maxAttemps          = 5;
        const drivers::I2CAddress fuelGaugeAddress = {ADDRESS, reg, i2c_subaddr_size};

        for (std::uint8_t i = 0; i < maxAttemps; ++i) {
            if (const auto result = i2c.Write(fuelGaugeAddress, &value, i2c_subaddr_size); result == i2c_subaddr_size) {
                return true;
            }
            i2c.ReInit();
            LOG_INFO("Attempting to write I2C data: %d", i);
            vTaskDelay(pdMS_TO_TICKS(i * 10));
        if (const auto result = i2c.Write(fuelGaugeAddress, &value, i2c_subaddr_size); result == i2c_subaddr_size) {
            return true;
        }
        return false;
    }

M module-bsp/hal/include/hal/battery_charger/AbstractBatteryCharger.hpp => module-bsp/hal/include/hal/battery_charger/AbstractBatteryCharger.hpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once


@@ 47,7 47,7 @@ namespace hal::battery

        virtual ~AbstractBatteryCharger() = default;

        virtual Voltage getBatteryVoltage() const          = 0;
        virtual std::optional<Voltage> getBatteryVoltage() const = 0;
        virtual std::optional<SOC> getSOC() const          = 0;
        virtual ChargingStatus getChargingStatus() const   = 0;
        virtual ChargerPresence getChargerPresence() const = 0;

M module-services/service-evtmgr/battery/BatteryController.cpp => module-services/service-evtmgr/battery/BatteryController.cpp +14 -4
@@ 95,7 95,7 @@ BatteryController::BatteryController(sys::Service *service,

    LOG_INFO("Initial charger state:%s", magic_enum::enum_name(Store::Battery::get().state).data());
    LOG_INFO("Initial battery SOC:%d", Store::Battery::get().level);
    LOG_INFO("Initial battery voltage:%" PRIu32 "mV", charger->getBatteryVoltage());
    LOG_INFO("Initial battery voltage:%" PRIu32 "mV", getVoltage());
    LOG_INFO("Initial battery state:%s", magic_enum::enum_name(Store::Battery::get().levelState).data());
}



@@ 125,7 125,7 @@ void sevm::battery::BatteryController::printCurrentState()
    LOG_INFO("Charger state:%s Battery SOC %d voltage: %" PRIu32 "mV state: %s",
             magic_enum::enum_name(Store::Battery::get().state).data(),
             Store::Battery::get().level,
             charger->getBatteryVoltage(),
             getVoltage(),
             magic_enum::enum_name(Store::Battery::get().levelState).data());
}
void sevm::battery::BatteryController::update()


@@ 152,12 152,22 @@ void sevm::battery::BatteryController::update()

void sevm::battery::BatteryController::updateSoC()
{
    auto batteryLevel = charger->getSOC();
    if (batteryLevel.has_value()) {
    const auto batteryLevel = charger->getSOC();
    if (batteryLevel) {
        Store::Battery::modify().level = batteryLevel.value();
    }
}

units::Voltage sevm::battery::BatteryController::getVoltage()
{
    const auto voltage = charger->getBatteryVoltage();
    if (voltage) {
        return *voltage;
    }
    LOG_ERROR("Can't get the voltage");
    return 0;
}

void sevm::battery::BatteryController::checkChargerPresence()
{
    const auto newChargerPresence = charger->getChargerPresence();

M module-services/service-evtmgr/battery/BatteryController.hpp => module-services/service-evtmgr/battery/BatteryController.hpp +1 -0
@@ 32,6 32,7 @@ namespace sevm::battery
        void updateSoC();
        void printCurrentState();
        void checkChargerPresence();
        units::Voltage getVoltage();
        sys::Service *service{nullptr};
        std::unique_ptr<hal::battery::AbstractBatteryCharger> charger;
        BatteryBrownoutDetector brownoutDetector;