Skip to content

Commit

Permalink
Add ESP32 core v3 auto TasConsole USB or Serial connection by @Staars
Browse files Browse the repository at this point in the history
  • Loading branch information
arendst committed Oct 24, 2023
1 parent 1d5f55d commit 84ced0f
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
- I2C bus2 support to SI1145/6/7 Ultra violet index and light sensor
- I2C bus2 support to LM75AD temperature sensor
- Command ``GpioRead`` to show input state (#19810)
- ESP32 core v3 auto TasConsole USB or Serial connection by @staars

### Breaking Changed

Expand Down
1 change: 1 addition & 0 deletions RELEASENOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- I2C bus2 support to SI1145/6/7 Ultra violet index and light sensor
- I2C bus2 support to LM75AD temperature sensor
- Experimental support for ESP32-C2 and ESP32-C6 using Arduino core v3
- ESP32 core v3 auto TasConsole USB or Serial connection by @staars

### Breaking Changed

Expand Down
110 changes: 110 additions & 0 deletions tasmota/include/tasconsole.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
tasconsole.h - ESP32 tasconsole driver for Tasmota
SPDX-FileCopyrightText: 2023 Christian Baars (@staars)
SPDX-License-Identifier: GPL-3.0-only
*/

#include <memory>

class TASCONSOLE {

struct Concept {
virtual ~Concept() = default;
virtual int available() = 0;
virtual void begin(uint32_t) = 0;
virtual void flush() = 0;
virtual size_t println() = 0;
virtual size_t print(char *) = 0;
virtual size_t printf(const char*, char *, const char*&, const char*&, const char*&) = 0;
virtual size_t printf(char *) = 0;
virtual size_t read() = 0;
virtual size_t setRxBufferSize(size_t) = 0;
};

public:
template <typename T>
TASCONSOLE(T&& obj){
object = std::make_unique<Model<T>>(std::forward<T>(obj));
}

int available() {
return object->available();
}

void begin(uint32_t baud) {
object->begin(baud);
}

void flush() {
object->flush();
}

size_t println() {
return object->println();
}

size_t print(char * string) {
return object->print(string);
}

size_t printf(char *format) {
return object->printf(format);
}

size_t printf(const char* a, char * b, const char*& c, const char*& d, const char*& f){
return object->printf(a,b,c,d,f);
}

size_t read() {
return object->read();
}

size_t setRxBufferSize(size_t rx_queue_len) {
return object->setRxBufferSize(rx_queue_len);
}

template< typename T >
struct Model : Concept {
Model(T const& t) : object(t) {}
int available() override {
return object.available();
}

void begin(uint32_t baud) override {
object.begin(baud);
}

void flush() override {
object.flush();
}

size_t println() override {
return object.println();
}
size_t print(char * string) override {
return object.print(string);
}

size_t printf(char *format) override {
return object.printf(format);
}

size_t printf(const char* a, char * b, const char*& c, const char*& d, const char*& f) override {
return object.printf(a,b,c,d,f);
}

size_t read() override {
return object.read();
}

size_t setRxBufferSize(size_t size) override {
return object.setRxBufferSize(size);
}
private:
T object;
};

std::unique_ptr<Concept> object;
};
111 changes: 110 additions & 1 deletion tasmota/tasmota.ino
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@
#endif // ESP32
#endif // USE_UFILESYS

#if ESP_IDF_VERSION_MAJOR >= 5
#include "include/tasconsole.h"
#if SOC_USB_SERIAL_JTAG_SUPPORTED
#include "hal/usb_serial_jtag_ll.h"
#include "esp_private/rtc_clk.h"
#endif // SOC_USB_SERIAL_JTAG_SUPPORTED
#endif // ESP_IDF_VERSION_MAJOr

// Structs
#include "include/tasmota_types.h"

Expand Down Expand Up @@ -198,6 +206,45 @@ struct XDRVMAILBOX {
WiFiUDP PortUdp; // UDP Syslog and Alexa

#ifdef ESP32
#if ESP_IDF_VERSION_MAJOR >= 5

/*
#if CONFIG_IDF_TARGET_ESP32C3 || // support USB via HWCDC using JTAG interface
CONFIG_IDF_TARGET_ESP32C6 || // 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_ESP32C6 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3

//#if CONFIG_TINYUSB_CDC_ENABLED // This define is not recognized here so use USE_USB_CDC_CONSOLE
#ifdef USE_USB_CDC_CONSOLE
//#warning **** TasConsole use USB ****
bool tasconsole_serial = false;

#if ARDUINO_USB_MODE
//#warning **** TasConsole ARDUINO_USB_MODE ****
TASCONSOLE TasConsole{USBSerial}; // ESP32C3/C6/S3 embedded USB using JTAG interface
//#warning **** TasConsole uses HWCDC ****
#else // No ARDUINO_USB_MODE
#include "USB.h"
#include "USBCDC.h"
TASCONSOLE TasConsole{USBSerial}; // ESP32Sx embedded USB interface
//#warning **** TasConsole uses USBCDC ****
#endif // ARDUINO_USB_MODE

#else // No USE_USB_CDC_CONSOLE
TASCONSOLE TasConsole{Serial};
bool tasconsole_serial = true;
//#warning **** TasConsole uses Serial ****
#endif // USE_USB_CDC_CONSOLE
#else // No ESP32C3, S2 or S3
TASCONSOLE TasConsole{Serial};
bool tasconsole_serial = true;
//#warning **** TasConsole uses Serial ****
#endif // ESP32C3, S2 or S3

#else // ESP_IDF_VERSION_MAJOR < 5

/*
#if CONFIG_IDF_TARGET_ESP32C3 || // support USB via HWCDC using JTAG interface
CONFIG_IDF_TARGET_ESP32C6 || // support USB via HWCDC using JTAG interface
Expand Down Expand Up @@ -235,6 +282,8 @@ bool tasconsole_serial = true;
//#warning **** TasConsole uses Serial ****
#endif // ESP32C3, S2 or S3

#endif // ESP_IDF_VERSION_MAJOR >= 5

#else // No ESP32
HardwareSerial TasConsole = Serial; // Only serial interface
#endif // ESP32
Expand Down Expand Up @@ -478,11 +527,64 @@ void setup(void) {
Settings = (TSettings*)malloc(sizeof(TSettings));
}

#ifdef ESP32
#if ESP_IDF_VERSION_MAJOR >= 5

#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#ifdef USE_USB_CDC_CONSOLE
bool is_connected_to_USB = false;

#if SOC_USB_SERIAL_JTAG_SUPPORTED // Not S2
rtc_clk_bbpll_add_consumer(); // Maybe unneeded
usb_serial_jtag_ll_ena_intr_mask(USB_SERIAL_JTAG_INTR_SOF);
usb_serial_jtag_ll_clr_intsts_mask(USB_SERIAL_JTAG_INTR_SOF);
// First check if USB cable is connected - maybe add a new SetOption to prevent this
for (uint32_t i = 0; i < 1000; i++) { // Allow the host to send at least one SOF packet, 1ms should be enough but let's be very conservative here - maybe unneeded
is_connected_to_USB = ((usb_serial_jtag_ll_get_intraw_mask() & USB_SERIAL_JTAG_INTR_SOF) != 0);
if (is_connected_to_USB) { break; }
delay(1);
}
rtc_clk_bbpll_remove_consumer();
#endif // SOC_USB_SERIAL_JTAG_SUPPORTED

if (is_connected_to_USB) {
TasConsole.setRxBufferSize(INPUT_BUFFER_SIZE);
// TasConsole.setTxBufferSize(INPUT_BUFFER_SIZE);
TasConsole.begin(115200); // Will always be 115200 bps
#if !ARDUINO_USB_MODE
USB.begin(); // This needs a serial console with DTR/DSR support
#endif // No ARDUINO_USB_MODE
TasConsole.println();
AddLog(LOG_LEVEL_INFO, PSTR("CMD: Using USB CDC"));
} else {
// Init command serial console preparing for AddLog use
Serial.begin(TasmotaGlobal.baudrate);
Serial.println();
TasConsole = Serial; // Fallback
tasconsole_serial = true;
AddLog(LOG_LEVEL_INFO, PSTR("CMD: Fall back to serial port, no SOF packet detected on USB port"));
}
#else // No USE_USB_CDC_CONSOLE
// Init command serial console preparing for AddLog use
Serial.begin(TasmotaGlobal.baudrate);
Serial.println();
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
TasConsole = Serial;
#endif // USE_USB_CDC_CONSOLE
#else // No ESP32C3, S2 or S3
// Init command serial console preparing for AddLog use
Serial.begin(TasmotaGlobal.baudrate);
Serial.println();
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
TasConsole = Serial;
#endif // ESP32C3, S2 or S3

#else // ESP_IDF_VERSION_MAJOR < 5

// 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_ESP32C6 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#ifdef USE_USB_CDC_CONSOLE
TasConsole.setRxBufferSize(INPUT_BUFFER_SIZE);
Expand All @@ -499,7 +601,14 @@ void setup(void) {
#else // No ESP32C3, S2 or S3
TasConsole = Serial;
#endif // ESP32C3, S2 or S3

#endif // ESP_IDF_VERSION_MAJOR >= 5

#else // No ESP32
// Init command serial console preparing for AddLog use
Serial.begin(TasmotaGlobal.baudrate);
Serial.println();
// Serial.setRxBufferSize(INPUT_BUFFER_SIZE); // Default is 256 chars
TasConsole = Serial;
#endif // ESP32

Expand Down

0 comments on commit 84ced0f

Please sign in to comment.