diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/GlobalFileTable.000 b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/GlobalFileTable.000 new file mode 100644 index 0000000..1d23d8c Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/GlobalFileTable.000 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/GlobalFileTable.001 b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/GlobalFileTable.001 new file mode 100644 index 0000000..692f45e Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/GlobalFileTable.001 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.npa00 b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.npa00 new file mode 100644 index 0000000..1d9963e Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.npa00 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.npd b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.npd new file mode 100644 index 0000000..f31e10f Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.npd differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.rdb b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.rdb new file mode 100644 index 0000000..7ab2492 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/SoapyRadioberryStreaming.rdb differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/codedb.lck b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/codedb.lck new file mode 100644 index 0000000..9e4ea5b --- /dev/null +++ b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/codedb.lck @@ -0,0 +1 @@ +This file was last opened by PID 12504 diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/tmp00000003.npa00 b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/tmp00000003.npa00 new file mode 100644 index 0000000..f2fd140 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Debug-VisualGDB/tmp00000003.npa00 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/GlobalFileTable.000 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/GlobalFileTable.000 new file mode 100644 index 0000000..37dfa2d Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/GlobalFileTable.000 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/GlobalFileTable.001 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/GlobalFileTable.001 new file mode 100644 index 0000000..1932872 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/GlobalFileTable.001 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.npa00 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.npa00 new file mode 100644 index 0000000..493d87c Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.npa00 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.npd b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.npd new file mode 100644 index 0000000..b93b00d Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.npd differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.rdb b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.rdb new file mode 100644 index 0000000..7402f13 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberry.rdb differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.npa01 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.npa01 new file mode 100644 index 0000000..66a107b Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.npa01 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.npd b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.npd new file mode 100644 index 0000000..a9110ee Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.npd differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.rdb b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.rdb new file mode 100644 index 0000000..566c9cb Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberrySettings.rdb differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.npa00 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.npa00 new file mode 100644 index 0000000..f667216 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.npa00 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.npd b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.npd new file mode 100644 index 0000000..5e13e3e Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.npd differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.rdb b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.rdb new file mode 100644 index 0000000..f48a041 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/SoapyRadioberryStreaming.rdb differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/codedb.lck b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/codedb.lck new file mode 100644 index 0000000..7dc7dc6 --- /dev/null +++ b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/codedb.lck @@ -0,0 +1 @@ +This file was last opened by PID 11240 diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/tmp00000003.npa00 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/tmp00000003.npa00 new file mode 100644 index 0000000..7d11cb6 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/tmp00000003.npa00 differ diff --git a/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/tmp00000006.npa00 b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/tmp00000006.npa00 new file mode 100644 index 0000000..30da5e0 Binary files /dev/null and b/.visualgdb/CodeDB/SoapyRadioberry-Release-VisualGDB/tmp00000006.npa00 differ diff --git a/.visualgdb/VisualGDBCache/SoapyRadioberry-Debug/SysprogsSyncCache/00.dat b/.visualgdb/VisualGDBCache/SoapyRadioberry-Debug/SysprogsSyncCache/00.dat new file mode 100644 index 0000000..a22b8bb Binary files /dev/null and b/.visualgdb/VisualGDBCache/SoapyRadioberry-Debug/SysprogsSyncCache/00.dat differ diff --git a/.visualgdb/VisualGDBCache/SoapyRadioberry-Debug/SysprogsSyncCache/00.id b/.visualgdb/VisualGDBCache/SoapyRadioberry-Debug/SysprogsSyncCache/00.id new file mode 100644 index 0000000..83a3a37 --- /dev/null +++ b/.visualgdb/VisualGDBCache/SoapyRadioberry-Debug/SysprogsSyncCache/00.id @@ -0,0 +1 @@ +h:\onedrive\source\soapyradioberry => /tmp/VisualGDB/h/OneDrive/source/SoapyRadioberry \ No newline at end of file diff --git a/.visualgdb/VisualGDBCache/SoapyRadioberry-Release/SysprogsSyncCache/00.dat b/.visualgdb/VisualGDBCache/SoapyRadioberry-Release/SysprogsSyncCache/00.dat new file mode 100644 index 0000000..8153e3b Binary files /dev/null and b/.visualgdb/VisualGDBCache/SoapyRadioberry-Release/SysprogsSyncCache/00.dat differ diff --git a/.visualgdb/VisualGDBCache/SoapyRadioberry-Release/SysprogsSyncCache/00.id b/.visualgdb/VisualGDBCache/SoapyRadioberry-Release/SysprogsSyncCache/00.id new file mode 100644 index 0000000..83a3a37 --- /dev/null +++ b/.visualgdb/VisualGDBCache/SoapyRadioberry-Release/SysprogsSyncCache/00.id @@ -0,0 +1 @@ +h:\onedrive\source\soapyradioberry => /tmp/VisualGDB/h/OneDrive/source/SoapyRadioberry \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c0d4850 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# SoapyRadioberry +SoapyRadioberry driver, this repo is an effort to extend the SoapyRadioberry driver of Johan PA0GSB. +I use the pluto SDR driver as an example, goal is to use this driver in my sdrberry project and be able to have +both Adalm pluto and Radioberry connected to a raspberry pi to create a tranceiver. + + +This source code is still in development. + +To install you need to configure rasberry pi OS in text only mode, (switch of the GUI) +Compiled using VisualGDB + +ToDo: +- Transmitter part + +Done: +- Bug fix for dev version of Radioberry +- added multiple samplerates + + +Installation of libraries is necessary: +- SoapySDR + + +https://www.youtube.com/watch?v=ds-n-7sHXl8&t=2s diff --git a/SoapyRadioberry-Debug.vgdbsettings b/SoapyRadioberry-Debug.vgdbsettings new file mode 100644 index 0000000..0eadc2c --- /dev/null +++ b/SoapyRadioberry-Debug.vgdbsettings @@ -0,0 +1,141 @@ + + + Debug + + + + RemoteUnix + + true + + 192.168.89.252 + SSH + pi + + + false + + 192.168.89.252 + SSH + pi + + $(ProjectDir) + /tmp/VisualGDB/$(ProjectDirUnixStyle) + + *.cpp + *.h + *.hpp + *.c + *.cc + *.cxx + *.mak + Makefile + *.txt + *.cmake + + true + true + true + true + + false + false + false + false + false + $(ProjectDir) + + + + + com.sysprogs.toolchain.default-gcc + + 0 + + + SoapyRadioberry.vcxproj + 0 + true + false + + + + + + + + + + + + + Default + + + + true + + + + Unknown + + true + true + true + + + + false + + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + 0 + true + + + $(TargetPath) + 2000 + + Auto + + false + false + Local + false + false + Auto + true + false + false + false + + \ No newline at end of file diff --git a/SoapyRadioberry-Release.vgdbsettings b/SoapyRadioberry-Release.vgdbsettings new file mode 100644 index 0000000..81e0b6c --- /dev/null +++ b/SoapyRadioberry-Release.vgdbsettings @@ -0,0 +1,141 @@ + + + Release + + + + RemoteUnix + + true + + 192.168.89.252 + SSH + pi + + + false + + 192.168.89.252 + SSH + pi + + $(ProjectDir) + /tmp/VisualGDB/$(ProjectDirUnixStyle) + + *.cpp + *.h + *.hpp + *.c + *.cc + *.cxx + *.mak + Makefile + *.txt + *.cmake + + true + true + true + true + + false + false + false + false + false + $(ProjectDir) + + + + + com.sysprogs.toolchain.default-gcc + + 0 + + + SoapyRadioberry.vcxproj + 0 + true + false + + + + + + + + + + + + + Default + + + + true + + + + Unknown + + true + true + true + + + + false + + + + + + + false + false + false + false + false + false + false + false + false + + false + false + false + false + false + false + true + false + None + false + false + main + true + false + false + false + 0 + true + + + $(TargetPath) + 2000 + + Auto + + false + false + Local + false + false + Auto + true + false + false + false + + \ No newline at end of file diff --git a/SoapyRadioberry.cpp b/SoapyRadioberry.cpp new file mode 100644 index 0000000..cbc6220 --- /dev/null +++ b/SoapyRadioberry.cpp @@ -0,0 +1,34 @@ +#include +#include + +#include "SoapyRadioberry.hpp" + +/*********************************************************************** + * Find available devices + **********************************************************************/ + + +SoapySDR::KwargsList findMyRadioberry(const SoapySDR::Kwargs &args) +{ + SoapySDR::Kwargs options; + + static std::vector results; + + options["driver"] = "radioberry"; + results.push_back(options); + + return results; +} + +/*********************************************************************** + * Make device instance + **********************************************************************/ +SoapySDR::Device *makeMyRadioberry(const SoapySDR::Kwargs &args) +{ + return new SoapyRadioberry(args); +} + +/*********************************************************************** + * Registration + **********************************************************************/ +static SoapySDR::Registry registerRadioberry("radioberry", &findMyRadioberry, &makeMyRadioberry, SOAPY_SDR_ABI_VERSION); diff --git a/SoapyRadioberry.hpp b/SoapyRadioberry.hpp new file mode 100644 index 0000000..a5b40fa --- /dev/null +++ b/SoapyRadioberry.hpp @@ -0,0 +1,134 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "radioberry_ioctl.h" + +const int npackages = 4; + +class SoapyRadioberry : public SoapySDR::Device{ + + public: + + SoapyRadioberry( const SoapySDR::Kwargs & args ); + ~SoapyRadioberry(); + + /******************************************************************* + * Identification API + ******************************************************************/ + + std::string getDriverKey( void ) const; + + std::string getHardwareKey( void ) const; + + SoapySDR::Kwargs getHardwareInfo( void ) const; + + /******************************************************************* + * Channels API + ******************************************************************/ + + size_t getNumChannels( const int direction ) const; + + bool getFullDuplex( const int direction, const size_t channel ) const; + + /******************************************************************* + * Stream API + ******************************************************************/ + SoapySDR::RangeList getSampleRateRange(const int direction, const size_t channel) const; + + std::vector getStreamFormats(const int direction, const size_t channel) const; + + std::string getNativeStreamFormat(const int direction, const size_t channel, double &fullScale) const; + + SoapySDR::ArgInfoList getStreamArgsInfo(const int direction, const size_t channel) const; + + + SoapySDR::Stream *setupStream( + const int direction, + const std::string &format, + const std::vector &channels = std::vector(), + const SoapySDR::Kwargs &args = SoapySDR::Kwargs() ); + + int readStream( + SoapySDR::Stream *stream, + void * const *buffs, + const size_t numElems, + int &flags, + long long &timeNs, + const long timeoutUs = 100000 ); + + + +/* + int writeStream( + SoapySDR::Stream *stream, + const void * const *buffs, + const size_t numElems, + int &flags, + const long long timeNs = 0, + const long timeoutUs = 100000); + + +*/ + + /******************************************************************* + * Sample Rate API + ******************************************************************/ + + void setSampleRate( const int direction, const size_t channel, const double rate ); + + double getBandwidth( const int direction, const size_t channel ) const; + + + std::vector listBandwidths( const int direction, const size_t channel ) const; + + + /******************************************************************* + * Frequency API + ******************************************************************/ + + void setFrequency( + const int direction, + const size_t channel, + const double frequency, + const SoapySDR::Kwargs &args = SoapySDR::Kwargs()); + + + SoapySDR::RangeList getFrequencyRange( const int direction, const size_t channel) const; + + + /******************************************************************* + * Antenna API + ******************************************************************/ + + std::vector listAntennas( const int direction, const size_t channel ) const; + + + /******************************************************************* + * Gain API + ******************************************************************/ + + std::vector listGains( const int direction, const size_t channel ) const; + + void setGain( const int direction, const size_t channel, const double value ); + + SoapySDR::Range getGainRange( const int direction, const size_t channel, const std::string &name ) const; + + + void controlRadioberry(uint32_t command, uint32_t command_data); + + private: + + int fd_rb; + int sample_rate; + int rx_frequency; + int no_channels; + struct rb_info_arg_t rb_control; + +}; diff --git a/SoapyRadioberry.sln b/SoapyRadioberry.sln new file mode 100644 index 0000000..84862f5 --- /dev/null +++ b/SoapyRadioberry.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31424.327 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SoapyRadioberry", "SoapyRadioberry.vcxproj", "{F825354D-9A24-4967-8BEB-7C9ECF0E15CE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|VisualGDB = Debug|VisualGDB + Release|VisualGDB = Release|VisualGDB + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F825354D-9A24-4967-8BEB-7C9ECF0E15CE}.Debug|VisualGDB.ActiveCfg = Debug|VisualGDB + {F825354D-9A24-4967-8BEB-7C9ECF0E15CE}.Debug|VisualGDB.Build.0 = Debug|VisualGDB + {F825354D-9A24-4967-8BEB-7C9ECF0E15CE}.Release|VisualGDB.ActiveCfg = Release|VisualGDB + {F825354D-9A24-4967-8BEB-7C9ECF0E15CE}.Release|VisualGDB.Build.0 = Release|VisualGDB + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6C42B5B2-9CE1-4378-B501-347D8680B331} + EndGlobalSection +EndGlobal diff --git a/SoapyRadioberry.vcxproj b/SoapyRadioberry.vcxproj new file mode 100644 index 0000000..c6da09d --- /dev/null +++ b/SoapyRadioberry.vcxproj @@ -0,0 +1,75 @@ + + + + + Debug + VisualGDB + + + Release + VisualGDB + + + + 16.0 + {F825354D-9A24-4967-8BEB-7C9ECF0E15CE} + + + + + + + + + + + + + + Debug + 192.168.89.252 + com.sysprogs.toolchain.default-gcc + + DynamicLibrary + + GCC + Ninja + libSoapyRadioberrySDR + + + 192.168.89.252 + com.sysprogs.toolchain.default-gcc + + DynamicLibrary + + GCC + Ninja + libSoapyRadioberrySDR + + + + CPP1Z + + + + + CPP1Z + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SoapyRadioberry.vcxproj.filters b/SoapyRadioberry.vcxproj.filters new file mode 100644 index 0000000..4f94e0a --- /dev/null +++ b/SoapyRadioberry.vcxproj.filters @@ -0,0 +1,48 @@ + + + + + {6216867d-e45a-4722-b4b7-779261ab96b0} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {17467aa9-de31-4895-8d5b-e0c9948218d5} + h;hpp;hxx;hm;inl;inc;xsd + + + {379f46f7-0ff8-4180-96a8-33028b6b355d} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + {fa8ab87d-56f2-4ebe-892a-1a5cc8333526} + vgdbsettings + + + + + Source files + + + Source files + + + Source files + + + + + VisualGDB settings + + + VisualGDB settings + + + + + Header files + + + Header files + + + \ No newline at end of file diff --git a/SoapyRadioberrySettings.cpp b/SoapyRadioberrySettings.cpp new file mode 100644 index 0000000..1e9bca8 --- /dev/null +++ b/SoapyRadioberrySettings.cpp @@ -0,0 +1,224 @@ +#include "SoapyRadioberry.hpp" + + +/*********************************************************************** + * Device interface + **********************************************************************/ + +SoapyRadioberry::SoapyRadioberry( const SoapySDR::Kwargs &args ){ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry constructor called"); + + no_channels = 1; + fd_rb = open("/dev/radioberry", O_RDWR); +} + +SoapyRadioberry::~SoapyRadioberry(void){ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::SoapyRadioberry destructor called"); + + if (fd_rb != 0) close(fd_rb); +} + +void SoapyRadioberry::controlRadioberry(uint32_t command, uint32_t command_data) { + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::controlRadioberry called"); + + uint32_t CWX =0; + uint32_t running = 1; + + rb_control.rb_command = (((CWX << 1) & 0x02) | (running & 0x01)); + rb_control.command = command; + rb_control.command_data = command_data; + + fprintf(stderr, "Command = %02X command_data = %08X\n", command, command_data); + + if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_control) == -1) { + SoapySDR_log(SOAPY_SDR_INFO, "Could not sent command to radioberry device."); + } else SoapySDR_log(SOAPY_SDR_INFO, "Command sent succesfull to radioberry device."); +} + +std::string SoapyRadioberry::getDriverKey( void ) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getDriverKey called"); + + return "radioberry"; +} + +std::string SoapyRadioberry::getHardwareKey( void ) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getHardwareKey called"); + + return "v2.0-beta5"; +} + +SoapySDR::Kwargs SoapyRadioberry::getHardwareInfo( void ) const +{ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getHardwareInfo called"); + + SoapySDR::Kwargs info; + + struct rb_info_arg_t rb_info; + + if (ioctl(fd_rb, RADIOBERRY_IOC_COMMAND, &rb_info) == -1) { + rb_info.major = 0; + rb_info.minor = 0; + } + + unsigned int major, minor; + major = rb_info.major; + minor = rb_info.minor; + + char firmware_version[100]; + snprintf(firmware_version, 100, "%u.%u", 0, 1); //0.1 + info["firmwareVersion"] = firmware_version; + + char gateware_version[100]; + snprintf(gateware_version, 100, "%u.%u ", major, minor); + info["gatewareVersion"] = gateware_version; + + char hardware_version[100]; + snprintf(hardware_version, 100, "%u.%u", 2, 4); //2.4 beta + info["hardwareVersion"] = hardware_version; + + char protocol_version[100]; + snprintf(protocol_version, 100, "%u.%u ", 1, 58); //1.58 protocol 1 + info["protocolVersion"] = protocol_version; + + return info; +} + +size_t SoapyRadioberry::getNumChannels( const int direction ) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getNumChannels called"); + + //if (direction == SOAPY_SDR_RX) return(4); + + return(1); //1 RX and 1 TX channel; making this for standalone radioberry! +} + +bool SoapyRadioberry::getFullDuplex( const int direction, const size_t channel ) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getFullDuplex called"); + + return(true); +} + +std::vector SoapyRadioberry::listBandwidths( const int direction, const size_t channel ) const +{ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::listBandwidths called"); + + + std::vector options; + + if (direction == SOAPY_SDR_RX) { + options.push_back(0.048e6); + options.push_back(0.096e6); + options.push_back(0.192e6); + options.push_back(0.384e6); + } + if (direction == SOAPY_SDR_TX) { + options.push_back(0.048e6); + } + return(options); +} + +double SoapyRadioberry::getBandwidth( const int direction, const size_t channel ) const +{ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getBandwidth called"); + + long long bandwidth = 48000.0; + + if(direction==SOAPY_SDR_RX){ + + //depends on settings.. TODO + + } + + else if(direction==SOAPY_SDR_TX){ + bandwidth = 48000.0; + } + + return double(bandwidth); +} + +SoapySDR::RangeList SoapyRadioberry::getFrequencyRange( const int direction, const size_t channel) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getFrequencyRange called"); + + SoapySDR::RangeList rangeList; + + rangeList.push_back(SoapySDR::Range(10000.0, 30000000.0, 1.0)); + + return rangeList; +} + +std::vector SoapyRadioberry::listAntennas( const int direction, const size_t channel ) const +{ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::listAntennas called"); + + std::vector options; + if(direction == SOAPY_SDR_RX) options.push_back( "ANTENNA RX" ); + if(direction == SOAPY_SDR_TX) options.push_back( "ANTENNA TX" ); + return(options); +} + + +/******************************************************************* + * Gain API + ******************************************************************/ + +std::vector SoapyRadioberry::listGains( const int direction, const size_t channel ) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::listGains called"); + + std::vector options; + //options.push_back("PGA"); in pihpsdr no additional gain settings. + return(options); +} + +SoapySDR::Range SoapyRadioberry::getGainRange( const int direction, const size_t channel, const std::string &name ) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getGainRange called"); + + if(direction==SOAPY_SDR_RX) + return(SoapySDR::Range(0, 60)); + return(SoapySDR::Range(0,18)); + +} + +void SoapyRadioberry::setGain( const int direction, const size_t channel, const double value ) { + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setGain called"); + + uint32_t command = 0; + uint32_t command_data = (0x40 | (((uint32_t) (value + 12.0)) & 0x3F)); + + if(direction==SOAPY_SDR_RX) command = 0x14; + if(direction==SOAPY_SDR_TX) { command = 2; } + + this->SoapyRadioberry::controlRadioberry(command, command_data); +} + +/******************************************************************* + * Frequency API + ******************************************************************/ +void SoapyRadioberry::setFrequency( const int direction, const size_t channel, const double frequency, const SoapySDR::Kwargs &args ) { + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setFrequency called"); + + uint32_t command = 0; + + if(direction==SOAPY_SDR_RX) command = 4; + if(direction==SOAPY_SDR_TX) command = 2; + + uint32_t command_data = (uint32_t) frequency; + + this->SoapyRadioberry::controlRadioberry(command, command_data); +} + +// end of source. \ No newline at end of file diff --git a/SoapyRadioberryStreaming.cpp b/SoapyRadioberryStreaming.cpp new file mode 100644 index 0000000..90194cd --- /dev/null +++ b/SoapyRadioberryStreaming.cpp @@ -0,0 +1,132 @@ +#include "SoapyRadioberry.hpp" + + void SoapyRadioberry::setSampleRate( const int direction, const size_t channel, const double rate ) { + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setSampleRate called"); + + int irate = floor(rate); + uint32_t ucom =0x00000004; + + if (rate < 48001.0) + ucom = 0x00000004; + if (rate > 48000.0 && rate < 96001.0) + ucom = 0x01000004; + if (rate > 96000.0 && rate < 192001.0) + ucom = 0x02000004; + if (rate > 192000.0) + ucom = 0x03000004; + + this->SoapyRadioberry::controlRadioberry(0, ucom); +} + +SoapySDR::RangeList SoapyRadioberry::getSampleRateRange(const int direction, const size_t channel) const +{ + + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getSampleRateRange called"); + + SoapySDR::RangeList rangeList; + + if (direction == SOAPY_SDR_RX) rangeList.push_back(SoapySDR::Range(48000.0, 192000.0, 1.0)); + if (direction == SOAPY_SDR_TX) rangeList.push_back(SoapySDR::Range(48000.0, 48000.0, 1.0)); + + return rangeList; +} + +std::vector SoapyRadioberry::getStreamFormats(const int direction, const size_t channel) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getStreamFormats called"); + + std::vector formats; + + formats.push_back(SOAPY_SDR_CF32); + + return formats; +} + +std::string SoapyRadioberry::getNativeStreamFormat(const int direction, const size_t channel, double &fullScale) const +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::getNativeStreamFormat called"); + + if (direction == SOAPY_SDR_RX) { + fullScale = 2048; // RX expects 12 bit samples LSB aligned + } + else if (direction == SOAPY_SDR_TX) { + fullScale = 32768; // TX expects 12 bit samples MSB aligned + } + return SOAPY_SDR_CF32; +} + +SoapySDR::ArgInfoList SoapyRadioberry::getStreamArgsInfo(const int direction, const size_t channel) const +{ + SoapySDR::ArgInfoList streamArgs; + + SoapySDR::ArgInfo bufflenArg; + bufflenArg.key = "bufflen"; + bufflenArg.value = "64"; + bufflenArg.name = "Buffer Size"; + bufflenArg.description = "Number of bytes per buffer, multiples of 512 only."; + bufflenArg.units = "bytes"; + bufflenArg.type = SoapySDR::ArgInfo::INT; + + streamArgs.push_back(bufflenArg); + + return streamArgs; +} + +SoapySDR::Stream *SoapyRadioberry::setupStream( + const int direction, + const std::string &format, + const std::vector &channels, + const SoapySDR::Kwargs &args ) +{ + SoapySDR_log(SOAPY_SDR_INFO, "SoapyRadioberry::setupStream called"); + + //check the format + if (format == SOAPY_SDR_CF32) { + SoapySDR_log(SOAPY_SDR_INFO, "Using format CF32."); + } + else { + throw std::runtime_error( + "setupStream invalid format '" + format + "' -- Only CF32 is supported by SoapyRadioberrySDR module."); + } + + return (SoapySDR::Stream *) this; + +} + +int SoapyRadioberry::readStream( + SoapySDR::Stream *handle, + void * const *buffs, + const size_t numElems, + int &flags, + long long &timeNs, + const long timeoutUs ) +{ + int i; + int iq = 0; + int left_sample; + int right_sample; + int nr_samples; + + void *buff_base = buffs[0]; + float *target_buffer = (float *) buff_base; + + char rx_buffer[512]; + for(int ii = 0 ; ii < npackages ; ii++) + { + nr_samples = read(fd_rb, rx_buffer, sizeof(rx_buffer)); + //printf("nr_samples %d sample: %d %d %d %d %d %d\n",nr_samples, (int)rx_buffer[0],(int)rx_buffer[1],(int)rx_buffer[2],(int)rx_buffer[3],(int)rx_buffer[4],(int)rx_buffer[5]); + for(i = 0 ; i < nr_samples ; i += 6) { + left_sample = (int)((signed char) rx_buffer[i]) << 16; + left_sample |= (int)((((unsigned char)rx_buffer[i + 1]) << 8) & 0xFF00); + left_sample |= (int)((unsigned char)rx_buffer[i + 2] & 0xFF); + right_sample = (int)((signed char)rx_buffer[i + 3]) << 16; + right_sample |= (int)((((unsigned char)rx_buffer[i + 4]) << 8) & 0xFF00); + right_sample |= (int)((unsigned char)rx_buffer[i + 5] & 0xFF); + + target_buffer[iq++] = (float)left_sample / 2048.0; // 12 bit sample + target_buffer[iq++] = (float)right_sample / 2048.0; // 12 bit sample + } + } + + return (npackages * nr_samples / 6); //return the number of IQ samples +} diff --git a/radioberry_ioctl.h b/radioberry_ioctl.h new file mode 100644 index 0000000..e3cda54 --- /dev/null +++ b/radioberry_ioctl.h @@ -0,0 +1,25 @@ +#ifndef __RADIOBERRY_IOCTL_H__ +#define __RADIOBERRY_IOCTL_H__ + +#include +#include + +#define RADIOBERRY_MAGIC ('x') + +#define RADIOBERRY_IOC_COMMAND _IOW(RADIOBERRY_MAGIC, 1, __u8) + +struct rb_info_arg_t +{ + int major, minor; + + int fpga; + + float version; + + int rb_command; + int command; + int command_data; + +} ; + +#endif