Compare commits

...

13 Commits

Author SHA1 Message Date
Robert Ghilduta 821fdb3822 bladeRF: convert to using std instead of boost for shared_ptr 2022-06-10 16:30:49 +02:00
Robert Ghilduta 038a26501c bladeRF: minor fixups to keep clang happy 2022-06-10 16:30:49 +02:00
Robert Ghilduta 95b1025b01 bladeRF: calculate number of samples based on stream count 2022-06-10 16:30:49 +02:00
Robert Ghilduta bfdc4d917c bladeRF: enable and disable each channel 2022-06-10 16:30:49 +02:00
Robert Ghilduta 34daf86ec3 bladeRF: set default gain mode to manual 2022-06-10 16:30:49 +02:00
Ryan Tucker a343cc208b source/sink_impl: query hardware for gains on init
Instead of guessing, query the device to populate _gain_mode and _gain.
2022-06-10 16:30:49 +02:00
Robert Ghilduta f6a8992856 bladeRF: check libbladeRF version before compiling 2022-06-10 16:30:49 +02:00
Eric Wild 6a22db7568 switch to gr-funcube
due to deprecation, see https://osmocom.org/issues/5445
2022-06-10 16:30:49 +02:00
Eric Wild 6b11b02947 fix missing sink/source iface destructor 2022-06-10 16:30:49 +02:00
Eric Wild a309841752 osmocom_fft: make it work with gr >= 3.9 qwidget/pyqwidget
This should fix it for both versions
2022-06-10 16:30:49 +02:00
Eric Wild 09e72004fe default to c++11
GR needs it anyway..
2022-06-10 16:28:52 +02:00
Eric Wild e13c2e4e1c add a reasonable .gitignore 2022-06-10 16:28:52 +02:00
Vadim Yanitskiy 9c58e8a991 apps/osmocom_siggen: fix missing parentheses in call to print 2022-05-14 14:50:48 +03:00
21 changed files with 93 additions and 79 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/.vscode/*
/build/*
*.pyc
*.pyo

View File

@ -63,15 +63,7 @@ if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
add_definitions(-fvisibility-inlines-hidden)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_STANDARD 11)
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_STANDARD 11)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_STANDARD 11)
else()
message(WARNING "C++ standard could not be set because compiler is not GNU, Clang or MSVC.")
endif()
set(CMAKE_CXX_STANDARD 11)
# Misc options
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
@ -179,7 +171,7 @@ find_package(LibHackRF)
find_package(LibAIRSPY)
find_package(LibAIRSPYHF)
find_package(LibbladeRF)
find_package(GnuradioFCDPP)
find_package(GnuradioFuncube)
find_package(SoapySDR NO_MODULE)
find_package(LibFreeSRP)
find_package(LibXTRX)

3
README
View File

@ -1,8 +1,7 @@
While primarily being developed for the OsmoSDR hardware, this block
as well supports:
* FUNcube Dongle through libgnuradio-fcd
* FUNcube Dongle Pro+ through gr-fcdproplus
* FUNcube Dongle / Pro+ through gr-funcube
* RTL2832U based DVB-T dongles through librtlsdr
* RTL-TCP spectrum server (see librtlsdr project)
* SDRplay RSP through SDRplay API library

View File

@ -238,11 +238,14 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
self.iq_balance_mag = 0
self.iq_balance_pha = 0
# see https://github.com/gnuradio/gnuradio/issues/5175 - 3.9 has a backport of pyqwidget, but 3.10 does not.
check_qwidget = lambda : self.scope.pyqwidget() if "pyqwidget" in dir(self.scope) else self.scope.qwidget()
if options.fosphor:
from gnuradio import fosphor
self.scope = fosphor.qt_sink_c()
self.scope.set_frequency_range(0, input_rate)
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
self.scope_win.setMinimumSize(800, 300)
elif options.waterfall:
self.scope = qtgui.waterfall_sink_c(
@ -256,7 +259,7 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
self.scope.enable_grid(False)
self.scope.enable_axis_labels(True)
self.scope.set_intensity_range(-100, 20)
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
self.scope_win.setMinimumSize(800, 420)
elif options.oscilloscope:
@ -266,7 +269,7 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
name="",
nconnections=1
)
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
self.scope_win.setMinimumSize(800, 600)
elif options.qtgui:
@ -281,7 +284,7 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
plottime=True,
plotconst=True
)
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
self.scope.set_update_time(1.0/10)
self.scope_win.setMinimumSize(800, 600)
@ -294,7 +297,7 @@ class app_top_block(gr.top_block, Qt.QMainWindow):
name="",
nconnections=1
)
self.scope_win = sip.wrapinstance(self.scope.pyqwidget(), Qt.QWidget)
self.scope_win = sip.wrapinstance(check_qwidget(), Qt.QWidget)
self.scope.disable_legend()
self.scope_win.setMinimumSize(800, 420)

View File

@ -483,7 +483,7 @@ def main():
app.MainLoop()
except RuntimeError, e:
print e
print(e)
sys.exit(1)
# Make sure to create the top block (tb) within a function: That code

View File

@ -1,27 +0,0 @@
if(NOT GNURADIO_FCDPP_FOUND)
pkg_check_modules (GNURADIO_FCDPP_PKG libgnuradio-fcdproplus)
find_path(GNURADIO_FCDPP_INCLUDE_DIRS NAMES fcdproplus/api.h
PATHS
${GNURADIO_FCDPP_PKG_INCLUDE_DIRS}
/usr/include
/usr/local/include
)
find_library(GNURADIO_FCDPP_LIBRARIES NAMES gnuradio-fcdproplus
PATHS
${GNURADIO_FCDPP_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
)
if(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
set(GNURADIO_FCDPP_FOUND TRUE CACHE INTERNAL "gnuradio-fcdproplus found")
message(STATUS "Found gnuradio-fcdproplus: ${GNURADIO_FCDPP_INCLUDE_DIRS}, ${GNURADIO_FCDPP_LIBRARIES}")
else(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
set(GNURADIO_FCDPP_FOUND FALSE CACHE INTERNAL "gnuradio-fcdproplus found")
message(STATUS "gnuradio-fcdproplus not found.")
endif(GNURADIO_FCDPP_INCLUDE_DIRS AND GNURADIO_FCDPP_LIBRARIES)
mark_as_advanced(GNURADIO_FCDPP_LIBRARIES GNURADIO_FCDPP_INCLUDE_DIRS)
endif(NOT GNURADIO_FCDPP_FOUND)

View File

@ -0,0 +1,27 @@
if(NOT GNURADIO_FUNCUBE_FOUND)
pkg_check_modules (GNURADIO_FUNCUBE_PKG libgnuradio-funcube)
find_path(GNURADIO_FUNCUBE_INCLUDE_DIRS NAMES funcube/api.h
PATHS
${GNURADIO_FUNCUBE_PKG_INCLUDE_DIRS}
/usr/include
/usr/local/include
)
find_library(GNURADIO_FUNCUBE_LIBRARIES NAMES gnuradio-funcube
PATHS
${GNURADIO_FUNCUBE_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
)
if(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
set(GNURADIO_FUNCUBE_FOUND TRUE CACHE INTERNAL "gnuradio-funcube found")
message(STATUS "Found gnuradio-funcube: ${GNURADIO_FUNCUBE_INCLUDE_DIRS}, ${GNURADIO_FUNCUBE_LIBRARIES}")
else(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
set(GNURADIO_FUNCUBE_FOUND FALSE CACHE INTERNAL "gnuradio-funcube found")
message(STATUS "gnuradio-funcube not found.")
endif(GNURADIO_FUNCUBE_INCLUDE_DIRS AND GNURADIO_FUNCUBE_LIBRARIES)
mark_as_advanced(GNURADIO_FUNCUBE_LIBRARIES GNURADIO_FUNCUBE_INCLUDE_DIRS)
endif(NOT GNURADIO_FUNCUBE_FOUND)

View File

@ -1,5 +1,9 @@
if(NOT LIBBLADERF_FOUND)
pkg_check_modules (LIBBLADERF_PKG libbladeRF)
if (LIBBLADERF_PKG_FOUND AND LIBBLADERF_PKG_VERSION VERSION_LESS "2")
message( FATAL_ERROR "Install version 2 or greater of libbladeRF."
" Current version ( ${LIBBLADERF_PKG_VERSION} ) is out of date." )
endif()
find_path(LIBBLADERF_INCLUDE_DIRS NAMES libbladeRF.h
PATHS
${LIBBLADERF_PKG_INCLUDE_DIRS}

View File

@ -138,7 +138,7 @@ endif(ENABLE_IQBALANCE)
########################################################################
# Setup FCD component
########################################################################
GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FCDPP_FOUND)
GR_REGISTER_COMPONENT("FUNcube Dongle" ENABLE_FCD GNURADIO_FUNCUBE_FOUND)
if(ENABLE_FCD)
add_subdirectory(fcd)
endif(ENABLE_FCD)

View File

@ -49,7 +49,7 @@ static size_t const STREAM_TIMEOUT_MS = 3000;
using namespace boost::assign;
std::mutex bladerf_common::_devs_mutex;
std::list<std::weak_ptr<struct bladerf>> bladerf_common::_devs;
std::list<std::weak_ptr<struct bladerf> > bladerf_common::_devs;
/* name for system-wide gain (which is not its own libbladeRF gain stage) */
static const char *SYSTEM_GAIN_NAME = "system";
@ -133,7 +133,7 @@ size_t num_streams(bladerf_channel_layout layout)
* Public methods
******************************************************************************/
bladerf_common::bladerf_common() :
_dev(NULL),
_dev(std::shared_ptr<struct bladerf>()),
_pfx("[bladeRF common] "),
_failures(0),
_num_buffers(NUM_BUFFERS),
@ -1107,7 +1107,7 @@ bladerf_sptr bladerf_common::open(std::string const &device_name)
/* Add the device handle to our cache */
bladerf_sptr dev = bladerf_sptr(raw_dev, bladerf_common::close);
_devs.push_back(static_cast<std::weak_ptr<struct bladerf>>(dev));
_devs.push_back(static_cast<std::weak_ptr<struct bladerf> >(dev));
return dev;
}
@ -1115,7 +1115,7 @@ bladerf_sptr bladerf_common::open(std::string const &device_name)
void bladerf_common::close(void *dev)
{
std::lock_guard<std::mutex> lock(_devs_mutex);
std::list<std::weak_ptr<struct bladerf>>::iterator it(_devs.begin());
std::list<std::weak_ptr<struct bladerf> >::iterator it(_devs.begin());
/* Prune expired entries from device cache */
while (it != _devs.end()) {

View File

@ -287,7 +287,7 @@ private:
* Private members
****************************************************************************/
static std::mutex _devs_mutex; /**< mutex for access to _devs */
static std::list<std::weak_ptr<struct bladerf>> _devs; /**< dev cache */
static std::list<std::weak_ptr<struct bladerf> > _devs; /**< dev cache */
};
#endif

View File

@ -66,7 +66,7 @@
}
/* Changed enums/defines */
#define BLADERF_GAIN_DEFAULT BLADERF_GAIN_AUTOMATIC
#define BLADERF_GAIN_DEFAULT BLADERF_GAIN_MANUAL
#define BLADERF_GAIN_MGC BLADERF_GAIN_MANUAL
#define BLADERF_RX_MUX_BASEBAND BLADERF_RX_MUX_BASEBAND_LMS

