Skip to content

Commit

Permalink
Add support for FreeSRP
Browse files Browse the repository at this point in the history
This patch adds support for both receiving and transmitting using
the FreeSRP. More information on the FreeSRP can be found at:

http://freesrp.org

The gr-osmosdr blocks added make use of libfreesrp, the library
required for interfacing with this device. The libfreesrp source
code is freely available at

https://github.com/freesrp/libfreesrp

Usage example:

osmocom_fft -a "freesrp"
  • Loading branch information
Lukas Lao Beyer authored and Dimitri Stolnikov committed Apr 18, 2017
1 parent e9dde9a commit 5ecfa25
Show file tree
Hide file tree
Showing 21 changed files with 2,716 additions and 0 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -6,3 +6,4 @@ Josh Blum
SDRplay Ltd.
Pavel Demin
Marcus Müller
Lukas Lao Beyer
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -172,6 +172,7 @@ find_package(LibAIRSPY)
find_package(Volk)
find_package(LibbladeRF)
find_package(SoapySDR NO_MODULE)
find_package(LibFreeSRP)
find_package(Doxygen)

if(NOT GNURADIO_RUNTIME_FOUND)
Expand Down
1 change: 1 addition & 0 deletions README
Expand Up @@ -17,6 +17,7 @@ as well supports:
* Ettus USRP Devices through Ettus UHD library
* Fairwaves UmTRX through Fairwaves' fork of UHD
* Red Pitaya SDR transceiver (http://bazaar.redpitaya.com)
* FreeSRP through libfreesrp

By using the OsmoSDR block you can take advantage of a common software api in
your application(s) independent of the underlying radio hardware.
Expand Down
27 changes: 27 additions & 0 deletions cmake/Modules/FindLibFreeSRP.cmake
@@ -0,0 +1,27 @@
if(NOT LIBFREESRP_FOUND)
pkg_check_modules (LIBFREESRP_PKG libfreesrp)
find_path(LIBFREESRP_INCLUDE_DIRS NAMES freesrp.hpp
PATHS
${LIBFREESRP_PKG_INCLUDE_DIRS}
/usr/include
/usr/local/include
)

find_library(LIBFREESRP_LIBRARIES NAMES freesrp
PATHS
${LIBFREESRP_PKG_LIBRARY_DIRS}
/usr/lib
/usr/local/lib
)

if(LIBFREESRP_INCLUDE_DIRS AND LIBFREESRP_LIBRARIES)
set(LIBFREESRP_FOUND TRUE CACHE INTERNAL "libfreesrp found")
message(STATUS "Found libfreesrp: ${LIBFREESRP_INCLUDE_DIRS}, ${LIBFREESRP_LIBRARIES}")
else(LIBFREESRP_INCLUDE_DIRS AND LIBFREESRP_LIBRARIES)
set(LIBFREESRP_FOUND FALSE CACHE INTERNAL "libfreesrp found")
message(STATUS "libfreesrp not found.")
endif(LIBFREESRP_INCLUDE_DIRS AND LIBFREESRP_LIBRARIES)

mark_as_advanced(LIBFREESRP_LIBRARIES LIBFREESRP_INCLUDE_DIRS)

endif(NOT LIBFREESRP_FOUND)
2 changes: 2 additions & 0 deletions grc/gen_osmosdr_blocks.py
Expand Up @@ -229,6 +229,7 @@
* Ettus USRP Devices through Ettus UHD library
* Fairwaves UmTRX through Fairwaves' fork of UHD
* Red Pitaya SDR transceiver (http://bazaar.redpitaya.com)
* FreeSRP through libfreesrp library
By using the osmocom $sourk block you can take advantage of a common software api in your application(s) independent of the underlying radio hardware.
Expand Down Expand Up @@ -264,6 +265,7 @@
file='/path/to/your file',rate=1e6[,freq=100e6][,append=true][,throttle=true] ...
#end if
redpitaya=192.168.1.100[:1001]
freesrp=0[,fx3='path/to/fx3.img',fpga='path/to/fpga.bin',loopback]
hackrf=0[,buffers=32][,bias=0|1][,bias_tx=0|1]
bladerf=0[,tamer=internal|external|external_1pps][,smb=25e6]
uhd[,serial=...][,lo_offset=0][,mcr=52e6][,nchan=2][,subdev='\\\\'B:0 A:0\\\\''] ...
Expand Down
8 changes: 8 additions & 0 deletions lib/CMakeLists.txt
Expand Up @@ -240,6 +240,14 @@ if(ENABLE_REDPITAYA)
GR_INCLUDE_SUBDIRECTORY(redpitaya)
endif(ENABLE_REDPITAYA)

########################################################################
# Setup FreeSRP component
########################################################################
GR_REGISTER_COMPONENT("FreeSRP support" ENABLE_FREESRP LIBFREESRP_FOUND)
if(ENABLE_FREESRP)
GR_INCLUDE_SUBDIRECTORY(freesrp)
endif(ENABLE_FREESRP)

########################################################################
# Setup configuration file
########################################################################
Expand Down
1 change: 1 addition & 0 deletions lib/config.h.in
Expand Up @@ -18,6 +18,7 @@
#cmakedefine ENABLE_AIRSPY
#cmakedefine ENABLE_SOAPY
#cmakedefine ENABLE_REDPITAYA
#cmakedefine ENABLE_FREESRP

//provide NAN define for MSVC older than VC12
#if defined(_MSC_VER) && (_MSC_VER < 1800)
Expand Down
8 changes: 8 additions & 0 deletions lib/device.cc
Expand Up @@ -86,6 +86,10 @@
#include <redpitaya_source_c.h>
#endif

#ifdef ENABLE_FREESRP
#include <freesrp_source_c.h>
#endif

#include "arg_helpers.h"

using namespace osmosdr;
Expand Down Expand Up @@ -182,6 +186,10 @@ devices_t device::find(const device_t &hint)
BOOST_FOREACH( std::string dev, airspy_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_FREESRP
BOOST_FOREACH( std::string dev, freesrp_source_c::get_devices() )
devices.push_back( device_t(dev) );
#endif
#ifdef ENABLE_SOAPY
BOOST_FOREACH( std::string dev, soapy_source_c::get_devices() )
devices.push_back( device_t(dev) );
Expand Down
39 changes: 39 additions & 0 deletions lib/freesrp/CMakeLists.txt
@@ -0,0 +1,39 @@
# Copyright 2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.

########################################################################
# This file included, use CMake directory variables
########################################################################

include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${LIBFREESRP_INCLUDE_DIRS}
)

set(freesrp_srcs
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_common.cc
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_source_c.cc
${CMAKE_CURRENT_SOURCE_DIR}/freesrp_sink_c.cc
)

########################################################################
# Append gnuradio-osmosdr library sources
########################################################################
list(APPEND gr_osmosdr_srcs ${freesrp_srcs})
list(APPEND gr_osmosdr_libs ${LIBFREESRP_LIBRARIES})
199 changes: 199 additions & 0 deletions lib/freesrp/freesrp_common.cc
@@ -0,0 +1,199 @@
#include "freesrp_common.h"

#include <cstdlib>

#include <boost/make_shared.hpp>
#include <boost/assign.hpp>

#include <arg_helpers.h>

using namespace FreeSRP;
using namespace std;
using namespace boost::assign;

boost::shared_ptr<::FreeSRP::FreeSRP> freesrp_common::_srp;

freesrp_common::freesrp_common(const string &args)
{
dict_t dict = params_to_dict(args);

if(!_srp)
{
try
{
string serial = "";

if(dict.count("freesrp"))
{
serial = dict["freesrp"];
}

if(dict.count("fx3"))
{
if(Util::find_fx3())
{
// Upload firmware to FX3
string firmware_path = string(getenv("HOME")) + "/.freesrp/fx3.img";
if(dict["fx3"].length() > 0)
{
firmware_path = dict["fx3"];
}
Util::find_fx3(true, firmware_path);
cout << "FX3 programmed with '" << firmware_path << "'" << endl;
// Give FX3 time to re-enumerate
this_thread::sleep_for(chrono::milliseconds(600));
}
else
{
cout << "No FX3 in bootloader mode found" << endl;
}
}

_srp.reset(new ::FreeSRP::FreeSRP(serial));

if(dict.count("fpga") || !_srp->fpga_loaded())
{
string bitstream_path = string(getenv("HOME")) + "/.freesrp/fpga.bin";
if(dict["fpga"].length() > 0)
{
bitstream_path = dict["fpga"];
}
fpga_status stat = _srp->load_fpga(bitstream_path);
switch(stat)
{
case FPGA_CONFIG_ERROR:
throw runtime_error("Could not load FPGA configuration!");
case FPGA_CONFIG_SKIPPED:
cout << "FPGA already configured. Restart the FreeSRP to load a new bitstream." << endl;
break;
case FPGA_CONFIG_DONE:
cout << "FPGA configured with '" << bitstream_path << "'" << endl;
break;
}
}

cout << "Connected to FreeSRP" << endl;

if(dict.count("loopback"))
{
response res = _srp->send_cmd({SET_LOOPBACK_EN, 1});
if(res.error == CMD_OK)
{
cout << "AD9364 in loopback mode" << endl;
}
else
{
throw runtime_error("Could not put AD9364 into loopback mode!");
}
}
else
{
response res = _srp->send_cmd({SET_LOOPBACK_EN, 0});
if(res.error != CMD_OK)
{
throw runtime_error("Error disabling AD9364 loopback mode!");
}
}

if(dict.count("ignore_overflow"))
{
_ignore_overflow = true;
}
else
{
_ignore_overflow = false;
}
}
catch(const runtime_error& e)
{
cerr << "FreeSRP Error: " << e.what() << endl;
throw runtime_error(e.what());
}
}
}

vector<string> freesrp_common::get_devices()
{
vector<string> devices;

try
{
::FreeSRP::FreeSRP srp;

string str;
str = "freesrp=0,label='FreeSRP'";

devices.push_back(str);
}
catch(const ConnectionError &err)
{
// No FreeSRP found.
}

return devices;
}

size_t freesrp_common::get_num_channels( void )
{
return 1;
}

osmosdr::meta_range_t freesrp_common::get_sample_rates( void )
{
osmosdr::meta_range_t range;

// Any sample rate between 1e6 and 61.44e6 can be requested.
// This list of some integer values is used instead of
// range += osmosdr::range_t(1e6, 61.44e6);
// because SoapyOsmo seems to handle the range object differently.
range += osmosdr::range_t(1e6);
range += osmosdr::range_t(8e6);
range += osmosdr::range_t(16e6);
range += osmosdr::range_t(20e6);
range += osmosdr::range_t(40e6);
range += osmosdr::range_t(50e6);
range += osmosdr::range_t(61.44e6);

return range;
}

osmosdr::freq_range_t freesrp_common::get_freq_range(size_t chan)
{
osmosdr::meta_range_t freq_ranges;

freq_ranges.push_back(osmosdr::range_t(7e7, 6e9, 2.4));

return freq_ranges;
}


osmosdr::freq_range_t freesrp_common::get_bandwidth_range(size_t chan)
{
osmosdr::meta_range_t range;

//range += osmosdr::range_t(2e5, 56e6);

range += osmosdr::range_t(2e5);
range += osmosdr::range_t(1e6);
range += osmosdr::range_t(8e6);
range += osmosdr::range_t(16e6);
range += osmosdr::range_t(20e6);
range += osmosdr::range_t(40e6);
range += osmosdr::range_t(50e6);
range += osmosdr::range_t(56e6);

return range;
}


double freesrp_common::set_freq_corr( double ppm, size_t chan )
{
// TODO: Set DCXO tuning
return 0;
}

double freesrp_common::get_freq_corr( size_t chan )
{
// TODO: Get DCXO tuning
return 0;
}
29 changes: 29 additions & 0 deletions lib/freesrp/freesrp_common.h
@@ -0,0 +1,29 @@
#ifndef INCLUDED_FREESRP_COMMON_H
#define INCLUDED_FREESRP_COMMON_H

#include <vector>
#include <string>

#include "osmosdr/ranges.h"

#include <freesrp.hpp>

class freesrp_common
{
protected:
freesrp_common(const std::string &args);
public:
static std::vector<std::string> get_devices();

size_t get_num_channels( void );
osmosdr::meta_range_t get_sample_rates( void );
osmosdr::freq_range_t get_freq_range( size_t chan = 0 );
osmosdr::freq_range_t get_bandwidth_range( size_t chan = 0 );
double set_freq_corr( double ppm, size_t chan = 0 );
double get_freq_corr( size_t chan = 0 );
protected:
static boost::shared_ptr<::FreeSRP::FreeSRP> _srp;
bool _ignore_overflow = false;
};

#endif

0 comments on commit 5ecfa25

Please sign in to comment.