diff --git a/include/Logging.h b/include/Logging.h index a79ef3d5..da710cfb 100644 --- a/include/Logging.h +++ b/include/Logging.h @@ -8,8 +8,6 @@ #include #include -extern "C" int log_printf(const char* fmt, ...); - template constexpr const char* openshockPathToFileName(const char (&path)[N]) { std::size_t pos = 0; @@ -32,37 +30,37 @@ constexpr const char* openshockPathToFileName(const char (&path)[N]) { #define OPENSHOCK_LOG_FORMAT(letter, format) "[%lli][" #letter "][%s:%u] %s(): " format "\r\n", OpenShock::millis(), openshockPathToFileName(__FILE__), __LINE__, __FUNCTION__ #if OPENSHOCK_LOG_LEVEL >= OPENSHOCK_LOG_LEVEL_VERBOSE -#define OS_LOGV(TAG, format, ...) log_printf(OPENSHOCK_LOG_FORMAT(V, "[%s] " format), TAG, ##__VA_ARGS__) +#define OS_LOGV(TAG, format, ...) esp_log_write(ESP_LOG_VERBOSE, TAG, OPENSHOCK_LOG_FORMAT(V, "[%s] " format), TAG, ##__VA_ARGS__) #else #define OS_LOGV(TAG, format, ...) do {} while(0) #endif #if OPENSHOCK_LOG_LEVEL >= OPENSHOCK_LOG_LEVEL_DEBUG -#define OS_LOGD(TAG, format, ...) log_printf(OPENSHOCK_LOG_FORMAT(D, "[%s] " format), TAG, ##__VA_ARGS__) +#define OS_LOGD(TAG, format, ...) esp_log_write(ESP_LOG_DEBUG, TAG, OPENSHOCK_LOG_FORMAT(D, "[%s] " format), TAG, ##__VA_ARGS__) #else #define OS_LOGD(TAG, format, ...) do {} while(0) #endif #if OPENSHOCK_LOG_LEVEL >= OPENSHOCK_LOG_LEVEL_INFO -#define OS_LOGI(TAG, format, ...) log_printf(OPENSHOCK_LOG_FORMAT(I, "[%s] " format), TAG, ##__VA_ARGS__) +#define OS_LOGI(TAG, format, ...) esp_log_write(ESP_LOG_INFO, TAG, OPENSHOCK_LOG_FORMAT(I, "[%s] " format), TAG, ##__VA_ARGS__) #else #define OS_LOGI(TAG, format, ...) do {} while(0) #endif #if OPENSHOCK_LOG_LEVEL >= OPENSHOCK_LOG_LEVEL_WARN -#define OS_LOGW(TAG, format, ...) log_printf(OPENSHOCK_LOG_FORMAT(W, "[%s] " format), TAG, ##__VA_ARGS__) +#define OS_LOGW(TAG, format, ...) esp_log_write(ESP_LOG_WARN, TAG, OPENSHOCK_LOG_FORMAT(W, "[%s] " format), TAG, ##__VA_ARGS__) #else #define OS_LOGW(TAG, format, ...) do {} while(0) #endif #if OPENSHOCK_LOG_LEVEL >= OPENSHOCK_LOG_LEVEL_ERROR -#define OS_LOGE(TAG, format, ...) log_printf(OPENSHOCK_LOG_FORMAT(E, "[%s] " format), TAG, ##__VA_ARGS__) +#define OS_LOGE(TAG, format, ...) esp_log_write(ESP_LOG_ERROR, TAG, OPENSHOCK_LOG_FORMAT(E, "[%s] " format), TAG, ##__VA_ARGS__) #else #define OS_LOGE(TAG, format, ...) do {} while(0) #endif #if OPENSHOCK_LOG_LEVEL >= OPENSHOCK_LOG_LEVEL_NONE -#define OS_LOGN(TAG, format, ...) log_printf(OPENSHOCK_LOG_FORMAT(E, "[%s] " format), TAG, ##__VA_ARGS__) +#define OS_LOGN(TAG, format, ...) esp_log_write(ESP_LOG_NONE, TAG, OPENSHOCK_LOG_FORMAT(E, "[%s] " format), TAG, ##__VA_ARGS__) #else #define OS_LOGN(TAG, format, ...) do {} while(0) #endif diff --git a/include/serial/SerialCompat.h b/include/serial/SerialCompat.h new file mode 100644 index 00000000..9a297c8b --- /dev/null +++ b/include/serial/SerialCompat.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +// Use the same UART that your console / printf uses +// On most boards this is UART_NUM_0 +#define OPENSHOCK_UART = UART_NUM_0; + +namespace OpenShock { + // Call this once during startup (instead of Serial.begin) + inline void SerialInit() + { + // If you already use esp_console, you might already have + // the driver installed. Then you can skip the install part. + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, + .source_clk = UART_SCLK_DEFAULT, + }; + ESP_ERROR_CHECK(uart_param_config(OPENSHOCK_UART, &uart_config)); + + // RX buffer only; TX is handled by vfs/printf + ESP_ERROR_CHECK(uart_driver_install(OPENSHOCK_UART, 2048, 0, 0, nullptr, 0)); + + // Route stdin/stdout to this UART so printf/scanf work + esp_vfs_dev_uart_use_driver(OPENSHOCK_UART); + } + + // Arduino-like helpers + inline int SerialAvailable() + { + size_t len = 0; + uart_get_buffered_data_len(OPENSHOCK_UART, &len); + return static_cast(len); + } + + inline int SerialRead() + { + std::uint8_t c; + // timeout = 0 ticks → non-blocking + int n = uart_read_bytes(OPENSHOCK_UART, &c, 1, 0); + if (n == 1) { + return static_cast(c); + } + return -1; // no data + } +} // namespace OpenShock \ No newline at end of file diff --git a/include/serial/command_handlers/common.h b/include/serial/command_handlers/common.h index f250a0e4..867debe8 100644 --- a/include/serial/command_handlers/common.h +++ b/include/serial/command_handlers/common.h @@ -4,9 +4,9 @@ #include "Logging.h" -#include +#include -#define SERPR_SYS(format, ...) ::Serial.printf("$SYS$|" format "\r\n", ##__VA_ARGS__) +#define SERPR_SYS(format, ...) printf("$SYS$|" format "\r\n", ##__VA_ARGS__) #define SERPR_RESPONSE(format, ...) SERPR_SYS("Response|" format, ##__VA_ARGS__) #define SERPR_SUCCESS(format, ...) SERPR_SYS("Success|" format, ##__VA_ARGS__) #define SERPR_ERROR(format, ...) SERPR_SYS("Error|" format, ##__VA_ARGS__) diff --git a/src/CaptivePortalInstance.cpp b/src/CaptivePortalInstance.cpp index 6a5d536c..64901458 100644 --- a/src/CaptivePortalInstance.cpp +++ b/src/CaptivePortalInstance.cpp @@ -198,7 +198,7 @@ void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMess break; default: m_socketDeFragger.clear(); - OS_LOGE(TAG, "Unknown WebSocket event type: %u", type); + OS_LOGE(TAG, "Unknown WebSocket event type: %hhu", static_cast(type)); break; } } diff --git a/src/GatewayConnectionManager.cpp b/src/GatewayConnectionManager.cpp index 3204373c..b843730d 100644 --- a/src/GatewayConnectionManager.cpp +++ b/src/GatewayConnectionManager.cpp @@ -202,7 +202,7 @@ bool FetchHubInfo(std::string authToken) OS_LOGI(TAG, "Hub Name: %s", response.data.hubName.c_str()); OS_LOGI(TAG, "Shockers:"); for (auto& shocker : response.data.shockers) { - OS_LOGI(TAG, " [%s] rf=%u model=%u", shocker.id.c_str(), shocker.rfId, shocker.model); + OS_LOGI(TAG, " [%s] rf=%hu model=%hhu", shocker.id.c_str(), shocker.rfId, static_cast(shocker.model)); } s_flags |= FLAG_LINKED; diff --git a/src/OtaUpdateManager.cpp b/src/OtaUpdateManager.cpp index 77c5ed40..f5492209 100644 --- a/src/OtaUpdateManager.cpp +++ b/src/OtaUpdateManager.cpp @@ -537,11 +537,11 @@ bool OtaUpdateManager::TryGetFirmwareVersion(OtaUpdateChannel channel, OpenShock channelIndexUrl = OPENSHOCK_FW_CDN_DEVELOP_URL ""sv; break; default: - OS_LOGE(TAG, "Unknown channel: %u", channel); + OS_LOGE(TAG, "Unknown channel: %hhu", static_cast(channel)); return false; } - OS_LOGD(TAG, "Fetching firmware version from %s", channelIndexUrl); + OS_LOGD(TAG, "Fetching firmware version from %s", channelIndexUrl.data()); auto response = OpenShock::HTTP::GetString( channelIndexUrl, diff --git a/src/main.cpp b/src/main.cpp index 153f4988..0ad78ed6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,14 +11,13 @@ const char* const TAG = "main"; #include "GatewayConnectionManager.h" #include "Logging.h" #include "OtaUpdateManager.h" +#include "serial/SerialCompat.h" #include "serial/SerialInputHandler.h" #include "util/TaskUtils.h" #include "VisualStateManager.h" #include "wifi/WiFiManager.h" #include "wifi/WiFiScanManager.h" -#include - #include // Internal setup function, returns true if setup succeeded, false otherwise. @@ -92,7 +91,8 @@ void appSetup() // Arduino setup function void setup() { - ::Serial.begin(115'200); + OpenShock::SerialInit(); + esp_log_level_set(ESP_LOG_VERBOSE); OpenShock::Config::Init(); diff --git a/src/message_handlers/websocket/gateway/_InvalidMessage.cpp b/src/message_handlers/websocket/gateway/_InvalidMessage.cpp index 15ae23aa..753e9b8c 100644 --- a/src/message_handlers/websocket/gateway/_InvalidMessage.cpp +++ b/src/message_handlers/websocket/gateway/_InvalidMessage.cpp @@ -13,5 +13,5 @@ void _Private::HandleInvalidMessage(const OpenShock::Serialization::Gateway::Gat return; } - OS_LOGE(TAG, "Invalid message type: %u", root->payload_type()); + OS_LOGE(TAG, "Invalid message type: %hhu", static_cast(root->payload_type())); } diff --git a/src/message_handlers/websocket/local/_InvalidMessage.cpp b/src/message_handlers/websocket/local/_InvalidMessage.cpp index 8afe35fa..57fd6dab 100644 --- a/src/message_handlers/websocket/local/_InvalidMessage.cpp +++ b/src/message_handlers/websocket/local/_InvalidMessage.cpp @@ -15,5 +15,5 @@ void _Private::HandleInvalidMessage(uint8_t socketId, const OpenShock::Serializa return; } - OS_LOGE(TAG, "Invalid message type: %d", root->payload_type()); + OS_LOGE(TAG, "Invalid message type: %hhu", static_cast(root->payload_type())); } diff --git a/src/radio/RFTransmitter.cpp b/src/radio/RFTransmitter.cpp index f08112b9..d21ac2a9 100644 --- a/src/radio/RFTransmitter.cpp +++ b/src/radio/RFTransmitter.cpp @@ -89,7 +89,7 @@ bool RFTransmitter::SendCommand(ShockerModelType model, uint16_t shockerId, Shoc durationMs = 300; overwriteExisting = true; } else { - OS_LOGD(TAG, "Command received: %u %u %u %u", model, shockerId, type, intensity); + OS_LOGD(TAG, "Command received: %hhu %hu %hhu %hhu", static_cast(model), shockerId, static_cast(type), intensity); } Command cmd = Command {.transmitEnd = OpenShock::millis() + durationMs, .modelType = model, .type = type, .shockerId = shockerId, .intensity = intensity, .flags = overwriteExisting ? kFlagOverwrite : (uint8_t)0}; @@ -222,7 +222,7 @@ void RFTransmitter::TransmitTask() } if (!addSequence(sequences, cmd.modelType, cmd.shockerId, cmd.type, cmd.intensity, cmd.transmitEnd)) { - OS_LOGD(TAG, "[pin-%hhi] Failed to add sequence"); + OS_LOGD(TAG, "[pin-%hhi] Failed to add sequence", m_txPin); } } diff --git a/src/radio/rmt/Sequence.cpp b/src/radio/rmt/Sequence.cpp index ce64d6d2..310058ca 100644 --- a/src/radio/rmt/Sequence.cpp +++ b/src/radio/rmt/Sequence.cpp @@ -34,7 +34,7 @@ inline static bool fillSequenceImpl(rmt_data_t* data, ShockerModelType modelType case ShockerModelType::Petrainer998DR: return Rmt::Petrainer998DREncoder::FillBuffer(data, shockerId, commandType, intensity); default: - OS_LOGE(TAG, "Unknown shocker model: %u", modelType); + OS_LOGE(TAG, "Unknown shocker model: %hhu", static_cast(modelType)); return false; } } diff --git a/src/serial/SerialInputHandler.cpp b/src/serial/SerialInputHandler.cpp index 5bd0acca..7582df41 100644 --- a/src/serial/SerialInputHandler.cpp +++ b/src/serial/SerialInputHandler.cpp @@ -12,6 +12,7 @@ const char* const TAG = "SerialInputHandler"; #include "FormatHelpers.h" #include "http/HTTPRequestManager.h" #include "Logging.h" +#include "serial/SerialCompat.h" #include "serial/command_handlers/CommandEntry.h" #include "serial/command_handlers/common.h" #include "serial/command_handlers/index.h" @@ -22,11 +23,9 @@ const char* const TAG = "SerialInputHandler"; #include "util/TaskUtils.h" #include "wifi/WiFiManager.h" -#include - #include -#include +#include #include #include #include @@ -123,7 +122,7 @@ void _printCompleteHelp() } SerialInputHandler::PrintWelcomeHeader(); - ::Serial.print(buffer.data()); + fwrite(buffer.data(), 1, buffer.size(), stdout); } void _printCommandHelp(Serial::CommandGroup& group) @@ -256,7 +255,7 @@ void _printCommandHelp(Serial::CommandGroup& group) buffer.push_back('\r'); buffer.push_back('\n'); - ::Serial.print(buffer.data()); + fwrite(buffer.data(), 1, buffer.size(), stdout); } void _handleHelpCommand(std::string_view arg, bool isAutomated) @@ -369,7 +368,7 @@ enum class SerialReadResult { SerialReadResult _tryReadSerialLine(SerialBuffer& buffer) { // Check if there's any data available - int available = ::Serial.available(); + int available = OpenShockSerialAvailable(); if (available <= 0) { return SerialReadResult::NoData; } @@ -379,11 +378,18 @@ SerialReadResult _tryReadSerialLine(SerialBuffer& buffer) // Read the data into the buffer while (available-- > 0) { - char c = ::Serial.read(); + int r = OpenShockSerialRead(); + if (r < 0) { + break; // no more data even though the previous length said otherwise + } + + char c = static_cast(r); // Handle backspace if (c == '\b') { - buffer.pop_back(); // Remove the last character from the buffer if it exists + if (!buffer.empty()) { + buffer.pop_back(); // Remove the last character from the buffer if it exists + } continue; } @@ -415,10 +421,15 @@ SerialReadResult _tryReadSerialLine(SerialBuffer& buffer) void _skipSerialWhitespaces(SerialBuffer& buffer) { - int available = ::Serial.available(); + int available = OpenShockSerialAvailable(); while (available-- > 0) { - char c = ::Serial.read(); + int r = OpenShockSerialRead(); + if (r < 0) { + break; + } + + char c = static_cast(r); if (c != ' ' && c != '\r' && c != '\n') { buffer.push_back(c); @@ -429,7 +440,7 @@ void _skipSerialWhitespaces(SerialBuffer& buffer) void _echoBuffer(std::string_view buffer) { - ::Serial.printf(CLEAR_LINE "> %.*s", buffer.size(), buffer.data()); + printf(CLEAR_LINE "> %.*s", buffer.size(), buffer.data()); } void _echoHandleSerialInput(std::string_view buffer, bool hasData) @@ -476,7 +487,7 @@ void _processSerialLine(std::string_view line) line = line.substr(1); } else if (s_echoEnabled) { _echoBuffer(line); - ::Serial.println(); + putchar('\n'); } auto parts = OpenShock::StringSplit(line, ' ', 1); @@ -567,7 +578,7 @@ void _serialRxTask(void*) _skipSerialWhitespaces(buffer); break; case SerialReadResult::AutoCompleteRequest: - ::Serial.printf(CLEAR_LINE "> %.*s [AutoComplete is not implemented]", buffer.size(), buffer.data()); + printf(CLEAR_LINE "> %.*s [AutoComplete is not implemented]", buffer.size(), buffer.data()); break; case SerialReadResult::Data: _echoHandleSerialInput(buffer, true); @@ -599,7 +610,7 @@ bool SerialInputHandler::Init() SerialInputHandler::PrintWelcomeHeader(); SerialInputHandler::PrintVersionInfo(); - ::Serial.println(); + putchar('\n'); if (!Config::GetSerialInputConfigEchoEnabled(s_echoEnabled)) { OS_LOGE(TAG, "Failed to get serial echo status from config"); @@ -625,22 +636,27 @@ void SerialInputHandler::SetSerialEchoEnabled(bool enabled) void SerialInputHandler::PrintWelcomeHeader() { - ::Serial.println("\ + auto string = "\ ============== OPENSHOCK ==============\r\n\ Contribute @ github.com/OpenShock\r\n\ Discuss @ discord.gg/OpenShock\r\n\ Type 'help' for available commands\r\n\ =======================================\r\n\ -"); +\r\n\ +"sv; + + fwrite(string.data(), 1, string.size(), stdout); } void SerialInputHandler::PrintVersionInfo() { - ::Serial.print("\ + auto string = "\ Version: " OPENSHOCK_FW_VERSION "\r\n\ Build: " OPENSHOCK_FW_MODE "\r\n\ Commit: " OPENSHOCK_FW_GIT_COMMIT "\r\n\ Board: " OPENSHOCK_FW_BOARD "\r\n\ Chip: " OPENSHOCK_FW_CHIP "\r\n\ -"); +"sv; + + fwrite(string.data(), 1, string.size(), stdout); } diff --git a/src/serial/command_handlers/factoryreset.cpp b/src/serial/command_handlers/factoryreset.cpp index bf973821..c397627c 100644 --- a/src/serial/command_handlers/factoryreset.cpp +++ b/src/serial/command_handlers/factoryreset.cpp @@ -4,13 +4,15 @@ #include +#include + void _handleFactoryResetCommand(std::string_view arg, bool isAutomated) { (void)arg; - ::Serial.println("Resetting to factory defaults..."); + printf("Resetting to factory defaults...\n"); OpenShock::Config::FactoryReset(); - ::Serial.println("Restarting..."); + printf("Restarting...\n"); esp_restart(); } diff --git a/src/serial/command_handlers/restart.cpp b/src/serial/command_handlers/restart.cpp index 9ea94df7..6b4e9efb 100644 --- a/src/serial/command_handlers/restart.cpp +++ b/src/serial/command_handlers/restart.cpp @@ -5,7 +5,7 @@ void _handleRestartCommand(std::string_view arg, bool isAutomated) { (void)arg; - ::Serial.println("Restarting ESP..."); + printf("Restarting ESP...\n"); esp_restart(); } diff --git a/src/serial/command_handlers/version.cpp b/src/serial/command_handlers/version.cpp index 52bd4dae..051a9d69 100644 --- a/src/serial/command_handlers/version.cpp +++ b/src/serial/command_handlers/version.cpp @@ -2,12 +2,15 @@ #include "serial/SerialInputHandler.h" +#include #include void _handleVersionCommand(std::string_view arg, bool isAutomated) { (void)arg; - ::Serial.println(); + putchar('\r'); + putchar('\n'); + OpenShock::SerialInputHandler::PrintVersionInfo(); }