From a6cdd53a86bb1d0ac5d868cacee0a42c9b6ba5d0 Mon Sep 17 00:00:00 2001 From: Wojtek Rzepecki Date: Tue, 2 Feb 2021 14:16:27 +0100 Subject: [PATCH] [EGD-5577] Add charger temperature cutoff Battery charger cutoff due in selected temperature range. Proper charged state detection for rt1051 --- .../linux/battery-charger/battery_charger.cpp | 17 +- .../rt1051/bsp/battery-charger/MAX77818.hpp | 61 ++++-- .../bsp/battery-charger/battery_charger.cpp | 190 +++++++++++++----- .../board/rt1051/common/irq/irq_gpio.cpp | 4 +- .../bsp/battery-charger/battery_charger.hpp | 19 +- .../service-evtmgr/WorkerEvent.cpp | 55 +++-- .../doc/charger_temperature_cutoff.md | 9 + .../doc/charger_temperature_cutoff.puml | 14 ++ .../doc/charger_temperature_cutoff.svg | 31 +++ 9 files changed, 305 insertions(+), 95 deletions(-) create mode 100644 module-services/service-evtmgr/doc/charger_temperature_cutoff.md create mode 100644 module-services/service-evtmgr/doc/charger_temperature_cutoff.puml create mode 100644 module-services/service-evtmgr/doc/charger_temperature_cutoff.svg diff --git a/module-bsp/board/linux/battery-charger/battery_charger.cpp b/module-bsp/board/linux/battery-charger/battery_charger.cpp index 7666cbe7b02f5ac13beec92b1b41f8e3e97c2b4b..cf4bde6a024f3fc96eb2323e14dc5103fd7c091f 100644 --- a/module-bsp/board/linux/battery-charger/battery_charger.cpp +++ b/module-bsp/board/linux/battery-charger/battery_charger.cpp @@ -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(buff[0])) { case chargerPlugStateChange: - notification = static_cast(batteryIRQSource::INOKB); + notification = static_cast(batteryIRQSource::INTB); + IRQSrc = topControllerIRQsource::CHGR_INT; plugged = !plugged; targetQueueHandle = IRQQueueHandle; break; case batteryLevelUp: notification = static_cast(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(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(batteryINTBSource::SOCOnePercentChange); } - void chargingFinishedAction() + std::uint8_t getTopControllerINTSource() + { + return static_cast(IRQSrc); + } + + void checkTemperatureRange() {} } // namespace bsp::battery_charger diff --git a/module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp b/module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp index ff581a8dc13d18283580fdf488e280eac5dca735..9770e0f2fee88e422d0e70e05e05de44cd896903 100644 --- a/module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp +++ b/module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp @@ -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 { diff --git a/module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp b/module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp index fdeb8f316a4af271e81853423744de841d1bf52e..efe9cbe814ada3ba6d523779fd841fd8caf7a857 100644 --- a/module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp +++ b/module-bsp/board/rt1051/bsp/battery-charger/battery_charger.cpp @@ -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 i2c; std::shared_ptr 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(CONFIG2::dSOCen) | // SOC 1% change alert - static_cast(CONFIG2::OCVQen); // Enable automatic empty compensation + std::uint16_t regVal = static_cast(CONFIG2::dSOCen) | // SOC 1% change alert + static_cast(CONFIG2::TAlrtEn) | // Temperature alerts + static_cast(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(CHG_MASK::CHG_M) | + static_cast(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(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(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(BoardDefinitions::BATTERY_CHARGER_INTB_PIN); gpio->ConfPin(INTBPinConfig); - gpio->EnableInterrupt(1 << static_cast(BoardDefinitions::BATTERY_CHARGER_INOKB_PIN)); gpio->EnableInterrupt(1 << static_cast(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(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(batteryINTBSource::all)); enableTopIRQs(); + enableChargerIRQs(); IRQPinsInit(); return 0; @@ -486,7 +554,6 @@ namespace bsp::battery_charger storeConfiguration(); gpio->DisableInterrupt(1 << static_cast(BoardDefinitions::BATTERY_CHARGER_INTB_PIN)); - gpio->DisableInterrupt(1 << static_cast(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(CHG_INT::CHGIN_I); - if (status) { + auto chargerDetails = getChargerDetails(); + + if (summary.second & static_cast(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(CHG_INT::CHGIN_I)) && + summary.second & static_cast(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(batteryIRQSource::INOKB); - xQueueSendFromISR(IRQQueueHandle, &val, &xHigherPriorityTaskWoken); - } - return xHigherPriorityTaskWoken; + auto value = chargerTopControllerRead(Registers::TOP_CONTROLL_IRQ_SRC_REG); + return value.second; } BaseType_t INTB_IRQHandler() diff --git a/module-bsp/board/rt1051/common/irq/irq_gpio.cpp b/module-bsp/board/rt1051/common/irq/irq_gpio.cpp index 7134f785c961329998a20f717435c4804dad9f37..b1c1039c267991a3da5c761f95e0314e4e3068ad 100644 --- a/module-bsp/board/rt1051/common/irq/irq_gpio.cpp +++ b/module-bsp/board/rt1051/common/irq/irq_gpio.cpp @@ -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)) {} diff --git a/module-bsp/bsp/battery-charger/battery_charger.hpp b/module-bsp/bsp/battery-charger/battery_charger.hpp index 590af74e530c7efccc372aebf525bcece05e6e6f..500418c5898015fb6407d75d2931d36d0ef6ca71 100644 --- a/module-bsp/bsp/battery-charger/battery_charger.hpp +++ b/module-bsp/bsp/battery-charger/battery_charger.hpp @@ -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(); diff --git a/module-services/service-evtmgr/WorkerEvent.cpp b/module-services/service-evtmgr/WorkerEvent.cpp index ec2ab00880e01db860a512c4f37fbfe756dab13f..bb3a70363e7d9d2d66d5a029ed7cd7a818c60646 100644 --- a/module-services/service-evtmgr/WorkerEvent.cpp +++ b/module-services/service-evtmgr/WorkerEvent.cpp @@ -85,33 +85,44 @@ bool WorkerEvent::handleMessage(uint32_t queueID) } } - if (queueID == static_cast(WorkerEventQueues::queueBattery)) { - uint8_t notification; + if (queueID == static_cast(WorkerEventQueues::queueBattery)) { + std::uint8_t notification; if (!queue->Dequeue(¬ification, 0)) { return false; } - if (notification == static_cast(bsp::battery_charger::batteryIRQSource::INTB)) { - const auto status = bsp::battery_charger::getStatusRegister(); - if (status & static_cast(bsp::battery_charger::batteryINTBSource::minVAlert)) { - auto messageBrownout = std::make_shared(); - service->bus.sendUnicast(messageBrownout, service::name::system_manager); - } - if (status & static_cast(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange)) { - bsp::battery_charger::StateOfCharge battLevel = bsp::battery_charger::getBatteryLevel(); - auto message = std::make_shared(battLevel, false); - service->bus.sendUnicast(message, service::name::evt_manager); - battery_level_check::checkBatteryLevelCritical(); + if (notification == static_cast(bsp::battery_charger::batteryIRQSource::INTB)) { + auto topINT = bsp::battery_charger::getTopControllerINTSource(); + if (topINT & static_cast(bsp::battery_charger::topControllerIRQsource::CHGR_INT)) { + auto message = std::make_shared(); + 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(bsp::battery_charger::batteryIRQSource::INOKB)) { - bsp::battery_charger::clearAllIRQs(); - auto message = std::make_shared(); - message->plugged = bsp::battery_charger::getChargeStatus(); - if (!message->plugged) { - bsp::battery_charger::chargingFinishedAction(); + if (topINT & static_cast(bsp::battery_charger::topControllerIRQsource::FG_INT)) { + const auto status = bsp::battery_charger::getStatusRegister(); + if (status & static_cast(bsp::battery_charger::batteryINTBSource::minVAlert)) { + auto messageBrownout = std::make_shared(); + service->bus.sendUnicast(std::move(messageBrownout), service::name::system_manager); + } + if (status & static_cast(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange)) { + bsp::battery_charger::clearFuelGuageIRQ( + static_cast(bsp::battery_charger::batteryINTBSource::SOCOnePercentChange)); + bsp::battery_charger::StateOfCharge battLevel = bsp::battery_charger::getBatteryLevel(); + auto message = std::make_shared(battLevel, false); + service->bus.sendUnicast(std::move(message), service::name::evt_manager); + battery_level_check::checkBatteryLevelCritical(); + } + if (status & static_cast(bsp::battery_charger::batteryINTBSource::maxTemp) || + status & static_cast(bsp::battery_charger::batteryINTBSource::minTemp)) { + bsp::battery_charger::clearFuelGuageIRQ( + static_cast(bsp::battery_charger::batteryINTBSource::maxTemp) | + static_cast(bsp::battery_charger::batteryINTBSource::minTemp)); + bsp::battery_charger::checkTemperatureRange(); + auto message = std::make_shared(); + message->plugged = bsp::battery_charger::getChargeStatus(); + service->bus.sendUnicast(std::move(message), service::name::evt_manager); + } } - service->bus.sendUnicast(message, service::name::evt_manager); } } diff --git a/module-services/service-evtmgr/doc/charger_temperature_cutoff.md b/module-services/service-evtmgr/doc/charger_temperature_cutoff.md new file mode 100644 index 0000000000000000000000000000000000000000..a4a3776430d7f70ba31ee36ba36a1911e683d28b --- /dev/null +++ b/module-services/service-evtmgr/doc/charger_temperature_cutoff.md @@ -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: + +![](charger_temperature_cutoff.svg "Charging cutoff") + +Additional 1 Cdeg hysteresis was introduced to prevent rapid changes in charging state. \ No newline at end of file diff --git a/module-services/service-evtmgr/doc/charger_temperature_cutoff.puml b/module-services/service-evtmgr/doc/charger_temperature_cutoff.puml new file mode 100644 index 0000000000000000000000000000000000000000..2edb132179bb854920ba9a57234bf17de95a2d37 --- /dev/null +++ b/module-services/service-evtmgr/doc/charger_temperature_cutoff.puml @@ -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 + diff --git a/module-services/service-evtmgr/doc/charger_temperature_cutoff.svg b/module-services/service-evtmgr/doc/charger_temperature_cutoff.svg new file mode 100644 index 0000000000000000000000000000000000000000..4904d3946459521c71da546ad1f36ac5b7b363c2 --- /dev/null +++ b/module-services/service-evtmgr/doc/charger_temperature_cutoff.svg @@ -0,0 +1,31 @@ +measurementteperature rangeviolation interruptcharger Onset normalinterrupt boundscharger offset interruptbounds with 1Cdeg hysteresisinitializationDetected rangeT = 1~45 CdegT<=0 CdegT>45 Cdeg \ No newline at end of file