SDRThread read/write setting support
This commit is contained in:
parent
c7ecc5f1f6
commit
97cf6c4b23
|
@ -296,6 +296,9 @@ void CubicSDR::removeRemote(std::string remoteAddr) {
|
||||||
|
|
||||||
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
|
void CubicSDR::sdrThreadNotify(SDRThread::SDRThreadState state, std::string message) {
|
||||||
notify_busy.lock();
|
notify_busy.lock();
|
||||||
|
if (state == SDRThread::SDR_THREAD_INITIALIZED) {
|
||||||
|
appframe->initDeviceParams(getDevice());
|
||||||
|
}
|
||||||
if (state == SDRThread::SDR_THREAD_MESSAGE) {
|
if (state == SDRThread::SDR_THREAD_MESSAGE) {
|
||||||
notifyMessage = message;
|
notifyMessage = message;
|
||||||
}
|
}
|
||||||
|
@ -422,8 +425,6 @@ void CubicSDR::setDevice(SDRDeviceInfo *dev) {
|
||||||
setOffset(devConfig->getOffset());
|
setOffset(devConfig->getOffset());
|
||||||
|
|
||||||
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||||
|
|
||||||
appframe->initDeviceParams(dev);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,6 +464,11 @@ SDRPostThread *CubicSDR::getSDRPostThread() {
|
||||||
return sdrPostThread;
|
return sdrPostThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDRThread *CubicSDR::getSDRThread() {
|
||||||
|
return sdrThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CubicSDR::bindDemodulator(DemodulatorInstance *demod) {
|
void CubicSDR::bindDemodulator(DemodulatorInstance *demod) {
|
||||||
if (!demod) {
|
if (!demod) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -76,6 +76,7 @@ public:
|
||||||
DemodulatorMgr &getDemodMgr();
|
DemodulatorMgr &getDemodMgr();
|
||||||
|
|
||||||
SDRPostThread *getSDRPostThread();
|
SDRPostThread *getSDRPostThread();
|
||||||
|
SDRThread *getSDRThread();
|
||||||
|
|
||||||
void bindDemodulator(DemodulatorInstance *demod);
|
void bindDemodulator(DemodulatorInstance *demod);
|
||||||
void removeDemodulator(DemodulatorInstance *demod);
|
void removeDemodulator(DemodulatorInstance *demod);
|
||||||
|
|
|
@ -31,6 +31,7 @@ SDRThread::SDRThread() : IOThread() {
|
||||||
agc_mode.store(true);
|
agc_mode.store(true);
|
||||||
agc_mode_changed.store(false);
|
agc_mode_changed.store(false);
|
||||||
gain_value_changed.store(false);
|
gain_value_changed.store(false);
|
||||||
|
setting_value_changed.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDRThread::~SDRThread() {
|
SDRThread::~SDRThread() {
|
||||||
|
@ -81,6 +82,30 @@ void SDRThread::init() {
|
||||||
inpBuffer.data.resize(numElems.load());
|
inpBuffer.data.resize(numElems.load());
|
||||||
|
|
||||||
buffs[0] = malloc(numElems * 2 * sizeof(float));
|
buffs[0] = malloc(numElems * 2 * sizeof(float));
|
||||||
|
|
||||||
|
SoapySDR::ArgInfoList settingsInfo = device->getSettingInfo();
|
||||||
|
SoapySDR::ArgInfoList::const_iterator settings_i;
|
||||||
|
|
||||||
|
if (!setting_value_changed.load()) {
|
||||||
|
settings.erase(settings.begin(), settings.end());
|
||||||
|
settingChanged.erase(settingChanged.begin(), settingChanged.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
setting_busy.lock();
|
||||||
|
for (settings_i = settingsInfo.begin(); settings_i != settingsInfo.end(); settings_i++) {
|
||||||
|
SoapySDR::ArgInfo setting = (*settings_i);
|
||||||
|
if ((settingChanged.find(setting.key) != settingChanged.end()) && (settings.find(setting.key) != settings.end())) {
|
||||||
|
device->writeSetting(setting.key, settings[setting.key]);
|
||||||
|
settingChanged[setting.key] = false;
|
||||||
|
} else {
|
||||||
|
settings[setting.key] = device->readSetting(setting.key);
|
||||||
|
settingChanged[setting.key] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setting_value_changed.store(false);
|
||||||
|
setting_busy.unlock();
|
||||||
|
|
||||||
|
wxGetApp().sdrThreadNotify(SDRThread::SDR_THREAD_INITIALIZED, std::string("Device Initialized."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDRThread::deinit() {
|
void SDRThread::deinit() {
|
||||||
|
@ -139,57 +164,10 @@ void SDRThread::readLoop() {
|
||||||
updateGains();
|
updateGains();
|
||||||
|
|
||||||
while (!terminated.load()) {
|
while (!terminated.load()) {
|
||||||
if (offset_changed.load()) {
|
updateSettings();
|
||||||
if (!freq_changed.load()) {
|
|
||||||
frequency.store(frequency.load());
|
|
||||||
freq_changed.store(true);
|
|
||||||
}
|
|
||||||
offset_changed.store(false);
|
|
||||||
}
|
|
||||||
if (rate_changed.load()) {
|
|
||||||
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
|
||||||
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
|
|
||||||
numChannels.store(getOptimalChannelCount(sampleRate.load()));
|
|
||||||
numElems.store(getOptimalElementCount(sampleRate.load(), 60));
|
|
||||||
inpBuffer.data.resize(numElems.load());
|
|
||||||
free(buffs[0]);
|
|
||||||
buffs[0] = malloc(numElems.load() * 2 * sizeof(float));
|
|
||||||
rate_changed.store(false);
|
|
||||||
}
|
|
||||||
if (ppm_changed.load() && hasPPM.load()) {
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load());
|
|
||||||
ppm_changed.store(false);
|
|
||||||
}
|
|
||||||
if (freq_changed.load()) {
|
|
||||||
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency.load() - offset.load());
|
|
||||||
freq_changed.store(false);
|
|
||||||
}
|
|
||||||
if (agc_mode_changed.load()) {
|
|
||||||
SDRDeviceInfo *devInfo = deviceInfo.load();
|
|
||||||
|
|
||||||
device->setGainMode(SOAPY_SDR_RX,devInfo->getRxChannel()->getChannel(),agc_mode.load());
|
|
||||||
agc_mode_changed.store(false);
|
|
||||||
if (!agc_mode.load()) {
|
|
||||||
updateGains();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gain_value_changed.load() && !agc_mode.load()) {
|
|
||||||
SDRDeviceInfo *devInfo = deviceInfo.load();
|
|
||||||
|
|
||||||
gain_busy.lock();
|
|
||||||
for (std::map<std::string,bool>::iterator gci = gainChanged.begin(); gci != gainChanged.end(); gci++) {
|
|
||||||
if (gci->second) {
|
|
||||||
device->setGain(SOAPY_SDR_RX, devInfo->getRxChannel()->getChannel(), gci->first, gainValues[gci->first]);
|
|
||||||
gainChanged[gci->first] = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gain_busy.unlock();
|
|
||||||
|
|
||||||
gain_value_changed.store(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
readStream(iqDataOutQueue);
|
readStream(iqDataOutQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffers.purge();
|
buffers.purge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,6 +186,76 @@ void SDRThread::updateGains() {
|
||||||
gain_value_changed.store(false);
|
gain_value_changed.store(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDRThread::updateSettings() {
|
||||||
|
if (offset_changed.load()) {
|
||||||
|
if (!freq_changed.load()) {
|
||||||
|
frequency.store(frequency.load());
|
||||||
|
freq_changed.store(true);
|
||||||
|
}
|
||||||
|
offset_changed.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rate_changed.load()) {
|
||||||
|
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
|
||||||
|
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
|
||||||
|
numChannels.store(getOptimalChannelCount(sampleRate.load()));
|
||||||
|
numElems.store(getOptimalElementCount(sampleRate.load(), 60));
|
||||||
|
inpBuffer.data.resize(numElems.load());
|
||||||
|
free(buffs[0]);
|
||||||
|
buffs[0] = malloc(numElems.load() * 2 * sizeof(float));
|
||||||
|
rate_changed.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppm_changed.load() && hasPPM.load()) {
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"CORR",ppm.load());
|
||||||
|
ppm_changed.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (freq_changed.load()) {
|
||||||
|
device->setFrequency(SOAPY_SDR_RX,0,"RF",frequency.load() - offset.load());
|
||||||
|
freq_changed.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agc_mode_changed.load()) {
|
||||||
|
SDRDeviceInfo *devInfo = deviceInfo.load();
|
||||||
|
|
||||||
|
device->setGainMode(SOAPY_SDR_RX,devInfo->getRxChannel()->getChannel(),agc_mode.load());
|
||||||
|
agc_mode_changed.store(false);
|
||||||
|
if (!agc_mode.load()) {
|
||||||
|
updateGains();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gain_value_changed.load() && !agc_mode.load()) {
|
||||||
|
SDRDeviceInfo *devInfo = deviceInfo.load();
|
||||||
|
|
||||||
|
gain_busy.lock();
|
||||||
|
for (std::map<std::string,bool>::iterator gci = gainChanged.begin(); gci != gainChanged.end(); gci++) {
|
||||||
|
if (gci->second) {
|
||||||
|
device->setGain(SOAPY_SDR_RX, devInfo->getRxChannel()->getChannel(), gci->first, gainValues[gci->first]);
|
||||||
|
gainChanged[gci->first] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gain_busy.unlock();
|
||||||
|
|
||||||
|
gain_value_changed.store(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (setting_value_changed.load()) {
|
||||||
|
setting_busy.lock();
|
||||||
|
|
||||||
|
for (std::map<std::string, bool>::iterator sci = settingChanged.begin(); sci != settingChanged.end(); sci++) {
|
||||||
|
if (sci->second) {
|
||||||
|
device->writeSetting(sci->first, settings[sci->first]);
|
||||||
|
settingChanged[sci->first] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setting_value_changed.store(false);
|
||||||
|
setting_busy.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SDRThread::run() {
|
void SDRThread::run() {
|
||||||
//#ifdef __APPLE__
|
//#ifdef __APPLE__
|
||||||
|
@ -341,3 +389,20 @@ float SDRThread::getGain(std::string name) {
|
||||||
gain_busy.unlock();
|
gain_busy.unlock();
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDRThread::writeSetting(std::string name, std::string value) {
|
||||||
|
setting_busy.lock();
|
||||||
|
settings[name] = value;
|
||||||
|
settingChanged[name] = true;
|
||||||
|
setting_value_changed.store(true);
|
||||||
|
setting_busy.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SDRThread::readSetting(std::string name) {
|
||||||
|
std::string val;
|
||||||
|
setting_busy.lock();
|
||||||
|
val = device->readSetting(name);
|
||||||
|
setting_busy.unlock();
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ private:
|
||||||
public:
|
public:
|
||||||
SDRThread();
|
SDRThread();
|
||||||
~SDRThread();
|
~SDRThread();
|
||||||
enum SDRThreadState { SDR_THREAD_MESSAGE, SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
|
enum SDRThreadState { SDR_THREAD_MESSAGE, SDR_THREAD_INITIALIZED, SDR_THREAD_TERMINATED, SDR_THREAD_FAILED };
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
|
@ -75,8 +75,12 @@ public:
|
||||||
void setGain(std::string name, float value);
|
void setGain(std::string name, float value);
|
||||||
float getGain(std::string name);
|
float getGain(std::string name);
|
||||||
|
|
||||||
|
void writeSetting(std::string name, std::string value);
|
||||||
|
std::string readSetting(std::string name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateGains();
|
void updateGains();
|
||||||
|
void updateSettings();
|
||||||
|
|
||||||
SoapySDR::Stream *stream;
|
SoapySDR::Stream *stream;
|
||||||
SoapySDR::Device *device;
|
SoapySDR::Device *device;
|
||||||
|
@ -86,12 +90,16 @@ protected:
|
||||||
std::atomic<DeviceConfig *> deviceConfig;
|
std::atomic<DeviceConfig *> deviceConfig;
|
||||||
std::atomic<SDRDeviceInfo *> deviceInfo;
|
std::atomic<SDRDeviceInfo *> deviceInfo;
|
||||||
|
|
||||||
|
std::mutex setting_busy;
|
||||||
|
std::map<std::string, std::string> settings;
|
||||||
|
std::map<std::string, bool> settingChanged;
|
||||||
|
|
||||||
std::atomic<uint32_t> sampleRate;
|
std::atomic<uint32_t> sampleRate;
|
||||||
std::atomic_llong frequency, offset;
|
std::atomic_llong frequency, offset;
|
||||||
std::atomic_int ppm, numElems, numChannels;
|
std::atomic_int ppm, numElems, numChannels;
|
||||||
std::atomic_bool hasPPM, hasHardwareDC;
|
std::atomic_bool hasPPM, hasHardwareDC;
|
||||||
std::atomic_bool agc_mode, rate_changed, freq_changed, offset_changed,
|
std::atomic_bool agc_mode, rate_changed, freq_changed, offset_changed,
|
||||||
ppm_changed, device_changed, agc_mode_changed, gain_value_changed;
|
ppm_changed, device_changed, agc_mode_changed, gain_value_changed, setting_value_changed;
|
||||||
|
|
||||||
std::mutex gain_busy;
|
std::mutex gain_busy;
|
||||||
std::map<std::string, float> gainValues;
|
std::map<std::string, float> gainValues;
|
||||||
|
|
Loading…
Reference in New Issue