11#if DETWS_ENABLE_HW_HEALTH
15void detws_hwhealth_rail_init(HwRailMonitor *m, uint32_t nominal_mv, uint32_t warn_mv, uint32_t crit_mv)
19 m->nominal_mv = nominal_mv;
22 m->min_mv = nominal_mv;
24 m->brownout_events = 0;
27HwRailVerdict detws_hwhealth_rail_sample(HwRailMonitor *m, uint32_t mv)
30 return HwRailVerdict::HW_RAIL_OK;
36 return HwRailVerdict::HW_RAIL_BROWNOUT;
41 return HwRailVerdict::HW_RAIL_SAG;
43 return HwRailVerdict::HW_RAIL_OK;
56void put(Buf *b,
const char *s)
60 size_t sl = strnlen(s, b->cap + 1);
61 if (b->len + sl >= b->cap)
66 memcpy(b->p + b->len, s, sl);
70void put_u32(Buf *b, uint32_t v)
76 t[n++] = (char)(
'0' + v % 10);
80 for (
int i = 0; i < n; i++)
87size_t detws_hwhealth_rail_json(
const HwRailMonitor *m,
char *out,
size_t cap)
89 if (!m || !out || cap == 0)
91 Buf b = {out, cap, 0,
true};
92 put(&b,
"{\"nominal_mv\":");
93 put_u32(&b, m->nominal_mv);
94 put(&b,
",\"min_mv\":");
95 put_u32(&b, m->min_mv);
97 put_u32(&b, m->sag_events);
98 put(&b,
",\"brownout\":");
99 put_u32(&b, m->brownout_events);
107void detws_hwhealth_spi_init(HwSpiBackoff *s, uint32_t start_hz, uint32_t min_hz, uint32_t max_hz, uint16_t fail_trip,
114 if (start_hz < min_hz)
116 else if (start_hz > max_hz)
122 s->fail_trip = fail_trip ? fail_trip : 1;
123 s->ok_trip = ok_trip ? ok_trip : 1;
126uint32_t detws_hwhealth_spi_result(HwSpiBackoff *s,
bool crc_ok)
133 if (++s->ok_streak >= s->ok_trip)
136 uint32_t up = s->hz << 1;
137 if (up < s->hz || up > s->max_hz)
145 if (++s->fail_streak >= s->fail_trip)
148 uint32_t down = s->hz >> 1;
149 if (down < s->min_hz)
157HwGpioVerdict detws_hwhealth_gpio_short(
bool driven_high,
bool read_high)
159 if (driven_high && !read_high)
160 return HwGpioVerdict::HW_GPIO_SHORT_GND;
161 if (!driven_high && read_high)
162 return HwGpioVerdict::HW_GPIO_SHORT_VCC;
163 return HwGpioVerdict::HW_GPIO_OK;
166HwCapVerdict detws_hwhealth_cap_leak(uint32_t measured_ms, uint32_t expected_ms, uint8_t tol_pct)
168 if (expected_ms == 0)
169 return HwCapVerdict::HW_CAP_OK;
171 uint64_t band = (uint64_t)expected_ms * tol_pct / 100;
172 uint64_t lo = (uint64_t)expected_ms > band ? (uint64_t)expected_ms - band : 0;
173 uint64_t hi = (uint64_t)expected_ms + band;
174 if (measured_ms < lo)
175 return HwCapVerdict::HW_CAP_LEAK;
176 if (measured_ms > hi)
177 return HwCapVerdict::HW_CAP_HIGH_ESR;
178 return HwCapVerdict::HW_CAP_OK;
Hardware-health diagnostics: rail droop, SPI CRC backoff, GPIO short, cap leakage (DETWS_ENABLE_HW_HE...