139 lines
3.5 KiB
C++
139 lines
3.5 KiB
C++
#include "Tactility/hal/radio/RadioDevice.h"
|
|
#include <cstring>
|
|
|
|
namespace tt::hal::radio {
|
|
|
|
constexpr const char* TAG = "RadioDevice";
|
|
|
|
bool RadioDevice::start(const Modulation modulation) {
|
|
auto lock = mutex.asScopedLock();
|
|
|
|
if (!isCapableOf(modulation)) {
|
|
TT_LOG_E(TAG, "Can't start device \"%s\", not capable of modulation \"%s\"", getName().c_str(), toString(modulation));
|
|
return false;
|
|
}
|
|
|
|
lock.lock();
|
|
|
|
if (thread != nullptr && thread->getState() != Thread::State::Stopped) {
|
|
TT_LOG_W(TAG, "Already started");
|
|
return true;
|
|
}
|
|
|
|
threadInterrupted = false;
|
|
|
|
TT_LOG_I(TAG, "Starting thread");
|
|
setState(State::PendingOn);
|
|
|
|
thread = std::make_unique<Thread>(
|
|
threadName,
|
|
threadSize,
|
|
[this, modulation]() {
|
|
return this->threadMain(modulation);
|
|
}
|
|
);
|
|
thread->setPriority(tt::Thread::Priority::High);
|
|
thread->start();
|
|
|
|
TT_LOG_I(TAG, "Starting finished");
|
|
return true;
|
|
}
|
|
|
|
bool RadioDevice::stop() {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
|
|
setState(State::PendingOff);
|
|
|
|
if (thread != nullptr) {
|
|
threadInterrupted = true;
|
|
getEventFlag().set(RADIO_TERMINATE_BIT);
|
|
|
|
// Detach thread, it will auto-delete when leaving the current scope
|
|
auto old_thread = std::move(thread);
|
|
|
|
if (old_thread->getState() != Thread::State::Stopped) {
|
|
// Unlock so thread can lock
|
|
lock.unlock();
|
|
// Wait for thread to finish
|
|
old_thread->join();
|
|
// Re-lock to continue logic below
|
|
lock.lock();
|
|
}
|
|
}
|
|
|
|
setState(State::Off);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool RadioDevice::isThreadInterrupted() const {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
return threadInterrupted;
|
|
}
|
|
|
|
RadioDevice::State RadioDevice::getState() const {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
return state; // Make copy because of thread safety
|
|
}
|
|
|
|
void RadioDevice::setState(State newState) {
|
|
auto lock = mutex.asScopedLock();
|
|
lock.lock();
|
|
state = newState;
|
|
}
|
|
|
|
void RadioDevice::publishRx(const RxPacket& packet) {
|
|
mutex.lock();
|
|
for (auto& subscription : rxSubscriptions) {
|
|
(*subscription.onData)(getId(), packet);
|
|
}
|
|
mutex.unlock();
|
|
}
|
|
|
|
const char* toString(RadioDevice::Modulation modulation) {
|
|
using enum RadioDevice::Modulation;
|
|
switch (modulation) {
|
|
case Fsk:
|
|
return "FSK";
|
|
case LoRa:
|
|
return "LoRa";
|
|
case LrFhss:
|
|
return "LR-FHSS";
|
|
default:
|
|
return "Unkown";
|
|
}
|
|
}
|
|
|
|
const char* toString(RadioDevice::Parameter parameter) {
|
|
using enum RadioDevice::Parameter;
|
|
switch (parameter) {
|
|
case Power:
|
|
return TT_STRINGIFY(Power);
|
|
case Frequency:
|
|
return TT_STRINGIFY(Frequency);
|
|
case Bandwidth:
|
|
return TT_STRINGIFY(Bandwidth);
|
|
case SpreadFactor:
|
|
return TT_STRINGIFY(SpreadFactor);
|
|
case CodingRate:
|
|
return TT_STRINGIFY(CodingRate);
|
|
case SyncWord:
|
|
return TT_STRINGIFY(SyncWord);
|
|
case PreambleLength:
|
|
return TT_STRINGIFY(PreambleLength);
|
|
case FrequencyDeviation:
|
|
return TT_STRINGIFY(FrequencyDeviation);
|
|
case DataRate:
|
|
return TT_STRINGIFY(DataRate);
|
|
case AddressWidth:
|
|
return TT_STRINGIFY(AddressWidth);
|
|
default:
|
|
return "Unknown";
|
|
}
|
|
}
|
|
|
|
} // namespace tt::hal::radio
|