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