mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 10:46:31 +00:00
Add experimental USB console
- Add experimental USB console for ESP32C3, S2 and S3 using embedded ESp32 USB interface (like lolin C3 mini) - Enable with define USE_USB_SERIAL_CONSOLE
This commit is contained in:
parent
a38c30d6c0
commit
a7e16192e0
@ -2403,13 +2403,24 @@ bool I2cSetDevice(uint32_t addr, uint32_t bus) {
|
|||||||
*
|
*
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
void SetSeriallog(uint32_t loglevel)
|
void SetTasConlog(uint32_t loglevel) {
|
||||||
{
|
|
||||||
Settings->seriallog_level = loglevel;
|
Settings->seriallog_level = loglevel;
|
||||||
TasmotaGlobal.seriallog_level = loglevel;
|
TasmotaGlobal.seriallog_level = loglevel;
|
||||||
TasmotaGlobal.seriallog_timer = 0;
|
TasmotaGlobal.seriallog_timer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetSeriallog(uint32_t loglevel) {
|
||||||
|
#ifdef ESP32
|
||||||
|
if (tasconsole_serial) {
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
|
SetTasConlog(loglevel);
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
}
|
||||||
|
#endif // ESP32
|
||||||
|
}
|
||||||
|
|
||||||
void SetSyslog(uint32_t loglevel)
|
void SetSyslog(uint32_t loglevel)
|
||||||
{
|
{
|
||||||
Settings->syslog_level = loglevel;
|
Settings->syslog_level = loglevel;
|
||||||
@ -2576,7 +2587,7 @@ void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_pa
|
|||||||
|
|
||||||
if ((loglevel <= TasmotaGlobal.seriallog_level) &&
|
if ((loglevel <= TasmotaGlobal.seriallog_level) &&
|
||||||
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
|
(TasmotaGlobal.masterlog_level <= TasmotaGlobal.seriallog_level)) {
|
||||||
Serial.printf("%s%s%s%s\r\n", mxtime, log_data, log_data_payload, log_data_retained);
|
TasConsole.printf("%s%s%s%s\r\n", mxtime, log_data, log_data_payload, log_data_retained);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TasmotaGlobal.log_buffer) { return; } // Leave now if there is no buffer available
|
if (!TasmotaGlobal.log_buffer) { return; } // Leave now if there is no buffer available
|
||||||
|
@ -857,8 +857,18 @@ void CmndOtaUrl(void)
|
|||||||
void CmndSeriallog(void)
|
void CmndSeriallog(void)
|
||||||
{
|
{
|
||||||
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
if (tasconsole_serial) {
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
Settings->flag.mqtt_serial = 0; // CMND_SERIALSEND and CMND_SERIALLOG
|
Settings->flag.mqtt_serial = 0; // CMND_SERIALSEND and CMND_SERIALLOG
|
||||||
SetSeriallog(XdrvMailbox.payload);
|
|
||||||
|
#ifdef ESP32
|
||||||
|
}
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
|
SetTasConlog(XdrvMailbox.payload);
|
||||||
}
|
}
|
||||||
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings->seriallog_level, TasmotaGlobal.seriallog_level);
|
Response_P(S_JSON_COMMAND_NVALUE_ACTIVE_NVALUE, XdrvMailbox.command, Settings->seriallog_level, TasmotaGlobal.seriallog_level);
|
||||||
}
|
}
|
||||||
|
@ -1520,8 +1520,8 @@ void ArduinoOTAInit(void)
|
|||||||
{
|
{
|
||||||
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level)) {
|
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level)) {
|
||||||
arduino_ota_progress_dot_count++;
|
arduino_ota_progress_dot_count++;
|
||||||
Serial.printf(".");
|
TasConsole.printf(".");
|
||||||
if (!(arduino_ota_progress_dot_count % 80)) { Serial.println(); }
|
if (!(arduino_ota_progress_dot_count % 80)) { TasConsole.println(); }
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1533,7 +1533,7 @@ void ArduinoOTAInit(void)
|
|||||||
*/
|
*/
|
||||||
char error_str[100];
|
char error_str[100];
|
||||||
|
|
||||||
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level) && arduino_ota_progress_dot_count) { Serial.println(); }
|
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level) && arduino_ota_progress_dot_count) { TasConsole.println(); }
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case OTA_BEGIN_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_2), sizeof(error_str)); break;
|
case OTA_BEGIN_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_2), sizeof(error_str)); break;
|
||||||
case OTA_RECEIVE_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_5), sizeof(error_str)); break;
|
case OTA_RECEIVE_ERROR: strncpy_P(error_str, PSTR(D_UPLOAD_ERR_5), sizeof(error_str)); break;
|
||||||
@ -1547,7 +1547,7 @@ void ArduinoOTAInit(void)
|
|||||||
|
|
||||||
ArduinoOTA.onEnd([]()
|
ArduinoOTA.onEnd([]()
|
||||||
{
|
{
|
||||||
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level)) { Serial.println(); }
|
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level)) { TasConsole.println(); }
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_UPLOAD "Arduino OTA " D_SUCCESSFUL ". " D_RESTARTING));
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_UPLOAD "Arduino OTA " D_SUCCESSFUL ". " D_RESTARTING));
|
||||||
EspRestart();
|
EspRestart();
|
||||||
});
|
});
|
||||||
@ -1657,6 +1657,10 @@ void SerialInput(void)
|
|||||||
#endif // USE_SONOFF_SC
|
#endif // USE_SONOFF_SC
|
||||||
/*-------------------------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
if (tasconsole_serial) {
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
if (!Settings->flag.mqtt_serial && (TasmotaGlobal.serial_in_byte == '\n')) { // CMND_SERIALSEND and CMND_SERIALLOG
|
if (!Settings->flag.mqtt_serial && (TasmotaGlobal.serial_in_byte == '\n')) { // CMND_SERIALSEND and CMND_SERIALLOG
|
||||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
|
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
|
||||||
TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level;
|
TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level;
|
||||||
@ -1671,7 +1675,12 @@ void SerialInput(void)
|
|||||||
Serial.flush();
|
Serial.flush();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#ifdef ESP32
|
||||||
|
}
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
|
} // endWhile
|
||||||
|
|
||||||
if (Settings->flag.mqtt_serial && TasmotaGlobal.serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG
|
if (Settings->flag.mqtt_serial && TasmotaGlobal.serial_in_byte_counter && (millis() > (serial_polling_window + SERIAL_POLLING))) { // CMND_SERIALSEND and CMND_SERIALLOG
|
||||||
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
|
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0; // Serial data completed
|
||||||
@ -1701,6 +1710,43 @@ void SerialInput(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
|
||||||
|
String console_buffer = "";
|
||||||
|
|
||||||
|
void TasConsoleInput(void) {
|
||||||
|
static bool console_buffer_overrun = false;
|
||||||
|
|
||||||
|
while (TasConsole.available()) {
|
||||||
|
delay(0);
|
||||||
|
char console_in_byte = TasConsole.read();
|
||||||
|
|
||||||
|
if (isprint(console_in_byte)) { // Any char between 32 and 127
|
||||||
|
if (console_buffer.length() < INPUT_BUFFER_SIZE) { // Add char to string if it still fits
|
||||||
|
console_buffer += console_in_byte;
|
||||||
|
} else {
|
||||||
|
console_buffer_overrun = true; // Signal overrun but continue reading input to flush until '\n' (EOL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (console_in_byte == '\n') {
|
||||||
|
TasmotaGlobal.seriallog_level = (Settings->seriallog_level < LOG_LEVEL_INFO) ? (uint8_t)LOG_LEVEL_INFO : Settings->seriallog_level;
|
||||||
|
if (console_buffer_overrun) {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "Console buffer overrun"));
|
||||||
|
} else {
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), console_buffer.c_str());
|
||||||
|
ExecuteCommand(console_buffer.c_str(), SRC_SERIAL);
|
||||||
|
}
|
||||||
|
console_buffer = "";
|
||||||
|
console_buffer_overrun = false;
|
||||||
|
TasConsole.flush();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
/********************************************************************************************/
|
/********************************************************************************************/
|
||||||
|
|
||||||
|
@ -97,6 +97,47 @@ const uint32_t VERSION_MARKER[] PROGMEM = { 0x5AA55AA5, 0xFFFFFFFF, 0xA55AA55A }
|
|||||||
|
|
||||||
WiFiUDP PortUdp; // UDP Syslog and Alexa
|
WiFiUDP PortUdp; // UDP Syslog and Alexa
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
/*
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C3 || // support USB via HWCDC using JTAG interface
|
||||||
|
CONFIG_IDF_TARGET_ESP32S2 || // support USB via USBCDC
|
||||||
|
CONFIG_IDF_TARGET_ESP32S3 // support USB via HWCDC using JTAG interface or USBCDC
|
||||||
|
*/
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
|
||||||
|
//#if CONFIG_TINYUSB_CDC_ENABLED // This define is not recognized here so use USE_USB_SERIAL_CONSOLE
|
||||||
|
#ifdef USE_USB_SERIAL_CONSOLE
|
||||||
|
//#warning **** TasConsole use USB ****
|
||||||
|
|
||||||
|
#if ARDUINO_USB_MODE
|
||||||
|
//#warning **** TasConsole ARDUINO_USB_MODE ****
|
||||||
|
HWCDC TasConsole; // ESP32C3/S3 embedded USB using JTAG interface
|
||||||
|
bool tasconsole_serial = false;
|
||||||
|
//#warning **** TasConsole uses HWCDC ****
|
||||||
|
#else // No ARDUINO_USB_MODE
|
||||||
|
#include "USB.h"
|
||||||
|
#include "USBCDC.h"
|
||||||
|
USBCDC TasConsole; // ESP32Sx embedded USB interface
|
||||||
|
bool tasconsole_serial = false;
|
||||||
|
//#warning **** TasConsole uses USBCDC ****
|
||||||
|
#endif // ARDUINO_USB_MODE
|
||||||
|
|
||||||
|
#else // No USE_USB_SERIAL_CONSOLE
|
||||||
|
HardwareSerial TasConsole = Serial; // Fallback serial interface for ESP32C3, S2 and S3 if no USB_SERIAL defined
|
||||||
|
bool tasconsole_serial = true;
|
||||||
|
//#warning **** TasConsole uses Serial ****
|
||||||
|
#endif // USE_USB_SERIAL_CONSOLE
|
||||||
|
|
||||||
|
#else // No ESP32C3, S2 or S3
|
||||||
|
HardwareSerial TasConsole = Serial; // Fallback serial interface for non ESP32C3, S2 and S3
|
||||||
|
bool tasconsole_serial = true;
|
||||||
|
//#warning **** TasConsole uses Serial ****
|
||||||
|
#endif // ESP32C3, S2 or S3
|
||||||
|
|
||||||
|
#else // No ESP32
|
||||||
|
HardwareSerial TasConsole = Serial; // Only serial interface
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
struct TasmotaGlobal_t {
|
struct TasmotaGlobal_t {
|
||||||
uint32_t global_update; // Timestamp of last global temperature and humidity update
|
uint32_t global_update; // Timestamp of last global temperature and humidity update
|
||||||
uint32_t baudrate; // Current Serial baudrate
|
uint32_t baudrate; // Current Serial baudrate
|
||||||
@ -281,6 +322,7 @@ void setup(void) {
|
|||||||
TasmotaGlobal.active_device = 1;
|
TasmotaGlobal.active_device = 1;
|
||||||
TasmotaGlobal.global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
TasmotaGlobal.global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues
|
||||||
TasmotaGlobal.enable_logging = 1;
|
TasmotaGlobal.enable_logging = 1;
|
||||||
|
TasmotaGlobal.seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded
|
||||||
|
|
||||||
RtcRebootLoad();
|
RtcRebootLoad();
|
||||||
if (!RtcRebootValid()) {
|
if (!RtcRebootValid()) {
|
||||||
@ -301,11 +343,8 @@ void setup(void) {
|
|||||||
uint32_t baudrate = (RtcSettings.baudrate / 300) * 300; // Make it a valid baudrate
|
uint32_t baudrate = (RtcSettings.baudrate / 300) * 300; // Make it a valid baudrate
|
||||||
if (baudrate) { TasmotaGlobal.baudrate = baudrate; }
|
if (baudrate) { TasmotaGlobal.baudrate = baudrate; }
|
||||||
}
|
}
|
||||||
Serial.begin(TasmotaGlobal.baudrate);
|
|
||||||
Serial.println();
|
|
||||||
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
|
|
||||||
TasmotaGlobal.seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded
|
|
||||||
|
|
||||||
|
// Init settings and logging preparing for AddLog use
|
||||||
#ifdef PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED
|
#ifdef PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED
|
||||||
ESP.setIramHeap();
|
ESP.setIramHeap();
|
||||||
Settings = (TSettings*)malloc(sizeof(TSettings)); // Allocate in "new" 16k heap space
|
Settings = (TSettings*)malloc(sizeof(TSettings)); // Allocate in "new" 16k heap space
|
||||||
@ -322,6 +361,31 @@ void setup(void) {
|
|||||||
Settings = (TSettings*)malloc(sizeof(TSettings));
|
Settings = (TSettings*)malloc(sizeof(TSettings));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init command console (either serial or USB) preparing for AddLog use
|
||||||
|
Serial.begin(TasmotaGlobal.baudrate);
|
||||||
|
Serial.println();
|
||||||
|
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
|
||||||
|
#ifdef ESP32
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||||
|
#ifdef USE_USB_SERIAL_CONSOLE
|
||||||
|
TasConsole.begin(115200); // Will always be 115200 bps
|
||||||
|
#if !ARDUINO_USB_MODE
|
||||||
|
USB.begin();
|
||||||
|
#endif // No ARDUINO_USB_MODE
|
||||||
|
TasConsole.println();
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR("CMD: Using embedded USB"));
|
||||||
|
#else // No USE_USB_SERIAL_CONSOLE
|
||||||
|
TasConsole = Serial;
|
||||||
|
#endif // USE_USB_SERIAL_CONSOLE
|
||||||
|
#else // No ESP32C3, S2 or S3
|
||||||
|
TasConsole = Serial;
|
||||||
|
#endif // ESP32C3, S2 or S3
|
||||||
|
#else // No ESP32
|
||||||
|
TasConsole = Serial;
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
|
// Ready for AddLog use
|
||||||
|
|
||||||
// AddLog(LOG_LEVEL_INFO, PSTR("ADR: Settings %p, Log %p"), Settings, TasmotaGlobal.log_buffer);
|
// AddLog(LOG_LEVEL_INFO, PSTR("ADR: Settings %p, Log %p"), Settings, TasmotaGlobal.log_buffer);
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
AddLog(LOG_LEVEL_INFO, PSTR("HDW: %s %s"), GetDeviceHardware().c_str(),
|
AddLog(LOG_LEVEL_INFO, PSTR("HDW: %s %s"), GetDeviceHardware().c_str(),
|
||||||
@ -583,6 +647,9 @@ void Scheduler(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!TasmotaGlobal.serial_local) { SerialInput(); }
|
if (!TasmotaGlobal.serial_local) { SerialInput(); }
|
||||||
|
#ifdef ESP32
|
||||||
|
if (!tasconsole_serial) { TasConsoleInput(); }
|
||||||
|
#endif // ESP32
|
||||||
|
|
||||||
#ifdef USE_ARDUINO_OTA
|
#ifdef USE_ARDUINO_OTA
|
||||||
ArduinoOtaLoop();
|
ArduinoOtaLoop();
|
||||||
|
@ -636,7 +636,7 @@ extern "C" {
|
|||||||
uint32_t len = ext_vsnprintf_P(log_data, LOGSZ-3, berry_buf, arg);
|
uint32_t len = ext_vsnprintf_P(log_data, LOGSZ-3, berry_buf, arg);
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
if (len+3 > LOGSZ) { strcat(log_data, "..."); } // Actual data is more
|
if (len+3 > LOGSZ) { strcat(log_data, "..."); } // Actual data is more
|
||||||
Serial.printf(log_data);
|
TasConsole.printf(log_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void berry_log_C(const char * berry_buf, ...) {
|
void berry_log_C(const char * berry_buf, ...) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user