Remove old HAL components and refactored GPS-related code (#583)
- Added generic GPS/GNSS support with device detection, configuration, and persistent settings. - Improved device and module lifecycle management. - Added flexible filesystem locking support for displays and storage. - Improved display-idle and keyboard backlight handling. - Updated architecture, driver, module, testing, and licensing documentation. - Removed old HAL device and related code.
This commit is contained in:
committed by
GitHub
parent
29e80cfd65
commit
2a2558b29a
@@ -6,8 +6,6 @@
|
||||
namespace tt::kernel {
|
||||
|
||||
enum class SystemEvent {
|
||||
BootInitHalBegin,
|
||||
BootInitHalEnd,
|
||||
BootSplash,
|
||||
/** Gained IP address */
|
||||
NetworkConnected,
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "tactility/concurrent/dispatcher.h"
|
||||
#include "tactility/device.h"
|
||||
#include "tactility/module.h"
|
||||
#include <tactility/concurrent/dispatcher.h>
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/module.h>
|
||||
#include <Tactility/app/AppManifest.h>
|
||||
#include <Tactility/hal/Configuration.h>
|
||||
#include <Tactility/service/ServiceManifest.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -45,15 +45,11 @@ struct FileCloser {
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<std::shared_ptr<Lock>(const std::string&)> FindLockFunction;
|
||||
|
||||
/**
|
||||
* @param[in] path the path to get a lock for
|
||||
* @return a lock instance (never null)
|
||||
*/
|
||||
std::shared_ptr<Lock> getLock(const std::string& path);
|
||||
|
||||
void setFindLockFunction(const FindLockFunction& function);
|
||||
std::shared_ptr<Lock> getLock(const std::string& path) __attribute__((deprecated("Use file_mutex.h from TactilityKernel")));
|
||||
|
||||
long getSize(FILE* file);
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@ namespace tt::file {
|
||||
|
||||
/**
|
||||
* @param[in] path the path to find a lock for
|
||||
* @deprecated
|
||||
* @return a lock instance when a lock was found, otherwise nullptr
|
||||
*/
|
||||
std::shared_ptr<Lock> findLock(const std::string& path);
|
||||
std::shared_ptr<Lock> findLock(const std::string& path) __attribute__((deprecated("Use file_get_mutex() from TactilityKernel")));
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <tactility/hal/Device.h>
|
||||
#include <vector>
|
||||
|
||||
namespace tt::hal {
|
||||
|
||||
typedef bool (*InitBoot)();
|
||||
|
||||
typedef std::vector<std::shared_ptr<Device>> DeviceVector;
|
||||
|
||||
typedef std::shared_ptr<Device> (*CreateDevice)();
|
||||
|
||||
struct Configuration {
|
||||
/**
|
||||
* Used for powering on the peripherals manually.
|
||||
*/
|
||||
const InitBoot initBoot = nullptr;
|
||||
|
||||
const std::function<DeviceVector()> createDevices = [] { return DeviceVector(); };
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
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<touch::TouchDevice> 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<DisplayDriver> getDisplayDriver() = 0;
|
||||
};
|
||||
|
||||
} // namespace tt::hal::display
|
||||
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/Lock.h>
|
||||
#include <cstdint>
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/display/DisplayDriver.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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();
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
enum class GpsModel {
|
||||
Unknown = 0,
|
||||
AG3335,
|
||||
AG3352,
|
||||
ATGM336H, // Casic (might work with AT6558, Neoway N58 LTE Cat.1, Neoway G2, Neoway G7A)
|
||||
LS20031,
|
||||
MTK,
|
||||
MTK_L76B,
|
||||
MTK_PA1616S,
|
||||
UBLOX6,
|
||||
UBLOX7,
|
||||
UBLOX8,
|
||||
UBLOX9,
|
||||
UBLOX10,
|
||||
UC6580,
|
||||
};
|
||||
|
||||
const char* toString(GpsModel model);
|
||||
|
||||
std::vector<std::string> getModels();
|
||||
|
||||
struct GpsConfiguration {
|
||||
char uartName[32]; // e.g. "Internal" or "/dev/ttyUSB0"
|
||||
uint32_t baudRate;
|
||||
GpsModel model; // Choosing "Unknown" will result in a probe
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
#include "GpsConfiguration.h"
|
||||
#include "Satellites.h"
|
||||
|
||||
#include <Tactility/Thread.h>
|
||||
#include <Tactility/RecursiveMutex.h>
|
||||
|
||||
#include <minmea.h>
|
||||
#include <utility>
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
enum class GpsResponse {
|
||||
None,
|
||||
NotAck,
|
||||
FrameErrors,
|
||||
Ok,
|
||||
};
|
||||
|
||||
class GpsDevice : public Device {
|
||||
|
||||
public:
|
||||
|
||||
typedef int GgaSubscriptionId;
|
||||
typedef int RmcSubscriptionId;
|
||||
|
||||
enum class State {
|
||||
PendingOn,
|
||||
On,
|
||||
Error,
|
||||
PendingOff,
|
||||
Off
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
struct GgaSubscription {
|
||||
GgaSubscriptionId id;
|
||||
std::shared_ptr<std::function<void(Device::Id id, const minmea_sentence_gga&)>> onData;
|
||||
};
|
||||
|
||||
struct RmcSubscription {
|
||||
RmcSubscriptionId id;
|
||||
std::shared_ptr<std::function<void(Device::Id id, const minmea_sentence_rmc&)>> onData;
|
||||
};
|
||||
|
||||
const GpsConfiguration configuration;
|
||||
RecursiveMutex mutex;
|
||||
std::unique_ptr<Thread> thread;
|
||||
bool threadInterrupted = false;
|
||||
std::vector<GgaSubscription> ggaSubscriptions;
|
||||
std::vector<RmcSubscription> rmcSubscriptions;
|
||||
GgaSubscriptionId lastSatelliteSubscriptionId = 0;
|
||||
RmcSubscriptionId lastRmcSubscriptionId = 0;
|
||||
GpsModel model = GpsModel::Unknown;
|
||||
State state = State::Off;
|
||||
|
||||
int32_t threadMain();
|
||||
|
||||
bool isThreadInterrupted() const;
|
||||
|
||||
void setState(State newState);
|
||||
|
||||
public:
|
||||
|
||||
explicit GpsDevice(GpsConfiguration configuration) : configuration(std::move(configuration)) {}
|
||||
|
||||
~GpsDevice() override = default;
|
||||
|
||||
Type getType() const override { return Type::Gps; }
|
||||
|
||||
std::string getName() const override {
|
||||
if (model != GpsModel::Unknown) {
|
||||
return toString(model);
|
||||
} else {
|
||||
return "Unknown GPS";
|
||||
}
|
||||
}
|
||||
|
||||
std::string getDescription() const override { return ""; }
|
||||
|
||||
bool start();
|
||||
bool stop();
|
||||
|
||||
GgaSubscriptionId subscribeGga(const std::function<void(Device::Id deviceId, const minmea_sentence_gga&)>& onData) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
ggaSubscriptions.push_back({
|
||||
.id = ++lastSatelliteSubscriptionId,
|
||||
.onData = std::make_shared<std::function<void(Device::Id, const minmea_sentence_gga&)>>(onData)
|
||||
});
|
||||
return lastSatelliteSubscriptionId;
|
||||
}
|
||||
|
||||
void unsubscribeGga(GgaSubscriptionId subscriptionId) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
std::erase_if(ggaSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
|
||||
}
|
||||
|
||||
RmcSubscriptionId subscribeRmc(const std::function<void(Device::Id deviceId, const minmea_sentence_rmc&)>& onData) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
rmcSubscriptions.push_back({
|
||||
.id = ++lastRmcSubscriptionId,
|
||||
.onData = std::make_shared<std::function<void(Device::Id, const minmea_sentence_rmc&)>>(onData)
|
||||
});
|
||||
return lastRmcSubscriptionId;
|
||||
}
|
||||
|
||||
void unsubscribeRmc(RmcSubscriptionId subscriptionId) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
std::erase_if(rmcSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
|
||||
}
|
||||
|
||||
GpsModel getModel() const;
|
||||
|
||||
State getState() const;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/freertoscompat/RTOS.h>
|
||||
#include <Tactility/RecursiveMutex.h>
|
||||
|
||||
#include <minmea.h>
|
||||
|
||||
#include <ranges>
|
||||
#include <memory>
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
/** Thread-safe storage of recent satellites */
|
||||
class SatelliteStorage {
|
||||
|
||||
public:
|
||||
|
||||
static constexpr size_t recordCount = 32;
|
||||
|
||||
private:
|
||||
|
||||
struct SatelliteRecord {
|
||||
minmea_sat_info data {
|
||||
.nr = 0,
|
||||
.elevation = 0,
|
||||
.azimuth = 0,
|
||||
.snr = 0
|
||||
};
|
||||
TickType_t lastUpdated = 0;
|
||||
bool inUse = false;
|
||||
};
|
||||
|
||||
RecursiveMutex mutex;
|
||||
std::array<SatelliteRecord, recordCount> records;
|
||||
uint16_t recycleTimeSeconds;
|
||||
uint16_t recentTimeSeconds;
|
||||
|
||||
SatelliteRecord* findRecord(int number);
|
||||
|
||||
SatelliteRecord* findUnusedRecord();
|
||||
|
||||
SatelliteRecord* findRecordToRecycle();
|
||||
|
||||
/** Tries to find an existing record, otherwise return a free one, otherwise return the oldest active one */
|
||||
SatelliteRecord* findWithFallback(int number);
|
||||
|
||||
public:
|
||||
|
||||
explicit SatelliteStorage(
|
||||
uint16_t recycleTimeSeconds = 120,
|
||||
uint16_t recentTimeSeconds = 60
|
||||
) : recycleTimeSeconds(recycleTimeSeconds), recentTimeSeconds(recentTimeSeconds) {}
|
||||
|
||||
void notify(const minmea_sat_info& info);
|
||||
|
||||
void getRecords(const std::function<void(const minmea_sat_info&)>& onRecord) const;
|
||||
};
|
||||
|
||||
} // namespace tt::hal::gps
|
||||
@@ -1,49 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
#include <tactility/drivers/i2c_controller.h>
|
||||
|
||||
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
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
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 {};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/touch/TouchDriver.h>
|
||||
|
||||
#include <tactility/device.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/hal/Device.h>
|
||||
#include "TouchDriver.h"
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
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<TouchDriver> getTouchDriver() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -14,11 +14,11 @@ constexpr TickType_t defaultLockTime = 500 / portTICK_PERIOD_MS;
|
||||
* @warning when passing zero, we wait forever, as this is the default behaviour for esp_lvgl_port, and we want it to remain consistent
|
||||
* @deprecated Use lvgl_lock() or lvgl_try_lock() from lvgl-module instead.
|
||||
*/
|
||||
bool lock(TickType_t timeout = portMAX_DELAY);
|
||||
bool lock(TickType_t timeout = portMAX_DELAY) __attribute__((deprecated("Use lvgl_lock() from lvgl-module")));
|
||||
|
||||
/** @deprecated Use lvgl_unlock() from lvgl-module instead. */
|
||||
void unlock();
|
||||
void unlock() __attribute__((deprecated("Use lvgl_unlock() from lvgl-module")));
|
||||
|
||||
std::shared_ptr<Lock> getSyncLock();
|
||||
std::shared_ptr<Lock> getSyncLock() __attribute__((deprecated("Use lvgl locking functions from lvgl-module")));
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/PubSub.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/RecursiveMutex.h>
|
||||
#include <Tactility/hal/gps/GpsDevice.h>
|
||||
#include <Tactility/service/Service.h>
|
||||
#include <Tactility/service/ServiceContext.h>
|
||||
#include <Tactility/service/gps/GpsState.h>
|
||||
|
||||
namespace tt::service::gps {
|
||||
|
||||
class GpsService final : public Service {
|
||||
|
||||
struct GpsDeviceRecord {
|
||||
std::shared_ptr<hal::gps::GpsDevice> device = nullptr;
|
||||
hal::gps::GpsDevice::GgaSubscriptionId satelliteSubscriptionId = -1;
|
||||
hal::gps::GpsDevice::RmcSubscriptionId rmcSubscriptionId = -1;
|
||||
};
|
||||
|
||||
minmea_sentence_rmc rmcRecord;
|
||||
TickType_t rmcTime = 0;
|
||||
|
||||
minmea_sentence_gga ggaRecord;
|
||||
TickType_t ggaTime = 0;
|
||||
|
||||
RecursiveMutex mutex;
|
||||
Mutex stateMutex;
|
||||
std::vector<GpsDeviceRecord> deviceRecords;
|
||||
std::shared_ptr<PubSub<State>> statePubSub = std::make_shared<PubSub<State>>();
|
||||
std::unique_ptr<ServicePaths> paths;
|
||||
State state = State::Off;
|
||||
|
||||
bool startGpsDevice(GpsDeviceRecord& deviceRecord);
|
||||
static bool stopGpsDevice(GpsDeviceRecord& deviceRecord);
|
||||
|
||||
/** return nullptr when not found */
|
||||
GpsDeviceRecord* findGpsRecord(const std::shared_ptr<hal::gps::GpsDevice>& record);
|
||||
|
||||
void onGgaSentence(hal::Device::Id deviceId, const minmea_sentence_gga& gga);
|
||||
void onRmcSentence(hal::Device::Id deviceId, const minmea_sentence_rmc& rmc);
|
||||
|
||||
void setState(State newState);
|
||||
|
||||
void addGpsDevice(const std::shared_ptr<hal::gps::GpsDevice>& device);
|
||||
void removeGpsDevice(const std::shared_ptr<hal::gps::GpsDevice>& device);
|
||||
|
||||
bool getConfigurationFilePath(std::string& output) const;
|
||||
|
||||
public:
|
||||
|
||||
bool onStart(ServiceContext &serviceContext) override;
|
||||
void onStop(ServiceContext &serviceContext) override;
|
||||
|
||||
bool addGpsConfiguration(hal::gps::GpsConfiguration configuration);
|
||||
bool removeGpsConfiguration(hal::gps::GpsConfiguration configuration);
|
||||
bool getGpsConfigurations(std::vector<hal::gps::GpsConfiguration>& configurations) const;
|
||||
|
||||
bool startReceiving();
|
||||
void stopReceiving();
|
||||
State getState() const;
|
||||
|
||||
bool hasCoordinates() const;
|
||||
bool getCoordinates(minmea_sentence_rmc& rmc) const;
|
||||
bool getGga(minmea_sentence_gga& gga) const;
|
||||
|
||||
/** @return GPS service pubsub that broadcasts State* objects */
|
||||
std::shared_ptr<PubSub<State>> getStatePubsub() const { return statePubSub; }
|
||||
};
|
||||
|
||||
std::shared_ptr<GpsService> findGpsService();
|
||||
|
||||
} // tt::service::gps
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace tt::service::gps {
|
||||
|
||||
enum class State {
|
||||
OnPending,
|
||||
On,
|
||||
OffPending,
|
||||
Off
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <minmea.h>
|
||||
|
||||
namespace tt::hal::gps {
|
||||
|
||||
/** @return true when the input float is valid (contains non-zero values) */
|
||||
inline bool isValid(const minmea_float& inFloat) { return inFloat.value != 0 && inFloat.scale != 0; }
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user