View File

@ -174,11 +174,9 @@ bool bladerf_sink_c::start()
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
if (get_channel_enable(brfch)) {
status = bladerf_enable_module(_dev.get(), brfch, true);
if (status != 0) {
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
if (status != 0) {
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
}
@ -210,11 +208,9 @@ bool bladerf_sink_c::stop()
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
bladerf_channel brfch = BLADERF_CHANNEL_TX(ch);
if (get_channel_enable(brfch)) {
status = bladerf_enable_module(_dev.get(), brfch, false);
if (status != 0) {
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
if (status != 0) {
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
}

View File

@ -230,11 +230,9 @@ bool bladerf_source_c::start()
for (size_t ch = 0; ch < get_max_channels(); ++ch) {
bladerf_channel brfch = BLADERF_CHANNEL_RX(ch);
if (get_channel_enable(brfch)) {
status = bladerf_enable_module(_dev.get(), brfch, true);
if (status != 0) {
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
status = bladerf_enable_module(_dev.get(), brfch, get_channel_enable(brfch));
if (status != 0) {
BLADERF_THROW_STATUS(status, "bladerf_enable_module failed");
}
}
@ -344,7 +342,7 @@ int bladerf_source_c::work(int noutput_items,
memcpy(out[0], _32fcbuf, sizeof(gr_complex) * noutput_items);
}
return noutput_items;
return noutput_items/(get_num_channels());
}
osmosdr::meta_range_t bladerf_source_c::get_sample_rates()

View File

@ -23,11 +23,11 @@
target_include_directories(gnuradio-osmosdr PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${GNURADIO_FCDPP_INCLUDE_DIRS}
${GNURADIO_FUNCUBE_INCLUDE_DIRS}
)
APPEND_LIB_LIST(
${GNURADIO_FCDPP_LIBRARIES}
${GNURADIO_FUNCUBE_LIBRARIES}
)
list(APPEND gr_osmosdr_srcs

View File

@ -143,7 +143,7 @@ fcd_source_c::fcd_source_c(const std::string &args) :
if ( FUNCUBE_V1 == _type )
{
_src_v1 = gr::fcdproplus::fcd::make( dev_name );
_src_v1 = gr::funcube::fcd::make( dev_name );
connect( _src_v1, 0, self(), 0 );
set_gain( 20, "LNA" );
@ -152,7 +152,7 @@ fcd_source_c::fcd_source_c(const std::string &args) :
if ( FUNCUBE_V2 == _type )
{
_src_v2 = gr::fcdproplus::fcdproplus::make( dev_name );
_src_v2 = gr::funcube::fcdpp::make( dev_name );
connect( _src_v2, 0, self(), 0 );
set_gain( 1, "LNA" );
@ -237,10 +237,10 @@ osmosdr::freq_range_t fcd_source_c::get_freq_range( size_t chan )
double fcd_source_c::set_center_freq( double freq, size_t chan )
{
if ( FUNCUBE_V1 == _type )
_src_v1->set_freq( float(freq) );
_src_v1->set_freq( freq );
if ( FUNCUBE_V2 == _type )
_src_v2->set_freq( float(freq) );
_src_v2->set_freq( freq );
_freq = freq;

View File

@ -22,8 +22,8 @@
#include <gnuradio/hier_block2.h>
#include <fcdproplus/fcd.h>
#include <fcdproplus/fcdproplus.h>
#include <funcube/fcd.h>
#include <funcube/fcdpp.h>
#include "source_iface.h"
@ -81,10 +81,10 @@ public:
private:
dongle_type _type;
gr::fcdproplus::fcd::sptr _src_v1;
gr::fcdproplus::fcdproplus::sptr _src_v2;
gr::funcube::fcd::sptr _src_v1;
gr::funcube::fcdpp::sptr _src_v2;
double _lna_gain, _mix_gain, _bb_gain, _freq;
int _correct;
double _correct;
};
#endif // FCD_SOURCE_C_H

View File

@ -32,6 +32,8 @@
class sink_iface
{
public:
virtual ~sink_iface() = default;
/*!
* Get the number of channels the underlying radio hardware offers.
* \return the number of available channels

View File

@ -245,6 +245,13 @@ sink_impl::sink_impl( const std::string &args )
if (!_devs.size())
throw std::runtime_error("No devices specified via device arguments.");
/* Populate the _gain and _gain_mode arrays with the hardware state */
for ( sink_iface *dev : _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
_gain_mode[dev_chan] = dev->get_gain_mode(dev_chan);
_gain[dev_chan] = dev->get_gain(dev_chan);
}
}
size_t sink_impl::get_num_channels()

View File

@ -32,6 +32,8 @@
class source_iface
{
public:
virtual ~source_iface() = default;
/*!
* Get the number of channels the underlying radio hardware offers.
* \return the number of available channels

View File

@ -403,6 +403,13 @@ source_impl::source_impl( const std::string &args )
if (!_devs.size())
throw std::runtime_error("No devices specified via device arguments.");
/* Populate the _gain and _gain_mode arrays with the hardware state */
for ( source_iface *dev : _devs )
for (size_t dev_chan = 0; dev_chan < dev->get_num_channels(); dev_chan++) {
_gain_mode[dev_chan] = dev->get_gain_mode(dev_chan);
_gain[dev_chan] = dev->get_gain(dev_chan);
}
}
size_t source_impl::get_num_channels()