Ken Van Hoeylandt 14e459e50f
GPS implementation (#216)
Implemented basic GPS support:
- GPS HAL
- GPS Service
- GPS Settings app
2025-02-11 23:46:52 +01:00

100 lines
3.0 KiB
C++

#pragma once
#include "../Device.h"
#include "../uart/Uart.h"
#include "GpsDeviceInitDefault.h"
#include "Satellites.h"
#include <Tactility/Mutex.h>
#include <Tactility/Thread.h>
#include <minmea.h>
#include <utility>
namespace tt::hal::gps {
class GpsDevice : public Device {
public:
typedef int SatelliteSubscriptionId;
typedef int LocationSubscriptionId;
struct Configuration {
std::string name;
uart_port_t uartPort;
uint32_t baudRate;
std::function<bool(uart_port_t)> initFunction = initGpsDefault;
};
private:
struct SatelliteSubscription {
SatelliteSubscriptionId id;
std::shared_ptr<std::function<void(Device::Id id, const minmea_sat_info&)>> onData;
};
struct LocationSubscription {
LocationSubscriptionId id;
std::shared_ptr<std::function<void(Device::Id id, const minmea_sentence_rmc&)>> onData;
};
const Configuration configuration;
Mutex mutex;
std::unique_ptr<Thread> thread;
bool threadInterrupted = false;
std::vector<SatelliteSubscription> satelliteSubscriptions;
std::vector<LocationSubscription> locationSubscriptions;
SatelliteSubscriptionId lastSatelliteSubscriptionId = 0;
LocationSubscriptionId lastLocationSubscriptionId = 0;
static int32_t threadMainStatic(void* parameter);
int32_t threadMain();
bool isThreadInterrupted() const;
public:
explicit GpsDevice(Configuration configuration) : configuration(std::move(configuration)) {
assert(this->configuration.initFunction != nullptr);
}
~GpsDevice() override = default;
Type getType() const override { return Type::Gps; }
std::string getName() const override { return configuration.name; }
std::string getDescription() const override { return ""; }
bool start();
bool stop();
bool isStarted() const;
SatelliteSubscriptionId subscribeSatellites(const std::function<void(Device::Id deviceId, const minmea_sat_info&)>& onData) {
satelliteSubscriptions.push_back({
.id = ++lastSatelliteSubscriptionId,
.onData = std::make_shared<std::function<void(Device::Id, const minmea_sat_info&)>>(onData)
});
return lastSatelliteSubscriptionId;
}
void unsubscribeSatellites(SatelliteSubscriptionId subscriptionId) {
std::erase_if(satelliteSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
}
LocationSubscriptionId subscribeLocations(const std::function<void(Device::Id deviceId, const minmea_sentence_rmc&)>& onData) {
locationSubscriptions.push_back({
.id = ++lastLocationSubscriptionId,
.onData = std::make_shared<std::function<void(Device::Id, const minmea_sentence_rmc&)>>(onData)
});
return lastLocationSubscriptionId;
}
void unsubscribeLocations(SatelliteSubscriptionId subscriptionId) {
std::erase_if(locationSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
}
};
}