@@ -42,6 +42,9 @@ static bool power_init = false;
4242static bool device_plugged = false;
4343static bool device_charged = false;
4444
45+ static bool chg_temp_warn = false;
46+ static int64 last_valid_temp = -1 ;
47+
4548LOG_MODULE_REGISTER (power , LOG_LEVEL_INF );
4649
4750static void sys_WOM (bool force );
@@ -75,6 +78,12 @@ static const struct gpio_dt_spec ldo_en = GPIO_DT_SPEC_GET(ZEPHYR_USER_NODE, ldo
7578#else
7679#pragma message "LDO enable GPIO does not exist"
7780#endif
81+ #if DT_NODE_HAS_PROP (ZEPHYR_USER_NODE , chg_en_gpios )
82+ #define CHG_EN_EXISTS true
83+ static const struct gpio_dt_spec chg_en = GPIO_DT_SPEC_GET (ZEPHYR_USER_NODE , chg_en_gpios );
84+ #else
85+ #pragma message "Charge enable GPIO does not exist"
86+ #endif
7887
7988#define ADAFRUIT_BOOTLOADER CONFIG_BUILD_OUTPUT_UF2
8089
@@ -189,6 +198,30 @@ static void set_regulator(enum sys_regulator regulator)
189198#endif
190199}
191200
201+ static int set_charger_enable (bool enable , bool plugged )
202+ {
203+ #if CHG_EN_EXISTS
204+ static bool last_chg_en = false;
205+ if (!plugged )
206+ enable = false; // always disable charger if not plugged
207+ if (enable != last_chg_en )
208+ {
209+ last_chg_en = enable ;
210+ gpio_pin_set_dt (& chg_en , enable );
211+ LOG_INF ("%s" , enable ? "Enabled charger" : "Disabled charger" );
212+ }
213+ #elif CONFIG_BATTERY_CHARGER_HAS_NTC
214+ // charger has implemented NTC and does not have enable pin, can ignore
215+ #else
216+ if (!enable && plugged )
217+ {
218+ LOG_ERR ("Cannot disable charger" );
219+ return -1 ;
220+ }
221+ #endif
222+ return 0 ;
223+ }
224+
192225static void wait_for_logging (void )
193226{
194227#if CONFIG_LOG_BACKEND_UART
@@ -463,6 +496,33 @@ static void power_thread(void)
463496 bool charging = chg_read ();
464497 bool charged = stby_read ();
465498
499+ float temp ;
500+ int chg_ret = sensor_get_sensor_temperature (& temp );
501+ switch (chg_ret )
502+ {
503+ case -2 :
504+ last_valid_temp = -1 ;
505+ chg_temp_warn = true;
506+ break :
507+ case -1 :
508+ if (last_valid_temp == -1 )
509+ last_valid_temp = k_uptime_get ();
510+ if (k_uptime_get () - last_valid_temp > 1000 ) // valid read timeout
511+ chg_temp_warn = true;
512+ break ;
513+ case 0 :
514+ last_valid_temp = k_uptime_get ();
515+ if (!chg_temp_warn && (temp < 5.f || temp > 45.f )) // this is still safe (hard limit is 0C, but that is dangerous)
516+ chg_temp_warn = true;
517+ else if (chg_temp_warn && temp > 10.f && temp < 40.f ) // safest range
518+ chg_temp_warn = false;
519+ default :
520+ break ;
521+ }
522+ chg_ret = set_charger_enable (!chg_temp_warn , device_plugged );
523+ // chg_ret = -1: outside safe temp range, but charger could not be disabled
524+ // chg_ret = 0 and chg_temp_warn = true: out of temp range, charger is disabled or already has thermistor
525+
466526 int battery_mV ;
467527 int16_t battery_pptt = read_batt_mV (& battery_mV );
468528 if (battery_level_pptt < 0 )
@@ -543,7 +603,14 @@ static void power_thread(void)
543603
544604 connection_update_battery (battery_available , device_plugged , device_charged , calibrated_battery_pptt , battery_mV );
545605
546- if (charging )
606+ if (chg_ret )
607+ set_led (SYS_LED_PATTERN_CRITICAL , SYS_LED_PRIORITY_CRITICAL );
608+ else
609+ set_led (SYS_LED_PATTERN_OFF , SYS_LED_PRIORITY_CRITICAL );
610+
611+ if (chg_temp_warn && plugged ) // don't need to warn if not plugged in
612+ set_led (SYS_LED_PATTERN_WARNING , SYS_LED_PRIORITY_SYSTEM ); // not critical
613+ else if (charging )
547614 set_led (SYS_LED_PATTERN_PULSE_PERSIST , SYS_LED_PRIORITY_SYSTEM );
548615 else if (charged )
549616 set_led (SYS_LED_PATTERN_ON_PERSIST , SYS_LED_PRIORITY_SYSTEM );
0 commit comments