diff --git a/Devices/lilygo-tdeck-plus/source/module.cpp b/Devices/lilygo-tdeck-plus/source/module.cpp index 8b3e97a7a..6caf5ef67 100644 --- a/Devices/lilygo-tdeck-plus/source/module.cpp +++ b/Devices/lilygo-tdeck-plus/source/module.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include diff --git a/Devices/lilygo-tlora-pager/source/module.cpp b/Devices/lilygo-tlora-pager/source/module.cpp index b5408b87e..7b4b60683 100644 --- a/Devices/lilygo-tlora-pager/source/module.cpp +++ b/Devices/lilygo-tlora-pager/source/module.cpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include diff --git a/Devices/simulator/Source/Simulator.cpp b/Devices/simulator/Source/Simulator.cpp index 0e44471d3..28ad34b1b 100644 --- a/Devices/simulator/Source/Simulator.cpp +++ b/Devices/simulator/Source/Simulator.cpp @@ -2,7 +2,6 @@ #include "hal/SdlKeyboard.h" #include "hal/SimulatorPower.h" -#include #define TAG "hardware" diff --git a/Firmware/Source/Main.cpp b/Firmware/Source/Main.cpp index 8dfa43506..8c902c8c4 100644 --- a/Firmware/Source/Main.cpp +++ b/Firmware/Source/Main.cpp @@ -1,6 +1,5 @@ #include -#include #include #ifdef ESP_PLATFORM @@ -9,30 +8,15 @@ #include #endif -#ifdef CONFIG_TT_USE_DEPRECATED_HAL -// Each board project declares this variable -extern const tt::hal::Configuration hardwareConfiguration; -#else -// Legacy placeholder (required until legacy HAL is cleaned up everywhere) -extern const tt::hal::Configuration hardwareConfiguration = {}; -#endif - extern "C" { void app_main() { - static const tt::Configuration config = { - /** - * Auto-select a board based on the ./sdkconfig.board.* file - * that you copied to ./sdkconfig before you opened this project. - */ - .hardware = &hardwareConfiguration - }; #ifdef ESP_PLATFORM tt_init_tactility_c(); // ELF bindings for side-loading on ESP32 #endif - tt::run(config, dts_modules, dts_devices); + tt::run(dts_modules, dts_devices); } } // extern \ No newline at end of file diff --git a/Tactility/Include/Tactility/Tactility.h b/Tactility/Include/Tactility/Tactility.h index 7078cb943..0e1b55b19 100644 --- a/Tactility/Include/Tactility/Tactility.h +++ b/Tactility/Include/Tactility/Tactility.h @@ -1,11 +1,9 @@ #pragma once -#include "tactility/concurrent/dispatcher.h" -#include "tactility/device.h" -#include "tactility/module.h" +#include +#include +#include #include -#include -#include #include @@ -40,27 +38,12 @@ private: DispatcherHandle_t handle; }; -/** @brief The configuration for the operating system - * It contains the hardware configuration, apps and services - */ -struct Configuration { - /** HAL configuration (drivers) */ - const hal::Configuration* hardware = nullptr; -}; - /** * @brief Main entry point for Tactility. * @param dtsModules List of modules from devicetree, null-terminated, non-null parameter * @param dtsDevices Array that is terminated with DTS_DEVICE_TERMINATOR */ -void run(const Configuration& config, Module* dtsModules[], DtsDevice dtsDevices[]); - -/** - * While technically nullable, this instance is always set if tt_init() succeeds. - * Could return nullptr if init was not called. - * @return the Configuration instance that was passed on to tt_init() if init is successful - */ -const Configuration* getConfiguration(); +void run(Module* dtsModules[], DtsDevice dtsDevices[]); /** Provides access to the dispatcher that runs on the main task. * @warning This dispatcher is used for WiFi and might block for some time during WiFi connection. @@ -68,11 +51,4 @@ const Configuration* getConfiguration(); */ MainDispatcher getMainDispatcher(); -namespace hal { - -/** While technically this configuration is nullable, it's never null after initHeadless() is called. */ -const Configuration* getConfiguration(); - -} // namespace hal - } // namespace tt diff --git a/Tactility/Include/Tactility/hal/Configuration.h b/Tactility/Include/Tactility/hal/Configuration.h deleted file mode 100644 index 8b085bb2e..000000000 --- a/Tactility/Include/Tactility/hal/Configuration.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace tt::hal { - -typedef bool (*InitBoot)(); - -typedef std::vector> DeviceVector; - -typedef std::shared_ptr (*CreateDevice)(); - -struct Configuration { - /** - * Used for powering on the peripherals manually. - */ - const InitBoot initBoot = nullptr; - - const std::function createDevices = [] { return DeviceVector(); }; -}; - -} // namespace diff --git a/Tactility/Include/Tactility/hal/display/DisplayDevice.h b/Tactility/Include/Tactility/hal/display/DisplayDevice.h deleted file mode 100644 index 7918bfb7e..000000000 --- a/Tactility/Include/Tactility/hal/display/DisplayDevice.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include - -#include - -namespace tt::hal::touch { -class TouchDevice; -} - -namespace tt::hal::display { - -class DisplayDriver; - -class DisplayDevice : public Device { - -public: - - Type getType() const override { return Type::Display; } - - /** Starts the internal driver */ - virtual bool start() = 0; - virtual bool stop() = 0; - - virtual void setPowerOn(bool turnOn) {} - virtual bool isPoweredOn() const { return true; } - virtual bool supportsPowerControl() const { return false; } - - /** For e-paper screens */ - virtual void requestFullRefresh() {} - - /** Blocks until any frame already handed to this display has physically - * finished drawing. Displays that draw synchronously within their flush - * callback can rely on the default no-op; displays with an asynchronous - * refresh pipeline (e.g. e-paper, where a full refresh can take seconds) - * should override this so callers can safely do something irreversible - * (like cutting power) right after a screen update. */ - virtual void waitForFlushComplete() {} - - /** Could return nullptr if not started */ - virtual std::shared_ptr getTouchDevice() = 0; - - /** Set a value in the range [0, 255] */ - virtual void setBacklightDuty(uint8_t backlightDuty) { /* NO-OP */ } - virtual bool supportsBacklightDuty() const { return false; } - - /** Set a value in the range [0, 255] */ - virtual void setGammaCurve(uint8_t index) { /* NO-OP */ } - virtual uint8_t getGammaCurveCount() const { return 0; } - - virtual bool supportsLvgl() const = 0; - virtual bool startLvgl() = 0; - virtual bool stopLvgl() = 0; - - /** Could return nullptr if not started */ - virtual lv_display_t* getLvglDisplay() const = 0; - - virtual bool supportsDisplayDriver() const = 0; - /** Could return nullptr if not supported */ - virtual std::shared_ptr getDisplayDriver() = 0; -}; - -} // namespace tt::hal::display diff --git a/Tactility/Include/Tactility/hal/display/DisplayDriver.h b/Tactility/Include/Tactility/hal/display/DisplayDriver.h deleted file mode 100644 index 16cafae38..000000000 --- a/Tactility/Include/Tactility/hal/display/DisplayDriver.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -namespace tt::hal::display { - -enum class ColorFormat { - Monochrome, // 1 bpp - BGR565, - BGR565Swapped, - RGB565, - RGB565Swapped, - RGB888 -}; - -class DisplayDriver { - -public: - - virtual ~DisplayDriver() = default; - - virtual ColorFormat getColorFormat() const = 0; - virtual uint16_t getPixelWidth() const = 0; - virtual uint16_t getPixelHeight() const = 0; - virtual bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) = 0; - - /** - * Returns direct pointers to the panel's hardware frame buffer(s), if the - * underlying driver supports it (DPI/MIPI-DSI panels only). - * @param[out] outBuffers receives up to 2 frame buffer pointers - * @return number of buffers written to outBuffers (0 if unsupported) - */ - virtual uint8_t getFrameBuffers(void* outBuffers[2]) const { return 0; } -}; - -} \ No newline at end of file diff --git a/Tactility/Include/Tactility/hal/display/KernelDisplayDriver.h b/Tactility/Include/Tactility/hal/display/KernelDisplayDriver.h deleted file mode 100644 index 757653690..000000000 --- a/Tactility/Include/Tactility/hal/display/KernelDisplayDriver.h +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#pragma once - -#include - -#include - -namespace tt::hal::display { - -/** Wraps a TactilityKernel Device of type DISPLAY_TYPE as a DisplayDriver. */ -class KernelDisplayDriver final : public DisplayDriver { - - ::Device* device; - -public: - - explicit KernelDisplayDriver(::Device* device); - - ColorFormat getColorFormat() const override; - uint16_t getPixelWidth() const override; - uint16_t getPixelHeight() const override; - bool drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) override; - uint8_t getFrameBuffers(void* outBuffers[2]) const override; -}; - -} diff --git a/Tactility/Include/Tactility/hal/encoder/EncoderDevice.h b/Tactility/Include/Tactility/hal/encoder/EncoderDevice.h deleted file mode 100644 index 7880c45a4..000000000 --- a/Tactility/Include/Tactility/hal/encoder/EncoderDevice.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -#include - -namespace tt::hal::encoder { - -class Display; - -class EncoderDevice : public Device { - -public: - - Type getType() const override { return Type::Encoder; } - - virtual bool startLvgl(lv_display_t* display) = 0; - virtual bool stopLvgl() = 0; - - /** Could return nullptr if not started */ - virtual lv_indev_t* getLvglIndev() = 0; -}; - -} diff --git a/Tactility/Include/Tactility/hal/gpio/Gpio.h b/Tactility/Include/Tactility/hal/gpio/Gpio.h deleted file mode 100644 index 8ef6f2a05..000000000 --- a/Tactility/Include/Tactility/hal/gpio/Gpio.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include - -namespace tt::hal::gpio { - -typedef unsigned int Pin; -constexpr Pin NO_PIN = -1; - -/** @warning The order must match GpioMode from tt_hal_gpio.h */ -enum class Mode { - Disable = 0, - Input, - Output, - OutputOpenDrain, - InputOutput, - InputOutputOpenDrain -}; - -/** Configure a single pin */ -bool configure(Pin pin, Mode mode, bool pullUp, bool pullDown); - -/** Configure a set of pins defined by their bit index */ -bool configureWithPinBitmask(uint64_t pinBitMask, Mode mode, bool pullUp, bool pullDown); - -bool setMode(Pin pin, Mode mode); - -bool getLevel(Pin pin); - -bool setLevel(Pin pin, bool level); - -int getPinCount(); - -} diff --git a/Tactility/Include/Tactility/hal/gps/GpsDevice.h b/Tactility/Include/Tactility/hal/gps/GpsDevice.h index c9355e933..4c9a08823 100644 --- a/Tactility/Include/Tactility/hal/gps/GpsDevice.h +++ b/Tactility/Include/Tactility/hal/gps/GpsDevice.h @@ -46,7 +46,10 @@ private: std::shared_ptr> onData; }; - const GpsConfiguration configuration; + ::Device* uartDevice; + uint32_t baudRate; + GpsModel model; + RecursiveMutex mutex; std::unique_ptr thread; bool threadInterrupted = false; @@ -54,7 +57,6 @@ private: std::vector rmcSubscriptions; GgaSubscriptionId lastSatelliteSubscriptionId = 0; RmcSubscriptionId lastRmcSubscriptionId = 0; - GpsModel model = GpsModel::Unknown; State state = State::Off; int32_t threadMain(); @@ -65,9 +67,18 @@ private: public: - explicit GpsDevice(GpsConfiguration configuration) : configuration(std::move(configuration)) {} + explicit GpsDevice( + ::Device* uartDevice, + uint32_t baudRate, + GpsModel model // Choosing "Unknown" will result in a probe + ) : uartDevice(uartDevice), baudRate(baudRate), model(model) { + assert(uartDevice != nullptr); + device_get(uartDevice); + }; - ~GpsDevice() override = default; + ~GpsDevice() override { + device_put(uartDevice); + } Type getType() const override { return Type::Gps; } diff --git a/Tactility/Include/Tactility/hal/i2c/I2cDevice.h b/Tactility/Include/Tactility/hal/i2c/I2cDevice.h deleted file mode 100644 index 97ad0249e..000000000 --- a/Tactility/Include/Tactility/hal/i2c/I2cDevice.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include - -namespace tt::hal::i2c { - -/** - * Represents an I2C peripheral at a specific port and address. - * It helps to read and write registers. - * - * All read and write calls are thread-safe. - * @deprecated Use the device API from the Kernel project - */ -class I2cDevice : public Device { - -protected: - - ::Device* controller; - uint8_t address; - - static constexpr TickType_t DEFAULT_TIMEOUT = 1000 / portTICK_PERIOD_MS; - - bool read(uint8_t* data, size_t dataSize, TickType_t timeout = DEFAULT_TIMEOUT); - bool write(const uint8_t* data, uint16_t dataSize, TickType_t timeout = DEFAULT_TIMEOUT); - bool writeRead(const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout = DEFAULT_TIMEOUT); - bool readRegister8(uint8_t reg, uint8_t& result) const; - bool writeRegister(uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout = DEFAULT_TIMEOUT); - bool writeRegister8(uint8_t reg, uint8_t value) const; - bool readRegister12(uint8_t reg, float& out) const; - bool readRegister14(uint8_t reg, float& out) const; - bool readRegister16(uint8_t reg, uint16_t& out) const; - bool bitOn(uint8_t reg, uint8_t bitmask) const; - bool bitOff(uint8_t reg, uint8_t bitmask) const; - bool bitOnByIndex(uint8_t reg, uint8_t index) const { return bitOn(reg, 1 << index); } - bool bitOffByIndex(uint8_t reg, uint8_t index) const { return bitOff(reg, 1 << index); } - -public: - - explicit I2cDevice(::Device* controller, uint32_t address) : controller(controller), address(address) {} - - Type getType() const override { return Type::I2c; } - - ::Device* getController() const { return controller; } - - uint8_t getAddress() const { return address; } -}; - -} // namespace tt::hal::i2c diff --git a/Tactility/Include/Tactility/hal/keyboard/KeyboardDevice.h b/Tactility/Include/Tactility/hal/keyboard/KeyboardDevice.h deleted file mode 100644 index 7c996569a..000000000 --- a/Tactility/Include/Tactility/hal/keyboard/KeyboardDevice.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -#include - -namespace tt::hal::keyboard { - -class Display; - -class KeyboardDevice : public Device { - -public: - - Type getType() const override { return Type::Keyboard; } - - virtual bool startLvgl(lv_display_t* display) = 0; - virtual bool stopLvgl() = 0; - - /** @return true when the keyboard currently is physically attached */ - virtual bool isAttached() const = 0; - - /** Could return nullptr if not started */ - virtual lv_indev_t* getLvglIndev() = 0; -}; - -} diff --git a/Tactility/Include/Tactility/hal/power/PowerDevice.h b/Tactility/Include/Tactility/hal/power/PowerDevice.h deleted file mode 100644 index 04173422b..000000000 --- a/Tactility/Include/Tactility/hal/power/PowerDevice.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace tt::hal::power { - -class PowerDevice : public Device { - -public: - - PowerDevice(); - ~PowerDevice() override; - - Type getType() const override { return Type::Power; } - - enum class MetricType { - IsCharging, // bool - Current, // int32_t, mAh - battery current: either during charging (positive value) or discharging (negative value) - BatteryVoltage, // uint32_t, mV - ChargeLevel, // uint8_t [0, 100] - }; - - union MetricData { - int32_t valueAsInt32 = 0; - uint32_t valueAsUint32; - uint8_t valueAsUint8; - float valueAsFloat; - bool valueAsBool; - }; - - virtual bool supportsMetric(MetricType type) const = 0; - - /** - * @return false when metric is not supported or (temporarily) not available. - */ - virtual bool getMetric(MetricType type, MetricData& data) = 0; - - virtual bool supportsChargeControl() const { return false; } - virtual bool isAllowedToCharge() const { return false; } - virtual void setAllowedToCharge(bool canCharge) { /* NO-OP*/ } - - virtual bool supportsQuickCharge() const { return false; } - virtual bool isQuickChargeEnabled() const { return false; } - virtual void setQuickChargeEnabled(bool enabled) { /* NO-OP */ } - - virtual bool supportsPowerOff() const { return false; } - virtual void powerOff() { /* NO-OP*/ } - -private: - - /** Creates the kernel-level power_supply device that exposes this instance to TactilityKernel. */ - void createPowerSupplyDevice(); - - /** Destroys the kernel-level power_supply device created by createPowerSupplyDevice(). */ - void destroyPowerSupplyDevice(); - - std::string kernelDeviceName; - KernelDevice kernelDevice {}; -}; - -} diff --git a/Tactility/Include/Tactility/hal/touch/KernelTouchDriver.h b/Tactility/Include/Tactility/hal/touch/KernelTouchDriver.h deleted file mode 100644 index 30ff49e2e..000000000 --- a/Tactility/Include/Tactility/hal/touch/KernelTouchDriver.h +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#pragma once - -#include - -#include - -namespace tt::hal::touch { - -/** Wraps a TactilityKernel Device of type POINTER_TYPE as a TouchDriver. */ -class KernelTouchDriver final : public TouchDriver { - - ::Device* device; - -public: - - explicit KernelTouchDriver(::Device* device); - - bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) override; -}; - -} diff --git a/Tactility/Include/Tactility/hal/touch/TouchDevice.h b/Tactility/Include/Tactility/hal/touch/TouchDevice.h deleted file mode 100644 index 1206ca1ba..000000000 --- a/Tactility/Include/Tactility/hal/touch/TouchDevice.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include "TouchDriver.h" - -#include - -namespace tt::hal::touch { - -class Display; - -class TouchDevice : public Device { - -public: - - Type getType() const override { return Type::Touch; } - - virtual bool start() = 0; - virtual bool stop() = 0; - - virtual bool supportsLvgl() const = 0; - virtual bool startLvgl(lv_display_t* display) = 0; - virtual bool stopLvgl() = 0; - - /** Could return nullptr if not started */ - virtual lv_indev_t* getLvglIndev() = 0; - - virtual bool supportsTouchDriver() = 0; - - virtual bool supportsCalibration() const { return false; } - - /** Could return nullptr if not supported */ - virtual std::shared_ptr getTouchDriver() = 0; -}; - -} diff --git a/Tactility/Include/Tactility/hal/touch/TouchDriver.h b/Tactility/Include/Tactility/hal/touch/TouchDriver.h deleted file mode 100644 index 58aa2515f..000000000 --- a/Tactility/Include/Tactility/hal/touch/TouchDriver.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -namespace tt::hal::touch { - -class TouchDriver { - -public: - - /** - * Get the coordinates for the currently touched points on the screen. - * - * @param[in] x array of X coordinates - * @param[in] y array of Y coordinates - * @param[in] strength optional array of strengths (nullable) - * @param[in] pointCount the number of points currently touched on the screen - * @param[in] maxPointCount the maximum number of points that can be touched at once - * - * @return true when touched and coordinates are available - */ - virtual bool getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) = 0; -}; - -} diff --git a/Tactility/Private/Tactility/hal/HalPrivate.h b/Tactility/Private/Tactility/hal/HalPrivate.h deleted file mode 100644 index 3e4712886..000000000 --- a/Tactility/Private/Tactility/hal/HalPrivate.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "Tactility/hal/Configuration.h" - -namespace tt::hal { - -void init(const Configuration& configuration); - -} // namespace diff --git a/Tactility/Private/Tactility/lvgl/LvglPrivate.h b/Tactility/Private/Tactility/lvgl/LvglPrivate.h deleted file mode 100644 index 0567d1681..000000000 --- a/Tactility/Private/Tactility/lvgl/LvglPrivate.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -namespace tt::lvgl { - -void attachDevices(); - -void detachDevices(); - -} diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index 83517aff6..31050c1d4 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -41,6 +39,8 @@ #endif #include "Tactility/Paths.h" +#include "Tactility/SystemEvents.h" +#include "Tactility/hal/SdCard.h" #include @@ -49,7 +49,6 @@ namespace tt { constexpr auto* TAG = "Tactility"; -static const Configuration* config_instance = nullptr; static DispatcherHandle_t mainDispatcherHandle = dispatcher_alloc(); namespace { @@ -183,8 +182,6 @@ static void registerInternalApps() { } if (device_exists_of_type(&DISPLAY_TYPE)) { addAppManifest(app::kerneldisplay::manifest); - } else if (hal::hasDevice(hal::Device::Type::Display)) { - addAppManifest(app::display::manifest); } addAppManifest(app::files::manifest); addAppManifest(app::fileselection::manifest); @@ -366,11 +363,9 @@ void registerApps() { registerInstalledAppsFromFileSystems(); } -void run(const Configuration& config, Module* dtsModules[], DtsDevice dtsDevices[]) { +void run(Module* dtsModules[], DtsDevice dtsDevices[]) { LOG_I(TAG, "Tactility v%s on %s (%s)", TT_VERSION, CONFIG_TT_DEVICE_NAME, CONFIG_TT_DEVICE_ID); - assert(config.hardware); - LOG_I(TAG, "Initializing kernel"); if (kernel_init(dtsModules, dtsDevices) != ERROR_NONE) { LOG_E(TAG, "Failed to initialize kernel"); @@ -383,23 +378,25 @@ void run(const Configuration& config, Module* dtsModules[], DtsDevice dtsDevices // crypt-module check(module_construct_add_start(&crypt_module) == ERROR_NONE); - // Assign early so starting services can use it - config_instance = &config; - #ifdef ESP_PLATFORM initEsp(); #endif file::setFindLockFunction(file::findLock); settings::initTimeZone(); - hal::init(*config.hardware); + + // Remnants of the old HAL + kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalBegin); + hal::sdcard::mountAll(); + kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalEnd); + network::ntp::init(); bluetooth::systemStart(); registerAndStartPrimaryServices(); lvgl_module_configure((LvglModuleConfig) { - .on_start = lvgl::attachDevices, - .on_stop = lvgl::detachDevices, + .on_start = nullptr, + .on_stop = nullptr, .task_priority = THREAD_PRIORITY_HIGHER, /** Minimum seems to be about 3500. In some scenarios, the WiFi app crashes at 8192, * so we now have 9120 to run in a stable manner. We should figure out a way to avoid this. @@ -411,7 +408,7 @@ void run(const Configuration& config, Module* dtsModules[], DtsDevice dtsDevices }); check(module_construct(&lvgl_module) == ERROR_NONE); check(module_add(&lvgl_module) == ERROR_NONE); - lvgl::start(); + module_start(&lvgl_module); registerAndStartSecondaryServices(); @@ -428,11 +425,6 @@ void run(const Configuration& config, Module* dtsModules[], DtsDevice dtsDevices } } -/** return the configuration or nullptr if it's not initialized */ -const Configuration* getConfiguration() { - return config_instance; -} - MainDispatcher getMainDispatcher() { return MainDispatcher(mainDispatcherHandle); } diff --git a/Tactility/Source/app/boot/Boot.cpp b/Tactility/Source/app/boot/Boot.cpp index 0838c6803..c7612b147 100644 --- a/Tactility/Source/app/boot/Boot.cpp +++ b/Tactility/Source/app/boot/Boot.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -36,10 +35,6 @@ constexpr auto* TAG = "Boot"; extern const AppManifest manifest; -static std::shared_ptr getHalDisplay() { - return hal::findFirstDevice(hal::Device::Type::Display); -} - class BootApp : public App { // Snapshot of hal::usb::isUsbBootMode(), taken before the boot thread starts and @@ -58,31 +53,7 @@ class BootApp : public App { getCpuAffinityConfiguration().system ); - static void setupHalDisplay() { - const auto hal_display = getHalDisplay(); - if (hal_display == nullptr) { - return; - } - - settings::display::DisplaySettings settings; - if (settings::display::load(settings)) { - if (hal_display->getGammaCurveCount() > 0) { - hal_display->setGammaCurve(settings.gammaCurve); - LOG_I(TAG, "Gamma curve %d", settings.gammaCurve); - } - } else { - settings = settings::display::getDefault(); - } - - if (hal_display->supportsBacklightDuty()) { - LOG_I(TAG, "Backlight %d", settings.backlightDuty); - hal_display->setBacklightDuty(settings.backlightDuty); - } else { - LOG_I(TAG, "No backlight"); - } - } - - static void setupKernelDisplay() { + static void setupDisplay() { auto* display = device_find_first_by_type(&DISPLAY_TYPE); // Boards not yet migrated to the kernel display driver register a placeholder device (so // the devicetree node resolves) with a NULL api - nothing for this function to act on. @@ -161,8 +132,8 @@ class BootApp : public App { // TODO: Support for multiple displays LOG_I(TAG, "Setup display"); - setupHalDisplay(); - setupKernelDisplay(); + setupDisplay(); + LOG_I(TAG, "Prepare file systems"); prepareFileSystems(); #ifdef CONFIG_TT_USER_DATA_LOCATION_SD diff --git a/Tactility/Source/app/development/Development.cpp b/Tactility/Source/app/development/Development.cpp index b96241bba..7179b6ae2 100644 --- a/Tactility/Source/app/development/Development.cpp +++ b/Tactility/Source/app/development/Development.cpp @@ -1,9 +1,8 @@ #ifdef ESP_PLATFORM -#include #include +#include #include -#include #include #include #include @@ -14,6 +13,7 @@ #include #include +#include #include #include @@ -33,7 +33,7 @@ class DevelopmentApp final : public App { Timer timer = Timer(Timer::Type::Periodic, pdMS_TO_TICKS(1000), [this] { auto lock = lvgl::getSyncLock()->asScopedLock(); // TODO: There's a crash when this is called when the app is being destroyed - if (lock.lock(lvgl::defaultLockTime) && lvgl::isStarted()) { + if (lock.lock(lvgl::defaultLockTime) && module_is_started(&lvgl_module)) { updateViewState(); } }); diff --git a/Tactility/Source/app/display/Display.cpp b/Tactility/Source/app/display/Display.cpp deleted file mode 100644 index 5697a8509..000000000 --- a/Tactility/Source/app/display/Display.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include - -#include - -#ifdef ESP_PLATFORM -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include - -namespace tt::app::display { - -constexpr auto* TAG = "Display"; - -static std::shared_ptr getHalDisplay() { - return hal::findFirstDevice(hal::Device::Type::Display); -} - -class HalDisplayApp final : public App { - - settings::display::DisplaySettings displaySettings; - bool displaySettingsUpdated = false; - lv_obj_t* timeoutSwitch = nullptr; - lv_obj_t* timeoutDropdown = nullptr; - lv_obj_t* screensaverDropdown = nullptr; - - static void onBacklightSliderEvent(lv_event_t* event) { - auto* slider = static_cast(lv_event_get_target(event)); - auto* app = static_cast(lv_event_get_user_data(event)); - auto hal_display = getHalDisplay(); - assert(hal_display != nullptr); - - if (hal_display->supportsBacklightDuty()) { - int32_t slider_value = lv_slider_get_value(slider); - app->displaySettings.backlightDuty = static_cast(slider_value); - app->displaySettingsUpdated = true; - hal_display->setBacklightDuty(app->displaySettings.backlightDuty); - } - } - - static void onGammaSliderEvent(lv_event_t* event) { - auto* slider = static_cast(lv_event_get_target(event)); - auto hal_display = hal::findFirstDevice(hal::Device::Type::Display); - auto* app = static_cast(lv_event_get_user_data(event)); - assert(hal_display != nullptr); - - if (hal_display->getGammaCurveCount() > 0) { - int32_t slider_value = lv_slider_get_value(slider); - app->displaySettings.gammaCurve = static_cast(slider_value); - app->displaySettingsUpdated = true; - hal_display->setGammaCurve(app->displaySettings.gammaCurve); - } - } - - static void onOrientationSet(lv_event_t* event) { - auto* app = static_cast(lv_event_get_user_data(event)); - auto* dropdown = static_cast(lv_event_get_target(event)); - uint32_t selected_index = lv_dropdown_get_selected(dropdown); - LOG_I(TAG, "Selected %u", (unsigned)selected_index); - auto selected_orientation = static_cast(selected_index); - if (selected_orientation != app->displaySettings.orientation) { - app->displaySettings.orientation = selected_orientation; - app->displaySettingsUpdated = true; - lv_display_set_rotation(lv_display_get_default(), settings::display::toLvglDisplayRotation(selected_orientation)); - } - } - - static void onTimeoutSwitch(lv_event_t* event) { - auto* app = static_cast(lv_event_get_user_data(event)); - auto* sw = static_cast(lv_event_get_target(event)); - bool enabled = lv_obj_has_state(sw, LV_STATE_CHECKED); - app->displaySettings.backlightTimeoutEnabled = enabled; - app->displaySettingsUpdated = true; - if (app->timeoutDropdown) { - if (enabled) { - lv_obj_clear_state(app->timeoutDropdown, LV_STATE_DISABLED); - if (app->screensaverDropdown) { - lv_obj_clear_state(app->screensaverDropdown, LV_STATE_DISABLED); - } - } else { - lv_obj_add_state(app->timeoutDropdown, LV_STATE_DISABLED); - if (app->screensaverDropdown) { - lv_obj_add_state(app->screensaverDropdown, LV_STATE_DISABLED); - } - } - } - } - - static void onTimeoutChanged(lv_event_t* event) { - auto* app = static_cast(lv_event_get_user_data(event)); - auto* dropdown = static_cast(lv_event_get_target(event)); - uint32_t idx = lv_dropdown_get_selected(dropdown); - // Map dropdown index to ms: 0=15s,1=30s,2=1m,3=2m,4=5m,5=Never - static const uint32_t values_ms[] = {15000, 30000, 60000, 120000, 300000, 0}; - if (idx < (sizeof(values_ms)/sizeof(values_ms[0]))) { - app->displaySettings.backlightTimeoutMs = values_ms[idx]; - app->displaySettingsUpdated = true; - } - } - - static void onScreensaverChanged(lv_event_t* event) { - auto* app = static_cast(lv_event_get_user_data(event)); - auto* dropdown = static_cast(lv_event_get_target(event)); - uint32_t idx = lv_dropdown_get_selected(dropdown); - // Validate index bounds before casting to enum - if (idx >= static_cast(settings::display::ScreensaverType::Count)) { - return; - } - auto selected_type = static_cast(idx); - if (selected_type != app->displaySettings.screensaverType) { - app->displaySettings.screensaverType = selected_type; - app->displaySettingsUpdated = true; - } - } - -public: - - void onShow(AppContext& app, lv_obj_t* parent) override { - displaySettings = settings::display::loadOrGetDefault(); - auto ui_density = lvgl_get_ui_density(); - - lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); - lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); - - auto hal_display = getHalDisplay(); - assert(hal_display != nullptr); - - lvgl::toolbar_create(parent, app); - - auto* main_wrapper = lv_obj_create(parent); - lv_obj_set_flex_flow(main_wrapper, LV_FLEX_FLOW_COLUMN); - lv_obj_set_width(main_wrapper, LV_PCT(100)); - lv_obj_set_flex_grow(main_wrapper, 1); - - // Backlight slider - - if (hal_display->supportsBacklightDuty()) { - auto* brightness_wrapper = lv_obj_create(main_wrapper); - lv_obj_set_size(brightness_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_hor(brightness_wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_border_width(brightness_wrapper, 0, LV_STATE_DEFAULT); - if (ui_density != LVGL_UI_DENSITY_COMPACT) { - lv_obj_set_style_pad_ver(brightness_wrapper, 4, LV_STATE_DEFAULT); - } - - auto* brightness_label = lv_label_create(brightness_wrapper); - lv_label_set_text(brightness_label, "Brightness"); - lv_obj_align(brightness_label, LV_ALIGN_LEFT_MID, 0, 0); - - auto* brightness_slider = lv_slider_create(brightness_wrapper); - lv_obj_set_width(brightness_slider, LV_PCT(50)); - lv_obj_align(brightness_slider, LV_ALIGN_RIGHT_MID, 0, 0); - lv_slider_set_range(brightness_slider, 0, 255); - lv_obj_add_event_cb(brightness_slider, onBacklightSliderEvent, LV_EVENT_VALUE_CHANGED, this); - - lv_slider_set_value(brightness_slider, displaySettings.backlightDuty, LV_ANIM_OFF); - } - - // Gamma slider - - if (hal_display->getGammaCurveCount() > 0) { - auto* gamma_wrapper = lv_obj_create(main_wrapper); - lv_obj_set_size(gamma_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_hor(gamma_wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_border_width(gamma_wrapper, 0, LV_STATE_DEFAULT); - if (ui_density != LVGL_UI_DENSITY_COMPACT) { - lv_obj_set_style_pad_ver(gamma_wrapper, 4, LV_STATE_DEFAULT); - } - - auto* gamma_label = lv_label_create(gamma_wrapper); - lv_label_set_text(gamma_label, "Gamma"); - lv_obj_align(gamma_label, LV_ALIGN_LEFT_MID, 0, 0); - lv_obj_set_y(gamma_label, 0); - - auto* gamma_slider = lv_slider_create(gamma_wrapper); - lv_obj_set_width(gamma_slider, LV_PCT(50)); - lv_obj_align(gamma_slider, LV_ALIGN_RIGHT_MID, 0, 0); - lv_slider_set_range(gamma_slider, 0, hal_display->getGammaCurveCount()); - lv_obj_add_event_cb(gamma_slider, onGammaSliderEvent, LV_EVENT_VALUE_CHANGED, this); - - uint8_t curve_index = displaySettings.gammaCurve; - lv_slider_set_value(gamma_slider, curve_index, LV_ANIM_OFF); - } - - // Orientation - - auto* orientation_wrapper = lv_obj_create(main_wrapper); - lv_obj_set_size(orientation_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(orientation_wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_border_width(orientation_wrapper, 0, LV_STATE_DEFAULT); - - auto* orientation_label = lv_label_create(orientation_wrapper); - lv_label_set_text(orientation_label, "Orientation"); - lv_obj_align(orientation_label, LV_ALIGN_LEFT_MID, 0, 0); - - auto* orientation_dropdown = lv_dropdown_create(orientation_wrapper); - // Note: order correlates with settings::display::Orientation item order - lv_dropdown_set_options(orientation_dropdown, "Landscape\nPortrait Right\nLandscape Flipped\nPortrait Left"); - lv_obj_align(orientation_dropdown, LV_ALIGN_RIGHT_MID, 0, 0); - lv_obj_add_event_cb(orientation_dropdown, onOrientationSet, LV_EVENT_VALUE_CHANGED, this); - // Set the dropdown to match current orientation enum - lv_dropdown_set_selected(orientation_dropdown, static_cast(displaySettings.orientation)); - - // Screen timeout - - if (hal_display->supportsBacklightDuty()) { - auto* timeout_wrapper = lv_obj_create(main_wrapper); - lv_obj_set_size(timeout_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(timeout_wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_border_width(timeout_wrapper, 0, LV_STATE_DEFAULT); - - auto* timeout_label = lv_label_create(timeout_wrapper); - lv_label_set_text(timeout_label, "Auto screen off"); - lv_obj_align(timeout_label, LV_ALIGN_LEFT_MID, 0, 0); - - timeoutSwitch = lv_switch_create(timeout_wrapper); - if (displaySettings.backlightTimeoutEnabled) { - lv_obj_add_state(timeoutSwitch, LV_STATE_CHECKED); - } - lv_obj_align(timeoutSwitch, LV_ALIGN_RIGHT_MID, 0, 0); - lv_obj_add_event_cb(timeoutSwitch, onTimeoutSwitch, LV_EVENT_VALUE_CHANGED, this); - - auto* timeout_select_wrapper = lv_obj_create(main_wrapper); - lv_obj_set_size(timeout_select_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(timeout_select_wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_border_width(timeout_select_wrapper, 0, LV_STATE_DEFAULT); - - auto* timeout_value_label = lv_label_create(timeout_select_wrapper); - lv_label_set_text(timeout_value_label, "Timeout"); - lv_obj_align(timeout_value_label, LV_ALIGN_LEFT_MID, 0, 0); - - timeoutDropdown = lv_dropdown_create(timeout_select_wrapper); - lv_dropdown_set_options(timeoutDropdown, "15 seconds\n30 seconds\n1 minute\n2 minutes\n5 minutes\nNever"); - lv_obj_align(timeoutDropdown, LV_ALIGN_RIGHT_MID, 0, 0); - lv_obj_add_event_cb(timeoutDropdown, onTimeoutChanged, LV_EVENT_VALUE_CHANGED, this); - // Initialize dropdown selection from settings - uint32_t ms = displaySettings.backlightTimeoutMs; - uint32_t idx = 2; // default 1 minute - if (ms == 15000) idx = 0; - else if (ms == 30000) - idx = 1; - else if (ms == 60000) - idx = 2; - else if (ms == 120000) - idx = 3; - else if (ms == 300000) - idx = 4; - else if (ms == 0) - idx = 5; - lv_dropdown_set_selected(timeoutDropdown, idx); - if (!displaySettings.backlightTimeoutEnabled) { - lv_obj_add_state(timeoutDropdown, LV_STATE_DISABLED); - } - - // Screensaver type - auto* screensaver_wrapper = lv_obj_create(main_wrapper); - lv_obj_set_size(screensaver_wrapper, LV_PCT(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(screensaver_wrapper, 0, LV_STATE_DEFAULT); - lv_obj_set_style_border_width(screensaver_wrapper, 0, LV_STATE_DEFAULT); - - auto* screensaver_label = lv_label_create(screensaver_wrapper); - lv_label_set_text(screensaver_label, "Screensaver"); - lv_obj_align(screensaver_label, LV_ALIGN_LEFT_MID, 0, 0); - - screensaverDropdown = lv_dropdown_create(screensaver_wrapper); - // Note: order correlates with settings::display::ScreensaverType enum order - lv_dropdown_set_options(screensaverDropdown, "None\nBouncing Balls\nMystify\nMatrix Rain\nStackChan"); - lv_obj_align(screensaverDropdown, LV_ALIGN_RIGHT_MID, 0, 0); - lv_obj_add_event_cb(screensaverDropdown, onScreensaverChanged, LV_EVENT_VALUE_CHANGED, this); - lv_dropdown_set_selected(screensaverDropdown, static_cast(displaySettings.screensaverType)); - if (!displaySettings.backlightTimeoutEnabled) { - lv_obj_add_state(screensaverDropdown, LV_STATE_DISABLED); - } - } - } - - void onHide(AppContext& app) override { - if (displaySettingsUpdated) { - // Dispatch it, so file IO doesn't block the UI - const settings::display::DisplaySettings settings_to_save = displaySettings; - getMainDispatcher().dispatch([settings_to_save] { - settings::display::save(settings_to_save); -#ifdef ESP_PLATFORM - // Notify DisplayIdle service to reload settings - auto displayIdle = service::displayidle::findService(); - if (displayIdle) { - displayIdle->reloadSettings(); - } -#endif - }); - } - } -}; - -extern const AppManifest manifest = { - .appId = "Display", - .appName = "Display", - .appIcon = LVGL_ICON_SHARED_DISPLAY_SETTINGS, - .appCategory = Category::Settings, - .createApp = create -}; - -} // namespace diff --git a/Tactility/Source/app/poweroff/PowerOff.cpp b/Tactility/Source/app/poweroff/PowerOff.cpp index e9a559886..572f40fdd 100644 --- a/Tactility/Source/app/poweroff/PowerOff.cpp +++ b/Tactility/Source/app/poweroff/PowerOff.cpp @@ -4,13 +4,11 @@ #include #include -#include #include #include #include #include -#include #include #include diff --git a/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp b/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp index d89a38507..5fe798302 100644 --- a/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp +++ b/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp @@ -1,4 +1,4 @@ -#include "tactility/lvgl_module.h" +#include #include diff --git a/Tactility/Source/hal/Hal.cpp b/Tactility/Source/hal/Hal.cpp deleted file mode 100644 index 8ce2ed084..000000000 --- a/Tactility/Source/hal/Hal.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace tt::hal { - -constexpr auto* TAG = "Hal"; - -void registerDevices(const Configuration& configuration) { - LOG_I(TAG, "Registering devices"); - - auto devices = configuration.createDevices(); - for (auto& device : devices) { - registerDevice(device); - - // Register attached devices - if (device->getType() == Device::Type::Display) { - const auto display = std::static_pointer_cast(device); - assert(display != nullptr); - const std::shared_ptr touch = display->getTouchDevice(); - if (touch != nullptr) { - registerDevice(touch); - } - } - } -} - -static void startDisplays() { - LOG_I(TAG, "Starting displays & touch"); - auto displays = hal::findDevices(Device::Type::Display); - for (auto& display : displays) { - LOG_I(TAG, "%s starting", display->getName().c_str()); - if (!display->start()) { - LOG_E(TAG, "%s start failed", display->getName().c_str()); - } else { - LOG_I(TAG, "%s started", display->getName().c_str()); - - if (display->supportsBacklightDuty()) { - LOG_I(TAG, "Setting backlight"); - display->setBacklightDuty(0); - } - - auto touch = display->getTouchDevice(); - if (touch != nullptr) { - LOG_I(TAG, "%s starting", touch->getName().c_str()); - if (!touch->start()) { - LOG_E(TAG, "%s start failed", touch->getName().c_str()); - } else { - LOG_I(TAG, "%s started", touch->getName().c_str()); - } - } - } - } -} - -void init(const Configuration& configuration) { - kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalBegin); - - if (configuration.initBoot != nullptr) { - check(configuration.initBoot(), "Init boot failed"); - } - - registerDevices(configuration); - - sdcard::mountAll(); // Warning: This needs to happen BEFORE displays are initialized on the SPI bus - - startDisplays(); // Warning: SPI displays need to start after SPI SD cards are mounted - - kernel::publishSystemEvent(kernel::SystemEvent::BootInitHalEnd); -} - -const Configuration* getConfiguration() { - return tt::getConfiguration()->hardware; -} - -} // namespace diff --git a/Tactility/Source/hal/display/KernelDisplayDriver.cpp b/Tactility/Source/hal/display/KernelDisplayDriver.cpp deleted file mode 100644 index 5808efbf7..000000000 --- a/Tactility/Source/hal/display/KernelDisplayDriver.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#include - -#include - -#include -#include -#include - -namespace tt::hal::display { - -static ColorFormat toColorFormat(DisplayColorFormat format) { - switch (format) { - case DISPLAY_COLOR_FORMAT_MONOCHROME: - return ColorFormat::Monochrome; - case DISPLAY_COLOR_FORMAT_BGR565: - return ColorFormat::BGR565; - case DISPLAY_COLOR_FORMAT_BGR565_SWAPPED: - return ColorFormat::BGR565Swapped; - case DISPLAY_COLOR_FORMAT_RGB565: - return ColorFormat::RGB565; - case DISPLAY_COLOR_FORMAT_RGB565_SWAPPED: - return ColorFormat::RGB565Swapped; - case DISPLAY_COLOR_FORMAT_RGB888: - return ColorFormat::RGB888; - default: - std::unreachable(); - } -} - -KernelDisplayDriver::KernelDisplayDriver(::Device* device) : device(device) { - assert(device_get_type(device) == &DISPLAY_TYPE); -} - -ColorFormat KernelDisplayDriver::getColorFormat() const { - return toColorFormat(display_get_color_format(device)); -} - -uint16_t KernelDisplayDriver::getPixelWidth() const { - return display_get_resolution_x(device); -} - -uint16_t KernelDisplayDriver::getPixelHeight() const { - return display_get_resolution_y(device); -} - -bool KernelDisplayDriver::drawBitmap(int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) { - return display_draw_bitmap(device, xStart, yStart, xEnd, yEnd, pixelData) == ERROR_NONE; -} - -uint8_t KernelDisplayDriver::getFrameBuffers(void* outBuffers[2]) const { - uint8_t count = std::min(display_get_frame_buffer_count(device), 2); - for (uint8_t i = 0; i < count; i++) { - display_get_frame_buffer(device, i, &outBuffers[i]); - } - return count; -} - -} diff --git a/Tactility/Source/hal/gpio/Gpio.cpp b/Tactility/Source/hal/gpio/Gpio.cpp deleted file mode 100644 index 0743c13e6..000000000 --- a/Tactility/Source/hal/gpio/Gpio.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include - -#ifdef ESP_PLATFORM -#include -#endif - -namespace tt::hal::gpio { - -#ifdef ESP_PLATFORM - -constexpr gpio_num_t toEspPin(Pin pin) { return static_cast(pin); } - -constexpr gpio_mode_t toEspGpioMode(Mode mode) { - switch (mode) { - case Mode::Input: - return GPIO_MODE_INPUT; - case Mode::Output: - return GPIO_MODE_OUTPUT; - case Mode::OutputOpenDrain: - return GPIO_MODE_OUTPUT_OD; - case Mode::InputOutput: - return GPIO_MODE_INPUT_OUTPUT; - case Mode::InputOutputOpenDrain: - return GPIO_MODE_INPUT_OUTPUT_OD; - case Mode::Disable: - default: - return GPIO_MODE_DISABLE; - } -} - -#endif - -bool getLevel(Pin pin) { -#ifdef ESP_PLATFORM - return gpio_get_level(toEspPin(pin)) == 1; -#else - return false; -#endif -} - -bool setLevel(Pin pin, bool level) { -#ifdef ESP_PLATFORM - return gpio_set_level(toEspPin(pin), level) == ESP_OK; -#else - return true; -#endif -} - -int getPinCount() { -#ifdef ESP_PLATFORM - return GPIO_NUM_MAX; -#else - return 16; -#endif -} - -bool configureWithPinBitmask(uint64_t pinBitMask, Mode mode, bool pullUp, bool pullDown) { -#ifdef ESP_PLATFORM - gpio_config_t sd_gpio_config = { - .pin_bit_mask = pinBitMask, - .mode = toEspGpioMode(mode), - .pull_up_en = pullUp ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, - .pull_down_en = pullDown ? GPIO_PULLDOWN_ENABLE : GPIO_PULLDOWN_DISABLE, - .intr_type = GPIO_INTR_DISABLE, - }; - return gpio_config(&sd_gpio_config) == ESP_OK; -#else - return true; -#endif -} - -bool configure(Pin pin, Mode mode, bool pullUp, bool pullDown) { -#ifdef ESP_PLATFORM - return configureWithPinBitmask(BIT64(toEspPin(pin)), mode, pullUp, pullDown); -#else - return true; -#endif -} - -bool setMode(Pin pin, Mode mode) { -#ifdef ESP_PLATFORM - return gpio_set_direction(toEspPin(pin), toEspGpioMode(mode)) == ESP_OK; -#endif - return true; -} - -} diff --git a/Tactility/Source/hal/gps/GpsConfiguration.cpp b/Tactility/Source/hal/gps/GpsConfiguration.cpp index 1f355dd05..c67d06aab 100644 --- a/Tactility/Source/hal/gps/GpsConfiguration.cpp +++ b/Tactility/Source/hal/gps/GpsConfiguration.cpp @@ -2,8 +2,6 @@ #include "Tactility/service/gps/GpsService.h" #include "Tactility/file/ObjectFile.h" -#include - namespace tt::hal::gps { const char* toString(GpsModel model) { diff --git a/Tactility/Source/hal/gps/GpsDevice.cpp b/Tactility/Source/hal/gps/GpsDevice.cpp index b6184fa48..982e7a73b 100644 --- a/Tactility/Source/hal/gps/GpsDevice.cpp +++ b/Tactility/Source/hal/gps/GpsDevice.cpp @@ -17,34 +17,27 @@ constexpr auto* TAG = "GpsDevice"; int32_t GpsDevice::threadMain() { uint8_t buffer[GPS_UART_BUFFER_SIZE]; - auto* uart = device_find_by_name(configuration.uartName); - if (uart == nullptr) { - LOG_E(TAG, "Failed to find UART %s", configuration.uartName); - return -1; - } - - struct UartConfig uartConfig = { - .baud_rate = configuration.baudRate, + UartConfig uartConfig = { + .baud_rate = baudRate, .data_bits = UART_CONTROLLER_DATA_8_BITS, .parity = UART_CONTROLLER_PARITY_DISABLE, .stop_bits = UART_CONTROLLER_STOP_BITS_1 }; - error_t error = uart_controller_set_config(uart, &uartConfig); + error_t error = uart_controller_set_config(uartDevice, &uartConfig); if (error != ERROR_NONE) { - LOG_E(TAG, "Failed to configure UART %s: %s", configuration.uartName, error_to_string(error)); + LOG_E(TAG, "Failed to configure UART %s: %s", uartDevice->name, error_to_string(error)); return -1; } - error = uart_controller_open(uart); + error = uart_controller_open(uartDevice); if (error != ERROR_NONE) { - LOG_E(TAG, "Failed to open UART %s: %s", configuration.uartName, error_to_string(error)); + LOG_E(TAG, "Failed to open UART %s: %s", uartDevice->name, error_to_string(error)); return -1; } - GpsModel model = configuration.model; if (model == GpsModel::Unknown) { - model = probe(uart); + model = probe(uartDevice); if (model == GpsModel::Unknown) { LOG_E(TAG, "Probe failed"); setState(State::Error); @@ -52,10 +45,9 @@ int32_t GpsDevice::threadMain() { } } mutex.lock(); - this->model = model; mutex.unlock(); - if (!init(uart, model)) { + if (!init(uartDevice, model)) { LOG_E(TAG, "Init failed"); setState(State::Error); return -1; @@ -66,7 +58,7 @@ int32_t GpsDevice::threadMain() { // Reference: https://gpsd.gitlab.io/gpsd/NMEA.html while (!isThreadInterrupted()) { size_t bytes_read = 0; - uart_controller_read_until(uart, buffer, GPS_UART_BUFFER_SIZE, '\n', true, &bytes_read, 100 / portTICK_PERIOD_MS); + uart_controller_read_until(uartDevice, buffer, GPS_UART_BUFFER_SIZE, '\n', true, &bytes_read, 100 / portTICK_PERIOD_MS); // Thread might've been interrupted in the meanwhile if (isThreadInterrupted()) { @@ -110,8 +102,8 @@ int32_t GpsDevice::threadMain() { } } - if (uart_controller_close(uart) != ERROR_NONE) { - LOG_W(TAG, "Failed to stop UART %s", configuration.uartName); + if (uart_controller_close(uartDevice) != ERROR_NONE) { + LOG_W(TAG, "Failed to stop UART %s", uartDevice->name); } return 0; diff --git a/Tactility/Source/hal/i2c/I2cDevice.cpp b/Tactility/Source/hal/i2c/I2cDevice.cpp deleted file mode 100644 index a59e455fa..000000000 --- a/Tactility/Source/hal/i2c/I2cDevice.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "Tactility/hal/i2c/I2cDevice.h" - -#include - -namespace tt::hal::i2c { - -bool I2cDevice::read(uint8_t* data, size_t dataSize, TickType_t timeout) { - return i2c_controller_read(controller, address, data, dataSize, timeout) == ERROR_NONE; -} - -bool I2cDevice::write(const uint8_t* data, uint16_t dataSize, TickType_t timeout) { - return i2c_controller_write(controller, address, data, dataSize, timeout) == ERROR_NONE; -} - -bool I2cDevice::writeRead(const uint8_t* writeData, size_t writeDataSize, uint8_t* readData, size_t readDataSize, TickType_t timeout) { - return i2c_controller_write_read(controller, address, writeData, writeDataSize, readData, readDataSize, timeout) == ERROR_NONE; -} - -bool I2cDevice::writeRegister(uint8_t reg, const uint8_t* data, uint16_t dataSize, TickType_t timeout) { - return i2c_controller_write_register(controller, address, reg, data, dataSize, timeout) == ERROR_NONE; -} - -bool I2cDevice::readRegister12(uint8_t reg, float& out) const { - std::uint8_t data[2] = {0}; - if (i2c_controller_read_register(controller, address, reg, data, 2, DEFAULT_TIMEOUT) == ERROR_NONE) { - out = (data[0] & 0x0F) << 8 | data[1]; - return true; - } else { - return false; - } -} - -bool I2cDevice::readRegister14(uint8_t reg, float& out) const { - std::uint8_t data[2] = {0}; - if (i2c_controller_read_register(controller, address, reg, data, 2, DEFAULT_TIMEOUT) == ERROR_NONE) { - out = (data[0] & 0x3F) << 8 | data[1]; - return true; - } else { - return false; - } -} - -bool I2cDevice::readRegister16(uint8_t reg, uint16_t& out) const { - std::uint8_t data[2] = {0}; - if (i2c_controller_read_register(controller, address, reg, data, 2, DEFAULT_TIMEOUT) == ERROR_NONE) { - out = data[0] << 8 | data[1]; - return true; - } else { - return false; - } -} - -bool I2cDevice::readRegister8(uint8_t reg, uint8_t& result) const { - return i2c_controller_write_read(controller, address, ®, 1, &result, 1, DEFAULT_TIMEOUT) == ERROR_NONE; -} - -bool I2cDevice::writeRegister8(uint8_t reg, uint8_t value) const { - return i2c_controller_write_register(controller, address, reg, &value, 1, DEFAULT_TIMEOUT) == ERROR_NONE; -} - -bool I2cDevice::bitOn(uint8_t reg, uint8_t bitmask) const { - uint8_t state; - if (readRegister8(reg, state)) { - state |= bitmask; - return writeRegister8(reg, state); - } else { - return false; - } -} - -bool I2cDevice::bitOff(uint8_t reg, uint8_t bitmask) const { - uint8_t state; - if (readRegister8(reg, state)) { - state &= ~bitmask; - return writeRegister8(reg, state); - } else { - return false; - } -} - -} // namespace tt::hal::i2c diff --git a/Tactility/Source/hal/power/PowerDevice.cpp b/Tactility/Source/hal/power/PowerDevice.cpp deleted file mode 100644 index 9f3085b36..000000000 --- a/Tactility/Source/hal/power/PowerDevice.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#include - -#include -#include -#include -#include - -#include - -namespace tt::hal::power { - -#define GET_POWER_DEVICE(device) (static_cast(device_get_driver_data(device))) - -static PowerDevice::MetricType toMetricType(PowerSupplyProperty property) { - switch (property) { - case POWER_SUPPLY_PROP_IS_CHARGING: - return PowerDevice::MetricType::IsCharging; - case POWER_SUPPLY_PROP_CURRENT: - return PowerDevice::MetricType::Current; - case POWER_SUPPLY_PROP_VOLTAGE: - return PowerDevice::MetricType::BatteryVoltage; - case POWER_SUPPLY_PROP_CAPACITY: - default: - return PowerDevice::MetricType::ChargeLevel; - } -} - -static int toIntValue(PowerDevice::MetricType type, const PowerDevice::MetricData& data) { - switch (type) { - case PowerDevice::MetricType::IsCharging: - return data.valueAsBool ? 1 : 0; - case PowerDevice::MetricType::Current: - return data.valueAsInt32; - case PowerDevice::MetricType::BatteryVoltage: - return static_cast(data.valueAsUint32); - case PowerDevice::MetricType::ChargeLevel: - default: - return data.valueAsUint8; - } -} - -static bool apiSupportsProperty(::Device* device, PowerSupplyProperty property) { - return GET_POWER_DEVICE(device)->supportsMetric(toMetricType(property)); -} - -static error_t apiGetProperty(::Device* device, PowerSupplyProperty property, PowerSupplyPropertyValue* outValue) { - auto* power_device = GET_POWER_DEVICE(device); - auto metric_type = toMetricType(property); - if (!power_device->supportsMetric(metric_type)) { - return ERROR_NOT_SUPPORTED; - } - PowerDevice::MetricData data; - if (!power_device->getMetric(metric_type, data)) { - return ERROR_NOT_FOUND; - } - outValue->int_value = toIntValue(metric_type, data); - return ERROR_NONE; -} - -static bool apiSupportsChargeControl(::Device* device) { - return GET_POWER_DEVICE(device)->supportsChargeControl(); -} - -static bool apiIsAllowedToCharge(::Device* device) { - return GET_POWER_DEVICE(device)->isAllowedToCharge(); -} - -static error_t apiSetAllowedToCharge(::Device* device, bool allowed) { - auto* power_device = GET_POWER_DEVICE(device); - if (!power_device->supportsChargeControl()) { - return ERROR_NOT_SUPPORTED; - } - power_device->setAllowedToCharge(allowed); - return ERROR_NONE; -} - -static bool apiSupportsQuickCharge(::Device* device) { - return GET_POWER_DEVICE(device)->supportsQuickCharge(); -} - -static bool apiIsQuickChargeEnabled(::Device* device) { - return GET_POWER_DEVICE(device)->isQuickChargeEnabled(); -} - -static error_t apiSetQuickChargeEnabled(::Device* device, bool enabled) { - auto* power_device = GET_POWER_DEVICE(device); - if (!power_device->supportsQuickCharge()) { - return ERROR_NOT_SUPPORTED; - } - power_device->setQuickChargeEnabled(enabled); - return ERROR_NONE; -} - -static bool apiSupportsPowerOff(::Device* device) { - return GET_POWER_DEVICE(device)->supportsPowerOff(); -} - -static error_t apiPowerOff(::Device* device) { - auto* power_device = GET_POWER_DEVICE(device); - if (!power_device->supportsPowerOff()) { - return ERROR_NOT_SUPPORTED; - } - power_device->powerOff(); - return ERROR_NONE; -} - -static error_t startDevice(::Device*) { return ERROR_NONE; } -static error_t stopDevice(::Device*) { return ERROR_NONE; } - -static PowerSupplyApi powerSupplyApi { - .supports_property = apiSupportsProperty, - .get_property = apiGetProperty, - .supports_charge_control = apiSupportsChargeControl, - .is_allowed_to_charge = apiIsAllowedToCharge, - .set_allowed_to_charge = apiSetAllowedToCharge, - .supports_quick_charge = apiSupportsQuickCharge, - .is_quick_charge_enabled = apiIsQuickChargeEnabled, - .set_quick_charge_enabled = apiSetQuickChargeEnabled, - .supports_power_off = apiSupportsPowerOff, - .power_off = apiPowerOff, -}; - -static const char* powerSupplyCompatible[] = { "hal-power-device", nullptr }; - -static Driver powerSupplyDriver { - .name = "hal-power-device", - .compatible = powerSupplyCompatible, - .start_device = startDevice, - .stop_device = stopDevice, - .api = &powerSupplyApi, - .device_type = &POWER_SUPPLY_TYPE, - .owner = nullptr, - .internal = nullptr, -}; - -/** Registers the "hal-power-device" driver with the kernel on first use. */ -static Driver& getPowerSupplyDriver() { - static const bool registered = [] { - check(driver_construct_add(&powerSupplyDriver) == ERROR_NONE); - return true; - }(); - (void)registered; - return powerSupplyDriver; -} - -void PowerDevice::createPowerSupplyDevice() { - kernelDeviceName = std::format("power-supply-{}", getId()); - kernelDevice.name = kernelDeviceName.c_str(); - check(device_construct(&kernelDevice) == ERROR_NONE); - check(device_add(&kernelDevice) == ERROR_NONE); - device_set_driver(&kernelDevice, &getPowerSupplyDriver()); - check(device_start(&kernelDevice) == ERROR_NONE); - device_set_driver_data(&kernelDevice, this); -} - -void PowerDevice::destroyPowerSupplyDevice() { - device_set_driver_data(&kernelDevice, nullptr); - check(device_stop(&kernelDevice) == ERROR_NONE); - check(device_remove(&kernelDevice) == ERROR_NONE); - check(device_destruct(&kernelDevice) == ERROR_NONE); -} - -PowerDevice::PowerDevice() { - createPowerSupplyDevice(); -} - -PowerDevice::~PowerDevice() { - destroyPowerSupplyDevice(); -} - -} diff --git a/Tactility/Source/hal/touch/KernelTouchDriver.cpp b/Tactility/Source/hal/touch/KernelTouchDriver.cpp deleted file mode 100644 index 7f8de3f8f..000000000 --- a/Tactility/Source/hal/touch/KernelTouchDriver.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -#include - -#include - -#include - -namespace tt::hal::touch { - -// Bus reads are expected to complete quickly; bound the wait so a stalled controller can't block the LVGL indev poll. -static constexpr TickType_t READ_TIMEOUT = pdMS_TO_TICKS(10); - -KernelTouchDriver::KernelTouchDriver(::Device* device) : device(device) { - assert(device_get_type(device) == &POINTER_TYPE); -} - -bool KernelTouchDriver::getTouchedPoints(uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) { - if (pointer_read_data(device, READ_TIMEOUT) != ERROR_NONE) { - return false; - } - return pointer_get_touched_points(device, x, y, strength, pointCount, maxPointCount); -} - -} diff --git a/Tactility/Source/lvgl/Lvgl.cpp b/Tactility/Source/lvgl/Lvgl.cpp deleted file mode 100644 index 601114be9..000000000 --- a/Tactility/Source/lvgl/Lvgl.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -namespace tt::lvgl { - -constexpr auto* TAG = "LVGL"; - -bool isStarted() { - return module_is_started(&lvgl_module); -} - -void attachDevices() { - LOG_I(TAG, "Adding devices"); - - auto lock = getSyncLock()->asScopedLock(); - lock.lock(); - - // Start displays (their related touch devices start automatically within) - - LOG_I(TAG, "Start displays"); - auto hal_displays= hal::findDevices(hal::Device::Type::Display); - for (const auto& display: hal_displays) { - if (display->supportsLvgl()) { - if (display->startLvgl()) { - LOG_I(TAG, "Started %s", display->getName().c_str()); - } else { - LOG_E(TAG, "Start failed for %s", display->getName().c_str()); - } - } - } - - auto* primary_lvgl_display = lv_disp_get_default(); - if (primary_lvgl_display != nullptr) { - LOG_I(TAG, "Set default display rotation"); - auto settings = settings::display::loadOrGetDefault(); - lv_display_rotation_t rotation = settings::display::toLvglDisplayRotation(settings.orientation); - if (rotation != lv_display_get_rotation(primary_lvgl_display)) { - lv_display_set_rotation(primary_lvgl_display, rotation); - } - } - - // Start touch - - if (primary_lvgl_display != nullptr) { - LOG_I(TAG, "Start touch devices"); - auto touch_devices = hal::findDevices(hal::Device::Type::Touch); - for (const auto& touch_device: touch_devices) { - // Start any touch devices that haven't been started yet - if (touch_device->supportsLvgl() && touch_device->getLvglIndev() == nullptr) { - if (touch_device->startLvgl(primary_lvgl_display)) { - LOG_I(TAG, "Started %s", touch_device->getName().c_str()); - } else { - LOG_E(TAG, "Start failed for %s", touch_device->getName().c_str()); - } - } - } - - // Apply touch calibration (kernel POINTER_TYPE model only - see tactility/lvgl_pointer.h) - LOG_I(TAG, "Apply touch calibration"); - auto touch_calibration_settings = settings::touch::loadOrGetDefault(); - if (touch_calibration_settings.enabled && settings::touch::isValid(touch_calibration_settings)) { - auto* pointer_indev = lvgl_pointer_get_default(); - if (pointer_indev != nullptr) { - struct LvglPointerCalibration calibration = { - .x_min = touch_calibration_settings.xMin, - .x_max = touch_calibration_settings.xMax, - .y_min = touch_calibration_settings.yMin, - .y_max = touch_calibration_settings.yMax, - }; - if (lvgl_pointer_set_calibration(pointer_indev, &calibration) != ERROR_NONE) { - LOG_E(TAG, "Failed to apply saved touch calibration"); - } - } - } - - // Start keyboards - LOG_I(TAG, "Start keyboards"); - auto keyboards = hal::findDevices(hal::Device::Type::Keyboard); - for (const auto& keyboard: keyboards) { - if (keyboard->isAttached()) { - if (keyboard->startLvgl(primary_lvgl_display)) { - lv_indev_t* keyboard_indev = keyboard->getLvglIndev(); - hardware_keyboard_set_indev(keyboard_indev); - LOG_I(TAG, "Started %s", keyboard->getName().c_str()); - } else { - LOG_E(TAG, "Start failed for %s", keyboard->getName().c_str()); - } - } - } - - // Start encoders - LOG_I(TAG, "Start encoders"); - auto encoders = hal::findDevices(hal::Device::Type::Encoder); - for (const auto& encoder: encoders) { - if (encoder->startLvgl(primary_lvgl_display)) { - LOG_I(TAG, "Started %s", encoder->getName().c_str()); - } else { - LOG_E(TAG, "Start failed for %s", encoder->getName().c_str()); - } - } - } - - // Restart services - - // We search for the manifest first, because during the initial start() during boot - // the service won't be registered yet. - if (service::findManifestById("Gui") != nullptr) { - if (service::getState("Gui") == SERVICE_STATE_STOPPED) { - service::startService("Gui"); - } else { - LOG_E(TAG, "Gui service is not in Stopped state"); - } - } - - // We search for the manifest first, because during the initial start() during boot - // the service won't be registered yet. - if (service::findManifestById("Statusbar") != nullptr) { - if (service::getState("Statusbar") == SERVICE_STATE_STOPPED) { - service::startService("Statusbar"); - } else { - LOG_E(TAG, "Statusbar service is not in Stopped state"); - } - } -} - -void detachDevices() { - LOG_I(TAG, "Removing devices"); - - auto lock = getSyncLock()->asScopedLock(); - lock.lock(); - - // Stop services that highly depend on LVGL - - service::stopService("Statusbar"); - service::stopService("Gui"); - - // Stop keyboards - - LOG_I(TAG, "Stopping keyboards"); - auto keyboards = hal::findDevices(hal::Device::Type::Keyboard); - for (auto keyboard: keyboards) { - if (keyboard->getLvglIndev() != nullptr) { - keyboard->stopLvgl(); - } - } - - // Stop touch - - LOG_I(TAG, "Stopping touch"); - // The display generally stops their own touch devices, but we'll clean up anything that didn't - auto touch_devices = hal::findDevices(hal::Device::Type::Touch); - for (auto touch_device: touch_devices) { - if (touch_device->getLvglIndev() != nullptr) { - touch_device->stopLvgl(); - } - } - - // Stop encoders - - LOG_I(TAG, "Stopping encoders"); - // The display generally stops their own touch devices, but we'll clean up anything that didn't - auto encoder_devices = hal::findDevices(hal::Device::Type::Encoder); - for (auto encoder_device: encoder_devices) { - if (encoder_device->getLvglIndev() != nullptr) { - encoder_device->stopLvgl(); - } - } - // Stop displays (and their touch devices) - - LOG_I(TAG, "Stopping displays"); - auto displays = hal::findDevices(hal::Device::Type::Display); - for (auto display: displays) { - if (display->supportsLvgl() && display->getLvglDisplay() != nullptr && !display->stopLvgl()) { - LOG_E(TAG, "Failed to detach display from LVGL"); - } - } -} - -void start() { - check(module_start(&lvgl_module) == ERROR_NONE); -} - -void stop() { - check(module_stop(&lvgl_module) == ERROR_NONE); -} - -} // namespace diff --git a/Tactility/Source/lvgl/Toolbar.cpp b/Tactility/Source/lvgl/Toolbar.cpp index ebed4be53..61911487c 100644 --- a/Tactility/Source/lvgl/Toolbar.cpp +++ b/Tactility/Source/lvgl/Toolbar.cpp @@ -3,6 +3,8 @@ #include #include +#include "tactility/drivers/pointer.h" + #include #include @@ -154,7 +156,7 @@ lv_obj_t* toolbar_create(lv_obj_t* parent, const std::string& title) { // If we don't have a touch device, we assume there's some other kind of input like a keyboard, an encoder or button control // In that scenario we want to automatically have the close button selected so the user doesn't have to press the widget selection // an extra time for every screen. - if (!hal::hasDevice(hal::Device::Type::Touch)) { + if (!device_has_active_by_type(&POINTER_TYPE)) { lv_group_focus_obj(toolbar->close_button); } diff --git a/Tactility/Source/service/displayidle/DisplayIdle.cpp b/Tactility/Source/service/displayidle/DisplayIdle.cpp index 713ae276e..9a3a82d0d 100644 --- a/Tactility/Source/service/displayidle/DisplayIdle.cpp +++ b/Tactility/Source/service/displayidle/DisplayIdle.cpp @@ -2,32 +2,28 @@ #include -#include "Screensaver.h" #include "BouncingBallsScreensaver.h" #include "MatrixRainScreensaver.h" #include "MystifyScreensaver.h" +#include "Screensaver.h" #include "StackChanScreensaver.h" -#include -#include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include + namespace tt::service::displayidle { constexpr auto* TAG = "DisplayIdle"; constexpr uint32_t kWakeActivityThresholdMs = 100; -static std::shared_ptr getDisplay() { - return hal::findFirstDevice(hal::Device::Type::Display); -} - void DisplayIdleService::stopScreensaverCb(lv_event_t* e) { auto* self = static_cast(lv_event_get_user_data(e)); lv_event_stop_bubbling(e); @@ -35,8 +31,34 @@ void DisplayIdleService::stopScreensaverCb(lv_event_t* e) { lv_display_trigger_activity(nullptr); } +static void setBacklightBrightness(uint8_t brightness) { + ::Device* display; + if (device_get_first_active_by_type(&DISPLAY_TYPE, &display) == ERROR_NONE) { + ::Device* backlight; + if (display_get_backlight(display, &backlight) == ERROR_NONE) { + device_get(backlight); + backlight_set_brightness(backlight, brightness); + device_put(backlight); + } + device_put(display); + } +} + +static bool hasDisplayWithBacklight() { + ::Device* display; + bool result = false; + if (device_get_first_active_by_type(&DISPLAY_TYPE, &display) == ERROR_NONE) { + ::Device* backlight; + if (display_get_backlight(display, &backlight) == ERROR_NONE) { + result = true; + } + device_put(display); + } + return result; +} + void DisplayIdleService::stopScreensaver() { - if (!lvgl::lock(100)) { + if (!lvgl_try_lock(100)) { // Lock failed - keep flag set to retry on next tick return; } @@ -52,7 +74,7 @@ void DisplayIdleService::stopScreensaver() { lv_obj_delete(screensaverOverlay); screensaverOverlay = nullptr; } - lvgl::unlock(); + lvgl_unlock(); stopScreensaverRequested.store(false, std::memory_order_relaxed); // Reset auto-off state @@ -60,10 +82,10 @@ void DisplayIdleService::stopScreensaver() { backlightOff = false; // Restore backlight if display was dimmed - auto display = getDisplay(); - if (display && wasDimmed) { - display->setBacklightDuty(restoreDuty); + if (wasDimmed) { + setBacklightBrightness(restoreDuty); } + displayDimmed = wasDimmed ? false : displayDimmed; } @@ -124,11 +146,11 @@ void DisplayIdleService::updateScreensaver() { } void DisplayIdleService::tick() { - if (!lvgl::lock(100)) { + if (!lvgl_try_lock(100)) { return; } if (lv_display_get_default() == nullptr) { - lvgl::unlock(); + lvgl_unlock(); return; } @@ -152,10 +174,7 @@ void DisplayIdleService::tick() { screensaver->stop(); screensaver.reset(); } - auto display = getDisplay(); - if (display) { - display->setBacklightDuty(0); - } + setBacklightBrightness(0); backlightOff = true; } else { updateScreensaver(); @@ -163,7 +182,7 @@ void DisplayIdleService::tick() { } } - lvgl::unlock(); + lvgl_unlock(); // Check stop request early for faster response if (stopScreensaverRequested.load(std::memory_order_acquire)) { @@ -171,23 +190,22 @@ void DisplayIdleService::tick() { return; } - auto display = getDisplay(); - if (display != nullptr && display->supportsBacklightDuty()) { + if (hasDisplayWithBacklight()) { if (!cachedDisplaySettings.backlightTimeoutEnabled || cachedDisplaySettings.backlightTimeoutMs == 0) { if (displayDimmed) { - display->setBacklightDuty(cachedDisplaySettings.backlightDuty); + setBacklightBrightness(cachedDisplaySettings.backlightDuty); displayDimmed = false; } } else { if (!displayDimmed && inactive_ms >= cachedDisplaySettings.backlightTimeoutMs) { - if (!lvgl::lock(100)) { + if (!lvgl_try_lock(100)) { return; // Retry on next tick } activateScreensaver(); - lvgl::unlock(); + lvgl_unlock(); // Turn off backlight for "None" screensaver (just black screen) if (cachedDisplaySettings.screensaverType == settings::display::ScreensaverType::None) { - display->setBacklightDuty(0); + setBacklightBrightness(0); } displayDimmed = true; } else if (displayDimmed && (inactive_ms < kWakeActivityThresholdMs)) { @@ -231,7 +249,7 @@ void DisplayIdleService::onStop(ServiceContext& service) { } void DisplayIdleService::startScreensaver() { - if (!lvgl::lock(100)) { + if (!lvgl_try_lock(100)) { return; } @@ -240,12 +258,11 @@ void DisplayIdleService::startScreensaver() { cachedDisplaySettings = settings::display::loadOrGetDefault(); activateScreensaver(); - lvgl::unlock(); + lvgl_unlock(); // Turn off backlight for "None" screensaver - auto display = getDisplay(); - if (display && cachedDisplaySettings.screensaverType == settings::display::ScreensaverType::None) { - display->setBacklightDuty(0); + if (hasDisplayWithBacklight() && cachedDisplaySettings.screensaverType == settings::display::ScreensaverType::None) { + setBacklightBrightness(0); } displayDimmed = true; } diff --git a/Tactility/Source/service/gps/GpsService.cpp b/Tactility/Source/service/gps/GpsService.cpp index a67685e99..8d4f707f1 100644 --- a/Tactility/Source/service/gps/GpsService.cpp +++ b/Tactility/Source/service/gps/GpsService.cpp @@ -157,8 +157,17 @@ bool GpsService::startReceiving() { } for (const auto& configuration: configurations) { - auto device = std::make_shared(configuration); - addGpsDevice(device); + ::Device* uart_device; + if (device_get_by_name(configuration.uartName, &uart_device) == ERROR_NONE) { + auto gps_device = std::make_shared( + uart_device, + configuration.baudRate, + configuration.model + ); + addGpsDevice(gps_device); + } else { + LOG_E(TAG, "Failed to find device %s", configuration.uartName); + } } // Reset times before starting devices to avoid race with incoming data diff --git a/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp b/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp index aef3b0833..d8f6c3ba1 100644 --- a/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp +++ b/Tactility/Source/service/keyboardidle/KeyboardIdle.cpp @@ -1,16 +1,18 @@ #ifdef ESP_PLATFORM -#include -#include -#include +#include + + +#include #include #include #include #include -#include #include #include +#include +#include namespace tt::service::keyboardidle { @@ -20,11 +22,15 @@ class KeyboardIdleService final : public Service { bool keyboardDimmed = false; settings::keyboard::KeyboardSettings cachedKeyboardSettings; - static std::shared_ptr getKeyboard() { - return hal::findFirstDevice(hal::Device::Type::Keyboard); - } - static Device* getKeyboardBacklight() { + ::Device* keyboard; + if (device_get_first_active_by_type(&KEYBOARD_TYPE, &keyboard) == ERROR_NONE) { + ::Device* backlight = nullptr; + keyboard_get_backlight(keyboard, &backlight); // disregard result + device_put(keyboard); + return backlight; // WARNING: did not increase refcount + } + // TODO: Remove after all drivers are migrated return device_find_by_name("keyboard_backlight"); } @@ -41,14 +47,13 @@ class KeyboardIdleService final : public Service { // Query LVGL inactivity once for both checks uint32_t inactive_ms = 0; - if (lvgl::lock(100)) { + if (lvgl_try_lock(100)) { inactive_ms = lv_display_get_inactive_time(nullptr); - lvgl::unlock(); + lvgl_unlock(); } // Handle keyboard backlight - auto keyboard = getKeyboard(); - if (keyboard != nullptr && keyboard->isAttached()) { + if (device_has_active_by_type(&KEYBOARD_TYPE)) { // If timeout disabled, ensure backlight restored if we had dimmed it if (!cachedKeyboardSettings.backlightTimeoutEnabled || cachedKeyboardSettings.backlightTimeoutMs == 0) { if (keyboardDimmed) { @@ -89,8 +94,7 @@ public: timer = nullptr; } // Ensure keyboard restored on stop - auto keyboard = getKeyboard(); - if (keyboard && keyboardDimmed) { + if (device_has_active_by_type(&KEYBOARD_TYPE) && keyboardDimmed) { setKeyboardBacklightBrightness(cachedKeyboardSettings.backlightEnabled ? cachedKeyboardSettings.backlightBrightness : 0); keyboardDimmed = false; } diff --git a/Tactility/Source/service/statusbar/Statusbar.cpp b/Tactility/Source/service/statusbar/Statusbar.cpp index cb9c8e7dc..32ac74cc8 100644 --- a/Tactility/Source/service/statusbar/Statusbar.cpp +++ b/Tactility/Source/service/statusbar/Statusbar.cpp @@ -1,25 +1,27 @@ #include +#include +#include "tactility/module.h" + #include #include -#include -#include -#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include @@ -267,15 +269,15 @@ class StatusbarService final : public Service { } void update() { - if (lvgl::isStarted()) { - if (lvgl::lock(100)) { + if (module_is_started(&lvgl_module)) { + if (lvgl_try_lock(100)) { updateGpsIcon(); updateBluetoothIcon(); updateWifiIcon(); updateSdCardIcon(); updatePowerStatusIcon(); updateUsbIcon(); - lvgl::unlock(); + lvgl_unlock(); } } } diff --git a/Tactility/Source/settings/DisplaySettings.cpp b/Tactility/Source/settings/DisplaySettings.cpp index 1e62ca4ed..ee2b082a3 100644 --- a/Tactility/Source/settings/DisplaySettings.cpp +++ b/Tactility/Source/settings/DisplaySettings.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include diff --git a/TactilityC/Include/tt_gps.h b/TactilityC/Include/tt_gps.h deleted file mode 100644 index 2a9e2f930..000000000 --- a/TactilityC/Include/tt_gps.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -bool tt_gps_has_coordinates(); - -bool tt_gps_get_coordinates( - float* longitude, - float* latitude, - float* speed, - float* course, - int* day, - int* month, - int* year -); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Include/tt_hal_device.h b/TactilityC/Include/tt_hal_device.h deleted file mode 100644 index e41e17e77..000000000 --- a/TactilityC/Include/tt_hal_device.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - DEVICE_TYPE_I2C, - DEVICE_TYPE_DISPLAY, - DEVICE_TYPE_TOUCH, - DEVICE_TYPE_SDCARD, - DEVICE_TYPE_KEYBOARD, - DEVICE_TYPE_POWER, - DEVICE_TYPE_GPS -} TtDeviceType; - -typedef uint32_t DeviceId; - -/** - * Find one or more devices of a certain type. - * @param[in] type the type to look for - * @param[inout] deviceIds the output ids, which should fit at least maxCount amount of devices - * @param[out] count the resulting number of device ids that were returned - * @param[in] maxCount the maximum number of items that the "deviceIds" output can contain (minimum value is 1) - * @return true if one or more devices were found - */ -bool tt_hal_device_find(TtDeviceType type, DeviceId* deviceIds, uint16_t* count, uint16_t maxCount); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Include/tt_hal_display.h b/TactilityC/Include/tt_hal_display.h deleted file mode 100644 index 1a7af6a03..000000000 --- a/TactilityC/Include/tt_hal_display.h +++ /dev/null @@ -1,100 +0,0 @@ -#pragma once - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* DisplayDriverHandle; - -typedef enum { - COLOR_FORMAT_MONOCHROME, // 1 bpp - COLOR_FORMAT_BGR565, - COLOR_FORMAT_BGR565_SWAPPED, - COLOR_FORMAT_RGB565, - COLOR_FORMAT_RGB565_SWAPPED, - COLOR_FORMAT_RGB888 -} ColorFormat; - -/** - * Check if the display driver interface is supported for this device. - * @param[in] displayId the identifier of the display device - * @return true if the driver is supported. - */ -bool tt_hal_display_driver_supported(DeviceId displayId); - -/** - * Allocate a driver object for the specified displayId. - * @warning check whether the driver is supported by calling tt_hal_display_driver_supported() first - * @param[in] displayId the identifier of the display device - * @return the driver handle - */ -DisplayDriverHandle tt_hal_display_driver_alloc(DeviceId displayId); - -/** - * Free the memory for the display driver. - * @param[in] handle the display driver handle - */ -void tt_hal_display_driver_free(DisplayDriverHandle handle); - -/** - * Lock the display device. Call this function before doing any draw calls. - * Certain display devices are on a shared bus (e.g. SPI) so they must run - * mutually exclusive with other devices on the same bus (e.g. SD card) - * @param[in] handle the display driver handle - * @param[in] timeout the maximum amount of ticks to wait for getting a lock - * @return true if the lock was acquired - */ -bool tt_hal_display_driver_lock(DisplayDriverHandle handle, TickType_t timeout); - -/** - * Unlock the display device. Must be called exactly once after locking. - * @param[in] handle the display driver handle - */ -void tt_hal_display_driver_unlock(DisplayDriverHandle handle); - -/** - * @param[in] handle the display driver handle - * @return the native color format for this display - */ -ColorFormat tt_hal_display_driver_get_colorformat(DisplayDriverHandle handle); - -/** - * @param[in] handle the display driver handle - * @return the horizontal resolution of the display - */ -uint16_t tt_hal_display_driver_get_pixel_width(DisplayDriverHandle handle); - -/** - * @param[in] handle the display driver handle - * @return the vertical resolution of the display - */ -uint16_t tt_hal_display_driver_get_pixel_height(DisplayDriverHandle handle); - -/** - * Draw pixels on the screen. Make sure to call the lock function first and unlock afterwards. - * Many draw calls can be done inbetween a single lock and unlock. - * @param[in] handle the display driver handle - * @param[in] xStart the starting x coordinate for rendering the pixel data - * @param[in] yStart the starting y coordinate for rendering the pixel data - * @param[in] xEnd the last x coordinate for rendering the pixel data (absolute pixel value, not relative to xStart!) - * @param[in] yEnd the last y coordinate for rendering the pixel data (absolute pixel value, not relative to yStart!) - * @param[in] pixelData a buffer of pixels. the data is placed as "RowRowRowRow". The size depends on the ColorFormat - */ -void tt_hal_display_driver_draw_bitmap(DisplayDriverHandle handle, int xStart, int yStart, int xEnd, int yEnd, const void* pixelData); - -/** - * Get direct pointers to the display's hardware frame buffer(s), if supported. - * Only available for panels with direct CPU-addressable frame buffers (e.g. MIPI-DSI/DPI). - * @param[in] handle the display driver handle - * @param[out] outBuffers receives up to 2 frame buffer pointers - * @return number of buffers written to outBuffers (0 if unsupported) - */ -uint8_t tt_hal_display_driver_get_frame_buffers(DisplayDriverHandle handle, void* outBuffers[2]); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Include/tt_hal_gpio.h b/TactilityC/Include/tt_hal_gpio.h deleted file mode 100644 index b80bd3ebb..000000000 --- a/TactilityC/Include/tt_hal_gpio.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */ -typedef unsigned int GpioPin; - -/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */ -#define GPIO_NO_PIN -1 - -/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */ -bool tt_hal_gpio_get_level(GpioPin pin); - -/** @deprecated NON-FUNCTIONAL - WILL BE REMOVED SOON */ -int tt_hal_gpio_get_pin_count(); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Include/tt_hal_touch.h b/TactilityC/Include/tt_hal_touch.h deleted file mode 100644 index b115a0279..000000000 --- a/TactilityC/Include/tt_hal_touch.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "tt_hal_device.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* TouchDriverHandle; -/** - * Check if the touch driver interface is supported for this device. - * @param[in] touchDeviceId the identifier of the touch device - * @return true if the driver is supported. - */ -bool tt_hal_touch_driver_supported(DeviceId touchDeviceId); - -/** - * Allocate a driver object for the specified touchDeviceId. - * @warning check whether the driver is supported by calling tt_hal_touch_driver_supported() first - * @param[in] touchDeviceId the identifier of the touch device - * @return the driver handle - */ -TouchDriverHandle tt_hal_touch_driver_alloc(DeviceId touchDeviceId); - -/** - * Free the memory for the touch driver. - * @param[in] handle the touch driver handle - */ -void tt_hal_touch_driver_free(TouchDriverHandle handle); - -/** - * Get the coordinates for the currently touched points on the screen. - * - * @param[in] handle the touch driver handle - * @param[in] x array of X coordinates - * @param[in] y array of Y coordinates - * @param[in] strength array of strengths (with the minimum size of maxPointCount) or NULL - * @param[in] pointCount the number of points currently touched on the screen - * @param[in] maxPointCount the maximum number of points that can be touched at once - * - * @return true when touched and coordinates are available - */ -bool tt_hal_touch_driver_get_touched_points(TouchDriverHandle handle, uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Include/tt_hal_uart.h b/TactilityC/Include/tt_hal_uart.h deleted file mode 100644 index 8f787aa08..000000000 --- a/TactilityC/Include/tt_hal_uart.h +++ /dev/null @@ -1,159 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * WARNING: THIS API IS NON-FUNCTIONAL AND DEPRECATED. - * IT WILL BE REMOVED IN A FUTURE RELEASE ONCE OFFICIAL APPS ARE MIGRATED. -* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - -/** - * @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_t 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_t 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_t 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_lvgl.h b/TactilityC/Include/tt_lvgl.h deleted file mode 100644 index 9d7245d40..000000000 --- a/TactilityC/Include/tt_lvgl.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -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(); - -/** Start LVGL and related background services */ -void tt_lvgl_start(); - -/** Stop LVGL and related background services */ -void tt_lvgl_stop(); - -/** Lock the LVGL context. Call this before doing LVGL-related operations from a non-LVLG thread */ -bool tt_lvgl_lock(TickType_t timeout); - -/** Unlock the LVGL context */ -void tt_lvgl_unlock(); - -#ifdef __cplusplus -} -#endif diff --git a/TactilityC/Source/tt_gps.cpp b/TactilityC/Source/tt_gps.cpp deleted file mode 100644 index 5131193cc..000000000 --- a/TactilityC/Source/tt_gps.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "tt_gps.h" -#include - -using namespace tt::service; - -extern "C" { - -bool tt_gps_has_coordinates() { - auto service = gps::findGpsService(); - return service != nullptr && service->hasCoordinates(); -} - -bool tt_gps_get_coordinates( - float* longitude, - float* latitude, - float* speed, - float* course, - int* day, - int* month, - int* year -) { - auto service = gps::findGpsService(); - - if (service == nullptr) { - return false; - } - - minmea_sentence_rmc rmc; - - if (!service->getCoordinates(rmc)) { - return false; - } - - *longitude = minmea_tocoord(&rmc.longitude); - *latitude = minmea_tocoord(&rmc.latitude); - *speed = minmea_tocoord(&rmc.speed); - *course = minmea_tocoord(&rmc.course); - *day = rmc.date.day; - *month = rmc.date.month; - *year = rmc.date.year; - - return true; -} - -} \ No newline at end of file diff --git a/TactilityC/Source/tt_hal_device.cpp b/TactilityC/Source/tt_hal_device.cpp deleted file mode 100644 index 6a5ad1f46..000000000 --- a/TactilityC/Source/tt_hal_device.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "tt_hal_device.h" - -#include - -#include - -static tt::hal::Device::Type toTactilityDeviceType(TtDeviceType type) { - switch (type) { - case DEVICE_TYPE_I2C: - return tt::hal::Device::Type::I2c; - case DEVICE_TYPE_DISPLAY: - return tt::hal::Device::Type::Display; - case DEVICE_TYPE_TOUCH: - return tt::hal::Device::Type::Touch; - case DEVICE_TYPE_SDCARD: - return tt::hal::Device::Type::SdCard; - case DEVICE_TYPE_KEYBOARD: - return tt::hal::Device::Type::Keyboard; - case DEVICE_TYPE_POWER: - return tt::hal::Device::Type::Power; - case DEVICE_TYPE_GPS: - return tt::hal::Device::Type::Gps; - default: - check(false, "Device::Type not supported"); - } -} - -extern "C" { - -bool tt_hal_device_find(TtDeviceType type, DeviceId* deviceIds, uint16_t* count, uint16_t maxCount) { - assert(maxCount > 0); - - int16_t currentIndex = -1; - uint16_t maxIndex = maxCount - 1; - - findDevices(toTactilityDeviceType(type), [&](const auto& device) { - currentIndex++; - deviceIds[currentIndex] = device->getId(); - // Continue if there is storage capacity left - return currentIndex < maxIndex; - }); - - *count = currentIndex + 1; - - return currentIndex >= 0; -} - -} diff --git a/TactilityC/Source/tt_hal_display.cpp b/TactilityC/Source/tt_hal_display.cpp deleted file mode 100644 index 6eae38740..000000000 --- a/TactilityC/Source/tt_hal_display.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "tt_hal_display.h" - -#include - -#include -#include -#include - -static ColorFormat toColorFormat(tt::hal::display::ColorFormat format) { - switch (format) { - case tt::hal::display::ColorFormat::Monochrome: - return COLOR_FORMAT_MONOCHROME; - case tt::hal::display::ColorFormat::BGR565: - return COLOR_FORMAT_BGR565; - case tt::hal::display::ColorFormat::BGR565Swapped: - return COLOR_FORMAT_BGR565_SWAPPED; - case tt::hal::display::ColorFormat::RGB565: - return COLOR_FORMAT_RGB565; - case tt::hal::display::ColorFormat::RGB565Swapped: - return COLOR_FORMAT_RGB565_SWAPPED; - case tt::hal::display::ColorFormat::RGB888: - return COLOR_FORMAT_RGB888; - default: - check(false, "ColorFormat not supported"); - } -} - -struct DriverWrapper { - std::shared_ptr driver; - DriverWrapper(std::shared_ptr driver) : driver(driver) {} -}; - -static std::shared_ptr findValidDisplayDevice(tt::hal::Device::Id id) { - auto device = tt::hal::findDevice(id); - if (device == nullptr || device->getType() != tt::hal::Device::Type::Display) { - return nullptr; - } - return std::reinterpret_pointer_cast(device); -} - -extern "C" { - -bool tt_hal_display_driver_supported(DeviceId id) { - auto display = findValidDisplayDevice(id); - return display != nullptr && display->supportsDisplayDriver(); -} - -DisplayDriverHandle tt_hal_display_driver_alloc(DeviceId id) { - auto display = findValidDisplayDevice(id); - assert(display->supportsDisplayDriver()); - return new DriverWrapper(display->getDisplayDriver()); -} - -void tt_hal_display_driver_free(DisplayDriverHandle handle) { - auto wrapper = static_cast(handle); - delete wrapper; -} - -bool tt_hal_display_driver_lock(DisplayDriverHandle handle, TickType_t timeout) { - // TODO: re-implement with SPI lock - return true; -} - -void tt_hal_display_driver_unlock(DisplayDriverHandle handle) { - // TODO: re-implement with SPI lock -} - -ColorFormat tt_hal_display_driver_get_colorformat(DisplayDriverHandle handle) { - auto wrapper = static_cast(handle); - return toColorFormat(wrapper->driver->getColorFormat()); -} - -uint16_t tt_hal_display_driver_get_pixel_width(DisplayDriverHandle handle) { - auto wrapper = static_cast(handle); - return wrapper->driver->getPixelWidth(); -} - -uint16_t tt_hal_display_driver_get_pixel_height(DisplayDriverHandle handle) { - auto wrapper = static_cast(handle); - return wrapper->driver->getPixelHeight(); -} - -void tt_hal_display_driver_draw_bitmap(DisplayDriverHandle handle, int xStart, int yStart, int xEnd, int yEnd, const void* pixelData) { - auto wrapper = static_cast(handle); - wrapper->driver->drawBitmap(xStart, yStart, xEnd, yEnd, pixelData); -} - -uint8_t tt_hal_display_driver_get_frame_buffers(DisplayDriverHandle handle, void* outBuffers[2]) { - auto wrapper = static_cast(handle); - return wrapper->driver->getFrameBuffers(outBuffers); -} - -} \ No newline at end of file diff --git a/TactilityC/Source/tt_hal_touch.cpp b/TactilityC/Source/tt_hal_touch.cpp deleted file mode 100644 index 9572275dc..000000000 --- a/TactilityC/Source/tt_hal_touch.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "tt_hal_touch.h" - -#include -#include "Tactility/hal/touch/TouchDevice.h" -#include "Tactility/hal/touch/TouchDriver.h" - -struct DriverWrapper { - std::shared_ptr driver; - DriverWrapper(std::shared_ptr driver) : driver(driver) {} -}; - -static std::shared_ptr findValidTouchDevice(tt::hal::Device::Id id) { - auto device = tt::hal::findDevice(id); - if (device == nullptr || device->getType() != tt::hal::Device::Type::Touch) { - return nullptr; - } - return std::reinterpret_pointer_cast(device); -} - -extern "C" { - -bool tt_hal_touch_driver_supported(DeviceId id) { - auto touch = findValidTouchDevice(id); - return touch != nullptr && touch->supportsTouchDriver(); -} - -TouchDriverHandle tt_hal_touch_driver_alloc(DeviceId id) { - auto touch = findValidTouchDevice(id); - assert(touch->supportsTouchDriver()); - return new DriverWrapper(touch->getTouchDriver()); -} - -void tt_hal_touch_driver_free(TouchDriverHandle handle) { - DriverWrapper* wrapper = static_cast(handle); - delete wrapper; -} - -bool tt_hal_touch_driver_get_touched_points(TouchDriverHandle handle, uint16_t* x, uint16_t* y, uint16_t* strength, uint8_t* pointCount, uint8_t maxPointCount) { - DriverWrapper* wrapper = static_cast(handle); - return wrapper->driver->getTouchedPoints(x, y, strength, pointCount, maxPointCount); -} - -} diff --git a/TactilityC/Source/tt_hal_uart.cpp b/TactilityC/Source/tt_hal_uart.cpp deleted file mode 100644 index 13a988fde..000000000 --- a/TactilityC/Source/tt_hal_uart.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "tt_hal_uart.h" - -#include - -extern "C" { - -size_t tt_hal_uart_get_count() { - return 0; -} - -bool tt_hal_uart_get_name(size_t index, char* name, size_t nameSizeLimit) { - return false; -} - -UartHandle tt_hal_uart_alloc(size_t index) { - return nullptr; -} - -void tt_hal_uart_free(UartHandle handle) { -} - -bool tt_hal_uart_start(UartHandle handle) { - return false; -} - -bool tt_hal_uart_is_started(UartHandle handle) { - return false; -} - -bool tt_hal_uart_stop(UartHandle handle) { - return false; -} - -size_t tt_hal_uart_read_bytes(UartHandle handle, char* buffer, size_t bufferSize, TickType_t timeout) { - return 0; -} - -bool tt_hal_uart_read_byte(UartHandle handle, char* output, TickType_t timeout) { - return false; -} - -size_t tt_hal_uart_write_bytes(UartHandle handle, const char* buffer, size_t bufferSize, TickType_t timeout) { - return 0; -} - -size_t tt_hal_uart_available(UartHandle handle) { - return 0; -} - -bool tt_hal_uart_set_baud_rate(UartHandle handle, size_t baud_rate) { - return false; -} - -uint32_t tt_hal_uart_get_baud_rate(UartHandle handle) { - return 0; -} - -void tt_hal_uart_flush_input(UartHandle handle) { -} - -} diff --git a/TactilityC/Source/tt_init.cpp b/TactilityC/Source/tt_init.cpp index 6e9554dc7..24326454a 100644 --- a/TactilityC/Source/tt_init.cpp +++ b/TactilityC/Source/tt_init.cpp @@ -5,13 +5,7 @@ #include "tt_app_fileselection.h" #include "tt_app_selectiondialog.h" #include "tt_bundle.h" -#include "tt_gps.h" -#include "tt_hal_device.h" -#include "tt_hal_display.h" -#include "tt_hal_touch.h" -#include "tt_hal_uart.h" #include -#include "tt_lvgl.h" #include "tt_lvgl_keyboard.h" #include "tt_lvgl_spinner.h" #include "tt_lvgl_toolbar.h" @@ -299,42 +293,6 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(tt_bundle_put_bool), ESP_ELFSYM_EXPORT(tt_bundle_put_int32), ESP_ELFSYM_EXPORT(tt_bundle_put_string), - ESP_ELFSYM_EXPORT(tt_gps_has_coordinates), - ESP_ELFSYM_EXPORT(tt_gps_get_coordinates), - ESP_ELFSYM_EXPORT(tt_hal_device_find), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_alloc), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_draw_bitmap), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_free), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_get_colorformat), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_get_pixel_height), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_get_pixel_width), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_lock), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_unlock), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_supported), - ESP_ELFSYM_EXPORT(tt_hal_display_driver_get_frame_buffers), - ESP_ELFSYM_EXPORT(tt_hal_touch_driver_supported), - 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_lvgl_is_started), - ESP_ELFSYM_EXPORT(tt_lvgl_lock), - ESP_ELFSYM_EXPORT(tt_lvgl_unlock), - ESP_ELFSYM_EXPORT(tt_lvgl_start), - ESP_ELFSYM_EXPORT(tt_lvgl_stop), ESP_ELFSYM_EXPORT(tt_lvgl_software_keyboard_show), ESP_ELFSYM_EXPORT(tt_lvgl_software_keyboard_hide), ESP_ELFSYM_EXPORT(tt_lvgl_software_keyboard_is_enabled), diff --git a/TactilityC/Source/tt_lvgl.cpp b/TactilityC/Source/tt_lvgl.cpp deleted file mode 100644 index 261d3eb58..000000000 --- a/TactilityC/Source/tt_lvgl.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include - -extern "C" { - -bool tt_lvgl_is_started() { - return tt::lvgl::isStarted(); -} - -void tt_lvgl_start() { - tt::lvgl::start(); -} - -void tt_lvgl_stop() { - tt::lvgl::stop(); -} - -bool tt_lvgl_lock(TickType_t timeout) { - return tt::lvgl::getSyncLock()->lock(timeout); -} - -void tt_lvgl_unlock() { - tt::lvgl::getSyncLock()->unlock(); -} - -} \ No newline at end of file diff --git a/TactilityKernel/include/tactility/device.h b/TactilityKernel/include/tactility/device.h index 78eea5645..c01d48615 100644 --- a/TactilityKernel/include/tactility/device.h +++ b/TactilityKernel/include/tactility/device.h @@ -392,6 +392,15 @@ error_t device_get_first_by_type(const struct DeviceType* type, struct Device** */ error_t device_get_first_active_by_type(const struct DeviceType* type, struct Device** out_device); +/** + * Check if there is an active device of the provided type. + * + * @param[in] type non-null device type pointer + * @retval ERROR_NOT_FOUND if no started device of that type exists + * @retval ERROR_NONE on success; caller must call device_put(*out_device) exactly once + */ +bool device_has_active_by_type(const struct DeviceType* type); + /** * Find the first device whose driver matches the given compatible string and atomically take a * reference on it. See device_get_by_name() for why this is preferred over diff --git a/TactilityKernel/include/tactility/drivers/keyboard.h b/TactilityKernel/include/tactility/drivers/keyboard.h index d7ea86994..42e4999f9 100644 --- a/TactilityKernel/include/tactility/drivers/keyboard.h +++ b/TactilityKernel/include/tactility/drivers/keyboard.h @@ -37,6 +37,15 @@ struct KeyboardApi { * @retval ERROR_NONE when the operation was successful */ error_t (*read_key)(struct Device* device, struct KeyboardKeyData* data); + + /** + * @brief Returns the baclight if the keyboard has one. + * @param[in] device the keyboard device + * @param[out] backlight_device the output backlight device + * @retval ERROR_NONE when the backlight_device was set + * @retval ERROR_NOT_SUPPORTED when this device has no backlight + */ + error_t (*get_backlight)(struct Device* device, struct Device** backlight_device); }; /** @@ -44,6 +53,16 @@ struct KeyboardApi { */ error_t keyboard_read_key(struct Device* device, struct KeyboardKeyData* data); +/** + * @brief Returns the backlight if the keyboard has one. + * @param[in] device the keyboard device + * @param[out] backlight_device the output backlight device + * @retval ERROR_NONE when the backlight_device was set + * @retval ERROR_NOT_SUPPORTED when this device has no backlight + */ +error_t keyboard_get_backlight(struct Device* device, struct Device** backlight_device); + + extern const struct DeviceType KEYBOARD_TYPE; #ifdef __cplusplus diff --git a/TactilityKernel/source/device.cpp b/TactilityKernel/source/device.cpp index 8f2aba03a..eaa6c67af 100644 --- a/TactilityKernel/source/device.cpp +++ b/TactilityKernel/source/device.cpp @@ -585,6 +585,20 @@ error_t device_get_first_active_by_type(const DeviceType* type, Device** out_dev return error; } +bool device_has_active_by_type(const struct DeviceType* type) { + ledger_lock(); + bool found = false; + for (auto* device : ledger.devices) { + auto* driver = device->internal->driver; + if (driver != nullptr && driver->device_type == type && device->internal->state.started) { + found = true; + break; + } + } + ledger_unlock(); + return found; +} + error_t device_get_first_by_compatible(const char* compatible, Device** out_device) { ledger_lock(); Device* found = nullptr; diff --git a/TactilityKernel/source/drivers/keyboard.cpp b/TactilityKernel/source/drivers/keyboard.cpp index 307590271..34c2b101f 100644 --- a/TactilityKernel/source/drivers/keyboard.cpp +++ b/TactilityKernel/source/drivers/keyboard.cpp @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 #include +#include #include #define KEYBOARD_DRIVER_API(driver) ((struct KeyboardApi*)driver->api) @@ -11,6 +12,16 @@ error_t keyboard_read_key(Device* device, KeyboardKeyData* data) { return KEYBOARD_DRIVER_API(driver)->read_key(device, data); } +error_t keyboard_get_backlight(Device* device, Device** backlight_device) { + const auto* driver = device_get_driver(device); + + if (KEYBOARD_DRIVER_API(driver)->get_backlight == nullptr) { + return ERROR_NOT_SUPPORTED; + } + + return KEYBOARD_DRIVER_API(driver)->get_backlight(device, backlight_device); +} + const DeviceType KEYBOARD_TYPE { .name = "keyboard" };