M module-bsp/board/linux/battery-charger/battery_charger.cpp => module-bsp/board/linux/battery-charger/battery_charger.cpp +13 -4
@@ 23,6 23,7 @@ namespace bsp::battery_charger
StateOfCharge battLevel = 100;
constexpr StateOfCharge fullBattery = 100;
bool plugged = false;
+ topControllerIRQsource IRQSrc = topControllerIRQsource::CHGR_INT;
constexpr auto chargerPlugStateChange = 'p';
constexpr auto batteryLevelUp = ']';
@@ 49,12 50,14 @@ namespace bsp::battery_charger
std::uint8_t notification = 0;
switch (static_cast<char>(buff[0])) {
case chargerPlugStateChange:
- notification = static_cast<std::uint8_t>(batteryIRQSource::INOKB);
+ notification = static_cast<std::uint8_t>(batteryIRQSource::INTB);
+ IRQSrc = topControllerIRQsource::CHGR_INT;
plugged = !plugged;
targetQueueHandle = IRQQueueHandle;
break;
case batteryLevelUp:
notification = static_cast<std::uint8_t>(batteryIRQSource::INTB);
+ IRQSrc = topControllerIRQsource::FG_INT;
if (battLevel < fullBattery)
battLevel++;
else {
@@ 67,6 70,7 @@ namespace bsp::battery_charger
break;
case batteryLevelDown:
notification = static_cast<std::uint8_t>(batteryIRQSource::INTB);
+ IRQSrc = topControllerIRQsource::FG_INT;
if (battLevel >= 1)
battLevel--;
if (plugged && Store::Battery::get().level == fullBattery) {
@@ 133,10 137,10 @@ namespace bsp::battery_charger
}
// TODO function unused in linux driver, left for compatibility with target driver
- void clearAllIRQs()
+ void clearAllChargerIRQs()
{}
// TODO function unused in linux driver, left for compatibility with target driver
- void clearFuelGuageIRQ()
+ void clearFuelGuageIRQ(std::uint16_t)
{}
std::uint16_t getStatusRegister()
@@ 144,7 148,12 @@ namespace bsp::battery_charger
return static_cast<std::uint16_t>(batteryINTBSource::SOCOnePercentChange);
}
- void chargingFinishedAction()
+ std::uint8_t getTopControllerINTSource()
+ {
+ return static_cast<std::uint8_t>(IRQSrc);
+ }
+
+ void checkTemperatureRange()
{}
} // namespace bsp::battery_charger
M module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp => module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp +45 -16
@@ 86,20 86,24 @@ namespace bsp::battery_charger
VFRemCap_REG = 0x4A,
QH_REG = 0x4D,
- CHG_INT_REG = 0xB0,
- CHG_INT_OK = 0xB2,
- CHG_CNFG_00 = 0xB7,
- CHG_CNFG_01 = 0xB8,
- CHG_CNFG_02 = 0xB9,
- CHG_CNFG_03 = 0xBA,
- CHG_CNFG_04 = 0xBB,
- CHG_CNFG_05 = 0xBC,
- CHG_CNFG_06 = 0xBD,
- CHG_CNFG_07 = 0xBE,
- CHG_CNFG_09 = 0xC0,
- CHG_CNFG_10 = 0xC1,
- CHG_CNFG_11 = 0xC2,
- CHG_CNFG_12 = 0xC3
+ CHG_INT_REG = 0xB0,
+ CHG_INT_MASK = 0xB1,
+ CHG_INT_OK = 0xB2,
+ CHG_DETAILS_00 = 0xB3,
+ CHG_DETAILS_01 = 0xB4,
+ CHG_DETAILS_02 = 0xB5,
+ CHG_CNFG_00 = 0xB7,
+ CHG_CNFG_01 = 0xB8,
+ CHG_CNFG_02 = 0xB9,
+ CHG_CNFG_03 = 0xBA,
+ CHG_CNFG_04 = 0xBB,
+ CHG_CNFG_05 = 0xBC,
+ CHG_CNFG_06 = 0xBD,
+ CHG_CNFG_07 = 0xBE,
+ CHG_CNFG_09 = 0xC0,
+ CHG_CNFG_10 = 0xC1,
+ CHG_CNFG_11 = 0xC2,
+ CHG_CNFG_12 = 0xC3
};
@@ 124,11 128,11 @@ namespace bsp::battery_charger
Br = (1 << 15),
};
- /// CHG_INT registers from documentation
+ /// CHG_INT register
enum class CHG_INT
{
BYP_I = (1 << 0),
- RSVD = (1 << 1),
+ RSVD_I = (1 << 1),
BATP_I = (1 << 2),
BAT_I = (1 << 3),
CHG_I = (1 << 4),
@@ 137,6 141,31 @@ namespace bsp::battery_charger
AICL_I = (1 << 7),
};
+ enum class CHG_MASK
+ {
+ BYP_M = (1 << 0),
+ RSVD_M = (1 << 1),
+ BATP_M = (1 << 2),
+ BAT_M = (1 << 3),
+ CHG_M = (1 << 4),
+ WCIN_M = (1 << 5),
+ CHGIN_M = (1 << 6),
+ AICL_M = (1 << 7)
+ };
+
+ /// CHG_DETAILS_01 register
+ enum CHG_DETAILS_01
+ {
+ CHARGER_PREQUALIFICATION = 0x00,
+ CHARGER_CC = 0x01,
+ CHARGER_CV = 0x02,
+ CHARGER_TOPOFF = 0x03,
+ CHARGER_DONE = 0x04,
+ CHARGER_TIMER_FAULT = 0x06,
+ CHARGER_BATTERY_DETECT = 0x07,
+ CHARGER_OFF = 0x08,
+ };
+
// CONFIG register bits
enum class CONFIG
{
M module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp => module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp +145 -45
@@ 26,6 26,9 @@ namespace bsp::battery_charger
constexpr std::uint16_t ENABLE_ALL_IRQ_MASK = 0xF8;
constexpr std::uint8_t UNLOCK_CHARGER = 0x3 << 2;
+ constexpr std::uint8_t CHG_ON_OTG_OFF_BUCK_ON = 0b00000101;
+ constexpr std::uint8_t CHG_OFF_OTG_OFF_BUCK_ON = 0b00000100;
+
constexpr std::uint8_t VSYS_MIN = 0x80; // 3.6V
constexpr std::uint8_t CHARGE_TARGET_VOLTAGE = 0x1D; // 4.35V
@@ 34,8 37,13 @@ namespace bsp::battery_charger
constexpr std::uint16_t nominalCapacitymAh = 1600;
- constexpr std::uint8_t maxTemperatureDegrees = 50;
- constexpr std::uint8_t minTemperatureDegrees = 5;
+ constexpr std::uint16_t fullyChargedSOC = 100;
+
+ constexpr std::uint8_t maxTemperatureDegrees = 46;
+ constexpr std::uint8_t minTemperatureDegrees = 0;
+ constexpr std::uint8_t maxDisabled = 0x7F;
+ constexpr std::uint8_t minDisabled = 0x80;
+ constexpr auto temperatureHysteresis = 1;
constexpr std::uint16_t maxVoltagemV = 4400;
constexpr std::uint16_t minVoltagemV = 3600;
@@ 77,6 85,13 @@ namespace bsp::battery_charger
} // namespace fuel_gauge_params
+ enum class TemperatureRanges
+ {
+ normal,
+ cold,
+ hot
+ };
+
std::shared_ptr<drivers::DriverI2C> i2c;
std::shared_ptr<drivers::DriverGPIO> gpio;
@@ 177,6 192,20 @@ namespace bsp::battery_charger
return batteryRetval::OK;
}
+ void enableCharging()
+ {
+ if (chargerWrite(Registers::CHG_CNFG_00, CHG_ON_OTG_OFF_BUCK_ON) != kStatus_Success) {
+ LOG_ERROR("Charge enable fail");
+ }
+ }
+
+ void disableCharging()
+ {
+ if (chargerWrite(Registers::CHG_CNFG_00, CHG_OFF_OTG_OFF_BUCK_ON) != kStatus_Success) {
+ LOG_ERROR("Charge disable fail");
+ }
+ }
+
void configureBatteryCharger()
{
unlockProtectedChargerRegisters();
@@ 199,6 228,12 @@ namespace bsp::battery_charger
lockProtectedChargerRegisters();
}
+ std::uint8_t getChargerDetails()
+ {
+ auto status = chargerRead(Registers::CHG_DETAILS_01);
+ return status.second & 0x0F;
+ }
+
batteryRetval configureFuelGaugeBatteryModel()
{
int status = fuelGaugeWrite(Registers::LearnCFG_REG, fuel_gauge_params::LearnCFG);
@@ 331,8 366,9 @@ namespace bsp::battery_charger
batteryRetval fillConfig2RegisterValue()
{
- std::uint16_t regVal = static_cast<std::uint16_t>(CONFIG2::dSOCen) | // SOC 1% change alert
- static_cast<std::uint16_t>(CONFIG2::OCVQen); // Enable automatic empty compensation
+ std::uint16_t regVal = static_cast<std::uint16_t>(CONFIG2::dSOCen) | // SOC 1% change alert
+ static_cast<std::uint16_t>(CONFIG2::TAlrtEn) | // Temperature alerts
+ static_cast<std::uint16_t>(CONFIG2::OCVQen); // Enable automatic empty compensation
if (fuelGaugeWrite(Registers::CONFIG2_REG, regVal) != kStatus_Success) {
LOG_ERROR("fillConfig2RegisterValue failed.");
@@ 372,7 408,20 @@ namespace bsp::battery_charger
std::uint8_t val = ENABLE_ALL_IRQ_MASK;
if (chargerTopControllerWrite(Registers::TOP_CONTROLL_IRQ_MASK_REG, val) != kStatus_Success) {
- LOG_ERROR("enableIRQs read failed.");
+ LOG_ERROR("enableIRQs failed.");
+ return batteryRetval::ChargerError;
+ }
+
+ return batteryRetval::OK;
+ }
+
+ batteryRetval enableChargerIRQs()
+ {
+ std::uint8_t mask = ~(static_cast<std::uint8_t>(CHG_MASK::CHG_M) |
+ static_cast<std::uint8_t>(CHG_MASK::CHGIN_M)); // unmask IRQs
+
+ if (chargerWrite(Registers::CHG_INT_MASK, mask) != kStatus_Success) {
+ LOG_ERROR("enableChargerIRQs failed.");
return batteryRetval::ChargerError;
}
@@ 385,13 434,6 @@ namespace bsp::battery_charger
drivers::DriverGPIO::Create(static_cast<drivers::GPIOInstances>(BoardDefinitions::BATTERY_CHARGER_GPIO),
drivers::DriverGPIOParams{});
- drivers::DriverGPIOPinParams INOKBPinConfig;
- INOKBPinConfig.dir = drivers::DriverGPIOPinParams::Direction::Input;
- INOKBPinConfig.irqMode = drivers::DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge;
- INOKBPinConfig.defLogic = 0;
- INOKBPinConfig.pin = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN);
- gpio->ConfPin(INOKBPinConfig);
-
drivers::DriverGPIOPinParams INTBPinConfig;
INTBPinConfig.dir = drivers::DriverGPIOPinParams::Direction::Input;
INTBPinConfig.irqMode = drivers::DriverGPIOPinParams::InterruptMode::IntFallingEdge;
@@ 399,7 441,6 @@ namespace bsp::battery_charger
INTBPinConfig.pin = static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN);
gpio->ConfPin(INTBPinConfig);
- gpio->EnableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN));
gpio->EnableInterrupt(1 << static_cast<std::uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN));
}
@@ 410,7 451,6 @@ namespace bsp::battery_charger
if (value.second & 0x8000) {
temperature *= -1;
}
- LOG_INFO("Battery cell temperature = %d Cdeg.", temperature);
return temperature;
}
@@ 430,7 470,6 @@ namespace bsp::battery_charger
// positive numbers
current = static_cast<int>(value.second * currentSenseGain);
}
- LOG_INFO("Battery current measurement = %d mA.", current);
return current;
}
@@ 438,9 477,36 @@ namespace bsp::battery_charger
{
auto value = fuelGaugeRead(Registers::VCELL_REG);
int voltage = value.second * voltageSenseGain;
- LOG_INFO("Battery cell voltage measurement = %d mV.", voltage);
return voltage;
}
+
+ void chargingFinishedAction()
+ {
+ LOG_DEBUG("Charging finished.");
+ storeConfiguration();
+ }
+
+ void processTemperatureRange(TemperatureRanges temperatureRange)
+ {
+ switch (temperatureRange) {
+ case TemperatureRanges::normal:
+ LOG_DEBUG("Normal temperature range, charging enabled.");
+ enableCharging();
+ setTemperatureThresholds(maxTemperatureDegrees, minTemperatureDegrees);
+ break;
+ case TemperatureRanges::cold:
+ LOG_DEBUG("Temperature too low, charging disabled.");
+ disableCharging();
+ setTemperatureThresholds(minTemperatureDegrees + temperatureHysteresis, minDisabled);
+ break;
+ case TemperatureRanges::hot:
+ LOG_DEBUG("Temperature too high, charging disabled.");
+ disableCharging();
+ setTemperatureThresholds(maxDisabled, maxTemperatureDegrees - temperatureHysteresis);
+ break;
+ }
+ }
+
} // namespace
int init(xQueueHandle irqQueueHandle, xQueueHandle dcdQueueHandle)
@@ 474,8 540,10 @@ namespace bsp::battery_charger
bool charging = getChargeStatus();
LOG_INFO("Phone battery start state: %d %d", level, charging);
- clearAllIRQs();
+ clearAllChargerIRQs();
+ clearFuelGuageIRQ(static_cast<std::uint16_t>(batteryINTBSource::all));
enableTopIRQs();
+ enableChargerIRQs();
IRQPinsInit();
return 0;
@@ 486,7 554,6 @@ namespace bsp::battery_charger
storeConfiguration();
gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN));
- gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN));
IRQQueueHandle = nullptr;
DCDQueueHandle = nullptr;
@@ 508,20 575,49 @@ namespace bsp::battery_charger
bool getChargeStatus()
{
- std::uint8_t val = 0;
// read clears state
- auto value = chargerRead(Registers::CHG_INT_OK);
- if (value.first != kStatus_Success) {
- LOG_ERROR("failed to read charge status");
+ auto IRQSource = chargerRead(Registers::CHG_INT_REG);
+ if (IRQSource.first != kStatus_Success) {
+ LOG_ERROR("failed to read charge INT source");
+ }
+ auto summary = chargerRead(Registers::CHG_INT_OK);
+ if (summary.first != kStatus_Success) {
+ LOG_ERROR("failed to read charge summary");
}
- bool status = value.second & static_cast<std::uint8_t>(CHG_INT::CHGIN_I);
- if (status) {
+ auto chargerDetails = getChargerDetails();
+
+ if (summary.second & static_cast<std::uint8_t>(CHG_INT::CHGIN_I)) {
Store::Battery::modify().state = Store::Battery::State::Charging;
}
else {
Store::Battery::modify().state = Store::Battery::State::Discharging;
}
- return status;
+
+ switch (chargerDetails) {
+ case CHG_DETAILS_01::CHARGER_DONE:
+ Store::Battery::modify().state = Store::Battery::State::PluggedNotCharging;
+ chargingFinishedAction();
+ break;
+ case CHG_DETAILS_01::CHARGER_OFF:
+ // IRQ from other source than CHGIN && Charger already plugged
+ if (!(IRQSource.second & static_cast<std::uint8_t>(CHG_INT::CHGIN_I)) &&
+ summary.second & static_cast<std::uint8_t>(CHG_INT::CHGIN_I)) {
+ Store::Battery::modify().state = Store::Battery::State::PluggedNotCharging;
+ }
+ break;
+ case CHG_DETAILS_01::CHARGER_PREQUALIFICATION:
+ [[fallthrough]];
+ case CHG_DETAILS_01::CHARGER_CC:
+ [[fallthrough]];
+ case CHG_DETAILS_01::CHARGER_CV:
+ [[fallthrough]];
+ case CHG_DETAILS_01::CHARGER_TOPOFF:
+ Store::Battery::modify().state = Store::Battery::State::Charging;
+ break;
+ }
+
+ return (Store::Battery::get().state == Store::Battery::State::PluggedNotCharging ||
+ Store::Battery::get().state == Store::Battery::State::Charging);
}
std::uint16_t getStatusRegister()
@@ 530,41 626,45 @@ namespace bsp::battery_charger
return status.second;
}
- void clearAllIRQs()
+ void clearAllChargerIRQs()
{
auto value = chargerRead(Registers::CHG_INT_REG);
if (value.second != 0) {
// write zero to clear irq source
chargerWrite(Registers::CHG_INT_REG, 0);
}
-
- std::uint16_t status = getStatusRegister();
- if (status != 0) {
- // write zero to clear irq source
- fuelGaugeWrite(Registers::STATUS_REG, 0);
- }
}
- void clearFuelGuageIRQ()
+ void clearFuelGuageIRQ(std::uint16_t intToClear)
{
- // write zero to clear interrupt source
- fuelGaugeWrite(Registers::STATUS_REG, 0x0000);
+ auto readout = fuelGaugeRead(Registers::STATUS_REG);
+ std::uint16_t toWrite = readout.second & (~intToClear);
+ fuelGaugeWrite(Registers::STATUS_REG, toWrite);
}
- void chargingFinishedAction()
+ void checkTemperatureRange()
{
- LOG_DEBUG("Charging finished.");
- storeConfiguration();
+ TemperatureRanges temperatureRange;
+
+ int temperature = getCellTemperature();
+ LOG_DEBUG("Cell temperature: %d", temperature);
+ if (temperature >= maxTemperatureDegrees) {
+ temperatureRange = TemperatureRanges::hot;
+ }
+ else if (temperature > minTemperatureDegrees) {
+ temperatureRange = TemperatureRanges::normal;
+ }
+ else {
+ temperatureRange = TemperatureRanges::cold;
+ }
+
+ processTemperatureRange(temperatureRange);
}
- BaseType_t INOKB_IRQHandler()
+ std::uint8_t getTopControllerINTSource()
{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- if (IRQQueueHandle != nullptr) {
- std::uint8_t val = static_cast<std::uint8_t>(batteryIRQSource::INOKB);
- xQueueSendFromISR(IRQQueueHandle, &val, &xHigherPriorityTaskWoken);
- }
- return xHigherPriorityTaskWoken;
+ auto value = chargerTopControllerRead(Registers::TOP_CONTROLL_IRQ_SRC_REG);
+ return value.second;
}
BaseType_t INTB_IRQHandler()
M module-bsp/board/rt1051/common/irq/irq_gpio.cpp => module-bsp/board/rt1051/common/irq/irq_gpio.cpp +1 -3
@@ 112,9 112,7 @@ namespace bsp
xHigherPriorityTaskWoken |= keyboard_right_functional_IRQHandler();
}
- if (irq_mask & (1 << BOARD_BATTERY_CHARGER_INOKB_PIN)) {
- xHigherPriorityTaskWoken |= bsp::battery_charger::INOKB_IRQHandler();
- }
+ if (irq_mask & (1 << BOARD_BATTERY_CHARGER_INOKB_PIN)) {}
if (irq_mask & (1 << BOARD_BATTERY_CHARGER_WCINOKB_PIN)) {}
M module-bsp/bsp/battery-charger/battery_charger.hpp => module-bsp/bsp/battery-charger/battery_charger.hpp +14 -5
@@ 29,10 29,19 @@ namespace bsp::battery_charger
INOKB = 0x02
};
+ enum class topControllerIRQsource{
+ CHGR_INT = (1 << 0),
+ FG_INT = (1 << 1),
+ SYS_INT = (1 << 2)
+ };
+
enum class batteryINTBSource{
+ maxTemp = 1 << 13,
minSOCAlert = 1 << 10,
+ minTemp = 1 << 9,
minVAlert = 1 << 8,
- SOCOnePercentChange = 1 << 7
+ SOCOnePercentChange = 1 << 7,
+ all = 0xFFFF
};
enum class batteryChargerType{
@@ 52,15 61,15 @@ namespace bsp::battery_charger
bool getChargeStatus();
- void clearAllIRQs();
+ void clearAllChargerIRQs();
- void clearFuelGuageIRQ();
+ void clearFuelGuageIRQ(std::uint16_t intToClear);
std::uint16_t getStatusRegister();
- void chargingFinishedAction();
+ void checkTemperatureRange();
- BaseType_t INOKB_IRQHandler();
+ std::uint8_t getTopControllerINTSource();
BaseType_t INTB_IRQHandler();
M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +33 -22
@@ 85,33 85,44 @@ bool WorkerEvent::handleMessage(uint32_t queueID)
}
}
- if (queueID == static_cast<uint32_t>(WorkerEventQueues::queueBattery)) {
- uint8_t notification;
+ if (queueID == static_cast<std::uint32_t>(WorkerEventQueues::queueBattery)) {
+ std::uint8_t notification;
if (!queue->Dequeue(¬ification, 0)) {
return false;
}
- if (notification == static_cast<uint8_t>(bsp::battery_charger::batteryIRQSource::INTB)) {
- const auto status = bsp::battery_charger::getStatusRegister();
- if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::minVAlert)) {
- auto messageBrownout = std::make_shared<sevm::BatteryBrownoutMessage>();
- service->bus.sendUnicast(messageBrownout, service::name::system_manager);
- }
- if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange)) {
- bsp::battery_charger::StateOfCharge battLevel = bsp::battery_charger::getBatteryLevel();
- auto message = std::make_shared<sevm::BatteryLevelMessage>(battLevel, false);
- service->bus.sendUnicast(message, service::name::evt_manager);
- battery_level_check::checkBatteryLevelCritical();
+ if (notification == static_cast<std::uint8_t>(bsp::battery_charger::batteryIRQSource::INTB)) {
+ auto topINT = bsp::battery_charger::getTopControllerINTSource();
+ if (topINT & static_cast<std::uint8_t>(bsp::battery_charger::topControllerIRQsource::CHGR_INT)) {
+ auto message = std::make_shared<sevm::BatteryPlugMessage>();
+ message->plugged = bsp::battery_charger::getChargeStatus();
+ service->bus.sendUnicast(std::move(message), service::name::evt_manager);
+ bsp::battery_charger::clearAllChargerIRQs();
}
- bsp::battery_charger::clearAllIRQs();
- }
- if (notification == static_cast<uint8_t>(bsp::battery_charger::batteryIRQSource::INOKB)) {
- bsp::battery_charger::clearAllIRQs();
- auto message = std::make_shared<sevm::BatteryPlugMessage>();
- message->plugged = bsp::battery_charger::getChargeStatus();
- if (!message->plugged) {
- bsp::battery_charger::chargingFinishedAction();
+ if (topINT & static_cast<std::uint8_t>(bsp::battery_charger::topControllerIRQsource::FG_INT)) {
+ const auto status = bsp::battery_charger::getStatusRegister();
+ if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::minVAlert)) {
+ auto messageBrownout = std::make_shared<sevm::BatteryBrownoutMessage>();
+ service->bus.sendUnicast(std::move(messageBrownout), service::name::system_manager);
+ }
+ if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange)) {
+ bsp::battery_charger::clearFuelGuageIRQ(
+ static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange));
+ bsp::battery_charger::StateOfCharge battLevel = bsp::battery_charger::getBatteryLevel();
+ auto message = std::make_shared<sevm::BatteryLevelMessage>(battLevel, false);
+ service->bus.sendUnicast(std::move(message), service::name::evt_manager);
+ battery_level_check::checkBatteryLevelCritical();
+ }
+ if (status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::maxTemp) ||
+ status & static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::minTemp)) {
+ bsp::battery_charger::clearFuelGuageIRQ(
+ static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::maxTemp) |
+ static_cast<std::uint16_t>(bsp::battery_charger::batteryINTBSource::minTemp));
+ bsp::battery_charger::checkTemperatureRange();
+ auto message = std::make_shared<sevm::BatteryPlugMessage>();
+ message->plugged = bsp::battery_charger::getChargeStatus();
+ service->bus.sendUnicast(std::move(message), service::name::evt_manager);
+ }
}
- service->bus.sendUnicast(message, service::name::evt_manager);
}
}
A module-services/service-evtmgr/doc/charger_temperature_cutoff.md => module-services/service-evtmgr/doc/charger_temperature_cutoff.md +9 -0
@@ 0,0 1,9 @@
+# Charger cutoff due to temperature
+
+In order to prevent fast battery cell degradation, charging action needs to be prohibited in specific temperature range. For given cell valid charging range is 0-45 Cdeg.
+
+Current implementation cuts off charging when cell temperature is outside this range. Mechanism is interrupt-driven. In interrupt handler temperature measurement is sampled and appropriate interrupt range is set. The same action is done at the time of initialization. This way no cyclic sampling of the temperature has to be done. Algorithm could be described by following graph:
+
+
+
+Additional 1 Cdeg hysteresis was introduced to prevent rapid changes in charging state.<
\ No newline at end of file
A module-services/service-evtmgr/doc/charger_temperature_cutoff.puml => module-services/service-evtmgr/doc/charger_temperature_cutoff.puml +14 -0
@@ 0,0 1,14 @@
+@startuml
+(*) --> [initialization] "measurement" as meas
+"teperature range\n violation interrupt" -> meas
+If "Detected range" then
+ --> [T = 1~45 Cdeg] charger On
+ --> set normal\ninterrupt bounds
+ else
+ ---> [T<=0 Cdeg] "charger off" as co
+ --> set interrupt\nbounds with 1Cdeg hysteresis
+ else
+ --> [T>45 Cdeg] co
+Endif
+@enduml
+
A module-services/service-evtmgr/doc/charger_temperature_cutoff.svg => module-services/service-evtmgr/doc/charger_temperature_cutoff.svg +31 -0
@@ 0,0 1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="472px" preserveAspectRatio="none" style="width:398px;height:472px;" version="1.1" viewBox="0 0 398 472" width="398px" zoomAndPan="magnify"><defs><filter height="300%" id="f1u2i229hjii8r" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><ellipse cx="215.5" cy="16" fill="#000000" filter="url(#f1u2i229hjii8r)" rx="10" ry="10" style="stroke:none;stroke-width:1.0;"/><rect fill="#FEFECE" filter="url(#f1u2i229hjii8r)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="107" x="162" y="87"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="87" x="172" y="108.1387">measurement</text><rect fill="#FEFECE" filter="url(#f1u2i229hjii8r)" height="47.9375" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="135" x="7" y="80"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="109" x="20" y="101.1387">teperature range</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="111" x="21" y="115.1074">violation interrupt</text><polygon fill="#FEFECE" filter="url(#f1u2i229hjii8r)" points="215.5,169,227.5,181,215.5,193,203.5,181,215.5,169" style="stroke:#A80036;stroke-width:1.5;"/><rect fill="#FEFECE" filter="url(#f1u2i229hjii8r)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="90" x="65.5" y="247"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="70" x="75.5" y="268.1387">charger On</text><rect fill="#FEFECE" filter="url(#f1u2i229hjii8r)" height="47.9375" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="126" x="47.5" y="322"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="67" x="77" y="343.1387">set normal</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="106" x="57.5" y="357.1074">interrupt bounds</text><rect fill="#FEFECE" filter="url(#f1u2i229hjii8r)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="89" x="236" y="329"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="69" x="246" y="350.1387">charger off</text><rect fill="#FEFECE" filter="url(#f1u2i229hjii8r)" height="47.9375" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="208" x="176.5" y="411"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="79" x="241" y="432.1387">set interrupt</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="188" x="186.5" y="446.1074">bounds with 1Cdeg hysteresis</text><!--MD5=[11b5d1c84b2a4e74ea342f7993200deb]
+link start to meas--><path d="M215.5,26.2 C215.5,39.32 215.5,63.77 215.5,81.57 " fill="none" id="start-to-meas" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="215.5,86.86,219.5,77.86,215.5,81.86,211.5,77.86,215.5,86.86" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="66" x="216.5" y="57.2104">initialization</text><!--MD5=[4450667bc073f2b45b1fdac68f3e6f8a]
+link teperature range\n violation interrupt to meas--><path d="M142.25,104 C147.08,104 151.91,104 156.75,104 " fill="none" id="teperature range\n violation interrupt-to-meas" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="161.99,104,152.99,100,156.99,104,152.99,108,161.99,104" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[077487f9f2e8a10fc24dfcbca2bf789f]
+link meas to #7--><path d="M215.5,121.27 C215.5,133.79 215.5,151.01 215.5,163.56 " fill="none" id="meas-to-#7" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="215.5,168.63,219.5,159.63,215.5,163.63,211.5,159.63,215.5,168.63" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="87" x="108.3813" y="158.5304">Detected range</text><!--MD5=[7a626c6d0fea94dec50a52aeac8ab79d]
+link #7 to charger On--><path d="M203.54,181.37 C180.99,180.92 132.46,183.62 110.5,213 C104.54,220.98 103.92,231.85 105.05,241.42 " fill="none" id="#7-to-charger On" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="105.84,246.57,108.4312,237.0681,105.0829,241.6276,100.5234,238.2794,105.84,246.57" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="87" x="111.5" y="224.2104">T = 1~45 Cdeg</text><!--MD5=[58a4a5f747a2c27f4bf696c153b55163]
+link charger On to set normal\ninterrupt bounds--><path d="M110.5,281.19 C110.5,291.42 110.5,304.91 110.5,316.85 " fill="none" id="charger On-to-set normal\ninterrupt bounds" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="110.5,321.86,114.5,312.86,110.5,316.86,106.5,312.86,110.5,321.86" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[b6ee3d217718ceeebac2d2d7bcaed2f6]
+link #7 to co--><path d="M215.38,192.89 C215.54,211.66 217.57,250.99 230.5,281 C237.57,297.4 249.88,313.25 260.52,325.06 " fill="none" id="#7-to-co" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="264.06,328.91,260.9189,319.5755,260.6781,325.2272,255.0264,324.9865,264.06,328.91" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="65" x="231.5" y="268.2104">T<=0 Cdeg</text><!--MD5=[b6ee3d217718ceeebac2d2d7bcaed2f6]
+link #7 to co--><path d="M223.38,185.25 C240.83,192.93 282.47,214.09 298.5,247 C310.56,271.76 300.65,303.64 291.44,324.19 " fill="none" id="#7-to-co-1" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="289.25,328.91,296.665,322.4279,291.3535,324.374,289.4074,319.0624,289.25,328.91" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="63" x="305.5" y="268.2104">T>45 Cdeg</text><!--MD5=[b5afd7c746ea92e84bbc379dded87ad4]
+link co to set interrupt\nbounds with 1Cdeg hysteresis--><path d="M280.5,363.36 C280.5,375.29 280.5,391.74 280.5,405.77 " fill="none" id="co-to-set interrupt\nbounds with 1Cdeg hysteresis" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="280.5,410.81,284.5,401.81,280.5,405.81,276.5,401.81,280.5,410.81" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[178c73281c7f99511c1343376cc26535]
+@startuml
+(*) - -> [initialization] "measurement" as meas
+"teperature range\n violation interrupt" -> meas
+If "Detected range" then
+ - -> [T = 1~45 Cdeg] charger On
+ - -> set normal\ninterrupt bounds
+ else
+ - - -> [T<=0 Cdeg] "charger off" as co
+ - -> set interrupt\nbounds with 1Cdeg hysteresis
+ else
+ - -> [T>45 Cdeg] co
+Endif
+@enduml
+
+PlantUML version 1.2021.00(Sun Jan 10 11:25:05 CET 2021)
+(GPL source distribution)
+Java Runtime: OpenJDK Runtime Environment
+JVM: OpenJDK 64-Bit Server VM
+Default Encoding: UTF-8
+Language: pl
+Country: PL
+--></g></svg><
\ No newline at end of file