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