Radio: Refactor RadioDevice thread into compat class
This commit is contained in:
parent
c705359427
commit
98c9fb7201
99
Drivers/RadioLibCompat/Source/RadiolibThreadedDevice.cpp
Normal file
99
Drivers/RadioLibCompat/Source/RadiolibThreadedDevice.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "RadiolibThreadedDevice.h"
|
||||
#include <cstring>
|
||||
|
||||
constexpr const char* TAG = "RadiolibThreadedDevice";
|
||||
|
||||
bool RadiolibThreadedDevice::start(const Modulation modulation) {
|
||||
auto lock = getMutex().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() != tt::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<tt::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 RadiolibThreadedDevice::stop() {
|
||||
auto lock = getMutex().asScopedLock();
|
||||
lock.lock();
|
||||
|
||||
setState(State::PendingOff);
|
||||
|
||||
if (thread != nullptr) {
|
||||
threadInterrupted = true;
|
||||
interruptSignal();
|
||||
|
||||
// Detach thread, it will auto-delete when leaving the current scope
|
||||
auto old_thread = std::move(thread);
|
||||
|
||||
if (old_thread->getState() != tt::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 RadiolibThreadedDevice::isThreadInterrupted() const {
|
||||
auto lock = getMutex().asScopedLock();
|
||||
lock.lock();
|
||||
return threadInterrupted;
|
||||
}
|
||||
|
||||
int32_t RadiolibThreadedDevice::threadMain(const Modulation modulation) {
|
||||
|
||||
int rc = doBegin(modulation);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
setState(State::On);
|
||||
|
||||
while (!isThreadInterrupted()) {
|
||||
doListen();
|
||||
|
||||
// Thread might've been interrupted in the meanwhile
|
||||
if (isThreadInterrupted()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (getTxQueueSize() > 0) {
|
||||
doTransmit();
|
||||
} else {
|
||||
doReceive();
|
||||
}
|
||||
}
|
||||
|
||||
doEnd();
|
||||
return 0;
|
||||
}
|
||||
37
Drivers/RadioLibCompat/Source/RadiolibThreadedDevice.h
Normal file
37
Drivers/RadioLibCompat/Source/RadiolibThreadedDevice.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/radio/RadioDevice.h>
|
||||
#include <Tactility/Thread.h>
|
||||
|
||||
class RadiolibThreadedDevice : public tt::hal::radio::RadioDevice {
|
||||
|
||||
private:
|
||||
std::string threadName;
|
||||
size_t threadSize;
|
||||
std::unique_ptr<tt::Thread> _Nullable thread;
|
||||
bool threadInterrupted = false;
|
||||
|
||||
protected:
|
||||
virtual int32_t threadMain(const Modulation modulation);
|
||||
bool isThreadInterrupted() const;
|
||||
|
||||
virtual void interruptSignal() = 0;
|
||||
|
||||
virtual int doBegin(const Modulation modulation) = 0;
|
||||
virtual void doEnd() = 0;
|
||||
virtual void doTransmit() = 0;
|
||||
virtual void doListen() = 0;
|
||||
virtual void doReceive() = 0;
|
||||
|
||||
public:
|
||||
explicit RadiolibThreadedDevice(const std::string& threadName, const size_t threadSize)
|
||||
: threadName(threadName)
|
||||
, threadSize(threadSize)
|
||||
{}
|
||||
|
||||
~RadiolibThreadedDevice() override = default;
|
||||
|
||||
virtual bool start(const Modulation modulation) override;
|
||||
virtual bool stop() override;
|
||||
|
||||
};
|
||||
@ -83,36 +83,21 @@ void Sx1262::unregisterDio1Isr() {
|
||||
gpio_wakeup_disable(configuration.irqPin);
|
||||
gpio_set_intr_type(configuration.irqPin, GPIO_INTR_DISABLE);
|
||||
}
|
||||
/*
|
||||
void IRAM_ATTR Sx1262::dio1Event() {
|
||||
static const auto DRAM_ATTR rxbit = RADIO_RECEIVED_BIT;
|
||||
static const auto DRAM_ATTR txbit = RADIO_TRANSMITTED_BIT;
|
||||
|
||||
switch (exchangeState) {
|
||||
case ExchangeState::Receive:
|
||||
getEventFlag().set(rxbit);
|
||||
break;
|
||||
case ExchangeState::TransmitWaiting:
|
||||
getEventFlag().set(txbit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gpio_set_level(GPIO_NUM_9, 1);
|
||||
}*/
|
||||
|
||||
|
||||
void IRAM_ATTR Sx1262::dio1Event() {
|
||||
static const auto DRAM_ATTR bit = SX1262_DIO1_EVENT_BIT;
|
||||
getEventFlag().set(bit);
|
||||
|
||||
gpio_set_level(GPIO_NUM_9, 1);
|
||||
events.set(bit);
|
||||
}
|
||||
|
||||
int32_t Sx1262::threadMain(const Modulation modulation) {
|
||||
using enum ExchangeState;
|
||||
void Sx1262::txQueuedSignal() {
|
||||
events.set(SX1262_QUEUED_TX_BIT);
|
||||
}
|
||||
|
||||
void Sx1262::interruptSignal() {
|
||||
events.set(SX1262_INTERRUPT_BIT);
|
||||
}
|
||||
|
||||
int Sx1262::doBegin(const Modulation modulation) {
|
||||
uint16_t rc = RADIOLIB_ERR_NONE;
|
||||
|
||||
if (modulation == Modulation::LoRa) {
|
||||
@ -127,13 +112,6 @@ int32_t Sx1262::threadMain(const Modulation modulation) {
|
||||
configuration.tcxoVoltage,
|
||||
configuration.useRegulatorLdo
|
||||
);
|
||||
/*
|
||||
radio.forceLDRO(false);
|
||||
radio.setCRC(true);
|
||||
radio.invertIQ(false);
|
||||
radio.setWhitening(true, 0x00FF);
|
||||
radio.explicitHeader();*/
|
||||
|
||||
} else if (modulation == Modulation::Fsk) {
|
||||
rc = radio.beginFSK(
|
||||
frequency,
|
||||
@ -158,79 +136,69 @@ int32_t Sx1262::threadMain(const Modulation modulation) {
|
||||
}
|
||||
|
||||
registerDio1Isr();
|
||||
setState(State::On);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TT_LOG_I(TAG, "SX1262 device ready to receive!");
|
||||
exchangeState = Receive;
|
||||
void Sx1262::doEnd() {
|
||||
unregisterDio1Isr();
|
||||
}
|
||||
|
||||
while (!isThreadInterrupted()) {
|
||||
radio.startReceive();
|
||||
TT_LOG_I(TAG, "WAIT FLAG");
|
||||
auto eventFlags = getEventFlag().wait(RADIO_TERMINATE_BIT | SX1262_DIO1_EVENT_BIT | RADIO_TRANSMIT_QUEUED_BIT);
|
||||
TT_LOG_W(TAG, "Event, flag=%X", eventFlags);
|
||||
void Sx1262::doTransmit() {
|
||||
currentTx = popNextQueuedTx();
|
||||
radio.standby();
|
||||
uint16_t rc = radio.startTransmit(currentTx.packet.data.data(), currentTx.packet.data.size());
|
||||
if (rc == RADIOLIB_ERR_NONE) {
|
||||
currentTx.callback(currentTx.id, TransmissionState::PendingTransmit);
|
||||
|
||||
TT_LOG_I(TAG, "WAIT TX FLAG");
|
||||
auto txEventFlags = events.wait(SX1262_INTERRUPT_BIT | SX1262_DIO1_EVENT_BIT, tt::EventFlag::WaitAny, pdMS_TO_TICKS(2000));
|
||||
TT_LOG_W(TAG, "Event, flag=%X", txEventFlags);
|
||||
|
||||
// Thread might've been interrupted in the meanwhile
|
||||
if (isThreadInterrupted()) {
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((eventFlags & RADIO_TRANSMIT_QUEUED_BIT) && (getTxQueueSize() > 0)) {
|
||||
currentTx = popNextQueuedTx();
|
||||
radio.standby();
|
||||
uint16_t rc = radio.startTransmit(currentTx.packet.data.data(), currentTx.packet.data.size());
|
||||
if (rc == RADIOLIB_ERR_NONE) {
|
||||
exchangeState = TransmitWaiting;
|
||||
currentTx.callback(currentTx.id, TransmissionState::PendingTransmit);
|
||||
|
||||
TT_LOG_I(TAG, "WAIT TX FLAG");
|
||||
auto txEventFlags = getEventFlag().wait(RADIO_TERMINATE_BIT | SX1262_DIO1_EVENT_BIT, tt::EventFlag::WaitAny, pdMS_TO_TICKS(2000));
|
||||
TT_LOG_W(TAG, "Event, flag=%X", txEventFlags);
|
||||
|
||||
// Thread might've been interrupted in the meanwhile
|
||||
if (isThreadInterrupted()) {
|
||||
break;
|
||||
}
|
||||
if (txEventFlags & SX1262_DIO1_EVENT_BIT) {
|
||||
currentTx.callback(currentTx.id, TransmissionState::Transmitted);
|
||||
} else {
|
||||
currentTx.callback(currentTx.id, TransmissionState::Timeout);
|
||||
}
|
||||
exchangeState = Receive;
|
||||
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Error transmitting id=%d, rc=%hi", currentTx.id, rc);
|
||||
currentTx.callback(currentTx.id, TransmissionState::Error);
|
||||
exchangeState = Receive;
|
||||
}
|
||||
} else if (eventFlags & SX1262_DIO1_EVENT_BIT) {
|
||||
uint16_t rxSize = radio.getPacketLength(true);
|
||||
std::vector<uint8_t> data(rxSize);
|
||||
uint16_t rc = radio.readData(data.data(), rxSize);
|
||||
if (rc != RADIOLIB_ERR_NONE) {
|
||||
TT_LOG_E(TAG, "Error receiving data, RadioLib returned %hi", rc);
|
||||
} else if(rxSize == 0) {
|
||||
//TT_LOG_W(TAG, "Received data length 0");
|
||||
} else {
|
||||
float rssi = radio.getRSSI();
|
||||
float snr = radio.getSNR();
|
||||
TT_LOG_I(TAG, "LoRa RX size=%d RSSI=%f SNR=%f", rxSize, rssi, snr);
|
||||
auto rxPacket = tt::hal::radio::RxPacket {
|
||||
.data = data,
|
||||
.rssi = rssi,
|
||||
.snr = snr
|
||||
};
|
||||
|
||||
publishRx(rxPacket);
|
||||
}
|
||||
|
||||
// A delay is needed before a new command
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
gpio_set_level(GPIO_NUM_9, 0);
|
||||
if (txEventFlags & SX1262_DIO1_EVENT_BIT) {
|
||||
currentTx.callback(currentTx.id, TransmissionState::Transmitted);
|
||||
} else {
|
||||
TT_LOG_W(TAG, "Unhandled event, flag=%X", eventFlags);
|
||||
currentTx.callback(currentTx.id, TransmissionState::Timeout);
|
||||
}
|
||||
|
||||
} else {
|
||||
TT_LOG_E(TAG, "Error transmitting id=%d, rc=%hi", currentTx.id, rc);
|
||||
currentTx.callback(currentTx.id, TransmissionState::Error);
|
||||
}
|
||||
}
|
||||
|
||||
void Sx1262::doListen() {
|
||||
radio.startReceive();
|
||||
TT_LOG_I(TAG, "WAIT FLAG");
|
||||
auto eventFlags = events.wait(SX1262_INTERRUPT_BIT | SX1262_DIO1_EVENT_BIT | SX1262_QUEUED_TX_BIT);
|
||||
TT_LOG_W(TAG, "Event, flag=%X", eventFlags);
|
||||
}
|
||||
|
||||
void Sx1262::doReceive() {
|
||||
uint16_t rxSize = radio.getPacketLength(true);
|
||||
std::vector<uint8_t> data(rxSize);
|
||||
uint16_t rc = radio.readData(data.data(), rxSize);
|
||||
if (rc != RADIOLIB_ERR_NONE) {
|
||||
TT_LOG_E(TAG, "Error receiving data, RadioLib returned %hi", rc);
|
||||
} else if(rxSize == 0) {
|
||||
//TT_LOG_W(TAG, "Received data length 0");
|
||||
} else {
|
||||
float rssi = radio.getRSSI();
|
||||
float snr = radio.getSNR();
|
||||
TT_LOG_I(TAG, "LoRa RX size=%d RSSI=%f SNR=%f", rxSize, rssi, snr);
|
||||
auto rxPacket = tt::hal::radio::RxPacket {
|
||||
.data = data,
|
||||
.rssi = rssi,
|
||||
.snr = snr
|
||||
};
|
||||
|
||||
publishRx(rxPacket);
|
||||
}
|
||||
|
||||
unregisterDio1Isr();
|
||||
return 0;
|
||||
// A delay is needed before a new command
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/hal/radio/RadioDevice.h>
|
||||
#include <Tactility/hal/spi/Spi.h>
|
||||
#include <Tactility/EventFlag.h>
|
||||
#include <Tactility/Lock.h>
|
||||
|
||||
#include <RadioLib.h>
|
||||
#include "RadiolibTactilityHal.h"
|
||||
#include "RadiolibThreadedDevice.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
class Sx1262 final : public tt::hal::radio::RadioDevice {
|
||||
class Sx1262 final : public RadiolibThreadedDevice {
|
||||
|
||||
public:
|
||||
struct Configuration {
|
||||
@ -23,23 +25,18 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
static constexpr auto SX1262_DIO1_EVENT_BIT = BIT8;
|
||||
|
||||
enum class ExchangeState {
|
||||
Idle,
|
||||
Receive,
|
||||
//TransmitInitiated,
|
||||
TransmitWaiting
|
||||
};
|
||||
static constexpr auto SX1262_INTERRUPT_BIT = BIT0;
|
||||
static constexpr auto SX1262_DIO1_EVENT_BIT = BIT1;
|
||||
static constexpr auto SX1262_QUEUED_TX_BIT = BIT2;
|
||||
|
||||
std::string name;
|
||||
const Configuration configuration;
|
||||
std::shared_ptr<tt::Lock> lock;
|
||||
tt::EventFlag events;
|
||||
RadiolibTactilityHal hal;
|
||||
Module radioModule;
|
||||
SX1262 radio;
|
||||
TxItem currentTx;
|
||||
ExchangeState exchangeState;
|
||||
|
||||
int8_t power = 0;
|
||||
float frequency = 0.0;
|
||||
@ -51,20 +48,29 @@ private:
|
||||
float bitRate = 0.0;
|
||||
float frequencyDeviation = 0.0;
|
||||
|
||||
int32_t threadMain();
|
||||
void registerDio1Isr();
|
||||
void unregisterDio1Isr();
|
||||
|
||||
protected:
|
||||
virtual void txQueuedSignal() override;
|
||||
virtual void interruptSignal() override;
|
||||
|
||||
virtual int doBegin(const Modulation modulation) override;
|
||||
virtual void doEnd() override;
|
||||
virtual void doTransmit() override;
|
||||
virtual void doListen() override;
|
||||
virtual void doReceive() override;
|
||||
|
||||
public:
|
||||
|
||||
explicit Sx1262(const std::string& name, const Configuration& configuration, std::shared_ptr<tt::Lock> lock = nullptr)
|
||||
: RadioDevice(name, 4096)
|
||||
: RadiolibThreadedDevice(name, 4096)
|
||||
, name(name)
|
||||
, configuration(configuration)
|
||||
, hal(configuration.spiHostDevice, configuration.spiFrequency, configuration.csPin, lock)
|
||||
, radioModule(&hal, configuration.csPin, configuration.irqPin, configuration.resetPin, configuration.busyPin)
|
||||
, radio(&radioModule)
|
||||
, exchangeState(ExchangeState::Idle) {}
|
||||
{}
|
||||
|
||||
~Sx1262() override = default;
|
||||
|
||||
@ -78,12 +84,5 @@ public:
|
||||
return (modulation == Modulation::Fsk) || (modulation == Modulation::LoRa);
|
||||
}
|
||||
|
||||
bool hasReceived();
|
||||
|
||||
void dio1Event();
|
||||
//void IRAM_ATTR setRxEvent() { rxFlag = true; }
|
||||
|
||||
protected:
|
||||
|
||||
int32_t threadMain(const Modulation modulation) override;
|
||||
};
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
|
||||
#include "../Device.h"
|
||||
|
||||
#include <Tactility/EventFlag.h>
|
||||
#include <Tactility/Lock.h>
|
||||
#include <Tactility/Mutex.h>
|
||||
#include <Tactility/Thread.h>
|
||||
|
||||
@ -80,31 +78,19 @@ private:
|
||||
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;
|
||||
std::deque<TxItem> txQueue;
|
||||
TxId lastTxId = 0;
|
||||
RxSubscriptionId lastRxSubscriptionId = 0;
|
||||
|
||||
protected:
|
||||
|
||||
static constexpr auto RADIO_TERMINATE_BIT = BIT0;
|
||||
static constexpr auto RADIO_TRANSMIT_QUEUED_BIT = BIT1;
|
||||
static constexpr auto RADIO_RECEIVED_BIT = BIT2;
|
||||
static constexpr auto RADIO_TRANSMITTED_BIT = BIT3;
|
||||
|
||||
virtual int32_t threadMain(const Modulation modulation) = 0;
|
||||
Mutex &getMutex() { return mutex; }
|
||||
EventFlag &getEventFlag() { return events; }
|
||||
bool isThreadInterrupted() const;
|
||||
const Mutex &getMutex() const { return mutex; }
|
||||
void setState(State newState);
|
||||
|
||||
virtual void txQueuedSignal() = 0;
|
||||
|
||||
size_t getTxQueueSize() const {
|
||||
auto lock = mutex.asScopedLock();
|
||||
lock.lock();
|
||||
@ -125,10 +111,8 @@ protected:
|
||||
void publishRx(const RxPacket& packet);
|
||||
|
||||
public:
|
||||
explicit RadioDevice(const std::string& threadName, const size_t threadSize)
|
||||
: threadName(threadName)
|
||||
, threadSize(threadSize)
|
||||
, state(State::Off) {}
|
||||
explicit RadioDevice()
|
||||
: state(State::Off) {}
|
||||
|
||||
~RadioDevice() override = default;
|
||||
|
||||
@ -137,8 +121,8 @@ public:
|
||||
virtual bool configure(const Parameter parameter, const float value) = 0;
|
||||
virtual bool isCapableOf(const Modulation modulation) = 0;
|
||||
|
||||
bool start(const Modulation modulation);
|
||||
bool stop();
|
||||
virtual bool start(const Modulation modulation) = 0;
|
||||
virtual bool stop() = 0;
|
||||
|
||||
TxId transmit(const TxPacket& packet, TxStateCallback callback) {
|
||||
auto lock = mutex.asScopedLock();
|
||||
@ -147,7 +131,7 @@ public:
|
||||
txQueue.push_back(TxItem{.id = txId, .packet = packet, .callback = callback});
|
||||
callback(txId, TransmissionState::Queued);
|
||||
lastTxId++;
|
||||
getEventFlag().set(RADIO_TRANSMIT_QUEUED_BIT);
|
||||
txQueuedSignal();
|
||||
return txId;
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +60,7 @@ namespace app {
|
||||
namespace boot { extern const AppManifest manifest; }
|
||||
namespace calculator { extern const AppManifest manifest; }
|
||||
namespace chat { extern const AppManifest manifest; }
|
||||
namespace chirp { extern const AppManifest manifest; }
|
||||
namespace development { extern const AppManifest manifest; }
|
||||
namespace display { extern const AppManifest manifest; }
|
||||
namespace files { extern const AppManifest manifest; }
|
||||
@ -121,6 +122,7 @@ static void registerSystemApps() {
|
||||
addApp(app::wifiapsettings::manifest);
|
||||
addApp(app::wificonnect::manifest);
|
||||
addApp(app::wifimanage::manifest);
|
||||
addApp(app::chirp::manifest);
|
||||
|
||||
#if defined(CONFIG_TINYUSB_MSC_ENABLED) && CONFIG_TINYUSB_MSC_ENABLED
|
||||
addApp(app::usbsettings::manifest);
|
||||
|
||||
@ -5,74 +5,6 @@ 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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user