M enabled_unittests => enabled_unittests +4 -2
@@ 463,6 463,8 @@ TESTS_LIST["catch2-unittest_ATURCStream"]="
URC AT Stream Parser;
"
#---------
-
-
+TESTS_LIST["catch2-module-bsp"]="
+ BatteryChargerUtilsTest;
+"
+#---------
M module-bsp/CMakeLists.txt => module-bsp/CMakeLists.txt +3 -0
@@ 94,3 94,6 @@ target_link_libraries(${PROJECT_NAME}
${TARGET_LIBRARIES}
)
+if (${ENABLE_TESTS})
+ add_subdirectory(tests)
+endif ()
M module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp => module-bsp/board/rt1051/bsp/battery-charger/MAX77818.hpp +7 -0
@@ 176,10 176,17 @@ namespace bsp::battery_charger
// CHG_CNFG_02 register
enum class ChargeCurrentLimit
{
+ lim300mA = 0x06, /// est. 0.2C of battery
lim450mA = 0x09, /// default
lim1600mA = 0x20, /// 1C of battery
};
+ enum class ChargeTerminationVoltage
+ {
+ mV4100 = 0x12, /// 4.1V
+ mV4350 = 0x1D, /// 4.35V nominal battery voltage
+ };
+
// 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 +81 -55
@@ 11,8 11,9 @@
#include "drivers/i2c/DriverI2C.hpp"
#include <purefs/filesystem_paths.hpp>
#include <utility>
-#include <bitset>
#include <fstream>
+#include <map>
+#include "battery_charger_utils.hpp"
namespace bsp::battery_charger
{
@@ 23,25 24,18 @@ namespace bsp::battery_charger
const auto cfgFile = purefs::dir::getUserDiskPath() / "batteryFuelGaugeConfig.cfg";
constexpr auto registersToStore = 0xFF + 1;
- constexpr std::uint16_t ENABLE_ALL_IRQ_MASK = 0xF8;
+ constexpr std::uint16_t ENABLE_CHG_FG_IRQ_MASK = 0xFC;
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
constexpr std::uint16_t nominalCapacitymAh = 1600;
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;
@@ 84,11 78,36 @@ namespace bsp::battery_charger
enum class TemperatureRanges
{
- normal,
- cold,
- hot
+ Cold,
+ Cdeg1to15,
+ Cdeg15to35,
+ Cdeg35to45,
+ Hot
};
+ struct TemparatureThresholds
+ {
+ int lowTemperatureThreshold;
+ int highTemperatureThreshold;
+ std::uint8_t alertLow;
+ std::uint8_t alertHigh;
+ };
+
+ constexpr std::uint8_t maxAlertDisabled{0x7F};
+ constexpr std::uint8_t minAlertDisabled{0x80};
+
+ // INT is triggered if T>=maxThreshold || T<minThreshold
+ constexpr std::uint8_t lowHysteresis{1};
+ constexpr std::uint8_t highHysteresis{2};
+
+ const std::map<TemperatureRanges, TemparatureThresholds> temperatureRanges{
+ {TemperatureRanges::Cold, {std::numeric_limits<std::int8_t>::min(), 1, minAlertDisabled, 1}},
+ {TemperatureRanges::Cdeg1to15, {1, 15, 0, 15 + highHysteresis}},
+ {TemperatureRanges::Cdeg15to35, {15, 35, 15 - lowHysteresis, 35 + highHysteresis}},
+ {TemperatureRanges::Cdeg35to45, {35, 45, 35 - lowHysteresis, 45 + highHysteresis}},
+ {TemperatureRanges::Hot,
+ {45, std::numeric_limits<std::int8_t>::max(), 45 - lowHysteresis, maxAlertDisabled}}};
+
std::shared_ptr<drivers::DriverI2C> i2c;
std::shared_ptr<drivers::DriverGPIO> gpio;
@@ 221,6 240,16 @@ namespace bsp::battery_charger
lockProtectedChargerRegisters();
}
+ void setChargeTargetVoltage(ChargeTerminationVoltage voltage)
+ {
+ unlockProtectedChargerRegisters();
+ std::uint8_t value = static_cast<std::uint8_t>(voltage) | VSYS_MIN;
+ if (chargerWrite(Registers::CHG_CNFG_04, value) != kStatus_Success) {
+ LOG_ERROR("Charge target voltage write fail");
+ }
+ lockProtectedChargerRegisters();
+ }
+
void resetUSBCurrrentLimit()
{
LOG_INFO("USB current limit set to 500mA");
@@ 229,15 258,7 @@ namespace bsp::battery_charger
void configureBatteryCharger()
{
- unlockProtectedChargerRegisters();
-
- std::uint8_t value = CHARGE_TARGET_VOLTAGE | VSYS_MIN;
- if (chargerWrite(Registers::CHG_CNFG_04, value) != kStatus_Success) {
- LOG_ERROR("Charge target voltage write fail");
- }
-
- lockProtectedChargerRegisters();
-
+ setChargeTargetVoltage(ChargeTerminationVoltage::mV4350);
resetUSBCurrrentLimit();
setMaxChargeCurrent(ChargeCurrentLimit::lim1600mA);
}
@@ 355,10 376,9 @@ namespace bsp::battery_charger
return batteryRetval::OK;
}
*/
- batteryRetval setTemperatureThresholds(std::uint8_t maxTemperatureDegrees, std::uint8_t minTemperatureDegrees)
+ batteryRetval setTemperatureThresholds(std::uint8_t minTemperatureDegrees, std::uint8_t maxTemperatureDegrees)
{
- std::uint16_t regVal = (maxTemperatureDegrees << 8) | minTemperatureDegrees;
-
+ std::uint16_t regVal = (static_cast<uint16_t>(maxTemperatureDegrees) << 8) | minTemperatureDegrees;
if (fuelGaugeWrite(Registers::TALRT_Th_REG, regVal) != kStatus_Success) {
LOG_ERROR("setTemperatureThresholds failed.");
return batteryRetval::ChargerError;
@@ 419,7 439,7 @@ namespace bsp::battery_charger
batteryRetval enableTopIRQs()
{
- std::uint8_t val = ENABLE_ALL_IRQ_MASK;
+ std::uint8_t val = ENABLE_CHG_FG_IRQ_MASK;
if (chargerTopControllerWrite(Registers::TOP_CONTROLL_IRQ_MASK_REG, val) != kStatus_Success) {
LOG_ERROR("enableIRQs failed.");
@@ 461,11 481,9 @@ namespace bsp::battery_charger
int getCellTemperature()
{
auto value = fuelGaugeRead(Registers::TEMP_REG);
- int temperature = value.second >> 8;
- if (value.second & 0x8000) {
- temperature *= -1;
- }
- return temperature;
+ // Round to integer by stripping fractions
+ std::uint8_t temperatureInt = value.second >> 8;
+ return utils::twosComplimentToInt(temperatureInt);
}
/*
int getCurrentMeasurement()
@@ 503,22 521,36 @@ namespace bsp::battery_charger
void processTemperatureRange(TemperatureRanges temperatureRange)
{
switch (temperatureRange) {
- case TemperatureRanges::normal:
- LOG_DEBUG("Normal temperature range, charging enabled.");
+ case TemperatureRanges::Cdeg1to15:
+ LOG_DEBUG("1 to 15 cell temperature range");
+ enableCharging();
+ setChargeTargetVoltage(ChargeTerminationVoltage::mV4350);
+ setMaxChargeCurrent(ChargeCurrentLimit::lim300mA);
+ break;
+ case TemperatureRanges::Cdeg15to35:
+ LOG_DEBUG("15 to 35 cell temperature range");
+ enableCharging();
+ setChargeTargetVoltage(ChargeTerminationVoltage::mV4350);
+ setMaxChargeCurrent(ChargeCurrentLimit::lim1600mA);
+ break;
+ case TemperatureRanges::Cdeg35to45:
+ LOG_DEBUG("35 to 45 cell temperature range");
enableCharging();
- setTemperatureThresholds(maxTemperatureDegrees, minTemperatureDegrees);
+ setChargeTargetVoltage(ChargeTerminationVoltage::mV4100);
+ setMaxChargeCurrent(ChargeCurrentLimit::lim1600mA);
break;
- case TemperatureRanges::cold:
- LOG_DEBUG("Temperature too low, charging disabled.");
+ case TemperatureRanges::Cold:
+ LOG_DEBUG("Cell temperature too low, charging disabled.");
disableCharging();
- setTemperatureThresholds(minTemperatureDegrees + temperatureHysteresis, minDisabled);
break;
- case TemperatureRanges::hot:
- LOG_DEBUG("Temperature too high, charging disabled.");
+ case TemperatureRanges::Hot:
+ LOG_DEBUG("Cell temperature too high, charging disabled.");
disableCharging();
- setTemperatureThresholds(maxDisabled, maxTemperatureDegrees - temperatureHysteresis);
break;
}
+
+ setTemperatureThresholds(temperatureRanges.at(temperatureRange).alertLow,
+ temperatureRanges.at(temperatureRange).alertHigh);
}
} // namespace
@@ 543,7 575,6 @@ namespace bsp::battery_charger
loadConfiguration();
}
- setTemperatureThresholds(maxTemperatureDegrees, minTemperatureDegrees);
setServiceVoltageThresholds(maxVoltagemV, minVoltagemV);
fillConfigRegisterValue();
@@ 566,6 597,7 @@ namespace bsp::battery_charger
void deinit()
{
+ resetUSBCurrrentLimit();
storeConfiguration();
gpio->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BATTERY_CHARGER_INTB_PIN));
@@ 662,21 694,16 @@ namespace bsp::battery_charger
void checkTemperatureRange()
{
- 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);
+ for (const auto &[range, thresholds] : temperatureRanges) {
+ if ((temperature > thresholds.lowTemperatureThreshold) &&
+ (temperature <= thresholds.highTemperatureThreshold)) {
+ processTemperatureRange(range);
+ break;
+ }
+ }
}
std::uint8_t getTopControllerINTSource()
@@ 700,9 727,8 @@ namespace bsp::battery_charger
case batteryChargerType::DcdCDP:
[[fallthrough]];
case batteryChargerType::DcdDCP:
- // TODO: Uncomment when temerature ranges protection implemented
- // LOG_INFO("USB current limit set to 1000mA");
- // setMaxBusCurrent(USBCurrentLimit::lim1000mA);
+ LOG_INFO("USB current limit set to 1000mA");
+ setMaxBusCurrent(USBCurrentLimit::lim1000mA);
break;
}
}
A module-bsp/board/rt1051/bsp/battery-charger/battery_charger_utils.hpp => module-bsp/board/rt1051/bsp/battery-charger/battery_charger_utils.hpp +23 -0
@@ 0,0 1,23 @@
+// 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 <bitset>
+
+namespace bsp::battery_charger::utils
+{
+ template <typename T> int twosComplimentToInt(T toConvert)
+ {
+ constexpr auto bitSize = sizeof(T) * 8;
+ std::bitset<bitSize> bitset{toConvert};
+
+ if (bitset[bitSize - 1]) {
+ bitset = std::bitset<bitSize>(toConvert - 1);
+ bitset.flip();
+ return static_cast<int>(bitset.to_ulong() * -1);
+ }
+ else {
+ return static_cast<int>(toConvert);
+ }
+ }
+} // namespace bsp::battery_charger::utils
A module-bsp/tests/CMakeLists.txt => module-bsp/tests/CMakeLists.txt +9 -0
@@ 0,0 1,9 @@
+add_catch2_executable(
+ NAME
+ module-bsp
+ SRCS
+ tests-main.cpp
+ test-battery-charger-utils.cpp
+ LIBS
+ module-bsp
+)
A module-bsp/tests/test-battery-charger-utils.cpp => module-bsp/tests/test-battery-charger-utils.cpp +38 -0
@@ 0,0 1,38 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <catch2/catch.hpp>
+#include <module-bsp/board/rt1051/bsp/battery-charger/battery_charger_utils.hpp>
+
+TEST_CASE("BatteryChargerUtilsTest")
+{
+ SECTION("2s compliment conversion test")
+ {
+ constexpr std::array uint8Fixtures = {std::make_pair<std::uint8_t, int>(0x00, 0),
+ std::make_pair<std::uint8_t, int>(0x80, -128),
+ std::make_pair<std::uint8_t, int>(0xFF, -1),
+ std::make_pair<std::uint8_t, int>(0x7F, 127)};
+
+ constexpr std::array uint16Fixtures = {std::make_pair<std::uint16_t, int>(0x0000, 0),
+ std::make_pair<std::uint16_t, int>(0x8000, -32768),
+ std::make_pair<std::uint16_t, int>(0xFFFF, -1),
+ std::make_pair<std::uint16_t, int>(0x7FFF, 32767)};
+
+ constexpr std::array uint32Fixtures = {std::make_pair<std::uint32_t, int>(0x00000000, 0),
+ std::make_pair<std::uint32_t, int>(0x80000000, -2147483648),
+ std::make_pair<std::uint32_t, int>(0xFFFFFFFF, -1),
+ std::make_pair<std::uint32_t, int>(0x7FFFFFFF, 2147483647)};
+
+ for (const auto &fixture : uint8Fixtures) {
+ CHECK(bsp::battery_charger::utils::twosComplimentToInt(fixture.first) == fixture.second);
+ }
+
+ for (const auto &fixture : uint16Fixtures) {
+ CHECK(bsp::battery_charger::utils::twosComplimentToInt(fixture.first) == fixture.second);
+ }
+
+ for (const auto &fixture : uint32Fixtures) {
+ CHECK(bsp::battery_charger::utils::twosComplimentToInt(fixture.first) == fixture.second);
+ }
+ }
+}
A module-bsp/tests/tests-main.cpp => module-bsp/tests/tests-main.cpp +5 -0
@@ 0,0 1,5 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
+#include <catch2/catch.hpp>
M module-services/service-evtmgr/doc/USB_current_selection.puml => module-services/service-evtmgr/doc/USB_current_selection.puml +2 -2
@@ 5,9 5,9 @@
If "Detected USB type" then
---> [SDP] "Limit 500mA"
else
- -> [CDP] "Limit 1500mA"
+ -> [CDP] "Limit 1000mA"
else
- --> [DCP] "Limit 1500mA"
+ --> [DCP] "Limit 1000mA"
Endif
"USB unplugged" --> "Limit 500mA"
M module-services/service-evtmgr/doc/USB_current_selection.svg => module-services/service-evtmgr/doc/USB_current_selection.svg +7 -7
@@ 1,11 1,11 @@
-<?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="282px" preserveAspectRatio="none" style="width:455px;height:282px;" version="1.1" viewBox="0 0 455 282" width="455px" zoomAndPan="magnify"><defs><filter height="300%" id="f12kntt60xghcw" 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="124" cy="252" fill="#000000" filter="url(#f12kntt60xghcw)" rx="10" ry="10" style="stroke:none;stroke-width:1.0;"/><rect fill="#FEFECE" filter="url(#f12kntt60xghcw)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="95" x="221.5" y="235"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="75" x="231.5" y="256.1387">Limit 500mA</text><rect fill="#FEFECE" filter="url(#f12kntt60xghcw)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="100" x="7" y="7"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="80" x="17" y="28.1387">USB plugged</text><rect fill="#FEFECE" filter="url(#f12kntt60xghcw)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="151" x="127.5" y="7"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="131" x="137.5" y="28.1387">USB type recognition</text><polygon fill="#FEFECE" filter="url(#f12kntt60xghcw)" points="203,82,215,94,203,106,191,94,203,82" style="stroke:#A80036;stroke-width:1.5;"/><rect fill="#FEFECE" filter="url(#f12kntt60xghcw)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="103" x="201.5" y="160"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="83" x="211.5" y="181.1387">Limit 1500mA</text><rect fill="#FEFECE" filter="url(#f12kntt60xghcw)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="116" x="325" y="160"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="335" y="181.1387">USB unplugged</text><!--MD5=[4efa0ceb8d869b0f02c9d84720c80e93]
+<?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="282px" preserveAspectRatio="none" style="width:455px;height:282px;" version="1.1" viewBox="0 0 455 282" width="455px" zoomAndPan="magnify"><defs><filter height="300%" id="f11qz7rz3vrzfa" 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="124" cy="252" fill="#000000" filter="url(#f11qz7rz3vrzfa)" rx="10" ry="10" style="stroke:none;stroke-width:1.0;"/><rect fill="#FEFECE" filter="url(#f11qz7rz3vrzfa)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="95" x="221.5" y="235"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="75" x="231.5" y="256.1387">Limit 500mA</text><rect fill="#FEFECE" filter="url(#f11qz7rz3vrzfa)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="100" x="7" y="7"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="80" x="17" y="28.1387">USB plugged</text><rect fill="#FEFECE" filter="url(#f11qz7rz3vrzfa)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="151" x="127.5" y="7"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="131" x="137.5" y="28.1387">USB type recognition</text><polygon fill="#FEFECE" filter="url(#f11qz7rz3vrzfa)" points="203,82,215,94,203,106,191,94,203,82" style="stroke:#A80036;stroke-width:1.5;"/><rect fill="#FEFECE" filter="url(#f11qz7rz3vrzfa)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="103" x="201.5" y="160"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="83" x="211.5" y="181.1387">Limit 1000mA</text><rect fill="#FEFECE" filter="url(#f11qz7rz3vrzfa)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="116" x="325" y="160"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="96" x="335" y="181.1387">USB unplugged</text><!--MD5=[4efa0ceb8d869b0f02c9d84720c80e93]
link start to Limit 500mA--><path d="M134.43,252 C151.43,252 186.24,252 216.2,252 " fill="none" id="start-to-Limit 500mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="221.34,252,212.34,248,216.34,252,212.34,256,221.34,252" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="66" x="144.75" y="246.2104">initialization</text><!--MD5=[04d55dba39d9a0eb7d067c791539fcd8]
link USB plugged to USB type recognition--><path d="M107.19,24 C112.24,24 117.29,24 122.35,24 " fill="none" id="USB plugged-to-USB type recognition" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="127.4,24,118.4,20,122.4,24,118.4,28,127.4,24" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[36317cad5e94ba9bb427f52905fd2925]
link USB type recognition to #8--><path d="M203,41.12 C203,51.92 203,66.08 203,76.88 " fill="none" id="USB type recognition-to-#8" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="203,81.89,207,72.89,203,76.89,199,72.89,203,81.89" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="106" x="76.7938" y="73.3494">Detected USB type</text><!--MD5=[8b72c5e5407284ef9afe374b980984ef]
-link #8 to Limit 500mA--><path d="M197.54,100.67 C183.16,116.32 146.62,161.12 166,194 C177.15,212.91 197.07,225.98 216.44,234.79 " fill="none" id="#8-to-Limit 500mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="221.35,236.94,214.6995,229.6756,216.7669,234.9412,211.5014,237.0085,221.35,236.94" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="23" x="167" y="181.2104">SDP</text><!--MD5=[b5dd0bbf25620b4138b920210523f638]
-link #8 to Limit 1500mA--><path d="M200.74,103.84 C198.8,113.34 197.16,128.6 203,140 C206.33,146.5 211.44,152.09 217.14,156.8 " fill="none" id="#8-to-Limit 1500mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="221.16,159.91,216.4833,151.2423,217.2033,156.8532,211.5924,157.5731,221.16,159.91" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="23" x="204" y="137.2104">CDP</text><!--MD5=[b5dd0bbf25620b4138b920210523f638]
-link #8 to Limit 1500mA--><path d="M208.66,100.82 C214.28,106.81 222.91,116.55 229,126 C234.87,135.1 240.21,145.84 244.35,155.04 " fill="none" id="#8-to-Limit 1500mA-1" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="246.41,159.69,246.4415,149.8412,244.3939,155.1145,239.1206,153.0669,246.41,159.69" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="23" x="238" y="137.2104">DCP</text><!--MD5=[96c530ca5284f63feb7182093e557ed9]
-link USB unplugged to Limit 500mA--><path d="M357.98,194.02 C340.58,205.16 317.3,220.07 298.92,231.84 " fill="none" id="USB unplugged-to-Limit 500mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="294.35,234.76,304.0859,233.2729,298.5601,232.0627,299.7703,226.5368,294.35,234.76" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[83154e0bea18ea5a1fea1a60710e90e5]
+link #8 to Limit 500mA--><path d="M197.54,100.67 C183.16,116.32 146.62,161.12 166,194 C177.15,212.91 197.07,225.98 216.44,234.79 " fill="none" id="#8-to-Limit 500mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="221.35,236.94,214.6995,229.6756,216.7669,234.9412,211.5014,237.0085,221.35,236.94" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="23" x="167" y="181.2104">SDP</text><!--MD5=[89706890e51c0f4911fc05b88ff306cf]
+link #8 to Limit 1000mA--><path d="M200.74,103.84 C198.8,113.34 197.16,128.6 203,140 C206.33,146.5 211.44,152.09 217.14,156.8 " fill="none" id="#8-to-Limit 1000mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="221.16,159.91,216.4833,151.2423,217.2033,156.8532,211.5924,157.5731,221.16,159.91" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="23" x="204" y="137.2104">CDP</text><!--MD5=[89706890e51c0f4911fc05b88ff306cf]
+link #8 to Limit 1000mA--><path d="M208.66,100.82 C214.28,106.81 222.91,116.55 229,126 C234.87,135.1 240.21,145.84 244.35,155.04 " fill="none" id="#8-to-Limit 1000mA-1" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="246.41,159.69,246.4415,149.8412,244.3939,155.1145,239.1206,153.0669,246.41,159.69" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="23" x="238" y="137.2104">DCP</text><!--MD5=[96c530ca5284f63feb7182093e557ed9]
+link USB unplugged to Limit 500mA--><path d="M357.98,194.02 C340.58,205.16 317.3,220.07 298.92,231.84 " fill="none" id="USB unplugged-to-Limit 500mA" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="294.35,234.76,304.0859,233.2729,298.5601,232.0627,299.7703,226.5368,294.35,234.76" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[46b2be1c205d9fe7ebe069df19495ff0]
@startuml
(*) -> [initialization] "Limit 500mA"
@@ 13,9 13,9 @@ link USB unplugged to Limit 500mA--><path d="M357.98,194.02 C340.58,205.16 317.3
If "Detected USB type" then
- - -> [SDP] "Limit 500mA"
else
- -> [CDP] "Limit 1500mA"
+ -> [CDP] "Limit 1000mA"
else
- - -> [DCP] "Limit 1500mA"
+ - -> [DCP] "Limit 1000mA"
Endif
"USB unplugged" - -> "Limit 500mA"
M module-services/service-evtmgr/doc/battery_charging.md => module-services/service-evtmgr/doc/battery_charging.md +12 -5
@@ 29,16 29,23 @@ Default current limit of a charger to draw from USB port is 500mA. Due to severa
- Charging downstream port (CDP)
- Dedicated charging port (DCP)
-PureOS limits the bus current to 500mA, in case of SDP, and to 1500mA in case of CDP and DCP. USB type recognition is part of the USB stack.
+PureOS limits the bus current to 500mA, in case of SDP, and to 1000mA in case of CDP and DCP. USB type recognition is part of the USB stack.

## 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.
+In order to prevent fast battery cell degradation, charging action needs to be controlled in specific temperature ranges. Given requirements from battery specification:
+- 1 to 15 Cdeg : 0.2C current limit
+- 15 to 35 Cdeg : 1C current limit
+- 35 to 45 Cdeg : 4.1V charging voltage
-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:
+For battery in the system value of 1C equals 1600mA.
-
+**NOTE: Charging current limit has lower priority than USB current limit. Therefore, final charging current will be lower than USB current.**
-Additional 1 Cdeg hysteresis was introduced to prevent rapid changes in charging state.>
\ No newline at end of file
+Implementation 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 2 Cdeg hysteresis was introduced to prevent rapid changes in charging states.<
\ No newline at end of file
A module-services/service-evtmgr/doc/charger_temperature_algorithm.puml => module-services/service-evtmgr/doc/charger_temperature_algorithm.puml +21 -0
@@ 0,0 1,21 @@
+@startuml
+(*) --> [initialization] "measurement" as meas
+"teperature range\n violation interrupt" -> meas
+If "Detected range" then
+ ---> [T<=0 Cdeg] "charger off" as coff
+ --> "set interrupt\nbounds with hysteresis" as sh
+ else
+ --> [T>45 Cdeg] coff
+ else
+ ---> [T = 1~15 Cdeg] "Charging: \nCC 300mA\nCV 4.35V"
+ -> "charger On" as con
+ else
+ ---> [T = 15~35 Cdeg] "Charging: \nCC 1600mA\nCV 4.35V"
+ --> con
+ else
+ ---> [T = 35~45 Cdeg] "Charging: \nCC 1600mA\nCV 4.1V"
+ -> con
+Endif
+con -> sh
+@enduml
+
A module-services/service-evtmgr/doc/charger_temperature_algorithm.svg => module-services/service-evtmgr/doc/charger_temperature_algorithm.svg +43 -0
@@ 0,0 1,43 @@
+<?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="514px" preserveAspectRatio="none" style="width:571px;height:514px;" version="1.1" viewBox="0 0 571 514" width="571px" zoomAndPan="magnify"><defs><filter height="300%" id="foarmiu62vpl5" 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="287.5" cy="16" fill="#000000" filter="url(#foarmiu62vpl5)" rx="10" ry="10" style="stroke:none;stroke-width:1.0;"/><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="107" x="234" y="87"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="87" x="244" y="108.1387">measurement</text><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="47.9375" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="135" x="79" y="80"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="109" x="92" y="101.1387">teperature range</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="111" x="93" y="115.1074">violation interrupt</text><polygon fill="#FEFECE" filter="url(#foarmiu62vpl5)" points="287.5,169,299.5,181,287.5,193,275.5,181,287.5,169" style="stroke:#A80036;stroke-width:1.5;"/><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="89" x="379" y="303"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="69" x="389" y="324.1387">charger off</text><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="47.9375" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="164" x="254.5" y="453"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="79" x="297" y="474.1387">set interrupt</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="144" x="264.5" y="488.1074">bounds with hysteresis</text><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="61.9063" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="84" x="125.5" y="371"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="60" x="135.5" y="392.1387">Charging:</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="63" x="136" y="406.1074">CC 300mA</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="56" x="139.5" y="420.0762">CV 4.35V</text><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="33.9688" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="90" x="126.5" y="460"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="70" x="136.5" y="481.1387">charger On</text><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="61.9063" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="91" x="241" y="289"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="60" x="254.5" y="310.1387">Charging:</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="71" x="251" y="324.1074">CC 1600mA</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="56" x="258.5" y="338.0762">CV 4.35V</text><rect fill="#FEFECE" filter="url(#foarmiu62vpl5)" height="61.9063" rx="12.5" ry="12.5" style="stroke:#A80036;stroke-width:1.5;" width="91" x="7" y="371"/><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="60" x="20.5" y="392.1387">Charging:</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="71" x="17" y="406.1074">CC 1600mA</text><text fill="#000000" font-family="sans-serif" font-size="12" lengthAdjust="spacing" textLength="48" x="28.5" y="420.0762">CV 4.1V</text><!--MD5=[11b5d1c84b2a4e74ea342f7993200deb]
+link start to meas--><path d="M287.5,26.2 C287.5,39.32 287.5,63.77 287.5,81.57 " fill="none" id="start-to-meas" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="287.5,86.86,291.5,77.86,287.5,81.86,283.5,77.86,287.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="288.5" y="57.2104">initialization</text><!--MD5=[4450667bc073f2b45b1fdac68f3e6f8a]
+link teperature range\n violation interrupt to meas--><path d="M214.25,104 C219.08,104 223.91,104 228.75,104 " fill="none" id="teperature range\n violation interrupt-to-meas" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="233.99,104,224.99,100,228.99,104,224.99,108,233.99,104" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[077487f9f2e8a10fc24dfcbca2bf789f]
+link meas to #7--><path d="M287.5,121.27 C287.5,133.79 287.5,151.01 287.5,163.56 " fill="none" id="meas-to-#7" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="287.5,168.63,291.5,159.63,287.5,163.63,283.5,159.63,287.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="180.3813" y="158.5304">Detected range</text><!--MD5=[129a0a37766bd6af2b3bfd9a065c831e]
+link #7 to coff--><path d="M297.74,182.86 C336.15,186.31 470.7,200.66 493.5,234 C509.83,257.86 482.43,283.2 457.27,299.94 " fill="none" id="#7-to-coff" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="452.93,302.76,462.6563,301.2112,457.1229,300.0361,458.298,294.5026,452.93,302.76" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="65" x="498.5" y="245.2104">T<=0 Cdeg</text><!--MD5=[129a0a37766bd6af2b3bfd9a065c831e]
+link #7 to coff--><path d="M296.34,184.29 C315.65,189.71 361.95,205.1 388.5,234 C405.08,252.05 414.36,279.03 419.14,297.73 " fill="none" id="#7-to-coff-1" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="420.37,302.77,422.1215,293.0781,419.1842,297.9126,414.3497,294.9754,420.37,302.77" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="63" x="399.5" y="245.2104">T>45 Cdeg</text><!--MD5=[c92698de465e82c79cce2754d2ab17d3]
+link coff to sh--><path d="M414.52,337 C399.79,363.25 370.32,415.75 352.11,448.19 " fill="none" id="coff-to-sh" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="349.51,452.82,357.4151,446.9455,351.9661,448.4648,350.4467,443.0158,349.51,452.82" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[4d006b7ef9043e6b5a2232c14858730a]
+link #7 to Charging: \nCC 300mA\nCV 4.35V--><path d="M278.47,184.14 C259.32,189.18 214.65,203.73 193.5,234 C166.26,272.97 163.09,329.51 164.43,365.77 " fill="none" id="#7-to-Charging: \nCC 300mA\nCV 4.35V" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="164.66,370.97,168.2448,361.7967,164.4317,365.9752,160.2532,362.1621,164.66,370.97" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="87" x="194.5" y="245.2104">T = 1~15 Cdeg</text><!--MD5=[439463d568db46a6e11f6b533f48af37]
+link Charging: \nCC 300mA\nCV 4.35V to con--><path d="M169.15,433.11 C169.54,440.23 169.95,447.68 170.31,454.34 " fill="none" id="Charging: \nCC 300mA\nCV 4.35V-to-con" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="170.61,459.73,174.1148,450.5259,170.3382,454.7374,166.1267,450.9608,170.61,459.73" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[383e9b22b311da0a0a996560d8232493]
+link #7 to Charging: \nCC 1600mA\nCV 4.35V--><path d="M287.42,193.21 C287.28,212.78 286.97,253.95 286.76,283.88 " fill="none" id="#7-to-Charging: \nCC 1600mA\nCV 4.35V" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="286.72,288.95,290.7714,279.973,286.7486,283.9501,282.7715,279.9273,286.72,288.95" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="94" x="288.5" y="245.2104">T = 15~35 Cdeg</text><!--MD5=[46f191a4e04ffd070c0f7e5546c45e6d]
+link Charging: \nCC 1600mA\nCV 4.35V to con--><path d="M271.68,351.13 C259.38,374.64 240.55,407.48 219.5,433 C212.65,441.31 204.16,449.45 196.24,456.37 " fill="none" id="Charging: \nCC 1600mA\nCV 4.35V-to-con" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="192.41,459.67,201.8412,456.8323,196.2002,456.409,196.6236,450.768,192.41,459.67" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[61891354fe19934057955d8d6f0c581c]
+link #7 to Charging: \nCC 1600mA\nCV 4.1V--><path d="M277.52,183.17 C240.61,187.69 112.67,205.24 85.5,234 C52.23,269.22 48.04,327.82 49.33,365.41 " fill="none" id="#7-to-Charging: \nCC 1600mA\nCV 4.1V" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="49.55,370.79,53.161,361.627,49.3359,365.7946,45.1683,361.9695,49.55,370.79" style="stroke:#A80036;stroke-width:1.0;"/><text fill="#000000" font-family="sans-serif" font-size="11" lengthAdjust="spacing" textLength="94" x="86.5" y="245.2104">T = 35~45 Cdeg</text><!--MD5=[ab18e15750f6c47341cd05412a31baf4]
+link Charging: \nCC 1600mA\nCV 4.1V to con--><path d="M98.17,431.01 C112.54,439.83 128.04,449.34 141.08,457.34 " fill="none" id="Charging: \nCC 1600mA\nCV 4.1V-to-con" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="145.4,459.99,139.8117,451.88,141.1354,457.3799,135.6355,458.7035,145.4,459.99" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[35204544fa74a7de4684b90de9f0b6f0]
+link con to sh--><path d="M216.62,477 C227.35,477 238.08,477 248.81,477 " fill="none" id="con-to-sh" style="stroke:#A80036;stroke-width:1.0;"/><polygon fill="#A80036" points="254.08,477,245.08,473,249.08,477,245.08,481,254.08,477" style="stroke:#A80036;stroke-width:1.0;"/><!--MD5=[d8f61ef04fae53f9eb7402cb27a4484c]
+@startuml
+(*) - -> [initialization] "measurement" as meas
+"teperature range\n violation interrupt" -> meas
+If "Detected range" then
+ - - -> [T<=0 Cdeg] "charger off" as coff
+ - -> "set interrupt\nbounds with hysteresis" as sh
+ else
+ - -> [T>45 Cdeg] coff
+ else
+ - - -> [T = 1~15 Cdeg] "Charging: \nCC 300mA\nCV 4.35V"
+ -> "charger On" as con
+ else
+ - - -> [T = 15~35 Cdeg] "Charging: \nCC 1600mA\nCV 4.35V"
+ - -> con
+ else
+ - - -> [T = 35~45 Cdeg] "Charging: \nCC 1600mA\nCV 4.1V"
+ -> con
+Endif
+con -> sh
+@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
D module-services/service-evtmgr/doc/charger_temperature_cutoff.puml => module-services/service-evtmgr/doc/charger_temperature_cutoff.puml +0 -14
@@ 1,14 0,0 @@
-@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
-
D module-services/service-evtmgr/doc/charger_temperature_cutoff.svg => module-services/service-evtmgr/doc/charger_temperature_cutoff.svg +0 -31
@@ 1,31 0,0 @@
-<?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