Add Usb Serial otg feature (#1055)

* Update esp3d_version.h
* Fix GCode client is not processed
* Update lua engine to 1.0.3
* Fix HOOKS and Init script conflicting at boot
* Add a queue for multiple scripts (max 5)
* Fix compilation failed on SERIAL_MKS on ESP32
* Explain better sanity check on SERIAL_MKS and DISPLAY
* Implement USB Serial OTG
This commit is contained in:
Luc 2024-10-19 18:13:45 +08:00 committed by GitHub
parent 9bac144416
commit b40937122a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
185 changed files with 9985 additions and 93 deletions

View File

@ -12,7 +12,8 @@ cp -r ./libraries/DHT_sensor_library_for_ESPx-1.0.6 $HOME/arduino_ide/libraries/
cp -r ./libraries/esp8266-oled-ssd1306-4.3.0 $HOME/arduino_ide/libraries/ cp -r ./libraries/esp8266-oled-ssd1306-4.3.0 $HOME/arduino_ide/libraries/
cp -r ./libraries/TFT_eSPI-2.5.43 $HOME/arduino_ide/libraries/ cp -r ./libraries/TFT_eSPI-2.5.43 $HOME/arduino_ide/libraries/
cp -r ./libraries/lvgl-8.2.0 $HOME/arduino_ide/libraries/ cp -r ./libraries/lvgl-8.2.0 $HOME/arduino_ide/libraries/
cp -r ./libraries/EspLuaEngine-1.0.2 $HOME/arduino_ide/libraries/ cp -r ./libraries/EspLuaEngine-1.0.3 $HOME/arduino_ide/libraries/
cp -r ./libraries/BMx280MI-1.2.0 $HOME/arduino_ide/libraries/ cp -r ./libraries/BMx280MI-1.2.0 $HOME/arduino_ide/libraries/
cp -r ./libraries/esp32-usb-serial-1.0.1 $HOME/arduino_ide/libraries/
#TODO add SDFat libraries according version and target #TODO add SDFat libraries according version and target

57
docs/Module-client.md Normal file
View File

@ -0,0 +1,57 @@
# Module client
## Summary
A module client is a class that represent a client, it handle commands from outside to the ESP3D, and handle commands from ESP3D to outside.
WebDav, FTP ,SSDP , MDNS are not module client, they are modules that handle in/out data differently.
The main clients are : Serial, USB Serial, Telnet, WebSocket are kind of full duplex, the http client is a half duplex client for everything but ESP3D commands, in that case it is a full duplex client.
## General description of data flow
The module client fill a buffer char by char until char `\n` or `r` is found or buffer is full, the data come from outside, serial port, usb port, telnet, websocket.
The catch of the commands is done by specific library, and the library inform the module client that a command is received, the module client will then dispatch the command to the ESP3D.
To do that the module client will add some context data to the command, the context data is the client type, the authentication level, the origin of the command, the target of the command, the size of the data, and the data itself. It is called a message.
there 3 cases:
* If a command is not recognized as ESP3D command and origin is not the printer/cnc the message will be transfered to the communication module client with the printer/cnc.
* If the command is recognized as ESP3D command what ever the origin, the message will be transfered to the ESP3D, and the message will change the origin as the target to answer the command.
* If a command is not recognized as ESP3D command and origin is the printer/cnc the message will be dispatched all clients.
The messages are stored in a FIFO which can be accessed from different thread on the ESP32 when it is done by differents functions on ESP8266 sequentially.
Note: Each message is a unique object, it is not possible to send the same message twice, in case of multiple client the message will be duplicated.
Note 2: message are dynamicaly allocated in memory, which means that when dispatch is done or failed the message must be freed to avoid any memory leak.
## Serial
Serial is a full duplex client, it is the default output client for printer/cnc. It use the native Serial library of the ESP32 and ESP8266.
### Output -> ESP3D
The Serial API allow to hook a function to be called when some data is received.
`Serials[_serialIndex]->onReceive(receiveSerialCb);`
When called the function read the data char by char until char `\n` or `r` is found or buffer is full, if it is the case the data is packaged as message and dispatched to the FIFO list by the flush function.
The FIFO list is accessed from different thread/function on the ESP32, it is done by differents functions sequentially on ESP8266 .
The handle function is the one that will dispatch the message to the defined target.
### ESP3D -> Output
When dispatched the message is packaged and sent to the targeted output client. It is delivered to client module by the function `dispatch(ESP3DMessage *message)`.
The message data will be delivered to the client module by the function `writeBytes(const uint8_t *buffer, size_t size)` and using the available function `availableForWrite()` to know how many data can be sent will dispatch the data to Serial.
## USB Serial
USB Serial is a full duplex client, it is optional output client for ESP32 S2/S3 only. It use the esp32-usb-serial library.
The Library has 2 intialization functions: `usb_serial_init()` and `usb_serial_create_task()` which handle usb events.
if no need to handle usb events just call `usb_serial_init()` and do not call `usb_serial_create_task()`.
Additionaly USB Serial client has a dedicated task that check if there is any supported USB Serial device connected, it try all drivers one by one until it find one that match the supported ones.
If device is found it willhook a usb event function and a onreceive function to handle data.

View File

@ -158,9 +158,15 @@ SENSOR_INTERVAL = 30000
#Target Firmware Marlin / Repetier / MarlinKimbra / Smoothieware / GRBL #Target Firmware Marlin / Repetier / MarlinKimbra / Smoothieware / GRBL
TargetFW=Marlin TargetFW=Marlin
#Output: SERIAL / USB
output=SERIAL
#Baud Rate #Baud Rate
Baud_rate = 115200 Baud_rate = 115200
#Baud Rate
USB_Serial_Baud_rate = 115200
#Boot delay in ms #Boot delay in ms
Boot_delay = 5000 Boot_delay = 5000

View File

@ -64,7 +64,7 @@
*/ */
#define COMMUNICATION_PROTOCOL RAW_SERIAL #define COMMUNICATION_PROTOCOL RAW_SERIAL
/* Main Serial port /* Main Serial port / Ouptut
* which serial ESP use to communicate to printer (ESP32 has 3 serials * which serial ESP use to communicate to printer (ESP32 has 3 serials
* available, ESP8266 only 2) USE_SERIAL_0 //for ESP8266/32, also used by * available, ESP8266 only 2) USE_SERIAL_0 //for ESP8266/32, also used by
* bootloader output, so consider to make it quiet USE_SERIAL_1 //for ESP8266/32 * bootloader output, so consider to make it quiet USE_SERIAL_1 //for ESP8266/32
@ -73,6 +73,13 @@
// Main serial port // Main serial port
#define ESP_SERIAL_OUTPUT USE_SERIAL_0 #define ESP_SERIAL_OUTPUT USE_SERIAL_0
/* Optional Output
* Instead of Serial, you can use USB Serial
* USE_USB_SERIAL //for ESP32 S2/S3 Only
*/
//#define USB_SERIAL_FEATURE
/* Bridge Serial port (deprecated on esp8266 as second serial is) /* Bridge Serial port (deprecated on esp8266 as second serial is)
* which serial ESP use to bridge to another device (ESP32 has 3 serials * which serial ESP use to bridge to another device (ESP32 has 3 serials
* available, ESP8266 only 2) USE_SERIAL_0 //for ESP8266/32, also used by * available, ESP8266 only 2) USE_SERIAL_0 //for ESP8266/32, also used by
@ -579,6 +586,7 @@
* Commands to run on startup * Commands to run on startup
* Separate commands with ';' or use file * Separate commands with ';' or use file
*/ */
// #define ESP_AUTOSTART_SCRIPT "[ESP300]/FS/init.lua\n"
// #define ESP_AUTOSTART_SCRIPT "M117 Mounting SD;M21" // #define ESP_AUTOSTART_SCRIPT "M117 Mounting SD;M21"
// #define ESP_AUTOSTART_SCRIPT_FILE "autoscript.gco" // #define ESP_AUTOSTART_SCRIPT_FILE "autoscript.gco"
@ -625,9 +633,9 @@
// LOG_OUTPUT_SERIAL2 // LOG_OUTPUT_SERIAL2
// LOG_OUTPUT_TELNET // LOG_OUTPUT_TELNET
// LOG_OUTPUT_WEBSOCKET // LOG_OUTPUT_WEBSOCKET
//#define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0 // #define ESP_LOG_FEATURE LOG_OUTPUT_SERIAL0
//#define ESP3D_DEBUG_LEVEL LOG_LEVEL_DEBUG // #define ESP3D_DEBUG_LEVEL LOG_LEVEL_DEBUG
#ifdef ESP_LOG_FEATURE #ifdef ESP_LOG_FEATURE
#define LOG_ESP3D_BAUDRATE 115200 #define LOG_ESP3D_BAUDRATE 115200

View File

@ -179,6 +179,9 @@ const char* help[] = {
"[ESP900](ENABLE/DISABLE) - display/set serial state", "[ESP900](ENABLE/DISABLE) - display/set serial state",
"[ESP901]<BAUD RATE> - display/set serial baud rate", "[ESP901]<BAUD RATE> - display/set serial baud rate",
#endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL
#if defined(USB_SERIAL_FEATURE)
"[ESP902]<BAUD RATE> - display/set USB Serial baud rate",
#endif // defined(USB_SERIAL_FEATURE)
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
"[ESP910](ENABLE/DISABLE) - display/set buzzer state", "[ESP910](ENABLE/DISABLE) - display/set buzzer state",
#endif // BUZZER_DEVICE #endif // BUZZER_DEVICE
@ -186,6 +189,9 @@ const char* help[] = {
"[ESP930](ENABLE/DISABLE/CLOSE) - display/set serial bridge state", "[ESP930](ENABLE/DISABLE/CLOSE) - display/set serial bridge state",
"[ESP931]<BAUD RATE> - display/set serial bridge baud rate", "[ESP931]<BAUD RATE> - display/set serial bridge baud rate",
#endif // defined(ESP_SERIAL_BRIDGE_OUTPUT) #endif // defined(ESP_SERIAL_BRIDGE_OUTPUT)
#if defined(USB_SERIAL_FEATURE)
"[ESP950]<SERIAL/USB> - display/set client output",
#endif // defined(USB_SERIAL_FEATURE)
#if defined(ARDUINO_ARCH_ESP32) && \ #if defined(ARDUINO_ARCH_ESP32) && \
(CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 || \ (CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 || \
CONFIG_IDF_TARGET_ESP32C3) CONFIG_IDF_TARGET_ESP32C3)
@ -304,13 +310,18 @@ const uint cmdlist[] = {
#if COMMUNICATION_PROTOCOL != SOCKET_SERIAL #if COMMUNICATION_PROTOCOL != SOCKET_SERIAL
900, 901, 900, 901,
#endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL
#if defined(USB_SERIAL_FEATURE)
902,
#endif // defined(USB_SERIAL_FEATURE)
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
910, 910,
#endif // BUZZER_DEVICE #endif // BUZZER_DEVICE
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
930, 931, 930, 931,
#endif // defined(ESP_SERIAL_BRIDGE_OUTPUT) #endif // defined(ESP_SERIAL_BRIDGE_OUTPUT)
#if defined(USB_SERIAL_FEATURE)
950,
#endif // defined(USB_SERIAL_FEATURE)
#if defined(ARDUINO_ARCH_ESP32) && \ #if defined(ARDUINO_ARCH_ESP32) && \
(CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 || \ (CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 || \
CONFIG_IDF_TARGET_ESP32C3) CONFIG_IDF_TARGET_ESP32C3)

View File

@ -32,6 +32,20 @@
#endif // TIMESTAMP_FEATURE #endif // TIMESTAMP_FEATURE
#define COMMAND_ID 400 #define COMMAND_ID 400
#ifndef STRINGIFY
#define STRINGIFY(x) #x
#endif // STRINGIFY
#define STRING(x) STRINGIFY(x)
#if defined(USB_SERIAL_FEATURE)
const char* OutputClientsLabels[] = {
"serial port",
"usb port",
};
const char* OutputClientsValues[] = {"1",
"2"};
#endif // USB_SERIAL_FEATURE
const char* YesNoLabels[] = {"no", "yes"}; const char* YesNoLabels[] = {"no", "yes"};
const char* YesNoValues[] = {"0", "1"}; const char* YesNoValues[] = {"0", "1"};
const char* RadioModeLabels[] = {"none" const char* RadioModeLabels[] = {"none"
@ -121,10 +135,14 @@ const char* IpModeValues[] = {"0", "1"};
const char* SupportedApChannelsStr[] = {"1", "2", "3", "4", "5", "6", "7", const char* SupportedApChannelsStr[] = {"1", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "11", "12", "13", "14"}; "8", "9", "10", "11", "12", "13", "14"};
/// Note Currently the Serial and USB Serial baud rate list is the same
// if this change this part need to be updated
const char* SupportedBaudListSizeStr[] = { const char* SupportedBaudListSizeStr[] = {
"9600", "19200", "38400", "57600", "74880", "115200", "230400", "9600", "19200", "38400", "57600", "74880", "115200", "230400",
"250000", "500000", "921600", "1000000", "1958400", "2000000"}; "250000", "500000", "921600", "1000000", "1958400", "2000000"};
#ifdef SENSOR_DEVICE #ifdef SENSOR_DEVICE
const char* SensorLabels[] = {"none" const char* SensorLabels[] = {"none"
@ -219,27 +237,31 @@ void ESP3DCommands::ESP400(int cmd_params_pos, ESP3DMessage* msg) {
-1, -1, -1, NULL, true, target, requestId); -1, -1, -1, NULL, true, target, requestId);
#if defined(ETH_FEATURE) #if defined(ETH_FEATURE)
// Ethernet STA IP mode // Ethernet STA IP mode
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_IP_MODE, "ip mode", IpModeValues, dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_IP_MODE, "ip mode",
IpModeLabels, sizeof(IpModeLabels) / sizeof(char*), -1, -1, IpModeValues, IpModeLabels,
-1, nullptr, true, target, requestId); sizeof(IpModeLabels) / sizeof(char*), -1, -1, -1, nullptr,
true, target, requestId);
// Ethernet STA static IP // Ethernet STA static IP
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_IP_VALUE, "ip", nullptr, nullptr, dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_IP_VALUE, "ip", nullptr,
-1, -1, -1, -1, nullptr, true, target, requestId); nullptr, -1, -1, -1, -1, nullptr, true, target, requestId);
// Ethernet STA static Gateway // Ethernet STA static Gateway
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_GATEWAY_VALUE, "gw", nullptr, dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_GATEWAY_VALUE, "gw",
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId); nullptr, nullptr, -1, -1, -1, -1, nullptr, true, target,
requestId);
// Ethernet STA static Mask // Ethernet STA static Mask
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_MASK_VALUE, "msk", nullptr, dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_MASK_VALUE, "msk",
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId); nullptr, nullptr, -1, -1, -1, -1, nullptr, true, target,
requestId);
// Ethernet STA static DNS // Ethernet STA static DNS
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_DNS_VALUE, "DNS", nullptr, dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_DNS_VALUE, "DNS",
nullptr, -1, -1, -1, -1, nullptr, true, target, requestId); nullptr, nullptr, -1, -1, -1, -1, nullptr, true, target,
requestId);
// Ethernet Sta fallback mode // Ethernet Sta fallback mode
dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_FALLBACK_MODE, dispatchSetting(json, "network/eth-sta", ESP_ETH_STA_FALLBACK_MODE,
"sta fallback mode", EthFallbackValues, EthFallbackLabels, "sta fallback mode", EthFallbackValues, EthFallbackLabels,
sizeof(EthFallbackValues) / sizeof(char*), -1, -1, -1, nullptr, sizeof(EthFallbackValues) / sizeof(char*), -1, -1, -1,
true, target, requestId); nullptr, true, target, requestId);
#endif // ETH_FEATURE #endif // ETH_FEATURE
#ifdef WIFI_FEATURE #ifdef WIFI_FEATURE
// STA SSID network/sta // STA SSID network/sta
@ -497,7 +519,20 @@ void ESP3DCommands::ESP400(int cmd_params_pos, ESP3DMessage* msg) {
true, target, requestId); true, target, requestId);
#endif // FIXED_FW_TARGET #endif // FIXED_FW_TARGET
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
// Baud Rate #if defined(USB_SERIAL_FEATURE)
dispatchSetting(json, "system/system", ESP_OUTPUT_CLIENT, "output",
OutputClientsValues, OutputClientsLabels,
sizeof(OutputClientsValues) / sizeof(char*), -1, -1, -1,
nullptr, true, target, requestId);
// Usb-Serial Baud Rate
dispatchSetting(json, "system/system", ESP_USB_SERIAL_BAUD_RATE,
"usb-serial baud", SupportedBaudListSizeStr,
SupportedBaudListSizeStr,
sizeof(SupportedBaudListSizeStr) / sizeof(char*), -1, -1, -1,
nullptr, true, target, requestId);
#endif // defined(USB_SERIAL_FEATURE)
// Serial Baud Rate
dispatchSetting(json, "system/system", ESP_BAUD_RATE, "baud", dispatchSetting(json, "system/system", ESP_BAUD_RATE, "baud",
SupportedBaudListSizeStr, SupportedBaudListSizeStr, SupportedBaudListSizeStr, SupportedBaudListSizeStr,
sizeof(SupportedBaudListSizeStr) / sizeof(char*), -1, -1, -1, sizeof(SupportedBaudListSizeStr) / sizeof(char*), -1, -1, -1,

View File

@ -82,6 +82,10 @@
#include "../../modules/authentication/authentication_service.h" #include "../../modules/authentication/authentication_service.h"
#endif // AUTHENTICATION_FEATURE #endif // AUTHENTICATION_FEATURE
#if defined(USB_SERIAL_FEATURE)
#include "../../modules/usb-serial/usb_serial_service.h"
#endif // defined(USB_SERIAL_FEATURE)
// Get ESP current status // Get ESP current status
// output is JSON or plain text according parameter // output is JSON or plain text according parameter
//[ESP420]json=<no> //[ESP420]json=<no>
@ -157,14 +161,14 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
// FW architecture // FW architecture
tmpstr = ESP3DSettings::TargetBoard(); tmpstr = ESP3DSettings::TargetBoard();
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
tmpstr = ESP.getChipModel(); tmpstr = ESP.getChipModel();
tmpstr+="-"; tmpstr += "-";
tmpstr+=ESP.getChipRevision(); tmpstr += ESP.getChipRevision();
tmpstr+="-"; tmpstr += "-";
tmpstr+=ESP.getChipCores(); tmpstr += ESP.getChipCores();
tmpstr+="@"; tmpstr += "@";
#endif // ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
if (!dispatchIdValue(json, "FW arch", tmpstr.c_str(), target, requestId, if (!dispatchIdValue(json, "FW arch", tmpstr.c_str(), target, requestId,
false)) { false)) {
return; return;
@ -217,15 +221,39 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
return; return;
} }
#endif // FILESYSTEM_FEATURE #endif // FILESYSTEM_FEATURE
#if defined(USB_SERIAL_FEATURE)
tmpstr = "???";
if (esp3d_commands.getOutputClient() == ESP3DClientType::usb_serial) {
tmpstr = "usb port";
}
if (esp3d_commands.getOutputClient() == ESP3DClientType::serial) {
tmpstr = "serial port";
}
if (!dispatchIdValue(json, "output", tmpstr.c_str(), target, requestId)) {
return;
}
if (esp3d_commands.getOutputClient() == ESP3DClientType::usb_serial) {
tmpstr = String(esp3d_usb_serial_service.baudRate());
if (!dispatchIdValue(json, "baud", tmpstr.c_str(), target, requestId,
false)) {
return;
}
}
#endif // defined(USB_SERIAL_FEATURE)
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
if (esp3d_commands.getOutputClient() == ESP3DClientType::serial) {
// baud rate // baud rate
tmpstr = String(esp3d_serial_service.baudRate()); tmpstr = String(esp3d_serial_service.baudRate());
if (!dispatchIdValue(json, "baud", tmpstr.c_str(), target, requestId, if (!dispatchIdValue(json, "baud", tmpstr.c_str(), target, requestId,
false)) { false)) {
return; return;
} }
}
#endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
// MKS_SERIAL // MKS_SERIAL
#if defined(WIFI_FEATURE) #if defined(WIFI_FEATURE)
if (WiFi.getMode() != WIFI_OFF) { if (WiFi.getMode() != WIFI_OFF) {
// sleep mode // sleep mode
@ -397,7 +425,7 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
return; return;
} }
// IP mode // IP mode
esp3d_log_d("IP mode %d", NetConfig::isIPModeDHCP(ESP_ETH_STA)); esp3d_log("IP mode %d", NetConfig::isIPModeDHCP(ESP_ETH_STA));
tmpstr = (NetConfig::isIPModeDHCP(ESP_ETH_STA)) ? "dhcp" : "static"; tmpstr = (NetConfig::isIPModeDHCP(ESP_ETH_STA)) ? "dhcp" : "static";
if (!dispatchIdValue(json, "ip mode", tmpstr.c_str(), target, requestId, if (!dispatchIdValue(json, "ip mode", tmpstr.c_str(), target, requestId,
false)) { false)) {
@ -428,8 +456,7 @@ void ESP3DCommands::ESP420(int cmd_params_pos, ESP3DMessage* msg) {
return; return;
} }
} else { } else {
if (!dispatchIdValue(json, "ethernet", "OFF", target, requestId, if (!dispatchIdValue(json, "ethernet", "OFF", target, requestId, false)) {
false)) {
return; return;
} }
} }

View File

@ -0,0 +1,86 @@
/*
ESP902.cpp - ESP3D command class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../include/esp3d_config.h"
#if defined(USB_SERIAL_FEATURE)
#include "../../modules/authentication/authentication_service.h"
#include "../../modules/usb-serial/usb_serial_service.h"
#include "../esp3d_commands.h"
#include "../esp3d_settings.h"
#define COMMAND_ID 902
// Set USB Serial baudrate
//[ESP902]<baude rate> json=<no> pwd=<admin password>
void ESP3DCommands::ESP902(int cmd_params_pos, ESP3DMessage* msg) {
ESP3DClientType target = msg->origin;
ESP3DRequest requestId = msg->request_id;
(void)requestId;
msg->target = target;
msg->origin = ESP3DClientType::command;
bool hasError = false;
String error_msg = "Invalid parameters";
String ok_msg = "ok";
bool json = hasTag(msg, cmd_params_pos, "json");
String tmpstr;
#if defined(AUTHENTICATION_FEATURE)
if (msg->authentication_level == ESP3DAuthenticationLevel::guest) {
msg->authentication_level = ESP3DAuthenticationLevel::not_authenticated;
dispatchAuthenticationError(msg, COMMAND_ID, json);
return;
}
#endif // AUTHENTICATION_FEATURE
tmpstr = get_clean_param(msg, cmd_params_pos);
if (tmpstr.length() == 0) {
const ESP3DSettingDescription* settingPtr =
ESP3DSettings::getSettingPtr(ESP_USB_SERIAL_BAUD_RATE);
if (settingPtr) {
ok_msg = String(ESP3DSettings::readUint32(ESP_USB_SERIAL_BAUD_RATE));
} else {
hasError = true;
error_msg = "This setting is unknown";
}
} else {
#if defined(AUTHENTICATION_FEATURE)
if (msg->authentication_level != ESP3DAuthenticationLevel::admin) {
dispatchAuthenticationError(msg, COMMAND_ID, json);
return;
}
#endif // AUTHENTICATION_FEATURE
esp3d_log(
"got %s param for a value of %s, is valid %d", tmpstr.c_str(),
tmpstr.c_str(),
ESP3DSettings::isValidIntegerSetting(tmpstr.toInt(), ESP_USB_SERIAL_BAUD_RATE));
if (ESP3DSettings::isValidIntegerSetting(tmpstr.toInt(), ESP_USB_SERIAL_BAUD_RATE)) {
esp3d_log("Value %s is valid", tmpstr.c_str());
if (!ESP3DSettings::writeUint32(ESP_USB_SERIAL_BAUD_RATE, tmpstr.toInt())) {
hasError = true;
error_msg = "Set value failed";
}
} else {
hasError = true;
error_msg = "Invalid parameter";
}
}
if (!dispatchAnswer(msg, COMMAND_ID, json, hasError,
hasError ? error_msg.c_str() : ok_msg.c_str())) {
esp3d_log_e("Error sending response to clients");
}
}
#endif // defined(USB_SERIAL_FEATURE)

View File

@ -0,0 +1,79 @@
/*
ESP950.cpp - ESP3D command class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../include/esp3d_config.h"
#if defined(USB_SERIAL_FEATURE)
#include "../../modules/authentication/authentication_service.h"
#include "../esp3d_commands.h"
#include "../esp3d_settings.h"
#define COMMAND_ID 950
// Get / Set Serial Output
//[ESP950]<SERIAL/USB> json=<no> pwd=<admin/user password>
void ESP3DCommands::ESP950(int cmd_params_pos, ESP3DMessage* msg) {
ESP3DClientType target = msg->origin;
ESP3DRequest requestId = msg->request_id;
(void)requestId;
msg->target = target;
msg->origin = ESP3DClientType::command;
bool hasError = false;
String error_msg = "Invalid parameters";
String ok_msg = "ok";
bool json = hasTag(msg, cmd_params_pos, "json");
String tmpstr;
#if defined(AUTHENTICATION_FEATURE)
if (msg->authentication_level == ESP3DAuthenticationLevel::guest) {
msg->authentication_level = ESP3DAuthenticationLevel::not_authenticated;
dispatchAuthenticationError(msg, COMMAND_ID, json);
return;
}
#endif // AUTHENTICATION_FEATURE
tmpstr = get_clean_param(msg, cmd_params_pos);
if (tmpstr.length() == 0) {
uint8_t setting_mode = ESP3DSettings::readByte(ESP_OUTPUT_CLIENT);
if (setting_mode == (uint8_t)ESP3DClientType::usb_serial) {
ok_msg = "USB";
} else {
ok_msg = "SERIAL";
}
} else {
#if defined(AUTHENTICATION_FEATURE)
if (msg->authentication_level != ESP3DAuthenticationLevel::admin) {
dispatchAuthenticationError(msg, COMMAND_ID, json);
return;
}
#endif // AUTHENTICATION_FEATURE
if (tmpstr == "USB" || tmpstr == "SERIAL") {
if (!ESP3DSettings::writeByte(ESP_OUTPUT_CLIENT, tmpstr == "USB" ? (uint8_t)ESP3DClientType::usb_serial: (uint8_t)ESP3DClientType::serial)) {
hasError = true;
error_msg = "Set value failed";
}
} else {
hasError = true;
error_msg = "Invalid parameter";
}
}
if (!dispatchAnswer(msg, COMMAND_ID, json, hasError,
hasError ? error_msg.c_str() : ok_msg.c_str())) {
esp3d_log_e("Error sending response to clients");
}
}
#endif // USB_SERIAL_FEATURE

View File

@ -28,6 +28,7 @@
#include "../include/esp3d_config.h" #include "../include/esp3d_config.h"
#include "esp3d_settings.h" #include "esp3d_settings.h"
#include "esp3d_commands.h"
#if COMMUNICATION_PROTOCOL != SOCKET_SERIAL || ESP_SERIAL_BRIDGE_OUTPUT #if COMMUNICATION_PROTOCOL != SOCKET_SERIAL || ESP_SERIAL_BRIDGE_OUTPUT
#include "../modules/serial/serial_service.h" #include "../modules/serial/serial_service.h"
@ -58,6 +59,9 @@
#ifdef ESP_LUA_INTERPRETER_FEATURE #ifdef ESP_LUA_INTERPRETER_FEATURE
#include "../modules/lua_interpreter/lua_interpreter_service.h" #include "../modules/lua_interpreter/lua_interpreter_service.h"
#endif // ESP_LUA_INTERPRETER_FEATURE #endif // ESP_LUA_INTERPRETER_FEATURE
#if defined(USB_SERIAL_FEATURE)
#include "../modules/usb-serial/usb_serial_service.h"
#endif // USB_SERIAL_FEATURE
bool Esp3D::restart = false; bool Esp3D::restart = false;
@ -102,8 +106,21 @@ bool Esp3D::begin() {
// Restart ESP3D // Restart ESP3D
restart_now(); restart_now();
} }
esp3d_commands.getOutputClient(true);
#if defined(USB_SERIAL_FEATURE)
if (esp3d_commands.getOutputClient() == ESP3DClientType::usb_serial) {
if (!esp3d_usb_serial_service.begin()) {
esp3d_log_e("Error with usb serial service");
res = false;
}
}
#endif // USB_SERIAL_FEATURE
// BT do not start automaticaly so should be OK // BT do not start automaticaly so should be OK
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
// Serial service // Serial service
if (!esp3d_serial_service.begin(ESP_SERIAL_OUTPUT)) { if (!esp3d_serial_service.begin(ESP_SERIAL_OUTPUT)) {
esp3d_log_e("Error with serial service"); esp3d_log_e("Error with serial service");
@ -163,6 +180,9 @@ void Esp3D::handle() {
if (restart) { if (restart) {
restart_now(); restart_now();
} }
#if defined(USB_SERIAL_FEATURE)
esp3d_usb_serial_service.handle();
#endif // USB_SERIAL_FEATURE
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
esp3d_serial_service.handle(); esp3d_serial_service.handle();
#endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==
@ -205,6 +225,9 @@ bool Esp3D::end() {
#if defined(FILESYSTEM_FEATURE) #if defined(FILESYSTEM_FEATURE)
ESP_FileSystem::end(); ESP_FileSystem::end();
#endif // FILESYSTEM_FEATURE #endif // FILESYSTEM_FEATURE
#if defined(USB_SERIAL_FEATURE)
esp3d_usb_serial_service.end();
#endif // USB_SERIAL_FEATURE
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
esp3d_serial_service.end(); esp3d_serial_service.end();
#endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL ==

View File

@ -82,9 +82,18 @@ const char *esp3dmsgstr[] = {"head", "core", "tail", "unique"};
#include "../modules/display/display.h" #include "../modules/display/display.h"
#endif // DISPLAY_DEVICE #endif // DISPLAY_DEVICE
#if defined(GCODE_HOST_FEATURE)
#include "../modules/gcode_host/gcode_host.h"
#endif // GCODE_HOST_FEATURE
#if defined(USB_SERIAL_FEATURE)
#include "../modules/usb-serial/usb_serial_service.h"
#endif // USB_SERIAL_FEATURE
ESP3DCommands esp3d_commands; ESP3DCommands esp3d_commands;
ESP3DCommands::ESP3DCommands() { ESP3DCommands::ESP3DCommands() {
//Need to sync with setting part
#if COMMUNICATION_PROTOCOL == RAW_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL
_output_client = ESP3DClientType::serial; _output_client = ESP3DClientType::serial;
#endif // COMMUNICATION_PROTOCOL == RAW_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL
@ -335,6 +344,7 @@ void ESP3DCommands::execute_internal_command(int cmd, int cmd_params_pos,
msg->origin == ESP3DClientType::serial_bridge || msg->origin == ESP3DClientType::serial_bridge ||
msg->origin == ESP3DClientType::telnet || msg->origin == ESP3DClientType::telnet ||
msg->origin == ESP3DClientType::websocket || msg->origin == ESP3DClientType::websocket ||
msg->origin == ESP3DClientType::usb_serial ||
msg->origin == ESP3DClientType::bluetooth)) { msg->origin == ESP3DClientType::bluetooth)) {
msg->authentication_level = msg->authentication_level =
AuthenticationService::getAuthenticatedLevel(pwd.c_str(), msg); AuthenticationService::getAuthenticatedLevel(pwd.c_str(), msg);
@ -348,6 +358,11 @@ void ESP3DCommands::execute_internal_command(int cmd, int cmd_params_pos,
serial_bridge_service.setAuthentication(msg->authentication_level); serial_bridge_service.setAuthentication(msg->authentication_level);
break; break;
#endif // ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
#if defined(USB_SERIAL_FEATURE)
case ESP3DClientType::usb_serial:
esp3d_usb_serial_service.setAuthentication(msg->authentication_level);
break;
#endif // USB_SERIAL_FEATURE
#if defined(TELNET_FEATURE) #if defined(TELNET_FEATURE)
case ESP3DClientType::telnet: case ESP3DClientType::telnet:
telnet_server.setAuthentication(msg->authentication_level); telnet_server.setAuthentication(msg->authentication_level);
@ -820,6 +835,17 @@ void ESP3DCommands::execute_internal_command(int cmd, int cmd_params_pos,
ESP901(cmd_params_pos, msg); ESP901(cmd_params_pos, msg);
break; break;
#endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL
#if defined(USB_SERIAL_FEATURE)
// Get / Set USB Serial Baud Rate
//[ESP902]<BAUD RATE> json=<no> pwd=<admin/user password>
case 902:
ESP902(cmd_params_pos, msg);
break;
// Get / Set Client Output
case 950:
ESP950(cmd_params_pos, msg);
break;
#endif // defined(USB_SERIAL_FEATURE)
#ifdef BUZZER_DEVICE #ifdef BUZZER_DEVICE
// Get state / Set Enable / Disable buzzer // Get state / Set Enable / Disable buzzer
//[ESP910]<ENABLE/DISABLE> //[ESP910]<ENABLE/DISABLE>
@ -1276,11 +1302,20 @@ bool ESP3DCommands::dispatch(const char *sbuf, ESP3DClientType target,
} }
ESP3DClientType ESP3DCommands::getOutputClient(bool fromSettings) { ESP3DClientType ESP3DCommands::getOutputClient(bool fromSettings) {
// TODO: add setting for it when necessary //It is a setting only if there is a choice between USB/Serial
#if defined(USB_SERIAL_FEATURE)
if (fromSettings) {
_output_client = (ESP3DClientType)ESP3DSettings::readByte(ESP_OUTPUT_CLIENT);
}
return _output_client;
#else
(void)fromSettings; (void)fromSettings;
//if not setting, then it is the default one, which is hardcoded
#endif
esp3d_log("OutputClient: %d %s", static_cast<uint8_t>(_output_client), esp3d_log("OutputClient: %d %s", static_cast<uint8_t>(_output_client),
GETCLIENTSTR(_output_client)); GETCLIENTSTR(_output_client));
return _output_client; return _output_client;
} }
bool ESP3DCommands::dispatch(ESP3DMessage *msg) { bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
@ -1306,6 +1341,15 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
esp3d_log_e("Serial dispatch failed"); esp3d_log_e("Serial dispatch failed");
} }
break; break;
#if defined(USB_SERIAL_FEATURE)
case ESP3DClientType::usb_serial:
esp3d_log("USB Serial message");
if (!esp3d_usb_serial_service.dispatch(msg)) {
sendOk = false;
esp3d_log_e("USB Serial dispatch failed");
}
break;
#endif // USB_SERIAL_FEATURE
#endif // COMMUNICATION_PROTOCOL == RAW_SERIAL #endif // COMMUNICATION_PROTOCOL == RAW_SERIAL
#if COMMUNICATION_PROTOCOL == SOCKET_SERIAL #if COMMUNICATION_PROTOCOL == SOCKET_SERIAL
@ -1416,6 +1460,16 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
break; break;
#endif // COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == MKS_SERIAL
#if defined(GCODE_HOST_FEATURE)
case ESP3DClientType::stream:
esp3d_log("Gcode host message");
if (!esp3d_gcode_host.dispatch(msg)) {
sendOk = false;
esp3d_log_e("Gcode host dispatch failed");
}
break;
#endif // GCODE_HOST_FEATURE
#ifdef PRINTER_HAS_DISPLAY #ifdef PRINTER_HAS_DISPLAY
case ESP3DClientType::remote_screen: case ESP3DClientType::remote_screen:
esp3d_log("Remote screen message"); esp3d_log("Remote screen message");
@ -1477,6 +1531,24 @@ bool ESP3DCommands::dispatch(ESP3DMessage *msg) {
} }
#endif // ESP_LUA_INTERPRETER_FEATURE #endif // ESP_LUA_INTERPRETER_FEATURE
#if defined(GCODE_HOST_FEATURE)
if (msg->origin != ESP3DClientType::stream && esp3d_gcode_host.getStatus() != HOST_NO_STREAM) {
if (msg->target == ESP3DClientType::all_clients) {
// become the reference message
msg->target = ESP3DClientType::stream;
} else {
// duplicate message because current is already pending
ESP3DMessage *copy_msg = esp3d_message_manager.copyMsg(*msg);
if (copy_msg) {
copy_msg->target = ESP3DClientType::stream;
dispatch(copy_msg);
} else {
esp3d_log_e("Cannot duplicate message for gcode host");
}
}
}
#endif
#if defined(DISPLAY_DEVICE) #if defined(DISPLAY_DEVICE)
if (msg->origin != ESP3DClientType::rendering && if (msg->origin != ESP3DClientType::rendering &&
msg->origin != getOutputClient()) { msg->origin != getOutputClient()) {

View File

@ -180,6 +180,10 @@ class ESP3DCommands {
void ESP900(int cmd_params_pos, ESP3DMessage* msg); void ESP900(int cmd_params_pos, ESP3DMessage* msg);
void ESP901(int cmd_params_pos, ESP3DMessage* msg); void ESP901(int cmd_params_pos, ESP3DMessage* msg);
#endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL #endif // COMMUNICATION_PROTOCOL != SOCKET_SERIAL
#if defined(USB_SERIAL_FEATURE)
void ESP902(int cmd_params_pos, ESP3DMessage* msg);
void ESP950(int cmd_params_pos, ESP3DMessage* msg);
#endif // defined(USB_SERIAL_FEATURE)
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
void ESP930(int cmd_params_pos, ESP3DMessage* msg); void ESP930(int cmd_params_pos, ESP3DMessage* msg);
void ESP931(int cmd_params_pos, ESP3DMessage* msg); void ESP931(int cmd_params_pos, ESP3DMessage* msg);

View File

@ -17,6 +17,7 @@
License along with This code; if not, write to the Free Software License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#pragma once
#if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP8285) #if !defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP8285)
#include <Arduino.h> #include <Arduino.h>

View File

@ -54,6 +54,9 @@
#endif // TIMESTAMP_FEATURE #endif // TIMESTAMP_FEATURE
#include "../modules/serial/serial_service.h" #include "../modules/serial/serial_service.h"
#if defined(USB_SERIAL_FEATURE)
#include "../modules/usb-serial/usb_serial_service.h"
#endif // USB_SERIAL_FEATURE
// Current Settings Version // Current Settings Version
#define CURRENT_SETTINGS_VERSION "ESP3D05" #define CURRENT_SETTINGS_VERSION "ESP3D05"
@ -101,6 +104,17 @@
#endif // BLUETOOTH_FEATURE #endif // BLUETOOTH_FEATURE
#endif // WIFI_FEATURE #endif // WIFI_FEATURE
#if COMMUNICATION_PROTOCOL == RAW_SERIAL
#define DEFAULT_OUTPUT_CLIENT STRING(ESP3DClientType::serial);
#endif // COMMUNICATION_PROTOCOL == RAW_SERIAL
#if COMMUNICATION_PROTOCOL == MKS_SERIAL
#define DEFAULT_OUTPUT_CLIENT STRING(ESP3DClientType::mks_serial);
#endif // COMMUNICATION_PROTOCOL == MKS_SERIAL
#if COMMUNICATION_PROTOCOL == SOCKET_SERIAL
#define DEFAULT_OUTPUT_CLIENT STRING(ESP3DClientType::socket_serial);
#endif
#define DEFAULT_BUZZER_STATE "1" #define DEFAULT_BUZZER_STATE "1"
#define DEFAULT_INTERNET_TIME "0" #define DEFAULT_INTERNET_TIME "0"
#define DEFAULT_SETUP "0" #define DEFAULT_SETUP "0"
@ -251,8 +265,9 @@ uint16_t ESP3DSettingsData[] = {ESP_RADIO_MODE,
ESP_FTP_DATA_ACTIVE_PORT, ESP_FTP_DATA_ACTIVE_PORT,
ESP_FTP_DATA_PASSIVE_PORT, ESP_FTP_DATA_PASSIVE_PORT,
ESP_WEBDAV_PORT, ESP_WEBDAV_PORT,
ESP_SERIAL_BRIDGE_BAUD ESP_SERIAL_BRIDGE_BAUD,
}; ESP_OUTPUT_CLIENT,
ESP_USB_SERIAL_BAUD_RATE};
#if defined(SD_DEVICE) #if defined(SD_DEVICE)
const uint8_t SupportedSPIDivider[] = {1, 2, 4, 6, 8, 16, 32}; const uint8_t SupportedSPIDivider[] = {1, 2, 4, 6, 8, 16, 32};
const uint8_t SupportedSPIDividerSize = const uint8_t SupportedSPIDividerSize =
@ -870,6 +885,15 @@ bool ESP3DSettings::isValidIntegerSetting(uint32_t value,
} }
switch (settingElement) { switch (settingElement) {
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == RAW_SERIAL || COMMUNICATION_PROTOCOL == MKS_SERIAL
#if defined(USB_SERIAL_FEATURE)
case ESP_USB_SERIAL_BAUD_RATE:
for (uint8_t i = 0; i < SupportedUsbSerialBaudListSize; i++) {
if (value == SupportedUsbSerialBaudList[i]) {
return true;
}
}
break;
#endif // USB_SERIAL_FEATURE
case ESP_SERIAL_BRIDGE_BAUD: case ESP_SERIAL_BRIDGE_BAUD:
case ESP_BAUD_RATE: case ESP_BAUD_RATE:
for (uint8_t i = 0; i < SupportedBaudListSize; i++) { for (uint8_t i = 0; i < SupportedBaudListSize; i++) {
@ -945,6 +969,12 @@ bool ESP3DSettings::isValidByteSetting(uint8_t value,
return true; return true;
} }
break; break;
case ESP_OUTPUT_CLIENT:
if (value == (uint8_t)ESP3DClientType::serial) return true;
#if ESP_SERIAL_OUTPUT == USE_USB_SERIAL
if (value == (uint8_t)ESP3DClientType::usb_serial) return true;
#endif // ESP_SERIAL_OUTPUT == USE_USB_SERIAL
break;
#if defined(NOTIFICATION_FEATURE) #if defined(NOTIFICATION_FEATURE)
case ESP_NOTIFICATION_TYPE: case ESP_NOTIFICATION_TYPE:
if (value == ESP_NO_NOTIFICATION || value == ESP_PUSHOVER_NOTIFICATION || if (value == ESP_NO_NOTIFICATION || value == ESP_PUSHOVER_NOTIFICATION ||
@ -1152,6 +1182,7 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
case ESP_SERIAL_BRIDGE_ON: case ESP_SERIAL_BRIDGE_ON:
case ESP_STA_IP_MODE: case ESP_STA_IP_MODE:
case ESP_ETH_STA_IP_MODE: case ESP_ETH_STA_IP_MODE:
case ESP_OUTPUT_CLIENT:
setting.type = ESP3DSettingType::byte_t; // byte setting.type = ESP3DSettingType::byte_t; // byte
break; break;
@ -1202,7 +1233,7 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
case ESP_FTP_DATA_PASSIVE_PORT: case ESP_FTP_DATA_PASSIVE_PORT:
case ESP_WEBDAV_PORT: case ESP_WEBDAV_PORT:
case ESP_SERIAL_BRIDGE_BAUD: case ESP_SERIAL_BRIDGE_BAUD:
case ESP_USB_SERIAL_BAUD_RATE:
setting.type = ESP3DSettingType::integer_t; // integer = 4 bytes setting.type = ESP3DSettingType::integer_t; // integer = 4 bytes
break; break;
default: default:
@ -1239,6 +1270,7 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
case ESP_SERIAL_BRIDGE_ON: case ESP_SERIAL_BRIDGE_ON:
case ESP_ETH_STA_IP_MODE: case ESP_ETH_STA_IP_MODE:
case ESP_STA_IP_MODE: case ESP_STA_IP_MODE:
case ESP_OUTPUT_CLIENT:
setting.size = 1; // 1 byte setting.size = 1; // 1 byte
break; break;
case ESP_ETH_STA_IP_VALUE: case ESP_ETH_STA_IP_VALUE:
@ -1266,6 +1298,7 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
case ESP_FTP_DATA_PASSIVE_PORT: case ESP_FTP_DATA_PASSIVE_PORT:
case ESP_WEBDAV_PORT: case ESP_WEBDAV_PORT:
case ESP_SERIAL_BRIDGE_BAUD: case ESP_SERIAL_BRIDGE_BAUD:
case ESP_USB_SERIAL_BAUD_RATE:
setting.size = 4; // 4 bytes setting.size = 4; // 4 bytes
break; break;
// Note for string size is the max size of the string, in EEPROM it use // Note for string size is the max size of the string, in EEPROM it use
@ -1321,7 +1354,6 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
// default value of setting in string // default value of setting in string
switch (index) { switch (index) {
case ESP_ETH_STA_IP_MODE: case ESP_ETH_STA_IP_MODE:
case ESP_STA_IP_MODE: case ESP_STA_IP_MODE:
setting.default_val = DEFAULT_STA_IP_MODE; setting.default_val = DEFAULT_STA_IP_MODE;
@ -1332,6 +1364,8 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
case ESP_STA_SSID: case ESP_STA_SSID:
setting.default_val = DEFAULT_STA_SSID; setting.default_val = DEFAULT_STA_SSID;
break; break;
case ESP_OUTPUT_CLIENT:
setting.default_val = DEFAULT_OUTPUT_CLIENT;
case ESP_NOTIFICATION_TYPE: case ESP_NOTIFICATION_TYPE:
setting.default_val = DEFAULT_NOTIFICATION_TYPE; setting.default_val = DEFAULT_NOTIFICATION_TYPE;
break; break;
@ -1468,6 +1502,7 @@ const ESP3DSettingDescription *ESP3DSettings::getSettingPtr(
case ESP_AP_IP_VALUE: case ESP_AP_IP_VALUE:
setting.default_val = DEFAULT_AP_IP_VALUE; setting.default_val = DEFAULT_AP_IP_VALUE;
break; break;
case ESP_USB_SERIAL_BAUD_RATE:
case ESP_BAUD_RATE: case ESP_BAUD_RATE:
setting.default_val = DEFAULT_BAUD_RATE; setting.default_val = DEFAULT_BAUD_RATE;
break; break;

View File

@ -59,7 +59,7 @@ typedef uint ESP3DSettingIndex;
#define ESP_INTERNET_TIME 120 // 1 byte = flag #define ESP_INTERNET_TIME 120 // 1 byte = flag
#define ESP_HTTP_PORT 121 // 4 bytes = int #define ESP_HTTP_PORT 121 // 4 bytes = int
#define ESP_TELNET_PORT 125 // 4 bytes = int #define ESP_TELNET_PORT 125 // 4 bytes = int
// #define FREE 129 // 1 bytes = flag #define ESP_OUTPUT_CLIENT 129 // 1 bytes = flag
#define ESP_HOSTNAME \ #define ESP_HOSTNAME \
130 // 33 bytes 32+1 = string ; warning does not support multibyte char like 130 // 33 bytes 32+1 = string ; warning does not support multibyte char like
// chinese // chinese
@ -140,6 +140,7 @@ typedef uint ESP3DSettingIndex;
#define ESP_ETH_STA_MASK_VALUE 1240 // 4 bytes xxx.xxx.xxx.xxx #define ESP_ETH_STA_MASK_VALUE 1240 // 4 bytes xxx.xxx.xxx.xxx
#define ESP_ETH_STA_GATEWAY_VALUE 1244 // 4 bytes xxx.xxx.xxx.xxx #define ESP_ETH_STA_GATEWAY_VALUE 1244 // 4 bytes xxx.xxx.xxx.xxx
#define ESP_ETH_STA_DNS_VALUE 1248 // 4 bytes xxx.xxx.xxx.xxx #define ESP_ETH_STA_DNS_VALUE 1248 // 4 bytes xxx.xxx.xxx.xxx
#define ESP_USB_SERIAL_BAUD_RATE 1252 // 4 bytes= int
// Hidden password // Hidden password
#define HIDDEN_PASSWORD "********" #define HIDDEN_PASSWORD "********"
@ -160,6 +161,7 @@ typedef uint ESP3DSettingIndex;
#define USE_SERIAL_0 1 #define USE_SERIAL_0 1
#define USE_SERIAL_1 2 #define USE_SERIAL_1 2
#define USE_SERIAL_2 3 #define USE_SERIAL_2 3
#define USE_USB_SERIAL -1
// Serial service ID // Serial service ID
#define MAIN_SERIAL 1 #define MAIN_SERIAL 1

View File

@ -74,13 +74,27 @@
#if COMMUNICATION_PROTOCOL == MKS_SERIAL #if COMMUNICATION_PROTOCOL == MKS_SERIAL
#if defined(PRINTER_HAS_DISPLAY) #if defined(PRINTER_HAS_DISPLAY)
#error MKS serial protocol is not compatible with display output #error MKS serial protocol is not compatible with `PRINTER_HAS_DISPLAY`, comment `PRINTER_HAS_DISPLAY` in configuration.h
#endif // defined(PRINTER_HAS_DISPLAY) #endif // defined(PRINTER_HAS_DISPLAY)
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
#error MKS serial protocol is not compatible with serial bridge output #error MKS serial protocol is not compatible with serial bridge output
#endif // defined(ESP_SERIAL_BRIDGE_OUTPUT) #endif // defined(ESP_SERIAL_BRIDGE_OUTPUT)
#endif // COMMUNICATION_PROTOCOL == MKS_SERIAL #endif // COMMUNICATION_PROTOCOL == MKS_SERIAL
/**************************
* USB-Serial
* ***********************/
#if defined(USB_SERIAL_FEATURE) && (!defined(ARDUINO_ARCH_ESP32) || (!defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3)))
#error USB-Serial is only available for ESP32 S2 and S3
#endif
#if ESP_SERIAL_OUTPUT == USE_USB_SERIAL && !defined(USB_SERIAL_FEATURE)
#error USB_SERIAL_FEATURE is necessary for ESP_SERIAL_OUTPUT == USE_USB_SERIAL
#endif
/************************** /**************************
* Bluetooth * Bluetooth
* ***********************/ * ***********************/

View File

@ -22,7 +22,7 @@
#define _VERSION_ESP3D_H #define _VERSION_ESP3D_H
// version and sources location // version and sources location
#define FW_VERSION "3.0.0.a237" #define FW_VERSION "3.0.0.a240"
#define REPOSITORY "https://github.com/luc-github/ESP3D/tree/3.0" #define REPOSITORY "https://github.com/luc-github/ESP3D/tree/3.0"
#endif //_VERSION_ESP3D_H #endif //_VERSION_ESP3D_H

View File

@ -80,7 +80,7 @@ bool EthConfig::begin(int8_t& espMode) {
ipMode(true); ipMode(true);
end(); end();
#if ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_LAN8720 #if ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_LAN8720
esp3d_log_d("ETH PHY Type %d", ESP3D_ETH_PHY_TYPE); esp3d_log("ETH PHY Type %d", ESP3D_ETH_PHY_TYPE);
_started = ETH.begin(); _started = ETH.begin();
#endif // ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_LAN8720 #endif // ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_LAN8720
#if ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_TLK110 || \ #if ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_TLK110 || \
@ -101,7 +101,7 @@ bool EthConfig::begin(int8_t& espMode) {
if (ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_KSZ8081) { if (ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_KSZ8081) {
phytype = ETH_PHY_KSZ8081; phytype = ETH_PHY_KSZ8081;
} }
esp3d_log_d("ETH PHY Type %d", phytype); esp3d_log("ETH PHY Type %d", phytype);
_started = ETH.begin(phytype, ESP3D_ETH_PHY_ADDR, _started = ETH.begin(phytype, ESP3D_ETH_PHY_ADDR,
ESP3D_ETH_PHY_POWER_PIN, ESP3D_ETH_PHY_MDC_PIN, ESP3D_ETH_PHY_POWER_PIN, ESP3D_ETH_PHY_MDC_PIN,
ESP3D_ETH_PHY_MDIO_PIN, ESP3D_ETH_CLK_MODE_PIN); ESP3D_ETH_PHY_MDIO_PIN, ESP3D_ETH_CLK_MODE_PIN);
@ -110,7 +110,7 @@ bool EthConfig::begin(int8_t& espMode) {
// ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_KSZ8041 || ESP3D_ETH_PHY_TYPE == // ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_KSZ8041 || ESP3D_ETH_PHY_TYPE ==
// TYPE_ETH_PHY_KSZ8081 // TYPE_ETH_PHY_KSZ8081
#if ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_W5500 #if ESP3D_ETH_PHY_TYPE == TYPE_ETH_PHY_W5500
esp3d_log_d("ETH spi PHY Type %d", ESP3D_ETH_PHY_TYPE); esp3d_log("ETH spi PHY Type %d", ESP3D_ETH_PHY_TYPE);
ETH_SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI); ETH_SPI.begin(ETH_SPI_SCK, ETH_SPI_MISO, ETH_SPI_MOSI);
_started = ETH.begin(ETH_PHY_W5500, ESP3D_ETH_PHY_ADDR, ETH_PHY_CS, _started = ETH.begin(ETH_PHY_W5500, ESP3D_ETH_PHY_ADDR, ETH_PHY_CS,
ETH_PHY_IRQ, ETH_PHY_RST, ETH_SPI); ETH_PHY_IRQ, ETH_PHY_RST, ETH_SPI);

View File

@ -47,6 +47,18 @@ bool GcodeHost::begin() {
return true; return true;
} }
bool GcodeHost::dispatch(ESP3DMessage* message) {
if (!message || _step == HOST_NO_STREAM) {
return false;
}
if (message->size > 0 && message->data) {
push(message->data, message->size);
esp3d_message_manager.deleteMsg(message);
return true;
}
return false;
}
void GcodeHost::end() { void GcodeHost::end() {
_commandNumber = 0; _commandNumber = 0;
_error = ERROR_NO_ERROR; _error = ERROR_NO_ERROR;
@ -213,6 +225,11 @@ void GcodeHost::endStream() {
} }
#endif // SD_DEVICE #endif // SD_DEVICE
_step = HOST_NO_STREAM; _step = HOST_NO_STREAM;
if (!_scriptList.isEmpty()){
ScriptEntry scr = _scriptList.pop();
processScript(scr.script.c_str(),scr.auth_type);
}
//TODO: do same for files
} }
void GcodeHost::readNextCommand() { void GcodeHost::readNextCommand() {
@ -313,7 +330,9 @@ void GcodeHost::processCommand() {
_step = HOST_READ_LINE; _step = HOST_READ_LINE;
} else { } else {
esp3d_log("Command %s is valid", _currentCommand.c_str()); esp3d_log("Command %s is valid", _currentCommand.c_str());
String cmd = _currentCommand + "\n"; if (!_currentCommand.endsWith("\n")) {
_currentCommand += "\n";
}
bool isESPcmd = esp3d_commands.is_esp_command( bool isESPcmd = esp3d_commands.is_esp_command(
(uint8_t *)_currentCommand.c_str(), _currentCommand.length()); (uint8_t *)_currentCommand.c_str(), _currentCommand.length());
if (isESPcmd) { if (isESPcmd) {
@ -323,7 +342,7 @@ void GcodeHost::processCommand() {
if (msg) { if (msg) {
// process command // process command
esp3d_commands.process(msg); esp3d_commands.process(msg);
esp3d_log("Command is ESP command: %s", cmd.c_str()); esp3d_log("Command is ESP command: %s", _currentCommand.c_str());
_step = HOST_READ_LINE; _step = HOST_READ_LINE;
} else { } else {
esp3d_log_e("Cannot create message"); esp3d_log_e("Cannot create message");
@ -337,7 +356,7 @@ void GcodeHost::processCommand() {
if (msg) { if (msg) {
// process command // process command
esp3d_commands.process(msg); esp3d_commands.process(msg);
esp3d_log("Command is GCODE command: %s", cmd.c_str()); esp3d_log("Command is GCODE command: %s", _currentCommand.c_str());
_startTimeOut = millis(); _startTimeOut = millis();
if (isAckNeeded()) { if (isAckNeeded()) {
_step = HOST_WAIT4_ACK; _step = HOST_WAIT4_ACK;
@ -494,10 +513,10 @@ uint32_t GcodeHost::getCommandNumber(String &response) {
bool GcodeHost::processScript(const char *line, bool GcodeHost::processScript(const char *line,
ESP3DAuthenticationLevel auth_type) { ESP3DAuthenticationLevel auth_type) {
if (_step != HOST_NO_STREAM) { if (_step != HOST_NO_STREAM) {
esp3d_log("Streaming already in progress"); esp3d_log("Streaming already in progress, put to queue");
while (_step != HOST_NO_STREAM) { String s = line;
handle(); _scriptList.push(line, auth_type);
} return true;
} }
_script = line; _script = line;
_script.trim(); _script.trim();

View File

@ -22,8 +22,9 @@
#define _GCODE_HOST_H #define _GCODE_HOST_H
#include <Arduino.h> #include <Arduino.h>
#include "../../core/esp3d_message.h"
#include "../authentication/authentication_service.h" #include "../authentication/authentication_service.h"
#include "./gcode_script_fifo.h"
#define ERROR_NO_ERROR 0 #define ERROR_NO_ERROR 0
#define ERROR_TIME_OUT 1 #define ERROR_TIME_OUT 1
@ -40,16 +41,16 @@
#define ERROR_FILE_NOT_FOUND 12 #define ERROR_FILE_NOT_FOUND 12
#define ERROR_STREAM_ABORTED 13 #define ERROR_STREAM_ABORTED 13
#define HOST_NO_STREAM 0 #define HOST_NO_STREAM 100
#define HOST_START_STREAM 1 #define HOST_START_STREAM 101
#define HOST_READ_LINE 2 #define HOST_READ_LINE 102
#define HOST_PROCESS_LINE 3 #define HOST_PROCESS_LINE 103
#define HOST_WAIT4_ACK 4 #define HOST_WAIT4_ACK 104
#define HOST_PAUSE_STREAM 5 #define HOST_PAUSE_STREAM 105
#define HOST_RESUME_STREAM 6 #define HOST_RESUME_STREAM 106
#define HOST_STOP_STREAM 7 #define HOST_STOP_STREAM 107
#define HOST_ERROR_STREAM 8 #define HOST_ERROR_STREAM 108
#define HOST_ABORT_STREAM 9 #define HOST_ABORT_STREAM 109
#define TYPE_SCRIPT_STREAM 0 #define TYPE_SCRIPT_STREAM 0
#define TYPE_FS_STREAM 1 #define TYPE_FS_STREAM 1
@ -74,6 +75,8 @@ class GcodeHost {
uint8_t Checksum(const char* command, uint32_t commandSize); uint8_t Checksum(const char* command, uint32_t commandSize);
String CheckSumCommand(const char* command, uint32_t commandnb); String CheckSumCommand(const char* command, uint32_t commandnb);
bool dispatch(ESP3DMessage* message);
/*bool wait_for_ack(uint32_t timeout = DEFAULT_TIMOUT, bool checksum=false, /*bool wait_for_ack(uint32_t timeout = DEFAULT_TIMOUT, bool checksum=false,
* const char * ack=nullptr);*/ * const char * ack=nullptr);*/
@ -110,6 +113,7 @@ class GcodeHost {
bool isAck(String& line); bool isAck(String& line);
private: private:
ESP3DScriptFIFO _scriptList;
ESP3DAuthenticationLevel _auth; ESP3DAuthenticationLevel _auth;
uint8_t _buffer[ESP_HOST_BUFFER_SIZE + 1]; uint8_t _buffer[ESP_HOST_BUFFER_SIZE + 1];
size_t _bufferSize; size_t _bufferSize;

View File

@ -0,0 +1,134 @@
/*
gcode_script_fifo.h - class for managing script list, thread safe
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <Arduino.h>
#include <queue>
#include "../../include/esp3d_config.h"
#include "../authentication/authentication_service.h"
#if defined(ARDUINO_ARCH_ESP32)
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#endif // ARDUINO_ARCH_ESP32
#if defined(ARDUINO_ARCH_ESP8266)
// Définitions pour ESP8266 comme dans votre code original
#ifndef pdTRUE
#define pdTRUE true
#define xSemaphoreTake(A, B) true
#define xSemaphoreGive(A)
#define xSemaphoreCreateMutex(A) 0
#define vSemaphoreDelete(A)
#define SemaphoreHandle_t void*
#endif // pdTRUE
#endif // ESP8266
struct ScriptEntry {
String script;
ESP3DAuthenticationLevel auth_type;
ScriptEntry(String s, ESP3DAuthenticationLevel a) : script(std::move(s)), auth_type(a) {}
};
class ESP3DScriptFIFO {
public:
ESP3DScriptFIFO(size_t maxSize = 5) : _maxSize(maxSize) {
_mutex = xSemaphoreCreateMutex();
}
~ESP3DScriptFIFO() {
clear();
vSemaphoreDelete(_mutex);
}
void setMaxSize(size_t maxSize) { _maxSize = maxSize; }
size_t getMaxSize() const { return _maxSize; }
void push(String script, ESP3DAuthenticationLevel auth_type) {
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
esp3d_log("push to list [%s] auth: %d, size: %d", script.c_str(), auth_type, fifo.size());
if (fifo.size() >= _maxSize && _maxSize != 0) {
esp3d_log("remove oldest script to make room for new one");
fifo.pop();
esp3d_log("oldest message removed, list size: %d", fifo.size());
}
fifo.emplace(std::move(script), auth_type);
esp3d_log("push to list size: %d", fifo.size());
xSemaphoreGive(_mutex);
} else {
esp3d_log_e("push to list [%s] id: %d failed, list size: %d", script.c_str(), auth_type, fifo.size());
}
}
ScriptEntry pop() {
ScriptEntry entry{String(""), ESP3DAuthenticationLevel::guest};
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
if (!fifo.empty()) {
esp3d_log("pop from list size: %d", fifo.size());
entry = std::move(fifo.front());
fifo.pop();
esp3d_log("Now list size: %d", fifo.size());
esp3d_log("Script: %s, ID: %d", entry.script.c_str(), entry.auth_type);
}
xSemaphoreGive(_mutex);
} else {
esp3d_log_e("pop from list failed, list size: %d", fifo.size());
}
return entry;
}
bool isEmpty() const {
bool empty = true;
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
empty = fifo.empty();
xSemaphoreGive(_mutex);
} else {
esp3d_log_e("Mutex not taken");
}
return empty;
}
size_t size() const {
size_t s = 0;
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
s = fifo.size();
xSemaphoreGive(_mutex);
} else {
esp3d_log_e("Mutex not taken");
}
return s;
}
void clear() {
if (xSemaphoreTake(_mutex, portMAX_DELAY) == pdTRUE) {
while (!fifo.empty()) {
fifo.pop();
}
xSemaphoreGive(_mutex);
} else {
esp3d_log_e("Mutex not taken");
}
}
private:
std::queue<ScriptEntry> fifo;
SemaphoreHandle_t _mutex;
size_t _maxSize;
};

View File

@ -71,9 +71,9 @@ bool LuaInterpreter::dispatch(ESP3DMessage *message) {
} }
const char *LuaInterpreter::getLastError() { const char *LuaInterpreter::getLastError() {
esp3d_log("getLastError %s %s", _lastError.c_str(), _luaEngine.getLastError()); esp3d_log("getLastError *%s * %s*", _lastError.c_str(), _luaEngine.getLastError());
if (_lastError.length() == 0) { if ( _lastError.length() == 0) {
return _luaEngine.getLastError(); _lastError = _luaEngine.getLastError();
} }
return _lastError.c_str(); return _lastError.c_str();
} }
@ -82,7 +82,7 @@ bool LuaInterpreter::createScriptTask() {
if (_scriptTask != NULL) { if (_scriptTask != NULL) {
deleteScriptTask(); deleteScriptTask();
} }
_luaEngine.clearError();
_lastError = ""; _lastError = "";
BaseType_t xReturned = xTaskCreatePinnedToCore( BaseType_t xReturned = xTaskCreatePinnedToCore(
scriptExecutionTask, /* Task function. */ scriptExecutionTask, /* Task function. */
@ -104,11 +104,14 @@ bool LuaInterpreter::createScriptTask() {
bool LuaInterpreter::executeScriptAsync(const char *script) { bool LuaInterpreter::executeScriptAsync(const char *script) {
bool result = true; bool result = true;
_luaEngine.clearError();
_lastError = "";
if (_luaEngine.isRunning()) { if (_luaEngine.isRunning()) {
if (_lastError.length() == 0) _lastError = "A script is already running"; if (_lastError.length() == 0) _lastError = "A script is already running";
return false; return false;
} }
_currentScriptName = script; _currentScriptName = script;
_lastError = "";
if (!createScriptTask()) { if (!createScriptTask()) {
if (_lastError.length() == 0) _lastError = "Failed to create script task"; if (_lastError.length() == 0) _lastError = "Failed to create script task";
result = false; result = false;

View File

@ -58,7 +58,7 @@ class ESP3DSerialService final {
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
void receiveCb(); void receiveCb();
static void receiveSerialCb(); static void receiveSerialCb();
static void receiveBridgeSeialCb(); static void receiveBridgeSerialCb();
#endif // ARDUINO_ARCH_ESP32 #endif // ARDUINO_ARCH_ESP32
private: private:
uint32_t _baudRate; uint32_t _baudRate;

View File

@ -19,7 +19,7 @@
*/ */
#if defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP32)
#include "../../include/esp3d_config.h" #include "../../include/esp3d_config.h"
#if COMMUNICATION_PROTOCOL == RAW_SERIAL || defined(ESP_SERIAL_BRIDGE_OUTPUT) #if COMMUNICATION_PROTOCOL == RAW_SERIAL || defined(ESP_SERIAL_BRIDGE_OUTPUT) || COMMUNICATION_PROTOCOL == MKS_SERIAL
#include "../../core/esp3d_commands.h" #include "../../core/esp3d_commands.h"
#include "../../core/esp3d_settings.h" #include "../../core/esp3d_settings.h"
#include "../../core/esp3d_string.h" #include "../../core/esp3d_string.h"
@ -116,7 +116,7 @@ ESP3DAuthenticationLevel ESP3DSerialService::getAuthentication() {
void ESP3DSerialService::receiveSerialCb() { esp3d_serial_service.receiveCb(); } void ESP3DSerialService::receiveSerialCb() { esp3d_serial_service.receiveCb(); }
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
void ESP3DSerialService::receiveBridgeSeialCb() { void ESP3DSerialService::receiveBridgeSerialCb() {
serial_bridge_service.receiveCb(); serial_bridge_service.receiveCb();
} }
#endif // ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
@ -205,7 +205,7 @@ bool ESP3DSerialService::begin(uint8_t serialIndex) {
} }
#if defined(ESP_SERIAL_BRIDGE_OUTPUT) #if defined(ESP_SERIAL_BRIDGE_OUTPUT)
if (_id == BRIDGE_SERIAL) { if (_id == BRIDGE_SERIAL) {
Serials[_serialIndex]->onReceive(receiveBridgeSeialCb); Serials[_serialIndex]->onReceive(receiveBridgeSerialCb);
} }
#endif // ESP_SERIAL_BRIDGE_OUTPUT #endif // ESP_SERIAL_BRIDGE_OUTPUT
} }
@ -246,7 +246,7 @@ void ESP3DSerialService::handle() {
len = 10; len = 10;
} }
while (len > 0) { while (len > 0) {
esp3d_log_d("Serial in fifo size %d", _messagesInFIFO.size()); esp3d_log("Serial in fifo size %d", _messagesInFIFO.size());
ESP3DMessage *message = _messagesInFIFO.pop(); ESP3DMessage *message = _messagesInFIFO.pop();
if (message) { if (message) {
esp3d_commands.process(message); esp3d_commands.process(message);
@ -274,7 +274,7 @@ void ESP3DSerialService::flushbuffer() {
if (message) { if (message) {
// process command // process command
message->type = ESP3DMessageType::unique; message->type = ESP3DMessageType::unique;
esp3d_log_d("Message sent to fifo list"); esp3d_log("Message sent to fifo list");
_messagesInFIFO.push(message); _messagesInFIFO.push(message);
} else { } else {
esp3d_log_e("Cannot create message"); esp3d_log_e("Cannot create message");

View File

@ -189,7 +189,7 @@ bool TimeService::updateTimeZone(bool fromsettings) {
_time_zone_config += ">"; _time_zone_config += ">";
_time_zone_config += _time_zone[0]=='+' ? "-" : "+"; _time_zone_config += _time_zone[0]=='+' ? "-" : "+";
_time_zone_config += &_time_zone[1]; _time_zone_config += &_time_zone[1];
esp3d_log_d("Time zone is %s", _time_zone_config.c_str()); esp3d_log("Time zone is %s", _time_zone_config.c_str());
return true; return true;
} }

View File

@ -87,9 +87,17 @@ const uint16_t ServintKeysPos[] = {
ESP_FTP_CTRL_PORT, ESP_FTP_DATA_ACTIVE_PORT, ESP_FTP_CTRL_PORT, ESP_FTP_DATA_ACTIVE_PORT,
ESP_FTP_DATA_PASSIVE_PORT}; ESP_FTP_DATA_PASSIVE_PORT};
const char* SysintKeysVal[] = {"Baud_rate", "Boot_delay"}; const char* SysintKeysVal[] = {"Baud_rate",
#if defined(USB_SERIAL_FEATURE)
"USB_Serial_Baud_rate",
#endif // USB_SERIAL_FEATURE
"Boot_delay"};
const uint16_t SysintKeysPos[] = {ESP_BAUD_RATE, ESP_BOOT_DELAY}; const uint16_t SysintKeysPos[] = {ESP_BAUD_RATE,
#if defined(USB_SERIAL_FEATURE)
ESP_USB_SERIAL_BAUD_RATE,
#endif // USB_SERIAL_FEATURE
ESP_BOOT_DELAY};
const char* ServboolKeysVal[] = {"Serial_Bridge_active", "AUTONOTIFICATION", const char* ServboolKeysVal[] = {"Serial_Bridge_active", "AUTONOTIFICATION",
"HTTP_active", "TELNET_active", "HTTP_active", "TELNET_active",
@ -403,6 +411,23 @@ bool processingFileFunction(const char* section, const char* key,
} }
} }
} }
//Output USB Serial
#if defined(USB_SERIAL_FEATURE)
if (!done) {
if (strcasecmp("output", key) == 0) {
T = 'B';
P = ESP_OUTPUT_CLIENT;
done = true;
if (strcasecmp("USB", value) == 0) {
b = ESP3DClientType::usb_serial;
} else if (strcasecmp("SERIAL", value) == 0) {
b = ESP3DClientType::serial;
} else {
P = -1; // invalid value
}
}
}
#endif // USB_SERIAL_FEATURE
} }
// now we save -handle saving status // now we save -handle saving status

View File

@ -0,0 +1,469 @@
/*
esp3d_usb_serial_service.cpp - serial services functions class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "../../include/esp3d_config.h"
#if defined(USB_SERIAL_FEATURE)
#include "../../core/esp3d_commands.h"
#include "../../core/esp3d_settings.h"
#include "../../core/esp3d_string.h"
#include "../authentication/authentication_service.h"
#include "usb_serial_service.h"
const uint32_t SupportedUsbSerialBaudList[] = {
9600, 19200, 38400, 57600, 74880, 115200, 230400,
250000, 500000, 921600, 1000000, 1958400, 2000000};
const size_t SupportedUsbSerialBaudListSize =
sizeof(SupportedUsbSerialBaudList) / sizeof(uint32_t);
ESP3DUsbSerialService esp3d_usb_serial_service;
#define SERIAL_COMMUNICATION_TIMEOUT 500
// Serial Parameters
#define ESP3D_USB_SERIAL_DATA_BITS (8)
#define ESP3D_USB_SERIAL_PARITY \
(0) // 0: 1 stopbit, 1: 1.5 stopbits, 2: 2 stopbits
#define ESP3D_USB_SERIAL_STOP_BITS \
(0) // 0: None, 1: Odd, 2: Even, 3: Mark, 4: Space
// Task parameters
#define ESP3D_USB_SERIAL_RX_BUFFER_SIZE 512
#define ESP3D_USB_SERIAL_TX_BUFFER_SIZE 128
#define ESP3D_USB_SERIAL_TASK_SIZE 4096
#if CONFIG_FREERTOS_UNICORE
#define ESP3D_USB_SERIAL_TASK_CORE 0
#else
#define ESP3D_USB_SERIAL_TASK_CORE 1
#endif // CONFIG_FREERTOS_UNICORE
#define ESP3D_USB_SERIAL_TASK_PRIORITY 10
#define TIMEOUT_USB_SERIAL_FLUSH 1500
// Constructor
ESP3DUsbSerialService::ESP3DUsbSerialService() {
_buffer_size = 0;
_buffer_mutex = NULL;
_device_disconnected_mutex = NULL;
_is_connected = false;
_xHandle = NULL;
_vcp_ptr = NULL;
_started = false;
#if defined(AUTHENTICATION_FEATURE)
_needauthentication = true;
#else
_needauthentication = false;
#endif // AUTHENTICATION_FEATURE
_origin = ESP3DClientType::usb_serial;
_messagesInFIFO.setId("in");
_messagesInFIFO.setMaxSize(0); // no limit
_baudRate = 0;
}
// Destructor
ESP3DUsbSerialService::~ESP3DUsbSerialService() { end(); }
// extra parameters that do not need a begin
void ESP3DUsbSerialService::setParameters() {
#if defined(AUTHENTICATION_FEATURE)
_needauthentication =
(ESP3DSettings::readByte(ESP_SECURE_SERIAL) == 0) ? false : true;
#else
_needauthentication = false;
#endif // AUTHENTICATION_FEATURE
}
void ESP3DUsbSerialService::initAuthentication() {
#if defined(AUTHENTICATION_FEATURE)
_auth = ESP3DAuthenticationLevel::guest;
#else
_auth = ESP3DAuthenticationLevel::admin;
#endif // AUTHENTICATION_FEATURE
}
ESP3DAuthenticationLevel ESP3DUsbSerialService::getAuthentication() {
if (_needauthentication) {
return _auth;
}
return ESP3DAuthenticationLevel::admin;
}
/**
* @brief Data received callback
*/
bool usb_rx_callback(const uint8_t *data, size_t data_len, void *arg) {
esp3d_log("rx_callback %d : %s", data_len, (const char *)data);
esp3d_usb_serial_service.receiveCb(data, data_len);
return true;
}
/**
* @brief Device event callback
*
* Apart from handling device disconnection it doesn't do anything useful
*/
void handle_event(const cdc_acm_host_dev_event_data_t *event, void *user_ctx) {
switch (event->type) {
case CDC_ACM_HOST_ERROR:
esp3d_log_e("CDC-ACM error has occurred, err_no = %d\n",
event->data.error);
break;
case CDC_ACM_HOST_DEVICE_DISCONNECTED:
esp3d_log("Device suddenly disconnected");
esp3d_usb_serial_service.setConnected(false);
break;
case CDC_ACM_HOST_SERIAL_STATE:
esp3d_log("Serial state notif 0x%04X\n", event->data.serial_state.val);
break;
case CDC_ACM_HOST_NETWORK_CONNECTION:
esp3d_log("Network connection established");
break;
default:
esp3d_log("Unknown event");
break;
}
}
void ESP3DUsbSerialService::setConnected(bool connected) {
_is_connected = connected;
if (_is_connected) {
esp3d_log("USB device connected");
if (xSemaphoreTake(_device_disconnected_mutex, portMAX_DELAY) != pdTRUE) {
esp3d_log_e("Mutex not taken");
_is_connected = false;
}
} else {
esp3d_log("USB device disconnected");
xSemaphoreGive(_device_disconnected_mutex);
_vcp_ptr = nullptr;
}
}
void ESP3DUsbSerialService::receiveCb(const uint8_t *data, size_t data_len,
void *arg) {
esp3d_log("receiveCb %d : %s", data_len, (const char *)data);
if (!started()) {
return;
}
if (xSemaphoreTake(_buffer_mutex, portMAX_DELAY) == pdTRUE) {
for (size_t i = 0; i < data_len; i++) {
_buffer[_buffer_size] = data[i];
_buffer_size++;
if (_buffer_size > ESP3D_USB_SERIAL_BUFFER_SIZE ||
_buffer[_buffer_size - 1] == '\n' ||
_buffer[_buffer_size - 1] == '\r') {
if (_buffer[_buffer_size - 1] == '\r') {
_buffer[_buffer_size - 1] = '\n';
}
flushbuffer();
}
}
xSemaphoreGive(_buffer_mutex);
} else {
esp3d_log_e("Mutex not taken");
}
}
// this task only handle connection
static void esp3d_usb_serial_connection_task(void *pvParameter) {
(void)pvParameter;
while (1) {
/* Delay */
vTaskDelay(pdMS_TO_TICKS(10));
if (!esp3d_usb_serial_service.started()) {
esp3d_log_e("USB Serial service not started");
break;
}
esp3d_usb_serial_service.connectDevice();
}
/* A task should NEVER return */
vTaskDelete(NULL);
}
void ESP3DUsbSerialService::connectDevice() {
if (!_started || _is_connected || _vcp_ptr ) {
//esp3d_log("USB device is connected (%d) or service not started (%d)", _is_connected, _started);
return;
}
const cdc_acm_host_device_config_t dev_config = {
.connection_timeout_ms = 5000, // 5 seconds, enough time to plug the
// device in or experiment with timeout
.out_buffer_size = ESP3D_USB_SERIAL_TX_BUFFER_SIZE,
.in_buffer_size = ESP3D_USB_SERIAL_RX_BUFFER_SIZE,
.event_cb = handle_event,
.data_cb = usb_rx_callback,
.user_arg = NULL,
};
cdc_acm_line_coding_t line_coding = {
.dwDTERate = _baudRate,
.bCharFormat = ESP3D_USB_SERIAL_STOP_BITS,
.bParityType = ESP3D_USB_SERIAL_PARITY,
.bDataBits = ESP3D_USB_SERIAL_DATA_BITS,
};
// You don't need to know the device's VID and PID. Just plug in any device
// and the VCP service will pick correct (already registered) driver for the
// device
esp3d_log("Waiting for USB device");
_vcp_ptr = std::unique_ptr<CdcAcmDevice>(esp_usb::VCP::open(&dev_config));
if (!_vcp_ptr) {
esp3d_log_e("USB device not found, retrying...");
return;
}
vTaskDelay(10);
esp3d_log("USB device found");
if (_vcp_ptr->line_coding_set(&line_coding) == ESP_OK) {
esp3d_log("USB Connected");
uint16_t vid = esp_usb::getVID();
uint16_t pid = esp_usb::getPID();
esp3d_log("USB device with VID: 0x%04X (%s), PID: 0x%04X (%s) found\n",
vid, esp_usb::getVIDString(), pid, esp_usb::getPIDString());
// TODO:
// Do notification to user ?
setConnected(true);
} else {
esp3d_log_e("USB device not identified");
}
}
// Setup Serial
bool ESP3DUsbSerialService::begin() {
_buffer_mutex = xSemaphoreCreateMutex();
if (_buffer_mutex == NULL) {
esp3d_log_e("Mutex creation failed");
return false;
}
_device_disconnected_mutex = xSemaphoreCreateMutex();
if (_device_disconnected_mutex == NULL) {
esp3d_log_e("Mutex creation failed");
return false;
}
_lastflush = millis();
// read from settings
_baudRate = ESP3DSettings::readUint32(ESP_USB_SERIAL_BAUD_RATE);
esp3d_log("Baud rate is %d ", _baudRate);
_buffer_size = 0;
// change only if different from current
if (ESP_OK != usb_serial_init()) {
esp3d_log_e("USB Serial Init failed");
return false;
} else {
esp3d_log("USB Serial Init OK");
if (ESP_OK != usb_serial_create_task()) {
esp3d_log_e("USB Serial Create Task failed");
return false;
} else {
esp3d_log("USB Serial Create Task OK");
}
_device_disconnected_mutex = xSemaphoreCreateMutex();
if (_device_disconnected_mutex == NULL) {
Serial.println("Mutex creation failed");
return false;
} else {
esp3d_log("Mutex creation OK");
}
_started = true;
BaseType_t res = xTaskCreatePinnedToCore(
esp3d_usb_serial_connection_task, "esp3d_usb_serial_task",
ESP3D_USB_SERIAL_TASK_SIZE, NULL, ESP3D_USB_SERIAL_TASK_PRIORITY,
&_xHandle, ESP3D_USB_SERIAL_TASK_CORE);
if (res != pdPASS || !_xHandle) {
esp3d_log_e("Failed to create USB Serial Connection Task");
_started = false;
return false;
} else {
esp3d_log("USB Serial Connection Task OK");
}
}
return true;
}
// End serial
bool ESP3DUsbSerialService::end() {
flush();
delay(100);
if (_buffer_mutex != NULL) {
vSemaphoreDelete(_buffer_mutex);
_buffer_mutex = NULL;
}
if (_device_disconnected_mutex != NULL) {
vSemaphoreDelete(_device_disconnected_mutex);
_device_disconnected_mutex = NULL;
}
// Serials[_serialIndex]->end();
_buffer_size = 0;
_started = false;
_is_connected = false;
if (_xHandle != NULL) {
vTaskDelete(_xHandle);
_xHandle = NULL;
esp3d_log("Task deleted");
}
if (_vcp_ptr != NULL) {
_vcp_ptr = NULL;
esp3d_log("VCP deleted");
}
usb_serial_deinit();
usb_serial_delete_task();
initAuthentication();
return true;
}
// return the array of uint32_t and array size
const uint32_t *ESP3DUsbSerialService::get_baudratelist(uint8_t *count) {
if (count) {
*count = sizeof(SupportedUsbSerialBaudList) / sizeof(uint32_t);
}
return SupportedUsbSerialBaudList;
}
// Function which could be called in other loop
void ESP3DUsbSerialService::handle() {
// Do we have some data waiting
size_t len = _messagesInFIFO.size();
if (len > 0) {
if (len > 10) {
len = 10;
}
while (len > 0) {
esp3d_log("Serial in fifo size %d", _messagesInFIFO.size());
ESP3DMessage *message = _messagesInFIFO.pop();
if (message) {
esp3d_commands.process(message);
} else {
esp3d_log_e("Cannot create message");
}
len--;
}
}
}
void ESP3DUsbSerialService::flushbuffer() {
_buffer[_buffer_size] = 0x0;
if (_buffer_size == 1 && _buffer[0] == '\n') {
_buffer_size = 0;
return;
}
// dispatch command
ESP3DMessage *message = esp3d_message_manager.newMsg(
_origin, ESP3DClientType::all_clients, (uint8_t *)_buffer, _buffer_size,
getAuthentication());
if (message) {
// process command
message->type = ESP3DMessageType::unique;
esp3d_log("Message sent to fifo list");
_messagesInFIFO.push(message);
} else {
esp3d_log_e("Cannot create message");
}
_lastflush = millis();
_buffer_size = 0;
}
void ESP3DUsbSerialService::updateBaudRate(uint32_t br) {
if (br != _baudRate) {
_baudRate = br;
}
}
// Get current baud rate
uint32_t ESP3DUsbSerialService::baudRate() { return _baudRate; }
size_t ESP3DUsbSerialService::writeBytes(const uint8_t *buffer, size_t size) {
if (!_started || !_is_connected) {
esp3d_log_e("USB Serial not started or not connected");
return 0;
}
esp3d_log("writeBytes %d : %s", size, (const char *)buffer);
if (_vcp_ptr && _vcp_ptr->tx_blocking((uint8_t *)buffer, size) == ESP_OK) {
if (!(_vcp_ptr && _vcp_ptr->set_control_line_state(true, true) == ESP_OK)) {
esp3d_log_e("Failed to set control line state");
return 0;
esp3d_log_e("Failed to send message");
return 0;
}
return size;
}
if (!_vcp_ptr) {
esp3d_log_e("_vcp_ptr is null");
} else {
esp3d_log_e("tx_blocking failed");
}
esp3d_log_e("Failed to send message");
return 0;
}
size_t ESP3DUsbSerialService::readBytes(uint8_t *sbuf, size_t len) {
if (!_started) {
return -1;
}
// return Serials[_serialIndex]->readBytes(sbuf, len);
return 0;
}
void ESP3DUsbSerialService::flush() {
if (!_started) {
return;
}
// Serials[_serialIndex]->flush();
}
void ESP3DUsbSerialService::swap() {
// Nothing to do
}
bool ESP3DUsbSerialService::dispatch(ESP3DMessage *message) {
esp3d_log("dispatching received message");
bool done = false;
// Only is serial service is started
if (_started) {
// Only if message is not null
if (message) {
// if message is not null
if (message->data && message->size != 0) {
if (writeBytes(message->data, message->size) == message->size) {
flush();
done = true;
// Delete message now
esp3d_log("Deleting message");
esp3d_message_manager.deleteMsg(message);
} else {
esp3d_log_e("Error while sending data");
}
} else {
esp3d_log_e("Error null data");
}
} else {
esp3d_log_e("Error null message");
}
} else {
esp3d_log_e("Serial service not started");
}
return done;
}
#endif // USB_SERIAL_FEATURE

View File

@ -0,0 +1,80 @@
/*
serial_service.h - serial services functions class
Copyright (c) 2014 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include <esp32_usb_serial.h>
#include "../../core/esp3d_client_types.h"
#include "../../core/esp3d_message.h"
#include "../../core/esp3d_messageFifo.h"
#define ESP3D_USB_SERIAL_BUFFER_SIZE 1024
extern const uint32_t SupportedUsbSerialBaudList[];
extern const size_t SupportedUsbSerialBaudListSize;
class ESP3DUsbSerialService final {
public:
ESP3DUsbSerialService();
~ESP3DUsbSerialService();
void setParameters();
bool begin();
bool end();
void updateBaudRate(uint32_t br);
void handle();
bool reset();
uint32_t baudRate();
const uint32_t *get_baudratelist(uint8_t *count);
void flush();
void swap();
size_t writeBytes(const uint8_t *buffer, size_t size);
size_t readBytes(uint8_t *sbuf, size_t len);
inline bool started() { return _started; }
bool dispatch(ESP3DMessage *message);
void initAuthentication();
void setAuthentication(ESP3DAuthenticationLevel auth) { _auth = auth; }
ESP3DAuthenticationLevel getAuthentication();
void connectDevice();
void setConnected(bool connected);
void receiveCb(const uint8_t *data, size_t data_len, void *arg = nullptr);
private:
uint32_t _baudRate;
ESP3DAuthenticationLevel _auth;
ESP3DClientType _origin;
bool _started;
bool _needauthentication;
uint32_t _lastflush;
uint8_t
_buffer[ESP3D_USB_SERIAL_BUFFER_SIZE + 1]; // keep space of 0x0 terminal
size_t _buffer_size;
SemaphoreHandle_t _buffer_mutex;
SemaphoreHandle_t _device_disconnected_mutex;
bool _is_connected;
std::unique_ptr<CdcAcmDevice> _vcp_ptr;
TaskHandle_t _xHandle;
ESP3DMessageFIFO _messagesInFIFO;
void flushbuffer();
};
extern ESP3DUsbSerialService esp3d_usb_serial_service;

View File

@ -1,5 +1,5 @@
name=EspLuaEngine name=EspLuaEngine
version=1.0.2 version=1.0.3
author=Luc LEBOSSE <luc.lebosse@tech-hunters.com> author=Luc LEBOSSE <luc.lebosse@tech-hunters.com>
maintainer=Luc LEBOSSE <luc.lebosse@tech-hunters.com> maintainer=Luc LEBOSSE <luc.lebosse@tech-hunters.com>
sentence=Lua engine for ESP sentence=Lua engine for ESP

View File

@ -66,6 +66,7 @@ class EspLuaEngine {
bool isRunning(); bool isRunning();
Status getStatus(); Status getStatus();
bool hasError(); bool hasError();
void clearError(){_lastError="";}
private: private:
lua_State* _lua_state; lua_State* _lua_state;

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Some files were not shown because too many files have changed in this diff Show More