diff --git a/arduino/beken-72xx/cores/arduino/Arduino.h b/arduino/beken-72xx/cores/arduino/Arduino.h index a7aa124..84b8544 100644 --- a/arduino/beken-72xx/cores/arduino/Arduino.h +++ b/arduino/beken-72xx/cores/arduino/Arduino.h @@ -14,21 +14,17 @@ // Include board variant #include "variant.h" +// Choose the main UART output port +#ifndef LT_UART_DEFAULT_PORT +#if defined(PIN_SERIAL2_TX) +#define LT_UART_DEFAULT_PORT 2 +#else +#define LT_UART_DEFAULT_PORT 1 +#endif +#endif + // Define available serial ports #ifdef __cplusplus #include "SerialClass.h" -#ifdef HAS_SERIAL_CLASS // failsafe for circular inclusion - -#ifdef PIN_SERIAL1_TX -extern SerialClass Serial1; -#endif - -#ifdef PIN_SERIAL2_TX -extern SerialClass Serial2; -#define Serial Serial2 -#else -#define Serial Serial1 -#endif - -#endif +#include #endif diff --git a/arduino/beken-72xx/cores/arduino/main.cpp b/arduino/beken-72xx/cores/arduino/main.cpp index d7e1d1a..2b52753 100644 --- a/arduino/beken-72xx/cores/arduino/main.cpp +++ b/arduino/beken-72xx/cores/arduino/main.cpp @@ -3,12 +3,21 @@ #include extern "C" { + #include #include -} + +extern int uart_print_port; + +} // extern "C" beken_thread_t mainThread; +void initArduino() { + // set default UART output port + uart_print_port = LT_UART_DEFAULT_PORT - 1; +} + bool startMainTask() { OSStatus ret = rtos_create_thread( &mainThread, diff --git a/arduino/beken-72xx/port/printf/printf.c b/arduino/beken-72xx/port/printf/printf.c index 09fdb27..0632070 100644 --- a/arduino/beken-72xx/port/printf/printf.c +++ b/arduino/beken-72xx/port/printf/printf.c @@ -14,4 +14,8 @@ void putchar_(char c) { bk_send_byte(uart_print_port, c); } +void putchar_p(char c, unsigned long port) { + bk_send_byte(port & 0xFF, c); +} + WRAP_PRINTF(bk_printf); diff --git a/arduino/libretuya/core/LibreTuyaConfig.h b/arduino/libretuya/core/LibreTuyaConfig.h index f4e5126..a445c4b 100644 --- a/arduino/libretuya/core/LibreTuyaConfig.h +++ b/arduino/libretuya/core/LibreTuyaConfig.h @@ -63,6 +63,14 @@ #define LT_UART_SILENT_ALL 0 #endif +#ifndef LT_UART_DEFAULT_LOGGER +#define LT_UART_DEFAULT_LOGGER LT_UART_DEFAULT_PORT +#endif + +#ifndef LT_UART_DEFAULT_SERIAL +#define LT_UART_DEFAULT_SERIAL LT_UART_DEFAULT_PORT +#endif + // Per-module debugging #ifndef LT_DEBUG_WIFI #define LT_DEBUG_WIFI 0 diff --git a/arduino/libretuya/core/SerialExtern.h b/arduino/libretuya/core/SerialExtern.h new file mode 100644 index 0000000..e404333 --- /dev/null +++ b/arduino/libretuya/core/SerialExtern.h @@ -0,0 +1,25 @@ +/* Copyright (c) Kuba SzczodrzyƄski 2022-07-04. */ + +#pragma once + +#include + +#ifdef HAS_SERIAL_CLASS // failsafe for circular inclusion + +#ifdef PIN_SERIAL0_TX +extern SerialClass Serial0; +#endif + +#ifdef PIN_SERIAL1_TX +extern SerialClass Serial1; +#endif + +#ifdef PIN_SERIAL2_TX +extern SerialClass Serial2; +#endif + +#define SerialN(x) Serial##x +#define SerialM(x) SerialN(x) +#define Serial SerialM(LT_UART_DEFAULT_SERIAL) + +#endif diff --git a/arduino/libretuya/core/lt_logger.c b/arduino/libretuya/core/lt_logger.c index 648ddfe..8bc0e78 100644 --- a/arduino/libretuya/core/lt_logger.c +++ b/arduino/libretuya/core/lt_logger.c @@ -3,6 +3,7 @@ #include "lt_logger.h" #include +#include #if LT_LOGGER_TASK && LT_HAS_FREERTOS #include @@ -27,10 +28,11 @@ #define COLOR_BRIGHT_CYAN 0x16 #define COLOR_BRIGHT_WHITE 0x17 -const char levels[] = {'V', 'D', 'I', 'W', 'E', 'F'}; +static uint8_t uart_port = LT_UART_DEFAULT_LOGGER; +static const char levels[] = {'V', 'D', 'I', 'W', 'E', 'F'}; #if LT_LOGGER_COLOR -const uint8_t colors[] = { +static const uint8_t colors[] = { COLOR_BRIGHT_CYAN, COLOR_BRIGHT_BLUE, COLOR_BRIGHT_GREEN, @@ -72,7 +74,10 @@ void lt_log(const uint8_t level, const char *format, ...) { char c_value = '0' + (colors[level] & 0x7); #endif - printf( + fctprintf( + putchar_p, + uart_port, + // format: #if LT_LOGGER_COLOR "\e[%c;3%cm" #endif @@ -94,6 +99,7 @@ void lt_log(const uint8_t level, const char *format, ...) { "%s%c " #endif , + // arguments: #if LT_LOGGER_COLOR c_bright, // whether text is bright c_value, // text color @@ -121,7 +127,12 @@ void lt_log(const uint8_t level, const char *format, ...) { va_list va_args; va_start(va_args, format); - vprintf(format, va_args); + vfctprintf(putchar_p, uart_port, format, va_args); va_end(va_args); - printf("\r\n"); + putchar_p('\r', uart_port); + putchar_p('\n', uart_port); +} + +void lt_log_set_port(uint8_t port) { + uart_port = port; } diff --git a/arduino/libretuya/core/lt_logger.h b/arduino/libretuya/core/lt_logger.h index f6c6156..c178841 100644 --- a/arduino/libretuya/core/lt_logger.h +++ b/arduino/libretuya/core/lt_logger.h @@ -13,6 +13,13 @@ void lt_log(const uint8_t level, const char *caller, const unsigned short line, void lt_log(const uint8_t level, const char *format, ...); #endif +/** + * @brief Change log output port. + * + * @param port UART port index - can be 0, 1 or 2 + */ +void lt_log_set_port(uint8_t port); + #if LT_LEVEL_TRACE >= LT_LOGLEVEL #define LT_T(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__) #define LT_V(...) LT_LOG(LT_LEVEL_TRACE, __FUNCTION__, __LINE__, __VA_ARGS__) diff --git a/arduino/libretuya/port/printf/printf_config.h b/arduino/libretuya/port/printf/printf_config.h index cf831ba..e89a456 100644 --- a/arduino/libretuya/port/printf/printf_config.h +++ b/arduino/libretuya/port/printf/printf_config.h @@ -14,6 +14,9 @@ #define vsnprintf_ __wrap_vsnprintf #define vprintf_ __wrap_vprintf +// declare putchar() method with custom output port +void putchar_p(char c, unsigned long port); + #define WRAP_DISABLE_DEF(name) \ extern void __wrap_##name##_disable(); \ extern void __wrap_##name##_enable(); \ diff --git a/arduino/realtek-ambz/cores/arduino/Arduino.h b/arduino/realtek-ambz/cores/arduino/Arduino.h index 57488a5..093f7f9 100644 --- a/arduino/realtek-ambz/cores/arduino/Arduino.h +++ b/arduino/realtek-ambz/cores/arduino/Arduino.h @@ -16,27 +16,19 @@ // Include board variant #include "variant.h" +// Choose the main UART output port +#ifndef LT_UART_DEFAULT_PORT +#if defined(PIN_SERIAL2_TX) +#define LT_UART_DEFAULT_PORT 2 +#elif defined(PIN_SERIAL0_TX) +#define LT_UART_DEFAULT_PORT 0 +#else +#define LT_UART_DEFAULT_PORT 1 +#endif +#endif + // Define available serial ports #ifdef __cplusplus #include "SerialClass.h" -#ifdef HAS_SERIAL_CLASS // failsafe for circular inclusion - -#ifdef PIN_SERIAL0_TX -extern SerialClass Serial0; -#endif - -#ifdef PIN_SERIAL1_TX -extern SerialClass Serial1; -#endif - -#ifdef PIN_SERIAL2_RX -extern SerialClass Serial2; -#define Serial Serial2 -#elif PIN_SERIAL0_TX -#define Serial Serial0 -#else -#define Serial Serial1 -#endif - -#endif +#include #endif diff --git a/arduino/realtek-ambz/cores/arduino/main.cpp b/arduino/realtek-ambz/cores/arduino/main.cpp index 817b436..cae04fb 100644 --- a/arduino/realtek-ambz/cores/arduino/main.cpp +++ b/arduino/realtek-ambz/cores/arduino/main.cpp @@ -1,37 +1,25 @@ -/* - main.cpp - Main loop for Arduino sketches - Copyright (c) 2005-2013 Arduino Team. All right reserved. - - This library 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 library 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 library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#define ARDUINO_MAIN +/* Copyright (c) Kuba SzczodrzyƄski 2022-06-19. */ #include -#include -osThreadId main_tid = 0; +extern "C" { + +#include extern uint32_t GlobalDebugEnable; extern uint16_t GlobalDebugLevel; extern uint8_t GlobalPrivateLog; +extern uint8_t lt_uart_port; + +} // extern "C" + +osThreadId main_tid = 0; void initArduino() { // make the SDK less verbose by default GlobalDebugEnable = 0; GlobalPrivateLog = 0; + lt_uart_port = LT_UART_DEFAULT_PORT; } bool startMainTask() { diff --git a/arduino/realtek-ambz/port/printf/printf.c b/arduino/realtek-ambz/port/printf/printf.c index 2f5d339..9724504 100644 --- a/arduino/realtek-ambz/port/printf/printf.c +++ b/arduino/realtek-ambz/port/printf/printf.c @@ -15,9 +15,21 @@ extern uint32_t UART_Writable(void *UARTx); extern void UART_CharPut(void *UARTx, uint8_t TxData); +static const void *uart_dev[3] = { + UART0_REG_BASE, + UART1_REG_BASE, + LOG_UART_REG_BASE, +}; + +uint8_t lt_uart_port = 2; + void putchar_(char c) { - while (UART_Writable(LOG_UART_REG_BASE) == 0) {} - UART_CharPut(LOG_UART_REG_BASE, c); + putchar_p(c, lt_uart_port); +} + +void putchar_p(char c, unsigned long port) { + while (UART_Writable(uart_dev[port]) == 0) {} + UART_CharPut(uart_dev[port], c); } WRAP_PRINTF(rtl_printf); diff --git a/docs/config.md b/docs/config.md index 5fe5526..5580d7c 100644 --- a/docs/config.md +++ b/docs/config.md @@ -62,9 +62,19 @@ Families should generally call i.e. WiFiClient debugging for client-related code Options for controlling default UART log output. +- `LT_UART_DEFAULT_PORT` (unset) - default output port for all messages (SDK, LT logger, Serial class); can be 0, 1 or 2 +- `LT_UART_DEFAULT_LOGGER` (unset) - override default output port for LT logger only +- `LT_UART_DEFAULT_SERIAL` (unset) - override default output port for `Serial` class (without a number) - `LT_UART_SILENT_ENABLED` (1) - enable auto-silencing of SDK "loggers"; this makes the serial output much more readable, but can hide some error messages - `LT_UART_SILENT_ALL` (0) - disable all SDK output (LT output and logger still work) +!!! info + Values 0, 1 and 2 correspond to physical UART port numbers (refer to board pinout for the available ports). + + Serial class instances (`Serial0`, `Serial1`, `Serial2`) use the respective port numbers for printing. + + If `LT_UART_DEFAULT_LOGGER` is not set, it is chosen by the family code - whichever port is most appropriate (i.e. LOG_UART (2) on Realtek, RX2/TX2 on Beken). + ### Family feature config These options are selectively set by all families, as part of the build process. They are used for enabling LT core API parts, if the family has support for it.