ESPHome  2024.11.0
debug_esp32.cpp
Go to the documentation of this file.
1 #include "debug_component.h"
2 #ifdef USE_ESP32
3 #include "esphome/core/log.h"
4 
5 #include <esp_heap_caps.h>
6 #include <esp_system.h>
7 #include <esp_chip_info.h>
8 
9 #if defined(USE_ESP32_VARIANT_ESP32)
10 #include <esp32/rom/rtc.h>
11 #elif defined(USE_ESP32_VARIANT_ESP32C3)
12 #include <esp32c3/rom/rtc.h>
13 #elif defined(USE_ESP32_VARIANT_ESP32C6)
14 #include <esp32c6/rom/rtc.h>
15 #elif defined(USE_ESP32_VARIANT_ESP32S2)
16 #include <esp32s2/rom/rtc.h>
17 #elif defined(USE_ESP32_VARIANT_ESP32S3)
18 #include <esp32s3/rom/rtc.h>
19 #elif defined(USE_ESP32_VARIANT_ESP32H2)
20 #include <esp32h2/rom/rtc.h>
21 #endif
22 #ifdef USE_ARDUINO
23 #include <Esp.h>
24 #endif
25 
26 namespace esphome {
27 namespace debug {
28 
29 static const char *const TAG = "debug";
30 
32  std::string reset_reason;
33  switch (rtc_get_reset_reason(0)) {
34  case POWERON_RESET:
35  reset_reason = "Power On Reset";
36  break;
37 #if defined(USE_ESP32_VARIANT_ESP32)
38  case SW_RESET:
39 #elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || \
40  defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
41  case RTC_SW_SYS_RESET:
42 #endif
43  reset_reason = "Software Reset Digital Core";
44  break;
45 #if defined(USE_ESP32_VARIANT_ESP32)
46  case OWDT_RESET:
47  reset_reason = "Watch Dog Reset Digital Core";
48  break;
49 #endif
50  case DEEPSLEEP_RESET:
51  reset_reason = "Deep Sleep Reset Digital Core";
52  break;
53 #if defined(USE_ESP32_VARIANT_ESP32)
54  case SDIO_RESET:
55  reset_reason = "SLC Module Reset Digital Core";
56  break;
57 #endif
58  case TG0WDT_SYS_RESET:
59  reset_reason = "Timer Group 0 Watch Dog Reset Digital Core";
60  break;
61  case TG1WDT_SYS_RESET:
62  reset_reason = "Timer Group 1 Watch Dog Reset Digital Core";
63  break;
64  case RTCWDT_SYS_RESET:
65  reset_reason = "RTC Watch Dog Reset Digital Core";
66  break;
67 #if !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
68  case INTRUSION_RESET:
69  reset_reason = "Intrusion Reset CPU";
70  break;
71 #endif
72 #if defined(USE_ESP32_VARIANT_ESP32)
73  case TGWDT_CPU_RESET:
74  reset_reason = "Timer Group Reset CPU";
75  break;
76 #elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || \
77  defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
78  case TG0WDT_CPU_RESET:
79  reset_reason = "Timer Group 0 Reset CPU";
80  break;
81 #endif
82 #if defined(USE_ESP32_VARIANT_ESP32)
83  case SW_CPU_RESET:
84 #elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || \
85  defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
86  case RTC_SW_CPU_RESET:
87 #endif
88  reset_reason = "Software Reset CPU";
89  break;
90  case RTCWDT_CPU_RESET:
91  reset_reason = "RTC Watch Dog Reset CPU";
92  break;
93 #if defined(USE_ESP32_VARIANT_ESP32)
94  case EXT_CPU_RESET:
95  reset_reason = "External CPU Reset";
96  break;
97 #endif
98  case RTCWDT_BROWN_OUT_RESET:
99  reset_reason = "Voltage Unstable Reset";
100  break;
101  case RTCWDT_RTC_RESET:
102  reset_reason = "RTC Watch Dog Reset Digital Core And RTC Module";
103  break;
104 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3) || \
105  defined(USE_ESP32_VARIANT_ESP32C6)
106  case TG1WDT_CPU_RESET:
107  reset_reason = "Timer Group 1 Reset CPU";
108  break;
109  case SUPER_WDT_RESET:
110  reset_reason = "Super Watchdog Reset Digital Core And RTC Module";
111  break;
112  case EFUSE_RESET:
113  reset_reason = "eFuse Reset Digital Core";
114  break;
115 #endif
116 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
117  case GLITCH_RTC_RESET:
118  reset_reason = "Glitch Reset Digital Core And RTC Module";
119  break;
120 #endif
121 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3) || defined(USE_ESP32_VARIANT_ESP32C6)
122  case USB_UART_CHIP_RESET:
123  reset_reason = "USB UART Reset Digital Core";
124  break;
125  case USB_JTAG_CHIP_RESET:
126  reset_reason = "USB JTAG Reset Digital Core";
127  break;
128 #endif
129 #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32S3)
130  case POWER_GLITCH_RESET:
131  reset_reason = "Power Glitch Reset Digital Core And RTC Module";
132  break;
133 #endif
134  default:
135  reset_reason = "Unknown Reset Reason";
136  }
137  ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
138  return reset_reason;
139 }
140 
141 uint32_t DebugComponent::get_free_heap_() { return heap_caps_get_free_size(MALLOC_CAP_INTERNAL); }
142 
143 void DebugComponent::get_device_info_(std::string &device_info) {
144 #if defined(USE_ARDUINO)
145  const char *flash_mode;
146  switch (ESP.getFlashChipMode()) { // NOLINT(readability-static-accessed-through-instance)
147  case FM_QIO:
148  flash_mode = "QIO";
149  break;
150  case FM_QOUT:
151  flash_mode = "QOUT";
152  break;
153  case FM_DIO:
154  flash_mode = "DIO";
155  break;
156  case FM_DOUT:
157  flash_mode = "DOUT";
158  break;
159  case FM_FAST_READ:
160  flash_mode = "FAST_READ";
161  break;
162  case FM_SLOW_READ:
163  flash_mode = "SLOW_READ";
164  break;
165  default:
166  flash_mode = "UNKNOWN";
167  }
168  ESP_LOGD(TAG, "Flash Chip: Size=%ukB Speed=%uMHz Mode=%s",
169  ESP.getFlashChipSize() / 1024, // NOLINT
170  ESP.getFlashChipSpeed() / 1000000, flash_mode); // NOLINT
171  device_info += "|Flash: " + to_string(ESP.getFlashChipSize() / 1024) + // NOLINT
172  "kB Speed:" + to_string(ESP.getFlashChipSpeed() / 1000000) + "MHz Mode:"; // NOLINT
173  device_info += flash_mode;
174 #endif
175 
176  esp_chip_info_t info;
177  esp_chip_info(&info);
178  const char *model;
179 #if defined(USE_ESP32_VARIANT_ESP32)
180  model = "ESP32";
181 #elif defined(USE_ESP32_VARIANT_ESP32C3)
182  model = "ESP32-C3";
183 #elif defined(USE_ESP32_VARIANT_ESP32C6)
184  model = "ESP32-C6";
185 #elif defined(USE_ESP32_VARIANT_ESP32S2)
186  model = "ESP32-S2";
187 #elif defined(USE_ESP32_VARIANT_ESP32S3)
188  model = "ESP32-S3";
189 #elif defined(USE_ESP32_VARIANT_ESP32H2)
190  model = "ESP32-H2";
191 #else
192  model = "UNKNOWN";
193 #endif
194  std::string features;
195  if (info.features & CHIP_FEATURE_EMB_FLASH) {
196  features += "EMB_FLASH,";
197  info.features &= ~CHIP_FEATURE_EMB_FLASH;
198  }
199  if (info.features & CHIP_FEATURE_WIFI_BGN) {
200  features += "WIFI_BGN,";
201  info.features &= ~CHIP_FEATURE_WIFI_BGN;
202  }
203  if (info.features & CHIP_FEATURE_BLE) {
204  features += "BLE,";
205  info.features &= ~CHIP_FEATURE_BLE;
206  }
207  if (info.features & CHIP_FEATURE_BT) {
208  features += "BT,";
209  info.features &= ~CHIP_FEATURE_BT;
210  }
211  if (info.features & CHIP_FEATURE_EMB_PSRAM) {
212  features += "EMB_PSRAM,";
213  info.features &= ~CHIP_FEATURE_EMB_PSRAM;
214  }
215  if (info.features)
216  features += "Other:" + format_hex(info.features);
217  ESP_LOGD(TAG, "Chip: Model=%s, Features=%s Cores=%u, Revision=%u", model, features.c_str(), info.cores,
218  info.revision);
219  device_info += "|Chip: ";
220  device_info += model;
221  device_info += " Features:";
222  device_info += features;
223  device_info += " Cores:" + to_string(info.cores);
224  device_info += " Revision:" + to_string(info.revision);
225 
226  ESP_LOGD(TAG, "ESP-IDF Version: %s", esp_get_idf_version());
227  device_info += "|ESP-IDF: ";
228  device_info += esp_get_idf_version();
229 
230  std::string mac = get_mac_address_pretty();
231  ESP_LOGD(TAG, "EFuse MAC: %s", mac.c_str());
232  device_info += "|EFuse MAC: ";
233  device_info += mac;
234 
235  device_info += "|Reset: ";
236  device_info += get_reset_reason_();
237 
238  const char *wakeup_reason;
239  switch (rtc_get_wakeup_cause()) {
240  case NO_SLEEP:
241  wakeup_reason = "No Sleep";
242  break;
243  case EXT_EVENT0_TRIG:
244  wakeup_reason = "External Event 0";
245  break;
246  case EXT_EVENT1_TRIG:
247  wakeup_reason = "External Event 1";
248  break;
249  case GPIO_TRIG:
250  wakeup_reason = "GPIO";
251  break;
252  case TIMER_EXPIRE:
253  wakeup_reason = "Wakeup Timer";
254  break;
255  case SDIO_TRIG:
256  wakeup_reason = "SDIO";
257  break;
258  case MAC_TRIG:
259  wakeup_reason = "MAC";
260  break;
261  case UART0_TRIG:
262  wakeup_reason = "UART0";
263  break;
264  case UART1_TRIG:
265  wakeup_reason = "UART1";
266  break;
267  case TOUCH_TRIG:
268  wakeup_reason = "Touch";
269  break;
270  case SAR_TRIG:
271  wakeup_reason = "SAR";
272  break;
273  case BT_TRIG:
274  wakeup_reason = "BT";
275  break;
276  default:
277  wakeup_reason = "Unknown";
278  }
279  ESP_LOGD(TAG, "Wakeup Reason: %s", wakeup_reason);
280  device_info += "|Wakeup: ";
281  device_info += wakeup_reason;
282 }
283 
285 #ifdef USE_SENSOR
286  if (this->block_sensor_ != nullptr) {
287  this->block_sensor_->publish_state(heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));
288  }
289  if (this->psram_sensor_ != nullptr) {
290  this->psram_sensor_->publish_state(heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
291  }
292 #endif
293 }
294 
295 } // namespace debug
296 } // namespace esphome
297 #endif
std::string format_hex(const uint8_t *data, size_t length)
Format the byte array data of length len in lowercased hex.
Definition: helpers.cpp:352
void get_device_info_(std::string &device_info)
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
std::string to_string(int value)
Definition: helpers.cpp:81
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
std::string get_mac_address_pretty()
Get the device MAC address as a string, in colon-separated uppercase hex notation.
Definition: helpers.cpp:712