From d25603166a920415004648a6c4800e735afa5b24 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Wed, 8 Oct 2025 23:16:45 +0200 Subject: [PATCH] Merge develop into main (#365) ### TactilityC - Create UART HAL - Refactor locking APIs - Bind new C++ functionality - Bind new LVGL functionality ### Apps - Remove Serial Console as it has been ported as an external app --- Data/system/app_icon_calculator_dark_mode.png | Bin 432 -> 0 bytes Tactility/Include/Tactility/hal/uart/Uart.h | 10 +- .../Tactility/app/serialconsole/ConnectView.h | 159 ---------- .../Tactility/app/serialconsole/ConsoleView.h | 283 ------------------ .../Tactility/app/serialconsole/View.h | 10 - .../Private/Tactility/hal/uart/UartEsp.h | 22 +- Tactility/Source/Tactility.cpp | 2 - .../app/serialconsole/SerialConsole.cpp | 95 ------ TactilityC/Include/tt_file.h | 13 - TactilityC/Include/tt_hal_uart.h | 152 ++++++++++ TactilityC/Include/tt_lock.h | 21 ++ TactilityC/Include/tt_lvgl.h | 4 +- TactilityC/Include/tt_mutex.h | 48 --- TactilityC/Private/symbols/cplusplus.h | 5 + TactilityC/Source/symbols/cplusplus.cpp | 18 ++ TactilityC/Source/symbols/esp_event.cpp | 6 + TactilityC/Source/symbols/esp_http_client.cpp | 6 + TactilityC/Source/symbols/gcc_soft_float.cpp | 8 +- TactilityC/Source/symbols/pthread.cpp | 6 + TactilityC/Source/symbols/stl.cpp | 17 +- TactilityC/Source/tt_file.cpp | 13 - TactilityC/Source/tt_hal_uart.cpp | 82 +++++ TactilityC/Source/tt_init.cpp | 45 ++- TactilityC/Source/tt_lock.cpp | 32 +- TactilityC/Source/tt_lvgl.cpp | 5 +- TactilityC/Source/tt_mutex.cpp | 31 -- 26 files changed, 391 insertions(+), 702 deletions(-) delete mode 100644 Data/system/app_icon_calculator_dark_mode.png delete mode 100644 Tactility/Private/Tactility/app/serialconsole/ConnectView.h delete mode 100644 Tactility/Private/Tactility/app/serialconsole/ConsoleView.h delete mode 100644 Tactility/Private/Tactility/app/serialconsole/View.h delete mode 100644 Tactility/Source/app/serialconsole/SerialConsole.cpp delete mode 100644 TactilityC/Include/tt_file.h create mode 100644 TactilityC/Include/tt_hal_uart.h delete mode 100644 TactilityC/Include/tt_mutex.h create mode 100644 TactilityC/Private/symbols/cplusplus.h create mode 100644 TactilityC/Source/symbols/cplusplus.cpp delete mode 100644 TactilityC/Source/tt_file.cpp create mode 100644 TactilityC/Source/tt_hal_uart.cpp delete mode 100644 TactilityC/Source/tt_mutex.cpp diff --git a/Data/system/app_icon_calculator_dark_mode.png b/Data/system/app_icon_calculator_dark_mode.png deleted file mode 100644 index 62549990718c0c161db6ce8f0a7198daac6d17ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432 zcmV;h0Z;ykP)Px$YDq*vR5(wilfOy>K@i4gc9nETxJe;cDA};ZqwpKO?nIm=JX3Xd%S(BI(-DdyY{q~!WZxDjfXf&n}aXvg7To($3mne#w z-E-_Nn7Ir9N8^6Z?zA%>6VZw7LqHu7D{&m3j)O4sApqX#=4BCi{SDw90L+6KX0E7e zyHqM2Fmqi*)|_**nF1^2D+i%TM0Asr12ej3@{oz%`(output), timeout); } - inline bool readByte(uint8_t* output, TickType_t timeout = defaultTimeout) { + bool readByte(uint8_t* output, TickType_t timeout = defaultTimeout) { return readByte(reinterpret_cast(output), timeout); } @@ -77,7 +75,7 @@ public: */ virtual size_t writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) = 0; - inline size_t writeBytes(const std::uint8_t* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) { + size_t writeBytes(const std::uint8_t* buffer, size_t bufferSize, TickType_t timeout = defaultTimeout) { return writeBytes(reinterpret_cast(buffer), bufferSize, timeout); } diff --git a/Tactility/Private/Tactility/app/serialconsole/ConnectView.h b/Tactility/Private/Tactility/app/serialconsole/ConnectView.h deleted file mode 100644 index f8b2ef2e..00000000 --- a/Tactility/Private/Tactility/app/serialconsole/ConnectView.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once - -#include "View.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace tt::app::serialconsole { - -class ConnectView final : public View { - -public: - - typedef std::function)> OnConnectedFunction; - std::vector uartNames; - Preferences preferences = Preferences("SerialConsole"); - -private: - - OnConnectedFunction onConnected; - lv_obj_t* busDropdown = nullptr; - lv_obj_t* speedTextarea = nullptr; - - int32_t getSpeedInput() const { - auto* speed_text = lv_textarea_get_text(speedTextarea); - return std::stoi(speed_text); - } - - void onConnect() { - auto lock = lvgl::getSyncLock()->asScopedLock(); - if (!lock.lock(lvgl::defaultLockTime)) { - return; - } - - auto selected_uart_index = lv_dropdown_get_selected(busDropdown); - if (selected_uart_index >= uartNames.size()) { - alertdialog::start("Error", "No UART selected"); - return; - } - - auto uart_name = uartNames[selected_uart_index]; - auto uart = hal::uart::open(uart_name); - if (uart == nullptr) { - alertdialog::start("Error", "Failed to connect to UART"); - return; - } - - int speed = getSpeedInput(); - if (speed <= 0) { - alertdialog::start("Error", "Invalid speed"); - return; - } - - if (!uart->start()) { - alertdialog::start("Error", "Failed to initialize"); - return; - } - - if (!uart->setBaudRate(speed)) { - uart->stop(); - alertdialog::start("Error", "Failed to set baud rate"); - return; - } - - onConnected(std::move(uart)); - } - - static void onConnectCallback(lv_event_t* event) { - auto* view = (ConnectView*)lv_event_get_user_data(event); - view->onConnect(); - } - - static lv_obj_t* createRowWrapper(lv_obj_t* parent) { - auto* wrapper = lv_obj_create(parent); - lv_obj_set_size(wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_border_width(wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_pad_all(wrapper, 0, LV_STATE_DEFAULT); - return wrapper; - } - -public: - - explicit ConnectView(OnConnectedFunction onConnected) : onConnected(std::move(onConnected)) {} - - void onStart(lv_obj_t* parent) { - uartNames = hal::uart::getNames(); - - auto* wrapper = lv_obj_create(parent); - lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); - lv_obj_set_size(wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_border_width(wrapper, 0, LV_STATE_DEFAULT); - lvgl::obj_set_style_bg_invisible(wrapper); - - // Bus selection - - auto* bus_wrapper = createRowWrapper(wrapper); - - busDropdown = lv_dropdown_create(bus_wrapper); - - auto bus_options = string::join(uartNames, "\n"); - lv_dropdown_set_options(busDropdown, bus_options.c_str()); - lv_obj_align(busDropdown, LV_ALIGN_RIGHT_MID, 0, 0); - lv_obj_set_width(busDropdown, LV_PCT(50)); - - int32_t bus_index = 0; - preferences.optInt32("bus", bus_index); - if (bus_index < uartNames.size()) { - lv_dropdown_set_selected(busDropdown, bus_index); - } - - auto* bus_label = lv_label_create(bus_wrapper); - lv_obj_align(bus_label, LV_ALIGN_LEFT_MID, 0, 0); - lv_label_set_text(bus_label, "Bus"); - - // Baud rate selection - auto* baud_wrapper = createRowWrapper(wrapper); - - int32_t speed = 115200; - preferences.optInt32("speed", speed); - speedTextarea = lv_textarea_create(baud_wrapper); - lv_textarea_set_text(speedTextarea, std::to_string(speed).c_str()); - lv_textarea_set_one_line(speedTextarea, true); - lv_obj_set_width(speedTextarea, LV_PCT(50)); - lv_obj_align(speedTextarea, LV_ALIGN_TOP_RIGHT, 0, 0); - - auto* baud_rate_label = lv_label_create(baud_wrapper); - lv_obj_align(baud_rate_label, LV_ALIGN_TOP_LEFT, 0, 0); - lv_label_set_text(baud_rate_label, "Baud"); - - // Connect - auto* connect_wrapper = createRowWrapper(wrapper); - - auto* connect_button = lv_button_create(connect_wrapper); - lv_obj_align(connect_button, LV_ALIGN_CENTER, 0, 0); - lv_obj_add_event_cb(connect_button, onConnectCallback, LV_EVENT_SHORT_CLICKED, this); - auto* connect_label = lv_label_create(connect_button); - lv_label_set_text(connect_label, "Connect"); - } - - void onStop() override { - int speed = getSpeedInput(); - if (speed > 0) { - preferences.putInt32("speed", speed); - } - - auto bus_index = (int32_t)lv_dropdown_get_selected(busDropdown); - preferences.putInt32("bus", bus_index); - } -}; - - -} // namespace tt::app::serialconsole diff --git a/Tactility/Private/Tactility/app/serialconsole/ConsoleView.h b/Tactility/Private/Tactility/app/serialconsole/ConsoleView.h deleted file mode 100644 index ded396f6..00000000 --- a/Tactility/Private/Tactility/app/serialconsole/ConsoleView.h +++ /dev/null @@ -1,283 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace tt::app::serialconsole { - -constexpr auto* TAG = "SerialConsole"; -constexpr size_t receiveBufferSize = 512; -constexpr size_t renderBufferSize = receiveBufferSize + 2; // Leave space for newline at split and null terminator at the end - -class ConsoleView final : public View { - - lv_obj_t* _Nullable parent = nullptr; - lv_obj_t* _Nullable logTextarea = nullptr; - lv_obj_t* _Nullable inputTextarea = nullptr; - std::unique_ptr _Nullable uart = nullptr; - std::shared_ptr uartThread _Nullable = nullptr; - bool uartThreadInterrupted = false; - std::shared_ptr viewThread _Nullable = nullptr; - bool viewThreadInterrupted = false; - Mutex mutex = Mutex(Mutex::Type::Recursive); - uint8_t receiveBuffer[receiveBufferSize]; - uint8_t renderBuffer[renderBufferSize]; - size_t receiveBufferPosition = 0; - std::string terminatorString = "\n"; - - bool isUartThreadInterrupted() const { - auto lock = mutex.asScopedLock(); - lock.lock(); - return uartThreadInterrupted; - } - - bool isViewThreadInterrupted() const { - auto lock = mutex.asScopedLock(); - lock.lock(); - return viewThreadInterrupted; - } - - void updateViews() { - auto lvgl_lock = lvgl::getSyncLock()->asScopedLock(); - if (!lvgl_lock.lock(lvgl::defaultLockTime)) { - return; - } - - if (parent == nullptr) { - return; - } - - // Updating the view is expensive, so we only want to set the text once: - // Gather all the lines in a single buffer - if (mutex.lock()) { - size_t first_part_size = receiveBufferSize - receiveBufferPosition; - memcpy(renderBuffer, receiveBuffer + receiveBufferPosition, first_part_size); - renderBuffer[receiveBufferPosition] = '\n'; - if (receiveBufferPosition > 0) { - memcpy(renderBuffer + first_part_size + 1, receiveBuffer, (receiveBufferSize - first_part_size)); - renderBuffer[receiveBufferSize - 1] = 0x00; - } - mutex.unlock(); - } - - if (lvgl::lock(lvgl::defaultLockTime)) { - lv_textarea_set_text(logTextarea, (const char*)renderBuffer); - lvgl::unlock(); - } - } - - int32_t viewThreadMain() { - while (!isViewThreadInterrupted()) { - auto start_time = kernel::getTicks(); - - updateViews(); - - auto end_time = kernel::getTicks(); - auto time_diff = end_time - start_time; - if (time_diff < 500U) { - kernel::delayTicks((500U - time_diff) / portTICK_PERIOD_MS); - } - } - - return 0; - } - - int32_t uartThreadMain() { - uint8_t byte; - - while (!isUartThreadInterrupted()) { - assert(uart != nullptr); - bool success = uart->readByte(&byte, 50 / portTICK_PERIOD_MS); - - // Thread might've been interrupted in the meanwhile - if (isUartThreadInterrupted()) { - break; - } - - if (success) { - mutex.lock(); - receiveBuffer[receiveBufferPosition++] = byte; - if (receiveBufferPosition == receiveBufferSize) { - receiveBufferPosition = 0; - } - mutex.unlock(); - } - - } - - return 0; - } - - static void onSendClickedCallback(lv_event_t* event) { - auto* view = (ConsoleView*)lv_event_get_user_data(event); - view->onSendClicked(); - } - - static void onTerminatorDropdownValueChangedCallback(lv_event_t* event) { - auto* view = (ConsoleView*)lv_event_get_user_data(event); - view->onTerminatorDropDownValueChanged(event); - } - - void onTerminatorDropDownValueChanged(lv_event_t* event) { - auto* dropdown = static_cast(lv_event_get_target(event)); - mutex.lock(); - switch (lv_dropdown_get_selected(dropdown)) { - case 0: - terminatorString = "\n"; - break; - case 1: - terminatorString = "\r\n"; - break; - } - mutex.unlock(); - } - - void onSendClicked() { - mutex.lock(); - std::string input_text = lv_textarea_get_text(inputTextarea); - std::string to_send = input_text + terminatorString; - mutex.unlock(); - - auto* safe_uart = uart.get(); - if (safe_uart != nullptr) { - if (!safe_uart->writeString(to_send.c_str(), 100 / portTICK_PERIOD_MS)) { - TT_LOG_E(TAG, "Failed to send \"%s\"", input_text.c_str()); - } - } - - lv_textarea_set_text(inputTextarea, ""); - } - -public: - - void startLogic(std::unique_ptr newUart) { - memset(receiveBuffer, 0, receiveBufferSize); - - assert(uartThread == nullptr); - assert(uart == nullptr); - - uart = std::move(newUart); - - uartThreadInterrupted = false; - uartThread = std::make_unique( - "SerConsUart", - 4096, - [this]() { - return this->uartThreadMain(); - } - ); - uartThread->setPriority(tt::Thread::Priority::High); - uartThread->start(); - } - - void startViews(lv_obj_t* parent) { - this->parent = parent; - - lv_obj_set_style_pad_gap(parent, 2, 0); - - logTextarea = lv_textarea_create(parent); - lv_textarea_set_placeholder_text(logTextarea, "Waiting for data..."); - lv_obj_set_flex_grow(logTextarea, 1); - lv_obj_set_width(logTextarea, LV_PCT(100)); - lv_obj_add_state(logTextarea, LV_STATE_DISABLED); - lv_obj_set_style_margin_ver(logTextarea, 0, 0); - - auto* input_wrapper = lv_obj_create(parent); - lv_obj_set_size(input_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(input_wrapper, 0, 0); - lv_obj_set_style_border_width(input_wrapper, 0, 0); - lv_obj_set_width(input_wrapper, LV_PCT(100)); - lv_obj_set_flex_flow(input_wrapper, LV_FLEX_FLOW_ROW); - - inputTextarea = lv_textarea_create(input_wrapper); - lv_textarea_set_one_line(inputTextarea, true); - lv_textarea_set_placeholder_text(inputTextarea, "Text to send"); - lv_obj_set_width(inputTextarea, LV_PCT(100)); - lv_obj_set_flex_grow(inputTextarea, 1); - - auto* terminator_dropdown = lv_dropdown_create(input_wrapper); - lv_dropdown_set_options(terminator_dropdown, "\\n\n\\r\\n"); - lv_obj_set_width(terminator_dropdown, 70); - lv_obj_add_event_cb(terminator_dropdown, onTerminatorDropdownValueChangedCallback, LV_EVENT_VALUE_CHANGED, this); - - - auto* button = lv_button_create(input_wrapper); - auto* button_label = lv_label_create(button); - lv_label_set_text(button_label, "Send"); - lv_obj_add_event_cb(button, onSendClickedCallback, LV_EVENT_SHORT_CLICKED, this); - - viewThreadInterrupted = false; - viewThread = std::make_unique( - "SerConsView", - 4096, - [this] { - return this->viewThreadMain(); - } - ); - viewThread->setPriority(THREAD_PRIORITY_RENDER); - viewThread->start(); - } - - void stopLogic() { - auto lock = mutex.asScopedLock(); - lock.lock(); - - uartThreadInterrupted = true; - - // Detach thread, it will auto-delete when leaving the current scope - auto old_uart_thread = std::move(uartThread); - // Unlock so thread can lock - lock.unlock(); - - if (old_uart_thread->getState() != Thread::State::Stopped) { - // Wait for thread to finish - old_uart_thread->join(); - } - } - - void stopViews() { - auto lock = mutex.asScopedLock(); - lock.lock(); - - viewThreadInterrupted = true; - - // Detach thread, it will auto-delete when leaving the current scope - auto old_view_thread = std::move(viewThread); - - // Unlock so thread can lock - lock.unlock(); - - if (old_view_thread->getState() != Thread::State::Stopped) { - // Wait for thread to finish - old_view_thread->join(); - } - } - - void stopUart() { - auto lock = mutex.asScopedLock(); - lock.lock(); - - if (uart != nullptr && uart->isStarted()) { - uart->stop(); - uart = nullptr; - } - } - - void onStart(lv_obj_t* parent, std::unique_ptr newUart) { - auto lock = mutex.asScopedLock(); - lock.lock(); - - startLogic(std::move(newUart)); - startViews(parent); - } - - void onStop() override { - stopViews(); - stopLogic(); - stopUart(); - } -}; - -} // namespace tt::app::serialconsole diff --git a/Tactility/Private/Tactility/app/serialconsole/View.h b/Tactility/Private/Tactility/app/serialconsole/View.h deleted file mode 100644 index 38ea46d8..00000000 --- a/Tactility/Private/Tactility/app/serialconsole/View.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace tt::app::serialconsole { - -class View { -public: - virtual void onStop() = 0; -}; - -} \ No newline at end of file diff --git a/Tactility/Private/Tactility/hal/uart/UartEsp.h b/Tactility/Private/Tactility/hal/uart/UartEsp.h index ac20293e..650d8f84 100644 --- a/Tactility/Private/Tactility/hal/uart/UartEsp.h +++ b/Tactility/Private/Tactility/hal/uart/UartEsp.h @@ -9,8 +9,6 @@ namespace tt::hal::uart { class UartEsp final : public Uart { -private: - Mutex mutex; const Configuration& configuration; bool started = false; @@ -19,16 +17,16 @@ public: explicit UartEsp(const Configuration& configuration) : configuration(configuration) {} - bool start() final; - bool isStarted() const final; - bool stop() final; - size_t readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout) final; - bool readByte(std::byte* output, TickType_t timeout) final; - size_t writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout) final; - size_t available(TickType_t timeout) final; - bool setBaudRate(uint32_t baudRate, TickType_t timeout) final; - uint32_t getBaudRate() final; - void flushInput() final; + bool start() override; + bool isStarted() const override; + bool stop() override; + size_t readBytes(std::byte* buffer, size_t bufferSize, TickType_t timeout) override; + bool readByte(std::byte* output, TickType_t timeout) override; + size_t writeBytes(const std::byte* buffer, size_t bufferSize, TickType_t timeout) override; + size_t available(TickType_t timeout) override; + bool setBaudRate(uint32_t baudRate, TickType_t timeout) override; + uint32_t getBaudRate() override; + void flushInput() override; }; std::unique_ptr create(const Configuration& configuration); diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index 35e06ae1..30516433 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -76,7 +76,6 @@ namespace app { namespace notes { extern const AppManifest manifest; } namespace power { extern const AppManifest manifest; } namespace selectiondialog { extern const AppManifest manifest; } - namespace serialconsole { extern const AppManifest manifest; } namespace settings { extern const AppManifest manifest; } namespace systeminfo { extern const AppManifest manifest; } namespace timedatesettings { extern const AppManifest manifest; } @@ -143,7 +142,6 @@ static void registerInternalApps() { if (!hal::getConfiguration()->uart.empty()) { addApp(app::addgps::manifest); addApp(app::gpssettings::manifest); - addApp(app::serialconsole::manifest); } if (hal::hasDevice(hal::Device::Type::Power)) { diff --git a/Tactility/Source/app/serialconsole/SerialConsole.cpp b/Tactility/Source/app/serialconsole/SerialConsole.cpp deleted file mode 100644 index f756be23..00000000 --- a/Tactility/Source/app/serialconsole/SerialConsole.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "../../../Private/Tactility/app/serialconsole/ConnectView.h" -#include "Tactility/app/serialconsole/ConsoleView.h" - -#include "Tactility/lvgl/Style.h" -#include "Tactility/lvgl/Toolbar.h" -#include "Tactility/service/loader/Loader.h" - -#include - -#include - -namespace tt::app::serialconsole { - -class SerialConsoleApp final : public App { - -private: - - lv_obj_t* disconnectButton = nullptr; - lv_obj_t* wrapperWidget = nullptr; - ConnectView connectView = ConnectView([this](auto uart){ - showConsoleView(std::move(uart)); - }); - ConsoleView consoleView; - View* activeView = nullptr; - - void stopActiveView() { - if (activeView != nullptr) { - activeView->onStop(); - lv_obj_clean(wrapperWidget); - activeView = nullptr; - } - } - - void showConsoleView(std::unique_ptr uart) { - stopActiveView(); - activeView = &consoleView; - consoleView.onStart(wrapperWidget, std::move(uart)); - lv_obj_remove_flag(disconnectButton, LV_OBJ_FLAG_HIDDEN); - } - - void showConnectView() { - stopActiveView(); - activeView = &connectView; - connectView.onStart(wrapperWidget); - lv_obj_add_flag(disconnectButton, LV_OBJ_FLAG_HIDDEN); - } - - void onDisconnect() { - // Changing views (calling ConsoleView::stop()) also disconnects the UART - showConnectView(); - } - - static void onDisconnectPressed(lv_event_t* event) { - auto* app = (SerialConsoleApp*)lv_event_get_user_data(event); - app->onDisconnect(); - } - -public: - - SerialConsoleApp() = default; - - void onShow(AppContext& app, lv_obj_t* parent) final { - lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); - lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); - - auto* toolbar = lvgl::toolbar_create(parent, app); - - disconnectButton = lvgl::toolbar_add_image_button_action(toolbar, LV_SYMBOL_POWER, onDisconnectPressed, this); - lv_obj_add_flag(disconnectButton, LV_OBJ_FLAG_HIDDEN); - - wrapperWidget = lv_obj_create(parent); - lv_obj_set_width(wrapperWidget, LV_PCT(100)); - lv_obj_set_flex_grow(wrapperWidget, 1); - lv_obj_set_flex_flow(wrapperWidget, LV_FLEX_FLOW_COLUMN); - lv_obj_set_style_pad_all(wrapperWidget, 0, 0); - lv_obj_set_style_border_width(wrapperWidget, 0, 0); - lvgl::obj_set_style_bg_invisible(wrapperWidget); - - showConnectView(); - } - - void onHide(AppContext& app) final { - stopActiveView(); - } -}; - -extern const AppManifest manifest = { - .appId = "SerialConsole", - .appName = "Serial Console", - .appIcon = LV_SYMBOL_LIST, - .appCategory = Category::System, - .createApp = create -}; - -} // namespace diff --git a/TactilityC/Include/tt_file.h b/TactilityC/Include/tt_file.h deleted file mode 100644 index 77589bf0..00000000 --- a/TactilityC/Include/tt_file.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "tt_lock.h" - -#ifdef __cplusplus -extern "C" { -#endif - -LockHandle tt_lock_alloc_for_file(const char* path); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Include/tt_hal_uart.h b/TactilityC/Include/tt_hal_uart.h new file mode 100644 index 00000000..51070b90 --- /dev/null +++ b/TactilityC/Include/tt_hal_uart.h @@ -0,0 +1,152 @@ +#pragma once + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file tt_hal_uart.h + * @brief C HAL interface for UART devices used by Tactility C modules. + * + * This header exposes a minimal, C-compatible UART API that mirrors the higher-level + * C++ UART interface (see Tactility/hal/uart). + * + * General notes: + * - Start the UART before I/O using tt_hal_uart_start(); stop it with tt_hal_uart_stop(). + */ + +typedef void* UartHandle; /**< Opaque handle to an underlying UART instance. */ + +/** + * @brief Get the number of UART devices available on this platform. + * @return Count of discoverable UARTs (0 if none). + */ +size_t tt_hal_uart_get_count(); + +/** + * @brief Get the user-friendly name of a UART by index. + * @param index Zero-based UART index in the range [0, tt_hal_uart_get_count()). + * @param[out] name Destination buffer to receive a null-terminated name. + * @param nameSizeLimit Size in bytes of the destination buffer. The name will be + * truncated to fit and always null-terminated if the size + * is greater than 0. + * @return true if a name was written to the buffer; false if the index is out of range + * or on other failure. + */ +bool tt_hal_uart_get_name(size_t index, char* name, size_t nameSizeLimit); + +/** + * @brief Allocate an opaque UART handle by index. + * + * Allocation does not start the hardware; call tt_hal_uart_start() to begin I/O. + * + * @param index Zero-based UART index. + * @return A valid UartHandle on success; NULL on failure (e.g., invalid index or already in use). + */ +UartHandle tt_hal_uart_alloc(size_t index); + +/** + * @brief Release a previously allocated UART handle and any associated resources. + * @param handle Handle returned by tt_hal_uart_alloc() + */ +void tt_hal_uart_free(UartHandle handle); + +/** + * @brief Start the UART so it can perform I/O. + * @param handle A valid UART handle. + * @return true on success; false on failure. + */ +bool tt_hal_uart_start(UartHandle handle); + +/** + * @brief Query whether the UART has been started. + * @param handle A valid UART handle. + * @return true if started; false otherwise. + */ +bool tt_hal_uart_is_started(UartHandle handle); + +/** + * @brief Stop the UART + * @param handle A valid UART handle. + * @return true on success; false on failure. + */ +bool tt_hal_uart_stop(UartHandle handle); + +/** + * @brief Read up to bufferSize bytes into buffer. + * + * This call may block up to timeout ticks waiting for data. It returns the actual + * number of bytes placed into the buffer, which can be less than bufferSize if + * fewer bytes became available before the timeout expired. + * + * @param handle A valid UART handle. + * @param[out] buffer Destination buffer. + * @param bufferSize Capacity of the destination buffer in bytes. + * @param timeout Maximum time to wait in ticks. Use 0 for non-blocking; use TT_MAX_TICKS + * to wait indefinitely. + * @return The number of bytes read (0 on timeout with no data). Never exceeds bufferSize. + */ +size_t tt_hal_uart_read_bytes(UartHandle handle, char* buffer, size_t bufferSize, TickType timeout); + +/** + * @brief Read a single byte. + * + * @param handle A valid UART handle. + * @param[out] output Where to store the read byte. + * @param timeout Maximum time to wait in ticks. Use 0 for non-blocking; use TT_MAX_TICKS + * to wait indefinitely. + * @return true if a byte was read and stored in output; false on timeout or failure. + */ +bool tt_hal_uart_read_byte(UartHandle handle, char* output, TickType timeout); + +/** + * @brief Write up to bufferSize bytes from buffer. + * + * This call may block up to timeout ticks waiting for transmit queue space. It returns + * the number of bytes accepted for transmission. + * + * @param handle A valid UART handle. + * @param[in] buffer Source buffer containing bytes to write. + * @param bufferSize Number of bytes to write from buffer. + * @param timeout Maximum time to wait in ticks. Use 0 for non-blocking; use TT_MAX_TICKS + * to wait indefinitely. + * @return The number of bytes written (may be less than bufferSize on timeout). + */ +size_t tt_hal_uart_write_bytes(UartHandle handle, const char* buffer, size_t bufferSize, TickType timeout); + +/** + * @brief Get the number of bytes currently available to read without blocking. + * @param handle A valid UART handle. + * @return The count of bytes available in the receive buffer. + */ +size_t tt_hal_uart_available(UartHandle handle); + +/** + * @brief Set the UART baud rate. + * @param handle A valid UART handle. + * @param baud_rate Desired baud rate in bits per second (e.g., 115200). + * @return true on success; false if the rate is unsupported or on error. + */ +bool tt_hal_uart_set_baud_rate(UartHandle handle, size_t baud_rate); + +/** + * @brief Get the current UART baud rate. + * @param handle A valid UART handle. + * @return The configured baud rate in bits per second. + */ +uint32_t tt_hal_uart_get_baud_rate(UartHandle handle); + +/** + * @brief Flush the UART input (receive) buffer, discarding any unread data. + * @param handle A valid UART handle. + */ +void tt_hal_uart_flush_input(UartHandle handle); + +#ifdef __cplusplus +} +#endif diff --git a/TactilityC/Include/tt_lock.h b/TactilityC/Include/tt_lock.h index 81800e80..7708992d 100644 --- a/TactilityC/Include/tt_lock.h +++ b/TactilityC/Include/tt_lock.h @@ -10,6 +10,26 @@ extern "C" { /** A handle that represents a lock instance. A lock could be a Mutex or similar construct */ typedef void* LockHandle; +enum TtMutexType { + MutexTypeNormal, + MutexTypeRecursive +}; + +/** + * Allocate a new mutex instance + * @param[in] type specify if the mutex is either a normal one, or whether it can recursively (re)lock + * @return the allocated lock handle + */ +LockHandle tt_lock_alloc_mutex(enum TtMutexType type); + +/** + * Allocate a lock for a file or folder. + * Locking is required before reading files for filesystems that are on a shared bus (e.g. SPI SD card sharing the bus with the display) + * @param path the path to create the lock for + * @return the allocated lock handle + */ +LockHandle tt_lock_alloc_for_path(const char* path); + /** * Attempt to lock the lock. * @param[in] handle the handle that represents the mutex instance @@ -26,6 +46,7 @@ bool tt_lock_acquire(LockHandle handle, TickType timeout); bool tt_lock_release(LockHandle handle); /** Free the memory for this lock + * This does not auto-release the lock. * @param[in] handle the handle that represents the mutex instance */ void tt_lock_free(LockHandle handle); diff --git a/TactilityC/Include/tt_lvgl.h b/TactilityC/Include/tt_lvgl.h index 44127d40..00cda06d 100644 --- a/TactilityC/Include/tt_lvgl.h +++ b/TactilityC/Include/tt_lvgl.h @@ -6,6 +6,8 @@ extern "C" { #endif +#define TT_LVGL_DEFAULT_LOCK_TIME 500 // 500 ticks = 500 ms + /** @return true if LVGL is started and active */ bool tt_lvgl_is_started(); @@ -16,7 +18,7 @@ void tt_lvgl_start(); void tt_lvgl_stop(); /** Lock the LVGL context. Call this before doing LVGL-related operations from a non-LVLG thread */ -void tt_lvgl_lock(); +bool tt_lvgl_lock(TickType timeout); /** Unlock the LVGL context */ void tt_lvgl_unlock(); diff --git a/TactilityC/Include/tt_mutex.h b/TactilityC/Include/tt_mutex.h deleted file mode 100644 index d316c875..00000000 --- a/TactilityC/Include/tt_mutex.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "tt_kernel.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -/** A handle that represents a mutex instance */ -typedef void* MutexHandle; - -enum TtMutexType { - MUTEX_TYPE_NORMAL, - MUTEX_TYPE_RECURSIVE -}; - -/** - * Allocate a new mutex instance - * @param[in] type specify if the mutex is either a normal one, or whether it can recursively (re)lock - * @return the allocated instance - */ -MutexHandle tt_mutex_alloc(enum TtMutexType type); - -/** Free up the memory of the specified mutex instance. */ -void tt_mutex_free(MutexHandle handle); - -/** - * Attempt to lock a mutex. - * @param[in] handle the handle that represents the mutex instance - * @param[in] timeout the maximum amount of ticks to wait when trying to lock - * @return true when the lock was acquired - */ -bool tt_mutex_lock(MutexHandle handle, TickType timeout); - -/** - * Attempt to unlock a mutex. - * @param[in] handle the handle that represents the mutex instance - * @param[in] timeout the maximum amount of ticks to wait when trying to unlock - * @return true when the lock was unlocked - */ -bool tt_mutex_unlock(MutexHandle handle); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/TactilityC/Private/symbols/cplusplus.h b/TactilityC/Private/symbols/cplusplus.h new file mode 100644 index 00000000..bdead21b --- /dev/null +++ b/TactilityC/Private/symbols/cplusplus.h @@ -0,0 +1,5 @@ +#pragma once + +#include + +extern const esp_elfsym cplusplus_symbols[]; diff --git a/TactilityC/Source/symbols/cplusplus.cpp b/TactilityC/Source/symbols/cplusplus.cpp new file mode 100644 index 00000000..176a6dd7 --- /dev/null +++ b/TactilityC/Source/symbols/cplusplus.cpp @@ -0,0 +1,18 @@ +#include +#include + +#include + +extern "C" { + extern void* _Znwj(uint32_t size); // operator new(unsigned int) + extern void _ZdlPvj(void* p, uint64_t size); // operator delete(void*, unsigned int) + extern void __cxa_pure_virtual(); +} + +const esp_elfsym cplusplus_symbols[] = { + ESP_ELFSYM_EXPORT(_Znwj), // operator new(unsigned int) + ESP_ELFSYM_EXPORT(_ZdlPvj), // operator delete(void*, unsigned int) + ESP_ELFSYM_EXPORT(__cxa_pure_virtual), // class-related, see https://arobenko.github.io/bare_metal_cpp/ + // delimiter + ESP_ELFSYM_END +}; diff --git a/TactilityC/Source/symbols/esp_event.cpp b/TactilityC/Source/symbols/esp_event.cpp index 239028ca..6be6135f 100644 --- a/TactilityC/Source/symbols/esp_event.cpp +++ b/TactilityC/Source/symbols/esp_event.cpp @@ -1,4 +1,8 @@ +#include +#include + #include + #include const esp_elfsym esp_event_symbols[] = { @@ -19,4 +23,6 @@ const esp_elfsym esp_event_symbols[] = { ESP_ELFSYM_EXPORT(esp_event_post_to), ESP_ELFSYM_EXPORT(esp_event_isr_post), ESP_ELFSYM_EXPORT(esp_event_isr_post_to), + // delimiter + ESP_ELFSYM_END }; diff --git a/TactilityC/Source/symbols/esp_http_client.cpp b/TactilityC/Source/symbols/esp_http_client.cpp index 5beb6df1..99a6fe22 100644 --- a/TactilityC/Source/symbols/esp_http_client.cpp +++ b/TactilityC/Source/symbols/esp_http_client.cpp @@ -1,4 +1,8 @@ +#include +#include + #include + #include const esp_elfsym esp_http_client_symbols[] = { @@ -43,4 +47,6 @@ const esp_elfsym esp_http_client_symbols[] = { ESP_ELFSYM_EXPORT(esp_http_client_flush_response), ESP_ELFSYM_EXPORT(esp_http_client_get_url), ESP_ELFSYM_EXPORT(esp_http_client_get_chunk_length), + // delimiter + ESP_ELFSYM_END }; diff --git a/TactilityC/Source/symbols/gcc_soft_float.cpp b/TactilityC/Source/symbols/gcc_soft_float.cpp index 34f5eda2..b6b2921e 100644 --- a/TactilityC/Source/symbols/gcc_soft_float.cpp +++ b/TactilityC/Source/symbols/gcc_soft_float.cpp @@ -1,6 +1,10 @@ -#include +#include +#include + #include +#include + // Reference: https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html extern "C" { @@ -139,7 +143,7 @@ int __gtsf2(float a, float b); int __gtdf2(double a, double b); // int __gttf2(long double a, long double b); -} +} // extern "C" const esp_elfsym gcc_soft_float_symbols[] = { ESP_ELFSYM_EXPORT(__addsf3), diff --git a/TactilityC/Source/symbols/pthread.cpp b/TactilityC/Source/symbols/pthread.cpp index c7f0cca0..dbfa961c 100644 --- a/TactilityC/Source/symbols/pthread.cpp +++ b/TactilityC/Source/symbols/pthread.cpp @@ -1,4 +1,8 @@ +#include +#include + #include + #include const esp_elfsym pthread_symbols[] = { @@ -8,4 +12,6 @@ const esp_elfsym pthread_symbols[] = { ESP_ELFSYM_EXPORT(pthread_detach), ESP_ELFSYM_EXPORT(pthread_join), ESP_ELFSYM_EXPORT(pthread_exit), + // delimiter + ESP_ELFSYM_END }; diff --git a/TactilityC/Source/symbols/stl.cpp b/TactilityC/Source/symbols/stl.cpp index e8ce08a1..a6513d8d 100644 --- a/TactilityC/Source/symbols/stl.cpp +++ b/TactilityC/Source/symbols/stl.cpp @@ -1,18 +1,17 @@ +#include +#include + #include #include -extern "C" { - extern void* _Znwj(uint32_t size); // operator new(unsigned int) - extern void _ZdlPvj(void* p, uint64_t size); // operator delete(void*, unsigned int) -} - const esp_elfsym stl_symbols[] = { - ESP_ELFSYM_EXPORT(_Znwj), // operator new(unsigned int) - ESP_ELFSYM_EXPORT(_ZdlPvj), // operator delete(void*, unsigned int) // Note: You have to use the mangled names here - { "_ZSt20__throw_length_errorPKc", (void*)&(std::__throw_length_error) }, + { "_ZSt17__throw_bad_allocv", (void*)&(std::__throw_bad_alloc) }, { "_ZSt28__throw_bad_array_new_lengthv", (void*)&(std::__throw_bad_array_new_length) }, - { "_ZSt17__throw_bad_allocv", (void*)&(std::__throw_bad_alloc) } + { "_ZSt25__throw_bad_function_callv", (void*)&(std::__throw_bad_function_call) }, + { "_ZSt20__throw_length_errorPKc", (void*)&(std::__throw_length_error) }, // { "", (void*)&(std::) }, + // delimiter + ESP_ELFSYM_END }; diff --git a/TactilityC/Source/tt_file.cpp b/TactilityC/Source/tt_file.cpp deleted file mode 100644 index 0d4d8ae8..00000000 --- a/TactilityC/Source/tt_file.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -extern "C" { - -LockHandle tt_lock_alloc_for_file(const char* path) { - auto lock = tt::file::getLock(path); - auto holder = new LockHolder(lock); - return holder; -} - -} diff --git a/TactilityC/Source/tt_hal_uart.cpp b/TactilityC/Source/tt_hal_uart.cpp new file mode 100644 index 00000000..ff6f9093 --- /dev/null +++ b/TactilityC/Source/tt_hal_uart.cpp @@ -0,0 +1,82 @@ +#include "tt_hal_uart.h" +#include + +using namespace tt::hal; + +struct UartWrapper { + std::shared_ptr uart; +}; + +#define HANDLE_AS_UART(handle) static_cast(handle)->uart + +extern "C" { + +size_t tt_hal_uart_get_count() { + return uart::getNames().size(); +} + +bool tt_hal_uart_get_name(size_t index, char* name, size_t nameSizeLimit) { + assert(index < uart::getNames().size()); + auto source_name = uart::getNames()[index]; + return strncpy(name, source_name.c_str(), nameSizeLimit) != nullptr; +} + +UartHandle tt_hal_uart_alloc(size_t index) { + assert(index < uart::getNames().size()); + auto* wrapper = new UartWrapper(); + auto name = uart::getNames()[index]; + wrapper->uart = uart::open(name); + assert(wrapper->uart != nullptr); + return wrapper; +} + +void tt_hal_uart_free(UartHandle handle) { + auto* wrapper = static_cast(handle); + assert(wrapper->uart != nullptr); + if (wrapper->uart->isStarted()) { + wrapper->uart->stop(); + } + delete wrapper; +} + +bool tt_hal_uart_start(UartHandle handle) { + return HANDLE_AS_UART(handle)->start(); +} + +bool tt_hal_uart_is_started(UartHandle handle) { + return HANDLE_AS_UART(handle)->isStarted(); +} + +bool tt_hal_uart_stop(UartHandle handle) { + return HANDLE_AS_UART(handle)->stop(); +} + +size_t tt_hal_uart_read_bytes(UartHandle handle, char* buffer, size_t bufferSize, TickType timeout) { + return HANDLE_AS_UART(handle)->readBytes(reinterpret_cast(buffer), bufferSize, timeout); +} + +bool tt_hal_uart_read_byte(UartHandle handle, char* output, TickType timeout) { + return HANDLE_AS_UART(handle)->readByte(reinterpret_cast(output), timeout); +} + +size_t tt_hal_uart_write_bytes(UartHandle handle, const char* buffer, size_t bufferSize, TickType timeout) { + return HANDLE_AS_UART(handle)->writeBytes(reinterpret_cast(buffer), bufferSize, timeout); +} + +size_t tt_hal_uart_available(UartHandle handle) { + return HANDLE_AS_UART(handle)->available(); +} + +bool tt_hal_uart_set_baud_rate(UartHandle handle, size_t baud_rate) { + return HANDLE_AS_UART(handle)->setBaudRate(baud_rate); +} + +uint32_t tt_hal_uart_get_baud_rate(UartHandle handle) { + return HANDLE_AS_UART(handle)->getBaudRate(); +} + +void tt_hal_uart_flush_input(UartHandle handle) { + HANDLE_AS_UART(handle)->flushInput(); +} + +} diff --git a/TactilityC/Source/tt_init.cpp b/TactilityC/Source/tt_init.cpp index 1ac208c6..f5ffb565 100644 --- a/TactilityC/Source/tt_init.cpp +++ b/TactilityC/Source/tt_init.cpp @@ -4,7 +4,6 @@ #include "tt_app_alertdialog.h" #include "tt_app_selectiondialog.h" #include "tt_bundle.h" -#include "tt_file.h" #include "tt_gps.h" #include "tt_hal.h" #include "tt_hal_device.h" @@ -12,13 +11,14 @@ #include "tt_hal_gpio.h" #include "tt_hal_i2c.h" #include "tt_hal_touch.h" +#include "tt_hal_uart.h" #include "tt_kernel.h" +#include #include "tt_lvgl.h" #include "tt_lvgl_keyboard.h" #include "tt_lvgl_spinner.h" #include "tt_lvgl_toolbar.h" #include "tt_message_queue.h" -#include "tt_mutex.h" #include "tt_preferences.h" #include "tt_semaphore.h" #include "tt_thread.h" @@ -31,6 +31,7 @@ #include "symbols/gcc_soft_float.h" #include "symbols/pthread.h" #include "symbols/stl.h" +#include "symbols/cplusplus.h" #include #include @@ -57,6 +58,8 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(rand), ESP_ELFSYM_EXPORT(srand), ESP_ELFSYM_EXPORT(rand_r), + ESP_ELFSYM_EXPORT(atoi), + ESP_ELFSYM_EXPORT(atol), // esp random ESP_ELFSYM_EXPORT(esp_random), ESP_ELFSYM_EXPORT(esp_fill_random), @@ -169,7 +172,8 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(tt_app_get_user_data_child_path), ESP_ELFSYM_EXPORT(tt_app_get_assets_path), ESP_ELFSYM_EXPORT(tt_app_get_assets_child_path), - ESP_ELFSYM_EXPORT(tt_lock_alloc_for_file), + ESP_ELFSYM_EXPORT(tt_lock_alloc_mutex), + ESP_ELFSYM_EXPORT(tt_lock_alloc_for_path), ESP_ELFSYM_EXPORT(tt_lock_acquire), ESP_ELFSYM_EXPORT(tt_lock_release), ESP_ELFSYM_EXPORT(tt_lock_free), @@ -215,6 +219,20 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(tt_hal_touch_driver_alloc), ESP_ELFSYM_EXPORT(tt_hal_touch_driver_free), ESP_ELFSYM_EXPORT(tt_hal_touch_driver_get_touched_points), + ESP_ELFSYM_EXPORT(tt_hal_uart_get_count), + ESP_ELFSYM_EXPORT(tt_hal_uart_get_name), + ESP_ELFSYM_EXPORT(tt_hal_uart_alloc), + ESP_ELFSYM_EXPORT(tt_hal_uart_free), + ESP_ELFSYM_EXPORT(tt_hal_uart_start), + ESP_ELFSYM_EXPORT(tt_hal_uart_is_started), + ESP_ELFSYM_EXPORT(tt_hal_uart_stop), + ESP_ELFSYM_EXPORT(tt_hal_uart_read_bytes), + ESP_ELFSYM_EXPORT(tt_hal_uart_read_byte), + ESP_ELFSYM_EXPORT(tt_hal_uart_write_bytes), + ESP_ELFSYM_EXPORT(tt_hal_uart_available), + ESP_ELFSYM_EXPORT(tt_hal_uart_set_baud_rate), + ESP_ELFSYM_EXPORT(tt_hal_uart_get_baud_rate), + ESP_ELFSYM_EXPORT(tt_hal_uart_flush_input), ESP_ELFSYM_EXPORT(tt_kernel_delay_millis), ESP_ELFSYM_EXPORT(tt_kernel_delay_micros), ESP_ELFSYM_EXPORT(tt_kernel_delay_ticks), @@ -252,10 +270,6 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(tt_message_queue_get_message_size), ESP_ELFSYM_EXPORT(tt_message_queue_get_count), ESP_ELFSYM_EXPORT(tt_message_queue_reset), - ESP_ELFSYM_EXPORT(tt_mutex_alloc), - ESP_ELFSYM_EXPORT(tt_mutex_free), - ESP_ELFSYM_EXPORT(tt_mutex_lock), - ESP_ELFSYM_EXPORT(tt_mutex_unlock), ESP_ELFSYM_EXPORT(tt_preferences_alloc), ESP_ELFSYM_EXPORT(tt_preferences_free), ESP_ELFSYM_EXPORT(tt_preferences_opt_bool), @@ -322,9 +336,12 @@ const esp_elfsym main_symbols[] { // lv_obj ESP_ELFSYM_EXPORT(lv_color_hex), ESP_ELFSYM_EXPORT(lv_color_make), + ESP_ELFSYM_EXPORT(lv_obj_clean), ESP_ELFSYM_EXPORT(lv_obj_create), ESP_ELFSYM_EXPORT(lv_obj_delete), ESP_ELFSYM_EXPORT(lv_obj_add_event_cb), + ESP_ELFSYM_EXPORT(lv_obj_add_flag), + ESP_ELFSYM_EXPORT(lv_obj_add_state), ESP_ELFSYM_EXPORT(lv_obj_align), ESP_ELFSYM_EXPORT(lv_obj_align_to), ESP_ELFSYM_EXPORT(lv_obj_get_parent), @@ -337,11 +354,11 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(lv_obj_get_content_width), ESP_ELFSYM_EXPORT(lv_obj_get_content_height), ESP_ELFSYM_EXPORT(lv_obj_center), - ESP_ELFSYM_EXPORT(lv_obj_remove_event_cb), ESP_ELFSYM_EXPORT(lv_obj_get_user_data), ESP_ELFSYM_EXPORT(lv_obj_set_user_data), + ESP_ELFSYM_EXPORT(lv_obj_remove_event_cb), ESP_ELFSYM_EXPORT(lv_obj_remove_flag), - ESP_ELFSYM_EXPORT(lv_obj_add_flag), + ESP_ELFSYM_EXPORT(lv_obj_remove_state), ESP_ELFSYM_EXPORT(lv_obj_set_pos), ESP_ELFSYM_EXPORT(lv_obj_set_flex_align), ESP_ELFSYM_EXPORT(lv_obj_set_flex_flow), @@ -442,6 +459,9 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(lv_dropdown_get_option_count), ESP_ELFSYM_EXPORT(lv_dropdown_get_option_index), ESP_ELFSYM_EXPORT(lv_dropdown_get_options), + ESP_ELFSYM_EXPORT(lv_dropdown_get_selected), + ESP_ELFSYM_EXPORT(lv_dropdown_get_selected_str), + ESP_ELFSYM_EXPORT(lv_dropdown_get_selected_highlight), ESP_ELFSYM_EXPORT(lv_dropdown_set_dir), ESP_ELFSYM_EXPORT(lv_dropdown_set_options), ESP_ELFSYM_EXPORT(lv_dropdown_set_options_static), @@ -462,6 +482,8 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(lv_textarea_get_label), ESP_ELFSYM_EXPORT(lv_textarea_get_max_length), ESP_ELFSYM_EXPORT(lv_textarea_get_one_line), + ESP_ELFSYM_EXPORT(lv_textarea_get_text), + ESP_ELFSYM_EXPORT(lv_textarea_get_text_selection), ESP_ELFSYM_EXPORT(lv_textarea_set_one_line), ESP_ELFSYM_EXPORT(lv_textarea_set_accepted_chars), ESP_ELFSYM_EXPORT(lv_textarea_set_align), @@ -526,9 +548,10 @@ uintptr_t tt_symbol_resolver(const char* symbolName) { main_symbols, gcc_soft_float_symbols, stl_symbols, + cplusplus_symbols, esp_event_symbols, esp_http_client_symbols, - pthread_symbols + pthread_symbols, }; for (const auto* symbols : all_symbols) { @@ -545,7 +568,7 @@ void tt_init_tactility_c() { elf_set_symbol_resolver(tt_symbol_resolver); } -} +} // extern "C" #else // Simulator diff --git a/TactilityC/Source/tt_lock.cpp b/TactilityC/Source/tt_lock.cpp index 99f3597e..1757b9ff 100644 --- a/TactilityC/Source/tt_lock.cpp +++ b/TactilityC/Source/tt_lock.cpp @@ -1,20 +1,42 @@ #include #include +#include +#include + +#define HANDLE_AS_LOCK(handle) (static_cast(handle)->lock) extern "C" { +LockHandle tt_lock_alloc_mutex(TtMutexType type) { + auto* lock_holder = new LockHolder(); + switch (type) { + case MutexTypeNormal: + lock_holder->lock = std::make_shared(tt::Mutex::Type::Normal); + break; + case MutexTypeRecursive: + lock_holder->lock = std::make_shared(tt::Mutex::Type::Recursive); + break; + default: + tt_crash("Type not supported"); + } + return lock_holder; +} + +LockHandle tt_lock_alloc_for_path(const char* path) { + const auto lock = tt::file::getLock(path); + return new LockHolder(lock); +} + bool tt_lock_acquire(LockHandle handle, TickType timeout) { - auto holder = static_cast(handle); - return holder->lock->lock(timeout); + return HANDLE_AS_LOCK(handle)->lock(timeout); } bool tt_lock_release(LockHandle handle) { - auto holder = static_cast(handle); - return holder->lock->unlock(); + return HANDLE_AS_LOCK(handle)->unlock(); } void tt_lock_free(LockHandle handle) { - auto holder = static_cast(handle); + const auto holder = static_cast(handle); delete holder; } diff --git a/TactilityC/Source/tt_lvgl.cpp b/TactilityC/Source/tt_lvgl.cpp index 2af6a4bf..8557c314 100644 --- a/TactilityC/Source/tt_lvgl.cpp +++ b/TactilityC/Source/tt_lvgl.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -15,8 +16,8 @@ void tt_lvgl_stop() { tt::lvgl::stop(); } -void tt_lvgl_lock() { - tt::lvgl::getSyncLock()->lock(); +void tt_lvgl_lock(TickType timeout) { + tt::lvgl::getSyncLock()->lock(timeout); } void tt_lvgl_unlock() { diff --git a/TactilityC/Source/tt_mutex.cpp b/TactilityC/Source/tt_mutex.cpp deleted file mode 100644 index 6cd2e8c5..00000000 --- a/TactilityC/Source/tt_mutex.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "tt_mutex.h" -#include - -extern "C" { - -#define HANDLE_AS_MUTEX(handle) ((tt::Mutex*)(handle)) - -MutexHandle tt_mutex_alloc(TtMutexType type) { - switch (type) { - case MUTEX_TYPE_NORMAL: - return new tt::Mutex(tt::Mutex::Type::Normal); - case MUTEX_TYPE_RECURSIVE: - return new tt::Mutex(tt::Mutex::Type::Recursive); - default: - tt_crash("Type not supported"); - } -} - -void tt_mutex_free(MutexHandle handle) { - delete HANDLE_AS_MUTEX(handle); -} - -bool tt_mutex_lock(MutexHandle handle, TickType timeout) { - return HANDLE_AS_MUTEX(handle)->lock(timeout); -} - -bool tt_mutex_unlock(MutexHandle handle) { - return HANDLE_AS_MUTEX(handle)->unlock(); -} - -} \ No newline at end of file