31 if (!buf || bufSize == 0)
return;
34 auto append = [&](
const char* fmt, ...) {
35 if (pos >= bufSize)
return;
38 int written = vsnprintf(buf + pos, bufSize - pos, fmt, args);
41 size_t w =
static_cast<size_t>(written);
42 pos += (w < (bufSize - pos)) ? w : (bufSize - pos - 1);
46 const char* okText =
ui::tr(
"core.ok");
47 const char* failText =
ui::tr(
"core.failed");
48 const char* naText =
ui::tr(
"core.hw_not_available");
50 append(
"=== %s ===\n",
ui::tr(
"core.hardware_info"));
56 append(
"%s: %s\n",
ui::tr(
"core.hw_i2c_bus"), i2cOk ? okText : failText);
62 append(
"%s: %s\n",
ui::tr(
"core.hw_bq25895"), powerOk ? okText : failText);
68 append(
"%s: %s\n",
ui::tr(
"core.hw_tca9535"), keypadOk ? okText : failText);
74 append(
"%s: %s\n",
ui::tr(
"core.hw_display"), displayOk ? okText : failText);
80 append(
"%s: %s\n",
ui::tr(
"core.hw_tropic01"), seOk ? okText : failText);
81 append(
"%s: %s\n",
ui::tr(
"core.hw_tr01_session"),
82 (se && se->isSessionActive()) ? okText : naText);
85 uint8_t riscvVer[4] = {0};
86 uint8_t spectVer[4] = {0};
87 if (se->getFwVersion(riscvVer, spectVer)) {
88 append(
"%s: %u.%u.%u.%u\n",
ui::tr(
"core.hw_tr01_riscv_fw"),
89 riscvVer[3], riscvVer[2], riscvVer[1], riscvVer[0]);
90 append(
"%s: %u.%u.%u.%u\n",
ui::tr(
"core.hw_tr01_spect_fw"),
91 spectVer[3], spectVer[2], spectVer[1], spectVer[0]);
93 append(
"%s: %s\n",
ui::tr(
"core.hw_tr01_riscv_fw"), naText);
94 append(
"%s: %s\n",
ui::tr(
"core.hw_tr01_spect_fw"), naText);
96 append(
"%s: %u B\n",
ui::tr(
"core.hw_tr01_rmem_slot"), se->getRmemSlotSize());
98 append(
"%s: %s\n",
ui::tr(
"core.hw_tr01_riscv_fw"), naText);
99 append(
"%s: %s\n",
ui::tr(
"core.hw_tr01_spect_fw"), naText);
100 append(
"%s: %s\n",
ui::tr(
"core.hw_tr01_rmem_slot"), naText);
107 append(
"%s: %s\n",
ui::tr(
"core.hw_wifi"), wifiOk ? okText : naText);
113 append(
"%s: %s\n",
ui::tr(
"core.hw_ble"), bleOk ? okText : naText);
115 append(
"\n--- %s ---\n",
ui::tr(
"core.hw_section_memory"));
117 size_t freeHeap = esp_get_free_heap_size();
118 size_t totalHeap = heap_caps_get_total_size(MALLOC_CAP_DEFAULT);
119 size_t usedHeap = (totalHeap > freeHeap) ? (totalHeap - freeHeap) : 0;
120 append(
"%s: %lu/%lu KB\n",
122 (
unsigned long)(usedHeap / 1024),
123 (
unsigned long)(totalHeap / 1024));
125 size_t intFree = heap_caps_get_free_size(MALLOC_CAP_INTERNAL);
126 size_t intTotal = heap_caps_get_total_size(MALLOC_CAP_INTERNAL);
127 size_t intLargest = heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL);
128 append(
"DRAM: %lu/%lu KB free, largest %lu B\n",
129 (
unsigned long)(intFree / 1024),
130 (
unsigned long)(intTotal / 1024),
131 (
unsigned long)intLargest);
133 size_t dmaFree = heap_caps_get_free_size(MALLOC_CAP_DMA);
134 size_t dmaLargest = heap_caps_get_largest_free_block(MALLOC_CAP_DMA);
135 append(
"DMA: %lu KB free, largest %lu B\n",
136 (
unsigned long)(dmaFree / 1024),
137 (
unsigned long)dmaLargest);
139 size_t psramFree = heap_caps_get_free_size(MALLOC_CAP_SPIRAM);
140 size_t psramTotal = heap_caps_get_total_size(MALLOC_CAP_SPIRAM);
141 size_t psramUsed = (psramTotal > psramFree) ? (psramTotal - psramFree) : 0;
142 append(
"%s: %lu/%lu KB\n",
144 (
unsigned long)(psramUsed / 1024),
145 (
unsigned long)(psramTotal / 1024));
147 nvs_stats_t nvsStats;
148 if (nvs_get_stats(
nullptr, &nvsStats) == ESP_OK) {
149 append(
"%s: %lu/%lu %s\n",
151 (
unsigned long)nvsStats.used_entries,
152 (
unsigned long)nvsStats.total_entries,
153 ui::tr(
"core.hw_entries"));
156 append(
"\n--- %s ---\n",
ui::tr(
"core.hw_section_runtime"));
161 ?
ui::tr(
"core.hw_charging_suffix")
163 append(
"%s: %u%%%s\n",
ui::tr(
"core.hw_battery"), power->getBatteryPercent(), chg);
165 append(
"%s: %s\n",
ui::tr(
"core.hw_battery"), naText);
170 if (espHw && espHw->getTemperatureC(&tempC)) {
171 append(
"%s: %.1f C\n",
ui::tr(
"core.hw_temp"), tempC);
173 append(
"%s: %s\n",
ui::tr(
"core.hw_temp"), naText);
176 uint64_t uptimeS = esp_timer_get_time() / 1000000ULL;
177 append(
"%s: %llu s\n",
ui::tr(
"core.hw_uptime"), (
unsigned long long)uptimeS);