119 lines
2.9 KiB
C++
119 lines
2.9 KiB
C++
#pragma once
|
|
|
|
#include "../Device.h"
|
|
#include <Tactility/EventFlag.h>
|
|
#include <Tactility/Lock.h>
|
|
#include <Tactility/Mutex.h>
|
|
#include <Tactility/Thread.h>
|
|
#include <utility>
|
|
|
|
namespace tt::hal::radio {
|
|
|
|
struct RxPacket {
|
|
uint8_t const *data;
|
|
size_t const size;
|
|
float rssi;
|
|
float snr;
|
|
};
|
|
|
|
class RadioDevice : public Device {
|
|
|
|
public:
|
|
|
|
enum class Modulation {
|
|
Fsk,
|
|
LoRa
|
|
};
|
|
|
|
enum class Parameter {
|
|
Power,
|
|
Frequency,
|
|
Bandwidth,
|
|
SpreadFactor,
|
|
CodingRate,
|
|
SyncWord,
|
|
PreambleLength,
|
|
FrequencyDeviation,
|
|
DataRate,
|
|
AddressWidth
|
|
};
|
|
|
|
typedef int RxSubscriptionId;
|
|
|
|
enum class State {
|
|
PendingOn,
|
|
On,
|
|
Error,
|
|
PendingOff,
|
|
Off
|
|
};
|
|
|
|
private:
|
|
|
|
struct RxSubscription {
|
|
RxSubscriptionId id;
|
|
std::shared_ptr<std::function<void(Device::Id id, const RxPacket&)>> onData;
|
|
};
|
|
|
|
std::string threadName;
|
|
size_t threadSize;
|
|
State state;
|
|
EventFlag events;
|
|
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
|
std::unique_ptr<Thread> _Nullable thread;
|
|
bool threadInterrupted = false;
|
|
std::vector<RxSubscription> rxSubscriptions;
|
|
RxSubscriptionId lastRxSubscriptionId = 0;
|
|
|
|
protected:
|
|
|
|
static constexpr auto RADIO_TERMINATE_BIT = BIT0;
|
|
static constexpr auto RADIO_RECEIVED_BIT = BIT1;
|
|
|
|
virtual int32_t threadMain(const Modulation modulation) = 0;
|
|
Mutex &getMutex() { return mutex; }
|
|
EventFlag &getEventFlag() { return events; }
|
|
bool isThreadInterrupted() const;
|
|
void setState(State newState);
|
|
|
|
void publishRx(const RxPacket& packet);
|
|
|
|
public:
|
|
explicit RadioDevice(const std::string& threadName, const size_t threadSize)
|
|
: threadName(threadName)
|
|
, threadSize(threadSize)
|
|
, state(State::Off) {}
|
|
|
|
~RadioDevice() override = default;
|
|
|
|
Type getType() const override { return Type::Radio; }
|
|
|
|
virtual bool configure(const Parameter parameter, const float value) = 0;
|
|
virtual bool isCapableOf(const Modulation modulation) = 0;
|
|
|
|
bool start(const Modulation modulation);
|
|
bool stop();
|
|
|
|
RxSubscriptionId subscribeRx(const std::function<void(Device::Id id, const RxPacket&)>& onData) {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
rxSubscriptions.push_back({
|
|
.id = ++lastRxSubscriptionId,
|
|
.onData = std::make_shared<std::function<void(Device::Id, const RxPacket&)>>(onData)
|
|
});
|
|
return lastRxSubscriptionId;
|
|
}
|
|
|
|
void unsubscribeRx(RxSubscriptionId subscriptionId) {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
std::erase_if(rxSubscriptions, [subscriptionId](auto& subscription) { return subscription.id == subscriptionId; });
|
|
}
|
|
|
|
State getState() const;
|
|
};
|
|
|
|
const char* toString(RadioDevice::Modulation modulation);
|
|
const char* toString(RadioDevice::Parameter parameter);
|
|
}
|