M module-bsp/CMakeLists.txt => module-bsp/CMakeLists.txt +1 -1
@@ 14,7 14,7 @@ target_sources(
bsp/lpm/bsp_lpm.cpp
devices/Device.cpp
devices/power/CW2015.cpp
- devices/power/MP2639B.cpp
+ devices/power/MP2615GQ.cpp
devices/temperature/CT7117.cpp
drivers/dma/DriverDMA.cpp
drivers/dmamux/DriverDMAMux.cpp
M module-bsp/board/rt1051/bellpx/hal/battery_charger/BatteryCharger.cpp => module-bsp/board/rt1051/bellpx/hal/battery_charger/BatteryCharger.cpp +14 -14
@@ 10,7 10,7 @@
#include "timers.h"
#include <hal/battery_charger/AbstractBatteryCharger.hpp>
-#include <devices/power/MP2639B.hpp>
+#include <devices/power/MP2615GQ.hpp>
#include <devices/power/CW2015.hpp>
#include <board/BoardDefinitions.hpp>
#include <log/log.hpp>
@@ 74,7 74,7 @@ namespace hal::battery
using BatteryWorkerQueue = WorkerQueue<IrqEvents>;
explicit BellBatteryCharger(xQueueHandle irqQueueHandle);
- ~BellBatteryCharger();
+ ~BellBatteryCharger() override;
std::optional<Voltage> getBatteryVoltage() const final;
std::optional<SOC> getSOC() const final;
@@ 92,7 92,7 @@ namespace hal::battery
void pollFuelGauge();
void handleIrqEvents(IrqEvents event);
- void handleChargerEvents(MP2639B::ChargingStatus status);
+ void handleChargerEvents(MP2615GQ::ChargingStatus status);
xTimerHandle reinit_timer;
xQueueHandle notification_channel;
@@ 102,7 102,7 @@ namespace hal::battery
std::shared_ptr<drivers::DriverI2C> i2c;
std::shared_ptr<drivers::DriverGPIO> charger_gpio_chgok;
std::shared_ptr<drivers::DriverGPIO> charger_gpio;
- mutable bsp::devices::power::MP2639B charger;
+ mutable bsp::devices::power::MP2615GQ charger;
std::shared_ptr<drivers::DriverGPIO> fuel_gauge_gpio;
mutable bsp::devices::power::CW2015 fuel_gauge;
@@ 111,7 111,7 @@ namespace hal::battery
BellBatteryCharger::BellBatteryCharger(xQueueHandle irqQueueHandle)
: notification_channel{irqQueueHandle}, i2c{drivers::DriverI2C::Create(i2c_instance, i2c_params)},
charger_gpio_chgok{drivers::DriverGPIO::Create(charger_irq_gpio_chgok, {})},
- charger_gpio{drivers::DriverGPIO::Create(charger_irq_gpio, {})}, charger{MP2639B::Configuration{
+ charger_gpio{drivers::DriverGPIO::Create(charger_irq_gpio, {})}, charger{MP2615GQ::Configuration{
charger_gpio,
charger_irq_pin_mode,
charger_gpio,
@@ 127,7 127,7 @@ namespace hal::battery
{
reinit_timer = xTimerCreate("reinit_timer", reinit_poll_time, pdFALSE, this, [](TimerHandle_t xTimer) {
- BellBatteryCharger *inst = static_cast<BellBatteryCharger *>(pvTimerGetTimerID(xTimer));
+ auto inst = static_cast<BellBatteryCharger *>(pvTimerGetTimerID(xTimer));
inst->fuel_gauge.reinit();
inst->pollFuelGauge();
});
@@ 169,26 169,26 @@ namespace hal::battery
AbstractBatteryCharger::ChargingStatus BellBatteryCharger::getChargingStatus() const
{
- /// Charger status fetched from MP2639B alone is not enough to be 100% sure what state we are currently in. For
- /// more info check the Table 2 (page 26) from the MP2639B datasheet. It is required to also take into account
+ /// Charger status fetched from MP2615GQ alone is not enough to be 100% sure what state we are currently in. For
+ /// more info check the Table 2 (page 26) from the MP2615GQ datasheet. It is required to also take into account
/// the current state of SOC.
const auto charger_status = charger.get_charge_status();
const auto current_soc = getSOC();
- if (charger_status == MP2639B::ChargingStatus::Complete && current_soc >= 100) {
+ if (charger_status == MP2615GQ::ChargingStatus::Complete && current_soc >= 100) {
return ChargingStatus::ChargingDone;
}
- else if (charger_status == MP2639B::ChargingStatus::Discharging) {
+ else if (charger_status == MP2615GQ::ChargingStatus::Discharging) {
return ChargingStatus::Discharging;
}
- else if (charger_status == MP2639B::ChargingStatus::Charging && current_soc < 100) {
+ else if (charger_status == MP2615GQ::ChargingStatus::Charging && current_soc < 100) {
return ChargingStatus::Charging;
}
- else if (charger_status == MP2639B::ChargingStatus::Complete && current_soc < 100) {
+ else if (charger_status == MP2615GQ::ChargingStatus::Complete && current_soc < 100) {
return ChargingStatus::PluggedNotCharging;
}
- else if (charger_status == MP2639B::ChargingStatus::Charging && current_soc >= 100) {
+ else if (charger_status == MP2615GQ::ChargingStatus::Charging && current_soc >= 100) {
LOG_INFO("The charger reports 'Charging state', but the battery SOC is 100");
return ChargingStatus::ChargingDone;
}
@@ 261,7 261,7 @@ namespace hal::battery
}},
event);
}
- void BellBatteryCharger::handleChargerEvents(const MP2639B::ChargingStatus)
+ void BellBatteryCharger::handleChargerEvents([[maybe_unused]] MP2615GQ::ChargingStatus status)
{
sendNotification(Events::Charger);
}
M module-bsp/devices/power/CW2015.cpp => module-bsp/devices/power/CW2015.cpp +12 -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 "CW2015.hpp"
@@ 19,7 19,6 @@
namespace
{
constexpr std::uint32_t i2c_subaddr_size = 1;
-
} // namespace
namespace bsp::devices::power
@@ 30,10 29,12 @@ namespace bsp::devices::power
{
status = init_chip();
}
+
CW2015::~CW2015()
{
sleep();
}
+
std::optional<units::SOC> CW2015::get_battery_soc()
{
// Only higher byte of SOC register pair is needed here. Accuracy will be enough
@@ 44,6 45,7 @@ namespace bsp::devices::power
return std::nullopt;
}
}
+
std::optional<units::Voltage> CW2015::get_battery_voltage()
{
constexpr auto median_samples = 3;
@@ 83,6 85,7 @@ namespace bsp::devices::power
return ADResult * adc_conversion_constant / micro_to_milli_ratio; // mV
}
+
CW2015::RetCodes CW2015::clear_irq()
{
const auto lsb = read(RRT_ALERT::ADDRESS_L);
@@ 154,6 157,7 @@ namespace bsp::devices::power
return RetCodes::Ok;
}
+
CW2015::RetCodes CW2015::reset_chip()
{
if (not write(Mode::ADDRESS, Mode{}.set_power_on_reset().get_raw())) {
@@ 165,12 169,14 @@ namespace bsp::devices::power
}
return RetCodes::Ok;
}
+
void CW2015::irq_handler()
{
if (const auto result = clear_irq(); result != RetCodes::Ok) {
LOG_ERROR("Error during handling irq, %s", magic_enum::enum_name(result).data());
}
}
+
void CW2015::init_irq_pin(std::shared_ptr<drivers::DriverGPIO> gpio, uint32_t pin)
{
drivers::DriverGPIOPinParams ALRTPinConfig{};
@@ 182,6 188,7 @@ namespace bsp::devices::power
gpio->EnableInterrupt(1 << pin);
}
+
CW2015::RetCodes CW2015::quick_start()
{
if (not write(Mode::ADDRESS, Mode{}.set_quick_start().get_raw())) {
@@ 193,6 200,7 @@ namespace bsp::devices::power
}
return RetCodes::Ok;
}
+
CW2015::RetCodes CW2015::poll() const
{
return status;
@@ 333,13 341,14 @@ namespace bsp::devices::power
}
return false;
}
+
CW2015::operator bool() const
{
return status == RetCodes::Ok;
}
+
CW2015::RetCodes CW2015::calibrate()
{
return quick_start();
}
-
} // namespace bsp::devices::power
M module-bsp/devices/power/CW2015.hpp => module-bsp/devices/power/CW2015.hpp +3 -4
@@ 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
#pragma once
@@ 10,7 10,7 @@
namespace bsp::devices::power
{
- /// MP2639B fuel gauge driver
+ /// CW2015 fuel gauge driver
/// To enable interrupts support call \ref init_irq_pin and then invoke \ref handle_irq in the corresponding IRQ
/// routine.
class CW2015
@@ 33,7 33,7 @@ namespace bsp::devices::power
CW2015 &operator=(CW2015 &&) noexcept = delete;
/// Returns the result of the chip initialization
- RetCodes poll() const;
+ [[nodiscard]] RetCodes poll() const;
/// Returns true if the chip initialization success, otherwise false
explicit operator bool() const;
/// Explicitly triggers chip initialization procedure. The result can be polled by \ref poll or using bool
@@ 79,5 79,4 @@ namespace bsp::devices::power
RetCodes status{};
units::SOC alert_threshold;
};
-
} // namespace bsp::devices::power
R module-bsp/devices/power/MP2639B.cpp => module-bsp/devices/power/MP2615GQ.cpp +38 -37
@@ 1,23 1,26 @@
-// 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 "MP2639B.hpp"
+#include "MP2615GQ.hpp"
namespace bsp::devices::power
{
- MP2639B::MP2639B(const Configuration &conf) : configuration{conf}
+ MP2615GQ::MP2615GQ(const Configuration &conf) : configuration{conf}
{
- irq_filter_timer =
- xTimerCreate("irq_charger_filter", pdMS_TO_TICKS(50), pdFALSE, this, [](TimerHandle_t xTimer) {
- MP2639B *inst = static_cast<MP2639B *>(pvTimerGetTimerID(xTimer));
- /// Charging disable is done automatically if the conditions are met.
- if (not inst->is_valid_voltage()) {
- inst->enable_charging(false);
- }
- if (inst->configuration.notification) {
- inst->configuration.notification(inst->get_charge_status());
- }
- });
+ irq_filter_timer = xTimerCreate(irq_filter_timer_name,
+ pdMS_TO_TICKS(irq_filter_timer_interval_ms),
+ pdFALSE,
+ this,
+ [](TimerHandle_t xTimer) {
+ auto inst = static_cast<MP2615GQ *>(pvTimerGetTimerID(xTimer));
+ /// Charging disable is done automatically if the conditions are met.
+ if (!inst->is_valid_voltage()) {
+ inst->enable_charging(false);
+ }
+ if (inst->configuration.notification) {
+ inst->configuration.notification(inst->get_charge_status());
+ }
+ });
drivers::DriverGPIOPinParams mode_pin_params{};
mode_pin_params.dir = drivers::DriverGPIOPinParams::Direction::Output;
@@ 30,44 33,40 @@ namespace bsp::devices::power
enable_charging(false);
}
- MP2639B::~MP2639B()
+ MP2615GQ::~MP2615GQ()
{
- xTimerDelete(irq_filter_timer, pdMS_TO_TICKS(100));
+ xTimerDelete(irq_filter_timer, pdMS_TO_TICKS(irq_filter_timer_cmd_timeout_ms));
configuration.chgok_gpio->DisableInterrupt(1 << configuration.chgok_pin);
configuration.acok_gpio->DisableInterrupt(1 << configuration.acok_pin);
enable_charging(false);
}
- MP2639B::ChargingStatus MP2639B::get_charge_status()
+
+ MP2615GQ::ChargingStatus MP2615GQ::get_charge_status()
{
/// For more info, please refer to the Table 1 "Charging Status Indication" in reference manual.
-
- ChargingStatus status{};
-
const auto valid_voltage = is_valid_voltage();
const auto charging = is_charging();
- if (not valid_voltage) {
+ ChargingStatus status{};
+ if (!valid_voltage) {
status = ChargingStatus::Discharging;
}
- else if (valid_voltage and is_charging_enabled()) {
+ else if (is_charging_enabled()) {
status = charging ? ChargingStatus::Charging : ChargingStatus::Complete;
}
- else if (valid_voltage and not is_charging_enabled()) {
+ else if (!is_charging_enabled()) {
status = ChargingStatus::PluggedNotCharging;
}
return status;
}
- void MP2639B::enable_charging(bool ctrl)
+
+ void MP2615GQ::enable_charging(bool ctrl)
{
- if (ctrl) {
- configuration.mode_gpio->WritePin(configuration.mode_pin, 0);
- }
- else {
- configuration.mode_gpio->WritePin(configuration.mode_pin, 1);
- }
+ configuration.mode_gpio->WritePin(configuration.mode_pin, ctrl ? 0 : 1);
}
- void MP2639B::enable_irq()
+
+ void MP2615GQ::enable_irq()
{
drivers::DriverGPIOPinParams ACOKPinConfig{};
ACOKPinConfig.dir = drivers::DriverGPIOPinParams::Direction::Input;
@@ 87,27 86,29 @@ namespace bsp::devices::power
configuration.acok_gpio->EnableInterrupt(1U << configuration.acok_pin);
}
- void MP2639B::handle_irq()
+ void MP2615GQ::handle_irq()
{
if (xTimerIsTimerActive(irq_filter_timer) == pdFALSE) {
- xTimerStart(irq_filter_timer, pdMS_TO_TICKS(500));
+ xTimerStart(irq_filter_timer, pdMS_TO_TICKS(irq_filter_timer_cmd_timeout_ms));
}
}
- bool MP2639B::is_charging_enabled() const
+
+ bool MP2615GQ::is_charging_enabled() const
{
return configuration.mode_gpio->ReadPin(configuration.mode_pin) == 0;
}
- bool MP2639B::is_valid_voltage() const
+
+ bool MP2615GQ::is_valid_voltage() const
{
/// ACOK -> Valid Input Supply Indicator. A logic Low on this pin indicates the presence of a valid input power
/// supply.
return configuration.acok_gpio->ReadPin(configuration.acok_pin) == 0;
}
- bool MP2639B::is_charging() const
+
+ bool MP2615GQ::is_charging() const
{
/// CHGOK -> Charging Completion Indicator. A logic Low indicates charging operation. The pin will become an
/// open drain once the charge is completed or suspended.
return configuration.chgok_gpio->ReadPin(configuration.chgok_pin) == 0;
}
-
} // namespace bsp::devices::power
R module-bsp/devices/power/MP2639B.hpp => module-bsp/devices/power/MP2615GQ.hpp +16 -12
@@ 12,10 12,10 @@
namespace bsp::devices::power
{
- /// MP2639B charger driver
+ /// MP2615GQ charger driver
/// To enable interrupts support call \ref enable_irq and then invoke \ref handle_irq in the corresponding IRQ
/// routine.
- class MP2639B
+ class MP2615GQ
{
public:
enum class ChargingStatus : std::uint8_t
@@ 44,13 44,13 @@ namespace bsp::devices::power
std::function<void(const ChargingStatus)> notification;
};
- explicit MP2639B(const Configuration &conf);
- ~MP2639B();
+ explicit MP2615GQ(const Configuration &conf);
+ ~MP2615GQ();
- MP2639B(const MP2639B &) = delete;
- MP2639B &operator=(const MP2639B &) = delete;
- MP2639B(MP2639B &&) = default;
- MP2639B &operator=(MP2639B &&) = delete;
+ MP2615GQ(const MP2615GQ &) = delete;
+ MP2615GQ &operator=(const MP2615GQ &) = delete;
+ MP2615GQ(MP2615GQ &&) = default;
+ MP2615GQ &operator=(MP2615GQ &&) = delete;
ChargingStatus get_charge_status();
void enable_charging(bool ctrl);
@@ 59,11 59,15 @@ namespace bsp::devices::power
void handle_irq();
private:
- bool is_charging() const;
- bool is_valid_voltage() const;
- bool is_charging_enabled() const;
+ [[nodiscard]] bool is_charging() const;
+ [[nodiscard]] bool is_valid_voltage() const;
+ [[nodiscard]] bool is_charging_enabled() const;
+
+ static constexpr auto irq_filter_timer_interval_ms = 50;
+ static constexpr auto irq_filter_timer_name = "irq_charger_filter";
+ static constexpr auto irq_filter_timer_cmd_timeout_ms = 100;
+
Configuration configuration;
xTimerHandle irq_filter_timer;
};
-
} // namespace bsp::devices::power
M module-bsp/hal/include/hal/battery_charger/AbstractBatteryCharger.hpp => module-bsp/hal/include/hal/battery_charger/AbstractBatteryCharger.hpp +8 -7
@@ 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
@@ 18,6 18,7 @@ namespace hal::battery
public:
using SOC = units::SOC;
using Voltage = units::Voltage;
+
enum class ChargingStatus
{
Discharging,
@@ 50,16 51,16 @@ namespace hal::battery
struct Factory
{
- static std::unique_ptr<AbstractBatteryCharger> create(xQueueHandle);
+ static std::unique_ptr<AbstractBatteryCharger> create(xQueueHandle irqQueueHandle);
};
virtual ~AbstractBatteryCharger() = default;
- virtual std::optional<Voltage> getBatteryVoltage() const = 0;
- virtual std::optional<SOC> getSOC() const = 0;
- virtual ChargingStatus getChargingStatus() const = 0;
- virtual ChargerPresence getChargerPresence() const = 0;
- virtual TemperatureState getTemperatureState() const = 0;
+ [[nodiscard]] virtual std::optional<Voltage> getBatteryVoltage() const = 0;
+ [[nodiscard]] virtual std::optional<SOC> getSOC() const = 0;
+ [[nodiscard]] virtual ChargingStatus getChargingStatus() const = 0;
+ [[nodiscard]] virtual ChargerPresence getChargerPresence() const = 0;
+ [[nodiscard]] virtual TemperatureState getTemperatureState() const = 0;
static_assert(sizeof(Events) == sizeof(std::uint8_t),
"All events processed by event manager ought to have size of std::uint8_t");