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:
Theo Arends 2022-05-06 14:57:03 +02:00
parent a38c30d6c0
commit a7e16192e0
5 changed files with 148 additions and 14 deletions

View File

@ -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;
TasmotaGlobal.seriallog_level = loglevel;
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)
{
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) &&
(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

View File

@ -857,8 +857,18 @@ void CmndOtaUrl(void)
void CmndSeriallog(void)
{
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
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);
}

View File

@ -1520,8 +1520,8 @@ void ArduinoOTAInit(void)
{
if ((LOG_LEVEL_DEBUG <= TasmotaGlobal.seriallog_level)) {
arduino_ota_progress_dot_count++;
Serial.printf(".");
if (!(arduino_ota_progress_dot_count % 80)) { Serial.println(); }
TasConsole.printf(".");
if (!(arduino_ota_progress_dot_count % 80)) { TasConsole.println(); }
}
});
@ -1533,7 +1533,7 @@ void ArduinoOTAInit(void)
*/
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) {
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;
@ -1547,7 +1547,7 @@ void ArduinoOTAInit(void)
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));
EspRestart();
});
@ -1657,6 +1657,10 @@ void SerialInput(void)
#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
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;
@ -1671,7 +1675,12 @@ void SerialInput(void)
Serial.flush();
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
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
/********************************************************************************************/

View File

@ -97,6 +97,47 @@ const uint32_t VERSION_MARKER[] PROGMEM = { 0x5AA55AA5, 0xFFFFFFFF, 0xA55AA55A }
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 {
uint32_t global_update; // Timestamp of last global temperature and humidity update
uint32_t baudrate; // Current Serial baudrate
@ -281,6 +322,7 @@ void setup(void) {
TasmotaGlobal.active_device = 1;
TasmotaGlobal.global_state.data = 0xF; // Init global state (wifi_down, mqtt_down) to solve possible network issues
TasmotaGlobal.enable_logging = 1;
TasmotaGlobal.seriallog_level = LOG_LEVEL_INFO; // Allow specific serial messages until config loaded
RtcRebootLoad();
if (!RtcRebootValid()) {
@ -301,11 +343,8 @@ void setup(void) {
uint32_t baudrate = (RtcSettings.baudrate / 300) * 300; // Make it a valid 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
ESP.setIramHeap();
Settings = (TSettings*)malloc(sizeof(TSettings)); // Allocate in "new" 16k heap space
@ -322,6 +361,31 @@ void setup(void) {
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);
#ifdef ESP32
AddLog(LOG_LEVEL_INFO, PSTR("HDW: %s %s"), GetDeviceHardware().c_str(),
@ -583,6 +647,9 @@ void Scheduler(void) {
}
if (!TasmotaGlobal.serial_local) { SerialInput(); }
#ifdef ESP32
if (!tasconsole_serial) { TasConsoleInput(); }
#endif // ESP32
#ifdef USE_ARDUINO_OTA
ArduinoOtaLoop();

View File

@ -636,7 +636,7 @@ extern "C" {
uint32_t len = ext_vsnprintf_P(log_data, LOGSZ-3, berry_buf, arg);
va_end(arg);
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, ...) {