From 56bd20d59b6e731909c9a72f651c6e9b51db19f4 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Tue, 24 Dec 2024 12:48:43 +0000 Subject: [PATCH] USRP: Implement GPIO settings. --- plugins/samplesink/usrpoutput/usrpoutput.cpp | 33 +++++++++++++++++++ .../usrpoutput/usrpoutputsettings.cpp | 20 +++++++++++ .../usrpoutput/usrpoutputsettings.h | 2 ++ plugins/samplesource/usrpinput/usrpinput.cpp | 33 +++++++++++++++++++ .../usrpinput/usrpinputsettings.cpp | 20 +++++++++++ .../usrpinput/usrpinputsettings.h | 4 ++- 6 files changed, 111 insertions(+), 1 deletion(-) diff --git a/plugins/samplesink/usrpoutput/usrpoutput.cpp b/plugins/samplesink/usrpoutput/usrpoutput.cpp index 8f9444e8a..9fe77db39 100644 --- a/plugins/samplesink/usrpoutput/usrpoutput.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutput.cpp @@ -813,6 +813,25 @@ bool USRPOutput::applySettings(const USRPOutputSettings& settings, const QListgetDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "CTRL", ~settings.m_gpioDir, 0xff); // 0 for GPIO, 1 for ATR + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "DDR", settings.m_gpioDir, 0xff); // 0 for input, 1 for output + qDebug() << "USRPOutput::applySettings: set GPIO dir to " << settings.m_gpioDir; + } + } + + if (settingsKeys.contains("gpioPins") || force) + { + if (m_deviceShared.m_deviceParams->getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "OUT", settings.m_gpioPins, 0xff); + qDebug() << "USRPOutput::applySettings: set GPIO pins to " << settings.m_gpioPins; + } + } + if (settingsKeys.contains("useReverseAPI")) { bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || @@ -1036,6 +1055,12 @@ void USRPOutput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getUsrpOutputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getUsrpOutputSettings()->getGpioDir(); + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getUsrpOutputSettings()->getGpioPins(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getUsrpOutputSettings()->getUseReverseApi() != 0; } @@ -1072,6 +1097,8 @@ void USRPOutput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& resp response.getUsrpOutputSettings()->setLpfBw(settings.m_lpfBW); response.getUsrpOutputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getUsrpOutputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getUsrpOutputSettings()->setGpioDir(settings.m_gpioDir); + response.getUsrpOutputSettings()->setGpioPins(settings.m_gpioPins); response.getUsrpOutputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getUsrpOutputSettings()->getReverseApiAddress()) { @@ -1172,6 +1199,12 @@ void USRPOutput::webapiReverseSendSettings(const QList& deviceSettingsK if (deviceSettingsKeys.contains("transverterMode") || force) { swgUsrpOutputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); } + if (deviceSettingsKeys.contains("gpioDir") || force) { + swgUsrpOutputSettings->setGpioDir(settings.m_gpioDir); + } + if (deviceSettingsKeys.contains("gpioPins") || force) { + swgUsrpOutputSettings->setGpioPins(settings.m_gpioPins); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp b/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp index c76207267..a726884fa 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp +++ b/plugins/samplesink/usrpoutput/usrpoutputsettings.cpp @@ -40,6 +40,8 @@ void USRPOutputSettings::resetToDefaults() m_clockSource = "internal"; m_transverterMode = false; m_transverterDeltaFrequency = 0; + m_gpioDir = 0; + m_gpioPins = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -63,6 +65,8 @@ QByteArray USRPOutputSettings::serialize() const s.writeU32(11, m_reverseAPIPort); s.writeU32(12, m_reverseAPIDeviceIndex); s.writeS32(13, m_loOffset); + s.writeU32(14, m_gpioDir); + s.writeU32(15, m_gpioPins); return s.final(); } @@ -102,6 +106,10 @@ bool USRPOutputSettings::deserialize(const QByteArray& data) d.readU32(12, &uintval, 0); m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval; d.readS32(13, &m_loOffset, 0); + d.readU32(14, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(15, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } @@ -148,6 +156,12 @@ void USRPOutputSettings::applySettings(const QStringList& settingsKeys, const US if (settingsKeys.contains("transverterDeltaFrequency")) { m_transverterDeltaFrequency = settings.m_transverterDeltaFrequency; } + if (settingsKeys.contains("gpioDir")) { + m_gpioDir = settings.m_gpioDir; + } + if (settingsKeys.contains("gpioPins")) { + m_gpioPins = settings.m_gpioPins; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -199,6 +213,12 @@ QString USRPOutputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("transverterDeltaFrequency") || force) { ostr << " m_transverterDeltaFrequency: " << m_transverterDeltaFrequency; } + if (settingsKeys.contains("gpioDir") || force) { + ostr << " m_gpioDir: " << (int) m_gpioDir; + } + if (settingsKeys.contains("gpioPins") || force) { + ostr << " m_gpioPins: " << (int) m_gpioPins; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesink/usrpoutput/usrpoutputsettings.h b/plugins/samplesink/usrpoutput/usrpoutputsettings.h index ec07c179e..3b11fcaff 100644 --- a/plugins/samplesink/usrpoutput/usrpoutputsettings.h +++ b/plugins/samplesink/usrpoutput/usrpoutputsettings.h @@ -45,6 +45,8 @@ struct USRPOutputSettings QString m_clockSource; bool m_transverterMode; qint64 m_transverterDeltaFrequency; + uint8_t m_gpioDir; //!< GPIO pin direction; 0 ATR (automatic transmit/receive), 1 output + uint8_t m_gpioPins; //!< GPIO pins levels for outputs bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort; diff --git a/plugins/samplesource/usrpinput/usrpinput.cpp b/plugins/samplesource/usrpinput/usrpinput.cpp index b6d8eb1c7..acc408d82 100644 --- a/plugins/samplesource/usrpinput/usrpinput.cpp +++ b/plugins/samplesource/usrpinput/usrpinput.cpp @@ -895,6 +895,25 @@ bool USRPInput::applySettings(const USRPInputSettings& settings, const QListgetDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "CTRL", ~settings.m_gpioDir, 0xff); // 0 for GPIO, 1 for ATR + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "DDR", settings.m_gpioDir, 0xff); // 0 for input, 1 for output + qDebug() << "USRPInput::applySettings: set GPIO dir to " << settings.m_gpioDir; + } + } + + if (settingsKeys.contains("gpioPins") || force) + { + if (m_deviceShared.m_deviceParams->getDevice()) + { + m_deviceShared.m_deviceParams->getDevice()->set_gpio_attr("FP0", "OUT", settings.m_gpioPins, 0xff); + qDebug() << "USRPInput::applySettings: set GPIO pins to " << settings.m_gpioPins; + } + } + if (settingsKeys.contains("useReverseAPI")) { bool fullUpdate = (settingsKeys.contains("useReverseAPI") && settings.m_useReverseAPI) || @@ -1162,6 +1181,12 @@ void USRPInput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("transverterMode")) { settings.m_transverterMode = response.getUsrpInputSettings()->getTransverterMode() != 0; } + if (deviceSettingsKeys.contains("gpioDir")) { + settings.m_gpioDir = response.getUsrpInputSettings()->getGpioDir(); + } + if (deviceSettingsKeys.contains("gpioPins")) { + settings.m_gpioPins = response.getUsrpInputSettings()->getGpioPins(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getUsrpInputSettings()->getUseReverseApi() != 0; } @@ -1191,6 +1216,8 @@ void USRPInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& respo response.getUsrpInputSettings()->setLpfBw(settings.m_lpfBW); response.getUsrpInputSettings()->setTransverterDeltaFrequency(settings.m_transverterDeltaFrequency); response.getUsrpInputSettings()->setTransverterMode(settings.m_transverterMode ? 1 : 0); + response.getUsrpInputSettings()->setGpioDir(settings.m_gpioDir); + response.getUsrpInputSettings()->setGpioPins(settings.m_gpioPins); response.getUsrpInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); if (response.getUsrpInputSettings()->getReverseApiAddress()) { @@ -1311,6 +1338,12 @@ void USRPInput::webapiReverseSendSettings(const QList& deviceSettingsKe if (deviceSettingsKeys.contains("transverterMode") || force) { swgUsrpInputSettings->setTransverterMode(settings.m_transverterMode ? 1 : 0); } + if (deviceSettingsKeys.contains("gpioDir") || force) { + swgUsrpInputSettings->setGpioDir(settings.m_gpioDir); + } + if (deviceSettingsKeys.contains("gpioPins") || force) { + swgUsrpInputSettings->setGpioPins(settings.m_gpioPins); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesource/usrpinput/usrpinputsettings.cpp b/plugins/samplesource/usrpinput/usrpinputsettings.cpp index e1b1381a2..82fec7e17 100644 --- a/plugins/samplesource/usrpinput/usrpinputsettings.cpp +++ b/plugins/samplesource/usrpinput/usrpinputsettings.cpp @@ -46,6 +46,8 @@ void USRPInputSettings::resetToDefaults() m_replayLength = 20.0f; m_replayStep = 5.0f; m_replayLoop = false; + m_gpioDir = 0; + m_gpioPins = 0; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -76,6 +78,8 @@ QByteArray USRPInputSettings::serialize() const s.writeFloat(18, m_replayLength); s.writeFloat(19, m_replayStep); s.writeBool(20, m_replayLoop); + s.writeU32(21, m_gpioDir); + s.writeU32(22, m_gpioPins); return s.final(); } @@ -124,6 +128,10 @@ bool USRPInputSettings::deserialize(const QByteArray& data) d.readFloat(18, &m_replayLength, 20.0f); d.readFloat(19, &m_replayStep, 5.0f); d.readBool(20, &m_replayLoop, false); + d.readU32(21, &uintval, 0); + m_gpioDir = uintval & 0xFF; + d.readU32(22, &uintval, 0); + m_gpioPins = uintval & 0xFF; return true; } @@ -191,6 +199,12 @@ void USRPInputSettings::applySettings(const QStringList& settingsKeys, const USR if (settingsKeys.contains("replayLoop")) { m_replayLoop = settings.m_replayLoop; } + if (settingsKeys.contains("gpioDir")) { + m_gpioDir = settings.m_gpioDir; + } + if (settingsKeys.contains("gpioPins")) { + m_gpioPins = settings.m_gpioPins; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -263,6 +277,12 @@ QString USRPInputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("replayLoop") || force) { ostr << " m_replayLoop: " << m_replayLoop; } + if (settingsKeys.contains("gpioDir") || force) { + ostr << " m_gpioDir: " << (int) m_gpioDir; + } + if (settingsKeys.contains("gpioPins") || force) { + ostr << " m_gpioPins: " << (int) m_gpioPins; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesource/usrpinput/usrpinputsettings.h b/plugins/samplesource/usrpinput/usrpinputsettings.h index ae2f6e15d..774e62bde 100644 --- a/plugins/samplesource/usrpinput/usrpinputsettings.h +++ b/plugins/samplesource/usrpinput/usrpinputsettings.h @@ -52,10 +52,12 @@ struct USRPInputSettings QString m_clockSource; bool m_transverterMode; qint64 m_transverterDeltaFrequency; - float m_replayOffset; //!< Replay offset in seconds + float m_replayOffset; //!< Replay offset in seconds float m_replayLength; //!< Replay buffer size in seconds float m_replayStep; //!< Replay forward/back step size in seconds bool m_replayLoop; //!< Replay buffer repeatedly without recording new data + uint8_t m_gpioDir; //!< GPIO pin direction; 0 ATR (automatic transmit/receive), 1 output + uint8_t m_gpioPins; //!< GPIO pins levels for outputs bool m_useReverseAPI; QString m_reverseAPIAddress; uint16_t m_reverseAPIPort;