FuriHal, Power, UnitTests: fix, rename battery charging voltage limit API (#2228)
* FuriHal, Power, UnitTests: rename battery charge voltage limit API * FuriHal: bump API, power info major versions * Power: fix battery charge voltage limit for > 7.935v Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									1d55aee39c
								
							
						
					
					
						commit
						09edf66a2a
					
				| @ -3,56 +3,63 @@ | |||||||
| #include "../minunit.h" | #include "../minunit.h" | ||||||
| 
 | 
 | ||||||
| static void power_test_deinit(void) { | static void power_test_deinit(void) { | ||||||
|     // Try to reset to default charging voltage
 |     // Try to reset to default charge voltage limit
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(4.208f); |     furi_hal_power_set_battery_charge_voltage_limit(4.208f); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(test_power_charge_voltage_exact) { | MU_TEST(test_power_charge_voltage_limit_exact) { | ||||||
|     // Power of 16mV charge voltages get applied exactly
 |     // Power of 16mV charge voltage limits get applied exactly
 | ||||||
|     // (bq25896 charge controller works in 16mV increments)
 |     // (bq25896 charge controller works in 16mV increments)
 | ||||||
|     //
 |     //
 | ||||||
|     // This test may need adapted if other charge controllers are used in the future.
 |     // This test may need adapted if other charge controllers are used in the future.
 | ||||||
|     for(uint16_t charge_mv = 3840; charge_mv <= 4208; charge_mv += 16) { |     for(uint16_t charge_mv = 3840; charge_mv <= 4208; charge_mv += 16) { | ||||||
|         float charge_volt = (float)charge_mv / 1000.0f; |         float charge_volt = (float)charge_mv / 1000.0f; | ||||||
|         furi_hal_power_set_battery_charging_voltage(charge_volt); |         furi_hal_power_set_battery_charge_voltage_limit(charge_volt); | ||||||
|         mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charging_voltage()); |         mu_assert_double_eq(charge_volt, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(test_power_charge_voltage_floating_imprecision) { | MU_TEST(test_power_charge_voltage_limit_floating_imprecision) { | ||||||
|     // 4.016f should act as 4.016 V, even with floating point imprecision
 |     // 4.016f should act as 4.016 V, even with floating point imprecision
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(4.016f); |     furi_hal_power_set_battery_charge_voltage_limit(4.016f); | ||||||
|     mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charging_voltage()); |     mu_assert_double_eq(4.016f, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(test_power_charge_voltage_inexact) { | MU_TEST(test_power_charge_voltage_limit_inexact) { | ||||||
|     // Charge voltages that are not power of 16mV get truncated down
 |     // Charge voltage limits that are not power of 16mV get truncated down
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(3.841f); |     furi_hal_power_set_battery_charge_voltage_limit(3.841f); | ||||||
|     mu_assert_double_eq(3.840, furi_hal_power_get_battery_charging_voltage()); |     mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
| 
 | 
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(3.900f); |     furi_hal_power_set_battery_charge_voltage_limit(3.900f); | ||||||
|     mu_assert_double_eq(3.888, furi_hal_power_get_battery_charging_voltage()); |     mu_assert_double_eq(3.888, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
| 
 | 
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(4.200f); |     furi_hal_power_set_battery_charge_voltage_limit(4.200f); | ||||||
|     mu_assert_double_eq(4.192, furi_hal_power_get_battery_charging_voltage()); |     mu_assert_double_eq(4.192, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(test_power_charge_voltage_invalid_clamped) { | MU_TEST(test_power_charge_voltage_limit_invalid_clamped) { | ||||||
|     // Out-of-range charge voltages get clamped to 3.840 V and 4.208 V
 |     // Out-of-range charge voltage limits get clamped to 3.840 V and 4.208 V
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(3.808f); |     furi_hal_power_set_battery_charge_voltage_limit(3.808f); | ||||||
|     mu_assert_double_eq(3.840, furi_hal_power_get_battery_charging_voltage()); |     mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
|  |     furi_hal_power_set_battery_charge_voltage_limit(1.0f); | ||||||
|  |     mu_assert_double_eq(3.840, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
| 
 | 
 | ||||||
|     // NOTE: Intentionally picking a small increment above 4.208 V to reduce the risk of an
 |     // NOTE: Intentionally picking a small increment above 4.208 V to reduce the risk of an
 | ||||||
|     // unhappy battery if this fails.
 |     // unhappy battery if this fails.
 | ||||||
|     furi_hal_power_set_battery_charging_voltage(4.240f); |     furi_hal_power_set_battery_charge_voltage_limit(4.240f); | ||||||
|     mu_assert_double_eq(4.208, furi_hal_power_get_battery_charging_voltage()); |     mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
|  |     // Likewise, picking a number that the uint8_t wraparound in the driver would result in a
 | ||||||
|  |     // VREG value under 23 if this test fails.
 | ||||||
|  |     // E.g. (uint8_t)((8105-3840)/16) -> 10
 | ||||||
|  |     furi_hal_power_set_battery_charge_voltage_limit(8.105f); | ||||||
|  |     mu_assert_double_eq(4.208, furi_hal_power_get_battery_charge_voltage_limit()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST_SUITE(test_power_suite) { | MU_TEST_SUITE(test_power_suite) { | ||||||
|     MU_RUN_TEST(test_power_charge_voltage_exact); |     MU_RUN_TEST(test_power_charge_voltage_limit_exact); | ||||||
|     MU_RUN_TEST(test_power_charge_voltage_floating_imprecision); |     MU_RUN_TEST(test_power_charge_voltage_limit_floating_imprecision); | ||||||
|     MU_RUN_TEST(test_power_charge_voltage_inexact); |     MU_RUN_TEST(test_power_charge_voltage_limit_inexact); | ||||||
|     MU_RUN_TEST(test_power_charge_voltage_invalid_clamped); |     MU_RUN_TEST(test_power_charge_voltage_limit_invalid_clamped); | ||||||
|     power_test_deinit(); |     power_test_deinit(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -13,8 +13,8 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { | |||||||
| 
 | 
 | ||||||
|     if(power->info.gauge_is_ok) { |     if(power->info.gauge_is_ok) { | ||||||
|         canvas_draw_box(canvas, 2, 2, (power->info.charge + 4) / 5, 4); |         canvas_draw_box(canvas, 2, 2, (power->info.charge + 4) / 5, 4); | ||||||
|         if(power->info.voltage_battery_charging < 4.2) { |         if(power->info.voltage_battery_charge_limit < 4.2) { | ||||||
|             // Battery charging voltage is modified, indicate with cross pattern
 |             // Battery charge voltage limit is modified, indicate with cross pattern
 | ||||||
|             canvas_invert_color(canvas); |             canvas_invert_color(canvas); | ||||||
|             uint8_t battery_bar_width = (power->info.charge + 4) / 5; |             uint8_t battery_bar_width = (power->info.charge + 4) / 5; | ||||||
|             bool cross_odd = false; |             bool cross_odd = false; | ||||||
| @ -147,7 +147,7 @@ static bool power_update_info(Power* power) { | |||||||
|     info.capacity_full = furi_hal_power_get_battery_full_capacity(); |     info.capacity_full = furi_hal_power_get_battery_full_capacity(); | ||||||
|     info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger); |     info.current_charger = furi_hal_power_get_battery_current(FuriHalPowerICCharger); | ||||||
|     info.current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge); |     info.current_gauge = furi_hal_power_get_battery_current(FuriHalPowerICFuelGauge); | ||||||
|     info.voltage_battery_charging = furi_hal_power_get_battery_charging_voltage(); |     info.voltage_battery_charge_limit = furi_hal_power_get_battery_charge_voltage_limit(); | ||||||
|     info.voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger); |     info.voltage_charger = furi_hal_power_get_battery_voltage(FuriHalPowerICCharger); | ||||||
|     info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge); |     info.voltage_gauge = furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge); | ||||||
|     info.voltage_vbus = furi_hal_power_get_usb_voltage(); |     info.voltage_vbus = furi_hal_power_get_usb_voltage(); | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ typedef struct { | |||||||
|     float current_charger; |     float current_charger; | ||||||
|     float current_gauge; |     float current_gauge; | ||||||
| 
 | 
 | ||||||
|     float voltage_battery_charging; |     float voltage_battery_charge_limit; | ||||||
|     float voltage_charger; |     float voltage_charger; | ||||||
|     float voltage_gauge; |     float voltage_gauge; | ||||||
|     float voltage_vbus; |     float voltage_vbus; | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ static void power_settings_scene_battery_info_update_model(PowerSettingsApp* app | |||||||
|         .gauge_voltage = app->info.voltage_gauge, |         .gauge_voltage = app->info.voltage_gauge, | ||||||
|         .gauge_current = app->info.current_gauge, |         .gauge_current = app->info.current_gauge, | ||||||
|         .gauge_temperature = app->info.temperature_gauge, |         .gauge_temperature = app->info.temperature_gauge, | ||||||
|         .charging_voltage = app->info.voltage_battery_charging, |         .charge_voltage_limit = app->info.voltage_battery_charge_limit, | ||||||
|         .charge = app->info.charge, |         .charge = app->info.charge, | ||||||
|         .health = app->info.health, |         .health = app->info.health, | ||||||
|     }; |     }; | ||||||
|  | |||||||
| @ -69,7 +69,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { | |||||||
|             drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); |             drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA"); | ||||||
|     } else if(drain_current != 0) { |     } else if(drain_current != 0) { | ||||||
|         snprintf(header, 20, "..."); |         snprintf(header, 20, "..."); | ||||||
|     } else if(data->charging_voltage < 4.2) { |     } else if(data->charge_voltage_limit < 4.2) { | ||||||
|         // Non-default battery charging limit, mention it
 |         // Non-default battery charging limit, mention it
 | ||||||
|         snprintf(emote, sizeof(emote), "Charged!"); |         snprintf(emote, sizeof(emote), "Charged!"); | ||||||
|         snprintf(header, sizeof(header), "Limited to"); |         snprintf(header, sizeof(header), "Limited to"); | ||||||
| @ -77,8 +77,8 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) { | |||||||
|             value, |             value, | ||||||
|             sizeof(value), |             sizeof(value), | ||||||
|             "%lu.%luV", |             "%lu.%luV", | ||||||
|             (uint32_t)(data->charging_voltage), |             (uint32_t)(data->charge_voltage_limit), | ||||||
|             (uint32_t)(data->charging_voltage * 10) % 10); |             (uint32_t)(data->charge_voltage_limit * 10) % 10); | ||||||
|     } else { |     } else { | ||||||
|         snprintf(header, sizeof(header), "Charged!"); |         snprintf(header, sizeof(header), "Charged!"); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ typedef struct { | |||||||
|     float gauge_voltage; |     float gauge_voltage; | ||||||
|     float gauge_current; |     float gauge_current; | ||||||
|     float gauge_temperature; |     float gauge_temperature; | ||||||
|     float charging_voltage; |     float charge_voltage_limit; | ||||||
|     uint8_t charge; |     uint8_t charge; | ||||||
|     uint8_t health; |     uint8_t health; | ||||||
| } BatteryInfoModel; | } BatteryInfoModel; | ||||||
|  | |||||||
| @ -1211,7 +1211,7 @@ Function,+,furi_hal_power_enable_external_3_3v,void, | |||||||
| Function,+,furi_hal_power_enable_otg,void, | Function,+,furi_hal_power_enable_otg,void, | ||||||
| Function,+,furi_hal_power_gauge_is_ok,_Bool, | Function,+,furi_hal_power_gauge_is_ok,_Bool, | ||||||
| Function,+,furi_hal_power_get_bat_health_pct,uint8_t, | Function,+,furi_hal_power_get_bat_health_pct,uint8_t, | ||||||
| Function,+,furi_hal_power_get_battery_charging_voltage,float, | Function,+,furi_hal_power_get_battery_charge_voltage_limit,float, | ||||||
| Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC | Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC | ||||||
| Function,+,furi_hal_power_get_battery_design_capacity,uint32_t, | Function,+,furi_hal_power_get_battery_design_capacity,uint32_t, | ||||||
| Function,+,furi_hal_power_get_battery_full_capacity,uint32_t, | Function,+,furi_hal_power_get_battery_full_capacity,uint32_t, | ||||||
| @ -1230,7 +1230,7 @@ Function,+,furi_hal_power_is_charging_done,_Bool, | |||||||
| Function,+,furi_hal_power_is_otg_enabled,_Bool, | Function,+,furi_hal_power_is_otg_enabled,_Bool, | ||||||
| Function,+,furi_hal_power_off,void, | Function,+,furi_hal_power_off,void, | ||||||
| Function,+,furi_hal_power_reset,void, | Function,+,furi_hal_power_reset,void, | ||||||
| Function,+,furi_hal_power_set_battery_charging_voltage,void,float | Function,+,furi_hal_power_set_battery_charge_voltage_limit,void,float | ||||||
| Function,+,furi_hal_power_shutdown,void, | Function,+,furi_hal_power_shutdown,void, | ||||||
| Function,+,furi_hal_power_sleep,void, | Function,+,furi_hal_power_sleep,void, | ||||||
| Function,+,furi_hal_power_sleep_available,_Bool, | Function,+,furi_hal_power_sleep_available,_Bool, | ||||||
|  | |||||||
| 
 | 
| @ -341,14 +341,14 @@ bool furi_hal_power_is_otg_enabled() { | |||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float furi_hal_power_get_battery_charging_voltage() { | float furi_hal_power_get_battery_charge_voltage_limit() { | ||||||
|     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); |     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); | ||||||
|     float ret = (float)bq25896_get_vreg_voltage(&furi_hal_i2c_handle_power) / 1000.0f; |     float ret = (float)bq25896_get_vreg_voltage(&furi_hal_i2c_handle_power) / 1000.0f; | ||||||
|     furi_hal_i2c_release(&furi_hal_i2c_handle_power); |     furi_hal_i2c_release(&furi_hal_i2c_handle_power); | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_hal_power_set_battery_charging_voltage(float voltage) { | void furi_hal_power_set_battery_charge_voltage_limit(float voltage) { | ||||||
|     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); |     furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); | ||||||
|     // Adding 0.0005 is necessary because 4.016f is 4.015999794000, which gets truncated
 |     // Adding 0.0005 is necessary because 4.016f is 4.015999794000, which gets truncated
 | ||||||
|     bq25896_set_vreg_voltage(&furi_hal_i2c_handle_power, (uint16_t)(voltage * 1000.0f + 0.0005f)); |     bq25896_set_vreg_voltage(&furi_hal_i2c_handle_power, (uint16_t)(voltage * 1000.0f + 0.0005f)); | ||||||
| @ -486,7 +486,7 @@ void furi_hal_power_info_get(PropertyValueCallback out, char sep, void* context) | |||||||
|         property_value_out(&property_context, NULL, 2, "format", "major", "2"); |         property_value_out(&property_context, NULL, 2, "format", "major", "2"); | ||||||
|         property_value_out(&property_context, NULL, 2, "format", "minor", "1"); |         property_value_out(&property_context, NULL, 2, "format", "minor", "1"); | ||||||
|     } else { |     } else { | ||||||
|         property_value_out(&property_context, NULL, 3, "power", "info", "major", "1"); |         property_value_out(&property_context, NULL, 3, "power", "info", "major", "2"); | ||||||
|         property_value_out(&property_context, NULL, 3, "power", "info", "minor", "1"); |         property_value_out(&property_context, NULL, 3, "power", "info", "minor", "1"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -505,8 +505,10 @@ void furi_hal_power_info_get(PropertyValueCallback out, char sep, void* context) | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     property_value_out(&property_context, NULL, 2, "charge", "state", charge_state); |     property_value_out(&property_context, NULL, 2, "charge", "state", charge_state); | ||||||
|     uint16_t charge_voltage = (uint16_t)(furi_hal_power_get_battery_charging_voltage() * 1000.f); |     uint16_t charge_voltage_limit = | ||||||
|     property_value_out(&property_context, "%u", 2, "charge", "voltage", charge_voltage); |         (uint16_t)(furi_hal_power_get_battery_charge_voltage_limit() * 1000.f); | ||||||
|  |     property_value_out( | ||||||
|  |         &property_context, "%u", 3, "charge", "voltage", "limit", charge_voltage_limit); | ||||||
|     uint16_t voltage = |     uint16_t voltage = | ||||||
|         (uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f); |         (uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f); | ||||||
|     property_value_out(&property_context, "%u", 2, "battery", "voltage", voltage); |     property_value_out(&property_context, "%u", 2, "battery", "voltage", voltage); | ||||||
|  | |||||||
| @ -121,21 +121,21 @@ void furi_hal_power_check_otg_status(); | |||||||
|  */ |  */ | ||||||
| bool furi_hal_power_is_otg_enabled(); | bool furi_hal_power_is_otg_enabled(); | ||||||
| 
 | 
 | ||||||
| /** Get battery charging voltage in V
 | /** Get battery charge voltage limit in V
 | ||||||
|  * |  * | ||||||
|  * @return     voltage in V |  * @return     voltage in V | ||||||
|  */ |  */ | ||||||
| float furi_hal_power_get_battery_charging_voltage(); | float furi_hal_power_get_battery_charge_voltage_limit(); | ||||||
| 
 | 
 | ||||||
| /** Set battery charging voltage in V
 | /** Set battery charge voltage limit in V
 | ||||||
|  * |  * | ||||||
|  * Invalid values will be clamped to the nearest valid value. |  * Invalid values will be clamped downward to the nearest valid value. | ||||||
|  * |  * | ||||||
|  * @param      voltage[in]  voltage in V |  * @param      voltage[in]  voltage in V | ||||||
|  * |  * | ||||||
|  * @return     voltage in V |  * @return     voltage in V | ||||||
|  */ |  */ | ||||||
| void furi_hal_power_set_battery_charging_voltage(float voltage); | void furi_hal_power_set_battery_charge_voltage_limit(float voltage); | ||||||
| 
 | 
 | ||||||
| /** Get remaining battery battery capacity in mAh
 | /** Get remaining battery battery capacity in mAh
 | ||||||
|  * |  * | ||||||
|  | |||||||
| @ -140,15 +140,18 @@ uint16_t bq25896_get_vreg_voltage(FuriHalI2cBusHandle* handle) { | |||||||
| 
 | 
 | ||||||
| void bq25896_set_vreg_voltage(FuriHalI2cBusHandle* handle, uint16_t vreg_voltage) { | void bq25896_set_vreg_voltage(FuriHalI2cBusHandle* handle, uint16_t vreg_voltage) { | ||||||
|     if(vreg_voltage < 3840) { |     if(vreg_voltage < 3840) { | ||||||
|         // Minimum value is 3840 mV
 |         // Minimum valid value is 3840 mV
 | ||||||
|         bq25896_regs.r06.VREG = 0; |         vreg_voltage = 3840; | ||||||
|     } else { |     } else if(vreg_voltage > 4208) { | ||||||
|         // Find the nearest voltage value (subtract offset, divide into sections)
 |         // Maximum safe value is 4208 mV
 | ||||||
|         // Values are truncated downward as needed (e.g. 4200mV -> 4192 mV)
 |         vreg_voltage = 4208; | ||||||
|         bq25896_regs.r06.VREG = (uint8_t)((vreg_voltage - 3840) / 16); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Do not allow values above 23 (0x17, 4208mV)
 |     // Find the nearest voltage value (subtract offset, divide into sections)
 | ||||||
|  |     // Values are truncated downward as needed (e.g. 4200mV -> 4192 mV)
 | ||||||
|  |     bq25896_regs.r06.VREG = (uint8_t)((vreg_voltage - 3840) / 16); | ||||||
|  | 
 | ||||||
|  |     // Double check: do not allow values above 23 (0x17, 4208mV)
 | ||||||
|     // Exceeding 4.2v will overcharge the battery!
 |     // Exceeding 4.2v will overcharge the battery!
 | ||||||
|     if(bq25896_regs.r06.VREG > 23) { |     if(bq25896_regs.r06.VREG > 23) { | ||||||
|         bq25896_regs.r06.VREG = 23; |         bq25896_regs.r06.VREG = 23; | ||||||
|  | |||||||
| @ -36,10 +36,10 @@ void bq25896_disable_otg(FuriHalI2cBusHandle* handle); | |||||||
| /** Is otg enabled */ | /** Is otg enabled */ | ||||||
| bool bq25896_is_otg_enabled(FuriHalI2cBusHandle* handle); | bool bq25896_is_otg_enabled(FuriHalI2cBusHandle* handle); | ||||||
| 
 | 
 | ||||||
| /** Get VREG (charging) voltage in mV */ | /** Get VREG (charging limit) voltage in mV */ | ||||||
| uint16_t bq25896_get_vreg_voltage(FuriHalI2cBusHandle* handle); | uint16_t bq25896_get_vreg_voltage(FuriHalI2cBusHandle* handle); | ||||||
| 
 | 
 | ||||||
| /** Set VREG (charging) voltage in mV
 | /** Set VREG (charging limit) voltage in mV
 | ||||||
|  * |  * | ||||||
|  * Valid range: 3840mV - 4208mV, in steps of 16mV |  * Valid range: 3840mV - 4208mV, in steps of 16mV | ||||||
|  */ |  */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Shane Synan
						Shane Synan