ESPHome  2024.11.0
logger_esp32.cpp
Go to the documentation of this file.
1 #ifdef USE_ESP32
2 #include "logger.h"
3 
4 #if defined(USE_ESP32_FRAMEWORK_ARDUINO) || defined(USE_ESP_IDF)
5 #include <esp_log.h>
6 #endif // USE_ESP32_FRAMEWORK_ARDUINO || USE_ESP_IDF
7 
8 #ifdef USE_ESP_IDF
9 #include <driver/uart.h>
10 
11 #ifdef USE_LOGGER_USB_SERIAL_JTAG
12 #include <driver/usb_serial_jtag.h>
13 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
14 #include <esp_vfs_dev.h>
15 #include <esp_vfs_usb_serial_jtag.h>
16 #else
17 #include <driver/usb_serial_jtag_vfs.h>
18 #endif
19 #endif
20 
21 #include "freertos/FreeRTOS.h"
22 #include "esp_idf_version.h"
23 
24 #include <cstdint>
25 #include <cstdio>
26 #include <fcntl.h>
27 
28 #endif // USE_ESP_IDF
29 
30 #include "esphome/core/log.h"
31 
32 namespace esphome {
33 namespace logger {
34 
35 static const char *const TAG = "logger";
36 
37 #ifdef USE_ESP_IDF
38 
39 #ifdef USE_LOGGER_USB_SERIAL_JTAG
40 static void init_usb_serial_jtag_() {
41  setvbuf(stdin, NULL, _IONBF, 0); // Disable buffering on stdin
42 
43 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
44  // Minicom, screen, idf_monitor send CR when ENTER key is pressed
45  esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
46  // Move the caret to the beginning of the next line on '\n'
47  esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
48 #else
49  // Minicom, screen, idf_monitor send CR when ENTER key is pressed
50  usb_serial_jtag_vfs_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
51  // Move the caret to the beginning of the next line on '\n'
52  usb_serial_jtag_vfs_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
53 #endif
54 
55  // Enable non-blocking mode on stdin and stdout
56  fcntl(fileno(stdout), F_SETFL, 0);
57  fcntl(fileno(stdin), F_SETFL, 0);
58 
59  usb_serial_jtag_driver_config_t usb_serial_jtag_config{};
60  usb_serial_jtag_config.rx_buffer_size = 512;
61  usb_serial_jtag_config.tx_buffer_size = 512;
62 
63  esp_err_t ret = ESP_OK;
64  // Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes
65  ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config);
66  if (ret != ESP_OK) {
67  return;
68  }
69 
70  // Tell vfs to use usb-serial-jtag driver
71 #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
72  esp_vfs_usb_serial_jtag_use_driver();
73 #else
74  usb_serial_jtag_vfs_use_driver();
75 #endif
76 }
77 #endif
78 
79 void init_uart(uart_port_t uart_num, uint32_t baud_rate, int tx_buffer_size) {
80  uart_config_t uart_config{};
81  uart_config.baud_rate = (int) baud_rate;
82  uart_config.data_bits = UART_DATA_8_BITS;
83  uart_config.parity = UART_PARITY_DISABLE;
84  uart_config.stop_bits = UART_STOP_BITS_1;
85  uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
86 #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
87  uart_config.source_clk = UART_SCLK_DEFAULT;
88 #endif
89  uart_param_config(uart_num, &uart_config);
90  const int uart_buffer_size = tx_buffer_size;
91  // Install UART driver using an event queue here
92  uart_driver_install(uart_num, uart_buffer_size, uart_buffer_size, 10, nullptr, 0);
93 }
94 
95 #endif // USE_ESP_IDF
96 
98  if (this->baud_rate_ > 0) {
99 #ifdef USE_ARDUINO
100  switch (this->uart_) {
102 #if ARDUINO_USB_CDC_ON_BOOT
103  this->hw_serial_ = &Serial0;
104  Serial0.begin(this->baud_rate_);
105 #else
106  this->hw_serial_ = &Serial;
107  Serial.begin(this->baud_rate_);
108 #endif
109  break;
111  this->hw_serial_ = &Serial1;
112  Serial1.begin(this->baud_rate_);
113  break;
114 #ifdef USE_ESP32_VARIANT_ESP32
116  this->hw_serial_ = &Serial2;
117  Serial2.begin(this->baud_rate_);
118  break;
119 #endif
120 
121 #ifdef USE_LOGGER_USB_CDC
123  this->hw_serial_ = &Serial;
124 #if ARDUINO_USB_CDC_ON_BOOT
125  Serial.setTxTimeoutMs(0); // workaround for 2.0.9 crash when there's no data connection
126 #endif
127  Serial.begin(this->baud_rate_);
128  break;
129 #endif
130  }
131 #endif // USE_ARDUINO
132 
133 #ifdef USE_ESP_IDF
134  this->uart_num_ = UART_NUM_0;
135  switch (this->uart_) {
137  this->uart_num_ = UART_NUM_0;
139  break;
141  this->uart_num_ = UART_NUM_1;
143  break;
144 #ifdef USE_ESP32_VARIANT_ESP32
146  this->uart_num_ = UART_NUM_2;
148  break;
149 #endif
150 #ifdef USE_LOGGER_USB_CDC
152  break;
153 #endif
154 #ifdef USE_LOGGER_USB_SERIAL_JTAG
156  init_usb_serial_jtag_();
157  break;
158 #endif
159  }
160 #endif // USE_ESP_IDF
161  }
162 
163  global_logger = this;
164 #if defined(USE_ESP_IDF) || defined(USE_ESP32_FRAMEWORK_ARDUINO)
165  esp_log_set_vprintf(esp_idf_log_vprintf_);
166  if (ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE) {
167  esp_log_level_set("*", ESP_LOG_VERBOSE);
168  }
169 #endif // USE_ESP_IDF || USE_ESP32_FRAMEWORK_ARDUINO
170 
171  ESP_LOGI(TAG, "Log initialized");
172 }
173 
174 #ifdef USE_ESP_IDF
175 void HOT Logger::write_msg_(const char *msg) {
176  if (
177 #if defined(USE_ESP32_VARIANT_ESP32S2)
179 #elif defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6) || defined(USE_ESP32_VARIANT_ESP32H2)
181 #elif defined(USE_ESP32_VARIANT_ESP32S3)
183 #else
184  /* DISABLES CODE */ (false) // NOLINT
185 #endif
186  ) {
187  puts(msg);
188  } else {
189  uart_write_bytes(this->uart_num_, msg, strlen(msg));
190  uart_write_bytes(this->uart_num_, "\n", 1);
191  }
192 }
193 #else
194 void HOT Logger::write_msg_(const char *msg) { this->hw_serial_->println(msg); }
195 #endif
196 
197 const char *const UART_SELECTIONS[] = {
198  "UART0", "UART1",
199 #ifdef USE_ESP32_VARIANT_ESP32
200  "UART2",
201 #endif
202 #ifdef USE_LOGGER_USB_CDC
203  "USB_CDC",
204 #endif
205 #ifdef USE_LOGGER_USB_SERIAL_JTAG
206  "USB_SERIAL_JTAG",
207 #endif
208 };
209 
210 const char *Logger::get_uart_selection_() { return UART_SELECTIONS[this->uart_]; }
211 
212 } // namespace logger
213 } // namespace esphome
214 #endif
Logger * global_logger
Definition: logger.cpp:198
uart_port_t uart_num_
Definition: logger.h:160
const char * get_uart_selection_()
void init_uart(uart_port_t uart_num, uint32_t baud_rate, int tx_buffer_size)
UARTSelection uart_
Definition: logger.h:151
void pre_setup()
Set up this component.
const char *const UART_SELECTIONS[]
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
void write_msg_(const char *msg)
int HOT esp_idf_log_vprintf_(const char *format, va_list args)
Definition: log.cpp:50