Below are some of the many papers involving GNU Radio and/or the USRP
Please feel free to add a summary, bibliographic info, and a link to your papers.
Lappeenranta University of TechnologyETH Zürich (Switzerland), System Security Group
University of Texas at Austin, Hydra Project
Virginia Tech, Center for Wireless Telecommunications (CWT)
Papers from Virginia Tech's Center for Wireless Telecommunications (CWT), a member of Wireless@VT, that specifically deal with SDR and cognitive radio techniques employing GNU Radio or USRP (links to papers will be provided later):
Karlsruhe Institute of Technology (Communications Engineering Lab)
University of California in LA, Networked & Embedded Systems Lab (NESL)
University of Delaware
University of Maryland
University of Pisa (Italy), DSP for Communications Lab
University of Washington, Magnetic Resonance Force Microscopy (MRFM)
University College London
Massachusetts Institute of Technology (MIT)
Royal Institute of Technology (KTH)
A decibel (dB) is a logarithmic comparison of two power measurements.
Let P1 and P2 be two measurements of power.
A Bel (as in Alexander Graham Bell) is defined as
B = log10 (P1 / P2)
A Bel is a huge difference, so customarily a tenth of a bel, or deciBel is used.
dB = 10 * log10 (P1 / P2)
(Decibels have never made any sense to me -- John Gilmore -- but Bels make
perfect sense. So just divide by ten and think in Bels, which are just
logarithms base ten. Thus 20dB is 2 Bels which is a factor of 100. Why the radio
world complicated the simplicity of logs by multiplying them all by ten baffles me -- it's like calculating in furlongs per fortnight.)
In the electrical domain, it's sometimes more convenient to measure voltage than power.
Volts can be related to power like this: P = V*V / R, where R is a resistance.
That is, power goes as the square of voltage.
For two voltages V1 and V2, measured across two resistances (impedances) R1 and R2 a little algebra gives you:
P1 = V1^2 / R1
P2 = V2^2 / R2
dB = 10 * log10 ((V1^2 / R1) / (V2^2 / R2))
If R1 == R2, this simplifies to
dB = 10 * log10 ((V1/V2)^2)
db = 10 * 2 * log10 (V1/V2)
db = 20 * log10 (V1/V2)
If you thought that was simple, they've thought of more stuff to complicate
your life. A dBm is a dB value calculated against a 1-milliwatt value.
Yep, not one watt, but a thousandth of a watt. Again the bogons have inserted
random factors into what ought to be simple.
Thus a 5dBm signal is a 0.5 Bel signal times 0.001 watt. 0.5 Bel is 10**0.5
or about 3.16. Thus 5 dBm is an inconvenient way to write 0.00316 watts. Didn't you always want to know
that?
Power
3 dB is a factor of 2 [10 * log10 (2) = 3.01]
6 dB is a factor of 4
10 dB is a factor of 10
20 dB is a factor of 100
-3 dB is a factor of 1/2
-6 dB is a factor of 1/4
-10 dB is a factor of 1/10
-20 dB is a factor of 1/100
Voltage
3 dB is a factor of 1.414
6 dB is a factor of 2
12 dB is a factor of 4
20 dB is a factor of 10
40 dB is a factor of 100
-3 dB is a factor of 0.707
-6 dB is a factor of 1/2
-12 dB is a factor of 1/4
-20 dB is a factor of 1/10
-40 dB is a factor of 1/100
----
CategoryDefinition
AM demodulation block, 10 KHz channel.
This block demodulates an AM channel conformant to 10K0A3E emission
standards, such as broadcast band AM transmissions.
@param channel_rate: incoming sample rate of the AM baseband
@type sample_rate: integer
@param audio_decim: input to output decimation rate
@type audio_decim: integer
This section documents the interfaces to programs and functions that are part of GNU Radio.
While the eventual goal is for this section to provide complete documentation on all programs and functions, this is a slow, evolutionary process that will probably never be more than partially completed. Therefore, to provide the greatest utility as quickly as possible, this section focuses on items NOT contained in other obvious places - most specifically any command line help option that is available for the program or function in question.
USAGE: usrp_rx_cfile.py [options] outputfilename
(NOTE: Contrary to the above description, the -f option is not optional)
LOCATION: gnuradio-examples/python/usrp
PURPOSE: To record data from a USRP RX (receiver) Daughterboard and dump it to a file.
OUTPUT: The data is written to the file as binary I,Q pairs. By default, values are IEEE single-precision (4-byte) floats but 16-bit integers can be selected using the -s option. The Endian-ness of the data is that of the processor.
DESCRIPTION: Set mixer frequency.
FORMAT: Engineering notation - a float followed immediately by an S.I. suffix (e.g., 3M or 2.9k).
DEFAULT VALUE: none (this is a required option - and, yes, that's an oxymoron)
FREQ is the frequency for the quadrature mixer located on the USRP. The incoming signal is multiplied by sin(FREQ*2pi*t) to yield the I output and cos(FREQ*2pi*t) to yield the Q output. This results in a frequency translation of the signal.
FREQ can be any value from -f~s~/2 to +f~s~/2. A value of 0 will result in no signal on the I output and the input signal being transferred directly to the Q output (after passing through the decimation filter).DESCRIPTION: Select signal source.
FORMAT: {A,B}[:{0,1}] (e.g., A or B:1)
DEFAULT VALUE: A (same as A:0)
The USRP has two slots for RX daughterboards, RXA and RXB. This option selects which daughterboard the data will be taken from. The RX daughterboard selected may also have two input ports, in which case a number following a colon can be added to select which one with :0 selecting the first input and :1 selecting the other. For instance, on the BasicRX board, the inputs are labeled "RX-A" and "RX-B", if this board is plugged into RXB on the USRP, then B:0 will select RX-A on this board while B:1 will select RX-B on it.DESCRIPTION: Set decimation factor.
FORMAT: An even integer in the range from 4 to 256
DEFAULT: 16
The output from the mixer is decimated by a factor of decimation factor
The USRP sampling frequency is typically 64 MSa/s, so a decimation factor of 64 will result in an effective sampling rate of 1 MSa/s being written to the file.DESCRIPTION: Set limit on number of samples to acquire.
FORMAT: positive integer
DEFAULT: infinity
The program is to terminate after collecting and writing the specified number of samples to the file. By default, the program will continue writing data until killed by the User.DESCRIPTION: Change output format to short integers instead of floats
FORMAT: No arguments
DEFAULT: IEEE single-precision (32-bit) floats.
If specified, the program will output 16-bit signed integers instead of 32-bit floats.$ sudo pacman -S fftw wxpython libusb guile swig cppunit boost portaudio sdl gputils alsa-utils
$ makepkg
$ sudo pacman -U sdcc-XXX.pkg.tar.gz
$ yaourt -S sdcc
It may be necessary to downgrade some packages, as Arch typically has the very latest gcc and python, and gnuradio may not be ported to the latest versions yet. For instructions on how to do so consult the Arch Linux wiki
$ ./configure $ make $ make check $ sudo make install.
PYTHONPATH=/usr/local/lib/python2.6/site-packages PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
ADROIT was a project funded by DARPA's ACERT program to create collaborative teams of cognitive software radios.
ADROIT uses GNU Radio and has implemented an 802.11 receiver.
ADROIT also provided funding for development of m-blocks.
The 802.11 code may be found on the ACERT Collaboration Server within the adroitgrdevel project.
The CVS repository may be browsed.
See also hints for 802.11 usage.
The GNU Radio source code build system uses the standard method:
$ ./configure $ make $ sudo make install
or using an alternate build directory:
$ mkdir build $ cd build $ ../configure $ make $ sudo make install
to build and install the software. This is a sufficient starting point for most users.
GNU Radio consists of a set of component libraries, simply called "components" in what follows.
Each component lives in a separate directory off the source code tree root, and has a set of prerequisites for which the 'configure' script tests. Depending on the outcome of these configuration checks, the build system either selects or deselects individual components to build, test, and install. The default behavior is to perform all configuration tests, build all components that pass, and ignore the ones that don't.
Some users may wish to have finer control over what gets built and what does not, and the build system provides a facility to accomplish that. The build system also allows for incremental installation of individual components.
Three options exist for each component in the GNU Radio source code tree:
--enable-foo --disable-foo --with-foo[=arg]
where *foo* is the directory name of the component to be affected, and for the last option *arg* is the full path to the pkg-config file for foo ('foo.pc').
There are also:
--enable-all-components --disable-all-components
These apply to all components in the tree that are not further specified on the configure script command line.
Specifying --enable-foo causes the build system to consider it an error if configuration checks fail for the *foo* component, and exit with an error when that happens ('error out'). This option is suitable for ensuring that a particular component gets built and installed, or for understanding why configure errored out when the checks fail.
Specifying --disable-foo prevents that component from being built or installed even if its configuration checks pass. This option is suitable for components that you're not interested in or you know ahead of time won't pass configuration checks.
Specifying --enable-all-components or --disable-all-components applies the above behavior to everything that isn't otherwise specified later in the command line.
Specifying --with-foo causes the build system to look for the pkg-config file, using the provided PKG_CONFIG_PATH environment variable, for *foo* as evidence that the component *foo* is already installed. If *foo* is not already installed, the an error will be printed and configuration will stop. Significant efforts have been made to ensure that if --with-foo is specified, and *foo* is installed, then the paths to *foo*'s libraries and header files will not interfere with those from the --enable'd components.
Speficying --with-foo=arg is the same as --with-foo, except that component *foo* is searched for solely using PKG_CONFIG_PATH=arg.
NOTE: Specifying both --enable-foo and --with-foo will result in an error.
NOTE: When using --with-foo[=arg] : Because the build system uses pkg-config to locate components, PKG_CONFIG_PATH must include the full path (e.g. "/opt/local/lib/pkgconfig") of those packages unless they are installed in the --prefix provided to configure since that path is internally prepended to PKG_CONFIG_PATH.
WARNING: It is possible to install components into different --prefix's, and thus to include them as pre-installed using the --with option. The build system will use the first found pkg-config file for any given pre-installed and --with included component.
Default Behavior:
$ ./configure
Select for build and installation everything that passes configuration checks.
Checking for Everything:
$ ./configure --enable-all-components
Select everything for build and installation, except exit with an error message if any configuration check doesn't pass. This will likely fail for everyone because some platform-specific configuration checks are mutually exclusive (such as the various audio modules for different systems).
Selective Build:
$ ./configure --enable-all-components \
--disable-foo1 \
--disable-foo2
where *foo1* and *foo2* are components that will fail and you don't care about, or that you don't want to build regardless. Otherwise you want the build to fail if anything else fails configuration checks. For example, on a Linux system that otherwise has all the build dependent libraries installed:
$ ./configure --enable-all-components \
--disable-gr-audio-osx \
--disable-gr-audio-windows \
--disable-gr-audio-oss
will ignore the non-Linux platform modules as well as the OSS audio stuff (which would otherwise compile ok).
Build Using Pre-Installed Components:
$ ./configure --disable-all-components \
--enable-foo1 \
--with-foo2
will try to build component *foo1* using just the already-installed library and header files for component *foo2* as found by pkg-config in the provided PKG_CONFIG_PATH.
Build Using Pre-Installed Components at a Specific Location:
$ ./configure --disable-all-components \
--enable-foo1 \
--with-foo2=bar
will try to build component *foo1* using just the already-installed library and header files for component *foo2* as found by pkg-config in PKG_CONFIG_PATH=bar.
To select a single component to build and install, use:
$ ./configure --disable-all-components \
--enable-foo
where *foo* is a single component directory. This will cause the build to fail if *foo* doesn't pass configuration checks, and ignore any other packages.
WARNING: Individual GNU Radio components generally depend upon other components (such as *gnuradio-core*) to successfully compile. When using --disable-all-components, each component dependency must be specified via an --enable or --with option. The build system will produce an error if dependencies are not met, and most likely that component build will be skipped.
For example, component *gr-usrp* depends on components *usrp* and *gnuradio-core*. The former depends on components *omnithread*, *mblock*, and *pmt*. The latter depends on the component *omnithread*, which is redundant with the *usrp*'s dependencies. Hence, from a fresh source code build with nothing already installed, one would need to use the following command line in order to try to build *gr-usrp*:
$ ./configure --disable-all-components \
--enable-gr-usrp \
--enable-gnuradio-core \
--enable-usrp \
--enable-pmt \
--enable-mblock \
--enable-omnithread
The order of these on the configure command line is not important; the build system knows the proper order in which to build them.
As another example, suppose that components *usrp* (and its dependents) are already installed, via the commands:
$ ./configure --disable-all-components \
--enable-usrp \
--enable-pmt \
--enable-mblock \
--enable-omnithread
$ make
$ sudo make install
Then one could use those pre-installed components and build *gr-usrp* via the command:
$ ./configure --disable-all-components \
--enable-gr-usrp
--enable-gnuradio-core \
--with-usrp \
--with-pmt \
--with-mblock \
--with-omnithread
Regardless of what gets enabled, disabled, or included via --with-foo[=arg], the 'make dist' and 'make distcheck' operations will create a source distribution tarball of the entire collection of components.
To build and install GNU Radio, you may either download a release tarball, or you may use the git client software to check out code from our git repository. Some operating systems may have binary installation packages available; see Operating System Specific Instructions below.
To checkout the latest stable release code, go to:http://gnuradio.org/releases/gnuradioTo instead checkout the latest code from the development trunk, enter this on the command line:
$ git clone http://gnuradio.org/git/gnuradio.git
In general, if you are developing GNU Radio applications which need to depend on the stability of the features and API of GNU Radio components, it is recommended that you use the 3.3 stable release series.
To get a handle on what's going on, clone the repository (if you haven't already), then run "qgit" or one of the other git viewers on it. It will show you all of the branching and merging, diffs, etc.
First, ensure that you've fulfilled the dependencies specified in the top-level
http://gnuradio.org/redmine/repositories/changes/gnuradio/README.
Most GNU/Linux systems come with our dependencies already packaged.
You may need to install them off of your install CD/DVD or over the net.
See below for Operating System specific notes.
To compile, there are 5 steps. Start by cd'ing to the gnuradio directory, then complete the
following commands:
$ ./bootstrap # Do NOT perform this step if you are building from a tarball. $ ./configure $ make $ make check $ sudo make install
This will perform all configuration checks and select for build, test, and installation all components that pass.
For finer control, read the instructions at BuildConfiguration.
1) Uninstall gnuradio:
$ sudo make uninstall
2) To restore the original git files from any added files during an old build:
$ git clean -d -x -f
Then you can bootstrap, configure, make, etc.
By default, gnuradio will automatically builds documentation if doxygen and xmlto programs are installed prior to installing gnuradio, so make sure they are installed in your system. Doxygen is used to build the gnuradio C++ API documentation. The generated documents can be found and browsed at docs/doxygen/html/index.html. The xmlto is used to convert the extra documentation xml files (found in usrp, gr-trellis,..etc folders) to html files.
This section links to guides which go into more specific detail for a given operating system, outlining how to fulfill the build prerequisites, any non-standard build steps that must be taken, and general configuration issues. If a given operating system has binary installation packages or another automated way to build GNU Radio, it will be listed here.
To compile the verilog source code for the fpga firmware for the usrp you need Altera Quartus II Web Edition. This is only needed if you change the verilog code, since the distribution contains precompiled versions of this firmware.
How to run Quartus II under Linux
openbts-2.5.4Lacassine.tar.gz:https://sourceforge.net/projects/openbts/
gnuradio-3.2.2.tar.gz:ftp://ftp.gnu.org/gnu/gnuradio/
libosip2-3.3.0.tar.gz:http://ftp.gnu.org/gnu/osip/
ortp-0.16.1.tar.gz:http://download.savannah.nongnu.org/releases/linphone/ortp/sources/
tar zxvf *.gz
ln -s openbts-2.5.4Lacassine openbts
ln -s gnuradio-3.2.2.tar.gz gnuradio
ln -s libosip2-3.3.0.tar.gz libosip
ln -s ortp-0.16.1.tar.gz ortp
cd gnuradio
./configure --disable-all-components --enable-usrp --enable-omnithread --enable-mblock --enable-pmt
make install
cd ../libosip2
./configure ; make install
cd ../ortp
./configure ; make install
cd openbts
./configure ; make install
Q:找不到usrp包
A:由于cygwin似乎不到/usr/local/lib/pkgconfig/ 里读包信息,所以要复制到他能读到的地方
cp /usr/local/lib/pkgconfig/* /usr/lib/pkgconfig/
Q:缺少USRP相关的头文件
A:安装似乎会少生成usrp目录,和相关的头文件,所以手工复制一下
mkdir /usr/include/usrp
cp gnuradio/usrp/host/lib/legacy/*.h /usr/include/usrp
Q:说tm结构里少tm_gmtoff
A:找到/usr/include/time.h 加入以下代码
#define tm_gmtoff tm_isdst
Q: openbts会报F16.h里有错误
A: 根据以下代码进行修改
F16 operator=(const F16& other)
{
mV = other.mV;
return mV;
}
F16 operator=(const F16& other)
{
mV = other.mV;
return this/*mV/;
}
Q:在Tranceiver里说不能引用 usrp_.........
A:在Makefile里找到USRP_LIBS 改成
USRP_LIBS = -lusrp
Q:ortp会有一些INET6的出错
A:因为CYGWIN缺少IPV6的一些头文件,所以禁用ipv6也不能解决问题,需要对源码进和编辑。
ortp/src/rtpsession_inet.c 里找到 AF_INET6
把相应的case 块用 #ifdef ORTP_INET6 和 #endif 包围起来
1.准备驱动程序
mkdir usrpinf
cp /usr/lib/libusb0.sys usrpinf/
cp /usr/bin/cygusb0.dll usrpinf/libusb0.dll
cp gnuradio/usrp/*.inf usrpinf/
2.连接USRP
3.从上面准备好的usrpinf手动安装驱动程序
4. cd openbts/Transceiver/
5. ./USRPping
6.再次安装驱动程序
7.USRP安装结束
Port GNU Radio to the Cell Processor.
Low-level interface to the AE6HO EZ Doppler radiolocation hardware. Can be used outside the GNU Radio framework.
[source:/gnuradio/trunk/ezdop /gnuradio/trunk/ezdop]
Current tickets regarding ezdop.
[source:/gnuradio/trunk/gnuradio-core /gnuradio/trunk/gnuradio-core]
TicketQuery(component=gnuradio-core&
TicketQuery(component=gnuradio-core&
TicketQuery(component=gnuradio-core&
Example programs on how to use the GNU Radio software package.
[source:/gnuradio/trunk/gnuradio-examples /gnuradio/trunk/gnuradio-examples]
Current tickets regarding gnuradio-examples.
TicketQuery(component=gnuradio-examples&
TicketQuery(component=gnuradio-examples&
TicketQuery(component=gnuradio-examples&
Implementation of Advanced Television Systems Committee ATSC digital video standard.
[source:/gnuradio/trunk/gr-atsc /gnuradio/trunk/gr-atsc]
Current tickets regarding gr-atsc.
TicketQuery(component=gr-atsc&
TicketQuery(component=gr-atsc&
TicketQuery(component=gr-atsc&
Interface to the Advanced Linux Sound Architecture (ALSA).
[source:/gnuradio/trunk/gr-audio-alsa /gnuradio/trunk/gr-audio-alsa]
Current tickets regarding gr-audio-alsa.
TicketQuery(component=gr-audio-alsa&
TicketQuery(component=gr-audio-alsa&
TicketQuery(component=gr-audio-alsa&
Interface to the Jack Audio Connection Kit (JACK).
[source:/gnuradio/trunk/gr-audio-jack /gnuradio/trunk/gr-audio-jack]
Current tickets regarding gr-audio-jack.
TicketQuery(component=gr-audio-jack&
TicketQuery(component=gr-audio-jack&
TicketQuery(component=gr-audio-jack&
Interface to the Open Sound System audio API (OSS).
[source:/gnuradio/trunk/gr-audio-oss /gnuradio/trunk/gr-audio-oss]
Current tickets regarding gr-audio-oss.
TicketQuery(component=gr-audio-oss&
TicketQuery(component=gr-audio-oss&
TicketQuery(component=gr-audio-oss&
Interface to the Mac OSX audio subsystem
[source:/gnuradio/trunk/gr-audio-osx /gnuradio/trunk/gr-audio-osx]
Current tickets regarding gr-audio-osx.
TicketQuery(component=gr-audio-osx&
TicketQuery(component=gr-audio-osx&
TicketQuery(component=gr-audio-osx&
Interface to the PortAudio portable cross-platform audio API.
[source:/gnuradio/trunk/gr-audio-portaudio /gnuradio/trunk/gr-audio-portaudio]
Current tickets regarding gr-audio-portaudio.
TicketQuery(component=gr-audio-portaudio&
TicketQuery(component=gr-audio-portaudio&
TicketQuery(component=gr-audio-portaudio&
Interface to the Win32 audio subsystem.
[source:/gnuradio/trunk/gr-audio-windows /gnuradio/trunk/gr-audio-windows]
Current tickets regarding gr-audio-windows.
TicketQuery(component=gr-audio-windows&
TicketQuery(component=gr-audio-windows&
TicketQuery(component=gr-audio-windows&
Interface to the Linux Control and Measurement Device Interface API.
[source:/gnuradio/trunk/gr-comedi /gnuradio/trunk/gr-comedi]
Current tickets regarding gr-comedi.
TicketQuery(component=gr-comedi&
TicketQuery(component=gr-comedi&
TicketQuery(component=gr-comedi&
Implementation of various error correcting channel codes.
[source:/gnuradio/trunk/gr-error-correcting-codes /gnuradio/trunk/gr-error-correcting-codes]
Current tickets regarding gr-error-correcting-codes.
TicketQuery(component=gr-error-correcting-codes&
TicketQuery(component=gr-error-correcting-codes&
TicketQuery(component=gr-error-correcting-codes&
Low-level interface to the AE6HO EZ Doppler radiolocation hardware. Can be used outside the GNU Radio framework.
[source:/gnuradio/trunk/gr-ezdop /gnuradio/trunk/gr-ezdop]
Current tickets regarding gr-ezdop.
TicketQuery(component=gr-ezdop&
TicketQuery(component=gr-ezdop&
TicketQuery(component=gr-ezdop&
gr-gpio is an extension to the normal USRP firmware, implemented as an alternative FPGA bitstream, using the existing USRP host code. With the gr-gpio component you can transmit and receive a digital stream to and from the USRP which is aligned with the existing analog stream. Digital data is sent to or received from the daughterboard GPIO pins and sacrifice one bit each from the I and the Q analog streams to transport the digital bits.
Digital streams are sampled from GPIO 14 and GPIO 15 from the selected daughterboard and replace the LSB of the I and Q analog streams, respectively. In the host, on can then use usrp.source_s() to obtain the combined streams and separate them with logical bit operations. The GPIO pins are sampled at the decimated RF rate; that is, the GPIO data replaces the LSBs at the output of the digital downconverter. As a result of pipeline delays in the analog processing stream, there will be a fixed but decimation rate dependent delta between the analog and digital streams.
In the host, one uses usrp.sink_s() and encodes the desired digital data into the LSBs of the I and Q sample data. These are then routed to GPIO 14 and GPIO 15 of the selected daughterboard. The data is output on the GPIO pins at the same rate as the sample data arriving over the USB. Due to pipeline delays in the analog processing stream, there will be a fixed but interpolation rate dependent delta between the analog and digital streams.
Note: The headers on the daughterboards have a line of ground pins next to the gpio pins. Also, it is not safe for some daughterboards to connect all pins on the RX header to all pins of the TX header using a flat cable for a loopback test. Only connect GPIO pins 14 and 15 (and the corresponding ground pins).
gr-gpio is available as part of the standard GNU Radio build and has no additional external dependencies. Without additional configuration, the gr-gpio component:
The USRP host code is not changed.
To receive streaming digital samples, one first creates a USRP source block using the gr-gpio FPGA bitstream:
from gnuradio import gpio u = usrp.source_s(fpga_filename=gpio.fpga_filename, ...) # In addition to any other parameters
Create and configure daughterboard object as normally done.
Note: when using the BasicRX or LFRX daughterboards, one must ensure the receive MUX is set to enable complex
the mux value manually.
If using the daughterboard in RXA use:
<pre>
If using the daughterboard in RXB use:
<pre>
Since the USRP source is instantiated with usrp.source_s() it will produce a datastream of interleaved shorts:
<pre>
<pre>
...br
<pre>
To make packing and unpacking the analog and digital sample streams easier a new gnuradio block has been added:
<pre>
<pre>
To extract the digital values create and insert into the flowgraph:
<pre>
To extract the analog stream use:
<pre>
After the ana_strip block the stream becomes:
<pre>
<pre>
...br
<pre>
<pre>
convert the stream into a series of complex values.
After the dig_strip the stream becomes:
<pre>
<pre>
...br
<pre>
<pre>
*To transmit streaming digital samples*, one first creates a USRP sink block using the *gr-gpio* FPGA bitstream:
<pre>
from gnuradio import gpio
u = usrp.sink_s(fpga_filename=gpio.fpga_filename, ...) # In addition to any other parameters
</pre>
This block expects 16-bit interleaved short input samples, with the LSB of I and Q encoded with the values that will be driven onto GPIO pins 14 and 15:
<pre>
<pre>
...br
<pre>
h2. Example Applications with gr-gpio
gr-gpio installs the following scripts in $prefix/bin:
<pre>
<pre>
$ gpio_rx_sfile.py --help
usage: gpio_rx_sfile.py: [options] analog_filename digital_filename
options:
-h, --help show this help message and exit
-R RX_SUBDEV_SPEC, --rx-subdev-spec=RX_SUBDEV_SPEC
select USRP Rx side A or B (default=A)
-d DECIM, --decim=DECIM
set fgpa decimation rate to DECIM [default=16]
-f FREQ, --freq=FREQ set frequency to FREQ
-g GAIN, --gain=GAIN set gain in dB (default is midpoint)
-N NSAMPLES, --nsamples=NSAMPLES
number of samples to collect [default=+inf]
-F, --force-complex-RXA
enable basicRX hack to force complex mode on basicRX
and LFRX. Only works on side A. Only use with --gain 0
</pre>
<pre>
<pre>
$gpio_usrp_siggen.py --help
usage: gpio_usrp_siggen.py [options]
options:
-h, --help show this help message and exit
-T TX_SUBDEV_SPEC, --tx-subdev-spec=TX_SUBDEV_SPEC
select USRP Tx side A or B
-f RF_FREQ, --rf-freq=RF_FREQ
set RF center frequency to FREQ
-i INTERP, --interp=INTERP
set fgpa interpolation rate to INTERP [default=512]
--sine generate a complex sinusoid [default]
--gaussian generate Gaussian random output
--uniform generate Uniform random output
-w WAVEFORM_FREQ, --waveform-freq=WAVEFORM_FREQ
set waveform frequency to FREQ [default=100000.0]
-a AMPL, --amplitude=AMPL
set waveform amplitude to AMPLITUDE [default=16000.0]
-g GAIN, --gain=GAIN set output gain to GAIN [default=none]
-o OFFSET, --offset=OFFSET
set waveform offset to OFFSET [default=0]
--digital generate (only) a digital wave on lsb (will be output
on gpio pins with special usrp firmware)
</pre>
<pre>
<pre>
$ gpio_usrp_fft.py --help
usage: gpio_usrp_fft.py [options]
options:
-h, --help show this help message and exit
-w NUM, --which=NUM select which USRP (0, 1, ...) default is 0
-A ANTENNA, --antenna=ANTENNA
select Rx Antenna (only on RFX-series boards)
-d DECIM, --decim=DECIM
set fgpa decimation rate to DECIM [default=32]
-f FREQ, --freq=FREQ set frequency to FREQ
-g GAIN, --gain=GAIN set gain in dB (default is midpoint)
-W, --waterfall Enable waterfall display
-8, --width-8 Enable 8-bit samples across USB
-S, --oscilloscope Enable oscilloscope display (default)
-F, --fft Enable FFT display
-n FRAME_DECIM, --frame-decim=FRAME_DECIM
set oscope frame decimation factor to n [default=1]
-v V_SCALE, --v-scale=V_SCALE
set oscope initial V/div to SCALE [default=1]
-t T_SCALE, --t-scale=T_SCALE
set oscope initial s/div to SCALE [default=10us]
--digital show (only) the digital wave on lsb (will be input
from gpio pins with special usrp firmware)
--analog show (only) the analog wave on msbs (will be input
from analog inputs)
--file=FILE input from file FILE in stead of USRP (will be input
from raw file in interleaved short format)
</pre>
h3. Loopback Testing
To perform a digital loopback test using BasicRX and BasicTX boards installed in side A,
connect GPIO pin 14 on the BasicTX to GPIO pin 14 on the BasicRX. Do the same for GPIO pin 15.
In one console:
<pre>
$ gpio_usrp_fft.py --digital -R A -d 128 -S
</pre>
This will create an oscilloscope which only shows the lsb of RXA (hardcoded).
In another console:
<pre>
$ gpio_usrp_siggen.py --digital -i 512
</pre>
This will send a digital test pattern (which only uses lsb) to TXA (hardcoded).
Component gr-gsm-fr-vocoder¶
Implementation of GSM 06.10 13 kbps voice codec.
Repository¶
[source:/gnuradio/trunk/gr-gsm-fr-vocoder /gnuradio/trunk/gr-gsm-fr-vocoder]
Status¶
Current tickets regarding gr-gsm-fr-vocoder.
Current Defects¶
TicketQuery(component=gr-gsm-fr-vocoder&
Current Enhancement Requests¶
TicketQuery(component=gr-gsm-fr-vocoder&
Current Tasks¶
TicketQuery(component=gr-gsm-fr-vocoder&
Component gr-howto-write-a-block¶
Tutorial on how to write a block for GNU Radio.
Repository¶
[source:/gnuradio/trunk/gr-howto-write-a-block /gnuradio/trunk/gr-howto-write-a-block]
Status¶
Current tickets regarding gr-howto-write-a-block.
Current Defects¶
TicketQuery(component=gr-howto-write-a-block&
Current Enhancement Requests¶
TicketQuery(component=gr-howto-write-a-block&
Current Tasks¶
TicketQuery(component=gr-howto-write-a-block&
Component gr-pager¶
Implementation of pager protocols.
Repository¶
[source:/gnuradio/trunk/gr-pager /gnuradio/trunk/gr-pager]
Status¶
Current tickets regarding gr-pager.
Current Defects¶
TicketQuery(component=gr-pager&
Current Enhancement Requests¶
TicketQuery(component=gr-pager&
Current Tasks¶
TicketQuery(component=gr-pager&
Component gr-qtgui¶
Provides Qt-based graphical user interface routines.
Repository¶
[source:/gnuradio/trunk/gr-qtgui /gnuradio/trunk/gr-qtgui]
Status¶
Current tickets regarding gr-qtgui.
Current Defects¶
TicketQuery(component=gr-qtgui&
Current Enhancement Requests¶
TicketQuery(component=gr-qtgui&
Current Tasks¶
TicketQuery(component=gr-qtgui&
Component gr-radar¶
Work-in-progress implementation of passive radar.
Repository¶
[source:/gnuradio/trunk/gr-radar /gnuradio/trunk/gr-radar]
Status¶
Current tickets regarding gr-radar.
Current Defects¶
TicketQuery(component=gr-radar&
Current Enhancement Requests¶
TicketQuery(component=gr-radar&
Current Tasks¶
TicketQuery(component=gr-radar&
Component gr-radio-astronomy¶
Radio Astronomy application based on USRP.
Repository¶
[source:/gnuradio/trunk/gr-radio-astronomy /gnuradio/trunk/gr-radio-astronomy]
Status¶
Current tickets regarding gr-radio-astronomy.
Current Defects¶
TicketQuery(component=gr-radio-astronomy&
Current Enhancement Requests¶
TicketQuery(component=gr-radio-astronomy&
Current Tasks¶
TicketQuery(component=gr-radio-astronomy&
Component gr-rdf¶
Work-in-progress radio direction finding routines.
Repository¶
[source:/gnuradio/trunk/gr-rdf /gnuradio/trunk/gr-rdf]
Status¶
Current tickets regarding gr-rdf.
Current Defects¶
Current Enhancement Requests¶
Current Tasks¶
Component gr-trellis¶
Implementation of various Tellis coding methods.
Repository¶
[source:/gnuradio/trunk/gr-trellis /gnuradio/trunk/gr-trellis]
Status¶
Current tickets regarding gr-trellis.
Current Defects¶
TicketQuery(component=gr-trellis&
Current Enhancement Requests¶
TicketQuery(component=gr-trellis&
Current Tasks¶
TicketQuery(component=gr-trellis&
Component gr-usrp¶
GNU Radio interface to the USRP.
Repository¶
[source:/gnuradio/trunk/gr-usrp /gnuradio/trunk/gr-usrp]
Status¶
Current tickets regarding gr-usrp.
Current Defects¶
TicketQuery(component=gr-usrp&
Current Enhancement Requests¶
TicketQuery(component=gr-usrp&
Current Tasks¶
TicketQuery(component=gr-usrp&
Component gr-video-sdl¶
Interface to the SDL video library.
Repository¶
[source:/gnuradio/trunk/gr-video-sdl /gnuradio/trunk/gr-video-sdl]
Status¶
Current tickets regarding gr-video-sdl.
Current Defects¶
TicketQuery(component=gr-video-sdl&
Current Enhancement Requests¶
TicketQuery(component=gr-video-sdl&
Current Tasks¶
TicketQuery(component=gr-video-sdl&
Component gr-wxgui¶
Provides wxPython-based graphical user interface routines.
Repository¶
[source:/gnuradio/trunk/gr-wxgui /gnuradio/trunk/gr-wxgui]
Status¶
Current tickets regarding gr-wxgui.
Current Defects¶
TicketQuery(component=gr-wxgui&
Current Enhancement Requests¶
TicketQuery(component=gr-wxgui&
Current Tasks¶
TicketQuery(component=gr-wxgui&
GL Sinks¶
The following graphical sinks have been implemented in PyOpenGL.
The scope, fft, and waterfall sinks are drop-in replacements for the non-gl sinks.
Rather than modifying existing programs, the GL sinks can be enabled via a configuration file.
To enable the GL sinks, edit or create ~/.gnuradio/config.conf and add the following lines:
[wxgui] style=gl
Additional configuration options can be found in the README.gl.
Certain graphics card/drivers cause the GL sinks to segfault.
Here is a list of known problem cards and potential solutions.
| * Card * | * OS * | * Verbose * | * Solution * | |||||
| Intel G965 | Unknown | segmentation fault | LIBGL_ALWAYS_INDIRECT=1 | |||||
| Intel G945 | Ubuntu | no issues |
Also, if rendering is slow and CPU intensive, try disabling visual effects/compositioning.
Note: If you're getting this error "RuntimeError: Unable to import OpenGL. Are Python wrappers for OpenGL installed?", then you need to install the package "python-opengl"!
Work-in-progress message block implementation
[source:/gnuradio/trunk/mblock /gnuradio/trunk/mblock]
Current tickets regarding mblock.
Provides the cross-platform threading capabilities for GNU Radio.
[source:/gnuradio/trunk/omnithread /gnuradio/trunk/omnithread]
Current tickets regarding omnithread.
TicketQuery(component=omnithread&
TicketQuery(component=omnithread&
TicketQuery(component=omnithread&
GNU Radio is divided into a number of self-contained components which provide some logical unit of functionality.
Components that exist in the repository trunk today are:
gnuradio-core
Provides the runtime and various signal processing primitives
gnuradio-examples
Examples and demonstrations of GNU Radio functionality
gr-howto-write-a-block
Tutorial on how to write a block for GNU Radio
omnithread
Provides the cross-platform threading capabilities for GNU Radio
pmt
Work-in-progress implementation of polymorphic types
mblock
Work-in-progress message block implementation
usrp
Low-level interface to the Universal Software Radio Peripheral (USRP). Can be used outside the GNU Radio framework.
gr-usrp
GNU Radio interface to the USRP
gr-comedi
Interface to the Linux Control and Measurement Device Interface API
ezdop
Low-level interface to the AE6HO EZ Doppler radiolocation hardware. Can be used outside the GNU Radio framework.
gr-ezdop
GNU Radio interface to the EZ Doppler
Usually only one of these needs to be used at a time.
gr-audio-alsa
Interface to the Advanced Linux Sound Architecture (ALSA)
gr-audio-jack
Interface to the Jack Audio Connection Kit (JACK)
gr-audio-oss
Interface to the Open Sound System audio API (OSS)
gr-audio-osx
Interface to the Mac OSX audio subsystem
gr-audio-portaudio
Interface to the PortAudio portable cross-platform audio API
gr-audio-windows
Interface to the Win32 audio subsystem
gr-qtgui
Provides Qt-based graphical user interface routines
gr-wxgui
Provides wxPython-based graphical user interface routines
gr-video-sdl
Interface to the SDL video library
gr-trellis
Implementation of various Trellis coding methods
gr-gsm-fr-vocoder
Implementation of GSM 06.10 13 kbps voice codec
gr-atsc
Implementation of Advanced Television Systems Committee ATSC digital video standard
gr-pager
Implementation of pager protocols
gr-radar
Work-in-progress implementation of passive radar
gr-radio-astronomy
Radio Astronomy application based on USRP
gr-rdf
Work-in-progress radio direction finding routines
GNU Radio component for polymorphic types.
[source:/gnuradio/trunk/pmt /gnuradio/trunk/pmt]
Current tickets regarding pmt.
Low-level interface to the Universal Software Radio Peripheral (USRP). Can be used outside the GNU Radio framework.
[source:/gnuradio/trunk/usrp /gnuradio/trunk/usrp]
Current tickets regarding usrp.
GNU Radio uses CppUnit for testing. Although users are not required to run the tests, the installation procedure requires that the code for testing be available.
Note: If you installed cppunit 1.9.14-1 using Cygwin setup, you should uninstall it (using Cygwin setup) before building cppunit 1.12.0.
(1) Downloadcppunit-1.12.0.tar.gz from https://sourceforge.net/project/showfiles.php?group_id=11795 to /usr/src (i.e., C:\cygwin\usr\src on a default Cygwin installation). Unpack with$ cd /usr/src $ tar zxf cppunit-1.12.0.tar.gz(2) If your gcc is older than 3.4.4-2: Download the patch file
cppunit_dll_string.patch from [attachment:#56:cppunit_dll_string.patch] (using the "Original Format" link at the bottom of the page) to /usr/src. Apply the patch with$ cd /usr/src/cppunit-1.12.0 $ patch -p0 -i ../cppunit_dll_string.patch $ aclocal -I config $ autoconf
cygcheck -c gcc-g++) you can skip this step.
(3) Build and install with:$ ./configure $ make $ make check $ make install
/usr/local/* by default.
/usr/local use the --prefix= option on ./configure (but be sure that GNU Radio's ./configure can find it)make check fails in cppunittestmain on Cygwin when compiled with versions of gcc older than 3.4.4-2, but CppUnit seems to work ok with GNU Radiomake check of GNU Radio will fail, but who really needs testing anyway?This page explains how to compile GNU Radio on an x86 or x86_64 platform, and
generate code for the Cell processor. This is most useful when developing
for the Sony PS3 which, because of it's small main memory size (256MB),
is a poor platform for software development.
There are several ways one can go about cross compiling anything. There are always
at least two machines involved: the build machine where the compilation takes place, and
the host machine where the resulting software runs. Oftentimes these machines have differing
architectures. In our case, the build machine is an x86 or x86-64 workstation
running GNU/Linux, while the host machine is a Cell based machine also running GNU/Linux. (These
instructions have been tested using a PS3, but are expected to work on a Cell bladeserver such as
the IBM QS21 too.)
The strategy described here requires that the build machine have read-only access via
NFS
to the root file system of the Cell host, and that both machines have read/write
access to a shared NFS file system.
In order to be concrete, we call the build machine *build* and the host machine *ps3*.
At present the only RPM's available are for x86, x86_64 or Cell/BE machines running Fedora 7.
They also work fine on Fedora 8.
It should be possible to build the cross toolchain from source on virtually
any machine, but that is beyond the scope of this page.
build$ id uid=500(eb) gid=500(eb) groups=3(sys),10(wheel),500(eb),1000(usrp) ps3$ id uid=500(eb) gid=500(eb) groups=4(adm),10(wheel),500(eb),1000(usrp)* Both *build* and *ps3* shall have ntp installed and operating and their clocks shall be synchronized.
$ sudo yum install ntp $ sudo chkconfig --level 35 ntpd on $ sudo service ntpd start
Congratulations on making it this far! _You have handled all the prerequisites described
above, right?_ If not, please take care of them now. Google or your local sys admin can
provide assistance.
To cross compile there is some one-time stuff that needs to be done to set up everything between
*build* and *ps3*, and then there's the actual steps for cross compiling GNU Radio.
We need to arrange for *build* to be able to see the installed packages, includes
and libraries on *ps3* so that we can compile and link against them.
In addition, so that we can compile the software
on *build* but run the QA code (make check) on *ps3*, we must arrange that
they see a common file system, with identical path names to the shared file system from the root of each
system. (configure hard-codes absolute file names into the generated Makefile's).
/ 192.168.64.0/24(ro,all_squash)
man exports if you've got questions. Then run exportfs to have it take effect.ps3$ sudo exportfs -a
build$ sudo mkdir /mnt/cell-root build$ sudo mount -o ro ps3:/ /mnt/cell-rootAt this point you should be able to see the ps3 root filesystem from *build*.
build$ ls -l /mnt/cell-root ls: cannot access /mnt/cell-root/net: No such file or directory ls: cannot access /mnt/cell-root/sys: No such file or directory ls: cannot access /mnt/cell-root/dev: No such file or directory ls: cannot access /mnt/cell-root/spu: No such file or directory ls: cannot access /mnt/cell-root/home: No such file or directory ls: cannot access /mnt/cell-root/proc: No such file or directory ls: cannot access /mnt/cell-root/misc: No such file or directory total 156 drwxr-xr-x 2 root root 4096 2007-11-08 04:56 bin drwxr-xr-x 4 root root 4096 2007-10-25 17:34 boot ?????????? ? ? ? ? ? dev drwxr-xr-x 99 root root 12288 2007-11-08 15:18 etc ?????????? ? ? ? ? ? home drwxr-xr-x 16 root root 4096 2007-11-08 04:55 lib drwxr-xr-x 7 root root 4096 2007-11-08 04:55 lib64 drwx------ 2 root root 16384 2007-10-04 13:22 lost+found drwxr-xr-x 2 root root 4096 2007-11-07 15:07 media ?????????? ? ? ? ? ? misc drwxr-xr-x 5 root root 4096 2007-11-08 13:12 mnt ?????????? ? ? ? ? ? net drwxr-xr-x 3 root root 4096 2007-10-24 13:41 opt ?????????? ? ? ? ? ? proc drwxr-xr-x 2 root root 4096 2007-11-08 19:50 proj drwxr-x--- 6 root root 4096 2007-11-07 13:55 root drwxr-xr-x 2 root root 12288 2007-11-08 04:56 sbin drwxr-xr-x 2 root root 4096 2007-10-04 13:26 selinux ?????????? ? ? ? ? ? spu drwxr-xr-x 3 root root 4096 2007-10-04 14:14 srv ?????????? ? ? ? ? ? sys drwxrwxrwt 14 root root 4096 2007-11-10 00:16 tmp drwxr-xr-x 16 root root 4096 2007-09-19 08:18 usr drwxr-xr-x 21 root root 4096 2007-10-04 14:43 var
ps3:/ /mnt/cell-root nfs ro,intr,bg 0 0
Now we need to create the shared directory on *build*, export it, and then mount it
on both systems.
build$ mkdir /mnt/misc/shareSet up this directory for export by adding a line similar to this to /etc/exports on *build*:
/mnt/misc/share 192.168.64.0/24(rw)Then export it:
build$ sudo exportfs -aCreate a mount point called /mnt/share on both machines:
build$ sudo mkdir /mnt/share ps3$ sudo mkdir /mnt/share
and mount it on both machines:
build$ sudo mount build:/mnt/misc/share /mnt/share ps3$ sudo mount build:/mnt/misc/share /mnt/shareYou should be able to create a file from either machine and see it on the other.
build$ date > /mnt/share/foo ps3$ cat /mnt/share/foo Sat Nov 10 02:29:44 PST 2007
If this isn't working, take a look at /var/log/messages on both machines.
Once this is working, add a line to /etc/fstab on both machines so that thebuild:/mnt/misc/share /mnt/share nfs rw,intr,bg 0 0
build$ mkdir /mnt/share/gr build$ cd /mnt/share/gr build$ svn co http://gnuradio.org/svn/gnuradio/trunkNow, on *ps3* do this:
ps3$ sudo /mnt/share/gr/trunk/dtools/bin/tweak-cell-for-cross-compiling
Excellent! All the one-time set up is complete!
Now on to the familar part...
To keep life simple we'll specify a *--prefix*
that's on /mnt/share. (This isn't required, but start this way. Otherwise, depending
on which machine you're on when you type "make install" you'll hose yourself with P(.5)
by installing binaries for the wrong architecture into /usr/local). The key difference
from native compilation is using the ./configure-cell-cross script instead
of ./configure directly. It accepts all the normal configure options.
build$ cd /mnt/share/gr/trunk build$ ./bootstrap build$ ./configure-cell-cross --prefix=/mnt/share/cell-install --with-boost=/mnt/cell-root/PLACE_YOU_INSTALLED_BOOST build$ make 2>&1 | tee make.logAssuming that configure and make completed successfully, we can
ps3$ cd /mnt/share/gr/trunk ps3$ make checkThis should also work fine. When you're happy:
ps3$ make installAt this point the installed code should be ready to run. Be sure to set your
ps3$ export PYTHONPATH=/mnt/share/cell-install/lib/python2.5/site-packages ps3$ export PATH=$PATH:/mnt/share/cell-install/binThen try to run something:
ps3$ usrp_fft.py ...
What could possibly go wrong???
setup.exeInstalling Cygwin is simple, but you must have administrator privileges for the initial installation, and you must either have administratior privileges or be the owner of the Cygwin registry entries to install Cygwin packages.
If you normally run with limited user privileges: Managing your Cygwin installation is easier if you are the owner of the Cygwin entries in the Windows registry.
The way to ensure this is to:
1. Log out of your usual account
2. Log into an account with administrator privileges and use the control panel to give your usual account administrator privileges
3. Switch to your usual account and install Cygwin using the procedure below
4. Log out of your usual account
5. Log into your administrator account and change your usual account back to limited user
If you do this, you will own the Cygwin entries in the registry. If you do not do this, you will need administrator privileges to install Cygwin packages.
There is also an option during the installation process to install Cygwin for "Just Me". This may be easier, but I have not tried it. You will still need administrator privileges if want to install a USRP.
To install Cygwin:
1. Go to http://www.cygwin.com
2. Click on "Mirror Sites" in the lefthand column and note the two mirror sites nearest you
3. Go back to http://www.cygwin.com and click on "Install Cygwin now"
4. Go ahead and run setup.exe; the default settings are fine, but you may want to make the "Local Package Directory" a subdirectory of your "Root Directory" (e.g., "C:\cygwin\setup")
5. When asked to choose a mirror site, choose one you selected above; if that one doesn't work, try the other one
6. Keep clicking "Next" until Cygwin has been installed; you probably want to click the boxes to put an icon on your desktop and add Cygwin to your startup menu
For convenience you may want to go back to http://www.cygwin.com, right-click on "Install Cygwin now" again, and save a copy of setup.exe in a convenient place (e.g., C:\cygwin\setup\setup.exe). You will be running setup.exe repeatedly to download and update Cygwin packages.
bash shell. You can start a Cygwin command window in one of the following ways:
setup.exe put one there)cygwin.bat; or you can right-click on cygwin.bat and select "Send To" -> "Desktop" to make a shortcut for next timesetup.exe¶One thing that makes Cygwin convenient is the ease of selecting and installing optional software packages with setup.exe. You can run setup.exe from the web, from a command prompt, or from Windows Explorer, depending on what privileges you have.
setup.exe from your local disk (e.g., /setup/setup.exe) if you saved a copy there; orsetup.exe (if you have one) and double-clickIf you have access to an account with administrator privileges and a non-blank password, you can:
1. Use Windows Explorer to navigate to the directory containing your saved setup.exe (if you have one) and double-click; then
2. Enter the account name and password when requested
Once Cygwin Setup is running, you can tell it to use the default values (Install from Internet; same root directory, "install for" setting, and default text file type as on your initial install; same local package directory; same internet connection; and same download site) until you get to the "Select Packages" window.
The "Select Packages" window is very powerful but is not immediately intutiive to all users, has no "Help" buttion, and the pop-up documentation may go away before you can finish reading it. The most important thing to know is that the "View" button cycles through several displays of packages:Although Cygwin uses a bash shell and many of the same commands and programs as Linux, it is still running under the Windows operating system and must accommodate the needs and limitations of that system. Some of the important consequences are:
bash shell uses "\" as an escape character)C:/cygwin for a default installation)ls "C:/Program Files/SDCC")PATH="$PATH:/cygdrive/c/Program Files/SDCC").exe but you can reference them in Cygwin without the .exe; thus the ls command actually runs /bin/ls.exe and ls /bin/ls shows the file /bin/ls even though the file is actually named /bin/ls.exeIn Linux, lines in a text file are separated by a newline characters (ASCII Ctrl-J, often shown as !^J, or '\n' in C). In Windows, lines are separated by carriage return and newline characters (the two-character sequence ^J or
"\r\n" in C). Many of the programs you will use with Cygwin don't care, but some do. When you see !^M popping up you know that there are Windows-style files around. When you look at a file in Windows Notepad and see all the lines running together with little boxes between them you know you are looking at a Linux-style file.
In general, when working on programs with Cygwin it is better to stick with the Linux \n line separators when possible. In particular, the Cygwin autoconf utility has problems with some .m4 files that include the !^M characters as line separators. This also means that it is better to use a Cygwin version of the Subversion program rather than a Windows version---the Windows version will give you the extra !^M characters with some files in some SVN repositories.
The Linux su and sudo commands do not work on Cygwin. On Windows, access to some files and to parts of the Windows registry (a database of system configuration information) is limited to accounts with administrator privileges. Most files in Cygwin can be accessed without administrator privileges.
setup.exe, automatically offer to let you run as another user); in order to use this feature, you need access to an account with administrator privileges that has a non-blank passwordThe best places to start are the Cygwin FAQ and User's Guide. Both are available at http://www.cygwin.com, and they should also be installed on your machine (look under "Cygwin" in your "Start" -> "All Programs" menu). The User's Guide includes sections for Windows users who are new to Linux and Linux users who are new to Windows.
The easiest way to install GNU Radio on Windows is to use the Cygwin (http://www.cygwin.com) environment. Once Cygwin and the required utilities and third-party libraries are installed, installation of GNU Radio is as easy on Windows as it is on Linux.
These instructions are for release 3.2.2 and are current as of September 29, 2009. They cover installation of the core GNU Radio components and components for using the USRP, wxPython GUI, and PortAudio. They do not cover installation of components needed for USRP2, GRC, SDL video, or the Qt GUI.
To install GNU Radio with Cygwin you need to:
Installing Cygwin is easy, but there are a few details to worry about; see getting started with Cygwin. If you have previously installed Cygwin, you should check to see that your packages are up-to-date.
Utilities and third-party libraries are of two types: those that are available as Cygwin packages and those that must be downloaded and/or built separately.
apt-cyg may help you installing. It works like aptitude, so you can install and search packages from the command line.
Some of the libraries and utilities required by GNU Radio are not available as Cygwin packages. These packages must be installed manually:
If you have a USRP you will also need:
GNU Radio can be built either from a release tarball (more stable) or from the latest code in the svn repository (latest features). This section describes how to build from the release tarball. Additional considerations when building from the svn repository are described later.
$ tar -zxf gnuradio-3.2.2.tar.gz
gnuradio-3.2.2.
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
$ cd gnuradio-3.2.2 $ ./configure --disable-all-components --enable-omnithread --enable-gruel --enable-gnuradio-core --enable-gr-audio-oss
$ make $ make check $ make install
make uninstall before you get to make check.
To actually make GNU Radio do something, try:$ export PYTHONPATH=/usr/local/lib/python2.5/site-packages $ cd gnuradio-3.2.2/gnuradio-examples/python/audio $ python dial_tone.py
dial_tone.py stops by itself without producing sound or gives a Windows error pop-up, your version of Cygwin may be out of date (see hints, tips, known problems, and solutions for Windows).
The PYTHONPATH environment variable must be set to tell Python where to find the GNU Radio extension modules.
With this minimal GNU Radio system you can capture signals from your sound card, read signals from a file, or generate signals; process signals; and play signals on your sound card or save them to a file. Note that you cannot simultaneously capture and play signals using the same sound card with gr-audio-oss.
$ cd gnuradio-3.2.2 $ ./configure
$ make $ make check $ make install
./configure --help to see how the components are named. Look for the "--enable-..." options and add the corresponding "--disable-..." option to your ./configure command and repeat the above steps. If an old version of GNU Radio is installed, you should remove it with make uninstall before doing make check.
Note that make check sometimes fails on Cygwin due to problems with "sem_init" or "allocate_lock". These are Python and/or Cygwin problems, which don't affect most users of GNU Radio.
Be sure that PYTHONPATH is set as above before running a GNU Radio application.
Note: These instructions are obsolete since the changeover to the git repository.
$ svn co http://gnuradio.org/svn/gnuradio/trunk gnuradio
^M) character at the end of each line.
The procedure for building the svn version is like that given above for building the release version, but because the svn version is constantly
changing, there may be extra requirements a need for patches. Note that the lists of requirements and patches may become out of date at any time.
Extra requirements:
The following patches are needed:
$ patch -p0 -b -i file.patch
file.patch with the name of the patch file) to apply the patch.
After applying any patches and before running ./configure you must initialize the build with$ ./bootstrap
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfigThe remainder of the build process is the same as for the release version except that boost should be found automatically in
/usr/local/include:$ ./configure $ make $ make check $ make install
Be sure that no older version of GNU Radio is installed when running make check.
Expect `make check` to fail in test_inband.exe with "uncaught exception of type mbe_mblock_failed" errors; see Issue #191 for details.
If you have a USRP you will need to install the driver for it; see installing the USRP driver for Windows.
Now that your GNU Radio system is installed, it is time to start exploring. The best way to learn about GNU Radio is to study and modify the examples in the various subdirectories of gnuradio-3.2.2/gnuradio-examples/python and gnuradio-3.2.2/gnuradio/gr-utils/src/python.
The official Debian package repository has GNU Radio 3.0.2 available, though this is rather obsolete.
It is recommended that you [[BuildGuide|complete a source build] from the 32 stable series either through downloading a Release32Branch] tarball or using Subversion to check out the software from our subversion repository.
In the first place you should have a look at the README file for the current dependencies. dpkg -l |grep <packagename> is your friend to see your current installed versions.
If you get errors about missing programs/libraries or wrong versions, use the package management system like described above. To find the name of a package that provides a certain file use the Debian package search page. To get old versions of packages have a look at "If you want to build a recent svn snapshot of gnuradio you need wxgtk version 2.8 or later.
Debian Etch only has wxgtk version 2.6 which is not recent enough.
But you can install more recent wxgtk versions from the wxwidgets debian and ubuntu repository.
See [http://wiki.wxpython.org/InstallingOnUbuntuOrDebian Installing wxgtk-2.8 on debian etch":http://snapshot.debian.net/].
GNU Radio now has binary and source packages in the Debian repository format.
These allow you to install GNU Radio on to an Ubuntu Linux distribution without having to
perform a source compilation of the tree. In addition, the system package manager is able
to identify which runtime dependencies are needed such that these get installed
automatically when the GNU Radio packages are installed.
Currently, binary and source packages are available for the Ubuntu 9.04 (Jaunty) Linux
distribution, both 32-bit and 64-bit versions. These packages may work with other
Debian derivative operating systems; however, this is untested.
The packages are not part of the Ubuntu official archives; the repository is hosted at the gnuradio.org site.
If you have already installed GNU Radio on your system via a source compile, you will need to
uninstall it prior to installing the binary packages. The easiest way to do this is to
change directory into the top level directory of your source tree, then run 'make uninstall.':
$ sudo make uninstall
This is only possible if you have not cleaned out your source tree since the original 'make install'
was executed. Otherwise, you will have to manually go into $prefix/* and remove all traces of
gnuradio (and USRP if you installed that).
To configure your package manager to reference the GNU Radio packages, you will either need to the below lines into the file.
To track the stable release branch, insert the following:
deb http://gnuradio.org/ubuntu stable main deb-src http://gnuradio.org/ubuntu stable main
To track the unstable development branch, insert the following:
deb http://gnuradio.org/ubuntu unstable main deb-src http://gnuradio.org/ubuntu unstable main
manager's knowledge of the available packages. From the command-line, you would enter:
$ sudo aptitude update
The packages themselves contain the necessary dependency information that will "pull in" anything
needed by the packages you select, including other GNU Radio packages. Several "virtual" packages
have been created to ease this process.
To install all of the GNU Radio and USRP documentation, libraries, examples, and utilities, enter:
$ sudo aptitude install gnuradio gnuradio-companion
In order for a regular user to have access to the hardware device, you must add that username to
$ sudo addgroup <USERNAME> usrp
The new group rights will become effective after the next login and after reconnecting or power cycling
the USRP. If you do not want to log out and log in, but only want to have a single shell with the new
rights immediately , you can su to your own account.
= Desktop Testing of OpenBTS =
Here's the hardware you will need for a desktop testing kit:
The recommended testing configuration is to operate in a cellular band not used in your area and use test phones that do not support your local cellular bands. This arrangement forces your test phone to camp to your basestation. It also prevents you from inadvertently attracting phones from the local licensed carriers. For example, to test in North America, you might use the EGSM900 band or the DCS1800 band and use a phone that does not support GSM850 or PCS1900.
If you do operate in a band that is also used by cellular carriers in your area, you will need to use SIMs from a carrier that does not offer service in you area and has no roaming agreements with carriers in your area. You can then use network parameters matched to the SIM and, hopefully, your test phones will ignore the local network and phones from your local network will ignore you.
If you do not operate in a band that is used by cellular carriers in your area, you can use any SIM you want.
If you want any flexibility at all in your choice of SIMs, you will need to use unlocked phones.
Be aware of power levels and local regulations. Here are some technical guidelines:
However, these are only technical pointers to help you comply with your local regulations. They are not legal advice on the regulations themselves. That is entirely your responsibility.
Git makes it easier for anyone to develop and contribute code to gnuradio. This article will describe how to use git with multiple repositiories so you can develop and publish your changes to gnuradio. The goal of this page is to help people manage git repositories so code may easily be shared among GNURadio developers.
The basic idea is you clone the gnuradio git repository and maintain a public repository with your work on github, or other public git server.
$ git clone http://gnuradio.org/git/gnuradio.git
$ git config user.name "Your Name"
$ git config user.email your@email.abc
$ cd gnuradio
$ git remote add balister git@github.com:balister/gnuradio-balister.git
$ git push balister master
Now you have a local repository and a copy on github so you can publish your work.
To update master on your public repository:
$ git commit [options] [files]
$ git push balister master
Create a local branch, and publish the new work.
$ git branch new_work
$ git checkout new_work
$ git push balister new_work
When you are done with the branch delete it locally, and on the remote repository (if needed):
To delete your branch locally:
$ git branch -d new_work
To Delete your branch from the server:
$ git push balister :new_work
If you want to create a local branch tracking a remote branch (e.g., to track a branch on the gnuradio server):
$ git branch --track local_new_work origin/new_work
$ git checkout local_new_work
Assuming that "new_work" is a branch on the repository you cloned originally
There are some of the git graphical browsing tools such as gitk and qgit. The gitk is the original TCL/TK GUI for browsing history of Git repositories. The qgit is a QT GUI for browsing history of Git repositories, similar to gitk but with more features.
The subversion imported commits have the revision number at the end of the description in the "git-svn-id" line. For example, you can create and checkout a new branch with svn revision 10184 by doing the following.
$ git log --grep=git-svn-id.*@10184
$ git checkout -b r10184 cd7b07f0140ddff6
Some external resources that may be useful for learning/working with git:
GNU Radio is currently maintained by:
All contributions should conform to the GNU Coding Standards as modified for C++ in [source:gnuradio/trunk/README.hacking README.hacking]
Before we can accept non-trivial code contributions from you, we need a copyright assignment on file with the FSF. A description of the process is available here.
This boils down to the following instructions:
Every patch must have several pieces of information before we can properly evaluate it.
Submit your patch by sending it to the patch-gnuradio@gnu.org mailing list.
When you have submitted your patch, somebody will tell you what to do next. If the patch is small, just send it directly to the list. Be sure to send the patch as a mime text attachment, or pasted directly into the mail. Uuencoded patches, or patches otherwise rendered unreadable by peculiar mime encoding make it much harder for the gnuradio developers to read and/or apply your patch. If your patch is very large (more than a hundred kilobytes), try to upload the patch itself to savannah and post only a link to the mailing list.
Persistent contributors who submit high quality patches may be given direct subversion access.
There is a special list for reporting bugs, bug-gnuradio@gnu.org, to enable the developers to track submitted bug reports. If you think you have found a bug in gnuradio, please send as complete a report as possible to this list. Ideally, you should include the text you get by running config.guess, the text you see when you run ./configure, and if you can, a patch made with diff -u5 which fixes the problem. If you can send a small script which fails with the unpatched distribution, but passes with your patch applied we can add the test to the distribution to make sure the bug doesn't reappear.
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2 <html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
3 <title>GNU Radio 3.2svn C++ API: Main Page</title>
4 </head><body>
5 <h1>GNU Radio 3.2svn C++ API Documentation</h1>
6 <p>
7 Welcome to GNU Radio!<p>
8 For a list of all GNU Radio C++ blocks, please see <a href="modules.html">C++ Blocks</a>.<p>
9
10 Please note that at this time, we haven't found an acceptable way to provide unified documentation for the C++ parts of the system and the parts written in Python (mostly hierarchical blocks). Until this gets worked out, please bear with us, or better yet, solve it for us! </div>
11
12 </body>
13 </html>
The latest stable release of GNU Radio can be found here:
[http://ftp.gnu.org/gnu/gnuradio/gnuradio-3.3.0.tar.gz]
An archive of older releases can be found here: [http://ftp.gnu.org/gnu/gnuradio/]
If you prefer the latest development code, wish to contribute to GNU Radio, or want to work with features that haven't yet made it into the stable branch, you can check out the source from the git repository using one of these two lines:
$ git clone git://gnuradio.org/gnuradioor
$ git clone http://gnuradio.org/git/gnuradio.git
$ git pull
If you're using Ubuntu, you can find pre-built Ubuntu packages for Ubuntu at this page: DebianPackages.
Documentación del USRP y GNU Radio en español. Gracias a Jorge A. Chávez Reyes.
The attached "gmskenhanced.py" file offers an enhanced GMSK demodulator that I believe to be superior to the GNURadio standard gmsk demodulator. It should be a drop-in replacement for the existing demodulator in designs, except that the transmitted data needs to be differentially encoded (you will NOT, however, need a differential decoder on the receive side). The enhanced demodulator should offer better bit error rate (BER) performance, especially for lower bandwidth-bittime (BT) products, such as the GSM standard BT=0.3, and in lower SNR conditions.
The GNURadio standard gmsk demod is an attempt at a one-bit differential detector, and looks at the phase-change over one sample (should actually be over one symbol). The enhanced gmsk demod looks at the phase-change over two SYMBOLS and is therefore a two-bit-differential detector. The net effect is that inter-symbol-interference (ISI) is reduced: the eye openings in the resulting eye-diagrams are wider, and therefore more resistant to noise. A side-effect of a two-bit-differential detector is that the eye diagram is asymmetric, thus the decision threshold needs to biased. The constructor's default value (decision_threshold=0.1) should be fine for most cases.
Work based largely on:
Differential Detection of Gaussian MSK in a Mobile Radio Environment
Also see:
Differential Detection of GMSK Using Decision Feedback
And:
GMSK Modulation for Digital Mobile Radio Telephony
Code cleanup.
Detector portion of demod should really be rewritten in C.
If sufficiently vetted, check into svn?
My BER testing shows a significant improvement, but I would like to hear from others. Please either post here or email me if you have a chance to try it out, even if it degrades performance or you can't make it work right.
UNICORN.p.clark@gmail.com (please replace the mythical beast with "steven", sorry for the CAPTCHA...)
Ettus Research is the main supplier of USRP motherboards along with the daughterboards required for transmitting and receiving signals over the air using the GNU Radio package.
Supplies can be purchased directly through Ettus Research.
A series of questions commonly asked (and answered). Gathered from the mailing list archives and various experts.
Who/what/when/where/why/how (not necessarily in that order)?
GNU Radio is a collection of software that when combined with minimal hardware, allows the construction of radios where the actual waveforms transmitted and received are defined by software. What this means is that the digital modulation schemes used in today's high performance wireless devices are now software problems.
Check the [[Download|download] page on the wiki then go over to the [wikiBuildGuide build guide]] for instructions on how to build and what dependencies GNU Radio has.
(Something is missing here...)
Have you read the [[BuildGuide|build guide] for your platform and made sure you have all the dependencies installed properly Also be sure to check the [wikiBuildGuide#CurrentKnownBuildProblems current known build problems]] section and be sure the problem affecting you is currently not listed.
If, after following the guide, nothing seems to work, ask the mailing list as a last resort.
You can point yourself over to the development page and first read it carefully, second read it again, and finally read it one more time. You should be able to figure out what to do by then.
There are currently some outstanding tasks that need to be accomplished as well as an endless supply of bugs that need to be fixed. Please feel free to enhance GNU Radio, but make sure you read the development page first before we can accept nontrivial contributions.
GNU Radio is maintained by Eric Blossom, with regular contributions by Johnathan Corgan, Matt Ettus and others.
For a more complete list of contributors, please visit the [source:gnuradio/trunk/AUTHORS AUTHORS] file in the subversion repository.
While GNU has been extremely successful in creating free software suites for exploration and hacking by the everyday user, there is still a large void when it comes to hardware hacking especially within the radio frequency spectrum. GNU Radio helps fill this void by supplying a suite of signal processing software blocks along with some tangible hardware to the general public at a modest price (free software, reasonably priced hardware).
If you have already tried looking at the BuildGuide page, and still seem to have build or runtime issues.
$ cat /etc/ld.so.conf
$ cp /etc/ld.so.conf /tmp/ld.so.conf $ echo /usr/local/lib >> /tmp/ld.so.conf $ sudo mv /tmp/ld.so.conf /etc/ld.so.conf... then finally:
$ sudo ldconfig
Now try running those GNU Radio scripts again.
Everything dealing with the creation, implementation and usage of the GNU Radio core signal processing blocks.
GNU Radio uses doxygen to help document all the different modules as well as the API for the core processing blocks.
Sure here are some examples. The information can be found here. If it hasn't been implemented, try it yourself! You'll be surprised what you'll learn.
It is currently being worked on (#128). There are a few different things that have to happen to support such a feat (#118), but if you want to see it done quicker feel free to help out.
Python is only used to setup the flow graph. Once setup, most of the work is done in C++.
Eric Blossom has put together a very nice tutorial on how to write a block for GNU Radio. Enjoy!
Questions specific to the USRP and daughterboards, their functionality, and role within GNU Radio.
The [trac:USRP Universal Software Radio Peripheral (USRP)] is a general purpose motherboard which hosts a wide range of daughterboards which can be used with the signal processing blocks found in the GNU Radio software package to give access to the radio frequency spectrum.
The USRP hosts dual Analog Devices AD9862 mixed signal analog front end devices connected to an Altera Cyclone EP1C12 FPGA where most of the initial downconversion is done within the RX chain.
src1 = usrp.source_c( which=0 ) src2 = usrp.source_c( which=1 )
Now which USRP gets assigned #0 and #1 is dependent on the order they enumerate on the USB, first by bus, then by device. This may be affected by which one is plugged in first or turned on first.
It's possible, when writing your own code, to retrieve the serial numberSomething missing here...
The other caveat is that most motherboards share a single USB controller for all their ports. So you're sharing the same 32 MB/s bandwidth across two USRPs now, effectively halving the maximum RF bandwidth you can work with if both USRPs are using the USB equally.
You'll need to write a small bit of code. The RX side of a USRP can only be opened once. Thus, you need a single program that reads input from both daughterboards at the same time.
Take a look at [source:gnuradio/trunk/gnuradio-examples/python/multi-antenna/multi_file.py multi_file.py]. It handles 4 simultaneous inputs.
Lastly, when using 2 inputs, there's no need to load special FPGA firmware. The standard file works fine.
Inband signaling is receiving and transmitting control, status and data packets to a USRP to perform specific actions at specific times. This will allow for tight tolerances for TDMA style Media Access Controllers (MACs).
Some code has been released which can send and receive 802.11b at 1 mbps. However, USB 2.0 is too slow to support two way 802.11 interactions. A new version of the USRP is under
development which will have a faster interface which may be 802.11 capable.
Currently, no simply due to the latencies required do not allow for round trip processing of packets over the USB 2.0 interface on the USRP. This might get quicker with the inclusion of inband signaling in an upcoming release, but the round trip delay plus processing time probably won't work too well.
Daughterboards are available which cover ranges from DC to 5.9 GHz.
Yes, but there are some caveats that you must take into consideration. First, if using a cabled setup, be sure there is some attenuation between the transmitter and receiver. Second, realize that there is not much isolation on the board itself and signal can leak through even without an antenna.
The current ADC chip (AD9862) on the main board can support 0-20 dB of gain, and various daughtercards can have different gain ranges of their own. Matt Ettus: "In general, we put as much gain as close to the antenna as possible. So the ADC gain is only added in if you request a very high gain. Each daughterboard is different, so check the files in gr-usrp/src/db_*.py for the exact system we use."
Yes, check out http://gnuradio.org/trac/wiki/CompGrGpio.
Comprehensive USRP FAQ can be found at USRP-FAQ page.
Instructions for Fedora Core has been moved to this page: FedoraInstall
Fedora Core 5 and 6 use udev, so follow these directions to configure non-root access to the USRP.
Install Fedora Core for software development, and then:
$ yum install fftw-devel cppunit-devel wxPython-devel libusb-devel sdccSome of the names of the binaries in sdcc are very generic, and they have therefore been moved to /usr/libexec/sdcc on Fedora, and symlinks prefixed with sdcc- have been created in /usr/bin. This might be a problem for existing programs, but the solution is simply to add /usr/libexec/sdcc to PATH before building GNU Radio:
$ export PATH=/usr/libexec/sdcc:$PATH
Now you have all the necessary bits and pieces to start a successful GNU Radio build.
If you wish to be able to generate the HTML documentation:
$ yum install xmlto graphviz
The default install path for GNU Radio is /usr/local, but this is not part of the default Python module search path. The easiest way to that is to add this to ~/.bashrc or in the personal initialization file for your favourite shell.
export PYTHONPATH=/usr/local/lib/python2.4/site-packagesX86-64 systems:
export PYTHONPATH=/usr/local/lib64/python2.4/site-packages
You can also run this from the command line before running GNU Radio applications.
Due to some issues with the configuration of Python in Fedora, earlier versions of GNU Radio did not install the python modules in the correct location. This has now been fixed in changeset:4628, and will be included in future releases.
Gnuradio is now in Fedora default repository. Use yum or your favorite package installed to install it.
yum install gnuradio usrp
Install Fedora (FYI, we work fine w/ Fedora 8, 9, 10, 11, and 12), and then:
$ yum groupinstall "Engineering and Scientific" "Development Tools" $ yum install fftw-devel cppunit-devel wxPython-devel libusb-devel \ guile boost-devel alsa-lib-devel numpy gsl-devel python-devel pygsl \ python-cheetah python-lxml PyOpenGL $ yum install PyQt4-devel qwt-devel qwtplot3d-qt4-devel (The pkg names depend on the version of Fedora. These work for 12)
You now have the basic requirements for building GNU Radio. Additional requirements are listed below. Notice that some are optional. Once you have all the requirements installed, you can proceed with the installation instructions included in the [[Download|GNU Radio distribution] or on-line [sourcegnuradiotrunkREADME]].
sdcc is available from the repository, and can therefore be installed by running:$ yum install sdccSome of the names of the binaries in sdcc are very generic, and they have therefore been moved to
/usr/libexec/sdcc on Fedora, and symlinks prefixed with sdcc- have been created in /usr/bin. This might be a problem for existing programs, but the solution is simply to add /usr/libexec/sdcc to your PATH before building GNU Radio:$ export PATH=/usr/libexec/sdcc:$PATH
The version of sdcc packaged for Fedora 11 (2.9.0) does not work with GNU Radio 3.2. It is possible to use the version packaged for Fedora 10 (2.8.0) available for i386 and x86_64. Alternatively sdcc 2.9.0 can be compiled from source available here.
On earlier versions of Fedora you have to download the _Small Device C Compiler, build and install yourself.
If you wish to be able to generate the HTML documentation:
$ yum install xmlto graphviz
If you want to build the gr-qtgui package to use Qt plotting tools, install:
$ yum install qt4-devel qwt-devel qwtplot3d-qt4-devel PyQt4-devel
Follow these directions to configure non-root access to the USRP.
The default install path for GNU Radio is /usr/local, but this is not part of the default Python module search path. The easiest way to that is to add this to ~/.bashrc or in the personal initialization file for your favourite shell.
$ python -V Python 2.5
Then set the PYTHONPATH environment variable to a value that includes your installation prefix
and the appropriate python version. E.g.,
export PYTHONPATH=/usr/local/lib/python2.5/site-packagesX86-64 systems:
export PYTHONPATH=/usr/local/lib64/python2.5/site-packages
You can also run this from the command line before running GNU Radio applications.
GNU Radio requires a shared, single-precision version of FFTW. Many contemporary GNU/Linux systems come with FFTW suitably packaged. Systems using pkgsrc can install math/fftwf. In the event that no package is readily available on your platfrom, FFTW is easily built from source on any Linux, Cygwin, or MinGW/MSYS system. These instructions were written for Cygwin and MinGW, but should work on any of these systems.
(1) Download fftw-3.2.2.tar.gz from http://www.fftw.org/download.html to /usr/src (i.e., C:\cygwin\usr\src on a default Cygwin installation or C:\msys\1.0\src on a default MSYS installation).
$ cd /usr/src $ tar zxf fftw-3.2.2.tar.gz $ cd fftw-3.1.2 $ ./configure --enable-float --enable-sse --enable-3dnow --enable-shared --disable-static $ make $ make check $ make install
./configure command:$ ./configure --with-our-malloc16 --enable-threads --with-combined-threads --enable-float --enable-sse --enable-shared --disable-static
/usr/local/* by default.
/usr/local use the --prefix= option on ./configure (but be sure that GNU Radio's ./configure can find it)Official documentation: http://www-corot.obspm.fr/COROT-ETC/Files/CY7C68013.pdf
Details of the FX2 microcontroller...
The following loops were examined from source:usrp/firmware/src/usrp2/usrp_main.c.
main( )¶main_loop( )main_loop( )¶Different USB endpoints are used to logically separate different operations occuring on the bus into separate flows. There are currently 3 USB endpoints checked/used within the main_loop( ) as described earlier.
| Endpoint | Description |
| 0 | Control/status |
| 2 | Host -> FPGA |
| 6 | FPGA -> Host |
Describe typical USB transfers. Always 512-byte bulk transfers. Link to in-band signaling information.
All control information is written using endpoint 0 and the vendor commands. These commands are separated into two different categories: VRT_VENDOR_IN and VRT_VENDOR_OUT. These are processed in the app_vendor_cmd( ) function seen in source:usrp/firmware/src/usrp2/usrp_main.c.
All control communication between the FPGA and FX2 microcontroller is done over the SPI. Daughterboards all seem to be controlled by the generic VRQ_I2C_* and VRQ_SPI_* commands.
VRT_VENDOR_IN Commands¶VRQ_GET_STATUS
GS_TX_UNDERRUNGS_RX_OVERRUNVRQ_I2C_READVRQ_SPI_READVRT_VENDOR_OUT Commands¶VRQ_SET_LEDVRQ_FPGA_LOAD
FL_BEGINFL_XFERFL_ENDVRQ_FPGA_SET_RESETVRQ_FPGA_SET_TX_ENABLEVRQ_FPGA_SET_RX_ENABLEVRQ_FPGA_SET_TX_RESETVRQ_FPGA_SET_RX_RESETVRQ_I2C_WRITEVRQ_SPI_WRITEgcell solves the problem of efficiently distributing potentially small tasks across the SPEs by using
a distributed SPE-centric scheduler that pulls work to SPEs as they become available.
In addition gcell provides high-performance DMA of arguments to and from the SPEs, task
completion notification to client processes, and binding and rendezvous between PPE and SPE code.
Benchmarks show near linear speed-up from 1 to 16 SPEs on 2-way Cell blades.
gcell: an SPE Scheduler and Asynchronous RPC Mechanism for the Cell Broadband Engine
The primary interface is given in
source:gcell/include/gcell/gc_job_manager.h and
source:gcell/include/gcell/gc_job_desc.h.
The benchmark code is
source:gcell/apps/benchmark_nop.cc.
Here's a snapshot of our current scaling performance. The test code submits 500k jobs and times how long it takes to complete all the jobs as a function of the number of spes used. Several runs are made, which vary in how much work each job does. For the purposes of the benchmark, the jobs busy wait for a specified number of microseconds on the SPE. This is called the 'work increment'. Thus, if the work increment is 10 us, the total useful_work is 10 us * 500k jobs = 5 seconds. The Y-axis plots useful_work divided by the real time required to complete all jobs. It's basically "speedup".


Firstly emerge the packages that gnuradio depends on.
$ emerge swig fftw cppunit boost alsa-lib sdcc guile wxpython xmlto numpy gsl
Next download a release tarball or the source from SVN and perform the standard build and install procedure. Add "--prefix=/usr/" to the ./configure command to install the components to the correct location for Gentoo.
$ ./bootstrap $ ./configure --prefix=/usr/ $ make $ make check $ make install
After these simple steps you should have a working GNU Radio install on your Gentoo system.
Three ways to start off with GNU Radio:
Official Stable Release:
Unstable development code:
If you have never used GNU Radio before, it is recommended to start with one of the official releases.
If your distribution has ready-to-use packages you are encouraged to start with them. It's easiest to install and you will get a usable GNU Radio installation to start right from. Official releases will give you a stable codebase for long-term development.
If your distribution or OS has no packages yet, you can build GNU Radio yourself from source. This can be be a bit challenging. Instructions for downloading can be found at Download. Instructions for installation are included in the GNU Radio distribution, but are also available online in the BuildGuide.
If you want to get the latest and greatest, need some recently added feature, or want to contribute to GNU Radio, you can get the latest version from the subversion repository. For instructions see the BuildGuide.
If you have any problems or questions, the place to ask is the discuss-gnuradio mailing list. Please take note of ReportingErrors
The Universal Software Radio Peripheral or USRP2 is the recommended device for interfacing GNU Radio with the real world The USRP has been developed especially for GNU Radio, and is available from Ettus Research.
It is possible to use GNU Radio with other I/O hardware. See the FAQ for details on supported hardware. It is also possible to use the USRP with software other than GNU Radio. See the UsrpFAQ for details.
If you or your group would like to get a jump start on using GNU Radio and the USRP, Corgan Enterprises LLC offers a 3-day, hands-on training class, to be held at your own location.
有三种方式开始你的GNURadio的旅程:
正式坚固版:非坚固开发代码:
** 用git获得非坚固版源码
如果你你从来没有用过GNURadio,建议你从一个正式版开始入手。
If your distribution has ready-to-use packages you are encouraged to start with them. It's easiest to install and you will get a usable GNU Radio installation to start right from. Official releases will give you a stable codebase for long-term development.
If your distribution or OS has no packages yet, you can build GNU Radio yourself from source. This can be be a bit challenging. Instructions for downloading can be found at Download. Instructions for installation are included in the GNU Radio distribution, but are also available online in the BuildGuide.
If you want to get the latest and greatest, need some recently added feature, or want to contribute to GNU Radio, you can get the latest version from the subversion repository. For instructions see the BuildGuide.
If you have any problems or questions, the place to ask is the discuss-gnuradio mailing list. Please take note of ReportingErrors
The Universal Software Radio Peripheral or USRP2 is the recommended device for interfacing GNU Radio with the real world The USRP has been developed especially for GNU Radio, and is available from Ettus Research.
It is possible to use GNU Radio with other I/O hardware. See the FAQ for details on supported hardware. It is also possible to use the USRP with software other than GNU Radio. See the UsrpFAQ for details.
If you or your group would like to get a jump start on using GNU Radio and the USRP, Corgan Enterprises LLC offers a 3-day, hands-on training class, to be held at your own location.
GNU Radio can be used to create GNSS receivers. The DBSRX daughterboard for the USRP is capable of receiving signal from all contemporary GNSS systems.
Below is a list of projects that uses the GNU Radio framework or the USRP to implement GNSS receivers. Please add your self to the list if you are doing similar work.
GNU Radio can be used to create GNSS receivers. The DBSRX daughterboard for the USRP is capable of receiving signal from all contemporary GNSS systems.
Q: What about DGPS for GPS positioning accuracy improvement?
A: For the continental US, WAAS is more reasonable. The marine DGPS beacons that operate at LF (~300kHz) would require another RF path and related antenna.
Q: What about WAAS, EGNOS (Europe), MSAS (Japan / Asia) for GPS positioning accuracy improvement?
A: WAAS is broadcast on the same L1 frequency as GPS itself. So WAAS support is a pure software feature.
----
CategoryRadio
![]()
Note This guide is for the GRC bundled with gnuradio and not for any of the current releases. If you are using GRC 0.70 and below, please use this guide instead.
GNU Radio Companion (GRC) is a graphical tool for creating signal flow graphs and generating flow-graph source code. It is currently under development by Josh Blum.
What has changed in GRC since the stable 0.70 release?
Most (if not all) of these requirements can be found in the package manager of you linux distribution.
GRC is bundled with the current gnuradio trunk and will be included in the 3.2 release. I recommend configuring your GNU Radio installation with wx-python, usrp, and audio support. However, any configuration will work (see note). Follow the build-guide
Note: GRC will let you generate flow graphs with components that are not included in your local install. For example, you can generate a flow graph with a usrp source, but the code will error when executed unless GNU Radio is configured with usrp support.
GRC is bundled with gnuradio, so following the build guide should be enough to install GRC. However, GRC will not be installed if you were missing any of the required components. Install any missing components and re-run configure/install:
./configure make sudo make install
GRC should appear in the list of configured components; if not, read the configure verbose for errors.
To view the blocks' documentation from inside GRC, install doxygen and configure gnuradio with doxygen support:
./configure --enable-doxygen make sudo make install
If you have an operating system that supports the freedesktop.org standards (Gnome, KDE, XFCE), then you may install the icons, mime type, and menu items bundled with GRC. After installing GRC, run the following command:
cd <prefix>/libexec/gnuradio/ sudo grc_setup_freedesktop install -- OR for older versions -- sudo grc_setup_freedesktop install
GRC installs several executable python files into your system's path.
Open a terminal and enter the following:
gnuradio-companion -- OR for older versions -- grc
GRC provides a GUI app to probe the USRP for daughter-board information. Open a terminal and enter the following:
usrp_probe
GRC provides a GUI app to probe the USRP2 for daughter-board information. Open a terminal and enter the following:
usrp2_probe
Variables map symbolic names to values. In GRC, a variable can define a global constant or, a variable can be used in conjunction with a GUI to control a running flow graph.
The variable block is the most basic way to use a variable in GRC. The ID parameter of the variable block is the "symbolic name". The symbolic name must be alpha-numeric (underscores allowed) and begin with a letter. To use the variable, simply enter the symbolic name into a parameter of another block.
Certain blocks have callback methods that allow their parameters to be changed while executing flow graph. Variable controls in GRC use variables in combination with callback methods to modify these parameters. If a parameter has a callback method, the parameter will be underlined in the block-properties dialog. The variable slider, variable text box, and the variable chooser block provide graphical widgets such as sliders, text boxes, radio buttons, and drop downs as variable controls. In addition, the variable sink block takes samples from a gnuradio stream and writes the samples to a variable.
String parameters have a two-phase evaluation. First, GRC evaluates the parameter as-is. If the parameter does not evaluate to a string data type or the evaluation fails, then it is understood that the parameter had implied quotation. In this case, GRC will evaluate the parameter again with quotation marks; which will return a string with the exact code that was typed into the parameter window.
To use a variable inside a string simply type the name of the variable into the parameter: my_var. If the variable is not a string, cast the variable with python's str function: str(my_var). Standard python string functionality applies: "My Var = " + str(my_var).
*Note: String parameter types also include the file open and file save types.
Many blocks in gnuradio that take an array of complex or real taps as a parameter. GNU Radio provides a package to generate all kinds of filter and window taps. See the firdes package from the gnuradio documentation.
For the pass band functions, window defaults to the Hamming window. The beta parameter defaults to 6.76, and only applies to the Kaiser window.
Create a new "import" block, and enter the following for the import parameter:
from gnuradio.gr import firdes
Note: Most blocks with a taps parameter automatically import the firdes module. You only need to use the import block when firdes will not evaluate.
Enter the following into the taps parameter of a filter block:
firdes.low_pass(1.0, samp_rate, 1000, 100, firdes.WIN_HAMMING)
Suppose that you have an array of filter taps stored in a file that you would like to use inside GRC:
Create a new "import" block, and enter the following for the import parameter:
import numpy
Enter the following into the taps parameter of a filter block:
numpy.fromfile('taps file path', numpy.complex64)
This will read an entire binary file and parse every 64 bytes into a complex number. Use numpy.float32 for real taps. See the numpy.fromfile help for more advanced usage:
Help on built-in function fromfile in numpy:
numpy.fromfile = fromfile(...)
fromfile(file=, dtype=float, count=-1, sep=_) -> array.
Required arguments:
file -- open file object or string containing file name.
Keyword arguments:
dtype -- type and order of the returned array (default float)
count -- number of items to input (default all)
sep -- separater between items if file is a text file (default "")
Return an array of the given data type from a text or binary file. The
'file' argument can be an open file or a string with the name of a file to
read from. If 'count' == -1 the entire file is read, otherwise count is the
number of items of the given type to read in. If 'sep' is "" it means to
read binary data from the file using the specified dtype, otherwise it gives
the separator between elements in a text file. The 'dtype' value is also
used to determine the size and order of the items in binary files.
GRC offers several graphical sinks and graphical controls for creating wx-gui flow graphs. (scope sink, fft sink, number sink, waterfall sink, constellation sink, slider control, and chooser control) Each of these graphical elements have a grid position parameter for precise positioning.
A grid position parameter is a list of 4 integers of the form (row, column, row span, column span). The row and column specify the position of the upper-left corner of the graphical element. The smallest position, the (0, 0) position, specifies the upper-left corner of the grid.
If left blank, the grid parameter specifies that the graphical element will be automatically stacked into a vertical sizer. The vertical sizer is positioned directly above the grid sizer. If you do not want any elements to be added to the vertical sizer, leave no grid parameters blank.
The row and column span specify the stretch, or the number of rows and columns that the graphical element can occupy. The row span specifies the number of rows down from the row positon, and the column span specifies the number of columns right of the column position. Therefore, the span must be at least (1, 1) to occupy the minimum of 1 grid cell.
The user wishes to place a slider, centered directly above a graphical sink. The slider will be positioned at the 2nd column of the top row and with a column span of 2. The sink will be positioned on the 2nd row, and with a row span of 2 and a column span of 4. Notice the grid parameters below, and the resulting gui layout:
The Elements:
The Resulting GUI:
| 0,0 | 0,1 | 0,2 | 0,3 | |||||
| 1,0 | 1,1 | 1,2 | 1,3 | |||||
| 2,0 | 2,1 | 2,2 | 2,3 |
GRC can create hierarchical blocks out of the built-in blocks. Hierarchical blocks can be instantiated inside of other grc flow graphs. The python code generated from a hierarchical block can itself be used in non-GRC flow graphs. Four important blocks are used in the creation of a hierarchical block: The options block, parameter blocks, and the pad source and pad sink.
In order to make a hierarchical block, the parameters in the options block must be set properly. The id of the options block sets the module name, and must be unique among the entire library of blocks (built-in and custom). The title parameter sets the display name for the block. The generate options must be set to "Hier Block". The category parameter sets the category for the new block. This category can be an existing category in the block selection window or a new category. Categories may be nested by specifying a name with slashes, ex: Custom/Filters. To put blocks into the root category, specify a single slash "/" (a blank category will hide your block).
Parameter blocks specify variables in your hierarchical block that should be configurable in the top level block. Parameter blocks work much like variable blocks with a few exceptions: Parameters blocks cannot depend on variable blocks or other parameter blocks. Parameter blocks have a label parameter for display purposes. Parameter blocks take the place of a variable block, do not try to create a variable block with the same id as your parameter block.
The pad source and sink blocks create inputs and outputs for the hierarchical block. The pad blocks have configurable data types, vector lengths, and number of ports. A flow graph can have at most, one pad source, and one pad sink. A hierarchical block may have one pad sink and no pad source or no pad sink and one pad source, but it must have at least one pad block.
Every block in GRC corresponds to an XML file that describes the block's parameters, inputs, outputs, and other attributes. Adding a custom block into GRC is simply a matter of creating one of these XML block definition files. A few caveats:
The best way to learn how to create the xml file is to learn by example. See the [/browser/gnuradio/trunk/grc/blocks block definitions] packaged with GRC, and read through a few files. Essentially, all block definitions are structured as follows:
<?xml version="1.0"?>
<block>
<name>My Block Name</name>
<key>my_package_my_block_ff</key>
<category>Filters</category>
<import>from gnuradio import my_package</import>
<make>my_package.my_block_ff($param1, $param2)</make>
<callback>set_param1($param1)</callback>
<param>
<name>Parameter 1</name>
<key>param1</key>
<type>real</type>
</param>
<param>
<name>Parameter 2</name>
<key>param2</key>
<value>1</value>
<type>int</type>
</param>
<sink>
<name>in</name>
<type>float</type>
</sink>
<source>
<name>out</name>
<type>float</type>
</source>
<source>
<name>out</name>
<type>float</type>
</source>
</block>
There are many methods to tell grc about your new xml file. Choose one of the following methods...
Create the *.xml file inside ~/.grc_gnuradio/ where ~ is your home directory. If the directory does not exist, create it: mkdir ~/.grc_gnuradio/
Create or edit ~/.gnuradio/config.conf and add the following lines:
[grc] local_blocks_path=/path/to/my/blocks
The local_blocks_path can contain multiple paths separated by colons: local_blocks_path=/path/to/blocks1:/path/to/blocks2
Set the GRC_BLOCKS_PATH environment variable to a path that contains your custom block wrapper. The GRC_BLOCKS_PATH can contain multiple paths separated by colons: GRC_BLOCKS_PATH=/path/to/blocks1:/path/to/blocks2
Feel free to submit your own screen shots or flow graphs.
Note These instructions are for GRC 0.70 and below. If you are using the GRC bundled with your gnuradio installation, please use this guide instead.
The GNU Radio Companion is a preliminary graphical user interface which allows GNU Radio components to be put together graphically. It is currently under development by Josh Blum. GNU Radio Companion encompasses over 200 blocks from the GNU Radio Project.
Blocks are manually integrated into GRC via descriptive python definitions. The definitions are very flexible, and allow multiple GNU Radio blocks to be grouped into a single "super-block". A graphical interface allows the user to configure and connect these blocks into a flow graph. The flow graph is saved in an xml format. Another program reads this xml file and reconstructs the flow graph with native GNU Radio blocks.
Flow Graph:
A flow graph is an interconnection of signal processing blocks. GRC provides a scrollable window to place and connect various signal blocks.
Signal Blocks:
Signal blocks perform all of the processing in a flow graph. For example: A signal block can be a filter, an adder, a source, or a sink. GRC represents signal blocks as colored, rectangular blocks. Each block has a label indicating the name of the block and a list of parameters.
Parameters:
Parameters influence the functioning of a signal block. For example: A parameter can be a sampling rate, a gain, or a flag. Most parameters for a signal block are displayed below the block's label.
Sockets:
Sockets are the inputs and outputs of a signal block. Each signal block has certain sockets associated with it. For example: An adder has several input sockets and one output socket. GRC represents a socket as a small rectangle attached to the graphical signal block. The socket has a label indicating its function. Labels are usually named "in" or "out". Some labels are named "vin" or "vout" to indicate a vector type. Sockets are also are colored to indicate their data type. Blue->complex. Red->float. Green->int. Yellow->short. Purple->byte.
Connections:
A connection joins an input and an output socket. GRC represents connections by drawing a line between the two sockets. Connections must be between matching data types (even vectored and non-vectored data types).
Variables:
A variable holds a number/string that is available to all elements in the flow graph. Variables serve two purposes: One, parameters can share a value by using a common variable. Two, a variable with a range can dynamically change the value of a parameter while the flow graph is running.
An archive of all releases can be found here: Release Archive
See the current GRC guide.
Notes for Ubuntu Hardy Heron users: Ubuntu removed the xml.dom.ext package from their repositories. GRC 0.70 and below require this package. Solution: download the pyxml source. Unpack the source, and run "sudo python setup.py install" from the source directory. This issue has been fixed in the trunk and in future releases.
Notes for Cygwin users: Install pygtk with the Cygwin setup. For python-xml, download the pyxml source.
Unpack the source, and run "sudo python setup.py install" from the source directory. If that fails, just copy the xml directory into the python site-packages directory (with GNU Radio). Make sure that you install the X11 server with cygwin, and start the X11 server before running GRC.
Notes for MacOSX users: Follow the Mac Install Instructions. Use mac ports (or whatever program you picked) to install the dependencies for GRC. Also, make sure to install wx-python 2.6.3 or 2.8.6, since 2.8.4 causes problems.
Operating System CompatibilityIn the src folder, execute Editor.py with the python interpreter. Saved flow graphs can be passed as the first argument to Editor.py.
Adding a block:
Select a block from the signal block tree menu. Double click the block or click the add button. A new signal block will be placed on the screen.
Moving a block:
Left click a block and drag it around the flow graph. If you drag a block near a border that can be scrolled, wiggle the block to advance the scroll bar.
Rotating a block:
With a block selected, select rotate right or left from the tool bar. Short-cut keys: right or left.
Deleting a block:
With a block selected, select delete from the tool bar. Short-cut keys: delete.
Connecting blocks:
Left click on one socket and then left click on another socket. A connection will only be created between input and output sockets. An input socket may have no existing connections. An output socket may have unlimited connections. Red lines surrounding the connection indicates that the data types of the sockets do not match.
Double click on a block or select it and choose properties from the edit menu. A dialog containing all the parameters for the signal block will appear. Some parameters are set via a drop down menu, most must be typed in as characters. These parameters are usually numeric, representing sampling rates, gains, and amplitudes. Numeric parameters may contain mathematical expressions with variables.
A math expression may contain any number of variables, numbers, and operators. There must be an operator between every number/variable. Possible operators are +, -, *, /, ^. Numbers can be integers, decimals, floating-point, and complex. Python's built in floating point and imaginary formats are used. Floating point numbers end in an "e" followed by a signed integer. Imaginary numbers end in a "j". Matching bracket pairs are allowed: (), [], {}. Variables are denoted by a leading '$' character.
See Help->Math Expressions in the Editor.
The variable window has 5 columns: variable name, default value, minimum value, maximum value, step size. Choose add to create a new variable entry. Choose remove to delete a selected variable entry. Any value in an entry can be edited by clicking on the input field in the selected row. Invalid changes to a cell are ignored. Variable names are case-sensitive and alpha-numeric, and they may contain hyphens. The first character must be a letter. The default value for the variable may be any string.
A variable with a range may be dynamically changed while the flow graph is executing. However, only signal block parameters, underlined in the signal block's properties window, can actually be altered while the flow graph is executing.
For a ranged variable, the default, minimum, maximum, and step size values must be of type float or int. To make a variable with a range, simply type a number into the min or the max input field and the other fields will be filled in. The min must be less than or equal to the default, and the max must be greater than or equal to the default. To remove the range from a variable, just clear one of the input cells for min, max, or step and all cells will be cleared.
If a flow graph is valid, all parameters are valid and all sockets are connected. Choose run from the tool bar or press F5. A wx window will appear with any sliders or graphs that were added. To stop the flow graph, close the wx window, press stop in the tool bar, or press F7. Flow graphs can be run without the interface by invoking the python interpreter on ExecFlowGraphGUI.py, and passing the saved flow graph as the first argument to ExecFlowGraphGUI.py.
Feel free to add requests for new features and behaviors.
Feel free to submit your own screen shots or flow graphs.
If you'd like to contribute, take a look at these, or add your own!
[I think a lot of these should be entered as Enhancement or Task tickets.]
GNU Radio 是免费软件开发套件,提供了信号实时处理的软件和低成本的软件无线电硬件。被广泛应用于业余爱好者,学术研究以及商业环境中去支持无线通讯的学术研究以便去真实实现无线电系统。
GNU Radio 应用程序用Python语言来编写,真实的信息处理过程是由C++浮点扩展库来实现的。因此开发者获得实时高效的可复用的应用开发环境。
虽然GNU Radio并不是主要用于仿真,但也要以不用真实硬件,而使用预先记录或生成的数据来开发信号处理算法。
.
Acronym for GNU Radio Companion , the graphical user interface used to string GNU Radio blocks together.
A high level introduction to m-blocks can be found here.
OverviewPage for info about the December 2006 HackFest
That was about all we had space for as you can see:
http://n4hy.smugmug.com/gallery/2262143
The HackFest will be held December 13th-20th, 2006. Plan to arrive late on the 12th or sometime on the 13th.
Ettus Research Galactic Headquarters
604 Mariposa Avenue
Mountain View, CA 94041
The best airport to fly into is San Jose (SJC). The next best would be San Francisco (SFO). Oakland (OAK) should be considered a last resort.
Suggested Hotel -- Marriott Residence Inn Mountain View and Palo Alto http://marriott.com/property/propertypage/SFOMV
Other Hotels -- http://maps.google.com/maps?f=l&hl=en&q=hotel&near=604+mariposa+ave,+94041&ie=UTF8&z=15&om=1
This one is literally around the corner from GHQ. If they are full or cost too much, let me know. There is another [somewhat less nice] place next door.
If Eric isn't driving here from Reno, then it would be nice if someone rented a car. We only need one, though.
Note from Johnathan: As I live in San Jose, I can help shuttle people from the airport to Matt's if need be.
Hack away on important things missing from GNU Radio, like:
In addition to all the hacking, we'll have some other suitably geeky distractions planned. Ideas I'm working on right now include tours of the Computer History Museum, Stanford Linear Accelerator, Stanford Radio Club and "Big Dish" area, and TechShop. Suggestions for others also welcome.
Lots of people have figured out surface-mount construction techniques and tools that work on a very limited budget. Getting boards assembled by a professional assembly house can be expensive, and there can be rules that may not make sense for a small project. (I've used an ISO-9000 board house in the past, and if I don't bring them paperwork that looks a particular way, they get antsy.) So these techniques for soldering teeny fine-pitch parts are cool, especially with the deals one can get these days on small runs of prototype PCBs.
Hints, tips, advice, background info, encouragement from: hams, piclist, gEDA mailing list, another ham, sci.electronics.basics
If you're going to do this, do NOT use your normal food toaster oven for soldering. Get another toaster oven just for soldering, and do NOT prepare food in it. It will fill up with lead and foul chemicals.
----
Radio Shack sells solder paste (which they call solder weld). I found a toaster oven at Walmart for $20. I decided to try to build the hot air pencil, which totalled about $20. I picked up a hobbyist kit with some surface-mount parts to experiment with. I also found it helpful to pick up a strong magnifying glass at an arts-and-crafts store.
My first experiment was to put some solder paste on two pads, put a resistor on them, and use the toaster oven to melt the solder paste. I used too much paste but the results were very successful. I am quite impressed with the toaster oven approach. Toaster oven discussions on the web talk a lot about the profile of temperature over time, and how semiconductors should not be subjected to extreme heat for more than a few seconds. My impression is that you want to run the thing a little below water's boiling temperature for a few minutes, to dry out any residual water, and then very quickly ramp up the temperature to the oven's maximum, watching the solder joints with the magnifier through the glass door. When the solder appears to have melted everywhere (and then giving it maybe another few seconds for the solder joints you can't see), turn off the oven and open the door so that things will cool quickly.
Then I put together the hot air pencil: a desoldering iron $10 with steel wool ($3, Home Depot) wedged into the nozzle, and replace the squeeze bulb with a tube ($2, Walmart) leading to an aquarium pump ($6, Walmart) so that hot air comes out of the nozzle. The trick is to jam as much steel wool into the nozzle as you can, otherwise the breeze will be so strong that it blows the SMT parts around, and it won't get hot enough to melt the paste. The steel wool provides more surface area to transfer more heat to the flowing air.
If you want a hot air pencil that isn't a cost-saving kludge, the Weller WSTA6 is available for about $60. It uses butane. I looked at one and it wasn't obvious where you get butane refills, or how you apply them. Boston-area people can get one at You-Do-It Electronics.
The hot air pencil seems to take considerable practice to use. Also the solder paste seems to be a bit cantankerous; I've read of people using brushes with it. I'll pick up one or two small paintbrushes and see if that makes it any easier.
There's a learning curve here, so be ready to do lots of inexpensive experiments. Get a roll of SMT resistors and some boards to solder them onto, and waste them liberally while you develop skill.
----
I've now done the toaster oven thing with two boards, having ordered a stencil from http://www.stencilsunlimited.com. I used the stencil for one board, and applied way too much solder paste, and my fine-pitch parts were full of shorts. I tried to remove these with solder wick but didn't have much luck.
I did the first board in a crowded roomful of hobbyists. It was fun, and it was a pleasant reminder of younger days, but the hustle and bustle weren't too helpful for the level of focus needed for SMT construction. I found it much easier, quicker, and more productive to do my SMT construction at home. You want quiet, lots of light, elbow room, and good magnifiers and tweezers. I haven't needed a microscope yet but it might be smart to start looking for one.
For the second board, I used a small paintbrush (the smallest in a set from the stationery section at Walmart) to apply paste directly to pads. On the second board, I decided to use the toaster oven twice, the first time to solder the resistors and caps, and the second time to solder the ICs. My reasoning is that (1) the Rs and Cs can handle heat better than silicon, and (2) this way, when I'm positioning the ICs, I don't need to worry that I'll accidentally push the Rs and Cs out of alignment. I don't think it's actually good practice, and I would be evil to recommend it to anybody who thinks they can populate their board with a single reflow.
One element where practice helps (and unfortunately nothing else seems to) is in knowing how much solder paste is right. The first time with the stencil, I put on too much, and studying it under the magnifier I worried that it might be too much, and the result was shorts. The second time I probably overcompensated, leaving only one or two grains of solder on some pads, and I'm concerned that some pins won't connect at all. Especially on the 144-pin FPGA, I doubt I have the eyesight or steadiness of hand to solder them individually.
Practice is important, and as I wrote earlier, it's good to create an environment where you can get a lot of practice for a small amount of money. The solder paste, the toaster oven, and the paintbrush are cheap, as are rolls of some 0805 and SOT-23 parts. It would be nice to find large cheap volumes of big fine-pitch ICs. The cheapest I've found is this CPLD for only $3.91, of $3.31 in lots of 25. It's in a 100-pin TQFP package with pin spacing of 0.5 mm. Somebody should make up a board especially for SMT construction practice, with no need for vias or a circuit that makes any sense. I might do that myself.
----
CategoryHardware
This page operates as a hub where ideas can come together and be linked to for further discussion and development. It also links to projects that are a work-in-progress as to help connect and get more input.
Moreover, this page gives a record of possible future projects that may be feasible well after the original idea has been presented.
GNU Radio Companion is a graphical user interface used to string components together and automatically generate the proper flowgraph.
Message blocks (or m-blocks) are to be used for implementing tighter time constraints for transmission and reception of signals. This should allow for development of more complex MAC protocols including, but not limited to, GSM and other TDMA style protocols.
Currently, wxPython provides the graphical components for GNU Radio. Since this is not necessarily the most efficient way to display information, OpenGL might be a more efficient method.
Due to the highly abstracted nature of GNU Radio, creating channel blocks for RF channels is not completely out of the question. Gaussian, Rayleigh Fading, Rician Fading, etc could all be simulated along with different frequency offsets to create a better way to evaluate equalizer performance without the use of a USRP or any hardware.
We are in the stage of profiling the code and are looking for users to help contribute profile results on different architectures. If you could contribute to an architecture, we would greatly appreciate it.
You should be able to follow through the instructions sequentially, for which I'm going to provide Ubuntu specifics and general.
We have profile statistics for the following architectures already:Running oprofile with full kernel profiling is required. To do this you must acquire an uncompressed version of your kernel, vmlinux.
In Ubuntu, building VMLinux can be done as follows:sudo apt-get install linux-kernel-devel fakeroot build-essential sudo apt-get source linux-image-2.6.20-16-generic sudo apt-get build-dep linux-image-2.6.20-16-generic cd linux-source-2.6.20-2.6.20/ sudo make oldconfig sudo make vmlinuxIf you are running a custom or self-built kernel, go to your kernel source tree and run the following command:
make vmlinux
sudo apt-get install oprofile glibc-dbg
To build oprofile manually, download it from the official oprofile site and follow the instructions. http://oprofile.sourceforge.net/download/
Before running the oprofile daemon, we must tell it where vmlinux is located. replace $VMLINUX_PATH with the path that vmlinux is located, such as /boot or /usr/src/linux/sudo opcontrol --setup --vmlinux=$VMLINUX_PATH/vmlinuxTest that oprofile will at least start with no errors:
sudo opcontrol --startYou should receive output similar to this, which specifies that it is using the kernel interface:
$ sudo opcontrol --start Using 2.6+ OProfile kernel interface. Reading module info. Using log file /var/lib/oprofile/oprofiled.log Daemon started. Profiler running.
svn co http://gnuradio.org/svn/gnuradio/branches/developers/gnychis/inband-profilingTo build the code, perform the following series of commands.
cd inband-profiling/ (./bootstrap && ./configure && make) | tee inband_logInstall the code:
sudo make install
If you encounter any errors building the code, please report your inband_log.
Since the new in-band code uses new packet formats across the USB bus which the USRP needs to interpret, a new RBF must be used.
You can obtain the RBF that will be used for profiling here:
http://www.andrew.cmu.edu/user/gnychis/usrp_inband_profiling.rbf
To install it, copy it to /usr/local/share/usrp/rev2/
In summary:wget http://www.andrew.cmu.edu/user/gnychis/usrp_inband_profiling.rbf sudo cp usrp_inband_profiling.rbf /usr/local/share/usrp/rev2/ sudo cp usrp_inband_profiling.rbf /usr/local/share/usrp/rev4/
cd inband-profiling/usrp/host/apps-inband/The following applications will be profiled:
$ time ./test_usrp_inband_rx [TEST_USRP_INBAND_RX] Opening the USRP [TEST_USRP_INBAND_RX] Requesting RX channel allocation [TEST_USRP_INBAND_RX] Receiving... [TEST_USRP_INBAND_RX] Deallocating RX channel [TEST_USRP_INBAND_RX] Closing the USRP mb_runtime_thread_per_block: dtor (# workers = 1) real 0m31.495s user 0m8.805s sys 0m0.436sSo let's get to the actual profiling! Start oprofile if you have not done so yet:
sudo opcontrol --startBefore EVERY oprofile run, reset the statistics or else they will carry over to other runs, and go ahead and run an application. Please provide your time per application with the reports. As soon as the application finishes, immediately save the statistics and perform a dump to ensure everything was written to disk. You now have a snapshot at the time your application finished. You will need to choose a different save name per run.
sudo opcontrol --reset time ./test_usrp_inband_rx sudo opcontrol --save=test_usrp_inband_rx_1 sudo opcontrol --dumpFinally, let's retrieve the statistics. The applications you actually run in the top-most directory are scripts which run the true binaries in the .libs directory. opreport needs the true binary, which is prefixed with lt in the .libs directory.
opreport -l session:test_usrp_inband_rx_1 .libs/lt-test_usrp_inband_rx &> oprofile-test_usrp_inband_rxAnd there you have it, if you look through oprofile-test_usrp_inband_rx you should see something similar to this:
CPU: P4 / Xeon with 2 hyper-threads, speed 2993 MHz (estimated) Counted GLOBAL_POWER_EVENTS events (time during which processor is not stopped) with a unit mask of 0x01 (mandatory) count 240000 samples % image name app name symbol name 40224 14.0335 libm-2.5.so libm-2.5.so sincosf 15753 5.4960 libpmt.so libpmt.so pmt_nthcdr(unsigned int, boost::shared_ptr<pmt_base>) 12494 4.3589 lt-test_usrp_inband_tx lt-test_usrp_inband_tx ui_nco<float, float>::sincos(std::complex<float>*, int, double) 12088 4.2173 libc-2.5.so libc-2.5.so malloc 11798 4.1161 libc-2.5.so libc-2.5.so free .......
If you see _ under _symbol name for images such as libc, you did not install debug symbols for the library. libc should be the only issue, scroll back up to read about installing this, we require that these symbols be included.
uname -a >> machine_specs cat /proc/cpuinfo >> machine_specsCreate a times file with information about the times of each application, such as:
test_usrp_inband_rx ------------------- real 0m31.495s user 0m8.805s sys 0m0.436s test_usrp_inband_tx ------------------- <fill me> test_usrp_inband_underrun ------------------------- <fill me>tar and compress your output files like so, for an attachment (or zip them, whichever is easier for you):
tar czvf inband_results.tar.gz machine_specs times oprofile-test_usrp_inband_tx oprofile-test_usrp_inband_rx oprofile-test_usrp_inband_underrun
Send an e-mail to George: gnychis at cmu dot edu, with inband_results.tar.gz as an attachment.
We greatly appreciate any help with the profiling, and once we collect enough profile results we will host them and there will be discussion on the board if you'd like to participate.
Thank you for your time!
The goal of in-band signaling in the [[USRP|USRP] is to support precision timing TDMA packet processing and other related items The in-band signaling allows for metadata and control information to be sent on the same channel as the data This information can be used to control the [wikiUSRP USRP]] on a per-packet basis, allowing low-latency transmission control which is needed for detailed Media Access Control (MAC) protocols.
To support in-band signaling, several changes need to be made to the USRP as well as the GNU Radio framework.
//img236.imageshack.us/img236/3688/groverall2ld9.png">http://img236.imageshack.us/img236/3688/groverall2ld9.png)
| Component | To Do | Deadline | Status | * Assignment * | |||||||
| M-Block | m-block | ----- | Testing | Eric | |||||||
| M-Block | Priority Scheduler | ????? | Not Started | Person | |||||||
| gr_usrp | Marshall 'm-block' to USB packet | ????? | Not Started | Person | |||||||
| -- Timestamp packet | ----- | Not Started | Person | ||||||||
| -- Set header fields | ----- | Not Started | Person | ||||||||
| -- Fill payload and pad | ----- | Not Started | Person | ||||||||
| gr_usrp | Marshall USB packet to m-block | ????? | Not Started | Person | |||||||
| FX2 | Differentiate [[MessageBlocks | m-block] packets from [wikiUsrpFPGA FPGA]] programming packets | ????? | Not Started | Person | ||||||
| FX2 | Strip/Add USB packet padding | ????? | Not Started | Person | |||||||
| FPGA | Parse and interpret USB packet | ????? | Not Started | Person | |||||||
| FPGA | Timestamp counter | ????? | Not Started | Person | |||||||
| FPGA | Add two buses, I2C and SPI | ????? | Not Started | Person | |||||||
| FPGA | Encoding inbound USB packet | ????? | Not Started | Person | |||||||
| -- Timestamp on first sample | ----- | Not Started | Person | ||||||||
| -- Set RSSI | ----- | Not Started | Person | ||||||||
| Daughterboard | Brian???? | ----- | Not Started | Person |
GSM is an acronym that stands for Global System for Mobile Communications. The original french acronym stands for Groupe Spécial Mobile. It was originally developed in 1984 as a standard for a mobile telephone system that could be used across Europe.
GSM is now an international standard for mobile service. It offers high mobility. Subscribers can easily roam worldwide and access any GSM network.
GSM is a digital cellular network. At the time the standard was developed it offered much higher capacity than the current analog systems. It also allowed for a more optimal allocation of the radio spectrum, which therefore allows for a larger number of subscribers.
GSM offers a number of services including voice communications, Short Message Service (SMS), fax, voice mail, and other supplemental services such as call forwarding and caller ID.
Currently there are several bands in use in GSM. 450 MHz, 850 MHZ, 900 MHz, 1800 MHz, and 1900 MHz are the most common ones.
Some bands also have Extended GSM (EGSM) bands added to them, increasing the amount of spectrum available for each band.
GSM makes use of Frequency Division Multiple Access (FDMA) and Time Division Multiple Access (TDMA).
*TDMA will be discussed later
GSM allows for use of duplex operation. Each band has a frequency range for the uplink (cell phone to tower) and a separate range for the downlink (tower to the cell phone). The uplink is also known as the Reverse and the downlink is also known as the Forward. In this tutorial, I will use the terms uplink and downlink.
The ARFCN is a number that describes a pair of frequencies, one uplink and one downlink. The uplink and downlink frequencies each have a bandwidth of 200 kHz. The uplink and downlink have a specific offset that varies for each band. The offset is the frequency separation of the uplink from the downlink. Every time the ARFCN increases, the uplink will increase by 200 khz and the downlink also increases by 200 khz.
*Note: Although GSM operates in duplex (separate frequencies for transmit and receive), the mobile station does not transmit and receive at the same time. A switch is used to toggle the antenna between the transmitter and receiver.
The following table summarizes the frequency ranges, offsets, and ARFCNs for several popular bands.
The following diagram illustrates an ARFCN with paired uplink and downlink frequencies for ARFCN 1 in the GSM 900 band.
The following is a way to calculate the uplink and downlink frequencies for some of the bands, given the band, the ARFCN, and the offset.
Up = 890.0 + (ARFCN * .2)
Down = Up + 45.0
example:
Given the ARFCN 72, and we know the offset is 45MHz for the GSM900 band:
Up = 890.0 + (72 * .2)
Up = 890.0 + (14.4)
Up = 904.40 MHz
Down = Up + Offset
Down = 904.40 + 45.0
Down = 949.40 MHz
The uplink/downlink pair for GSM900 ARFCN72 is 904.40/949.40 (MHz)
Here are the formulas for EGSM900, DCS1800, and PCS1900:Up = 890.0 + (ARFCN * .2)
Down = Up + 45.0
Up = 1710.0 + ((ARFCN - 511) * .2)
Down = Up + 95.0
Up = 1850.0 + ((ARFCN - 512) * .2)
Down = Up + 80.0
The MSISDN is the subscriber's phone number. It is the number that another person would dial in order to reach the subscriber. The MSISDN is composed of three parts:
Country Code (CC)
National Destination Code (NDC)
Subscriber Number (SN)
Country Code (CC) - This is the international dialing code for whichever country the MS is registered to.
National Destination Code (NDC) - In GSM, an NDC is assigned to each PLMN. In many cases, a PLMN may need more than one NDC.
Subscriber Number (SN) - This is a number assigned to the subscriber by the service provider (PLMN).
The combination of the NDC and the SN is known as the National (significant) Mobile Number. This number identifies a subscriber within the GSM PLMN.
The IMSI is how the subscriber is identified to the network. It uniquely identifies the subscriber within the GSM global network. The IMSI is burned into the SIM card when the subscriber registers with PLMN service provider. The IMSI is composed of three parts :
Mobile Country Code (MCC)
Mobile Network Code (MNC)
Mobile Subscriber Identification Number (MSIN)
Type Allocation Code (TAC) - This number uniquely identifies the model of a wireless device. It is composed of 8 digits. Under the new system (as of April 2004), the first two digits of a TAC are the Reporting Body Identifier of the GSMA approved group that allocated this model type.
Serial Number (SNR) - This number is a manufacturer defined serial number for the model of wireless device.
Spare (SP) This number is a check digit known as a Luhn Check Digit. It is omitted during transmission within the GSM network.
On many devices the IMEI number can be retrieved by entering *#06#
Prior to April, 2004 the IMEI had a different structure:
Type Allocation Code (TAC) - 6 digits
Factory Assembly Code (FAC) - 2 digits
Serial Number (SNR) - 6 digits
Spare (SP) - 1 digit
As of April 2004, the use of the FAC was no longer required. The current practice is for the TAC for a new model to get approved by national regulating bodies, known as the Reporting Body Identifier.
This is a newer form of the IMEI that omits the Spare digit at the end and adds a 2-digit Software Version Number (SVN) at the end. The SVN identifies the software version that the wireless device is using. This results in a 16-digit IMEI.
Type Allocation Code (TAC) - 8 digits
Serial Number (SNR) - 6 digits
Software Version Number (SVN) - 2 digits
There is an irc channel on the http://www.freenode.net network where people talk about GNURadio called #gnuradio.
Xilinx ISE Tools will run on Fedora 6 through 8, but you have to fight it a bit -- this was tested on 9.1i. Do the following:
* Turn off SELinux in the System:Administration:Security Level And Firewall menu from the GNOME Panel. ISE won't run (and won't tell you why) if SELinux is enabled. * Download and unzip the ISE distribution. * If running on X86_64, Edit the setup file to change references from lin64 to lin, just like the 386 version. The 64-bit version is not distributed for free. * Install normally * Install the 32 bit version of libstdc++ version 5# yum install compat-libstdc++-33* If you need to run several of the tools like the Constraints Editor and PACE, you'll have to install OpenMotif *** Download the Fedora Core 5 Openmotif rpm from http://download.fedora.redhat.com/pub/fedora/linux/core/updates/5/i386/ *** Extract the files in /tmp
# rpm2cpio openmotif-2.3.0-0.1.9.3.i386.rpm | cpio -ivd*** Copy the extracted library to /usr/lib
# cp ./usr/lib/libXm.so.4.0.0 /usr/lib*** Create the needed symlinks
# cd /usr/lib # ln -s libXm.so.4.0.0 libXm.so.4 # ln -s libXm.so.4.0.0 libXm.so.3*** Install libXp
# yum install libXp.i386*** Before running any of the programs that need OpenMotif, you need to do the following from the shell
export DISPLAY=:0
GNU Radio has been compiled and installed on Mac OS X "Tiger" 10.4 or "Leopard" 10.5 ("OSX") running any compatible version of XCode on all recent Macs -- whether Intel or PPC. Although it might be possible to use GNU Radio under OSX 10.3, getting the background libraries and applications installed would likely be difficult.
There are 2 primary guides for installing GNU Radio on OSX: Jon Jacky and RadioWare@UND. As of the GNU Radio 3.2 release (24 May 2009), then former is somewhat out of date but can still be used as a reference if desired. The latter is up to date for 3.2, provides scripts for most of the work that provide equivalent functionality on either version of OSX.
There are a number of background libraries and applications that must be installed from source or binary in order to compile or execute GNU Radio. These can be obtained by using Fink, MacPorts, and/or from source / scratch. MacPorts tends to be more up-to-date with respect to new releases, which can be both a blessing and a curse. Both Fink and MacPorts offer thousands of ready-to-install libraries and applications, and hence they are highly recommended to use instead of installing from source / scratch. MacPorts will soon offer a meta-installer for GNU Radio release 3.2: "sudo port install gnuradio ursp" will install all known compilable GNU Radio modules including USRP.
NOTES:
GNU Radio hosts a number of email lists for discussion of GNU Radio related topics at "It is strongly recommended that everyone using GNU Radio and/or the USRP subscribe to the discuss-gnuradio mailing list. It is the proper place to ask if you have any questions or problems.
For hints and rationales see How do I quote correctly.
You can use the following table as a guide to the lists which are most relevant to you.
Please note that you must be subscribed to post to these lists. Postings from non-subscribed addresses are quietly dropped.
| Name | Description | View archive | Subscribe |
| discuss-gnuradio@gnu.org | This list is for discussion of GNU Radio development, porting to new platforms, ideas for the future, general GNU Radio usage or problems. New alpha and stable releases are announced here. | View | Mailman |
| patch-gnuradio@gnu.org | This is where the patches to the gnuradio repository are posted for peer review before being committed to SVN. | View | Mailman |
| commit-gnuradio@gnu.org | Automatically generated notifications of commits to the source code repository (read-only). | View | Mailman |
| usrp-announce@lists.ettus.com | The USRP-announce mailing list, which gets about 1 message per month, contains the latest news on the USRP. | View | Mailman |
This information worked fine for Mandriva 2007.1
You should NOT need to compile any dependencies from source. EVERYTHING is available as a package. The install should be trivial. Some packages you will need to install if not already installed:You can install these packages by using your favourite package manager.
Then follow instructions at BuildGuide.
Message blocks (or m-blocks) are a GNU Radio extension, designed in cooperation with BBN, that allows more natural handling of packet-based data. Full details of the message block can be found in the original BBN proposal: http://acert.ir.bbn.com/downloads/adroit/gnuradio-architectural-enhancements-3.pdf | http://web.archive.org/web/20070316174431/http://acert.ir.bbn.com/downloads/adroit/gnuradio-architectural-enhancements-3.pdf
The message-block introduces several new capabilities to GNU Radio:A message-block is a bi-directional block in which information flows as messages that may contain data, metadata, control information, status information, and signals. Since m-blocks can communicate many different types of messages, each port is typed with a protocol class to ensure that only compatible ports are connected. This ensures that an m-block communicating control information is not connected with an m-block communicating status information. An m-block may have zero or more bi-directional message ports of the same protocol.
Multiple levels of aggregation can be used with the m-block such that m-blocks may be enclosed within each other. However, the m-block is not limited to containing other m-blocks. It may contain collections of GNU Radio blocks or flow_graphs. Aggregation allows for conversions between messages and streams of data samples to take place in an internal fashion to a single m-block. The following terminology is used:Unlike GNU Radio blocks which are connected through a flow_graph which provides a scheduler and maintains topological information, the aggregation property of m-blocks require them to maintain their own topological information. There will only be a single top-level m-block that provides equivalent topological functionality of a GNU Radio flow_graph, rather than a corresponding flow_graph being needed for each m-block.
Each m-block has a processing callback function, handle_message, which handles the data and metadata processing as well as the message timing functionality. The handle_message callback relies on the scheduler for external event notification and therefore never blocks.
When used in conjunction with a priority based scheduler, the priority of the m-block will be the priority of the highest priority message within its queue. With a series of m-blocks in the scheduler, this allows for high priority signals to be processed quickly.
The messages that flow through m-blocks have two types of information: metadata and data. The metadata may contain the message version, timestamps, a priority, segmentation information, and commands/notifications from external entities. The data portion of the message carriers the data which may be transformed by blocks as it is passed through a flow_graph. The following is the proposed message format, taken from the BBN proposal:
| Field | _Description | |||
| Message Handle | Unique identifier for this message. | |||
| Priority | Message priority. | |||
| Signal | An event name used to control state transitions within the FSM of m-blocks that process this message. | |||
| Timestamps | A table that carries the entry/exit timestamps for blocks in the processing path. (not required of all blocks) | |||
| Data portion | The data to be operated on by the blocks in a processing flow_graph. |
As discussed in the introduction, each port on an m-block has an associated protocol class to ensure m-blocks connected to each other carry the same types of messages. Aside from the type, the protocol class also has an associated direction that specifies whether a message is permitted to travel in or out of the port. The proposed classes are the following:
see MultiUsrp
These instructions are for using MinGW and MSYS to install and build GNU Radio software, including USRP TX/RX support, under Windows XP.
NOTE: Do not use Windows folder names with spaces. This means that your default Windows home directory (typically C:/Documents and Settings/user-name/My Documents) should not be used. Your MSYS home directory is a better place to work (unless your user name contains spaces).
You can build and use GNU Radio under MinGW/MSYS and Cygwin on the same system, but you will need separate build directories. It is easiest to have separate home directories and not try to share source code between the two systems.
Installation with MinGW/MSYS requires the following main steps:The recommended version of Python for GNU Radio under MinGW/MSYS is Python 2.6.5. Versions 2.5 and 2.4 can be used if you already have them intalled. Later versions have not been tested. The instructions that follow assume you are using version 2.6.5.
Download Python 2.6.5 Windows installer (from http://www.python.org/download). Double-click python-2.6.5.msi to install. Edit the installation directory if needed; otherwise, the default options can be used.
Download numpy-1.4.1-win32-superpack-python2.6.exe (from http://sourceforge.net/projects/numpy/files). Double-click numpy-1.4.1-win32-superpack-python2.6.exe to install, using default options.
wxPython is not required to build GNU Radio, but many applications use it. To install it, download wxPython2.8-win32-ansi-2.8.10.1-py26.exe (from http://sourceforge.net/projects/wxpython/files). Double-click wxPython2.8-win32-ansi-2.8.10.1-py26.exe to install. You may need administrator privileges for this step.
To install MinGW and MSYS you will need to install the base systems then add the latest packages needed for GNU Radio. The following instructions assume that you install MinGW in C:/MinGW and MSYS in C:/msys/1.0.
Download MinGW-5.1.6.exe (from http://sourceforge.net/projects/mingw/files). Double-click on MinGW-5.1.6.exe to run the installer. Select the "Candidate" and "g++ compiler" options.
Download MSYS-1.0.11.exe (from http://sourceforge.net/projects/mingw/files). Double-click on MSYS-1.0.11.exe to run the installer; use the default settings. Type "y" to continue with post install, "y" when asked if MinGW is installed, and "C:/MinGW" when prompted for the MinGW install directory.
More recent versions of MSYS are available, but automated installers are not yet available for them, and they don't seem to be needed for building GNU Radio.
The MSYS instllation should produce an MSYS icon on your desktop. Double-clicking this icon will start an MSYS shell. All commands given in the following instructions should be entered in an MSYS shell.
C:/MinGW. These can be found at http://sourceforge.net/projects/mingw/files, but the direct links below are faster:
file above with the following commands:cd /mingw tar --lzma -xf file
C:/msys/1.0. These can be found at http://sourceforge.net/projects/mingw/files, but the direct links below are faster:
file above with the following commands:cd / tar --lzma -xf fileCreate source directories with the commands:
cd /usr mkdir src mkdir local
C:/msys/1.0/src and the local directory at C:/msys/1.0/local.
Unless otherwise noted, the following packages are required for building GNU Radio:
C:/msys/1.0/local:
and unpack them (into C:/msys/1.0/local) using Windows "Extract All..." or your favorite unzip utility.
Download
swigwin-1.3.40.zip (from http://www.swig.org/download.html) to C:/msys/1.0/local. Extract swigwin-1.3.40.zip to create the folder swigwin-1.3.40. You can move this folder to another location, but the instructions below assume it is in /usr/local (C:/msys/1.0/local).
Follow the instructions in installing FFTW.
Installing only prebuilt DLLs for Windows is not sufficient for building GNU Radio unless you know how to create the necessary pkgconfig file.
C:\msys\1.0\src. From an MSYS shell, install it with:cd /usr/src tar -zxf cppunit-1.12.0.tar.gz cd cppunit-1.12.0 ./configure --disable-static make make check make install
Note that attempts to build CppUnit 1.12.1 under MinGW/MSYS fail at the make check step.
/usr/src (C:/msys/1.0/src) and install it with the commands:cd /usr/src tar -jxf boost_1_43_0.tar.bz2 cd boost_1_43_0 ./bootstrap.sh --with-toolset=mingw ./bootstrap.sh --with-libraries=thread,date_time,program_options --with-bjam=tools/jam/src/bin.ntx86/bjam ./bjam --prefix=/usr/local link=shared install mv /usr/local/lib/*boost*.dll /usr/local/bin
C:\msys\1.0\src. From an MSYS shell, install it with: cd /usr/src tar -zxf gsl-1.14.tar.gz cd gsl-1.14 ./configure --disable-static make make check make install
This package is optional. It is needed to build gr-audio-portaudio, which currently works better than gr-audio-windows. See hints, tips, and known problems and solutions for Windows for more information.
To install PortAudio see installing PortAudio.
SDCC is not required to build GNU Radio but is needed to use the USRP.
Download sdcc-2.9.0-setup.exe (from http://sourceforge.net/projects/sdcc/files). Double-click on sdcc-2.9.0-setup.exe to install; the default prompts work fine, but only the base tools and the include files are needed. SDCC is installed in C:\Program Files\SDCC. You will be given the option of adding this location to your Windows PATH; you can either do this (once only!) or add /c/Progra~1/SDCC/bin to your MSYS PATH (see PATH environment variable below).
This is not required to build GNU Radio but is needed to use the USRP.
Download libusb-win32-device-bin-0.1.12.2.tar.gz (from http://sourceforge.net/projects/libusb-win32/files) toC:\msys\1.0\src. From an MSYS shell, install it with:cd /usr/src tar -zxf libusb-win32-device-bin-0.1.12.2.tar.gz cd libusb-win32-device-bin-0.1.12.2 cp include/* /usr/local/include cp lib/gcc/* /usr/local/lib cp bin/* /usr/local/bin
/etc/profile (i.e., C:\msys\1.0\etc\profile) to include a line like:export PATH="$PATH:/c/Python26:/usr/local/swigwin-1.3.40:/c/Progra~1/SDCC/bin"
~/.bash_profile. You can also add lines to /etc/profile or ~/.bash_profile to define the path to USRP firmware files and the GNU Radio Python modules:export USRP_PATH=/usr/local/share/usrp export PYTHONPATH=/usr/local/lib/site-packages
/usr/local/bin/swig:#! /bin/sh exec /usr/local/swigwin-1.3.40/swig.exe "$@"
python (in /usr/local/bin/python) is a little more complicated:#! /bin/sh if test $# -ne 0; then exec /c/Python26/python.exe "$@" else exec /c/Python26/python.exe -i fi
NOTE: The following instructions are written for GNU Radio release candidate 3.3.0-rc0. It is expected that they will apply to later candidate releases and to release 3.3.0 when they become available. To build a release other than 3.3.0-rc0, substitute the number of the release wherever 3.3.0-rc0 appears in the following instructions.
tar -zxf gnuradio-3.3.0-rc0.tar.gz cd gnuradio-3.3.0-rc0 export PKG_CONFIG_PATH=/usr/local/pkgconfig export CXX="g++ -mthreads" export CPPFLAGS="-DWINVER=0x0501 -I/usr/local/include" export LDFLAGS="-L/usr/local/lib -lws2_32" ./bootstrap ./configure --prefix=C:/msys/1.0/local
./bootstrap command won't be necessary in future releases; don't be surprised if it gives a bunch of warning messages.
The ./configure command should produce a lot of output, ending with a list of components that have been successfully configured and a list of components that were skipped. Check the list of skipped components to see if any that you need are listed; if they are, you will need to examine the output listing and the file config.log to figure out why they were skipped. After correcting the problem, you will need to repeat the ./configure command.
make
make check
make install
/usr/local/bin you will need to have C:/Python26 in your PATH. You can add it with:
export PATH="${PATH}:/c/Python26"
/etc/profile or ~/.bash_profile or anytime prior to using Python (or you can add it to your Windows PATH). You will also need to specify the path to the GNU Radio Python modules:export PYTHONPATH=/usr/local/lib/site-packages
/etc/profile or ~/.bash_profile. set PATH=%PATH%;C:\Python26;C:\msys\1.0\local\bin;C:\mingw\bin set PYTHONPATH=C:\msys\1.0\local\lib\site-packages
gnuradio):cp /usr/bin/libusb0.* gnuradio/usrp
Your USRP should be ready to go!
1 <table width="100%" border="0">
2 <tr>
3 <td align=center><strong>1 pipeline x 3 stages</strong></td>
4 <td align=center><strong>3 pipelines x 1 stage</strong></td>
5 <td align=center><strong>3 pipelines x 3 stages</strong></td>
6 </tr>
7 <tr>
8 <td align=center valign=top><img src="http://gnuradio.org/images/perf-data-images/1x3.png"></td>
9 <td align=center valign=top><img src="http://gnuradio.org/images/perf-data-images/3x1.png"></td>
10 <td align=center valign=top><img src="http://gnuradio.org/images/perf-data-images/3x3.png"></td>
11 </tr>
12 </table>
Each FIR has 256 taps. Since these are implemented with a dot-product, we count 2 floating point operations (FLOP) per tap, per sample. For each run of the benchmark, we measure the user, system and real time. In addition we know the number of samples processed by the graph and the topology, thus we can compute the total number of floating point operations. We compute GFLOPS as the total FLOPs / real time / 1e9.
The benchmark code and raw data are in
[source:gnuradio/branches/features/mp-sched/gnuradio-examples/python/mp-sched gnuradio-examples/python/mp-sched.]
You can plot the raw data and fly it around in 3D using
On the x86 machines the kernel of gr.fir_filter_fff is implemented with SSE.
http://gnuradio.org/images/perf-data-images/dual-quad-core.png
http://gnuradio.org/images/perf-data-images/dual-quad-core-2.33-clovertown.png
http://gnuradio.org/images/perf-data-images/core2-duo.png
http://gnuradio.org/images/perf-data-images/core-duo.png
Note the differences in scaling between the same machines depending on whether we're using
Altvec or not. It's especially pronounced on the PS3.
http://gnuradio.org/images/perf-data-images/js21-altivec.png
In the next two graphs running on cell processors we're not yet using the SPEs.
This is all running on the PPE.
http://gnuradio.org/images/perf-data-images/qs21-altivec.png
http://gnuradio.org/images/perf-data-images/ps3-altivec.png
Please note that the benchmark does not contain any AltiVec code. Thus these machines are
at a disadvantage to the SSE enabled benchmark code on the x86 and x86_64. Within a graph, however,
the scaling is valid.
http://gnuradio.org/images/perf-data-images/js21.png
In the next two graphs running on cell processors we're not yet using the SPEs.
This is all running on the PPE.
http://gnuradio.org/images/perf-data-images/qs21.png
http://gnuradio.org/images/perf-data-images/ps3.png
Here follows a description on how to connect two or more usrps (with a locked clock) and get synchronised samples.
In other words, how to get locked LO (Local Oscillators) and PhaseCoherent samples from multiple channels of multiple usrps (MIMO).
Unpack, build and install usrp, gnuradio-core and gr-usrp
Versions need to be more recent then 2.7cvs/svn 11 may 2006
Make sure usrp/fpga/rbf/rev2/multi*.rbf is installed in /usr/local/share/usrp/rev2/
Make sure usrp/fpga/rbf/rev4/multi*.rbf is installed in /usr/local/share/usrp/rev4/
(If in doubt, copy manually)
Build and install gr-wxgui gr-audio-xxx and so on.
unpack gnuradio-examples.
There is a gnuradio-examples/python/multi_usrp directory which contains examples and explanation.
Put at least a basic RX or dbsrx board in RXA of the master and RXA of the slave board.
Make sure that the usrps have a serial or unique identifier programmed in their eeprom.
(All new rev 4.1 boards have this)
You can do without a serial but then you never know which usrp is the master and which is the slave.
Now connect the 64MHz clocks between the boards with a short sma coax cable.
See USRPClockingNotes on how to enable clock-out and clock-in, and which daughterboards are supported.
You need one board with a clock out and one board with a clock in.
You can choose any of the two boards as master or slave, this is not dependant on which board has the clock-out or in.
In my experiments I had fewer problems when the board that has the clock-in will be the master board.
You can use a standard 16-pole flatcable to connect tvrx, basic-rx or dbsrx boards.
Of this 16pin flatcable only two pins are used (io15 and ground)
For all new daughterboards which use up a lot of io pins you have to use a cable with fewer connections.
The savest is using a 2pin headercable connected to io15,gnd (a cable like the ones used to connect frontpanel leds to the mainboard of a PC)
Connect a 16-pole flatcable from J25 on basicrx/dbs_rx in rxa of the master usrp to J25 on basicrx/dbsrx in RXA of the slave usrp Don't twist the cable (Make sure the pin1 marker (red line on the flatcable) is on the same side of the connector (at io-8 on the master and at io8 on the slave.)) For basic_rx this means the marker should be on the side of the dboard with the sma connectors. For dbs_rx this means the marker should be on the side of the dboard with the two little chips. In other words, don't twist the cable, you will burn your board if you do.
You can also connect a flatcable with multiple connectors from master-J25 to slave1-J25 to slave2-J25 to ...
You will however have to think of something to create a common 64Mhz clock for more then two usrps. (See USRPClockingNotes)
connect a 2wire cable from masterRXA J25 io15,gnd to slaveRXA J25 io15,gnd
So now the hardware is setup, software is setup. Lets do some tests.
Connect power to both usrps.
unpack the gnuradio_examples somewhere (cvs version later then 11 may 2006)
go to the gnuradio-examples/python/multi_usrp folder.
./multi_usrp_oscope.py -x 12345678
./multi_usrp_oscope.py -x actualserialnum
./multi_usrp_oscope.py --help
Now you are ready to do phase-locked aligned signal processing.
You can also capture to file with:./multi_usrp_rx_cfile.pyTo see all available options:
./multi_usrp_rx_cfile.py --help
Multi usrp
With this code you can connect two or more usrps (with a locked clock) and get synchronised samples.
You must connect a (flat)cable between a dboard on the master in RXA and a dboard on the slave in RXA.
You then put one usrp in master mode, put the other in slave mode.
The easiest thing to see how this works is just looking at the code in
multi_usrp_oscope.py
multi_usrp_rx_cfile.py
Use the usrp_multi block which is installed by gr-usrp.
instantiate in the following way:
self.multi=usrp_multi.multi_source_align( fg=self, master_serialno=options.master_serialno, decim=options.decim, nchan=options.nchan )
nchan should be 2 or 4.
You determine which is the master by master_serialno (this is a text string a hexadecimal number).
If you enter a serial number which is not found it will print the serial numbers which are available.
If you give no serial number (master_serialno=None), the code will pick a Master for you.
self.um=self.multi.get_master_usrp()
self.us=self.multi.get_slave_usrp()
aligned_master_source_c=self.multi.get_master_source_c() aligned_slave_source_c=self.multi.get_slave_source_c()
These blocks have multiple outputs.
output 0 is the sample counter (high bits in I, low bits in Q)
You normally don't need the samplecounters so you can ignore output 0
output 1 is the first aligend output channel (if you enable 2 or 4 channels)
output 2 is the second output channel (only if you enable 4 channels)
self.aligned_master_chan1=(self.multi.get_master_source_c(),1) self.aligned_master_chan2=(self.multi.get_master_source_c(),2) self.aligned_slave_chan1=(self.multi.get_slave_source_c(),1) self.aligned_slave_chan2=(self.multi.get_slave_source_c(),2)
self.aligned_master_samplecounter=(self.multi.get_master_source_c(),0) self.aligned_slave_samplecounter=(self.multi.get_slave_source_c(),0)You can set the gain or tune the frequency for all 4 receive daughetrboards at once:
self.multi.set_gain_all_rx(options.gain)
result,r1,r2,r3,r4 = self.multi.tune_all_rx(options.freq)
You must call self.multi.sync() at least once AFTER the flowgraph has started running.
(This will synchronise the streams of the two usrps)
This work was funded by Toby Oliver at Sensus Analytics / Path Intelligence.
Many Thanks for making this possible.
It was written by Martin Dudok van Heel of Olifantasia.com.
email: nldudok1_olifantasia_com
.
These instructions should work for most systems using pkgsrc (such as DragonflyBSD).
The most recent release of GNU Radio is usually available in pkgsrc, currently meta-pkgs/gnuradio. An easy way to get most of the dependencies installed in order to build from SVN is to build the GNU Radio meta-pkg. It can then be deleted, or left in place.
As of 2006-10, the GNU Radio sources build with BSD make as well as GNU make. In case of mysterious failures, try GNU make and report the bug.
To use dependencies provided by pkgsrc, one must pass CPPFLAGS and LDFLAGS to configure. Programs not built by pkgsrc should not be placed in /usr/pkg, so use a different prefix.
./bootstrap.sh
LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" CPPFLAGS="-I/usr/pkg/include" ./configure --prefix=/usr/gnuradio
make
sudo make install
To run "make distcheck", one must pass LDFLAGS and CPPFLAGS as above because distcheck runs configure after creating a tarball and unpacking it.
To run "make check", one must have large amounts of space free in /tmp (over 128 MB?) One can do "TMP=/usr/tmp make check" after creating another tmp dir to work around this problem.
Support for improved USB speed was committed to NetBSD-current in July, 2006. This code is also in the netbsd-4 branch. Code to use the new USB driver enhancements was committed to GNU Radio svn in September, 2006 prior to the creation of the 3.0 release branch.
Documentation of speed tests of the USB code are at
the ACERT ADROIT GNU Radio project CVS repository. See also the main project page.
Please try this new build and report on the mailing list any successes or failures. If you wish to build it yourself, you'll need to get it out of the new_eth branch of this git repository:
http://gnuradio.org/git/matt.git/To create a local tracking branch do:
git branch --track new_eth origin/new_eth git checkout new_ethFor those who can't do that, builds are attached to this page. You'll need both the FPGA image and the new firmware. If building yourself, make sure to do a make clean in both the fpga/top/u2_rev3 and firmware directories.
.
Installing Numpy¶
On most systems, numpy is available as a pre-built package, but if needed it can be installed from source by
downloading numpy-1.1.0.tar.gz from http://sourceforge.net/project/showfiles.php?group_id=1369 to /usr/src then:
cd /usr/src tar zxf numpy-1.1.0.tar.gz cd numpy-1.1.0 python setup.py installIf you get errors that say
Error: suffix or operands invalid for @fnstsw'
it is because you are using Cygwin binutils 20080523-1. You will need to either reinstall binutils 20060817-1 or make corrections to the Numpy source; see hints tips known problems and solutions for Windows.On MinGW, download and run numpy-1.0.3.1.win32-py2.4.exe (or the python 2.5 version,
if that is what you need). Or you can be the first to try a newer version.
Octave is the most popular analysis tool with GNU Radio, as the GNU Radio package includes its own set of scripts for reading and parsing output.
sudo apt-get install octaveTo use the GNU Radio octave scripts, you must add the path to your Octave path variable. This is easily done using your local ~/.octaverc configuration file. If you check out the GNU Radio trunk to /home/username/gnuradio/, you can add the following to ~/.octaverc:
addpath("/home/username/gnuradio/gnuradio-core/src/utils/")
To parse data output from GNU Radio, the easiest thing to do is use the provided scripts. Ensure that you have added the GNU Radio script path to your octave path, as described in the installing guide. These help you read data that you may have dumped to disk using gr.file_sink(size, filename).
You want to use one of the following methods, based on the size parameter used in gr.file_sink(). Each method takes a filename as the first parameter, and an optional second parameter which is the number of items to read from the file:
c=read_complex_binary('capture.dat');
Data captured directly from the USRP is stored as 32-bit complex, rather than 64-bit complex (gr.sizeof_gr_complex). To read this data, first use read_short_binary() and then split it into a two dimensional vector:d=read_short_binary(data); c=split_vect(d,2);
sudo apt-get install gnuplotTo plot I and Q separately over time, graph each component separately:
plot([real(c), imag(c)])Generating an I/Q plot (x-axis I, y-axis Q) can be done using:
plot(c)

OpenBTS® is an open-source Unix application that uses the Universal Software Radio Peripheral (USRP) to present a GSM air interface to standard GSM handset and uses the Asterisk software PBX to connect calls. The combination of the ubiquitous GSM air interface with VoIP backhaul could form the basis of a new type of cellular network that could be deployed and operated at substantially lower cost than existing technologies in greenfields in the developing world.
In plain language, we are working on a new kind of cellular network that can be installed and operated at about 1/10 the cost of current technologies, but that will still be compatible with most of the handsets that are already in the market. This technology can also be used in private network applications (wireless PBX, rapid deployment, etc.) at much lower cost and complexity than conventional GSM.
The pages are organized here by topic area. If you have something useful to add, please do so. To edit the wiki, you can register an account or use "guest" as a user name, and "gnuradio" as the password.
Grab the project source code via git:
We still waiting for our GNU git repository. Until then, we are hosting out of sf.net. -- August 2010.
git://openbts.git.sourceforge.net/gitroot/openbts/openbts
If you wait write access to the sf.net git repository, please contact dburgess (at) kestrelsp.com for information.
OpenBTS replies on an external SIP PBX for its call switching functions.
We use the Burning Man festival as an opportunity to run test networks.
Asterisk dialplan designed for use with OpenBTS
; This dialplan is specially designed for use with OpenBTS.
; It can also be used as an Asterisk based solution without using mobile phones.
; It provides full hotdesking for all phones registered and configured with sip entry in
; /etc/asterisk/sip.conf
;
; SIP entries in /etc/asterisk/sip.conf
; SIP entries in sip.conf has to look like this:
;
; [IMSI204123170034543]
; callerid=IMSI204123170034543 <IMSI204123170034543>
; canreinvite=no
; type=friend
; allow=gsm
; context=sip-internal
; host=dynamic
;
; Be aware of the fact that with SIP entries as above smqueue will not work properly.
;
; Automatic configuration of discovered IMSI numbers should be easy
; Because no dialplan info has to be added, automatic configuration of a SIP entry after
; discovering should not be that hard. The use of a file for every SIP entry included
; in SIP.conf is the way to go for this.
;
;*Simple, safe and flexible dialplan*
; This dialplan provides flexibility and seperates the SIP registration based on IMSI
; number and the actual phone numbers used to call.
;
; The basic idea behind this dial plan is to keep it as simple, safe and flexible
; as possible. It can be used as a ready to go solution but it might be
; a good idea to make some adjustments based on particular needs.
;
;*Number range 1001 - 1012 preconfigured*
; The number 1001 to 1012 are preconfigured. Expanding the number range is
; just a matter of copy and past of all the 1001 to 1012 parts in the dialplan and make some
; adjustments on the numbers. The dialplan should suite every OpenBTS deployment.
;
;*Logging in*
; When a mobile phone is registered to OpenBTS and Asterisk it needs
; to be logged in for a phone number. This is done by dialing 0<phone number>.
; Dialing 01001 makes the phone reachable at number 1001 and set the callerid
; to 1001. By default the pincode is 1234 but this can easily be changed.
; One phone can log in an unlimited number of phonenumbers. The limitation is
; the the range of numbers available within the dialplan.
;
;*Logging off*
; Dial 1<phonenumber> to log out of a phone umber. The result of dialing 11001 is that
; the phone is no longer reachable at number 1001
;
;*Automatic log off*
; A phone number will be logged off if a call is made to that number and the status is
; UNAVAILABLE.
;
;*Logging in is needed to make useful calls*
; A phone registered to the OpenBTS and Asterisk but not logged to a phonenumber
; can't make any usefull phonecalls. Any dialed number is routed to an Asterisk
; music on hold extensions or the monkeys screaming. This can be changed to personal
; needs like a voiceprompt that let the caller know that a login to a number is needed.
; This provides security to this solution. You need to have the proper credentials to make
; phonecalls.
;
;*Using a trunk*
; The dialplan is ready for use with a trunk so outbound calls can be made if the connection
; is actually there. In the dialplan all numbers of 10 positions are routed to the trunk.
; In the Netherlands this enables making national phonecalls. A phone needs to be logged into
; a phone number before an outbound call can be made. The numbermatching ca be changed to your needs.
; OPENBTS_TRUNK is the global variable to store the trunk.
;
;*Special numbers*
; Some special numbers, handy when testing, have been added to the dialplan:
; 01234 -> releases all logged in numbers. be aware that if you call this number and enter
; the password (default 1234) all phones are without an actual number.
; 02345 -> shows all phonenumbers and, if available, the IMSI number related to the phonenumber
; in the Asterisk Cli.
; 03456 -> shows the device state of the SIP registered IMSI numbers in the Asterisk Cli.
; This doesn't work at the moment while it should :-(
; 02000 -> a music on hold extension.
;
; Absolute timeout
; Set(Timeout(absolute)=XX) is used now and then so calls without the proper credentials
; end within a certain time. XX is the number of seconds before the connection will be ended.
;
; 4 different scenarios for a call
; Different things can happen when dialing a number, depending on the status of the phone used and the
; status of the number called. Info about the actual status can be viewed from the Asterisk Cli with verbose
; set to 5 (set verbose 5)
;
; scenario 1
; The phone used to dial a number hasn't been logged in. It is not possible
; to make any call without first logging in with a proper combination of number and password/pincode
;
; scenario 2
; The phone has been logged in properly but the number dialed isn't logged in
;
; scenario 3
; The phone has been logged in properly, the number dialed is logged in but the phone is switch off
; or out of range. When this happens the dialed number is logged off. Because OpenBTS does return a SIP code
; that Asterisk doesn't translate in a CHANUNAVAIL but in a NOANSWER dialstatus the handling of this status doesn't
; work properly. This isn't a real problem because the phone isn'r reachable anyway. The result is that the login
; stays in place despite the fact that the phone is turned off or out of reach.
;
; scenario 4
; The phone has been logged in properly and the number dialed has been logged in properly. the dialed phone will
; ring and probably be picked up ;-)
;
; When a trunk is configured the phone used to dial an outbound number has to be properly logged into
; The global variable OPENBTS_TRUNK is used to store the actual trunk.
;
;*How to install this dialplan?*
; Just do a select all of this wiki text and do a paste in an empty file. Save this file as /etc/asterisk/extensions.conf
; add some sip entries like the example at the beginning of this text to /etc/asteisk/sip.conf and do a reload.
; Now you are ready to go ;-)
;
; Hope it is useful and you will have lots of fun!
;
;
;Erik
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; auteur : Erik de Wild
; company : Tripple-o : Your Asterisk migration partner
; e-mail : info at tripple-o.nl
; phone : 0031621830837
;
; Rights : Tripple-o owns the rights to this dialplan
; Country : the Netherlands
; Time Zone : GMT +1
;
; version : 1.0
; date : 24 december 2009
; License : This dialplan is GPL3 licensed with the condition that
; this header (from top to [global]) is kept in place, credits are addressed and you don't charge
; money for the dialplan as it is. Under this conditions you are allowed to use, change and
; redistribute it.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[globals]
OPENBTS_TRUNK => SIP/31208123456
; variables for the IMSI numbers
;;;;;;;;;;;;;;;
; Here you can couple a phone to a number used in a sip entry in sip.conf. Used with
; OpenBTS this is the IMSI.
;
; Be aware of the fact that a reload will also reset the values of the NR<NUMBER> variables.
; during testing and trying this might be usefull, but in production this will lead to
; a lot of confusing because of lost logins.
;
; Number 1001 is used to show how a static link between a phone number and the callerid defined in a sip entry can be established.
; This is just an example for further adjustments to your personal needs
;;;;;;;;;;;;;;;
;;;;;;;;;;;;
; Number 1001 is an example of how to change a hotdesk phonenumber into a static phonenumber.
; This can be done with every phonenumber available. Be sure to make all the adjustments
; needed. Logging in, logging off, automatic logging of if dialstatus is CHANUNAVAIL, logging
; off of all the numbers by calling 01234 and enter pincode.
;;;;;;;;;;;;
NR1001 => STATIC0000001 ; This will, in combination with some other adjustments, change 1001 in a static number
;NR1002 =>
;NR1003 =>
;NR1004 =>
;NR1005 =>
;NR1006 =>
;NR1007 =>
;NR1008 =>
;NR1009 =>
;NR1010 =>
;NR1011 =>
;NR1012 =>
[default]
[trunk]
exten => s,1,GotoIf($CALLERID}" class="wiki-page new">${NR1001}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1002}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1003}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1004}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1005}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1006}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1007}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1008}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1009}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1010}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1011}" = "${CALLERID}?CONTINUE)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1012}" = "${CALLERID}?CONTINUE)
exten => s,n,Answer()
exten => s,n,NoOp(The phone used to make an outbound call has not been logged into with proper credentials so no calls can be made.)
exten => s,n,Set(TIMEOUT=15) ; this is to assure that the line is released after 15 seconds
exten => s,n,MusicOnHold()
; MOH has to be replaced by some usefull voiceprompt like "sorry, you are not allowed to make
; outbound calls until you log in"
exten => s,n,NoOp(The trunk used for this outboundcall is ${OPENBTS_TRUNK})
exten => s,n(CONTINUE),Dial(${OPENBTS_TRUNK}/${CALLED_NUMBER},40,rt)
exten => s,n,Hangup()
exten => _31208080651,1,Dial(SIP/IMSI204203000434438,40,t)
exten => _31208080651,n,Hangup()
[sip-internal]
exten => _XXXX,1,Set(CALLED_NUMBER=${EXTEN})
exten => _XXXX,n,Goto(dialplan,start,1)
exten => _0XXXXXXXXX,1,Set(CALLED_NUMBER=${EXTEN})
exten => _0XXXXXXXXX,n,Goto(trunk,s,1)
exten => _0XXXX,1,Set(CALLED_NUMBER=${EXTEN})
exten => _0XXXX,n,Goto(dialplan,${EXTEN},1)
exten => _1XXXX,1,Set(CALLED_NUMBER=${EXTEN})
exten => _1XXXX,n,Goto(dialplan,${EXTEN},1)
[dialplan]
include => trunk
exten => start,1,GotoIf($CALLERID}" class="wiki-page new">${NR1001}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1002}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1003}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1004}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1005}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1006}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1007}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1008}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1009}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1010}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1011}" = "${CALLERID}?CONTINUE)
exten => start,n,GotoIf($CALLERID}" class="wiki-page new">${NR1012}" = "${CALLERID}?CONTINUE)
exten => start,n,NoOp(Phone used to make a phonecall is not logged in yet)
exten => start,n,Answer()
exten => start,n,Set(TIMEOUT=15) ; this is to assure that the line is released
; after 15 seconds
exten => start,n,MusicOnHold() ; has to be changed in a voiceprompt inviting to
; login to one of the numbers
exten => start,n(CONTINUE),Goto(00${CALLED_NUMBER},1)
exten => 001001,1,Macro(dialGSM,${NR1001},${CALLED_NUMBER})
exten => 001002,1,Macro(dialGSM,${NR1002},${CALLED_NUMBER})
exten => 001003,1,Macro(dialGSM,${NR1003},${CALLED_NUMBER})
exten => 001004,1,Macro(dialGSM,${NR1004},${CALLED_NUMBER})
exten => 001005,1,Macro(dialGSM,${NR1005},${CALLED_NUMBER})
exten => 001006,1,Macro(dialGSM,${NR1006},${CALLED_NUMBER})
exten => 001007,1,Macro(dialGSM,${NR1007},${CALLED_NUMBER})
exten => 001008,1,Macro(dialGSM,${NR1008},${CALLED_NUMBER})
exten => 001009,1,Macro(dialGSM,${NR1009},${CALLED_NUMBER})
exten => 001010,1,Macro(dialGSM,${NR1010},${CALLED_NUMBER})
exten => 001011,1,Macro(dialGSM,${NR1011},${CALLED_NUMBER})
exten => 001012,1,Macro(dialGSM,${NR1012},${CALLED_NUMBER})
exten => _00XXXX,1,NoOp(A non existing number has been dialed)
exten => _00XXXX,n,PlayBack(silence/3)
exten => _00XXXX,n,PlayBack(tt-monkeys)
exten => _00XXXX,n,Hangup()
exten => 02000,1,Answer
exten => 02000,n,MusicOnHold()
exten => 02000,n,Hangup()
;;;;;;;;;;;;
; clearing the values of all variables so you can start all over again
;;;;;;;;;;;;
exten => 01234,1,Answer()
exten => 01234,n,Background(silence/3)
exten => 01234,n,Authenticate(1234)
; exten => 01234,n,Set(GLOBAL=) ; should stay untouched because 1001 is a static number
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Set(GLOBAL=)
exten => 01234,n,Hangup()
;;;;;;;;;;;;;;
; this routine shows the values of the NR<XXXX> variables on screen of the Asterisk CLI when verbose is above 5
;;;;;;;;;;;;;
exten => 02345,1,Answer()
exten => 02345,n,NoOp(The value of NR1001 is: ${NR1001})
exten => 02345,n,NoOp(The value of NR1002 is: ${NR1002})
exten => 02345,n,NoOp(The value of NR1003 is: ${NR1003})
exten => 02345,n,NoOp(The value of NR1004 is: ${NR1004})
exten => 02345,n,NoOp(The value of NR1005 is: ${NR1005})
exten => 02345,n,NoOp(The value of NR1006 is: ${NR1006})
exten => 02345,n,NoOp(The value of NR1007 is: ${NR1007})
exten => 02345,n,NoOp(The value of NR1008 is: ${NR1008})
exten => 02345,n,NoOp(The value of NR1009 is: ${NR1009})
exten => 02345,n,NoOp(The value of NR1010 is: ${NR1010})
exten => 02345,n,NoOp(The value of NR1011 is: ${NR1011})
exten => 02345,n,NoOp(The value of NR1012 is: ${NR1012})
exten => 02345,n,Hangup()
exten => 03456,1,Answer()
exten => 03456,n,NoOP(The status of ZOIPER is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1001} attached to 1001 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1002} attached to 1002 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1003} attached to 1003 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1004} attached to 1004 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1005} attached to 1005 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1006} attached to 1006 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1007} attached to 1007 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1008} attached to 1008 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1009} attached to 1009 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1010} attached to 1010 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1011} attached to 1011 is ${DEVSTATE})
exten => 03456,n,NoOP(The status of ${NR1012} attached to 1012 is ${DEVSTATE})
;;;;;;;;;;;;;;;;
; this actually links phonenumber to an IMSI number
;;;;;;;;;;;;;;;;
; commented because no log in to number 1001 is needed
;;;;;;;;;;;;;;;;
;exten => 01001,1,Answer()
;exten => 01001,n,Background(silence/3)
;exten => 01001,n,Authenticate(1234)
;exten => 01001,n,Set(GLOBAL=${CALLERID})
;exten => 01001,n,Hangup()
exten => 01002,1,Answer()
exten => 01002,n,Background(silence/3)
exten => 01002,n,Authenticate(1234)
exten => 01002,n,Set(GLOBAL=${CALLERID})
exten => 01002,n,Hangup()
exten => 01003,1,Answer()
exten => 01003,n,Background(silence/3)
exten => 01003,n,Authenticate(1234)
exten => 01003,n,Set(GLOBAL=${CALLERID})
exten => 01003,n,Hangup()
exten => 01004,1,Answer()
exten => 01004,n,Background(silence/3)
exten => 01004,n,Authenticate(1234)
exten => 01004,n,Set(GLOBAL=${CALLERID})
exten => 01004,n,Hangup()
exten => 01005,1,Answer()
exten => 01005,n,Background(silence/3)
exten => 01005,n,Authenticate(1234)
exten => 01005,n,Set(GLOBAL=${CALLERID})
exten => 01005,n,Hangup()
exten => 01006,1,Answer()
exten => 01006,n,Background(silence/3)
exten => 01006,n,Authenticate(1234)
exten => 01006,n,Set(GLOBAL=${CALLERID})
exten => 01006,n,Hangup()
exten => 01007,1,Answer()
exten => 01007,n,Background(silence/3)
exten => 01007,n,Authenticate(1234)
exten => 01007,n,Set(GLOBAL=${CALLERID})
exten => 01007,n,Hangup()
exten => 01008,1,Answer()
exten => 01008,n,Background(silence/3)
exten => 01008,n,Authenticate(1234)
exten => 01008,n,Set(GLOBAL=${CALLERID})
exten => 01008,n,Hangup()
exten => 01009,1,Answer()
exten => 01009,n,Background(silence/3)
exten => 01009,n,Authenticate(1234)
exten => 01009,n,Set(GLOBAL=${CALLERID})
exten => 01009,n,Hangup()
exten => 01010,1,Answer()
exten => 01010,n,Background(silence/3)
exten => 01010,n,Authenticate(1234)
exten => 01010,n,Set(GLOBAL=${CALLERID})
exten => 01010,n,Hangup()
exten => 01011,1,Answer()
exten => 01011,n,Background(silence/3)
exten => 01011,n,Authenticate(1234)
exten => 01011,n,Set(GLOBAL=${CALLERID})
exten => 01011,n,Hangup()
exten => 01012,1,Answer()
exten => 01012,n,Background(silence/3)
exten => 01012,n,Authenticate(1234)
exten => 01012,n,Set(GLOBAL=${CALLERID})
exten => 01012,n,Hangup()
;;;;;;;;;;;;;;;;;;;;;
; this removes the link between a phone number and an IMSI number
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;
; commented out because loging off is not needed with a static number
;;;;;;;;;;;;;;;
;exten => 11001,1,Answer()
;exten => 11001,n,Set(GLOBAL=)
;exten => 11001,n,Goto(beep,1)
exten => 11002,1,Answer()
exten => 11002,n,Set(GLOBAL=)
exten => 11002,n,Goto(beep,1)
exten => 11003,1,Answer()
exten => 11003,n,Set(GLOBAL=)
exten => 11003,n,Goto(beep,1)
exten => 11004,1,Answer()
exten => 11004,n,Set(GLOBAL=)
exten => 11004,n,Goto(beep,1)
exten => 11005,1,Answer()
exten => 11005,n,Set(GLOBAL=)
exten => 11005,n,Goto(beep,1)
exten => 11006,1,Answer()
exten => 11006,n,Set(GLOBAL=)
exten => 11006,n,Goto(beep,1)
exten => 11007,1,Answer()
exten => 11007,n,Set(GLOBAL=)
exten => 11007,n,Goto(beep,1)
exten => 11008,1,Answer()
exten => 11008,n,Set(GLOBAL=)
exten => 11008,n,Goto(beep,1)
exten => 11009,1,Answer()
exten => 11009,n,Set(GLOBAL=)
exten => 11009,n,Goto(beep,1)
exten => 11010,1,Answer()
exten => 11010,n,Set(GLOBAL=)
exten => 11010,n,Goto(beep,1)
exten => 11011,1,Answer()
exten => 11011,n,Set(GLOBAL=)
exten => 11011,n,Goto(beep,1)
exten => 11012,1,Answer()
exten => 11012,n,Set(GLOBAL=)
exten => 11012,n,Goto(beep,1)
;;;;;;;;;;;
; just some useless noice
;;;;;;;;;;;
exten => beep,1,Background(silence/2)
exten => beep,n,PlayBack(beep)
exten => beep,n,PlayBack(beep)
exten => beep,n,PlayBack(beep)
exten => beep,n,PlayBack(beep)
exten => beep,n,PlayBack(beep)
exten => beep,n,Hangup()
[macro-dialGSM]
;;;;;;;;;;;;;
; check all NR<number> variables to determine what phone number is used to call,
; so there is proper value for ${CALLERID}
;;;;;;;;;;;;;
exten => s,1,GotoIf($CALLERID}" class="wiki-page new">${NR1001}" = "${CALLERID}?NR1001)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1002}" = "${CALLERID}?NR1002)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1003}" = "${CALLERID}?NR1003)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1004}" = "${CALLERID}?NR1004)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1005}" = "${CALLERID}?NR1005)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1006}" = "${CALLERID}?NR1006)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1007}" = "${CALLERID}?NR1007)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1008}" = "${CALLERID}?NR1008)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1009}" = "${CALLERID}?NR1009)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1010}" = "${CALLERID}?NR1010)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1011}" = "${CALLERID}?NR1011)
exten => s,n,GotoIf($CALLERID}" class="wiki-page new">${NR1012}" = "${CALLERID}?NR1012:NOT_LOGGED_IN)
;;;;;;;;;;;;;;;;
; you have to add call-limit=1 to the sip entries for the gsm phones
; to make DEVSTATE (asterisk 1.4) or DEVICE_STATE (asterisk 1.6) work
; The result is that when a phone is busy the dialstatus
; returned by Asterisk is CHANUNAVAIL instead of BUSY. This is the reason why
; (for now) the automatic log off in case of dialstatus is disabled
; edw 29 december 2009
;;;;;;;;;;;;;;;;
exten => s,n(NR1001),Set(CALLERID=1001)
exten => s,n,Set(CALLERID=1001)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1002),Set(CALLERID=1002)
exten => s,n,Set(CALLERID=1002)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1003),Set(CALLERID=1003)
exten => s,n,Set(CALLERID=1003)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1004),Set(CALLERID=1004)
exten => s,n,Set(CALLERID=1004)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1005),Set(CALLERID=1005)
exten => s,n,Set(CALLERID=1005)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1006),Set(CALLERID=1006)
exten => s,n,Set(CALLERID=1006)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1007),Set(CALLERID=1007)
exten => s,n,Set(CALLERID=1007)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1008),Set(CALLERID=1008)
exten => s,n,Set(CALLERID=1008)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1009),Set(CALLERID=1009)
exten => s,n,Set(CALLERID=1009)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1010),Set(CALLERID=1010)
exten => s,n,Set(CALLERID=1010)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1011),Set(CALLERID=1011)
exten => s,n,Set(CALLERID=1011)
exten => s,n,Goto(CONTINUE)
exten => s,n(NR1012),Set(CALLERID=1012)
exten => s,n,Set(CALLERID=1012)
exten => s,n,Goto(CONTINUE)
exten => s,n,(NOT_LOGGED_IN),NoOp(The phone that is used to make a call is not logged into with proper credentials)
exten => s,n,Set(TIMEOUT=15)
exten => s,n,PlayBack(silence/2)
exten => s,n,MusicOnHold()
exten => s,n,Hangup()
exten => s,n(CONTINUE),Set(STOP=0) ; just a variable to hold the value zero
exten => s,n,NoOp(${LEN}) ; handy as cli output
exten => s,n,GotoIf($LEN}"_=_"${STOP}" class="wiki-page new">${LEN}" = "${STOP}?STOPCALL) ; If no IMSI code is stored into NR<NUMBER> variable
; and for that reason the variable is empty stop, otherwise
; dial the number.
exten => s,n,NoOp(the call is actually set up and all checks are passed)
exten => s,n,Set(TIMEOUT=300) ; set length of call to the max of 5 minutes 300 seconds
exten => s,n,Dial(SIP/${ARG1},20,rt)
exten => s,n,Goto(s-${DIALSTATUS},1)
exten => s,n(STOPCALL),NoOp(The number dialed is not logged in and for that reason not reachable)
exten => s,n,playback(silence/2)
exten => s,n,Set(TIMEOUT=15)
exten => s,n,Answer()
exten => s,n,MusicOnHold()
exten => s,n,Hangup()
exten => s-CANCEL,1,Hangup()
exten => s-NOANSWER,1,Hangup()
exten => s-BUSY,1,Busy(30)
;;;;;;
; add the handling as you would like it
;;;;;;
exten => s-BUSY,n,Hangup()
exten => s-CONGESTION,1,Congestion(10)
exten => s-CONGESTION,n,NoOp(call routed to congestion extension)
exten => s-CONGESTION,n,Goto(s-CHANUNAVAIL,1)
exten => s-CONGESTION,n,Hangup()
exten => s-CHANUNAVAIL,1,NoOp(The phone number called is logged in but the phone is turned off or out of range)
exten => s-CHANUNAVAIL,n,playback(silence/2)
exten => s-CHANUNAVAIL,n,playback(ss-noservice)
exten => s-CHANUNAVAIL,n,Goto(s-${ARG2},1)
;;;;;;
; if phonenumber is not available the value of NR<XXXX> variable will be erased
; so the relation between a phonenumber and an IMSI number ends
; This is disabled because of the returned dialstatus (CHANUNAVAIL) when call-limit+1 is reached
; The return value should be BUSY
;;;;;;
; comented out because 1001 is static number
;;;;;;
;exten => s-1001,1,NoOp(SET=)
;exten => s-1001,n,Hangup()
exten => s-1002,1,NoOp(SET=))
exten => s-1002,n,Hangup()
exten => s-1003,1,NoOp(SET=))
exten => s-1003,n,Hangup()
exten => s-1004,1,NoOp(SET=))
exten => s-1004,n,Hangup()
exten => s-1005,1,NoOp(SET=))
exten => s-1005,n,Hangup()
exten => s-1006,1,NoOp(SET=))
exten => s-1006,n,Hangup()
exten => s-1007,1,NoOp(SET=))
exten => s-1007,n,Hangup()
exten => s-1008,1,NoOp(SET=))
exten => s-1008,n,Hangup()
exten => s-1009,1,NoOp(SET=))
exten => s-1009,n,Hangup()
exten => s-1010,1,NoOp(SET=))
exten => s-1010,n,Hangup()
exten => s-1011,1,NoOp(SET=))
exten => s-1011,n,Hangup()
exten => s-1012,1,NoOp(SET=))
exten => s-1012,n,Hangup()
The OpenBTS Project is an effort to construct an open-source Unix application that uses the Universal Software Radio Peripheral (USRP) to present a GSM air interface ("Um") to standard GSM handsets and uses the Asterisk software PBX to connect calls. This is in fact very different from a conventional GSM BTS, which is a dumb device that is managed externally by a basestation controller (BSC) and connects calls in a remote "mobile switching center" (MSC). Because of this important architectural difference, the end product of this project is better referred to as an access point, even though the project is called "OpenBTS".

Overall Architecture of the OpenBTS Access Point
GSM is a good choice precisely because it is old and boring. Everyone knows it works and 80% of the world's carriers are still using it. It's a proven technology that is well-suited to the target application and the specification is publicly available.
CDMA physical layers are too complex for an inexpensive all-software radio and do not scale well for low-capacity cells. CMDA capacity comes in increments of 50 or more subscriber lines and the lowest layers of your radio must process all of that bandwidth whether you intend to use it or not. By contrast, GSM capacity comes in increments of 7-8 lines and a well-managed radio can even ignore inactive parts of the signal. Beyond the technical issues, IS-95-style CMDA (including cdma2000) is tightly controlled intellectual property. You can't even get a copy of the specification without signing an NDA and paying several hundred dollars, so open-source CDMA is out of the question.
Future versions of the OpenBTS may well support GPRS and EDGE. GPRS, when available, should be a software-only upgrade for any installed OpenBTS system. EDGE support may require additional computational resources but the additional software is not complex, at least when compared to the rest of the BTS. UMTS, however, is a radically different CDMA-style physical layer and well outside the current scope of this project.
All that said, let's walk before we run by implementing basic voice services on a single-ARFCN GMSK BTS.
There are a lot of people out there who would rather not blanket Africa with WiWhatever than find a way to make GSM dirt cheap. We say "not" because none of those people who talk about it are really going to do it because it's not a realistic goal. It's sexier to talk about the newest air interface and that talk gets a lot a buzz, but the truth is that that WiWhatever is poorly suited to mobile telephony.
WiFi range is far too short for mobile coverage in rural areas. For example, you're not going to cover 700 square miles with a single WiFi tower, but that's exactly what GSM was made to do. If access points are connected through different ISPs, handovers will be unreliable. The phones are expensive and power-hungry, and compared to GSM they always will be. WiFi may become a decent technology for semi-mobile telephones in dense urban areas, but it's not a mobile phone standard and it's not well-matched to the rural cellular application.
WiMax has most of the problems of WiFi. To make matters worse, most WiMax bands don't penetrate structures very well. Most WiMax deployers are planning to solve this problem by saturating large buildings with small access points. That's fine in Manhattan and London, but we don't see anyone putting femtocells in a million houses when those households couldn't afford phones in the first place.
More important than all of that is to remember the goal of the OpenBTS: universal telephone service. Our project philosophy is that it is much better to give people basic telephone service with an upgrade path to 250 kb/sec packet service than to generate a lot of hype over a scorching fast broadband technology that can probably never be truly universal.
WiWhatevers do have a place in OpenBTS, though: backhaul. The standard OpenBTS backhaul is likely to be redundant-path point-to-point WiFi or WiMax.
We certainly hope so.
OpenBTS is now part of the GNU Radio project and administered by the Free Software Foundation.
The original founders of this project are David A. Burgess (dburgess00 (at) gnuradio.org) and Harvind S. Samra (hssarmra (at) gnuradio.org). They are still major contributors, but assigned their copyrights to FSF on 24 October 2008. For a number of practical reasons, Harvind and David also conduct a lot of their OpenBTS activities through a California S-Corporation called Kestrel Signal Processing, Inc.
Start from the project's main GNU Radio wiki page, OpenBTS. Read it all, get a copy and try to use it.
After that, it depends on what you want to do.
USRP -> 3318PA -> DB4090 -> 20' LMR-400 -> lightning arrestor -> 20' RG-8X -> 9 dBi antenna
One problem to note is that the USRP puts out spurs and noise in the rx band, about 80 dB down from the tx signal, but still high enough to be a problem without good duplexing isolation.
With cable losses the EIRP of the antenna was about 39dBm.
9 dBi antenna -> 20' RG-8X -> lightning arrestor -> 20' LMR-400 -> DB4090 -> preamps -> rx filter -> USRP
The Rx chain of the USRP was set to maximum gain, so the RF amp was set to the max of 70dB, and the programmable gain amp in front of the A/D was set to 20dB. According to the USRP RFX900 specs, the low-pass filter has a notch about 50-55 MHz from the center freq. So we twiddled with the RFX900 receive LO, so that our transmit frequency fell into this notch, giving us more transmit isolation. That feature would not work, however, in a multi-ARFCN system.
http://openbts.sourceforge.net/FieldTest/layout.jpg
We have legal clearance for operation in 870-880 MHz downlink, 825-835 MHz uplink.
We start by planning the uplink (receive) path. Here are the core facts:

antenna -> long cable -> duplexer -> LNA1 -> BPF -> USRP
Comments on components:
LNA1 is outside the USRP to help overcome any noise or crosstalk inside the USRP case. We need a phone at the edge of the service radius to produce -112 dBm at that LNA1 input. The path from the handset to the LNA1 is
30 dBm -P +10 -2 -1 -1 = 36 dBm -P = -112 dBm
where P is the path loss. Rearrange for
P = 112 + 36 = 148 dB.
So we can tolerate a path loss of 148 dB and we are working from a 15 m tower at 830 MHz. According to the Hata model, that corresponds to a range of 5.0 km (3.1 mi) for suburban service and 15.8 km (9.8 mi) for open rural service. Black Rock City is about 3.8 km wide and the distance from center camp to the highway is 8-10 km, so this system will meet the goals of providing solid coverage over BRC and much of the "deep Playa" and providing service over the last few miles of highway approaching the turn to the front gate.
How much LNA gain do we need? The D/A on the USRP has a range of 2 v p-p (10 dBm on 50 Ohms) and the bottom 5% of that range (-16 dBm on 50 Ohms) is occupied by noise at maximum gain. So to match our thermal noise of -120 dBm to the USRP's noise floor of -16 dBm, we need a total gain of 104 dB. The USRP already has an internal gain of up to 81 dB, so we need 23 dB of gain from LNA1. LNA1 also allows us to tolerate insertion loss in the BPF without a loss of receiver performance.
USRP -> PA -> duplexer -> long cable -> antenna
Our ERP is limited to 20 W (43 dBm) by our license. Since the handset is transmitting 1 W, downlink range isn't going to be an issue. The point of the transmit path analysis is to determine the specifications for PA. The path gain from the PA to the antenna is:
T -1 -2 +10 = T +7 = 43 dBm
where T is the transmit power, so T is 36 dBm maximum, or 4 Watts. In a 2-ARFCN system, that will be 2 W/ARFCN, or 10 W EIRP/ARFCN, which is plenty of downlink power for this system.
The output of the USRP is about 20 dBm, so we need a gain of about 16 dBm in the PA.
In summary, our ideal PA is 36 dBm output, 16 dB gain. We can use PAs with slightly higher power or higher gain by scaling back the USRP output or using an attenuator.
These aspects of the design determine the required degree of rx/tx isolation:
So we need a total of 156 dB of transmitted signal suppression from the duplexer and BPF together. We need at least 60 dB of that to come from the duplexer.
We are planning to use the Mini-Circuits ZRL-1150LN. It is readily available and is very reasonably priced, given its specifications:
Because we are operating under an experimental license in GMS850, we can use modified or de-rated 33 cm amateur equipment, which will save a considerable amount of money. The Downeast Microwave 3340PA is a good candidate:
The 3340PA will require a 15 VCD Zener diode on its power supply terminals to protect from over-voltage damage. We will need a 10-15 dB attenuator to match the output level of the RFX900 to the expected input level of the PA.
The candidate duplexer is the Anatech Microwave AD836-881D200:
The candidate BPF is the Aantech Microwave AB832B477:
With the 70 dB duplexer, this BPF will give a total tx-rx isolation of 165 dB, beating our requirement by 9 dB.
The candidate antenna is the Hyperlink HG913P-120:
The additional 3 dB of antenna gain may add 40% to the coverage range.
Each unit pulled 60 W:
Part of the problem is that we used an oversized class A PA with very low efficiency. That PA power load should probably be cut in half.
OpenBTS is written to compile in a typical GNU build environment run on POSIX operating systems. (MS Windows does not meet either of those requirements. This is not a Windows application.) The current supported systems are Linux and Apple OS X, although ports to other Unix-like systems should not be difficult. If you get stuck, take a look at the OpenBTSsupport page for possible source of help.
OpenBTS requires three (or four) running binaries:
For testing, you probably also want a local SIP softphone. Zoiper works well for this. We have also used wired phones on unlocked PAP2 adapters.
Asterisk configuration files are normally kept in /etc/asterisk. Most aspects of Asterisk's default configuration are adequate for OpenBTS. Look at the files in the Asterisk directory and read all of the comments. These is also a detailed description on the Setting Up Asterisk page. The files of interest for OpenBTS are:
Check the port assignments given above. If possible, set the SIP test phone to use the GSM codec.
Most of OpenBTS is a kit of parts that can be assembled to form a basestation of a specific configuration. The OpenBTS.cpp file in the standard distribution is just an example basestation to show how that's done.
If you are building on Linux or Mac OS X, libosip and libortp are likely available via your package management system (apt-get, macports, etc). If not, follow the usual ./configure, make, make install process.
Make sure that the versions downloaded via the package management system match the requirements. In a deb-based distribution you can check the version of the package using the commandaptitude show libosip2-dev
If you compile libortp 0.13.1 from source and you are using a modern version of gcc, you will get errors of the type 'format not a string literal and no format arguments' in the tests folder, grab the tests from the latest version of libortp 0.16 that correct those formating errors.
libusrp is available via gnuradio. All releases of OpenBTS through 2.3 are made for use with GNU Radio 3.1. Starting from release 2.5 both GNU Radio 3.1 and GNU Radio 3.2 are supported.
If you're a happy Ubuntu user, look at this detailed manual on how to install GNU Radio on your system.
After getting the appropriate gnuradio sources, build libusrp by configuring with the following arguments:./configure --disable-all-components --enable-usrp --enable-omnithread --enable-mblock --enable-pmt
This will build just libusrp (and dependencies) from gnuradio. You might need to install a few extra dependencies: python-all-dev, swig, libfft3w-dev, libcppunit-dev, libboost-dev, sdcc-nf (notice the non-free package that includes the ASX8051 port).
There are some other common build problems you might encounter: * If you are trying to build under OS X, you will encounter a problem with XML validation in the documentation that will prevent you from building libusrp. The solution to this problem is to remove xmlto from your path. See "for details. * If you had to install the "boost" libraries, the include files were probably installed in /usr/local/include/boost-<version>, where <version> is whatever version you installed. You may need to create a soft link to /usr/local/include/boost for the compiler to find them. You can do that with the commandsudo ln -s /usr/local/include/boost-<version> /usr/local/include/boost* If you use ubuntu, there is a problem into our configure script that don't look the right place searching libusrp. To fix it (until we don't fix the configure script) follow the next steps:
$ cd /usr/local/include/ $ sudo ln -sf usrp/usrp_bytesex.h . $ sudo ln -sf usrp/usrp_standard.h . $ sudo ln -sf usrp/usrp_prims.h .
cmake . make sudo make install
OpenBTS, since release 1.2, "Breaux Bridge",uses a typical GNU build process. Once all the dependencies are satisfied, grab the sources. There are a few ways to do that.
Anyone can get the public release from GNU Radio via SVN:svn co http://gnuradio.org/svn/openbts/trunk/ openbtsIf you are an active contributor and have the password for the kestrelsp.com server, you get a development release via SFTP:
sftp openbts@kestrelsp.com
tar xzf openbts-<whatever>.tar.gzThe build process follows the standard GNU procedure:
cd openbts ./bootstrap ./configure make make installYou will get:
In the 2.x release series, you will also get a binary called "sendsms" in the apps/ directory that can be used to send text messages to handsets, although this utility is obsolete after 2.3 as it has been replaced with a command in the OpenBTS CLI.
These are obsolete, unsupported releases, so you are on your own from here.
sudo port install guile libusb libosip2* ortp needs to be built by source.
attachment:OpenBTS_FedoraCore11_InstallGuide.pdf
Note that this install guide is a little out of date, especially with respect to instructions for finding and downloading the source code packages. This wiki page is authoritative.
For GCC 4.4.1 and OpenBTS revision 11665 I had to manually add:
The OpenBTS system is a set of multiple applications that work together and communicate.
In these releases, OpenBTS is configured by editing and re-compiling the main OpenBTS application. Diagnostic and status messages are dumped to stdout and stderr, controlled by "#define DEBUG" entries in the source code of the various modules. The transceiver is started manually along with the GSM stack.
To run these versions, you will need at least three terminal windows.In these releases, OpenBTS is configured by a file called "OpenBTS.config". The transceiver is started manually along with the GSM stack.
To run these versions, you will need at least three terminal windows.In these releases, OpenBTS is initially configured by a file called "OpenBTS.config", but some aspects of the configuration can be controlled in real time from a command line interface (CLI). Diagnostic and status messages are logged to files with logging level and destination controlled by entries in the configuration file and can also be controlled from the CLI. The transceiver is started automatically along with the GSM stack.
In releases "Kinder" (2.4) and later, the OpenBTs.config file is not directly in the distribution. Instead there is a file called "OpenBTS.config.example" that needs to be copied to "OpenBTS.config" before starting the application for the first time. This change was made to allow OpenBTS.config to be overwritten from the CLI without destroying the original file. It also prevents individual developers' versions of OpenBTS.config from getting put into the distribution by accident.
Once the system is running, you can use the "help" command to get more information on the features of the CLI. The features vary from one release to the next.
dburgess@localhost:~/r2.5Lacassine/apps$ ./OpenBTS ./OpenBTS: error while loading shared libraries: libosip2.so.4: cannot open shared object file: No such file or directory
[dburgess@localhost apps]$ ./OpenBTS bind() failed: Address already in use terminate called after throwing an instance of 'SocketError' Aborted
Problem: OpenBTS shut down uncleanly and left a stray transceiver process.
Solution: Kill the stray transceiver process and try again. Like this[dburgess@localhost apps]$ ps PID TTY TIME CMD 23233 pts/1 00:00:00 bash 23342 pts/1 00:00:32 transceiver 23369 pts/1 00:00:00 ps [dburgess@localhost apps]$ kill -KILL 23342 [dburgess@localhost apps]$ !. ./OpenBTSYou can also use killall:
killall transceiver
This is a common mistake in releases prior to 2.3.
Symptom: A run attempt ends with1254170958.179475 0xa072f500: TRXManager.cpp:268: WARNING -- retrying transceiver command after response timeout 1254170959.200521 0xa072f500: TRXManager.cpp:268: WARNING -- retrying transceiver command after response timeout 1254170959.200624 0xa072f500: TRXManager.cpp:283: ERROR -- lost control link to transceiver terminate called after throwing an instance of 'SocketError' Abort trap
Problem: OpenBTS is trying to connect to the transceiver process, but it isn't there.
Solution: Start the transceiver before starting OpenBTS, as per the instructions in the "Running" section for releases prior to 2.2 and earlier.
This can happen in all releases.
Symptom: You get a lot of this message1253778301.154327 3082251152: USRPDevice.cpp:353: WARNING -- UNDERRUN in TRX->USRP interface
Problem: The software is not feeding transmitted data to the radio fast enough to keep up with real time. An occasion underrun is OK, but more than a few every few minutes will make your system unusable.
Solution(s):1254342002.0361 ALARM 1077699712 Transceiver.cpp:519: RX failed to tune 1254342002.0375 ALARM 1073875856 TRXManager.cpp:357: RXTUNE failed with status 1 1254342002.0805 ALARM 1073875856 TRXManager.cpp:409: POWERON failed with status 1 1254342002.0850 ALARM 1073875856 TRXManager.cpp:422: SETPOWER failed with status 1
Problem: You may be running the wrong transceiver program for your USRP hardware. For a stock 64 MHz USRP, user Transceiver/transceiver. For a 52 MHz USRP, use Transceiver52M/transceiver.
Solution: Set the correct path for TRX.Path in OpenBTS.config.
Starting program: OpenBTS Reading symbols for shared libraries .+++.+ done cannot open configuration file OpenBTS.config ../CommonLibs/Configuration.h:83: failed assertion `readFile(filename)'
Your OpenBTS.config file does not exist or is not where expected. For an initial installation, copy OpenBTS.config.example to OpenBTS.config
If you don't have expensive laboratory equipment and you want to know accuracy of your USRP clock, you can use an application Kalibrator (Copyright (c) 2009 Joshua Lackey, Alexander Chemeris). Of cource you cannot achieve such precision measurement like with hi-tech lab equipment, but it's enough to find out modest clock calibration errors.
Latest version of Kalibrator today is 0.2 and is available here. Starting from the next update of OpenBTS Kalibrator will be distributed as a part of OpenBTS standard package.
Kalibrator takes advantage of the existing real networks and their accuracy. So you need to be in range within some operator's BTS. You pass the downlink frequency of the previously scanned ARFCN as a command line parameter for Kalibrator. Using some math Kalibrator can estimate the value of frequency difference between the frequency it tunes USRP to and the frequency of a BTS working in +-200kHz range near that frequency.
To build Kalibrator with gnuradio 3.2.2 (ver. 3.1.3 is not currently supported) run 'make' and you will get binary file 'kal' which is ready for use.
Now you need to know which ARFCN is better to use. With any GPRS modem supporting AT commands it is possible to find an ARFCN with the strongest signal. Without such modem, you have to scan whole band by manual iteration through downlink frequencies (it can be inconvenient especially on 1800/1900 band). Search this file for specific downlinks all_gsm_channels_arfcn.txt.
Suitable channels must have at least -70 to -80dBm strenght, else you got to much overruns and the result could be misguiding. That's just good to have more channels to scan to eliminate possible wrong error. There is an example of network scan from GPRS modem (offset values are added manually).T-Mobile operator ================= at^moni Serving Cell I Dedicated channel chann rs dBm MCC MNC LAC cell NCC BCC PWR RXLev C1 I chann TS timAdv PWR dBm Q ChMod offset 58 53 -57 230 01 4358 719D 2 4 33 -106 48 I Limited Service -2197 Hz OK at^monp chann rs dBm MCC MNC BCC C1 C2 offset 106 45 -65 230 01 7 40 40 -2507 Hz 75 37 -73 230 01 2 32 32 -2367 Hz 28 21 -89 230 01 4 16 16 N/A 80 17 -93 230 01 1 12 12 N/A OK Telefonica O2 operator ====================== at^moni Serving Cell Z I Dedicated channel chann rs dBm MCC MNC LAC cell NCC BCC PWR RXLev C1 I chann TS timAdv PWR dBm Q ChMod offset 86 59 -51 230 02 04BC 090B 1 3 33 -106 54 I Limited Service -2496 Hz OK at^monp chann rs dBm MCC MNC BCC C1 C2 offset 114 47 -63 230 02 4 42 42 N/A 112 30 -80 230 02 7 25 25 N/A 93 19 -91 230 02 7 14 14 N/A OK
Here is obvious how the values were obtained.
[openBTS@openBTS kal-0.2]# ./kal -f 946600000 -u USRP side: B FPGA clock: 52000000 Decimation: 192 Antenna: RX2 Sample rate: 270833.343750 average [min, max] (range, stddev) -2197.789062 [-2431, -1843] (588, 146.761444) overruns: 0 not found: 0 [openBTS@openBTS kal-0.2]# ./kal -f 956200000 -u USRP side: B FPGA clock: 52000000 Decimation: 192 Antenna: RX2 Sample rate: 270833.343750 average [min, max] (range, stddev) -2507.531006 [-2575, -2436] (139, 40.815132) overruns: 0 not found: 0 [openBTS@openBTS kal-0.2]# ./kal -f 950000000 -u USRP side: B FPGA clock: 52000000 Decimation: 192 Antenna: RX2 Sample rate: 270833.343750 average [min, max] (range, stddev) -2367.053467 [-2431, -2275] (156, 43.972340) overruns: 0 not found: 0 [openBTS@openBTS kal-0.2]# ./kal -f 952200000 -u USRP side: B FPGA clock: 52000000 Decimation: 192 Antenna: RX2 Sample rate: 270833.343750 average [min, max] (range, stddev) -2496.760254 [-2592, -2375] (217, 61.745182) overruns: 0 not found: 0
By default RX and side are set to ones used by OpenBTS, so usually you need only one mandatory parameter '-f'. You can use -u is optional parameter for continous display.
... page in progress
The default clock of the USRP is 64Mhz. GSM clocks are derived from a 13 Mhz so multiples of 13 are "good clocks" for the host. Reclocking the USRP to 52 Mhz will make your host more CPU efficient.
There are presently three choices widely used with OpenBTS:
So now you've got an external clock signal, probably a stable 52Mhz clock, and you want to run OpenBTS with it. Here are the hardware and software setup instructions.
For gnuradio ver. 3.1.3:
long fpga_master_clock_freq () const { return 52000000; } //assert (dac_freq () == 128000000);
For gnuradio ver. 3.2 or higher:
d_verbose (false), d_fpga_master_clock_freq(52000000), d_db(2)
// assert (dac_rate() == 128000000);
return 52e6/_refclk_divisor();
As of release 2.5 "Lacassine", the 52 MHz modifications do not work with Mac OS X systems. If you use OS X, you will need to continue to use a 64 MHz clock.
Many of the problems getting phones to "camp" in both OpenBTS and OpenBSC have been related to frequency accuracy. To understand this problem, you have to understand clock technologies and you have to understand how a typical GSM phone acquires a signal.
Let's start with this, from GSM 05.10 Section 5.1:
The BTS shall use a single frequency source of absolute accuracy better than 0.05 ppm for both RF frequency generation and clocking the timebase. The same source shall be used for all carriers of the BTS.
For the pico BTS class the absolute accuracy requirement is relaxed to 0.1ppm.
An error of 0.05 ppm is 45 Hz in the low bands (850/900) and 90 Hz in the high bands (1800/1900). That is VERY accurate, the kind of accuracy you get from a GPS-disciplined VCTCXO (temperature-compensated voltage-controlled crystal oscillator) or an OCXO (oven-controlled crystal oscillator, a $100-$200 part). Doppler shift in the direct path from a 150 km/h car or train is on the order of 0.15 ppm, so the necessity of this kind of accuracy is questionable, but that's what is in the spec. Given Doppler effects, the observed frequency difference between two carrier-grade basestations is a few hundred Hz, worst case.
The typical GSM handset has a medium-quality VCTCXO. On a cold start, not locked to any outside clock, this clock has a an accuracy of around 20 ppm, or about 18 kHz in the low bands (850/900) and about 36 kHz in the high (1800/1900) bands. So, starting "cold" with no information, the phone runs a time-consuming frequency search over the whole possible drift range of its own clock and continues this search until it finds a beacon signal from a BTS.
Once the phone finds a beacon, it uses the carrier from the BTS to correct its own local clock by adjusting the control voltage on the VCTCXO. From that point on, the VCTCXO is just as accurate os the BTS clock as long as it is receiving the BTS signal. If the BTS signal is lost, the handset's clock will drift within some know worst-case rate. Knowing how long its local clock has been drifting, the handset can calculate the worst-case drift and use that information to narrow next frequency search.
So, you turn on a handset from "cold", it does a big frequency search until it finds a BTS. If it looses that BTS signal, it searches for another, but this time it does a much smaller frequency search, knowing that the signal from the next BTS will be within a few hundred Hz of its expected frequency and that its own local clock has not drifted much since last seeing a beacon. If the handset finds another beacon during this small search, it will stop searching. (That's critical for the next part of this discussion.) If the handset fails to find a beacon in the small search, it will widen the search range or a multiband phone might try a different band.
Now, suppose your BTS uses a simple XO (crystal oscillator) clock, which produces an error on the order of a several kHz on your RF
carrier. This is the case for OpenBTS with a "stock" USRP and it is also the case with the the Siemens BS-11 (used by OpenBSC) when it is locked to the clock from a typical ISDN-grade E1 interface card. This kind of BTS can fail in three possible ways, depending on just how bad the clock error is and how the system is being used:
The first type of failure is where the BTS XO error is so large that your BTS beacon falls completely outside the handset's "big" search range. The handset simply never finds the BTS signal. This is the error Fabian Uehlin found when he first tried to operate OpenBTS in the 1800 band. He fixed it by using an external clock with much better accuracy.
The second type of failure is when your BTS RF carrier is within the "big" search range but differs from the local "real" networks by more than a few hundred Hz. In this situation, the handset will either see your BTS or it will see the "real" network, but not both. Whatever system the handset sees first will control its clock and make it blind to the other. This kind of failure was discussed in detail in the OpenBSC e-mail list in Spring 2009. It has not been discussed much in the OpenBTS list, but it is safe to assume that it happens if you try to run the BTS in the same band as your local GSM carriers or try to work with multi-band phones. If I am not mistaken, the OpenBSC people fixed this problem by realizing that the VCOCXO in the BS-11 is much better than the XO on their standard E1 card -- if they just leave it alone. In OpenBTS we avoid this problem by operating in non-local bands and disabling other bands in the handsets so that they never see any other network. (OpenBTS can do that because unlike OpenBSC our radio is mostly software and very flexible.)
The XO errors of the BTS and the handsets will vary with age and temperature, so the failure behavior will be different for every handset at any given time and will vary from hour to hour as things warm up and cool down. That can make it all seem very mysterious and can make diagnosis difficult.
Normally, a handset receives a neighbor list from its serving BTS and constantly monitors the signal levels from the beacons of these neighbors. The key feature used for this monitoring is the extended training sequence (XTS) of the synchronization burst. This XTS has a duration of 64 symbols (roughly 0.25 ms). If we search for this XTS with a matched filter, the performance of that matched filter will degrade rapidly for frequency offsets greater than about 1/(4*0.25 ms), or about 1 kHz, because at higher frequencies the relative phases of the XTS and the matched filter will drift by more than 90 degrees over the correlation period. So neighbor monitoring (and therefore mobility itself) starts to fail for per-BTS carrier offsets of more than 500 Hz.
A 500 Hz error is 0.5 ppm in the low bands and 0.25 ppm in the high bands. While this is an easier requirement than the 0.05 ppm given in the spec, it is much tighter than could be provided by a simple XO. This accuracy can be provided by an OCXO or a good quality VCTCXO with regular calibration.
In the long-term, OpenBTS will fix both of these clock problems completely replacing the XO clock in the USRP with something much more accurate, either a true OCXO or a very high-quality VCTCXO with an automated calibration procedure.
Several OpenBTS uses have also recommended the kit "FA-SY 1" from Funkamateur, available for about 40€, for desktop testing.
Getting back to 05.10 Section 5.1, the GSM specifications dictate that the RF carrier and the symbol clock in the BTS be derived from a common source.
In the handset, the symbol clock is disciplined by the BTS RF carrier, just like the carrier clock. So, if your BTS RF carrier is in error by N ppm, the handset symbol clock will also be in error by N ppm. That's OK if the BTS symbol clock has exactly the same error, which it WILL if you derive everything from a common clock that way the specification tells you to.
But suppose you try to be clever. You know that once your equipment is warmed up, your BTS XO is consistently in error by +11 ppm, giving an RF carrier error of +10 kHz. So you deliberately de-tune your RF carrier by -10 kHz. That fixes the problems described in the previous section, but creates a new problem in the symbol rate clock. The standard GSM symbol clock is 270.833333 kHz. Your BTS XO is really off by +11 ppm, so your BTS symbol clock is really 270.836312 kHz. The handset locks to your BTS RF carrier, which is now spot-on its specified frequency, so the handset generates a correct internal symbol clock of 270.833333 kHz. So now the BTS and handset symbol clocks are slipping against each other at a rate of 11 ppm, or about 3 symbols per second.
Another variation on this problem is if you ignore the spec and use different clock devices for your RF carrier and your symbol clock. For example, suppose you have two 0.5 ppm OCXOs. Their relative fractional difference will be about 0.5 ppm, giving a drift of about one symbol every 7 seconds or so. (I've actually see this done before, too.)
Different handsets respond to the slipping symbol clock in different ways. In our experience, Nokia DCT3s just deal with it, apparently re-syncing on every frame, so if we only use DCT3s for testing, we may never realize that it is a serious problem. A Nokia DCT4 may camp to the beacon briefly, but will abort a transaction when the clock slips. In some handset designs, the symbol slipping interacts with the closed-loop timing advance, making that control loop unstable. Again, the error seems mysterious because different handset models respond in different ways and the effect will very with temperature as the XO in the BTS drifts around.
All handsets have bugs in their GSM stacks. If your BTS has no bugs of its own, then it will not invoke most of these latent handset bugs. When we see specific handset models behave badly with OpenBTS, that lets us know that OpenBTS has a bug. Eventually, as OpenBTS improves, the bugs will get fixed and all of these phones will move to the "Known to Work" list. Also, handset manufacturers tend to use the same GSM stacks for years across many products, so if a single handset from a given manufacturer works then there's a good chance that many other models from that manufacturer made around the same time will work as well.
Developers are encouraged to update this page frequently to report their experiences, especially with phone models not already listed here.
Note that most multi-band phones will require forcing when tested in the presence of other networks. That is normal behavior of the handset and does not indicate a problem with OpenBTS.
| phone manufacturer | phone model(notes) | SIM type | GSM band | USRP clock | computer (CPU, clock, mem, OS) | GNU Radio version | 1.6 | 2.3 | 2.4 | 2.5.1 | 2.6 |
| Nokia | DCT-3 series | many | 850, 900, 1800 | 64 or 52 | various | 3.1, 3.2 | OK | OK | OK | OK | OK |
| DCT-4 series | many | 850, 900, 1800 | 64 or 52 | various | 3.1, 3.2 | OK | OK | OK | OK | ||
| DCT-4+ series | many | 850, 900, 1800 | 64 or 52 | various | 3.1, 3.2 | OK | |||||
| 7650 | China (460 00), Thailand (520 01), Israel (425-01 and 425-02) | 900 MHz | 52 MHz TCXO | P4 2.4 GHz With Centos, linux kernel 2.6.18 | OK | OK | OK | OK | |||
| 6021 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.04, 2.6.28 | 3.2.2 | OK | OK | |||||
| 3310 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.04, 2.6.28 | 3.2.2 | OK | ||||||
| 3410 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.04, 2.6.28 | 3.2.2 | OK | ||||||
| 2600 | 230/01 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.2.2 | OK | |||||
| 3120 | 230/02 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.2.2 | OK | |||||
| 7250 | 230/02 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.2.2 | OK | |||||
| 3120 classic | 230/02 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.2.2 | OK | |||||
| 6720 classic | o² Germany | 1800 MHz | external clock @ 64 MHz | Ubuntu Karmic, 2 GB | 3.1.3 | OK | |||||
| 6230b | T-Mobile USA | 1900 MHz | ClockTamer @ 52 MHz | Intel C2D P7570 2.26GHz, 2GB RAM, F12, 2.6.33-rc5 | 3.3git (02616cf) | OK | |||||
| Siemens | MT50 | 230/03 | 900 MHz | 64 MHz internal | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.1.3 | OK | OK | |||
| CF62 | 230/03 | 900 MHz | 64 MHz internal | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.1.3 | OK | OK | OK | |||
| MC75 modem | 230/03 | 900 MHz | 64 MHz internal | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | 3.1.3 | OK | OK | ||||
| A52 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.04, 2.6.28 | 3.2.2 | OK | OK | |||||
| A65 | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.04, 2.6.28 | 3.2.2 | OK | OK | |||||
| AX75 | Vodafone CZ (230/03), China (460/02) | 900 MHz | KSP's 52 MHz | Intel E3200 @1.9GHz, GA-G41M, 1GB RAM, Ubuntu 9.10, 2.6.31-16 | 3.2.2 | OK | |||||
| Ericsson | R310 | 230/03 | 900 MHz | 64 MHz internal | Intel C2D 2.26GHz, 3GB RAM, fc11 2.6.29 | OK | OK | ||||
| T68i | OK | ||||||||||
| Alcatel | BG3 | Vodafone | 900 MHz | ClockTamer @ 52 MHz | Intel C2D 1.86GHz, 4GB RAM, Ubuntu 9.10 | OK | |||||
| Treo | 650 | OK | |||||||||
| 700 | OK | ||||||||||
| T-Mobile | G1 | stock 64 MHz | OK | OK | |||||||
| Motorola | F3 | OK | |||||||||
| Apple | iPhone 2G | OK (?) | |||||||||
| Apple | iPhone 3G | OK | |||||||||
| OpenMoko FreeRunner | 2G | OK | |||||||||
| Samsung | M140L | 850 MHz | 64MHz external clock | OK | |||||||
| C270 | O2 Germany | 900 MHz | ClockTamer @ 52 MHz | Intel CPU, Ubuntu 9.10 64Bit | 3.2.2 | OK | |||||
| A137 | ATT | 850 MHz | stock 64 MHz | Intel MacBook Pro | 3.1 | OK | |||||
| E-Ten | Glofiish M700 | 850 MHz | 64MHz external clock | OK | |||||||
| HTC | Touch | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.04, 2.6.28 | 3.2.2 | NO | OK | ||||
| Hero | o² Germany | 1800 MHz | external clock @ 64 MHz | Ubuntu Karmic, 2 GB | 3.1.3 | OK | |||||
| LG | GB102 o2 branded, unlocked | 900 MHz | ClockTamer @ 52 MHz | Intel C2D T7200@1GHz, 4GB RAM, Ubuntu 9.10, 2.6.31-17 | 3.3git (ecbbd26) | kind of | |||||
| BlackBerry | Curve 8320 | T-Mobile USA | EGSM/900/1900 | ClockTamer @ 52 MHz | Intel C2D P7570 2.26GHz, 2GB RAM, F12, 2.6.33-rc5 | 3.3git (02616cf) | OK |
The Nokia 3410 and Nokia 3310 sometimes fail to register. This is caused by interference from existing GSM network, so if you see this you should try to find ARFCN with less interference. Seems Nokia phones are much more sensitive to interference then e.g. Siemens ones.
Recent Blackberry models can register, do SMS and sometimes place calls but sometimes hang in strange states. Last tested with release 2.4 and need retesting in 2.5 or later.
Nokia N80 and E71 camp with OpenBTS but not consistently, probably only after the SIM connected from a more 'friendly' phone (e.g. Nokia 7650). Tested with OpenBTS 2.4 with a 52 MHz clock. Test performed in Israel on the 900 MHz band. SIM cards from Israel (425 01 and 425 02). OpenBTS running on P4 2.4 GHz with Centos, linux kernel 2.6.18. This needs to be retested with 2.5 or 2.6. Update: Nokia E71 was tested with OpenBTS 2.5.3, GnuRadio pre-3.3 (from git) and ClockTamer@52MHz clock. It registers with OpenBTS smoothly and receives SMSes without any problems. Call Nokia E71 to Samsung S5230 establishes fine, but no audio is heard. This needs to be tested better.
The LG GB102 o2 branded, unlocked to work with any SIM-card can't connect to OpenBTS. It sees the network, but when you press "Connect" it says "Fail" immediately. At the same time it connects perfectly to commercial GSM network. Further tests have shown that it connects to OpenBTS if it mimics to the home network of the SIM card inserted. But when you try to use test network (001:01) phone can't connect to it. This appears to be a serious bug in the handset, not a flaw in OpenBTS.
The Motorola Razr V3 is fails to register with OpenBTS. Last tested with release 2.4. This is probably due to an improper response to the GPRS Suspension Request message and should be fixed in release 2.5 but has still not been retested.
Here's the hardware you will need for a desktop testing kit:
burn-db-eeprom -A --force -t rfx900
OpenBTS will transmit on the "A" board, on the "TX/RX" connector.
OpenBTS will receive on the "B" board, on the "RX2" connector.
Need a visual of that? Here's a laptop, USRP and a couple of DCT-3 test phones:

The recommended testing configuration is to operate in a cellular band not used in your area and use test phones that do not support your local cellular bands. This arrangement forces your test phone to camp to your basestation. It also prevents you from inadvertently attracting phones from the local licensed carriers. For example, to test in North America, you might use the EGSM900 band or the DCS1800 band and use a phone that does not support GSM850 or PCS1900.
If you do operate in a band that is also used by cellular carriers in your area, you will need to use SIMs from a carrier that does not offer service in you area and has no roaming agreements with carriers in your area. You can then use network parameters matched to the SIM and, hopefully, your test phones will ignore the local network and phones from your local network will ignore you.
If you do not operate in a band that is used by cellular carriers in your area, you can use any SIM you want.
If you want any flexibility at all in your choice of SIMs, you will need to use unlocked phones.
Be aware of power levels and local regulations. Here are some technical guidelines:
However, these are only technical pointers to help you comply with your local regulations. They are not legal advice on the regulations themselves. That is entirely your responsibility.
To make your phone choose OpenBTS even if other networks try to steal your connection you should:
PS If you change MCC&MNC in your OpenBTS setup, don't forget to update network settings in your test phones accordingly.
As of release 2.6, OpenBTS does not support the USRP2. There are no official plans to support that equipment and to our knowledge no one is doing it.
On of the main limiting factors of BTS performance is uplink/downlink isolation. For a full-range GSM system, we need about 160 dB of isolation. This degree of isolation does not appear possible on a single RFX board.
This is possible and there are patches on the openbts-discuss (at) lists.sourceforce.net mailing list to support that and the performance is adequate for desktop development work. As of release 2.6.0, though, these patches are not in the official distribution.
This is possible and there are patches on the openbts-discuss (at) lists.sourceforce.net mailing list to support that. As of release 2.6.0, though, these patches are not in the official distribution.
Kestrel Signal Processing, Inc. (KSP) is a software and signal processing consulting company in Fairfield, California. OpenBTS originated at KSP. KSP holds a blanket license for non-GPL distributions of OpenBTS and the great majority of publicly-available OpenBTS source code was written or commissioned by KSP. Any source code included in the official distribution of OpenBTS must be submitted under a contributor's license agreement (CLA) that assigns copyrights to KSP. KSP will then reassign copyrights to the FSF for any public release.
Note that the copyright-transfer requirement applies only to the core OpenBTS application, the GSM "stack". It does not apply to support applications like smqueue. Those components will be used under GPL even in commercial applications and can include any GPL-compatible components. If someone contributes GPL code to those support applications, it may also be incorporated into KSP's development trunk under GPL terms.
Yes. If you to use OpenBTS in a commercial application, you will probably need a non-GPLv3 license from KSP. You will still be responsible for arranging your own patent licensing for those patent-encumbered parts of the GSM specification. There are 100-200 essential patents for elements 2G GSM, depending on the feature set you intend to support.
The commercial release of OpenBTS includes features not in the public release and the GSM stack is not GPL. It is generally distributed only on KSP-provided hardware. Source code for the non-GPL components of the commercial release is available under commercial licenses.
As of July 2010, not quite yet, but it is being used in the development of real products that will probably reach the market later in 2010.
OpenBTS is part of the GNU Radio project and uses the same USRP hardware. However, the only part of the GNU Radio software actually used by OpenBTS is the libusrp device interface.
OpenBSC is an Abis-based GSM core network simulator designed for use with commercial BTS products. It is an entirely different project with an entirely different set of goals. Furthermore, the different implementation styles (C single-thread event driven versus C++ multithread dataflow) prevent direct transfer of code from one project to another. That said, the two projects often encounter identical engineering and design problems and many people who contribute in one project often follow technical discussions in the other.
Airprobe is a GSM passive receiver and protocol analyzer. Airprobe may be useful as a debugging tool for OpenBTS developers, but it is not supported by the OpenBTS project.
Mirror is also available here.
Contains an article GSM, which has a brief description of the system. That page also has versions in many other languages (e.g. Russian) which may be useful for non-English speakers.
Very good introduction to the protocol logical structure is given at the page Um Interface.
They are mostly in German, available for download on his web-page.
One lecture is available in English and is a good introduction into GSM architecture in general and Dm channels specifically: The GSM-Dm-Channels, a correspondence lesson
В сети нетрудно найти, например, введение в GSM от Вымпелкома (бренд Билайн) - достаточно забить в поисковик "GSM - обзор системы. Корпоративный тренинг Вымпелком."
Есть, наверное, и другие хорошие введения. Если вы знаете какие - добавьте ссылки сюда, пожалуйста.
The question of how idle sequences are generated drives much of the L1 and L2 architecture in a software BTS. In the OpenBTS architecture, the bulk of any idle fill task is handled at a very low level by the software defined radio, in what is sometimes called "L0", the radio interface below the L1 FEC modules.
To support idle filling, the software transmitter keeps a table for each timeslot large enough to store all of the radio bursts for a a complete cycle of that slot's TDMA pattern. (The software transmitter is aware of the channel combination in use on a given timeslot.) There are two rules for managing this table:
1. Whenever a radio burst is sent to the software transmitter, the transmitter stores a copy of the outgoing burst in that slot's filler table, indexed by the outgoing bust's frame number, modulo the TDMA cycle period.
1. Whenever the software transmitter needs to send a radio burst at a specific position in the TDMA pattern and none is enqueued for transmission, the transmitter will pull a substitute burst from the filler table.
The effect of this pair of rules is that whenever the bursts of an L2 frame are sent to the radio for transmission on a particular logical channel, that burst pattern will continue to be repeated in its TMDA positions on the radio link until the bursts of another L2 frame are sent to replace it. The implication for the higher layers is that an idle filling frame need only be sent once, at the start of an idle period, and the lower layers of the radio will continue to repeat that idle pattern until some new activity overwrites it.
With a sufficiently long TDMA cycle time, this mechanism may also be used to generate the system information messages of the SACCH or BCCH, although we do not do that yet.
GSM is an acronym that stands for Global System for Mobile Communications. The original french acronym stands for Groupe Spécial Mobile. It was originally developed in 1984 as a standard for a mobile telephone system that could be used across Europe.
GSM is now an international standard for mobile service. It offers high mobility. Subscribers can easily roam worldwide and access any GSM network.
GSM is a digital cellular network. At the time the standard was developed it offered much higher capacity than the current analog systems. It also allowed for a more optimal allocation of the radio spectrum, which therefore allows for a larger number of subscribers.
GSM offers a number of services including voice communications, Short Message Service (SMS), fax, voice mail, and other supplemental services such as call forwarding and caller ID.
Currently there are several bands in use in GSM. 450 MHz, 850 MHZ, 900 MHz, 1800 MHz, and 1900 MHz are the most common ones.
Some bands also have Extended GSM (EGSM) bands added to them, increasing the amount of spectrum available for each band.
GSM makes use of Frequency Division Multiple Access (FDMA) and Time Division Multiple Access (TDMA).
*TDMA will be discussed later
GSM allows for use of duplex operation. Each band has a frequency range for the uplink (cell phone to tower) and a separate range for the downlink (tower to the cell phone). The uplink is also known as the Reverse and the downlink is also known as the Forward. In this tutorial, I will use the terms uplink and downlink.

GSM divides the allocated spectrum for each band up into idividual carrier frequencies. Carrier separation is 200 khz. This is the FDMA aspect of GSM.
The ARFCN is a number that describes a pair of frequencies, one uplink and one downlink. The uplink and downlink frequencies each have a bandwidth of 200 kHz. The uplink and downlink have a specific offset that varies for each band. The offset is the frequency separation of the uplink from the downlink. Every time the ARFCN increases, the uplink will increase by 200 khz and the downlink also increases by 200 khz.
*Note: Although GSM operates in duplex (separate frequencies for transmit and receive), the mobile station does not transmit and receive at the same time. A switch is used to toggle the antenna between the transmitter and receiver.
The following table summarizes the frequency ranges, offsets, and ARFCNs for several popular bands.

The following diagram illustrates an ARFCN with paired uplink and downlink frequencies for ARFCN 1 in the GSM 900 band.

The following is a way to calculate the uplink and downlink frequencies for some of the bands, given the band, the ARFCN, and the offset.
Up = 890.0 + (ARFCN * .2)
Down = Up + 45.0
example:
Given the ARFCN 72, and we know the offset is 45MHz for the GSM900 band:
Up = 890.0 + (72 * .2)
Up = 890.0 + (14.4)
Up = 904.40 MHz
Down = Up + Offset
Down = 904.40 + 45.0
Down = 949.40 MHz
The uplink/downlink pair for GSM900 ARFCN72 is 904.40/949.40 (MHz)
Here are the formulas for EGSM900, DCS1800, and PCS1900:Up = 890.0 + (ARFCN * .2)
Down = Up + 45.0
Up = 1710.0 + ((ARFCN - 511) * .2)
Down = Up + 95.0
Up = 1850.0 + ((ARFCN - 512) * .2)
Down = Up + 80.0
The MSISDN is the subscriber's phone number. It is the number that another person would dial in order to reach the subscriber. The MSISDN is composed of three parts:
Country Code (CC)
National Destination Code (NDC)
Subscriber Number (SN)

Country Code (CC) - This is the international dialing code for whichever country the MS is registered to.
National Destination Code (NDC) - In GSM, an NDC is assigned to each PLMN. In many cases, a PLMN may need more than one NDC.
Subscriber Number (SN) - This is a number assigned to the subscriber by the service provider (PLMN).
The combination of the NDC and the SN is known as the National (significant) Mobile Number. This number identifies a subscriber within the GSM PLMN.

The IMSI is how the subscriber is identified to the network. It uniquely identifies the subscriber within the GSM global network. The IMSI is burned into the SIM card when the subscriber registers with PLMN service provider. The IMSI is composed of three parts:
Mobile Country Code (MCC)
Mobile Network Code (MNC)
Mobile Subscriber Identification Number (MSIN)

Mobile Country Code (MCC) - This number identifies which country the subscriber's network is in. It has 3 digits.
Mobile Network Code (MNC) - This number identifies the home GSM PLMN of the subscriber (Cingular, T-Mobile, etc.). It has 2 or 3 digits. Some networks may have more than one MNC allocated to it.
Mobile Subscriber Identification Number (MSIN) - This number uniquely identifies a user within the home GSM network.
The IMEI uniquely identifies the Mobile Equipment itself. It is essentially a serial number that is burned into the phone by the manufacturer. The IMEI is composed of three parts:
Type Allocation Code (TAC) - 8 digits
Serial Number (SNR) - 6 digits
Spare (SP) - 1 digit

Type Allocation Code (TAC) - This number uniquely identifies the model of a wireless device. It is composed of 8 digits. Under the new system (as of April 2004), the first two digits of a TAC are the Reporting Body Identifier of the GSMA approved group that allocated this model type.
Serial Number (SNR) - This number is a manufacturer defined serial number for the model of wireless device.
Spare (SP) This number is a check digit known as a Luhn Check Digit. It is omitted during transmission within the GSM network.
On many devices the IMEI number can be retrieved by entering *#06#
Prior to April, 2004 the IMEI had a different structure:
Type Allocation Code (TAC) - 6 digits
Factory Assembly Code (FAC) - 2 digits
Serial Number (SNR) - 6 digits
Spare (SP) - 1 digit

As of April 2004, the use of the FAC was no longer required. The current practice is for the TAC for a new model to get approved by national regulating bodies, known as the Reporting Body Identifier.
This is a newer form of the IMEI that omits the Spare digit at the end and adds a 2-digit Software Version Number (SVN) at the end. The SVN identifies the software version that the wireless device is using. This results in a 16-digit IMEI.
Type Allocation Code (TAC) - 8 digits
Serial Number (SNR) - 6 digits
Software Version Number (SVN) - 2 digits

As you remember from the Introduction to TDMA tutorial. GSM divides up each ARFCN into 8 time slots.
These 8 timeslots are further broken up into logical channels.
Logical channels can be thought of as just different types of data that is transmitted only on certain frames in a certain timeslot.
Different time slots will carry different logical channels, depending on the structure the BSS uses.
There are two main categories of logical channels in GSM:
Signaling Channels
Traffic Channels (TCH)
These are the main types of signaling Channels:Broadcast Channels (BCH) - Transmitted by the BTS to the MS. This channel carries system parameters needed to identify the network, synchronize time and frequency with the network, and gain access to the network.
Common Control Channels (CCH) - Used for signaling between the BTS and the MS and to request and grant access to the network.
Standalone Dedicated Control Channels (SDCCH) - Used for call setup.
Associated Control Channels (ACCH) - Used for signaling associated with calls and call-setup. An ACCH is always allocated in conjunction with a TCH or a SDCCH.
*keep in mind, these are only categories of logical channels, they are not logical channels themselves.
The above categories can be divided into the following logical channels:
Broadcast Channels (BCH)
Broadcast Control Channel (BCCH)
Frequency Correction Channel (FCCH)
Synchronization Channel (SCH)
Cell Broadcast Channel (CBCH)
Common Control Channels (CCCH)
Paging Channel (PCH)
Random Access Channel (RACH)
Access Grant Channel (AGCH)
Standalone Dedicated Control Channel (SDCCH)
Associated Control Channel (ACCH)
Fast Associated Control Channel (FACCH)
Slow Associated Control Channel (SACCH)
Let's examine each type of logical channel individually.
Broadcast Control Channel (BCCH) - DOWNLINK - This channel contains system parameters needed to identify the network and gain access. These paramters include the Location Area Code (LAC), the Mobile Network Code (MNC), the frequencies of neighboring cells, and access parameters.
Frequency Correction Channel (FCCH) - DOWNLINK - This channel is used by the MS as a frequency reference. This channel contains frequency correction bursts.
Synchronization Channel (SCH) - DOWNLINK - This channel is used by the MS to learn the Base Station Information Code (BSIC) as well as the TDMA frame number (FN). This lets the MS know what TDMA frame they are on within the hyperframe.
*The BSIC was covered in the Introduction to GSM Tutorial. You can also read about the numbering schemes used in GSM.
Cell Broadcast Channel (CBCH) - DOWNLINK - This channel is not truly its own type of logical channel. The CBCH is for point-to-omnipoint messages. It is used to broadcast specific information to network subscribers; such as weather, traffic, sports, stocks, etc. Messages can be of any nature depending on what service is provided. Messages are normally public service type messages or announcements. The CBCH isnt allocated a slot for itself, it is assigned to an SDCCH. It only occurs on the downlink. The CBCH usually occupies the second subslot of the SDCCH. The mobile will not acknowledge any of the messages.
[Back to Top]
Paging Channel (PCH) - DOWNLINK - This channel is used to inform the MS that it has incoming traffic. The traffic could be a voice call, SMS, or some other form of traffic.
Random Access Channel (RACH) - UPLINK This channel is used by a MS to request an initial dedicated channel from the BTS. This would be the first transmission made by a MS to access the network and request radio resources. The MS sends an Access Burst on this channel in order to request access.
Access Grant Channel (AGCH) - DOWNLINK - This channel is used by a BTS to notify the MS of the assignement of an initial SDCCH for initial signaling.
[Back to Top]
Standalone Dedicated Control Channel (SDCCH) - UPLINK/DOWNLINK - This channel is used for signaling and call setup between the MS and the BTS.
Associated Control Channels (ACCH)
Fast Associated Control Channel (FACCH) - UPLINK/DOWNLINK - This channel is used for control requirements such as handoffs. There is no TS and frame allocation dedicated to a FAACH. The FAACH is a burst-stealing channel, it steals a Timeslot from a Traffic Channel (TCH).
Slow Associated Control Channel (SACCH) - UPLINK/DOWNLINK - This channel is a continuous stream channel that is used for control and supervisory signals associated with the traffic channels.
[Back to Top]
Normally the first two timeslots are allocated to signaling channels.
Remember that Control Channel (aka signaling channels) are composed of 51 TDMA frames. On a time slot Within the multiframe, the 51 TDMA frames are divided up and allocated to the various logical channels.
There are several channel combinations allowed in GSM. Some of the more common ones are:
FCCH + SCH + BCCH + CCCH
BCCH + CCCH
FCCH + SCH + BCCH + CCCH + SDCCH/4(0..3) + SACCH/C4(0..3)
SDCCH/8(0 .7) + SACCH/C8(0 . 7)
FCCH + SCH + BCCH + CCCH
Downlink
Uplink BCCH + CCCH
/>
Downlink
Uplink
FCCH + SCH + BCCH + CCCH + SDCCH/4(0..3) + SACCH/C4(0..3)
The SACCH that is associated with each SDCCH is only transmitted every other multiframe. Each SACCH only gets half of the transmit time as the SDCCH that it is associated with. So, in one multiframe, SACCH0 and SACCH1 would be transmitted, and in the next multiframe, SACCH2 and SACCH3 would be transmitted. The two sequential multiframes would look like this:
/>
Downlink
Uplink
You will also notice that the downlink and uplink multiframes do not align with each other. This is done so that if the BTS sends an information request to the MS, it does not have to wait an entire multiframes to receive the needed information. The uplink is transmitted 15 TDMA frames behind the downlink. For example, the BTS might send an authentication request to the MS on SDCCH0 (downlink) which corresponds to TDMA frames 22-25. The MS then has enough time to process the request and reply on SDCCH0 (uplink) which immediately follows it on TDMA frames 37-40.
SDCCH/8(0 .7) + SACCH/C8(0 . 7)
Once again, the SACCH that is associated with an SDCCH is only transmitted every other multiframe. Two consecutive multiframes would look like this:
/>
Downlink
Uplink
Traffic Channels (TCH)
Traffic Channels are used to carry two types of information to and from the user:
/>
Encoded Speech
Data
There are two basic types of Encoded Speech channels:
Encoded Speech - Encoded speech is voice audio that is converted into digital form and compressed. See the Speech Encoding tutorial to see the process.
Full Rate Speech TCH (TCH/FS) - 13 kb/s
Half Rate Speech TCH (TCH/HS) - 5.6 kb/s
Data - Data refers to user data such as text messages, picture messages, internet browsing, etc. It includes pretty much everything except speech.
Full rate Data TCH (TCH/F14.1) - 14.4 kb/s
Full rate Data TCH (TCH/F9.6) - 9.6 kb/s
Full rate Data TCH (TCH/F4.8) - 4.8 kb/s
Half rate Data TCH (TCH/F4.8) - 4.8 kb/s
Full rate Data TCH (TCH/F2.4) - ≤2.4 kb/s
Half rate Data TCH (TCH/H2.4) - ≤2.4 kb/s
[Back to Top]
Traffic Channel Mapping
Time slots 2 through 7 are normally used for Traffic Channels (TCH)
Traffic Channel Multiframes are composed of only 26 TDMA frames. On each multiframe, there are 24 frames for Traffic Channels, 1 frame for a SACCH, and the last frame is Idle. Remember that a MS (or other device) only gets one time slot per TDMA frame to transmit, so in the following diagrams we are looking at a single time slot.
Full Rate Traffic Channel (TCH/FS)
When using Half-Rate Speech Encoding (TCH/HS), the speech encoding bit rate is 5.6 kb/s, so one time slot can handle two half-rate channels. In this case, one channel will transmit every other TDMA frame, and the other channel would be transmitted on the other frames. The final frame (25), which is normally used as an Idle frame, is now used as a SACCH for the second half-rate channel.
Half Rate Traffic Channel (TCH/HS)
[Back to Top]
ARFCN Mapping
This diagram shows a sample Multiframe with logical channels mapped to time slots and TDMA frames. This is just one possible configuration for an ARFCN.
*For illustrative purposes, half of the traffic channels are full-rate and the other half are half-rate
TS0
TS1
TS2
TS3
TS4
TS5
TS6
TS7
*Remember that CCH Multiframes have 51 frames and TCH Multiframes only have 26. Their sequences will synchronize every superframe.
[Back to Top]
Offset
Even though GSM uses a full duplex radio channel, the MS and the BTS do not transmit at the exact same time. If a MS is assigned a given time slot, both the MS and the BTS will transmit during that given time slot, but their timing is offset. The uplink is exactly 3 time slots behind the downlink. For example, if the MS was allocated a TCH on TS3, the BTS would transmit when the downlink is on TS3 and the MS is set to receive on TS3. At this point, the uplink is only on TS0. Once the uplink reaches TS3, the MS would begin to transmit, and the BTS is set to receive on TS3. At this point, the downlink would be at TS6. When the MS is not transmitting or receiving, it switches frequencies to monitor the BCCH of adjacent cells.
[Back to Top]
Speech Data Throughput
When looking at a Time slot allocated to a TCH, you will notice that TCH does not occur on every single frame within a time slot. There is one reserved for a SACCH and one that is Idle. So, in a TCH Multiframe, only 24 of the 26 frames are used for traffic (voice/data). This leaves us with a data throughput of 22.8 kb/s.
Here is the math:
1. Calculate bits per TCH Multiframe:
We know that there are 114 bits of data on a single burst, and we know that only 24 of the 26 frames in a TCH multiframe are used to send user data.
114 bits × 24 frames = 2736 bits per TCH multiframe
So, we know that on a single timeslot over the duration of one TCH multiframe, the data throughput is 2736 bits.
2. Calculate bits per millisecond (ms):
From step one above, we know that the throughput of a single TCH multiframe is 2736 bits. We also know that the duration of a TCH multiframe is 120ms.
2736 bits / 120 ms = 22.8 bits per millisecond
3. Convert milliseconds (ms) to seconds:
Now we need to put the value into terms of seconds. There are 1000 milliseconds in a second, so we simply multiply the value by 1000.
22.8 bits/millisecond × 1000 = 22,800 bits per second (22.8 kb/s)
4. Convert bits to kilobits:
Finally, we want to put it into terms of kilobits per second, wich is the most common term for referring to data throughput. We know a kilobit is 1000 bits, so we simply divide the term by 1000.
22,800 bits/s ÷ 1000 = 22.8 kb/s
So now we see why the data throughput of a single allocated timeslot is 22.8 kb/s.
There is an easier method to come to this number:
We know that only 24 of the 26 frames carry data, so we can say that the new throughput would be 24/26 of the original throughput. If we convert this to decimal form:
24÷26 = .9231
We know from the TDMA Tutorial that the data throughput of a single timeslot is 24.7 kb/s. Apply this 24/26 ratio to the 24.7 kb/s throughput:
24.7 × .9231 = 22.8 kb/s
You can see that we get the same answer as above.
A single BTS may have several Transceivers (TRX) assigned to it, each having its own ARFCN, each ARFCN having 8 time slots.
The logical channels that support signaling will normally only be on one ARFCN. All of the other ARFCNs assigned to a BTS will allocate all 8 time slots to Traffic Channels, to support multiple users.
The following diagram is an example of how a medium-sized cell might be set up with 4 TRX (ARFCNs).
Sample Medium-Size Cell
[Back to Top]
Frequency Hopping
Each radio frequency Channel (ARFCN) is influenced differently by propagation conditions. What affects channel 23 may not affect channel 78 at all. Within a given cell, some frequencies will have good propagation in a certain area and some will have poor propagation in that area. In order to take advantage of the good propagation and to defeat the poor propagation, GSM utilizes frequency hopping. Frequency hopping means that a transceiver hops from one frequency to another in a predetermined sequence. If a transceiver hops through all of the avilable frequencies in a cell then it will average out the propagation. GSM uses Slow Frequency Hopping (SFH). It is considered slow becuase the system hops relatively slow, compared with other frequency hopping systems. In GSM, the operating frequency is changed every TDMA frame.
The main reason for using slow frequency hopping is because the MS must also change its frequency often in order to monitor adjacent cells. The device in a transceiver that generates the frequency is called a frequency synthesizer. On a MS, a synthesizer must be able to change its frequency within the time frame of one time slot, which is equal to 577 µs. GSM does not require the BTS to utilize frequency hopping. However, a MS must be capable of utilizing frequency hopping when told to do so.
The frequency hopping and timing sequence is known as the hopping algorithm. There are two types of hopping algorithms available to a MS.
There are a total of 63 different hopping algorithms available in GSM. When the MS is told to switch to frequency hopping mode, the BTS will assign it a list of channels and the Hopping Sequence Number (HSN), which corresponds to the particular hopping algorithm that will be used.
The base channel on the BTS does not frequency hop. This channel, located in time slot 0, holds the Broadcast Control Channels which the MS needs to monitor to determine strength measurements, determine access parameters, and synchronize with the system.
If a BTS uses multiple transceivers (TRX) then only one TRX will hold the the Broadcast Channels on time slot 0. All of the other TRXs may use time slot 0 for traffic or signaling and may take part in the frequency hopping.
There are two types of frequency hopping method available for the BTS: synthesizer hopping and baseband hopping.
Baseband Frequency Hopping
The openbts logo was developed by Alex Polvi with the help of Logan Welliver and released into the public domain on November 17th, 2008.
This is about OpenBTS' HLR replacement, which we will just call an "HLR" here for simplicity.
The HLR can be implemented using Asterisk's internal databases or with a database server.
At a minimum, the HLR stores the following for each subscriber:
At a minimum, the HLR will support these actions:
asterisk -rx "<command>"Here's an example of popen() use:
FILE* result = popen("dialplan show 2003@sip-local","r");
if (!result) {
// Handle error here.
}
// Now read and parse the result as if reading a file.
//...
// When done, close the stream.
pclose(result);
dburgess@pBook> sudo asterisk -rx "dialplan show 2003@sip-local" [ Context 'sip-local' created by 'pbx_config' ] '2003' => 1. Dial(SIP/310410226242003) [pbx_config] -= 1 extension (1 priority) in 1 context. =-
dburgess@pBook> sudo asterisk -rx "sip show user 310410226242003" ** Name : 310410226242003 Secret : <Not set> MD5Secret : <Not set> Context : sip-external Language : AMA flags : Unknown Transfer mode: open MaxCallBR : 384 kbps CallingPres : Presentation Allowed, Not Screened Call limit : 0 Callgroup : Pickupgroup : Callerid : "" <2003> ACL : No Codec Order : (gsm:20) Auto-Framing: No
dburgess@pBook> sudo asterisk -rx "database showkey SIP/Registry/310410226242003" /SIP/Registry/310410226242003 : 127.0.0.1:5062:3600:310410226242003:sip:310410226242003@127.0.0.1:5061;rinstance=6cc428b1f3f45ada
We will do this by modifying sip.conf and extensions.conf and then reloading them into Asterisk.
We should not do this more often than once every few minutes, though.
This is done by the BTS itself via the SIP interface during the registration process. That already works.
In the long run (after the Asterisk version works) the HLR will be implemented as a MySQL database table.
From this table, we construct the sip.conf and extensions.conf files for our Asterisk servers.
Whenever a new subscriber is added or an E.164 field or IMSI is altered, the sip.conf and extensions.conf files need to be regenerated and reloaded for the serving Asterisk server. There must be a better way to do that.
The following are the cell requirements for normal MS cell camping (ref 1):
The handset's decision to camp to a BTS is made in the handset. The BTS can send signals that can encourage a handset to behave one way or another, but in the end the BTS cannot force a handset to camp,
only offer an attractive invitation.
The handset will camp to whatever network its SIM is programmed to prefer, which is usually the network of the operator that issued the SIM, followed by its roaming partners. (A locked phone is one that will only accept SIMs from the carrier that locked it.) The only way sure to get the MS to camp to your BTS automatically is to be the only BTS available. Here are four ways to do that:
Note that we DO NOT RECOMMEND using the network parameters from your local network and relying on proximity to the test BTS to get a phone to camp to it. First, that is much less reliable than the options
listed above. Second, that risks interfering with your local cellular service. If you distract a phone from the real network while someone is making an emergency call, you can find yourself in jail, just to offer an example of the kind of thing that can go wrong. So mimicking AT&T/Voda/BT/whomever is a BAD IDEA.
Camping depends heavily on a number of factors. Once a handset has registered with a network, it usually is quite happy to stay there until something prompts a change. In most cases, if you are using an operator's SIM, say AT&T, the handset will stay on the current network until its current connection quality drops, it moves, or it sees another AT&T signal or another signal in the SIM cards preferred provider list. Your BTS then either needs to be broadcasting the same NMC/MCC (i.e. spoofing...which has legal implications) or you need your own SIM card in the handset that is configured with the MCC/MNC of your BTS.
The other way to accomplish this is to set your OpenBTS to use the 001 test code for MNC. Most phones will attempt to camp on this code if its the best signal around and its not happy on its own network. This
works best if you are in a zero-coverage area and you are sending out the 001 test code.
In the end, unless you use your own SIM cards and you have the phone configured to use your BTS, it won't just jump over to you if its happy where it is....and certainly for operator SIM cards, the phone will keep to its preferred provider list. You should also be aware that if the phone is SIM locked then you can't even put your own SIM card in the device as it will only work with the network that locked it (i.e. if you have an ATT phone and its been locked to only use the ATT network, then it won't work at all when you change the SIM card).
The MTC is the most complex operation in the Stage 1 OpenBTS. The MTC is the transaction by which an incoming call is connected to a mobile handset. It is largely implemented in Control/CallControl, but with other parts in SIP/SIPInterface, Control/SDCCHDispatch and Control/FACCHDisptach.
Here is the transaction sequence for the MTC:
1. An INVITE arrives at the SIPInterface giving the GSM mobile ID (an IMSI) as the SIP user ID.
1. The SIPInterface (in SIPInterface::checkInvite) creates a call entry in the global transaction table and also initiates the paging process (via Pager::addID).
1. The Pager sends out the mobile ID of the called handset in Paging Request messages on the CCCH (Common Control Channel). The CCCH is a unicast channel monitored by all idle handsets in the cell.
1. The handset, upon seeing its ID in a paging request, starts sending channel requests on the RACH (Random Access Channel).
1. The RACH bursts are received and decoded in L1 and passed up to the AccessGrantController in Control/RadioResource. The RACH burst contains an 8-bit tag.
1. AccessGrantController allocates an SDCCH (Standalone Dedicated Control Channel) and sends a description of this channel, along with the associated 8-bit tag, in an Immediate Assignment message on the CCCH.
1. The handset, still monitoring the CCCH, sees its 8-bit tag in the immediate assignment and goes to the assigned channel.
1. The first message on the SDCCH is a Paging Response from the handset. This message is processed in the SDCCHDispatcher, which checks the indicated service type and passes the message along to the MTCStarter in Control/CallControl, via the PagingResponseHandler in Control/RadioResource.
1. The MTCStarter searches the transaction table for the entry created by the SIPInterface back in step 2.
1. MTCStarter initiates alerting (ie, makes the handset ring) and allocates a Traffic Channel (TCH) for the call.
1. The TCH assignment is sent to the handset in an Assignment Message. The transaction ID for this call is also put onto the TCH channel object as a tag.
1. The handset moves to the assigned channel and sends an Assignment Complete message on the FACCH.
1. The assignment complete message arrives in the FACCHDispatcher, which checks its tagged transaction ID in the transaction table and passes control to the MTCController, also in Control/CallControl.
1. The call setup proceeds in the MTCController.
1. Once the call is fully connected, control passes to the callManagementLoop, also in Control/CallControl.
If things go well, all of this will take 3-5 seconds.
Suppose you have an isolated area with no cellular coverage. You want to cover it with OpenBTS. Not far away there is a city covered by a standard GSM carrier. You want a phone that will work in both places with a single number. You do not expect to negotiate a settlement agreement or direct network integration with the incumbent GSM carrier.
Now,
Also, if you are really cheap, you can just get a single E.164 DID in step 2 to be shared by all subscribers through a set of extensions in you OpenBTS Asterisk server, but this will make dialing non-standard for inbound callers.
A GSM network is made up of multiple components and interfaces that facilitate sending and receiving of signalling and traffic messages. It is a collection of transceivers, controllers, switches, routers, and registers.
A Public Land Mobile Network (PLMN) is a network that is owned and operated by one GSM service provider or administration, which includes all of the components and equipment as described below. For example, all of the equipment and network resources that is owned and operated by Cingular is considered a PLMN.
Mobile Station (MS)
The Mobile Station (MS) is made up of two components:
Mobile Equipment (ME) This refers to the physical phone itself. The phone must be able to operate on a GSM network. Older phones operated on a single band only. Newer phones are dual-band, triple-band, and even quad-band capable. A quad-band phone has the technical capability to operate on any GSM network worldwide.
Each phone is uniquely identified by the International Mobile Equipment Identity (IMEI) number. This number is burned into the phone by the manufacturer. The IMEI can usually be found by removing the battery of the phone and reading the panel in the battery well.
It is possible to change the IMEI on a phone to reflect a different IMEI. This is known as IMEI spoofing or IMEI cloning. This is usually done on stolen phones. The average user does not have the technical ability to change a phone's IMEI.
Subscriber Identity Module (SIM) - The SIM is a small smart card that is inserted into the phone and carries information specific to the subscriber, such as IMSI, TMSI, Ki (used for encryption), Service Provider Name (SPN), and Local Area Identity (LAI). The SIM can also store phone numbers (MSISDN) dialed and received, the Kc (used for encryption), phone books, and data for other applications. A SIM card can be removed from one phone, inserted into another GSM capable phone and the subscriber will get the same service as always.
Eadch SIM card is protected by a 4-digit Personal Identification Number (PIN). In order to unlock a card, the user must enter the PIN. If a PIN is entered incorrectly three times in a row, the card blocks itself and can not be used. It can only be unblocked with an 8-digit Personal Unblocking Key (PUK), which is also stored on the SIM card.

Base Transceiver Station (BTS) - The BTS is the Mobile Station's access point to the network. It is responsible for carrying out radio communications between the network and the MS. It handles speech encoding, encryption, multiplexing (TDMA), and modulation/demodulation of the radio signals. It is also capable of frequency hopping. A BTS will have between 1 and 16 Transceivers (TRX), depending on the geography and user demand of an area. Each TRX represents one ARFCN.
One BTS usually covers a single 120 degree sector of an area. Usually a tower with 3 BTSs will accomodate all 360 degrees around the tower. However, depending on geography and user demand of an area, a cell may be divided up into one or two sectors, or a cell may be serviced by several BTSs with redundant sector coverage.
A BTS is assigned a Cell Identity. The cell identity is 16-bit number (double octet) that identifies that cell in a particular Location Area. The cell identity is part of the Cell Global Identification (CGI), which is discussed in the section about the Visitor Location Register (VLR).
120 ° Sector
The interface between the MS and the BTS is known as the Um Interface or the Air Interface.

Um Interface
Base Station Controller (BSC) - The BSC controls multiple BTSs. It handles allocation of radio channels, frequency administration, power and signal measurements from the MS, and handovers from one BTS to another (if both BTSs are controlled by the same BSC). A BSC also functions as a "funneler". It reduces the number of connections to the Mobile Switching Center (MSC) and allows for higher capacity connections to the MSC.
A BSC my be collocated with a BTS or it may be geographically separate. It may even be collocated with the Mobile Switching Center (MSC).

Base Station Controller
The interface between the BTS and the BSC is known as the Abis Interface

Abis Interface
The Base Transceiver Station (BTS) and the Base Station Controller (BSC) together make up the Base Station System (BSS).

Base Station System
Mobile Switching Center (MSC) - The MSC is the heart of the GSM netowrk. It handles call routing, call setup, and basic switching functions. An MSC handles multiple BSCs and also interfaces with other MSC's and registers. It also handles iner-BSC handoffs as well as coordinates with other MSC's for inter-MSC handoffs.

Mobile Switching Center
The interface between the BSC and the MSC is known as the A Interface

A Interface
There is another important type of MSC, called a Gateway Mobile Switching Center (GMSC). The GMSC functions as a gateway between two networks. If a mobile subscriber wants to place a call to a regular landline, then the call would have to go through a GMSC in order to switch to the Public Switched Telephone Network (PSTN).

Gateway Mobile Switching Center
For example, if a subscriber on the Cingular network wants to call a subscriber on a T-Mobile network, the call would have to go through a GMSC.

Connections Between Two Networks
The interface between two Mobile Switching Centers (MSC) is called the E Interface

E Interface
Home Location Register (HLR) - The HLR is a large database that permanently stores data about subscribers. The HLR maintains subscriber-specific information such as the MSISDN, IMSI, current location of the MS, roaming restrictions, and subscriber supplemental feautures. There is logically only one HLR in any given network, but generally speaking each network has multiple physical HLRs spread out across its network.
Visitor Location Register (VLR) - The VLR is a database that contains a subset of the information located on the HLR. It contains similar information as the HLR, but only for subscribers currently in its Location Area. There is a VLR for every Location Area. The VLR reduces the overall number of queries to the HLR and thus reduces network traffic. VLRs are often identified by the Location Area Code (LAC) for the area they service.

Visitor Location Register
Location Area Code (LAC)
A LAC is a fixed-length code (two octets) that identifies a location area within the network. Each Location Area is serviced by a VLR, so we can think of a Location Area Code (LAC) being assigned to a VLR.
Location Area Identity (LAI)
An LAI is a globally uniqe number that identifies the country, network provider, and LAC of any given Location Area, which coincides with a VLR. It is composed of the Mobile Country Code (MCC), the Mobile Network Code (MNC), and the Location Area Code (LAC). The MCC and the MNC are the same numbers used when forming the IMSI.

Location Area Identity (LAI)
Cell Global Identification (CGI)
The CGI is a number that uniquely identifies a specific cell within its location area, network, and country. The CGI is composed of the MCC, MNC, LAI, and Cell Identity (CI)

Cell Global Identity
The VLR also has one other very important function: the assignment of a Temporary Mobile Subscriber Identity (TMSI). TMSIs are assigned by the VLR to a MS as it comes into its Location Area. TMSIs are unique to a VLR. TMSIs are only allocated when in cipher mode.
The interface between the MSC and the VLR is known as the B Interface and the interface between the VLR and the HLR is known as the D Interface. The interface between two VLRs is called the G Interface

B and D Interfaces
Equipment Identity Register (EIR) - The EIR is a database that keeps tracks of handsets on the network using the IMEI. There is only one EIR per network. It is composed of three lists. The white list, the gray list, and the black list.
The black list is a list if IMEIs that are to be denied service by the network for some reason. Reasons include the IMEI being listed as stolen or clonedor if the handset is malfunctioning or doesnt have the technical capabilities to operate on the network.
The gray list is a list of IMEIs that are to be monitored for suspicous activity. This could include handsets that are behaving oddly or not performing as the network expects it to.
The white list is an unpopulated list. That means if an IMEI is not on the black list or on the gray list, then it is considered good and is "on the white list".
The interface between the MSC and the EIR is called the F Interface.

Equipment Identity Register
Authentication Center (AuC) - The AuC handles the authentication and encryption tasks for the network. The Auc stores the Ki for each IMSI on the network. It also generates cryptovariables such as the RAND, SRES, and Kc. Although it is not required, the Auc is normally physically collocated with the HLR.

Authentication Center
There is one last interface that we haven't discussed. The interface between the HLR and a GMSC is called the C Interface. You will see it in the full network diagram below.This completes the introduction to the network architecture of a GSM network. Below you will find a network diagram with all of the components as well as the names of all of the interfaces.

Full GSM Network
| model | bands | field test enabling | ||||
| 2100 | ||||||
| 3210 | ||||||
| 3310 | 900 1800 | serial | ||||
| 3315 | ||||||
| 3330 | ||||||
| 3350 | ||||||
| 3390 | ||||||
| 3395 | ||||||
| 3410 | ||||||
| 3610 | ||||||
| 3810 | ||||||
| 5110 | 900 | serial | ||||
| 5130 | ||||||
| 5190 | 1900 | serial? | ||||
| 5210 | ||||||
| 5510 | ||||||
| 6110 | 900 | serial | ||||
| 6130 | ||||||
| 6138 | ||||||
| 6150 | ||||||
| 6190 | 1900 | serial? | ||||
| 6210 | ||||||
| 6250 | ||||||
| 7110 | ||||||
| 7190 | 1900 | keypad | ||||
| 8210 | ||||||
| 8250 | ||||||
| 8290 | 1900 | keypad | ||||
| 8810 | ||||||
| 8850 | ||||||
| 8855 | ||||||
| 8890 | 900 1900 | IR | ||||
| 9110 |
(Please update this page with your own experiences.)
The most important screen in field test mode is screen "01":
01
ARF RSI PCC
S TT Q MMM
C1 C2
CHAN
An excellent document covering field test mode/net monitor for Nokia phones is available | here
A description of the test is available | here
With the appropriate MBUS serial cable, DCT-3 phones can also log the LAPDm signaling they send and receive. Gammu is used to create the traces, which can then be displayed by Wireshark 1.1.2 or later. This procedure is detailed here, but briefly:
gammu --nokiadebug nhm5_587.txt v20-25,v18-19wireshark out.xmlLogo Express 3.1b did the work in Nokia 6110 with a serial cable http://www.geocities.com/wolfitdown/download.htm
This information is somewhat out of date. More accurate information will be put into the Trac milestones. When that is sufficiently complete, this page will be removed.
Our current development goals are:Loads on a 2.33 GHz core 2 duo Apple MacBook Pro are:
| num active lines | OpenBTS | transceiver | Asterisk | total | ||||||
| 0 | 0.5% | 33% | 0% | 34% | ||||||
| 1 | 3.3% | 37% | 1% | 41% | ||||||
| 2 | 6.0% | 40% | 1% | 47% | ||||||
| 3 | 7.8% | 44% | 1.1% | 52% | ||||||
| 4 | 11% | 46% | 1.4% | 58% |
These loads are percentages of a single core, so a fully loaded system is 200% on this scale.
In the transceiver, most of this load is in the demodulator. In the OpenBTS application, roughly half of this load is in L1 FEC decoding, with the rest spread around in other components.
These load figures do not include the vocoders, since these are GSM-to-GSM calls and no transcoding is required in the BTS. (The BTS is just forming a conduit for GSM vocoder frames.)
I don't have 7 test phones handy at the moment, but using a simple linear projection, the full-load computational requirement is:
| num active lines | OpenBTS | transceiver | Asterisk | total | ||||||
| 7 | 19% | 56% | 2.5% | 76% |
... or the equivalent of a single 1.8 GHz core.
Please, write down your own findings on how to tackle with this inceadibly huge specification. Estecially, where newcomer should start from.
Your notes here
The primary document for L2 is GSM 04.06, but that document assumes prior knowledge of HDLC.
Most of L3 specification is contained in Technical Specification (TS) 04.08.
But to understand message format descriptions you must read Section 11 and Annex B of TS 04.07, where required notation is introduced.
Releases are numbered and named. The release series 1.x, 2.x, etc. are based on the stages defined in OpenBTSPlan. Numeric sequences are chronological within each release series, but not across series. Names are taken from small towns in Louisiana and are chronological alphabetical, ignoring name prefixes like "Saint" and "New".
| Stage 1 | Basic Speech | |||||||||||||
| Number | Name | Release Date YYYY-MM-DD | GNU Radio SVN | Site | New Features | Bugs Fixed | ||||||||
| 1.0 | (none) | 2008-11-09 | pre-GNU | obsolete | completed L1, L2 | |||||||||
| 1.1 | Arnaudville | 2008-11-20 | r10019 | obsolete | MTC timeout | |||||||||
| 1.2 | Breaux Bridge | 2008-11-?? | r10088 ? | GNU FTP | GNU build, VEA ( |
|
||||||||
| 1.3 | Carencro | 2009-12-?? | N/A | obsolete | first injunction release | |||||||||
| 1.4 | Donaldsonville | 2009-12-?? | N/A | obsolete | fixed Ubuntu build errors | |||||||||
| 1.5 | Eunice | 2008-12-22 | N/A | obsolete | moved "abort" calls into L3 subclasses | fixed L2 bugs | ||||||||
| 1.6 | New Iberia | 2009-02-28 | r11641 | sf.net | import of 2.2 improvements to non-SMS release | |||||||||
| Stage 2 | Text Messaging | |||||||||||||
| Number | Name | Release Date YYYY-MM-DD | GNU Radio SVN | Site | New Features | Bugs Fixed | ||||||||
| 2.0 | St. Francisville | 2009-01-09 | N/A | obsolete | SMS, config file | |||||||||
| 2.1 | Grand Coteau | 2009-03-?? | N/A | obsolete | DTMF | Linux stack overflow | ||||||||
| 2.2 | Houma | 2009-03-10 | N/A | obsolete | LEGAL notice | several threading and clocking errors in the transceiver | ||||||||
| 2.3 | Jean Lafitte | 2009-04-22 | N/A | obsolete | CLI, logging, emergency calls | better TRX-stack clock sync | ||||||||
| 2.4 | Kinder | 2009-06-18 | r11656 | sf.net | neighbor lists | non-Asterisk SIP bugs | ||||||||
| 2.4.1 | Kinder | 2009-10-21 | r11657 | sf.net | several bugs cleaned up with valgrind | |||||||||
| 2.5 | Lacassine | 2009-11-30 | r11664 | sf.net | smqueue SMS server | GNU Radio 3.2 compatibility | ||||||||
| 2.5.1 | Lacassine | 2009-12-02 | TBD | sf.net | ||||||||||
| 2.6 | Mamou | TBD | TBD | TBD | limited RRLP, improved CLI config management, congestion management | DCT-4+ early assignment, timing advance bugs |
These are our ideas for future RF development. If you are working on the RF task, feel free to edit and comment in this document.
Bear in mind that this device may not need FCC certification in its intended deployments.
USRP -> tx filter -> PA -> duplexer -> cables and antenna
antenna and cables -> duplexer -> rx filter -> preamps -> USRP
Ticket #334 tracks the status of this work.
For omni cells, we can probably get a lot of service from marine cellular band antennas, built to be installed on boats and yachts. They are tough, efficient and only about $100 each. For sectorized installations, there are a number of panel style antennas on the market that should be suitable, including inexpensive designs built for the US 900 MHz ISM band.
We only want two connector types in our RF system: SMA for low power and N for high power.
OpenBTS integration with Asterisk is simple in principle: each SIM is configured in Asterisk as a SIP user, using the IMSI as the SIP user name.
So provisioning an OpenBTS subscriber has two steps:
# Get the IMSI from the SIM.
# Make the corresponding entries in sip.conf and extensions.conf to support the new SIP user.
There are several ways to get the IMSI for a SIM so that it can be programmed into Asterisk's configuration files. Which one you use will depend on the volume of SIMs you need to provision.
This is the easiest approach for small numbers of SIMs.
Whenever a handset tries to register with OpenBTS, it will send a mobile identity. You can force the handset to use the IMSI as its identity and then capture the IMSI from the OpenBTS console output when the handset tries to register. Here are the steps:
FACCHDispatch.cpp:53 ControlLayer FACCHDispatcher waiting for ESTABLISH RadioResource.cpp:87 ControlLayer AccessGrantResponder RA=27 when=0:7734 RadioResource.cpp:127 ControlLayer AccessGrantResponder sending PageMode=(0) DedicatedModeOrTBF=(TMA=0 Downlink=0 DMOrTBF=0) ChannelDescription=(typeAndOffset=SDCCH/4-3 TN=0 TSC=0 ARFCN=29) RequestReference=(RA=27 T1'=5 T2=12 T3=33) TimingAdvance=0 SDCCHDispatch.cpp:101 ControlLayer SDCCHDispatcher got MM Location Updating Request MobileIdentity=(IMSI=310410186585294) MobilityManagement.cpp:111 ControlLayer LocationUpdatingController MM Location Updating Request MobileIdentity=(IMSI=310410186585294) MobilityManagement.cpp:121 ControlLayer LocationUpdatingController waiting for registration MobilityManagement.cpp:137 ControlLayer LocationUpdatingController : SIPRegistration -> FAIL SDCCHDispatch.cpp:136 ControlLayer SDCCHDisptacher waiting for RELEASE SDCCHDispatch.cpp:97 ControlLayer SDCCHDisptacher waiting for ESTABLISH
RadioResource.cpp:152: AccessGrantResponder RA=0x15 when=0:1192710 age=25 TOA=0.0000 RadioResource.cpp:196: AccessGrantResponder sending PageMode=(0) DedicatedModeOrTBF=(TMA=0 Downlink=0 DMOrTBF=0) ChannelDescription=(typeAndOffset=SDCCH/4-0 TN=0 TSC=0 ARFCN=975) RequestReference=(RA=21 T1'=3 T2=12 T3=24) TimingAdvance=0 MobilityManagement.cpp:119: LocationUpdatingController MM Location Updating Request LAI=(MCC=901 MNC=55 LAC=0x29b) MobileIdentity=(TMSI=0x49ffcddd) MobilityManagement.cpp:172: LocationUpdatingController registration FAIL: IMSI=234100223456161
In either version, the SIP registration attempt will return "FAIL" because this IMSI is not yet provisioned in Asterisk.
If you're really clever, you'll write some kind of Python script to catch the log output and automatically update the Asterisk configuration files. If you do that, please share your scripts with the rest of us. That would make this technique applicable to very large numbers of SIMs in situations where acceptance rules can be applied based on the upper digits of the IMSI.
Many GSM devices support a Hayes-style "AT" command interface, defined in GSM 07.07. This interface supports the "AT+CIMI" command, described in GSM 07.07 Section 5.6, which will return the IMSI of the device's installed SIM.
This is a good approach if you have a device that affords easy SIM changes, like a MultiTech GSM modem and need to provision a few dozen subscribers.
Again, if you're really clever you'll write a script to automate that. And if you're a good person you'll share it with the rest of us.
If you need even larger numbers of SIMs provisioned you might consider ordering a batch of them with sequential IMSIs that can be easily programmed into Asterisk with a script.
To provision an IMSI into Asterisk you will need to modify two files: sip.conf and extensions.conf. These files are normally located in /etc/asterisk.
r310410186585294 canreinvite=no type=friend allow=gsm context=sip-external host=dynamic
[macro-dialGSM]
exten => s,1,Dial(SIP/${ARG1})
exten => s,2,Goto(s-${DIALSTATUS},1)
exten => s-CANCEL,1,Hangup
exten => s-NOANSWER,1,Hangup
exten => s-BUSY,1,Busy(30)
exten => s-CONGESTION,1,Congestion(30)
exten => s-CHANUNAVAIL,1,playback(ss-noservice)
exten => s-CANCEL,1,Hangup
;; the name in the brackets is the context, it should be the same with the context line in sip.conf [sip-external] exten => 2103,1,Macro(dialGSM,310410186585291)
exten => _5XXX,1,Macro(dialGSM,310410186585${EXTEN:-3})
We have evaluated OpenBTS 2.5 (trunk) with FreeSWITCH 1.0.4. There are a few things to consider to get the setup running:
OpenBTS acts as a SIP client that registers into FreeSWITCH. You need to change OpenBTS.Config to match the IP address of your internal or external default profiles. If you use the external profile make sure that the port number is 5080 and not 5060. FreeSWITCH needs to be have a profile that accepts the registration without requesting authentication. If you try to register OpenBTS with FreeSWITCH, you want to make sure that 401 (Unauthorized) or 407 (Proxy Authentication Required) are not requested.
OpenBTS has a very minimal SIP stack, so make sure that FreeSWITCH accepts the registration blindly.
One alternative is to use IP CIDR to ensure that only OpenBTS is accepted. Create a new entry in the directory to allow local registrations (registrations that come from the very same server) blindly
<include>
<user id="31041464646464646" cidr="192.168.46.15/24">
<params>
<param name="vm-password" value="461000"/>
<param name="accept-blind-reg" value="true"/>
<param name="accept-blind-auth" value="true"/>
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local"/>
<variable name="accountcode" value="31041464646464646"/>
<variable name="user_context" value="default"/>
<variable name="effective_caller_id_name" value="Extension 461000"/>
<variable name="effective_caller_id_number" value="461000"/>
<variable name="outbound_caller_id_name" value="$${outbound_caller_name}"/>
<variable name="outbound_caller_id_number" value="$${outbound_caller_id}"/>
<variable name="callgroup" value="techsupport"/>
</variables>
</user>
</include>
Another issue that you need to consider is the codec, the current implementation of OpenBTS supports GSM. Make sure that your profile accepts GSM as default codec. If your audio sounds like dropping dozen of wine glasses against the floor, it might the case that FreeSWITCH is sending PCMU audio to the phone. Not good! :) There is a bug around (20090917) that should be fixed soon in trunk.
The third issue to deal with is DTMF detection. OpenBTS provides DTFM to FreeSWITCH as INFO SIP Messages. DTMF are sent to FreeSWITCH as Signal=Number {0-12} where 11 is * and 12 is #. FreeSWITCH expects the * and # as Signal=* and not Signal=11. There is a bug around (20090917) that should be fixed soon in trunk that relates to multiple DTMFs in a single call. The CSeq field in the SIP Message needs to increments per DTMF or the DTMF are not properly detected by FreeSWITCH (in fact, it will only detect the first one!).
If you are working with OpenBTS and FS drop me a line, check for my address in http://www.it46.se/contact
Smqueue is an RFC-3428 store and forward server, used to support SMS in OpenBTS installations. Smqueue runs alongside Asterisk to provide SMS routing service. Smqueue is distributed with OpenBTS releases 2.5 and later. It uses parts of the OpenBTS source code, but has very different build dependencies and may be run on a different machine than the one used to run OpenBTS. Because of these different build and installation requirements, smqueue is not part of the normal GNU build process for the rest of the OpenBTS application.
To build smqueue, go to the smqueue directory and type "make -f Makefile.standalone". That's it. You do not have to run the OpenBTS configure script to do this. If you get build errors, it is probably due to having an out-of-date osip2 installation. You need osip2 release 3.3 or later.
As of release 2.5, smqueue uses the Asterisk SIP registry for address resolution and message routing. Therefore smqueue must be run as root and must run on the same machine as your Asterisk server.
The original version of smqueue was written by John Gilmore and used for the experimental SMS system at Burning Man 2009.
The OpenBTS application implements SMS delivery over the air interface. It does not, on its own, provide any mechanism for store and forward handling of text messages. This document describes the proper SMS interface for OpenBTS and the "smqueue" application that will provides the store and forward function. Smqueue is not intended to be a complete SMSC, but does serve the purpose of an SMSC in OpenBTS networks.
To deliver a text message to the MS through OpenBTS, smqueue sends to OpenBTS a SIP MESSAGE request addressed to the destination user's IMSI and containing the message string. OpenBTS will attempt to deliver the message as the payload of an RP-DATA message, as described in GSM 04.11 Section 6. If delivery is successful, as determined by the receipt of an RP-ACK message from the MS, OpenBTS will respond with 200 OK. If delivery fails with an RP-ERROR message from the handset, OpenBTS will respond with a corresponding SIP error response. However, the most common delivery failure will be when the handset does not respond to paging, in which case OpenBTS will not produce any response at all.
When an MS sends a text message though OpenBTS, it will do so by sending the message string as the payload in an RP-DATA message, as per GSM 04.11. OpenBTS will decode the SIP headers to determine the destination address of the message. OpenBTS will then submit a SIP MESSAGE request to smqueue, addressed to the E.164 address of the destination user and containing the message string. Smqueue responds with 202 Accepted, which OpenBTS then relays to the MS as an RP-ACK message.
Needs to be completed.
Messages with destination ISDN addresses to not corresponding to known IMSIs in the HLR are set aside for special handling.
A full SMS implementation would include delivery reports to the original sender of a message reporting the final success or failure of a message. Such reports would be generated whenever a subscribed-originated message is deleted from the messages table.
We need handling for non-numeric SIP destinations. Another candidate for a short code function.
GSM 03.40 Section 3.8 describes internetworking between SMS and internet electronic mail at the transport layer.
Smqueue should support this feature.
A short code is a destination ISDN address inside the SMSC that corresponds to a special function that acts on the message content. A well-known example of a short code is the 40404 address through which North American cellular subscribers can submit messages to Twitter.
The smqueue application can implement short code functions by registering those functions in a map (associative array) indexed by short code. Each short code function takes two arguments, the message string and the IMSI of the sender.
As of release 2.5, smqueue implements the following short code applications in smcommands.cpp:
Messages addressed to normal E.164 addresses not in the HLR should be sent to an outside SMSC for delivery through standard GSM mechanisms. Smqueue will also (eventually) need to interface to standard SMSCs to accept incoming SMS from standard GSM sources. Both types of interfacing should be possible with Kannel.
Useful documents:While OpenBTS is much simpler than a conventional GSM system, it is admittedly more complex to install and configure than a typical desktop application. If you don't have a working knowledge of GSM, Unix, and VoIP, all at the same time, you might have problems getting your system to work. Help is available.
(A lot of this comes from the GNU Radio GettingHelp wiki page.)
Free support for OpenBTS is available from this wiki and through the public mailing list openbts-discuss (at) sourceforge.net. You can subscribe at https://lists.sourceforge.net/lists/listinfo/openbts-discuss.
Please read the wiki carefully and search the list archives before posting.
If you ask a question from the FAQ or documentation on the mailing list, it will probably be ignored.
Your problem might be that you need to learn more about the things that OpenBTS uses, rather than an issue with OpenBTS itself. If it turns out that you have a general question about C++, Unix, Asterisk, the USRP or some other technology, please consider asking your question in a forum dedicated to the engineering discipline that you need help with. If your question is specifically about OpenBTS, GSM, or closely related concepts, discuss-openbts is probably the best forum you can ask, but try to answer your question using the GSM specifications themselves and the Web first.
How To Ask Questions The Smart Way has excellent guidance on this question. The following are the most commonly violated principles. These rules might differ from what you're used to at work or at school, particularly if your organization uses Outlook or PDAs. They are conventions that Unix users and Usenet have followed since at least the 1980s, and your messages are more likely to be answered if you follow them.
Often the reason the question has not been answered is that it appears as if the questioner has not followed the suggestions on this page. By following the suggestions on this page, you will increase your chances of getting an answer.
Questions often don't receive an answer until days after they were posted. While you are waiting, please continue to work on your problem yourself; mail the list if you find a solution. Don't re-post the same question to the list and don't ask it directly to someone whose email address you got from the list. Please remember that participants offer support through the discussion list as a courtesy, not an obligation. They have their own problems to work on most of the time.
One big difference between open source and proprietary software is that in the open source world, people will ignore your problems for free. But if you are in a hurry or have a commercial project dependent on OpenBTS, you should consider actually paying someone for their time instead of just depending on the kindness of strangers. Income from paid support is part of what makes this project possible.
Kestrel Signal Processing, Inc., the commercial home of OpenBTS, provides the following services:
For more information, contact dburgess (at) kestrelsp.com. Kestrel can also provide customizations of OpenBTS under licenses other than GPL. When contacting Kestrel through e-mail, please be sure to put "openbts" (all lowercase) in the subject line. Please do not contact Kestrel directly seeking free support.
Note that GNU/FSF does not endorse Kestrel, but the simple fact is that they maintain the project and wrote most of the source code.
You may also find developers available for contract-based support on the openbts-discuss mailing list. These developers may be able to provide many of the services listed above, with the exception of non-GPL licensing. (And if you are such a developer, feel free to put your contact information on this wiki page.)
You can download PDF version of standards from ETSI web site. The best way I found to do this is using ETSI Standards Search:
1. Open ETSI Standards Search page in your browser.
1. Enter standard number, e.g. "04.08" in "Search for" field. Make sure that "exact expression" is selected in the radio-box on the right and all check-boxes are unchecked. You may also wish to select "All on 1 page". Then press "Search" button.
1. Search for the latest standard available. Latest GSM standards belong to so called "Phase 2+" and their name starts with "Digital cellular telecommunications system (Phase 2+)" and usually have several revisions (aka versions). Usually latest version is 7.xx.xx.
1. Click "Download" on right-up to the standard name.
1. If you haven't registered, register your e-mail (it's free!), and then you'll need to just enter your e-mail and click "Submit" - you'll be forwarded to reqested standard download page.
If you prefer MS Word files, you can get them from (in Zipped form) from 3GPP site: http://www.3gpp.org/ftp/Specs/archive/ Archives are named like xxyy-abc.zip for the standard XX.YY with version A.B.C. E.g. for 04.07 version 7.3.0: http://www.3gpp.org/ftp/Specs/archive/04_series/04.07/0407-730.zip
Detaied information on the version history, etc can be obtained at these pages: http://www.3gpp.org/ftp/Specs/html-info/
E.g. page for 04.07 is at http://www.3gpp.org/ftp/Specs/html-info/0407.htm
Especially useful (but huuuge) page is this: http://www.3gpp.org/ftp/Specs/html-info/SpecReleaseMatrix.htm Here you can find full list of standards with their revision history.
Note: It seems that 3GPP downloads offer more recent versions for some parts of the standard. E.g. latest version of 04.08, available from ETSI is v7.7.1, while 3GPP offers v7.21.0 (see here)
There seem to be ready to go solution for autoregistration available within Asterisk. Just add "autocreatepeer=yes" to the general part with some extra lines to /etc/asterisk/sip.conf and it is working ok! See http://www.voip-info.org/wiki/page_history.php?page_id=685
for the Asterisk developer who earn the credits for adding this option to Asterisk.
[general]
allowoverlap=no ; Disable overlap dialing support. (Default is yes)
bindport=5060 ; UDP Port to bind to (SIP standard port is 5060)
bindaddr=0.0.0.0 ; IP address to bind to (0.0.0.0 binds to all)
srvlookup=yes ; Enable DNS SRV lookups on outbound calls
; lines for automatic sim registration
autocreatepeer=yes
canreinvite=no
call-limit=1
type=friend
allow=gsm
context=sip-internal
host=127.0.0.1 ; the assumption is that OpenBts and Asterisk bth run on the same machine
This [general] part is from a working system. Originally the autocreatepeer=yes is mend for the scenario where a dedicated registrar like kamailio/openser is in front of Asterisk and Asterisk can accept any request for registring a peer because the authentication already took place. In combination with the hotdesk routine I added to the wiki this is actually working great.
Be aware of the fact that the context "sip-internal" has to be part of your dialplan or you have to adjust this line in sip.conf so the
context fits with an available extension in the dialplan. Using this option without further authentication with number and pincode before
calling out introduces a great security risk. I guess you don't want people freely to register to your OpenBTS network and have the
permission to make outbound calls s be carefull. Context sip-internal should offer only the permission to log in. I hope this is helpfull
Be aware of the legal framework you have to comply to. What is explained might not be allowed in your country. Don't end up in jail or spending vacation money on penalties!
\Erik
GSM uses Time Division Multiple Acces (TDMA) as its access scheme. This is how the MS interfaces with the network. TDMA is the protocol used on the Air (Um) Link. GSM uses Gaussian Minimum-Shift Keying (GMSK) as its modulation methos.
Time Division means that the frequency is divided up into blocks of time and only certain logical channels are transmitted at certain times. Logical channels will be introduced in the next lesson.The time divisions in TDMA are known as Time Slots.
Time Slots
A frequency is divided up into 8 time slots, numbered 0 to 7.

Time Slots
On a side note, also remember that GSM carrier frequencies are separated by 200kHz and that GSM operates in duplex. A channel number assigned to a pair of frequencies, one uplink and one downlink, is known as an Absolute Radio Frequency Channel Number (ARFCN). For a review of the ARFCN go to the Introduction to GSM Tutorial.
Each time slot lasts 576.9 µs. A time slot is the basic radio resource used to facilitate communication between the MS and the BTS.

Time Slot Duration
As stated earlier, GSM uses Gaussian Minimum-Shift Keying (GMSK) as its modulation method. GMSK provides a modulation rate of 270.833 kilobits per second (kb/s).
At that rate, a maximum of 156.25 bits can be transmitted in each time slot (576.9 µs).
Math:
270.833 kb/s × 1000 = 270,833 bits/sec (Converting from kilobits to bits)
270,833 b/sec ÷ 1,000,000 = .207833 b/µs (Calculating bits per miscrosecond)
.207833 b/µs × 576.9 µs = 156.25 bits (Calculating number of bits per time slot)
So, 156.25 bits can be transmitted in a single time slot

Bits per Time Slot
The data transmitted during a single time slot is known as a burst. Each burst allows 8.25 bits for guard time within a time slot. This is to prevent bursts from overlapping and interfering with transmissions in other time slots. Subtracting this from the 156.25 bits, there are 148 bits usable for each burst.
There are four main types of bursts in TDMA:
Normal Burst (NB)
Frequency Correction Burst (FB)
Synchronization Burst (SB)
Access Burst (AB)
Normal Burst
The data transmitted during a single time slot is known as a burst. Each burst allows 8.25 bits for guard time. This is to prevent bursts from overlapping and interfering with transmissions in other time slots.
Out of 156.25, this leaves 148 bits usable for each burst.
Here is the structure of a normal burst:

Burst
Tail Bits - Each burst leaves 3 bits on each end in which no data is transmitted. This is designed to compensate for the time it takes for the power to rise up to its peak during a transmission. The bits at the end compensate for the powering down at the end of the transmission.
Data Bits - There are two data payloads of 57 bits each.
Stealing Flags - Indicates whether the burst is being used for voice/data (set to "0") or if the burst is being "stolen" by the FACCH to be used for singalling (set to "1"). *The FACCH is discussed in the Logical Channels Tutorial
Training Sequence - The training sequence bits are used to overcome multi-path fading and propagation effects through a method called equalization.
*Note: 3GPP TS 45.001 Standard does not describe stealing bits, and instead allows for two 58-bit data payloads in a burst. However, it is common practice in GSM networks to use 57-bit payloads and stealing bits.
This diagram illustrates a single burst inside a time slot. Remember that 8.25 bits are not used in order to allow for a guard time.

Burst within a Time Slot
Since each burst has two 57-bit data segments, we can see that a single burst has a data payload of 114 bits.
This burst is used for frequency synchronization of the mobile station. It is an unmodulated carrier that shifts in frequency. It has the same guard time as a normal bit (8.25 bits). The broadcast of the FB usually occurs on the logical channel FCCH.
*The FCCH is discussed in the Logical Channels Tutorial

Frequency Correction Burst
This burst is used for time synchronization of the mobile. The data payload carries the TDMA Frame Number (FN) and the Base Station Identity Code (BSIC). It is broadcast with the frequency correction burst. The Synchronization Burst is broadcast on the Synchronization Channel (SCH).
*The SCH is discussed in the Logical Channels Tutorial

Synchronization Burst
This burst is used the by mobile station for random access. It has a much longer guard period (68.25 bits compared to the 8.25 bits in a normal burst). It is designed to compensate for the unknown distance of the mobile station from the tower, when the MS wants access to a new BTS, it will not know the correct Timing Advance.
*The RACH is discussed in the Logical Channels Tutorial

Access Burst
Since each burst has two 57-bit data segments, we can see that a single burst has a data payload of 114 bits.
Each burst lasts 576.9 µs, so we can calculate the theoretical bit rate of a single time slot:
114 bits ÷ 576.9 µs = .1976 bits/µs (Calculating bits per µs)
.1976 bits/µs × 1,000,000 = 197,607 bits/sec nbsp; (Converting µs to sec)
Since there are 8 time slots per carrier frequency, each time slot would only get 1/8 of this bit rate, so...
197,607 bits ÷ 8 = 24,700 bits (Calculating bit rate for one of eight time slots.)
24,700 bits ÷ 1000 = 24.7 kbits/sec (Converting bits to kilobits)
So, using GMSK modulation there is a maximum bit rate of 24.7 kb/s for a single time slot. Note that this bit rate does not account for any error correction bits. Any bits used for error correction would have to be stolen from the 114-bit data payload of each burst.

A TDMA Frame
Multiframe
A Multiframe is composed of multiple TDMA frames.
There are two types of multiframes:
Control Channel Multiframes
Traffic Channel Multiframes
*Control Channels and Traffic Channels are explained in Logical Channels Tutorial.
Control Channel Multiframe
composed of 51 TDMA frames
duration = 235.4 ms

Control Channel Multiframe
Traffic Channel Multiframe
composed of 26 TDMA frames
duration = 120 ms

Traffic Channel Multiframe
Here is a diagram comparing the Control Channel multiframe and a traffic channel multiframe.

Traffic Channel and Control Channel Multiframes
The next diagram shows a Traffic Channel (TCH) Multiframe with TS2 (green) being allocated to a Mobile Station (MS). The red arrow indicates the sequence of transmission. The sequence starts in TDMA frame 0 at TS0, proceeds through all eight time slots, then starts again with TDMA frame 1.
In this example, the MS has been allocated a Traffic Channel in TS2. Therefore the MS will only transmit/receive during TS2 of each TDMA frame.

Single Time Slot Allocated
A Superframe is composed of multiple Multiframes.
Again, there is a superframe for Control Channels and one for Traffic Channels.
Control Channel Superframe
composed of 26 Control Channel (CCH) multiframes (each CCH multiframe has 51 TDMA frames)
duration = 6.12 seconds
Traffic Channel Superframe
composed of 51 Traffic Channel (TCH) multiframes (each TCH) multiframe has 26 TDMA frames)
duration = 6.12 seconds
Each superframe, whether it is a CCH or TCH frame, consists of 1326 TDMA frames (51 * 26)
*Note: The CCH and TCH frame sequences will synchronize every superframe.
Hyperframe
A hyperframe is composed of 2048 superframes.
duration = 3h 28m 53s 76ms (12,533.76 seconds)
consists of 2,715,548 TDMA frames
Each TDMA frame is numbered according to its sequence within the hyperframe, starting from 0 and ending at 2,715,547.
The TDMA frame number within a hyperframe is abbreviated FN. The FN is one of the variables used in GSM encryption algorithms.
The following diagram shows the relationship between all of the various time segments introduced in this tutorial.

Relationship of All Time Segments

NOTA: Questa pagina è in fase di traduzione, per cui, potrebbe contenere errori grammaticali. Si consiglia di fare sempre affidamento alla pagina in inglese che è costantemente aggiornata. Ultimo aggiornamento 13 Agosto 2010.
OpenBTS® è una applicazione open-source per sistemi Unix che usa l’Universal Software Radio Peripheral (USRP) per realizzare l'interfaccia radio GSM ("Um") ai cellulari GSM ed usa il software Asterisk per connettere le chiamate. La combinazione dell’interfaccia GSM con il VoIP potrebbe formare le basi di un nuovo tipo di reti cellulari che potrebbero essere sviluppate ed implementare a costi notevolmente più bassi rispetto alle verdi tecnologie in sviluppo nel mondo.
In parole povere, noi stiamo lavorando su un nuovo tipo di rete cellulare che può essere installata ed implementata ad 1/10 del costo delle attuali tecnologie, ma che sarà comunque compatibile con la maggior parte dei cellulari attualmente sul mercato. Questa tecnologia può anche essere usata nelle applicazioni delle reti private ad un costo molto più basso e complesso del convenzionale GSM.
Le pagine sono qui organizzate per aree tematiche. Se tu hai qualcosa di utile da aggiungere, per favore fallo. Per modificare il wiki, tu puoi registrare un account oppure usare la username “guest” e la password “gnuradio”.
Prendi il codice sorgente del progetto tramite il git:
git://openbts.git.sourceforge.net/gitroot/openbts/openbts
Se aspetti un accesso in scrittura alla repository sf.net, per favore contatta dbrgess (at) kestrelsp.com per informazioni.

OpenBST是开源UNIX应用程序,使用通用无线电外设(USRP)去为标准GSM手机实现GSM空中接口 ,利用Asterisk软件交换机 连接不同的呼叫。用GSM通用接口组合VOIP隧道可以用来部署和操作各类蜂窝网络,大大地降低成本,来研发现有的各类技术标准。
简单地说,我们在用一种只需要现有技术的十分之一的成本,来布署蜂窝网络,然而将兼容大多数市场上已经在出售的手持设备(手机)。此技术和现有技术相比,以很低的成本和复杂度,用于私人网络应用(无线公用拨号技术网络交换机(PBX),快速部署,等等)。
本页在这里组织了一些话题区域。如果你有一些有用的内容,请加入。去编译这个wiki,你可以注册一个账号
获取本项目的源码通过svn:
*我们正在尝试移到git并且更新完成这些操作。现在,你可以用svn取出代码,但是可能不再允许更新。-- 2010/01/04 ( YYYY/MM/DD )
svn co http://gnuradio.org/svn/openbts/trunk/openbts
svn co http://gnuradio.org/svn/openbts/branches/releases/xx
*以上两个连接其实并不好用。可以直接到http://sourceforge.net/projects/openbts/
进行下载的下面页是在cygwin上的安装过程
OpenBTS 回答外部的SIP PBX 去实现呼叫交换功能.
We use the Burning Man festival as an opportunity to run test networks.
According to Ticket #91, the current way of displaying the graphical sinks (oscope, fft, waterfall, etc) are all done in Python without the use of C++ wxWidgets. There is apparently already an OpenGL version of the waterfall scope as Ticket #86 explains. It might be worth while to investigate getting all of these components to be written and optimized for OpenGL.
BBN has written 802.11 code under funding from DARPA.
After GNU Radio is installed, build it using bootstrap/configure/make install to the same prefix.
This has been tested on NetBSD, and reported to work on Linux.
The following has been reported working
Those experimenting with the code should be familiar with both GNU Radio and 802.11; this is not a good area for beginners.
The UW Quantum System Engineering Laboratory has written code for Magnetic Resonance Force Microscopy (MRFM) under funding from the Army Research Office. The code, with explanation and instructions, is available here.
Some of the code might be useful to other GNU Radio users.This is a page which users can use to let people know what sorts of things they are doing with GNU Radio and/or the USRP. We have divided the users into various groups.
Please feel free to add your organization to this list. Even better would be to create a simple page with links to your work, info about your project, and how GNU Radio and/or the USRP have made your work possible or easier.
To edit this page, you'll need to log in. If you don't have your own account, please use the "guest" account and its password. If you don't know the guest password, please send mail to gnuradio-ops@gnuradio.org.
Commercial_(since 0.11
The default content for a new wiki page can be chosen from a list of page templates.
That list is made up from all the existing wiki pages having a name starting with PageTemplates/.
The initial content of a new page will simply be the content of the chosen template page, or a blank page if the special (blank page) entry is selected. When there's actually no wiki pages matching that prefix, the initial content will always be the blank page and the list selector will not be shown (i.e. this matches the behavior we had up to now).
To create a new template, simply create a new page having a name starting with PageTemplates/.
(Hint: one could even create a !PageTemplates/Template for facilitating the creation of new templates!)
Available templates:
TitleIndex(PageTemplates/)
----
See also: TracWiki
Date: Wed, 23 Jan 2008 12:25:20 -0800
From: Eric Blossom <eb@comsec.com>
Subject: Re: [Discuss-gnuradio] Enhancing Gnuradio Doxygen Generated Official Documentation
To: "Firas A." <firasmail2000@yahoo.com>
Cc: Discuss-gnuradio@gnu.org
Sender: discuss-gnuradio-bounces+eb=comsec.com@gnu.org
On Wed, Jan 23, 2008 at 11:42:50AM -0800, Firas A. wrote:
>
> Hi Eric,
>
> kindly, I have a question about the possibility to make the
> documentation changes to svn source files.
>
Firas (and everybody else!),
I'd prefer that you send us lots of relatively small changes, instead
of one big change in 15 days. This allows one of the committers to
take a quick look at the patch and apply it. Smaller patches take
less review from us, and are more likely to get applied right away.
This is the way we manage the software too.
Here's how to do it:
** check out the trunk
** edit the header file documentation or python doc strings, or whatever
** when you're happy with your changes send the output of
$ svn diff
to patch-gnuradio.
One of the committers will review the patch and if it looks good will
apply it to the trunk or will suggest changes.
Then you can update your copy of the trunk, and continue working. To
pipeline this process, checkout a new copy of the trunk in a different
directory and start working on your second set of changes in there.
Then when you send the diff, it'll be for the new changes only.
After we've seen a series of good patches from you that apply cleanly,
and follow our conventions, we can talk about getting you write
access to the repo.
Thanks again for your commitment to improving GNU Radio!
Eric
Date: Wed, 23 Jan 2008 13:02:11 -0800 From: Johnathan Corgan <jcorgan@corganenterprises.com> Subject: [Discuss-gnuradio] Patch submission guidelines To: "discuss-gnuradio@gnu.org" <discuss-gnuradio@gnu.org> Sender: discuss-gnuradio-bounces+eb=comsec.com@gnu.org None of the below are mandatory, but are some conventions to follow to help us more easily evaluate and apply a patch. These are not just for documentation patches, but for functionality as well: * Patches are submitted in the form of a SVN created diff, not individual files. * Diffs are made from the GNU Radio tree root, and are based on an SVN check out of the GNU Radio trunk. * The diff contains the minimal but related incremental changes, for all the files needing modification to implement the change. In other words, the diff should take a working GNU Radio source tree and modify it to become a working GNU Radio source tree with the feature implemented. * After applying the diff, the tests 'make check' and 'make distcheck' must both pass. * When relevant, QA code exists to automate unit testing of the new functionality. * There should be no additional compiler warnings to what already occurs. * No gratuitous whitespace changes. It does take time and practice to follow the above, so again, the above aren't rules, but more of a "scoring system" that will improve the chance of your contribution being accepted into the project. Incidentally, these are the same criteria that we review before we merge code from our developer branches into the trunk.
.
The Sony PlayStation 3 is the cheapest way to get access to a Cell Processor.
http://www.us.playstation.com/PS3/About
PortAudio (http://www.portaudio.com) provides a uniform programming interface to a variety of audio devices. For Windows users, it is a convenient way to get a working, full-duplex, soundcard interface for GNU Radio. Although PortAudio includes code to access Windows audio through DirectX, kernel streaming, ASIO, or WASAPI interfaces, performance with the traditional Windows "wave" interface is satisfactory for most GNU Radio purposes. This version is easily built under Cygwin and MinGW/MSYS. (These instructions should also work for Linux systems, but need to be tested.)
pa_snapshot.tgz from http://www.portaudio.com/download.html to /usr/src. Then:$ cd /usr/src $ tar -zxf pa_snapshot.tgz $ cd portaudio $ ./configure --disable-static $ make $ make install
PortAudio is installed under /usr/local/* by default.
portaudio-2.0.pc.in to change the line
Libs: -L${libdir} -lportaudio @LIBS@
Libs: -L${libdir} -lportaudio @DLL_LIBS@
./configure. This will prevent the linker from trying to include -luuid when building the gr-audio-portaudio DLL.
autoconf before doing ./configure/usr/local use the --prefix= option on ./configure (but be sure that GNU Radio's ./configure can find it)This page is meant to hold presentations on GNU Radio implementations and applications the people wish to make publicly available.
details of the new scheduler
Follow the instructions at:
"Retyped here for convenience (and in case link ever goes away). I also removed the last few pages of information regarding starting the X Server. This takes too many resources, and we're only interested in getting it on the network and running GNU Radio, anyway.
You'll want to have a USB/RF keyboard attached to the PS3 at this point.
yum install fftw-devel cppunit-devel libusb-devel sdcc alsa-lib-devel guile numpy wxPython
tar xjf swig-1.3.31.tar.gz cd swig-1.3.31 ./configure && make && sudo make install
ln -s /usr/bin/sdcc-sdcc /usr/bin/sdcc ln -s /usr/bin/sdcc-asx8051 /usr/bin/asx8051 ln -s /usr/bin/sdcc-sdcpp /usr/bin/sdcpp ln -s /usr/bin/sdcc-aslink /usr/bin/aslink
svn co http://gnuradio.org/svn/gnuradio/trunk cd trunk ./bootstrap ./configure make sudo make install
Audio is an unresolved issue. Success was reported with native PS3 sound on Yellow Dog but not on FC6 yet.
An investigation on the use of the Atlas/Janus/Ozy hardware from the HPSDR project is underway. This is an open source (GPL) and open hardware project (contributions are covered by the TAPR [http://tapr.org] Open Hardware License The combination of boards mentioned here are available from TAPR. They are quite inexpensive for this level of hardware. Taken together they provide a USB2 interface to a 200 kHz wide baseband IF system with a pulse width modulator and codec for microphone and speaker connections. Bill Tracey (kd5tfd@XXXXewjt.com) is a GnuRadio user, HPSDR contributor, has a PS3, and is working on using this interface under Linux for several DSP projects including [http://gnuradio.org/trac/wiki]. and DttSP "h1. Using GNU Radio
The normal flow graph control in Python is broken and we haven't found a fix for it yet. (fixed in [6212":http://groups.yahoo.com/group/dttsp-linux]) However, the new method of running the scheduler and flow graphs is to use hier_block2s. This will eventually become the standard way of handling the flow graphs when version 3.2 is released, which deprecate hier_block. The hier_block2 work in the PS3, although there are a few bugs and unresolved issues. Most basic items work, though.
To test a GNU Radio example, use the example code found in:
gnuradio-examples/python/hier
Specifically, to test that the USRP works, run:
cd gnuradio-examples/python/hier/usrp ./usrp_siggen.py -T <A|B> -f <frequency>
There are some unresolved issues with the hier_block2's, but this simple example runs fine.
If you want to write code that takes advantage of the Cell SPE's,
you'll need the IBM SDK.
The SDK requires FC6.
yum install ed freeglut freeglut-devel libXmu-devel libXext-devel gcc make perl rsync flex byacc netpbm netpbm-devel mesa-libGL-devel mesa-libGLU-devel libX11-devel numactl numactl-devel* Follow the instructions starting on page 13 of ""Software Development Kit 2.1 Installation Guide"":http://www-304.ibm.com/jct01004c/systems/support/supportsite.wss/docdisplay?brandind=5000008&lndocid=MIGR-65726 * When you're ready to install, do:
./cellsdk install --nosim --nokernel ./cellsdk build --gcc
These are the quick and dirty instructions. If these don't make sense, take a look
Installing Fedora Core 6 on the [[PlayStation 3]] for additional background.
You'll want to have a USB/RF keyboard attached to the PS3 at this point.
# yaboot.conf generated by anaconda
boot=/dev/sda
init-message=Welcome to Fedora!\nHit <TAB> for boot options
partition=1
timeout=80
install=/usr/lib/yaboot/yaboot
delay=10
enablecdboot
enableofboot
enablenetboot
nonvram
mntpoint=/boot/yaboot
usemount
image=/boot/vmlinux-2.6.23
label=linux-23
read-only
initrd=/boot/initrd.img-2.6.23
append="video=720p rhgb quiet root=LABEL=/1"
image=/boot/vmlinuz-2.6.21-1.3194.fc7
label=linux-21
read-only
initrd=/boot/initrd-2.6.21-1.3194.fc7.img
append="video=720p rhgb quiet root=LABEL=/1"
These are the rawhide directories and are inconsistent with the use of SDK 3.0
$ sudo yum groupinstall "Development Tools" $ sudo yum install fftw-devel cppunit-devel libusb-devel guile boost-devel alsa-lib-devel numpy swig sdcc
/usr/libexec/sdcc on [http://www.fedoraproject.org Fedora":http://www.kernel.org/pub/linux/kernel/people/geoff/cell], and symlinks prefixed with sdcc- have been created in /usr/bin. This might be a problem for existing programs, but the solution is simply to add /usr/libexec/sdcc to your PATH before building GNU Radio:$ export PATH=/usr/libexec/sdcc:$PATH
svn co http://gnuradio.org/svn/gnuradio/trunk cd trunk ./bootstrap ./configure make sudo make install
FIXME update this
Follow the download and installation instructions
here.
You'll need to create an IBM ID if you don't already have one.
Note, the IBM SDK contains both free and non-free software.
We're only using the free stuff, and it should be possible to get the free stuff
without agreeing to IBM's non-free licenses. Perhaps somebody with some time can sort this
out.
Hint: They install
this repo file
in /etc/yum.repos.d/cellsdk-Fedora.repo
I think all the free stuff is in the CellSDK-Open-Fedora-* repository at the Barcelona Supercomputing Center.
Fedora 8 can be installed on the PS3. It has improved kernels, libraries, compilers, and more.
It is compatible with the Cell SDK 3.0 and it is easy enough to install on the PS3.
IT MUST BE INSTALLED IN TEXT MODE AS FOLLOWS:
You'll want to have a USB/RF keyboard attached to the PS3 at this point.
Disable any rawhide repositories in the files /etc/yum.repo.d as they are inconsistent with the use of SDK 3.0
$ sudo yum groupinstall "Development Tools" $ sudo yum install fftw-devel cppunit-devel libusb-devel guile boost-devel alsa-lib-devel python-devel numpy swig sdcc gsl-devel pygsl
/usr/libexec/sdcc on Fedora, and symlinks prefixed with sdcc- have been created in /usr/bin. This might be a problem for existing programs, but the solution is simply to add /usr/libexec/sdcc to your PATH before building GNU Radio:$ export PATH=/usr/libexec/sdcc:$PATH
svn co http://gnuradio.org/svn/gnuradio/trunk cd trunk ./bootstrap ./configure make sudo make install
FIXME update this
To successfully install all the correct tools on Fedora 8 the following additions to the SDK installation instructions are needed:
sudo yum install compat-expat1 yum-fastestmirror yum-skip-broken
sudo yum erase oprofile oprofile-debuginfo blas blas-devel numactl numactl-devel
sudo vi /etc/yum.repos.d/fedora.repo
and change the enable=1 to enable=0
sudo vi /etc/yum.repos.d/fedora-updates.repo
and change the enable=1 to enable=0
Follow the download and installation instructions
here.
You'll need to create an IBM ID if you don't already have one.
Following the successful COMPLETION of the installation (sudo /opt/cell/cellsdk verify gives all the right answers) do the following:
sudo vi /etc/yum.conf
and add a line
exclude=blas blas-devel oprofile oprofile-debuginfo numactl numactl-devel
sudo vi /etc/yum.repos.d/fedora.repo
and change the enable=0 you did above back to enable=1
sudo vi /etc/yum.repos.d/fedora-updates.repo
and change the enable=0 you did above back to enable=1
run
sudo yum update
just to make sure it is now checking all of the following repositories
fedora, fedora-updates, cellsdk-open, cellsdk-fedora, and cellsdk-extras-fedora.
make sure that the ppu32-gcc compiler is in your PATH, otherwise:
export PATH=/opt/cell/toolchain/bin:$PATH
Note, the IBM SDK contains both free and non-free software.
We're only using the free stuff, and it should be possible to get the free stuff
without agreeing to IBM's non-free licenses. Perhaps somebody with some time can sort this
out.
Hint: They install
this repo file
in /etc/yum.repos.d/cellsdk-Fedora.repo
I think all the free stuff is in the CellSDK-Open-Fedora-* repository at the Barcelona Supercomputing Center.
Now that you've got all the software installed and have discovered that compiling on the PS3
(or QS21 for that matter) takes nearly forever, please check out these instructions for CrossCompilingForCell.
It's how most of us do our actual Cell development.
To generate the firmware for the altera Cyclone FPGA on the usrp from the usrp verilog sourcecode you need Quartus II Web Edition version 5.1 or later.
Unfortunately this is not opensource, but there is a free download with from the altera website.
You also need to get a free license.
Download Quartus II Web edition
This is windows-only software.
At the time of this writing, version 5.1SP1 and version 6.0 seems to work fine for the usrp verilog code.
I don't think the 5.1SP1 version is still available for download (the 6.0SPx version is)
The files I downloaded and tested were:
quartusii_51_sp1_web_edition.exe
quartusii_60_sp1_web_edition.exe
There are several ways to run this software under linux.
Install Wine version 0.9.19 or later (a recent cvs version will probably also work).
(Older versions do not work, believe me, I tried. I even tried cxoffice.)
Now make sure you set the emulated operating system to windows 98.
(run winecfg and set Applicatios\default settings Windows to windows98)
If you emulate windows 2000 it will not work.
The problem is mainly that the licensing copy protection crashes.
I have allways found it strange that you need to install a very invasive kernel_mode licensing/copyprotection tool to install software which is free to download with a license that is free and forever renewable.
If you want to get rid of any old wine settings and applications you can just move ~/.wine to something else and run winecfg. It will generate a clean .wine folder including default registry settings for you.
Now run the quartus installer.
make sure you select at least the quartus core component and the cyclone device, the tutorials are also probably handy.
All other devices are not needed for the usrp.
You don't really need the extra options you get when you select the talkback feature, so you can disable it.
If you want to do timing analysis and stuff you should keep it selected.
Quartus Ii 5.1SP1 should run to completion without any trouble.
It might hang on the last screen. If you nothing happens for a very long time you can savely kill it with CRTL-C in the console which started wine.
Now you need to get and install the (free) license.
You can request it on the altera website.
To request a license you need your NIC ID.
NIC ID
The NIC ID is a 12-character hexadecimal string embedded in the
network interface card that Altera uses to uniquely identify the PC where
the software is installed.
nldudok1@quarkdeb:/$ /sbin/ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:B0:D0:AB:CC:BA
inet addr:192.168.0.1 Bcast:10.0.0.255 Mask:255.255.255.0
inet6 addr: fe80::213:ffff:aabb:ccdd/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:16137 errors:0 dropped:0 overruns:0 frame:0
TX packets:10640 errors:0 dropped:0 overruns:0 carrier:0
collisions:2 txqueuelen:1000
RX bytes:20428079 (19.4 MiB) TX bytes:898048 (877.0 KiB)
Interrupt:58 Base address:0xe400
/$ cd ~/.wine/drive_c/altera/quartusXXX/win/ ~/.wine/drive_c/altera/quartusXXX/win$ wine lmutil.exe hostid Invoking /usr/lib/wine/wine.bin lmutil.exe hostid ... lmutil - Copyright (c) 1989-2003 by Macrovision Corporation. All rights reserved. The FLEXlm host ID of this machine is ""00b0d0abccba 001122334455"" Only use ONE from the list of hostids. Wine exited with a successful status
Now you have the right NIC ID you can request a license on the altera website:
Go back to the quatus download page and click "Get Web Edition License"
Download Quartus and get web edition license
Fill out the form, including the NIC ID and a valid emailadres.
You should now get a licensefile by email.
Save the license file somewhere on you wine C-drive
for example:
~/.wine/drive_c/altera/
For any other licensing problems see the altera licensing document
Altera Software Licensing
/$ cd ~/.wine/drive_c/altera/quartusXXX/bin/ ~/.wine/drive_c/altera/quartusXXX/bin$ wine quartus.exe
Quartus 6.0 will open with a few errors:
error:This program is for windows NT only.
Click on OK.
error:Quartus II is not fully registered, with a list of problems.
Click on OK.
Quartus 5.1SP will not have these errormessage.
message:Quartus II help will only work if you have installed Internet Explorer 4.0 or higher.
I haven't worked on this error yet. It might go away if you install the wine gecko fake IE or find a way to install a real IE.
Quartus should now start with a license options screen.
Choose, "I have a valid license"
And direct it to C:\altera\ (or wherever you put the file) and choose the license file.
You can allways change the license file and options with the Tools menu\License setup.
Here you will also see the NICID you entered earlier.
Now you are ready to compile the usrp verilog code to a usrp????.rbf file.
The easiest way is to open the usrp quartus project file
gnuradiosrcdir/usrp/fpga/toplevel/usrp_std/usrp_std.qpf
(Note with the default wine configuration you Z: drive is the same as /)
If you want you can now try to set back the default settings of wine to windows 2000 and only run quartus.exe and quartus_sh.exe as windows 98.
I have not tried this though.
For this you have to run winecfg again.
Warning Untested:
Install a recent Qemu.
Make a new virtual machine and install windows 98 or windows 2000 or windows XP.
Download Quartus II (see above)
Install Quartus within the virtual machine.
Request a license file using the NICID of you virtual machine
In you virtual windows do:
Type ipconfig /all at a commandprompt.
The NIC ID is the physical address without the dashes. If
your PC has more than one network card, you can use any of the
cards’ NIC IDs as long as the selected network card is always
connected to the computer.
Now you have the right NIC ID you can request a license on the altera website:
Go back to the quatus download page and click "Get Web Edition License"
Download Quartus and get web edition license
Fill out the form, including the NIC ID and a valid emailadres.
You should now get a licensefile by email.
Save the license file somewhere on you qemu virtual C-drive.
Run quartus II from the start menu and choose "have valid license"
You could also choose request a license now. (This should work within Qemu if you have networking setup and working)
Install some flavour of VMware.
Make a new virtual machine and install windows 2000 or windows XP.
Download Quartus II (see above)
Install Quartus within the virtual machine.
Request a license file using the NICID of you virtual machine
In you virtual windows do:
Type ipconfig /all at a commandprompt.
The NIC ID is the physical address without the dashes. If
your PC has more than one network card, you can use any of the
cards’ NIC IDs as long as the selected network card is always
connected to the computer.
Now you have the right NIC ID you can request a license on the altera website:
Go back to the quatus download page and click "Get Web Edition License"
Download Quartus and get web edition license
Fill out the form, including the NIC ID and a valid emailadres.
You should now get a licensefile by email.
Save the license file somewhere on you vmware virtual C-drive.
Run quartus II from the start menu and choose "have valid license"
You could also choose "request a license now". (This should work within VMware if you have networking setup and working)
I have used the VMware method for a long time now. It works, is stable and the speed is usable.
But I don't like having to install a complete windows inside my linux machine just to run one program.
The same disadvantage goes for Qemu. (although Qemu itself is a very nice opensource product which I can recommend to anyone.)
The wine method doesn't need any microsoft components.
It is less stable though and only works if you emulate windows 98, which is not supported anymore by quartus II 6.0 and later.
I had a few crashes already, but also succesfull compiles (both with version 5.1SP1 and 6.0SP1)
I hope this is of help to others trying to develop opensource verilog code but who are forced to running closed-source windows programs.
Martin
Release 3.0 is the first release with the new repository, new build system, new Wiki, etc.
Next bug fix release.
Bux fix release.
Bug fix release.
First maintenance release for 3.2 series.
The BuildGuide has the instructions for compiling and installing GNU Radio on your system.
source:/gnuradio/branches/releases/3.0
Releases tagged:
Bug Fixes:
Minor Enhancements:
Documentation:
Build System:
Miscellaneous:
(none)
The BuildGuide has the instructions for compiling and installing GNU Radio on your system.
source:/gnuradio/branches/releases/3.1
Releases tagged:
Removed the wobbly bits (r6622:6624, r6626:6627):
The BuildGuide has the instructions for compiling and installing GNU Radio on your system.
?
GNU Radio is a large, complex project. Working with it requires patience and skill. The GNU Radio community are helpful people, but they expect you to try to help yourself. Questions that demonstrate that you've done your homework are more likely to elicit a response. Also, please remember that no one gets paid to answer your questions. Your question might go unanswered for days or even weeks, or even forever, even if it's a good question.
There's a lot of advice in this document. It might seem unfair to be expected to put so much work into asking questions in a specific way. However, consider this: Questions you ask on this list reach hundreds of expert engineers with decades of experience in communication, signal processing, and related fields. If you have a good question and ask it well, you are likely to get many of them to spend a lot of time thinking it through, responding, and possibly doing additional work for you, all for free. Consultants with the same levels of experience are quite expensive.
First, install a clean installation of the current GNU Radio code from git, using the exact steps given in the documentation at the following two links, and see if your issue persists. At this point, most of the people on the GNU Radio mailing list are interested in improving the state of the art, not in supporting earlier releases or debugging integration issues caused by unusual customized installations.
Next, check whether you can help yourself or someone else has had the same issue that you're dealing with.
If nothing listed above helps you address your specific question or problem, your next step is to make sure that you're generally familiar with GNU Radio and the USRP. If you ask a question from the FAQ or documentation on the mailing list, it will probably be ignored.
Finally, you should have some understanding of the components involved in GNU Radio and their theoretical underpinnings. Your problem might be that you need to learn more about the things that GNU Radio uses, rather than an issue with GNU Radio itself. If it turns out that you have a general question about Python, C++, Unix, basic signal processing, FPGA design, analog RF electronics, or some other technology, please consider asking your question in a forum dedicated to the engineering discipline that you need help with. If your question is specifically about GNU Radio, the USRP series, or closely related concepts in software-defined radio, discuss-gnuradio is probably the best forum you can ask, but try to answer your question using textbooks and the Web first. A list of reference texts is available at SuggestedReading.
You're most likely to get a helpful response on the mailing list if you ask nicely and provide enough information for us to diagnose the problem. Read and understand How To Ask Questions The Smart Way. At the very least, we need to know: * How did you invoke the code that isn't working? (If you ran a program, we need to know the entire command line, and the output of "printenv" might help; if you're calling preexisting code from your own program, we need your code or at the very least the lines of code that are failing; if your problem is with a GRC flowgraph, please provide both the .grc XML file and the .py code that GRC generates for your flowgraph.) * What error messages did you get, if any? * How did the behavior of your code differ from what you expected? * What GNU Radio software has worked for you so far, if any? Try some of the examples, e.g. usrp_fft.py. * If you got abnormal output from a GUI program, save it or make a screen shot, put it on a Web or FTP server, and give us a link to it.
Some GNU-Radio-specific things that we'll need to know are:
How To Ask Questions The Smart Way has excellent guidance on this question. The following are the most commonly violated principles. These rules might differ from what you're used to at work or at school, particularly if your organization uses Outlook or PDAs. They are conventions that Unix users and Usenet have followed since at least the 1980s, and your messages are more likely to be answered if you follow them.
Questions often don't receive an answer until days after they were posted. While you are waiting, please continue to work on your problem yourself; mail the list if you find a solution. Don't re-post the same question to the list and don't ask it directly to someone whose email address you got from the list. Do not "bump" your message either.
Often the reason the question has not been answered is that it appears as if the questioner has not followed the suggestions on this page. By following the suggestions on this page, you will increase your chances of getting an answer.
If you're in a serious hurry or your question to the mailing list has gone a couple weeks without an answer and you're completely stumped, your only recourse is to hire a consultant. This will be expensive. There are quite a few communications sytem design and signal processing consultants out there; GNU Radio does not specifically endorse any of them, but at least one of the maintainers of GNU Radio is sometimes available for consulting work: Corgan Enterprises.
Helpers need some candy from time to time. If you found some support helpful, say so. You'll get extra karma points for thanking.
Though GNU Radio was first thought of for being a software defined radio (SDR) platform capable of receiving or transmitting arbitrary waveforms such as to take the airwaves back to the people, the development of the software has lent itself very useful for the possiblity of abstracting statistical RF channel models for simulations.
For what purpose would this be a good idea? Who needs simulation, you ask?
When designing adaptive equalizers or RAKE receivers, it might be good to know the typical performance given a specific channel type. For some cases - such as dense areas like urban settings it might be better to use one setting versus another.
I think that RF channel simulation blocks, though boring and possibly not quite as exciting as some of the other blocks, will bring GNU Radio to the forefront of SDR development and might possibly lead to the software package being used more commercially.
The Flex400 uses 2 of the ADF4360-7 VCO/PLL chips from Analog Devices, one on TX and one on RX. The way the board is designed, the output frequency of the VCO/PLL is divided by 2 to give the actual channel frequency. For example, since the RFX400 covers 400-500 MHz, the VCO/PLL actually tunes from 800-1000 MHz. If you want to cover 136-174MHz, you would have to design for 272-348 MHz.
The frequency range of the ADF4360-7 is controlled by 2 inductors, L31 and L32 on RX, and L105 and L116 on TX. They are 0402-sized, and ship with 4.3nH installed. The ADF4360-7 datasheet has instructions on how to select the inductors for your desired frequency range. If you are ordering the inductors, I would suggest not only ordering the value you think you need, but also ordering at least one bigger and one smaller value since the calculations in the datasheet are not exact.
Other things to note:
This page links to various source of sample data.
Please add more!
bzip2'd NOAA-12 data, binary little endian complex<float>, Fs = 250kS/s,
Date: Sun, 10 Dec 2006 12:11:55 +1030 From: Berndt Josef Wulf <wulf@ping.net.au> Subject: Re: [Discuss-gnuradio] APT signals To: discuss-gnuradio@gnu.org Organization: NTC-Electronics Sender: discuss-gnuradio-bounces+eb=comsec.com@gnu.org G'day, I managed to capture the spectrum emitted by NOAA-12 for its entire pass; not quite sure anymore which one it was. Using a Diamond D130 discone antenna and a low noise broadband power amplifier (10-2000MHz, g=20dB, nf=3.5, po=+20dbm!!!) the signal was recorded utilizing the usrp_rx_cfile.py python script, a gain of 100, and decimation of 250 centered on 137.5MHz. It produced a very large file -rw-r--r-- 1 root wheel 1117519872 Dec 9 20:01 noaa-12.dat This a little more than 1GB!!!! and 419MB zipped. Do we have a place were it can be uploaded for other list members that are interested? My bandwidth isn't large enough to offer it to public from here. I was surprised how loud the signal was, considering the equipment used here, and how well the TVRX card performed. Now I'm really looking forward to shooting the big birds = geostationary satellites. BTW: Do we have an AFC block to compensate for doublershift or is this something we still need to implement? I looked through the documentation but failed to find anything there. cheerio Berndt
If you have a USRP, you will need the Small Device C Compiler (SDCC) in order to build the firmware. (If you don't have a USRP, you can skip this step.) The SDCC is available as a self-installing binary package for Windows. To install it:
(1) Download sdcc-2.9.0-setup.exe (2.9.0 under sdcc-win32) from http://sourceforge.net/projects/sdcc/files/ to a directory of your choice.
(2) Run sdcc-2.9.0-setup.exe. You must have administrator privileges; it is easiest if you use the same account you will use to build GNU Radio.
$ which sdcc
sdcc is displayed, you are done. Otherwise you need to add the path to sdcc to your PATH environment variable.~/.bash_profile (assuming you are using a bash shell) or by adding it to your Windows path. The command you need to add to your ~/.bash_profile is$ PATH="$PATH:/cygdrive/c/Program Files/SDCC/bin"
$ PATH="$PATH:/c/Program Files/SDCC/bin"
C:\Program Files\SDCC). To add sdcc to your Windows path:
* open the Windows control panel:
* go to Performance and Maintenance -> System to get the "System Properties" window
* click the "Advanced" tab and click "Environment Variables"
* select "Path" in the top pane and click "Edit"
* add C:/Program Files/SDCC/bin to the end of the variable value; if there is already something there, separate the new text from the old with ";"
* click "OK" in the "Edit Variable", "Environment Variables", and "System Properties" windows
* log out and log back in againPATH, you should start a new command window and repeat the which sdcc command to be sure that SDCC is found.
VPATH builds (i.e., configure run from another directory) or make distcheck because Cygwin symbolic links are not recognized by the Windows version of SDCC. If you want to do a VPATH build or make distcheck you can do one of the following:
readlink) and substitute copies of the target files (not tried, but should work).ln -s" and/or "$(LN_S)" to "cp -p" in the .a51.rel target.If you don't know where to start, look at the SuggestedReadingOrder page for some hints.
Hence most newcomers may only need to read through a small subset of the references. This page presents suggested reading order for newcomers coming from different backgrounds in order to get started quickly.
You may already be familiar with various programming languages. If you already know C++ and Python, you can directly start of with the signal processing side of things. Even if you know only C++, you can get a hang of Python really quickly; you may not be able to write idiomatic Python, but you can write C-like Python and do well enough. The following may be a good reading order for you:
If you don't need to mess with the FPGA or the hardware, you can safely skip the Electronics and Verilog sections.
If you don't need to deal with techniques requiring advanced RF topics or antenna design (e.g. MIMO etc.), you can safely skip the Radio and RF design section, although a skim of Wikipedia on the topic can't hurt. Given the DSP background above, it may be sufficient just to be aware of the following concepts: fading, multipath propagation, frequency up-conversion and down-conversion.
http://www.complextoreal.com/tutorial.htm may be a decent starting point for both, DSP basics, and Digital Communications, especially if you want to get started really quickly. Personally, overlooking minor typos, I thought the "Fourier Analysis Made Easy" tutorials were easy to read and explained some concepts pretty well.
This information should work for openSUSE 11.1, and also hopefully SuSE 10.1.
If you choose to use downloadable packages, get the most recent package version, then use rpm to install (rpm -ivh package_filename).
To install dependencies using the YAST2 package manager, issue "sudo /sbin/yast2" and a GUI will be brought up. Search for each package to install, find the correct package name, then hit the spacebar to mark it for installation.
sudo mkdir /usr/local/include/qwtplot3d (cd include; tar cf - . | (cd /usr/local/include/qwtplot3d; sudo tar xf -)) tar cf - lib | (cd /usr/local; sudo tar xf -)
Then follow instructions at BuildGuide.
SuSE 10.1 uses "udev" rather than "hotplug" to automatically handle plug/unplug events for usb devices. To allow users other than root to use the USRP, follow these directions.
Test Page
Placeholder for open tickets until dispositioned.
Before Trac 0.11, it was only possible to define fine-grained permissions checks on the repository browser sub-system.
Since 0.11, there's a general mechanism in place that allows custom permission policy plugins to grant or deny any action on any kind of Trac resources, even at the level of specific versions of such resources.
trac.ini:[trac] ... permission_policies = AuthzPolicy, DefaultPermissionPolicy, LegacyAttachmentPolicy [authz_policy] authz_file = /some/trac/env/conf/authzpolicy.conf [components] ... authz_policy = enabled
Note that the order in which permission policies are specified is quite critical,
as policies will be examined in the sequence provided.
A policy will return either True, False or None for a given permission check.
Only if the return value is None will the next permission policy be consulted.
If no policy explicitly grants the permission, the final result will be False
(i.e. no permission).
authz_file contains:WikiStart@* * = WIKI_VIEW PrivatePage@* john = WIKI_VIEW * =
john WIKI_VIEW jack WIKI_VIEW # anonymous has no WIKI_VIEW
Then:
- All versions of WikiStart will be viewable by everybody (including anonymous)
- PrivatePage will be viewable only by john
- other pages will be viewable only by john and jack
At the time of this writing, the old fine grained permissions system from Trac 0.10 and before used for restricting access to the repository has not yet been converted to a permission policy component, but from the user point of view, this makes little if no differences.
That kind of fine-grained permission control needs a definition file, which is the one used by Subversion's mod_authz_svn.
More information about this file format and about its usage in Subversion is available in the Subversion Book.
[/] * = r [/branches/calc/bug-142] harry = rw sally = r [/branches/calc/bug-142/secret] harry =
<pre> [trac] authz_file = /path/to/svnaccessfile </pre> if you want to support the use of the @[@_modulename_@:/@_some_@/@_path_@]@ syntax within the @authz_file@, add <pre> authz_module_name = modulename </pre> where _modulename_ refers to the same repository indicated by the @repository_dir@ entry in the @[trac]@ section. *Note:* Usernames inside the Authz file +must+ be the same as those used inside trac. h4. Subversion Configuration The same access file is typically applied to the corresponding Subversion repository using an Apache directive like this: <pre> <Location /repos> DAV svn SVNParentPath /usr/local/svn # our access control policy AuthzSVNAccessFile /path/to/svnaccessfile </Location> </pre> For information about how to restrict access to entire projects in a multiple project environment see [trac:wiki:TracMultipleProjectsSVNAccess] ---- See also: TracPermissions
Trac Navigation¶
Starting with Trac 0.11, it is now possible to customize the main and meta navigation entries in some basic ways.
The new
[mainnav]and[metanav]configuration sections can now be used to customize the text and link used for the navigation items, or even to disable them.
[mainnav]corresponds to the main navigation bar, the one containing entries such as Wiki, Timeline, Roadmap, Browse Source and so on. This navigation bar is meant to access the default page of the main modules enabled in Trac and accessible for the current user.
[metanav]corresponds to the meta navigation bar, by default positioned above the main navigation bar and below the Search box. It contains the Log in, Logout, Help/Guide etc. entries. This navigation bar is meant to access some global information about the Trac project and the current user.Note that it is still not possible to customize the contextual navigation bar, i.e. the one usually placed below the main navigation bar.
Example¶
In the following example, we rename the link to the Wiki start "Home", and hide the "Help/Guide" link.
Relevant excerpt from the TracIni:
We also make the "View Tickets" entry link to a specific report.
[mainnav] wiki.label = Home tickets.href = /report/24 [metanav] help = disabled----
See also: TracInterfaceCustomization, the TracHacks:NavAddPlugin (still needed for adding entries)
The Trac Ticket Workflow System¶
The Trac issue database provides a configurable workflow.
The Default Ticket Workflow
Environments upgraded from 0.10 =
When you runtrac-admin <env> upgrade, yourtrac.iniwill be modified to include a[ticket-workflow]section.
The workflow configured in this case is the original workflow, so that ticket actions will behave like they did in 0.10.¶Graphically, that looks like this:
../common/guide/original-workflow.png)
There are some significant "warts" in this; such as accepting a ticket sets it to 'assigned' state, and assigning a ticket sets it to 'new' state. Perfectly obvious, right?
So you will probably want to migrate to "basic" workflow;contrib/workflow/migrate_original_to_basic.pymay be helpful.Environments created with 0.11¶
When a new environment is created, a default workflow is configured in your trac.ini. This workflow is the basic workflow (described in
basic-workflow.ini), which is somewhat different from the workflow of the 0.10 releases.Graphically, it looks like this:
../common/guide/basic-workflow.png)
Additional Ticket Workflows¶
There are several example workflows provided in the Trac source tree; look in
contrib/workflowfor.iniconfig sections. One of those may be a good match for what you want. They can be pasted into the[ticket-workflow]section of yourtrac.inifile.Basic Ticket Workflow Customization¶
Create a[ticket-workflow]section intrac.ini.
Within this section, each entry is an action that may be taken on a ticket.
For example, consider theacceptaction fromsimple-workflow.ini:
accept = new,accepted -> accepted accept.permissions = TICKET_MODIFY accept.operations = set_owner_to_self
The first line in this example defines theacceptaction, along with the states the action is valid in (newandaccepted), and the new state of the ticket when the action is taken (accepted).
Theaccept.permissionsline specifies what permissions the user must have to use this action.
Theaccept.operationsline specifies changes that will be made to the ticket in addition to the status change when this action is taken. In this case, when a user clicks onaccept, the ticket owner field is updated to the logged in user. Multiple operations may be specified in a comma separated list. The available operations are:
- del_owner -- Clear the owner field.
- set_owner -- Sets the owner to the selected or entered owner.
- actionname@.set_owner@ may optionally be set to a comma delimited list or a single value.
- set_owner_to_self -- Sets the owner to the logged in user.
- del_resolution -- Clears the resolution field
- set_resolution -- Sets the resolution to the selected value.
- actionname@.set_resolution@ may optionally be set to a comma delimited list or a single value.
Example: resolve_new = new -> closed resolve_new.name = resolve resolve_new.operations = set_resolution resolve_new.permissions = TICKET_MODIFY resolve_new.set_resolution = invalid,wontfix
- leave_status -- Displays "leave as <current status>" and makes no change to the ticket.
Note: Specifying conflicting operations (such asset_owneranddel_owner) has unspecified results.resolve_accepted = accepted -> closed resolve_accepted.name = resolve resolve_accepted.permissions = TICKET_MODIFY resolve_accepted.operations = set_resolutionIn this example, we see the
For actions that should be available in all states,.nameattribute used. The action here isresolve_accepted, but it will be presented to the user asresolve.*may be used in place of the state. The obvious example is theleaveaction:
leave = * -> * leave.operations = leave_status leave.default = 1
This also shows the use of the.defaultattribute. This value is expected to be an integer, and the order in which the actions are displayed is determined by this value. The action with the highest.defaultvalue is listed first, and is selected by default. The rest of the actions are listed in order of decreasing.defaultvalues.
If not specified for an action,.defaultis 0. The value may be negative.There are a couple of hard-coded constraints to the workflow. In particular, tickets are created with status
new, and tickets are expected to have aclosedstate. Further, the default reports/queries treat any state other thanclosedas an open state.While creating or modifying a ticket workfow,
This can be done as follows (your install path may be different).contrib/workflow/workflow_parser.pymay be useful. It can create.dotfiles that GraphViz understands to provide a visual description of the workflow.
cd /var/local/trac_devel/contrib/workflow/ sudo ./showworkflow /srv/trac/PlannerSuite/conf/trac.ini
And then open up the resultingtrac.pdffile created by the script (it will be in the same directory as thetrac.inifile).After you have changed a workflow, you need to restart apache for the changes to take effect. This is important, because the changes will still show up when you run your script, but all the old workflow steps will still be there until the server is restarted.
Example: Adding optional Testing with Workflow¶
By adding the following to your [ticket-workflow] section of trac.ini you get optional testing. When the ticket is in new, accepted or needs_work status you can choose to submit it for testing. When it's in the testing status the user gets the option to reject it and send it back to needs_work, or pass the testing and send it along to closed. If they accept it then it gets automatically marked as closed and the resolution is set to fixed. Since all the old work flow remains, a ticket can skip this entire section.
testing = new,accepted,needs_work -> testing testing.name = Submit to reporter for testing testing.permissions = TICKET_MODIFY reject = testing -> needs_work reject.name = Failed testing, return to developer pass = testing -> closed pass.name = Passes Testing pass.operations = set_resolution pass.set_resolution = fixedExample: Limit the resolution options for a new ticket¶
The above resolve_new operation allows you to set the possible resolutions for a new ticket. By modifying the existing resolve action and removing the new status from before the
->we then get two resolve actions. One with limited resolutions for new tickets, and then the regular one once a ticket is accepted.resolve_new = new -> closed resolve_new.name = resolve resolve_new.operations = set_resolution resolve_new.permissions = TICKET_MODIFY resolve_new.set_resolution = invalid,wontfix,duplicate resolve = assigned,accepted,reopened -> closed resolve.operations = set_resolution resolve.permissions = TICKET_MODIFYAdvanced Ticket Workflow Customization¶
If the customization above is not extensive enough for your needs, you can extend the workflow using plugins. These plugins can provide additional operations for the workflow (like code_review), or implement side-effects for an action (such as triggering a build) that may not be merely simple state changes. Look at [trac:source:trunk/sample-plugins/workflow sample-plugins/workflow] for a few simple examples to get started.
But if even that is not enough, you can disable the ConfigurableTicketWorkflow component and create a plugin that completely replaces it.
some ideas for next steps¶
New enhancement ideas for the workflow system should be filed as enhancement tickets against the
ticket systemcomponent. If desired, add a single-line link to that ticket here.If you have a response to the comments below, create an enhancement ticket, and replace the description below with a link to the ticket.
set_owner operation, or needs to be clarified.triage action that sets the next state based on the ticket type, so a new ticket would move to new_task, new_defect, etc., and the workflow graph would separate at that point.Repository location:
Last release branch created:
source:/gnuradio/branches/releases/3.0
Latest SVN tarballs:
Next release branch version:
milestone:release-3.1
(Please feel free to volunteer!)
(Please feel free to volunteer!)
WritePythonApplications - A tutorial on how to develop Python GNU Radio applications. Some DSP and programming background required.
QTGUI Tutorial - A tutorial on how to develop Python GNU Radio applications. Some DSP and programming background required.
This document demonstrates how to use the QT GUI features in GNU Radio. There is one main QT interface defined that comes as either a complex sink or floating point sink, they are called:
As this shows, the sinks are located in the module gnuradio.qtgui and is imported into Python with:
1 from gnuradio.qtgui import qtgui
Both the complex and floating point versions of the sink take the same arguments using the following class constructor:
1
2 qtgui_make_sink_X (int fftsize, int wintype, double fc=0,
3 double bandwidth=1.0, const std::string &name="Spectrum Display",
4 bool plotfreq=true, bool plotwaterfall=true, bool plotwaterfall3d=true,
5 bool plottime=true, bool plotconst=true, bool use_openGL=true,
6 QWidget *parent=NULL)
The following describes the arguments meanings more:
If you have successfully installed the gr-qtgui module with GNU Radio, then all of the prerequisites should be installed. Just in case, the Python modules you will need to run a QT GUI application are:
It is also recommended that you get PyQWT5 to be able to build more extensive and nicer looking GUIs.
The first step is to be able to create a qtgui sink and display it on screen. This is both the simplest and most useful for debugging. By understanding how this example works, you can go and easily add a GUI to any existing GNU Radio application to see the signals at any point in the flow graph.
Here is the full code:
1 #!/usr/bin/env python
2
3 from gnuradio import gr
4 from gnuradio.qtgui import qtgui
5
6 from PyQt4 import QtGui
7 import sys, sip
8
9 class my_tb(gr.top_block):
10 def __init__(self):
11 gr.top_block.__init__(self)
12
13 # Make a local QtApp so we can start it from our side
14 self.qapp = QtGui.QApplication(sys.argv)
15
16 fftsize = 2048
17
18 self.src = gr.sig_source_c(1, gr.GR_SIN_WAVE, 0.1, 1)
19 self.nse = gr.noise_source_c(gr.GR_GAUSSIAN, 0.1)
20 self.add = gr.add_cc()
21 self.thr = gr.throttle(gr.sizeof_gr_complex, 100*fftsize)
22 self.snk = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS)
23
24 self.connect(self.src, (self.add, 0))
25 self.connect(self.nse, (self.add, 1))
26 self.connect(self.add, self.thr, self.snk)
27
28 # Tell the sink we want it displayed
29 self.pyobj = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget)
30 self.pyobj.show()
31
32 def main():
33 tb = my_tb()
34 tb.start()
35 tb.qapp.exec_()
36
37 if __name__ == "__main__":
38 try:
39 main()
40 except KeyboardInterrupt:
41 pass
Lines 1 - 7 just set up the environment and modules, including the PyQT modules we require. Lines 9 - 11 simply set up the "my_tb" class as a GNU Radio top block class and initialize it.
Line 14 is the first deviation from normal GNU Radio flow graphs. This line gets a reference to the qApp, which is QT global application element. Right now, it is enough to know that we require it, but we won't do anything with it until later.
Line 16 just sets a variable for the FFT size. Lines 18 - 22 build the blocks of the flow graph, including the qtgui block. In this flow graph, we create a sine wave and add noise to it. The noise is to make sure the signal is constantly changing in the display as a simple sine wave looks like nothing changes between frames. There is a threshold block so the GUI is not trying to run at full speed, too. Finally, the sink is a complex qtgui sink with just the first two arguments given. As can be seen in the class constructor listed above, all of the other arguments have defaults, so we will use these for now.
Lines 24 - 26 just connect all of the blocks. Like any other block, the qtgui sink is added as just another connection.
Lines 29 and 30 are specific to making the qtgui blocks visible. We have to use the "show" operation on the qtgui block, but first, we have to convert it to a Python object. Line 29 does the conversion by using the SIP wrapper interface to go from a PyObject in C++ to a native Python object as a QWidget. The "pyqwidget" method of the qtgui sink passes the proper object pointer back to allow this handling. Now, the Python object has the "show()" method required to display the sink that is called in Line 30. Without this, the code would run, but we would see nothing displayed.
The final bit of tickery that deviates from a normal flow graph is how we tell the class to run. Line 33 instantiates an object of our "my_tb" class. Instead of calling "run()" on this object, though, we only call "start()" in line 34, which is non-blocking (run() performs both a start() and wait() call). We then tell the qApp that we got a reference to in Line 10 to execute with the "exec_()" method on line 35. This starts the QT runtime engine to handle the display and controls of the QT widgets. Now, when we run the program, we should see a QT application with a widget displaying the frequency domain. [SHOWPCITURE]
The big take-aways message here is the relatively minor changes required to make a qtgui application from a flow graph.
Welcome, GNU Radio beginners. If you are reading this tutorial, you probably already have some very basic knowledge about how GNU Radio works, what it is and what it can do - and now you want to enter this exciting world of Open Source digital signal processing (DSP) yourself.
This is a tutorial on how to write applications for GNU Radio in Python. It is no introduction to programming, software radio or signal processing, nor does it cover how to extend GNU Radio by creating new blocks or adding code to the source tree. If you have some background in the mentioned topics and are starting to work with GNU Radio, this probably is the correct tutorial for you. If you don't know what a Software Radio is or what a FIR filter does, you should probably go a few steps back and get a more solid background on signal processing theory. But don't let this discourage you - the best way to learn something is by trying it out.
Although this tutorial is designed to make your introduction to GNU Radio as easy as possible, it is not a definitive guide. In fact, I might sometimes simply not tell the real truth to make explanations easier. I might even contradict myself in later chapters. Usage of brain power is still necessary to develop GNU Radio applications.
Before you get started with this tutorial, make sure your GNU Radio installation is ready and working. You don't necessarily need a USRP, but some kind of source and sink (USRP or audio) is helpful, although not strictly required. If the GNU Radio examples work (such as dial_tone.py in gnuradio-examples/python/audio), you're ready to go.
You should also have some background in programming - but don't worry if you've never programmed Python, it is a very easy language to learn.
Before we start banging out code, first we need to understand the most basic concepts about GNU Radio: flow graphs (as in graph theory) and blocks. Many GNU Radio applications contain nothing other than a flow graph. The nodes of such a graph are called blocks, and the data flows along the edges.
Any actual signal processing is done in the blocks. Ideally, every block does exactly one job - this way GNU Radio stays modular and flexible. Blocks are written in C++; writing new blocks is not very difficult (but explained elsewhere).
The data passing between blocks can be of any kind - practically any type of data you can define in C++ is possible. In practice, the most common data types are complex and real short or long integers and floating point values as most of the time, data passing from one block to the next will either be samples or bits.
In order to illuminate this diffuse topic a little, let's start with some examples:
Low-pass filtered audio recorder+-----+ +-----+ +----------------+ | Mic +--+ LPF +--+ Record to file | +-----+ +-----+ +----------------+
First, an audio signal from a microphone is recorded by your PCs sound card and converted into a digital signal. The samples are streamed to the next block, the low pass filter (LPF), which could be implemented as an FIR filter. The filtered signal is passed on to the final block, which records the filtered audio signal into a file.
This is a simple, yet complete flow graph. The first and last block serve a special purpose: they operate as source and sink. Every flow graph needs at least one source and sink to be able to function.
Dial tone generator
+------------------------+
| Sine generator (350Hz) +---+
+------------------------+ | +------------+
+---+ |
| Audio sink |
+---+ |
+------------------------+ | +------------+
| Sine generator (440Hz) +---+
+------------------------+
This simple example is often called the "Hello World of GNU Radio". Other than the first example, it has two sources. The sink, on the other hand, has two inputs - in this case for the left and right channel of the sound card. Code for this example is available at gnuradio-examples/python/audio/dial_tone.py.
QPSK Demodulator
+-------------+ +----------------+ +------------------+
| USRP Source +--+ Frequency sync +--+ Matched filter |
+-------------+ +----------------+ +-----------+------+
| COMPLEX SAMPLES
+-------------+------+
| Symbol demodulator |
+-------------+------+
| COMPLEX SYMBOLS
+-----------------+ +-----------------+ +------+------+
| Source decoder +--+ Channel decoder +--+ Bit mapping |
+--------+--------+ +-----------------+ +-------------+
| BITS
+--------+--------+
| Application | DATA
+-----------------+
This example is a bit more sophisticated, but should look quite familiar to RF engineers. In this case, the source is a USRP which is connected to an antenna. This kind of source sends complex samples to the following blocks.
The interesting part about this kind of flow graph is that the data types change during the flow graph: at first, complex baseband samples are passed along. Then, complex symbols are gathered from the signal. Next, these symbols are turned into bits which again are processed further. Finally, the decoded bits are passed to some application which makes use of the data.
Walkie Talkie+--------------+ +------------------+ +---------+ +------------+ | USRP Source +--+ NBFM Demodulator +--+ Squelch +--+ Audio Sink | +--------------+ +------------------+ +---------+ +------------+ +--------------+ +----------------+ +------------+ | Audio Source +----------+ NBFM Modulator +---------+ USRP Sink | +--------------+ +----------------+ +------------+
This applications consists of two separate flow graphs, both running in parallel. One of them deals with the Tx path, the other with the Rx path. This kind of application would require some extra code (outside the flow graphs) to mute one path while the other is active. Both flow graphs still require at least one source and sink, each. You can find a GNU Radio application that does this (only a bit more sophisticated) at gnuradio-examples/python/usrp/usrp_nbfm_ptt.py.
This concludes the chapter about flow graphs. Here's a quick summary about the most vital points you really need to know:
Next step is to find out how to write those flow graphs in real Python. Let's start by examining some code line-by-line. If you are familiar with Python, you can probably skip some of the explanations, but don't rush to the next section yet - the explanations are both for Python and GNU Radio beginners.
The following code example represents the flow graph from example 2. It is actually a slightly modified version of the code example you can find in gnuradio-examples/python/audio/dial_tone.py.
1 #!/usr/bin/env python
2
3 from gnuradio import gr
4 from gnuradio import audio
5
6 class my_top_block(gr.top_block):
7 def __init__(self):
8 gr.top_block.__init__(self)
9
10 sample_rate = 32000
11 ampl = 0.1
12
13 src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)
14 src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl)
15 dst = audio.sink (sample_rate, "")
16 self.connect (src0, (dst, 0))
17 self.connect (src1, (dst, 1))
18
19 if __name__ == '__main__':
20 try:
21 my_top_block().run()
22 except KeyboardInterrupt:
23 pass
The first line should look familiar to anyone with some Unix or Linux background: It tells the shell that this file is a Python file and to use the Python interpreter to run this file. You need this line if you want to run this file directly from the command line.
Lines 3 and 4 import necessary Python modules to run GNU Radio. The import command is similar to the #include directive in C/C++. Here, two modules from the gnuradio-package are imported: gr and audio. The first module, gr, is the basic GNU Radio module. You will always have to import this to run a GNU Radio application. The second loads audio device blocks. There are many GNU Radio modules, a short list of modules will be presented later on.
Lines 6-17 define a class called my_top_block which is derived from another class, gr.top_block. This class is basically a container for the flow graph. By deriving from gr.top_block, you get all the hooks and functions you need to add blocks and connect them.
Only one member function is defined for this class: the function +init+(), which is the constructor of this class. In the first line of this function (line 8), the parent constructor is called (in Python, this needs to be done explicitly. Most things in Python need to be done explicitly; in fact, this is one main Python principle).
Next, two variables are defined: sample_rate and ampl. These will control sampling rate and amplitude of the signal generators.
Before explaining the next lines, have another look at the sketched flow graph chart in the previous section: it consists of three blocks and two edges. The blocks are defined in lines 13-15: Two signal sources are generated (called src0 and src1). These sources continuously create sine waves at given frequencies (350 and 440Hz) and a given sampling rate (here 32kHz). The amplitude is controlled by the ampl variable and set to 0.1. The prefix "f" of the block type gr.sig_source_f indicates the output is of type float, which is a good thing because the audio sink accepts floating point samples in the range between -1 and +1. These kind of things must be taken care of by the programmer: although GNU Radio does some checks to make sure the connections make sense, there is still some things that must be taken care of manually. For example, if you wanted to feed integer samples to audio.sink, GNU Radio would throw an error - but if you would set the amplitude in the above example to anything larger than 1, you would get a distorted signal without receiving an error.
The signal sink is defined in line 15: audio.sink() returns a block which acts as a soundcard control and plays back any samples piped into it. As in the blocks beforehand, the sampling rate needs to be set explicitly, even though this was set already for the signal sources. GNU Radio cannot guess the correct sampling rate from the context, as it is not part of the information flow between blocks.
Lines 16 and 17 connect the blocks. The general syntax for connecting blocks is self.connect(block1, block2, block3, ...) which would connect the output of block1 with the input of block2, the output of block2 with the input of block3 and so on. You can connect as many blocks as you wish with one connect() call. Here, a special syntax is necessary because we want to connect src0 with the first input of dst and src1 with the second one. self.connect (src0, (dst, 0)) does exactly this: it specifically connects src0 to port 0 of dst. (dst, 0) is called a "tuple" in Python jargon. In the self.connect() call it is used to specify the port number. When the port number is zero, the block may be used alone. An equivalent command to the one in line 16 would thus have been
1 self.connect((src0, 0), (dst, 0))
That's all there is to create a flow graph. The last 5 lines do nothing but start the flow graph (line 22). The try and except statements simply make sure the flow graph (which would otherwise run infinitely) are stopped when Ctrl+C is pressed (which triggers a KeyboardInterrupt Python exception).
For Python-beginners, two more remarks should not be left out: As you might have noticed, the class my_top_block is run without creating an instance beforehand. In Python, this is a quite common thing to do, especially if you have a class which would only get one instance anyway. However, you could just as well create one or more instances of the class and then call the run() method on the instance(es).
Second, the indenting is part of the code and not, like in C++, simply for the programmers convenience. If you try and modify this code, make sure you don't start mixing tabs and spaces. Every level must be consistently indented.
If you want to go on with this tutorial, you should first get a more solid Python background. Python documentation can be found at the Python web site http://www.python.org/, or a library of your choice. A good place to start for people with prior programming experience is http://wiki.python.org/moin/BeginnersGuide/Programmers .
from gnuradio import command. You always need the module gr.gr.top_block.gr.sig_source_f() and saving the return value to a variable.self.connect() from within the flow graph classThe next section will give a more detailed overview about writing GNU Radio applications in Python.
The example above already covers quite a lot of how to write Python GNU Radio applications. This chapter and the next will try to show the possibilites of GNU Radio applications and how to use them. From now on, there is no need to linearly read these chapters section-for-section, it probably makes more sense to go over the titles and find out what you want to know.
GNU Radio comes with quite a lot of libraries and modules. You will usually include modules with the following syntax:
1 from gnuradio import MODULENAME
Some modules work a bit differently, see the following list on the most common modules.
| gr | The main GNU Radio library. You will nearly always need this. | |||
| usrp | USRP sources and sinks and controls. | |||
| audio | Soundcard controls (sources, sinks). You can use this to send or receive audio to the sound cards, but you can also use your sound card as a narrow band receiver with an external RF frontend. | |||
| blks2 | This module contains additional blocks written in Python which include often-used tasks like modulators and demodulators, some extra filter code, resamplers, squelch and so on. | |||
| optfir | Routines for designing optimal FIR filters. | |||
| plot_data | Some functions to plot data with Matplotlib | |||
| wxgui | This is actually a submodule, containing utilities to quickly create graphical user interfaces to your flow graphs. Use from gnuradio.wxgui import * to import everything in the submodule or from gnuradio.wxgui import stdgui2, fftsink2 to import specific components. See the section 'Graphical User Interfaces' for more information. |
|||
| eng_notation | Adds some functions to deals with numbers in engineering notation such as @100M' for 100 * 10^6'. | |||
| eng_options | Use from gnuradio.eng_options import eng_options to import this feature. This module extends Pythons optparse module to understand engineering notation (see above). |
|||
| gru | Miscellaneous utilities, mathematical and others. |
This is by far not a complete list, nor are the descriptions of the modules very useful by themselves. GNU Radio code changes a lot, so creating a static documentation would not be very sensible.
Instead, you will have to use the good old Star Wars motto to delve further into the details of the modules: "Use the source!". If you feel GNU Radio should really already have some functionality you want to use, either browse through the module directory Python uses or go through the source directory of GNU Radio. In particular, pay attention to the directories starting with gr- in the source directory, such as gr-sounder or gr-radar-mono. These produce their own code and, consequently, their own modules.
Of course, Python itself comes with a lot of modules, some of which are extremely useful - if not necessary - to write GNU Radio applications. Check the Python documentation and the SciPy website for more information.
GNU Radio comes with an abundance of pre-defined blocks, so for beginners, it is often quite confusing to find the correct blocks for their applications and set them up correctly.
As with modules, the GNU Radio code changes around quite a bit, so a static documentation doesn't really make sense. However, the situation is a bit different with blocks. First of all, there's the unofficial GNU Radio manual (based on GNU Radio 3.1.1) which can be downloaded at
http://rapidshare.com/files/72169239/Simple-Gnuradio-User-Manual-v1.0.pdf
Thanks to the author for the massive effort!
Then, there's the automatically generated documentation. This is created by Doxygen from the source code. I recommend making these docs the same time as building the rest. Run ./configure with the --enable-doxygen switch for to create the docs when running make. The latter is particularly useful as it consists of multiple HTML documents which can be browsed easily. If you don't want to create the documents yourself or don't have to possibility to do so, you can find a version (although not an up-to-date one) on the web at http://gnuradio.org/doc/doxygen/hierarchy.html. The auto-generated docs are in your source directory beneath gnuradio-core/doc/html.
Learning how to use these documentations is a major part of learning how to use GNU Radio!
Let's get practical. Here's the three lines from the previous example which define the blocks:
1 src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)
2 src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 440, ampl)
3 dst = audio.sink (sample_rate, "")
Here's a simplified version of what happens when this code is executed: First, a function called sig_source_f in the module gr is executed. It receives four function arguments:
This function creates a class which is subsequently assigned to src0. The same happens on the other two lines, although the sink is fetched from a different module (audio).
So how did I know which block to use and what to pass to gr.sig_source_f()? This is where the documentation comes in. If you use the Doxygen-generated docs, click on the top left tab called "Modules". Proceed to "Signal Sources". You will find a list of signal generators, including the sig_source_* family. The suffix defines the data type at the output:
These suffixes are used for all types of blocks, e.g. gr.fir_filter_ccf() will define an FIR filter with complex input, complex output and float taps, and gr.add_const_ss() will define a block which adds incoming short values with another, constant, short int.
A list of all classes with a short description can be obtained by clicking on the top tab called "Classes". The unofficial GNU Radio manual lists all classes sorted by module and can be searched using your PDF reader of choice.
Most blocks you'll be using at the beginning are either from the gr, audio or usrp modules. So if you find a class called gr_sig_source_f in the auto-generated docs, you can create this class in Python by calling gr.sig_source_f().
At this point it is worth having a closer look behind the curtains of GNU Radio. The reason you can easily use the blocks - written in C++ - in your Python code is because GNU Radio uses a tool called SWIG to create an interface between Python and C++. Every block in C++ comes with a creating function, called gr_make_*** (gr_make_sig_source_f() in the example mentioned above). This function is always documented on the same page as the matching class, and this function is what gets exported to Python, so gr.sig_source_f() in Python calls gr_make_sig_source_f() in C++. For the same reason, it takes the same arguments - that's how you know how to initialise a block in Python.
Once you're browsing the Doxygen documentation of the class gr_sig_source_f, you might notice many other class methods, such as set_frequency(). These functions get exported to Python as well. So if you have created a signal source and want to change the frequency (say your application has a user frequency control) you can use this method on your Python defined block:
1 # We're in some cool application here
2
3 src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, 350, ampl)
4 # Other, fantastic things happen here
5
6 src0.set_frequency(880) # Change frequency
will change the frequency of the first signal generator to 880Hz.
Hopefully, GNU Radio documentation will grow and become more and more complete. But to completely understand the workings of blocks in detail, you will probably have to have a look at the code sooner or later, no matter how good the documentation gets.
Use the connect() method of gr.top_block to connect blocks. Some things are worth mentioning:
These are basic rules for connecting blocks and they work in most cases. However, when mixing data types some more notes are worth mentioning.
packed_to_unpacked* and unpacked_to_packed* blocks for this.Sometimes it makes sense to combine several blocks into a new block. Say you have several applications which all have a common signal processing component which consists of several blocks. These blocks can be combined into a new block, which in turn can be used in your applications is if it were a normal GNU Radio block.
Example: Say you have two different flow graphs, FG1 and FG2. Both use - among others - the blocks B1 and B2. You want to combine them to a hierarchical block called HierBlock:
+-------------------+ | +-----+ +----+ | --+--+ B1 +--+ B2 +--+--- | +-----+ +----+ | | HierBlock | +-------------------+
This is what you do: create a flow graph which derives from gr.hier_block2 and use self as source and sink:
1 class HierBlock(gr.hier_block2):
2 def __init__(self, audio_rate, if_rate):
3 gr.hier_block2.__init__(self, "HierBlock",
4 gr.io_signature(1, 1, gr.sizeof_float),
5 gr.io_signature(1, 2, gr.sizeof_gr_complex))
6
7 B1 = gr.block1(...) # Put in proper code here!
8 B2 = gr.block2(...)
9
10 self.connect(self, B1, B2, self)
As you can see, creating a hierarchical block is very similar to creating a flow graph with gr.top_block. Apart from using self as source and sink, there is another difference: the constructor for the parent class (called in line 3) needs to receive additional information. The call to gr.hier_block2.+init+() takes four parameters:
The last two require some extra explanation unless you have already written your own blocks in C++. GNU Radio needs to know what types of input and output the block uses. Creating an input/output signature can be done by calling gr.io_signature(), as is done here. This function call takes 3 arguments:
For the hierarchical block HierBlock, you can see that it has exactly one input and one or two outputs. The incoming objects are of size float, so the block processes incoming real float values. Somewhere in B1 or B2, the data is converted to complex float values, so the output signature declares outgoing objects to be of size gr.sizeof_gr_complex. The 'gr.sizeof_float@ and gr.sizeof_gr_complex are equivalent to the C++ return values of the sizeof() call. Other predefined constants are
Use gr.io_signature(0, 0, 0) to create a null IO signature, i.e. for defining hierarchical blocks as sources or sinks.
That's all. You can now use HierBlock as you would use a regular block. For example, you could put this code in the same file:
1 class FG1(gr.top_block):
2 def __init__(self):
3 gr.top_block.__init__(self)
4
5 ... # Sources and other blocks are defined here
6 other_block1 = gr.other_block()
7 hierblock = HierBlock()
8 other_block2 = gr.other_block()
9
10 self.connect(other_block1, hierblock, other_block2)
11
12 ... # Define rest of FG1
Of course, to make use of Pythons modularity, you could also put the code for HierBlock in an extra file called hier_block.py. To use this block from another file, simply add an import directive to your code:
1 from hier_block import HierBlock
and you can use HierBlock as mentioned above.
Examples for hierarchical blocks:
gnuradio-examples/python/usrp/fm_tx4.py gnuradio-examples/python/usrp/fm_tx_2_daughterboards.py gnuradio-examples/python/digital/tx_voice.py
In some cases, you might want to have completely separate flow graphs, e.g. for receive and transmit paths (see the example 'Walkie-Talkie' above). Currently (June 2008), it is not possible to have multiple top_blocks running at the same time, but what you can do is create full flow graphs as hierarchical blocks using gr.hier_block2 like in the section above. Then, create a top_block to hold the flow graphs.
Example:
1 class transmit_path(gr.hier_block2):
2 def __init__(self):
3 gr.hier_block2.__init__(self, "transmit_path",
4 gr.io_signature(0, 0, 0), # Null signature
5 gr.io_signature(0, 0, 0))
6
7 source_block = gr.source()
8 signal_proc = gr.other_block()
9 sink_block = gr.sink()
10
11 self.connect(source_block, signal_proc, sink_block)
12
13 class receive_path(gr.hier_block2):
14 def __init__(self):
15 gr.hier_block2.__init__(self, "receive_path",
16 gr.io_signature(0, 0, 0), # Null signature
17 gr.io_signature(0, 0, 0))
18
19 source_block = gr.source()
20 signal_proc = gr.other_block()
21 sink_block = gr.sink()
22
23 self.connect(source_block, signal_proc, sink_block)
24
25 class my_top_block(gr.top_block):
26 def __init__(self):
27 gr.top_block.__init__(self)
28
29 tx_path = transmit_path()
30
31 rx_path = receive_path()
32
33 self.connect(tx_path)
34 self.connect(rx_path)
Now, when you start my_top_block, both flow graphs are started in parallel. Note that the hierarchical blocks have explicitly no inputs and outputs defined, they have a null IO signature. Consequently, they don't connect to self as source or sink; they rather define their own sources or sink (just as you would do when defining a hierarchical block as source or sink). The top block simply connects the hierarchical blocks to itself, but does not connect them up in any way.
Examples for multiple flow graphs:
gnuradio-examples/python/usrp/usrp_nbfm_ptt.py
GNU Radio is more than blocks and flow graphs - it comes with a lot of tools and code to help you write DSP applications.
A collection of useful GNU Radio applications designed to aid you is in gr-utils/.
Browse the source code in gnuradio-core/src/python/gnuradio to find utilities you can use in your Python code such as filter design code, modulation utilities and more.
If you have followed the tutorial so far, you will have noticed that a flow graph has always been implemented as a class, derived from gr.top_block. The question remains on how to control one of these classes.
As mentioned before, deriving the class from gr.top_block brings along all the functionality you might need. To run or stop an existing flow graph, use the following methods:
run() |
The simplest way to run a flow graph. Calls start(), then wait(). Used to run a flow graph that will stop on its own, or to run a flow graph indefinitely until SIGINT is received. | |||
start() |
Start the contained flow graph. Returns to the caller once the threads are created. | |||
stop() |
Stop the running flow graph. Notifies each thread created by the scheduler to shutdown, then returns to caller. | |||
wait() |
Wait for a flow graph to complete. Flowgraphs complete when either (1) all blocks indicate that they are done, or (2) after stop has been called to request shutdown. | |||
lock() |
Lock a flow graph in preparation for reconfiguration. | |||
unlock() |
Unlock a flow graph in preparation for reconfiguration. When an equal number of calls to lock() and unlock() have occurred, the flow graph will be restarted automatically. |
See the documentation for gr_top_block for more details.
Example:
1 class my_top_block(gr.top_block):
2 def __init__(self):
3 gr.top_block.__init__(self)
4 ... # Define blocks etc. here
5
6 if +name+ == '+main+':
7 my_top_block().start()
8 sleep(5) # Wait 5 secs (assuming sleep was imported!)
9 my_top_block().stop()
10 my_top_block().wait() # If the graph is needed to run again, wait() must be called after stop
11 ... # Reconfigure the graph or modify it
12 my_top_block().start() # start it again
13 sleep(5) # Wait 5 secs (assuming sleep was imported!)
14 my_top_block().stop() # since (assuming) the graph will not run again, no need for wait() to be called
These methods help you to control the flow graph from the outside. For many problems this might not be enough: you don't simply want to start or stop a flow graph, you want to reconfigure the way it behaves. For example, imagine your application has a volume control somewhere in your flow graph. This volume control is implemented by inserting a multiplier into the sample stream. This multiplier is of type gr.multiply_const_ff. If you check the documentation for this kind of of block, you will find a function gr.multiply_const_ff.set_k() which sets the multiplication factor.
You need to make the settings visible to the outside in order to control it. The simplest way is to make the block an attribute of the flow graph class.
Example:
1 class my_top_block(gr.top_block):
2 def __init__(self):
3 gr.top_block.__init__(self)
4 ... # Define some blocks
5 self.amp = gr.multiply_const_ff(1) # Define multiplier block
6 ... # Define more blocks
7
8 self.connect(..., self.amp, ...) # Connect all blocks
9
10 def set_volume(self, volume):
11 self.amp.set_k(volume)
12
13 if __name__ == '__main__':
14 my_top_block().start()
15 sleep(2) # Wait 2 secs (assuming sleep was imported!)
16 my_top_block.set_volume(2) # Pump up the volume (by factor 2)
17 sleep(2) # Wait 2 secs (assuming sleep was imported!)
18 my_top_block().stop()
This example runs the flow graph for 2 seconds and then doubles the volume by accessing the amp block through a member function called set_volume(). Of course, one could have accessed the amp attribute directly, omitting the member function.
Hint: making blocks attributes of the flow graph is generally a good idea as it makes extending the flow graph with extra member functions easier.
Up until now, GNU Radio applications in this tutorial have always been centred around the one class derived from gr.top_block. However, this is not necessarily how GNU Radio needs to be used. GNU Radio was designed to develop DSP applications from Python, so there's no reason to not use the full power of Python when using GNU Radio.
Python is an extremely powerful language, and new libraries and functionalities are constantly being added. In a way, GNU Radio extends Python with a powerful, real-time-capable DSP library. By combining this with other libraries you have immense functionality right there at your fingertips. For example, by combining GNU Radio with SciPy, a collection of scientific Python libraries, you can record RF signals in real time and do extensive mathematical operations off line, save statistics to a database and so on - all in the same application. Even expensive engineering software such as Matlab might become unnecessary if you combine all these libraries.
If you have really read the previous sections, you already know enough to write your first Python GNU Radio applications. This section will adress some slightly more advanced functionalities for Python GNU Radio applications.
For most cases, the aforementioned way to define flow graphs is completely adequate. If you need more flexibility in your application, you might want to have even more control over the flow graph from outside the class.
This can be achieved by taking the code out of the +init+() function and simply using gr.top_block as a container. Example:
1 ... # We are inside some application
2 tb = gr.top_block() # Define the container
3
4 block1 = gr.some_other_block()
5 block2 = gr.yet_another_block()
6
7 tb.connect(block1, block2)
8
9 ... # The application does some wonderful things here
10
11 tb.start() # Start the flow graph
12
13 ... # Do some more incredible and fascinating stuff here
If you are writing some application which needs to dynamically stop a flow graph (reconfigure it, re-start it and so) on this might be a more practical way to do it.
Examples for this kind of flow graph setup:
gnuradio-examples/python/apps/hf_explorer/hfx2.py
Python has its own libraries to parse command line options. See the documentation for the module optparse to find out how to use it.
GNU Radio extends optparse by new command line option types. Use @from gnuradio.eng_option import eng_option' to import this extension. With eng_option, you have the following types:
| eng_float | Like the original float option, but also accepts engineering notation like 101.8M | |||
| subdev | Only accepts valid subdevice descriptors such as A:0 (To specify a daughterboard on a USRP) | |||
| intx | Only accepts integers |
If your application supports command line options, it would be ever so nice if you could stick to the GNU Radio conventions for command line options. You can find these (along with more hints for developers) in README.hacking.
Nearly every GNU Radio example uses this feature. Try dial_tone.py for an easy example.
If you are a Python expert and also have some experience in writing GUIs for Python (using whatever GUI toolkit you like), you might not even need this section. As mentioned before, GNU Radio merely extends Python with DSP routines - so if you like, just go ahead and write a GUI application, add a GNU Radio flow graph to it and define some interfaces to carry GNU Radio information to your application and vice versa. If you want to plot your data, you could use Matplotlib or Qwt.
However, sometimes you simply want to write a quick GUI application without bothering with setting up widgets, defining all the menus etc. GNU Radio comes with some predefined classes to help you write graphical GNU Radio applications.
These modules are based on wxWidgets (or to be precise, wxPython), a platform-independent GUI toolkit. You will need some background in wxPython - but don't worry, it is not that complicated and there are several tutorials available on the net. Check the wxPython website for documentation (http://www.wxpython.org/).
To use the GNU Radio wxWidgets tools, you need to import some modules:
1 from gnuradio.wxgui import stdgui2, fftsink2, slider, form
Here, 4 components were imported from the gnuradio.wxgui submodule. Here's a quick list of the modules (again, not necessarily complete. You will have to browse the modules or the source code in gr-wxgui/src/python).
| stdgui2 | Basic GUI stuff, you always need this | |||
| fftsink2 | Plot FFTs of your data to create spectrum analyzers or whatever | |||
| scopesink2 | Oscilloscope output | |||
| waterfallsink2 | Waterfall output | |||
| numbersink2 | Displays numerical values of incoming data | |||
| form | Often used input forms (see below) |
Next, we have to define a new flow graph. This time, we don't derive from gr.top_block but from stdgui2.std_top_block:
1 class my_gui_flow graph(stdgui2.std_top_block):
2 def __init__(self, frame, panel, vbox, argv):
3 stdgui2.std_top_block.__init__ (self, frame, panel, vbox, argv)
As you can see, there's another difference: the constructor gets a couple of new parameters. This is because a stdgui2.std_top_block does not only include flow graph functionality (it is derived from gr.top_block itself), but also directly creates a window with some basic components (like a menu). This is good news for all of those who just want to quickly hack a graphical application: GNU Radio creates the window and everything, you just need to add the widgets. Here's a list of what you can do with these new objects (this probably won't mean much to you if you have no idea about GUI programming):
| frame | The wx.Frame of your window. You can get at the predefined menu by using frame.GetMenuBar() | |||
| panel | A panel, placed in @frame', to hold all your wxControl widgets | |||
| vbox | A vertical box sizer (wx.BoxSizer(wx.VERTICAL) is how it is defined), used to align your widgets in the panel | |||
| argv | The command line arguments |
Now you have all you need to create your GUI. You can simply add new box sizers and widgets to vbox, change the menu or whatever. Some typical functions have been simplified further in the GNU Radio GUI library form.
form has a great number of input widgets: form.static_text_field() for static text field (display only), form.float_field(), to input float values, form.text_field() to input text, form.checkbox_field() for checkboxes, form.radiobox_field() for radioboxes etc. Check the source code of gr-wxgui/src/python/form.py for the complete list. Most of these calls pass most of their arguments to the appropriate wxPython objects, so the function arguments are quite self-explanatory.
See one of the examples mentioned below on how to add widgets using form.
Probably the most useful part of gnuradio.wxgui is the possibility to directly plot incoming data. To do this, you need one of the sinks that come with gnuradio.wxgui, such as fftsink2. These sinks work just as any other GNU Radio sink, but also have properties needed for use with wxPython. Example:
1 from gnuradio.wxgui import stdgui2, fftsink2
2
3 # App gets defined here ...
4
5 # FFT display (pseudo-spectrum analyzer)
6 my_fft = fftsink2.fft_sink_f(panel, title="FFT of some Signal", fft_size=512,
7 sample_rate=sample_rate, ref_level=0, y_per_div=20)
8 self.connect(source_block, my_fft)
9 vbox.Add(my_fft.win, 1, wx.EXPAND)
First, the block is defined (fftsink2.fft_sink_f). Apart from typical DSP parameters such as the sampling rate, it also needs the panel object which is passed to the constructor. Next, the block is connected to a source. Finally, the FFT window (my_fft.win) is placed inside the vbox BoxSizer to actually display it. Remember that a signal block output can be connected to any amount of inputs.
Finally, the whole thing needs to be started. Because we need an wx.App() to run the GUI, the startup code is a bit different from a regular flow graph:
1 if __name__ == '__main__':
2 app = stdgui2.stdapp(my_gui_flow_graph, "GUI GNU Radio Application")
3 app.MainLoop()
stdgui2.stdapp() creates the wx.App with my_gui_flow_graph (the first argument). The window title is set to "GUI GNU Radio Application".
Examples for simple GNU Radio GUIs:
gr-utils/src/python/usrp_fft.py gr-utils/src/python/usrp_oscope.py gnuradio-examples/python/audio/audio_fft.py gnuradio-examples/python/usrp/usrp_am_mw_rcv.py
And many more.
Young Padawan, no more there is I can teach you. If you have any more questions on how to write GNU Radio applications in Python, there are still a number of resources you can use:
A new data type introduced for use with the new m-blocks, is a polymorphic data type. The type can really be used to store anything, but also has simple conversion methods for common data types such as bool, long, or a vector.
The polymorphic type simplifies the data passing between m-blocks, as all of the data is of the same type, including the message.
Overview:To make PMT, the data type pmt_t is used just like any other data type.
The following is an example:pmt_t p_instance;
To construct or assign a value to a PMT, a method is available for each type of the following syntax: pmt<type>_.
The following constructors are available, all of which return pmt_t:pmt_t p_num = pmt_integer(3);
With a polymorphic type, it is useful to have methods to check what type it actually is if unknown.
The following methods are available for testing PMT types, all of which return bool:pmt_t p_num = pmt_integer(3); bool test_pmt = pmt_is_integer(p_num);
When a PMT is initialized with no value, such as pmt_dict() ... it is equivalent to PMT_NIL until it is assigned elements.
pmt_t p1 = pmt_integer(5); pmt_t p2 = pmt_integer(5); pmt_t p3 = pmt_integer(1); pmt_eq(p1, p1); // Returns true pmt_eq(p1, p2); // Returns false pmt_eqv(p1, p1); // Returns true pmt_eqv(p1, p2); // Returns true pmt_t p3 = pmt_pair(p1, p1); pmt_t p4 = pmt_pair(p1, p2); pmt_t p5 = pmt_pair(p1, p3); pmt_equal(p3, p4); // Returns true, equivalence in values pmt_equal(p3, p5); // Returns false, values are different
There are simple methods to store common C++ types as PMT for use in passing the data in m-block messages.
All of the conversion methods are of a similar syntax:pmt_t p_val = pmt_from_long(3); long l_val = pmt_to_long(p_val);
pmt_t p1 = pmt_integer(1); pmt_t p2 = pmt_integer(2); pmt_t p3 = pmt_integer(3); pmt_t p_list = pmt_list3(p1, p2, p3); pmt_length(p_list); // Returns 3
PMT lists are as they sound, lists! Each list element is of type pmt_t, and the list can be of infinite length.
To create a base list, you can use the following methods:List items cannot be removed, as they are implemented as constants.
To access the nth element in a list, the following method is available which returns the nth element:pmt_t p_list1 = pmt_list1(PMT_T); p_list1 = pmt_list_add(p_list1, PMT_F); pmt_t p_list2 = pmt_list2(PMT_T, PMT_F); pmt_equal(p_list1, p_list2); // Returns true pmt_t p_element0 = pmt_nth(0, p_list2); // Access elements pmt_t p_element1 = pmt_nth(1, p_list2); pmt_eqv(p_element0, PMT_T); // Returns true pmt_eqv(p_element1, PMT_F); // Returns true
static const int nelements = 64; pmt_t s16vec = pmt_make_s16vector(nelements, 0); // Initializes all 64 elements to 0 size_t vec_size; int16_t *elements = pmt_s16vector_writeable_elements(s16vec, vec_size); // Returns pointer, vec_size is set to 64 // Now you can access the elements like a standard array for(int i=0; i<vec_size; i++) elements[i] = 1;
A dictionary behaves exactly like a hash. PMT objects are referenced with a pmt_symbol (string-like PMT type).
To create a dictionary, use:
pmt_t p_dict = pmt_make_dict(); // Empty dictionary
pmt_dict_set(p_dict, pmt_symbol("number of dogs"), pmt_integer(3));
pmt_dict_set(p_dict, pmt_symbol("number of cats"), pmt_integer(5));
pmt_dict_set(p_dict, pmt_symbol("has a dog"), PMT_T);
pmt_dict_set(p_dict, pmt_symbol("has a turtle"), PMT_F);
if(pmt_is_dict(p_dict)) {
pmt_t p_ndogs = pmt_dict_ref(p_dict, pmt_symbol("number of dogs"), PMT_NIL);
pmt_t p_ncats = pmt_dict_ref(p_dict, pmt_symbol("number of cats"), PMT_NIL);
pmt_t p_dog = pmt_dict_ref(p_dict, pmt_symbol("has a dog"), PMT_NIL);
pmt_t p_turtle = pmt_dict_ref(p_dict, pmt_symbol("has a turtle"), PMT_NIL);
std::cout << "I have " << pmt_to_long(p_ndogs) << " dogs!\n";
std::cout << "I have " << pmt_to_long(p_ncats) << " cats!\n";
if(pmt_eqv(p_dog, PMT_T))
std::cout << "I have a dog\n"; // This will be outputted
else
std::cout << " I do not have a dog\n";
if(pmt_eqv(p_turtle, PMT_T))
std::cout << "I have a turtle\n";
else
std::cout << "I do not have a turtle\n"; // This will be outputted
}
When there is nothing to store your type, use a pmt_any. This allows you to cast anything into a pmt_t using boost::any cast.
Example:
typedef struct d_frame_hdr_t {
long src_addr;
long dst_addr;
} +attribute+((+packed+));
d_frame_hdr_t my_header;
my_header.src_addr = 3;
my_header.dst_addr = 4;
pmt_t p_any = pmt_make_any(my_header);
// After extracting using pmt_any_ref the following will be true:
// extract_header.src_addr == 3
// extract_header.dst_addr == 4
d_frame_hdr_t extract_header = boost::any_cast<d_frame_hdr_t> (pmt_any_ref(p_any));
With the latest GNU Radio release 3.2, binary package installation is available for Ubuntu 9.04 (Jaunty), bypassing the need for manually installing build tool prerequisites and performing a source code installation. In addition, installation and configuration of the USRP and USRP2 is automated. This is fastest and easiest way to get a working GNU Radio platform.
The rest of this page is now somewhat outdated and needs some reorganization.
This page provides information and scripts to compile and install GNU Radio and its required background applications, libraries, and includes on Ubuntu Linux 6.10 ("Edgy") or newer; they can probably be applied to some previous versions, though that hasn't been tested.
Installation on Ubuntu 6.10 ("Edgy") can be completed for the most part using binary packages and a package manager, but some packages must be downloaded and compiled from source.
Installation on Ubuntu 7.04 ("Feisty") or newer systems can be completed entirely using binary packages and a package manager, or may be done by download and source compile.
NOTE: The official releases of GNU Radio, version 3.0.3 or earlier, will *NOT* reliably function on Feisty when using a USRP; the USRP will work once, then fail and require the USRP to be power cycled or Ubuntu to be rebooted. Fixes for correct functionality are available in the SVN trunk.
The following packages are required for compiling various parts of GNU Radio on Ubuntu. These packages can be installed via "synaptic", "dselect", or "apt-get". Use the latest versions of all packages unless otherwise noted.
The following are scripts to take most users through a GNU Radio install on a typical Ubuntu install, with the hope that it provides enough guidance such that you can get GNU Radio up and running on your Ubuntu box.
* This section is for Edgy or previous only (no changes are needed on Feisty or newer, except possibly to disable the CDROM entry):sudo <EDITOR> /etc/apt/sources.list
deb http://us.archive.ubuntu.com/ubuntu/ DIST main restricted universe multiverse deb http://us.archive.ubuntu.com/ubuntu/ DIST-updates main restricted universe multiverse deb http://security.ubuntu.com/ubuntu/ DIST-security main restricted universe multiverseUpdate the local dpkg cache:
sudo apt-get update
Install required packages (some are likely already installed by Ubuntu by default; some are likely redundant with others; but these groups cover all of the required packages, except for in Edgy)
* Lucid (10.04):sudo apt-get -y install libfontconfig1-dev libxrender-dev libpulse-dev swig g++ automake libtool python-dev libfftw3-dev \ libcppunit-dev libboost-all-dev libusb-dev fort77 sdcc sdcc-libraries \ libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev \ libqt4-dev python-numpy ccache python-opengl libgsl0-dev \ python-cheetah python-lxml doxygen qt4-dev-tools \ libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools* Karmic (9.10):
sudo apt-get -y install swig g++ automake libtool python-dev libfftw3-dev \ libcppunit-dev libboost1.38-dev libusb-dev fort77 sdcc sdcc-libraries \ libsdl1.2-dev python-wxgtk2.8 subversion git-core guile-1.8-dev \ libqt4-dev python-numpy ccache python-opengl libgsl0-dev \ python-cheetah python-lxml doxygen qt4-dev-tools \ libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools* Jaunty (9.04): **Package sdcc-nf needs to be installed (instead of sdcc)**
sudo apt-get -y install swig g++ automake1.9 libtool python-dev fftw3-dev \ libcppunit-dev libboost1.35-dev sdcc-nf libusb-dev \ libsdl1.2-dev python-wxgtk2.8 subversion git guile-1.8-dev \ libqt4-dev python-numpy ccache python-opengl libgsl0-dev \ python-cheetah python-lxml doxygen qt4-dev-tools \ libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools
sudo apt-get -y install swig g++ automake1.9 libtool python-dev fftw3-dev \ libcppunit-dev libboost1.35-dev sdcc-nf libusb-dev \ libsdl1.2-dev python-wxgtk2.8 subversion git guile-1.8-dev \ libqt4-dev python-numpy ccache python-opengl libgsl0-dev \ python-cheetah python-lxml doxygen qt4-dev-tools \ libqwt5-qt4-dev libqwtplot3d-qt4-dev pyqt4-dev-tools* Hardy (8.04): **Boost should be installed as explained in README.building-boost file **
sudo apt-get -y install swig g++ automake1.9 libtool python-dev fftw3-dev \ libcppunit-dev sdcc libusb-dev libasound2-dev libsdl1.2-dev \ python-wxgtk2.8 subversion guile-1.8-dev libqt4-dev python-numpy-ext \ ccache python-opengl libgsl0-dev python-cheetah python-lxml doxygen \ libqwt5-qt4-dev libqwtplot3d-qt4-dev qt4-dev-tools* Gutsy (7.10): **Boost should be installed as explained in README.building-boost file. GSL is required Also **
sudo apt-get -y install g++ automake libtool python-dev fftw3-dev \ libcppunit-dev sdcc libusb-dev libasound2-dev \ libsdl1.2-dev python-wxgtk2.8 subversion guile-1.8-dev libgsl0-dev \ libqt3-mt-dev python-numpy-ext swig ccache* Feisty (7.04): **Boost should be installed as explained in README.building-boost file. GSL is required Also **
sudo apt-get -y install g++ automake1.9 libtool python-dev fftw3-dev \ libcppunit-dev sdcc libusb-dev libasound2-dev \ libsdl1.2-dev python-wxgtk2.8 subversion guile-1.6-dev\ libqt3-mt-dev python-numpy-ext swig ccache* Edgy (6.10): **It is strongly recommended that you use one of the newer releases above**
sudo apt-get -y install g++ automake1.9 libtool python-dev fftw3-dev \ libcppunit-dev libboost-dev sdcc libusb-dev libasound2-dev \ libsdl1.2-dev python-wxgtk2.6 subversion guile-1.6-dev \ libqt3-mt-dev python-numpy-ext ccache
sudo apt-get -y install gkrellm wx-common libwxgtk2.8-dev alsa-base autoconf xorg-dev g77 gawk bison openssh-server emacs cvs usbview octaveFor Edgy only: Get, Compile, and Install SWIG
wget http://prdownloads.sourceforge.net/swig/swig-1.3.33.tar.gz tar zxf swig-1.3.33.tar.gz cd swig-1.3.33 ./configure make sudo make install cd ..Optional: Get, Compile, Install QWT 5.0.0 (or newer): * NOTE: You should not need to set the environment variables "QTDIR" or "QWT_CFLAGS", so leave them be (for now).
wget http://superb-east.dl.sourceforge.net/sourceforge/qwt/qwt-5.0.2.tar.bz2 tar jxf qwt-5.0.2.tar.bz2 cd qwt-5.0.2* Now edit qwtconfig.pri: ** Change the unix version of "INSTALLBASE" to "/usr/local" (was "/usr/local/qwt-5.0.2"); ** Change "doc.path" to "$$INSTALLBASE/doc/qwt" (was "$$INSTALLBASE/doc"); ** Save, exit.
qmake make sudo make install cd ..
For Ubuntu 8.04 and older, download and install Boost 1.35 or later as follows (see README.building-boost file):
1) Download the latest version of boost from boost.sourceforge.net (boost_1_37_0.tar.bz2 was the latest when this was written).
2) unpack it somewhere and cd into the resulting directory$ cd boost_1_37_0
3) Pick a prefix to install it into. For example use /opt/boost_1_37_0
$ BOOST_PREFIX=/opt/boost_1_37_04) Configure
$ ./configure --prefix=$BOOST_PREFIX --with-libraries=thread,date_time,program_options5) Compile the package
$ make6) Install the package
$ sudo make install $ cd ..
# Install GNU Radio from git git clone http://gnuradio.org/git/gnuradio.git cd gnuradio export LD_LIBRARY_PATH=$BOOST_PREFIX/lib # As per the instructions for installing Boost ./bootstrap ./configure --with-boost=$BOOST_PREFIX # As per the instructions for installing Boost makeOptionally: Run the GNU Radio software self-check; does not require a USRP.
make check
sudo make installUbuntu uses udev for handling hotplug devices, and does not by default provide non-root access to the USRP. The following script is taken from directions, and sets up groups to handle USRP via USB, either live or hot-plug
sudo addgroup usrp
sudo usermod -G usrp -a <YOUR_USERNAME>
echo 'ACTION=="add", BUS=="usb", SYSFS{idVendor}=="fffe", SYSFS{idProduct}=="0002", GROUP:="usrp", MODE:="0660"' > tmpfile
sudo chown root.root tmpfile
sudo mv tmpfile /etc/udev/rules.d/10-usrp.rules
* At this point, Ubuntu is configured to know what to do if/when it detects the USRP on the USB, except that "udev" needs to reload the rules to include the newly created one. The following might work, but if it doesn't then rebooting the computer will.sudo udevadm control --reload-rules
sudo /etc/init.d/udev stop sudo /etc/init.d/udev start
sudo killall -HUP udevdYou can check if the USRP is being recognized, by examining /dev/bus/usb after plugging in a USRP. Using the command:
ls -lR /dev/bus/usb | grep usrp
crw-rw---- 1 root usrp 189, 514 Mar 24 09:46 003
Once you've verified that the USRP is available to Ubuntu, now it is time to verify that GNU Radio works with the USRP (if installed; if not, skip this). While "usrp_benchmark_usb" might not return a full 32 MB/s of throughput, the script should at least run properly; if not, either GNU Radio didn't make correctly or the USRP isn't accessible. From the "gnuradio" directory, verify that all of the following work:
* Python interface to the USRP; provides a rough estimate of the maximum throughput (quantized to a power of 2) between the host computer and the USRP.cd gnuradio-examples/python/usrp ./usrp_benchmark_usb.py* C++ interface to the USRP; provides a good estimate of the maximum throughput (non-quantized) between the host computer and the USRP.
cd usrp/host/apps ./test_usrp_standard_tx ./test_usrp_standard_rxUpdate the rest of the system, after which you might need or want to reboot:
sudo apt-get -y upgradeUpdate the Linux distro, after which a reboot is required:
sudo apt-get -y dist-upgrade
Because Debian and Ubuntu apply a poorly implemented "enhancement" to the upstream version of libtool,
they break the ability to test code and libraries prior to installing them. We think that testing before
installation is a good idea. To work around their damage, be sure to include
$PREFIX/lib (and $PREFIX/lib64 on 64-bit machines) in /etc/ld.so.conf.
If you don't include $PREFIX/lib in /etc/ld.so.conf, you will see errors during the linking phase
of the build. There are several places it shows up. The first one is often during the build of
mblocks. It's not an mblock problem. It's a Debian/Ubuntu problem.
Do this to work around this "feature":
1) Make a copy from the current ld.so.conf file and save it in a temp folder:cp /etc/ld.so.conf /tmp/ld.so.conf2) Add /usr/local/lib path to it :
echo /usr/local/lib >> /tmp/ld.so.conf3) If you installed Boost (version 1_37_0 for example) manually, then add its library path to the file:
echo /opt/boost_1_37_0/lib >> /tmp/ld.so.conf4) Delete the original ld.so.conf file and put the modified file instead:
sudo mv /tmp/ld.so.conf /etc/ld.so.conf5) Do ldconfig:
sudo ldconfig
The udev daemon is used by some Linux distributions to handle plug/unplug events for usb devices.
Follow these steps to allow users other than root to use the USRP:
1. Define a group for the usrp
sudo groupadd usrp
2. Add users to the usrp group
sudo usermod -G usrp [username]
3. Add a new udev rule
echo 'ACTION=="add", BUS=="usb", SYSFS{idVendor}=="fffe", SYSFS{idProduct}=="0002", GROUP:="usrp", MODE:="0660"' > tmpfile
sudo chown root.root tmpfile
sudo mv tmpfile /etc/udev/rules.d/10-usrp.rules
4. Load the new udev rule
sudo udevadm control --reload-rules
Power cycle the usrp device and:
lsusb | grep fffe:0002
You should see an entry with ID: fffe:0002
ls -lR /dev/bus/usb
You should see a device file with group usrp and mode crw-rw----
The schematics for all Ettus Research products, including the USRP, USRP2, and all daughterboards are available here:
http://code.ettus.com/redmine/ettus/projects/public/documents
The USRP2 builds on the success of the original USRP, and adds these new features:
Not all features are currently ready for production use. The USRP2
is initially supported on Linux, and we anticipate that drivers
for Windows, Mac OS X, and other systems will be developed in the
coming months.
Everything we need to have done before the first shipment of the USRP2.
In order to use the DBSRX receive daughterboard with the USRP2, you will need to modify the the DBSRX hardware.
According to the manufacturer:
"This will only work if you have a DBSRX which says "Rev 2.2". This
should be most units from 2007, and everything from 2008 or 2009. It
will not work with older DBSRX boards. For those, there is no way to
use them with the USRP2."
Support for the DBSRX in USRP2 requires using at least revision 10524 (February 26, 2009) of the GNU Radio trunk software, the USRP2 FPGA image, and USRP2 firmware. These last two may be obtained at http://gnuradio.org/releases/usrp2-bin/trunk and are installed on the USRP2 SD card.
There are 2 steps to the process:
Call "usrp2_probe" to verify the DBSRX daughterboard ID. After successful burning, it should change from 2 to 13.
| USRP1 | USRP2 | |
| Interface | USB 2.0 | Gigabit Ethernet |
| FPGA | ltera EP1C12 | Xilinx Spartan 3 2000 |
| RF Bandwidth to/from host | 8 MHz @ 16bits | 25 MHz @ 16bits |
| Cost | $700 | $1400 |
| ADC Samples | 12-bit, 64 MS/s | 14-bit, 100 MS/s |
| DAC Samples | 14-bit, 128 MS/s | 16-bit, 400 MS/s |
| Daughterboard capacity | 2 TX, 2 RX | 1 TX, 1 RX |
| SRAM | None | 1 Megabyte |
| Power | 6V, 3A | 6V, 3A |
XC3S2000-5FGG456, That is the Spartan 3 2000, fast speed grade (-5), 456 pin BGA package.
You would need two USRP2s linked with a MIMO cable in order to have 2 coherent receivers. The exception is if you use your own external RF downconverters, in which case you can connect two of them to one BasicRX.
Please note that the USRP2 uses a Spartan 3-2000 chip. This means that if you intend to do your own FPGA development, you need to use the full version of the Xilinx tools in order to generate an image for it. You cannot use the free web pack version. Thus there are several options for you:
There are 3 things necessary to get MIMO working.
1. All systems need to be phase-locked to a common clock (10 MHz in this case)
2. All systems need to have a common time reference (often a 1 PPS signal) so that they know which sample in one system corresponds to which sample in the other
3. All the data needs to come from / go to the same place
The MIMO Expansion interface on the USRP2 carries all 3 of those.
Scenario 1 - Two USRP2 systems connected by a MIMO cable:
The Master USRP2 is the one connected to both ethernet and the MIMO cable.
The Slave USRP2 is the one connected to just the MIMO cable.
The master provides a clock to the slave over the MIMO cable.
The master provides the time reference to the slave over the MIMO cable.
On transmit, the host sends all data over the ethernet to the master.
The master uses the data which is intended for the master, and passes the data for the slave over the MIMO cable.
On receive, the slave sends all data over the MIMO cable to the master, and the master passes it back to the host over ethernet. It also sends its own data over the ethernet to the host.
The firmware and host driver code to do this is not ready yet, but is in progress. (14 November 2008)
Scenario 2 - Up to Four USRP2 systems connected by MIMO cables to the not-yet-in-existence HUB:
The HUB has a big FPGA on it.
The HUB provides clock and time reference to all USRP2 systems.
The HUB communicates with the host computer by ethernet or PCI Express, or operates standalone.
All USRP2 systems send data back and forth to the HUB.
The HUB is not ready yet, but the design is in progress. We hope to have it ready in 9-12 months. (14 November 2008)
Scenario 3 - An arbitrary number of USRP2 systems, no MIMO cables, no HUB:
Some means of providing the same 10 MHz reference to all USRP2 systems must be set up. Typically this would be the 10 MHz output of some lab reference like a GPS-locked reference. That reference would be put through some sort of active splitter, and fed into all the USRP2s by SMA connector on the front panel.
Some means of providing the same time reference to all USRP2 systems is also needed. This would normally be a 1 PPS signal generated by the same reference. It will need to go through some sort of active splitter and send into the PPS input of all the USRP2 systems.
ALL the USRP2 systems will need to be connected to the host computer by gigabit ethernet. You can probably use an ethernet switch, but there will be issues with sharing the bandwidth.
The firmware to do this is ready. The host code to do it is not ready yet. (14 November 2008)
The USRP2 uses a 100 MHz clock internally. That clock will be locked to the 10 MHz reference you provide.
Samples can be time stamped, and that time can be calibrated to the 1 PPS signal. In the most general case, that 1 PPS input just goes directly to the FPGA, so internally you can do whatever you want with it.
The 1 PPS input goes to an FPGA pin, so you can program the FPGA to do whatever you want. This includes accepting faster sync pulses, encoded timestamps, Morse code, etc.
The Reference input can take a square or sine wave input that is DC-blocked and terminated in 50 ohms. The input should be less than 3V pk-pk.
The PPS input is not DC blocked. It is AC terminated in 50 ohms, DC terminated in 1K ohms. The digital signal you put in should be between 0 and 5 V. It should never go below 0V and never above 6V.
The PPS signal should be synchronous to the 10 MHz reference. Nearly any GPS frequency reference should work. Everything from http://jackson-labs.com would suffice.
In the standard FPGA build we provide right now, it isn't used at all. One could set it up for a number of different uses:
All of the above would require some Verilog coding on your part.
The MIMO connector brings the frequency reference from one USRP2 to the other. If you wish to use an external frequency reference to lock both USRP2s, you would feed it to the first USRP2, and the MIMO connector will deliver it to the 2nd.
Not directly. Eventually, we will be selling another device to allow you to connect more than 2 USRP2s together (most likely 4), but for now you would be limited to 2.
When the 4-way USRP2 link device discussed above is used, and each USRP2 is used with 2 separate RF channels via the BasicRX and BasicTX, you would get 8 channels.
Usually the 2 are used for I and Q from the downconverters, but you can use them separately as well by using the BasicRX.
Actually, you can use 100 MHz as well, you will just need to change one line of the firmware to set the R-divider on the PLL. You can use any frequency for which the following equation has a solution:
100 MHz / N = Ref / R
for which N and R are integers and smaller than 32,768
The internal clock (a very clean VCXO) is locked to the external reference if one is applied. You have a lot of flexibility in selecting the reference frequency (see previous question), but you cannot pull the VCXO further than a few kHz, and you cannot use the reference as the main system clock. So there is no way, for example, to put in a 120 MHz clock and have everything run off of that. You are basically stuck with 100 MHz unless you are willing to solder.
If you are willing to do some soldering, there are pin-compatible VCXOs in other frequencies which are available. The part is the CVHD950 from Crystek, and you can get them from Mouser. Note than anything over 100 MHz may make it hard to get the FPGA to meet timing requirements. Also, the ADC is only specified to 105 MHz, but there is a pin-compatible version spec'ed to 125 MHz.
The 10 MHz reference input on the front is optional. If you connect it and enable locking, the 100 MHz main oscillator will lock to it, otherwise it will free run. Everything inside the FPGA runs at 100 MHz (DSP) or 50 MHz (processor).
There is also a 10 MHz reference clock sent out on the MIMO connector. When turned on, it will be the 100 MHz clock divided down by 10.
It's done with an open source MAC implemented in the FPGA and a National Semicondutor PHY chip, DP83865.
The CPLD (a Xilinx XC9572) reads the first megabyte from the SD card and
writes it to the FPGA config pins in slave-serial mode. Once the FPGA is
configured, it requests the firmware for the aeMB processor from the SD
card. After that, the CPLD is switched over to passthru mode, and the
FPGA has direct access to the SD card under program control.
The main ADC is the Dual 14-bit LTC2284, used at 100 MS/s. There is an auxiliary 2 channels, 12-bit
ADC (the AD7922) for each dboard connector.
The main DAC is the Dual 16-bit AD9777 fed with 100 Ms/s and produces 400 Ms/s based analog output. The auxiliary DACs are the dual 12-bit AD5623.
The same USRP1 16 digital IOs, SPI, and I2C to each daughterboard connector. The whole interface to the daughterboards is the same as the USRP1, except instead of it being implemented all in the AD9862, it is done with the following set:
The DDCs are very similar to the USRP1 with a 4 stage CIC but with 2 HBF filters. The CIC can decimate in the range [1..128]. The high rate HBF has 7 taps and it decimates by 2. The low rate HBF has 31 taps and also decimates by 2.
Again, very similar. There us a 4 stage CIC and 2 HBF filters each working in interpolation mode.

It is identical to the one of the interpolator, see above.

I will explain the RX side, the TX side is basically the same.
small_hb_dec is the short filter which works at the higher rate. There are 2 of them instantiated, one for I and one for Q. It has 7 taps. One of those taps is the center tap which only requires a shift and not a multiply, and 2 of those taps are zeros. That leaves 4 taps. The taps are symmetric, which leaves 2 multiplies per output. Since we have at least 2 cycles to produce each output, we can use a single multiplier.
hb_dec is 2nd halfband filter and it works at the lower rate. There are 2 of them instantiated, one for I and one for Q. It has 31 taps. One of those taps is the center tap which only requires a shift and not a multiply, and half of the remainder are zeros. That leaves 16 taps. They are symmetric, so that means we need to do 8 multiplies to produce each output. There are at least 4 cycles to produce each output, so we need to do 2 multiplies at a time.
One of those multipliers does the "outer" coefficients, meaning the ones at the very beginning and end of the impulse response, and one does the "inner" coefficients, meaning the ones around the center of the impulse response. This division is purely an implementation choice, and does not affect the output. I could have put the odd ones on one mult and the even ones on the other, or any other split you could imagine. It doesn't matter.
Minimum interpolation and decimation is 4 and maximum is 512. If you use odd decimation or interpolation, you just get a CIC with no halfbands. If you use an even rate but not a multiple of 4, you just get one halfband (the low rate one). If your rate is a multiple of 4, you use both halfbands.
The FPGA talks to the DAC at 100 MS/s just like it talks to the ADC at 100 MS/s. The interpolation from 100 MS/s to 400 MS/s happens inside the DAC chip itself. Unless you are doing something fancy, you can think of the
DAC as operating at 100 MS/s.
The primary reason for the x4 interpolation to 400 MS/s is to simplify the analog reconstruction filters. It also allows for a coarse modulation up to 150 MHz, but I don't anticipate that being used very often.
The standard USRP2 FPGA image does not use IP, just raw ethernet.
No, but we have our own, find_usrps
About 20 ppm unless you lock to an external reference.
44 MHz is the highest frequency in the first Nyquist zone on the USRP1.
Much higher frequencies can be used in the higher zones. The USRP2 takes 100 MS/s rates and interpolates up to 400 MS/s. Direct
frequencies up to ~170 MHz should be usable. The code that initializes the DAC is in u2_init.c
Currently, overruns are shown on the UART port and not on the host. They
are shown with a "O". The reality is that you should never see them.
If the host computer can't keep up, you will see an "S" messages in the
terminal on the host that indicates a sequence number error.
Under runs are shown on the UART port as "U".
In the FPGA code, the tx_control.v and rx_control.v show inband
signalling, dsp_core_rx and dsp_core_tx show the DSP, and u2_core.v is
the top level. In the firmware, start with txrx.c.
37 out of 40 block RAMs, 16 or 18 of the 40 multipliers, and about 35 to
40% of the logic area.
The serial is TTL level with 230400 baud, 8N1 format
The scaling itself is done in the DSP pipeline in the FPGA.
The aeMB processor is a fully synthesized CPU that forms the heart of
the USRP2 FPGA system-on-a-chip design. It performs configuration and
status reporting for all the FPGA peripherals, manages the control
channel for the GbE transport, and handles RF daughterboard operation.
It does not perform any DSP functions; these are done purely in logic
in the DSP RX and TX pipelines. It is clocked at 50 MHz, half the
system clock rate.
The USRP2's MAC address is stored on the USRP2's motherboard EEPROM.
At start-up, all 6 LEDs will flash and 2 will remain ON. The bottom one shows that the FPGA is configured. The next one up shows that the firmware is running. The others are unused.
The following is a chart of the status of Gigabit Ethernet cards and how well they seem to work with the USRP2. Some may require special settings, which should be listed below. Please add information about card you have had success or problems with.
| Chipset | Brand/Motherboard | Interface | Driver | Good/Bad/? | Reported By | Notes | ||||||||
| Agere ET131x | StarTech ST1000BTPEX | PCIe | et131x | Bad | ematlis | Problems on Linux in general | ||||||||
| Broadcom BCM5755M | Dell motherboards | PCIe | tg3 | Good | matt | |||||||||
| Intel PRO/1000 | Intel MB, Thinkpads | PCIe | e1000e | Good | matt | |||||||||
| Intel 82566 | Intel 82566MM GLAN | PCIe | e1000 | Good | Firas | |||||||||
| Intel 82572EI | PCIe | e1000e | Good | ematlis | ||||||||||
| Intel 82572L | Thinkpad T60 | PCIe | e1000e | Good | jcorgan | |||||||||
| Intel 82575EB | Supermicro 7045A-WTB | PCIe | igb | Good | jcorgan | |||||||||
| Marvell 88E8001 | D-Link DGE-530T | PCI | skge | Ok | matt | Trouble keeping up at highest data rates | ||||||||
| Marvell 88E8052 | D-Link DGE-560T | PCIe | sky2 | Good | matt | Very similar to 88E8056 | ||||||||
| Marvell 88E8055 | Fujitsu-Siemens laptop | PCIe | sky2 | Good | azimout | |||||||||
| Marvell 88E8056 | Common | PCIe | sky2 | Good | matt | |||||||||
| Marvell 88E8058 | Linux on MacBook Pro | PCIe | sky2 | Good | geiger | |||||||||
| Marvell Yukon2 | Belkin Gigabit Express | ExpressCard | sky2 | Good | trnewman | May require special settings | ||||||||
| RealTek 8169 | NetGear GA-311, TrendNet TEG-PCITXR | PCI | r8169 | Bad? | blt | Works for others (ettus, xil, Firas) | ||||||||
| RealTek 8168/8111 | Realtek RTL 8168/8111 PCI-E Gigabit | PCIe | r8169 | Good | Firas | |||||||||
| RealTek RTL8111B | Startech ST1000SPEX | PCIe | Good | EricS | no problems with Ubuntu. Fast | |||||||||
| SIS968 | ASUS P5S-MX SE MB | Southbridge | sis968 | Bad | hl1oap | Problems on Linux in general |
USRP2 Schematics
The most recent schematics for Ettus Research products can be found here:
http://code.ettus.com/redmine/ettus/projects/public/documents
The SD Card hold the FPGA configuration and microprocessor firmware. You can also store data on the rest of the card, but that is currently not implemented in the firware.
The USRP2 needs to have the SD card plugged in to operate. And the SD card needs to be programmed with a valid FPGA configuration and firmware build. Without this the USRP2 does nothing but sit there. The SD card is NOT optional. If you put it in the slot on the USRP2 and power up the USRP2, you should see all 6 LEDs flash, and 2 will remain on. If you don't, then the card is not programmed properly.
The SD card that came with the USRP2 is preprogrammed with a build which was the latest at the time when it shipped. You can always find the latest released versions at http://code.ettus.com/redmine/ettus/projects/public/wiki/U2binaries . To build your own firmware you will need to install the Microblaze tools http://gnuradio.org/tools. To build the FPGA yourself you'll need to use the full (pay) version of Xilinx ISE 10.1.03.
Some SD Cards shipped in Nov and Dec of 2009 (Blue, 2GB Patriot brand) will not work. Go to http://ettus.com/flash for more details on how to get a replacement.
The SD card does NOT contain a filesystem, and you will NOT be able to read or write it using normal tools.
To change the firmware and FPGA code, you need an SD card programmer. These are available from Ettus Research, or at your local electronics store. Here are the steps to upgrade the firmware:
sudo u2_flash_tool --dev=/dev/XXXX -t s/w usrp2/firmware/txrx.bin -w
Here are the steps to upgrade the FPGA code on the SD card:
sudo u2_flash_tool --dev=/dev/XXXX -t fpga u2_rev3.bin -w
To find out what XXXX is, you can goto http://vic.gedris.org/linux-UsbMassStorage/ which tells you to do the following steps to determine which device you would like to flash.
$sudo apt-get update $sudo apt-get install sg3-utils
$sudo sg_scan -i
$sudo sg_map
For the USRP2 + WBX combination use the txrx_wbx_raw_eth_20100608.bin firmware. The default firmware that comes with the USRP2 SD card needs to be replaced with the txrx_wbx firmware to work the WBX module, with the SMA connector connected to the TX/RX port on the WBX module.
It is strongly recommended that the USRP2 be connected directly to the host computer via gigabit ethernet. You can use a switch, but your system's main network connection should be separate. Also, operation at 10 or 100 mbps instead of 1 Gbps is not currently supported. The hardware is capable, but the current FPGA verilog code disables it for a variety of reasons.
The first question to answer is how you want to attach the gigabit ethernet interface to the computer:
| PCI Express (also known as PCIe) | Strongly suggested, as it is the fastest interface commonly available. |
| PCI | Plain old PCI is 32 bits wide and 33 MHz. This is not really fast enough to handle the full USRP2 capabilities, but will work for most users. 64 Bit and/or 66 MHz variations of PCI would be better, but are not very common. |
| PCI-X | This is NOT the same as PCI Express. It is faster than plain PCI, and so is preferable to it, but is not very common. |
| USB 2.0 | This is simply nowhere near fast enough for our purposes and its use is strongly discouraged. If you wish to use USB 2.0, we suggest using it with the USRP1. |
| PCMCIA/CardBUS | CardBUS is a plain old PCI bus with a PCMCIA card form factor. See PCI above. |
| ExpressCard | ExpressCard is PCI Express in a card form factor. These should work fine as long as the drivers exist for your card. Some of these cards (perhaps all) will cause the kernel to "oops", or crash your whole machine, if you pull them out while in operation, so be careful. |
Most Gigabit Ethernet interfaces built onto a motherboard or into a laptop are either PCI Express (mostly newer systems) or plain PCI (older systems).
For further info, see USRP2GigEReports
Your Ethernet interface is not autonegotiating flow control properly. You can force the correct settings on your ethernet card by running the following command:
ethtool -A eth0 rx on
You should replace "eth0" with the ethernet interface you are actually using, usually eth0 or eth1. You will probably need to run this command every time you boot, and will probably need to run it as root.
The first step is to update to the latest svn for the entire gnuradio tree, and get it all installed. Then, run:
find_usrps
Run
usrp2_fft.py
usrp2_fft.py -h
S means that the PC is seeing 2 successive packets which do not have 2 successive sequence numbers. This means that the host computer has dropped the packets in between. It is essentially the equivalent of an overrun. The USRP2 does not actually overrun, however, since it is not throttled by the host computer.
You'll need to download or build the gcc toolchain first. If you're on x86 or x86_64 linux, we've got a binary tarball that you can download and unpack into /opt.
$ wget http://gnuradio.org/tools/mb-gcc-4.1.1.gr2.i386.tar.gz
Once you've downloaded the tarball,
$ sudo bash # cd /opt # tar xzvf <path-to-tarball>
Then add /opt/microblaze/bin to PATH ( export PATH=$PATH:/opt/microblaze/bin ) and you're good to go.
NOTE -- This may not work on Fedora 10 x64_64. See below.
$ svn export http://gnuradio.org/svn/gnuradio/trunk/dtools/microblaze/mb-gcc-4.1.1-gr-1.patch $ wget http://gnuradio.org/tools/EDK101_GPL_GNU_src.tar.gz $ tar -xzvf EDK101_GPL_GNU_src.tar.gz $ patch -p1 <mb-gcc-4.1.1-gr-1.patch $ cd Xilinx_EDK_GNU_10.1i/mb $ /bin/bash ./build_binutils.sh $ /bin/bash ./build_gcc.sh $ cp -r release/lin/mb /opt/microblaze
(Older directions at http://www.aeste.net/index.php?q=node/16. Doesn't include patch that reduces size of libgcc 64-bit support routines.)
On Fedora 10, you will need to install compat-gcc-34-3.4.6-9.x86_64 and then run the build commands like this:
$ CC=/usr/bin/x86_64-redhat-linux-gcc34 /bin/bash ./build_binutils.sh $ CC=/usr/bin/x86_64-redhat-linux-gcc34 /bin/bash ./build_gcc.sh
The debug port is a standard Mictor connector which is often used with logic analyzers from Agilent and Tektronix. It has 2 clock pins and 32 data pins. All 34 of those are directly connected to the FPGA, so you can do whatever you want with them.
If you plug in a BasicRX (or LFRX) and a BasicTX (or LFTX), you will have an additional 32 bits of IO which can also be used for debugging. This gives a total of 64 bits plus 2 clocks for debug.
Yes, there is a standard JTAG header on the board connected to the FPGA and a CPLD, but you may not need it. Since the FPGA is programmed from the SD Card by the bootstrapping CPLD, the main utility of the JTAG port is to reprogram the CPLD. You may be able to use the JTAG port with ChipScope.
The expansion port is pretty straightforward. It uses a serial-attached SCSI (mini-SAS) cable. The cable has 4 lanes. Each lane consists of 1 differential pair input and 1 differential pair output. All lanes are AC (capacitor) coupled. The 4 lanes are allocated as follows:
1 - High-speed SERDES, 2 gbps 8B10B encoded. This interface is handled by a TLK2701 from TI, and it connects to the FPGA. You should be able to connect this interface to the RocketIO GTP/GTX transceivers on the virtex 5. Also, see the usrp2/fpga/serdes directory in the SVN repository to see how we handle the interface and protocol, framing, and flow control.
2 - 10 MHz clock reference
3 - Digital IO, connected directly to LVDS IOs on the FPGA. We currently have this set up to do time syncing, but you can do whatever you like with it.
4 - Unused
The code that talks to the USRP2 uses raw socket access (SOCK_RAW) on the ethernet port. This allows the use of a custom ethertype rather than building on a higher level protocol like IP or UDP. The kernel does not allow anyone but root to use raw sockets. This is unlikely to change any time soon. Other tools that use raw sockets must also be run as root or are suid (like ping).
It is possible to allow suid access to the USRP2 by making usrp2_socket_opener suid root. This allows us to use the least privileges possible on all other programs, and usrp2_socket_opener is a nice short program that can easily be audited. Example:
sudo chmod u+s /usr/local/bin/usrp2_socket_opener
Note that if you do a make install again it may overwrite your usrp2_socket_opener, and then it won't have the permissions set anymore. You can avoid this by putting the suid copy in your ~/bin directory, which won't be overwritten every time.
To enable real-time scheduling for non-root users, edit /etc/security/limits.conf and add this line:@usrp - rtprio 50
make sure that your user is a member of group usrp, then logout and back in.
In order to use the DBSRX receive daughterboard with the USRP2, you will need to modify the the DBSRX hardware and reprogram its eeprom. Here are instruction for how to do so.
This document details the current USRP base class, and as we proceed will contain details on the new USRP base class with support for in-band signaling. The current USRP base class is found in [source:/gnuradio/trunk/usrp/host/lib/usrp_basic.cc usrp_basic.cc] as usrp_basic. More information about the class can be found in the usrp_basic doxygen documentation. The inheritance diagram for the usrp_basic class is as follows:
http://gnuradio.org/doc/doxygen/classusrp+basic+inherit+graph.png
Some functionality that the base class gives access to are the FPGA registers, AD9862 registers, I2C peripheral, DAC/ADC, and the EEPROMs for the motherboard and daughterboards.
usrp_basic¶1. Load the USRP firmware with usrp_load_firmware_nth()
1. Load the FPGA bitstream with usrp_load_fpga()
1. Initialize the common RX and TX AD9862 registers
usrp_standard_rx¶1. Set the format of the RX data via the control register (FR_RX_FORMAT)
1. Set the number of channels (FR_TX_MUX)
1. Set the decimal rate between 4 and 256 (FR_DECIM_RATE)
1. Set the mux (FR_RX_MUX)
1. Set the FPGA mode (FR_MODE)
1. For each channel, initialize the RX frequencies and the DDC phases to 0 (FR_RX_FREQ_* FR_RX_PHASE_*)
usrp_standard_tx¶1. Initialize AD9862 TX registers
1. Set the number of channels (FR_TX_MUX)
1. Set transmission interpolation rate from 4 to 512, a multiple of 4 (FP_INTERP_RATE)
1. Set the mux (FR_TX_MUX)
1. For each channel, initialize the TX frequency to 0 (FR_TX_FREQ_*)
Having synchronized clocks throughout the entire transceiver chain allows you to build MIMO systems, smart antennas, phased arrays, and interferometers. The USRP was designed with this capability in mind. Below are some notes on how to use it.
If you have multiple daughterboards in a system, and desire phase coherence, you will have to take these steps, depending on your daughterboards
To synchronize the clocks on multiple USRPs, you must convert them to use a common reference clock. This is done as follows:
Specifications
RX: 1MHz - 250MHz
TX: N/A
The BasicTX and BasicRX are designed for use with external RF frontends as an intermediate frequency (IF) interface. The ADC inputs
and DAC outputs are directly transformer-coupled to SMA connectors (50Ω impedance) with no mixers, filters, or amplifiers.
The BasicTX and BasicRX give direct access to all of the signals on the daughterboard interface (including 16 bits of high-speed digital I/O, SPI and I2C buses, and the low-speed ADCs and DACs), and as such are useful for developing your own daughterboards or custom FPGA designs.
NOTE: It is possible for the BasicRX board to go down to 100kHz, but YMMV.
While the BasicRX has two antennas (A and B), the driver presents 3 subdevices: 0, 1 and 2.
Subdevice0 is the antenna A, Subdevice1 is the antenna B. You can use both subdevice 0 and 1 at the same time on two different ddc inputs and tune them separately. These subdevices are used as real inputs, and the Q inputs to the ddc are set to zero.
The third possibility is to use subdevice2 which treats the antenna A and B as a single complex input (I and Q), and connects them to the I and Q inputs of the DDC input0. When using subdevice2, you cannot use subdevice 0 and 1.
(Thanks to Josh Blum for the clarification)

Specifications
RX: N/A
TX: 1MHz - 250MHz
The BasicTX and BasicRX are designed for use with external RF frontends as an intermediate frequency (IF) interface. The ADC inputs and DAC outputs are directly transformer-coupled to SMA connectors (50Ω impedance) with no mixers, filters, or amplifiers.
The BasicTX and BasicRX give direct access to all of the signals on the daughterboard interface (including 16 bits of high-speed digital I/O, SPI and I2C buses, and the low-speed ADCs and DACs), and as such are useful for developing your own daughterboards or custom FPGA designs.
NOTE: It is possible for the BasicTX board to go down to 100kHz, but YMMV.

Specifications
RX: 800MHz - 2.4GHz
TX: N/A

This section contains a collection of notes regarding the DBSRX daughterboard.
The frequency range and maximum and minimum bandwidth given in the MAX2118 is different from the one stated in the datasheet from www.ettus.com. Matt Ettus explains the differences:
The MAX2118 datasheet says that it covers 925 to 2175 MHz. They spec that because it is the range that their typical customer needs (for small satellite dish IFs). However, I have never found one which doesn't work to the larger 800 MHz to 2400 MHz range. Maxim guarantees 925 to 2175, I guarantee the larger range.
When Maxim states that their maximum LPF bandwidth is 33 MHz, they mean one-sided bandwidth (i.e. 0 to 33 MHz). Since it is used in a direct conversion IQ system, that actually gives a 66 MHz bandwidth (-33 MHz to +33 MHz). Since that is beyond Nyquist for our ADC, I spec to 60 MHz (+/- 30 MHz).
On the low end, they specify 4 MHz, which is really 8 MHz (+/-4 MHz) of RF bandwidth. The filter is actually capable of going to a much narrow frequency, but it is outside of Maxim's specs, since nobody in the small satellite dish market cares about less than 8 MHz of BW. So I spec that it goes down to 1 MHz wide. It should be noted that when you go below 4 MHz wide (2 MHz in Maxim-speak) that your noise floor will rise a bit and phase noise may also rise.
Taken from an email to discuss-gnuradio on 27 Mar 2007 from Gregory W Heckler:
Tuning the down-converter on the DBS-RX card consists of programming the values of 2 dividers. The R divider divides down the reference clock frequency (4 MHz, which derives from the 64 MHz board clock). The N divider divides down the LO frequency. The R divider has a range from 2 to 256, the N divider from 256 to 32768. The Max2118 phase locks the divided LO frequency to the divided reference clock frequency, or:
LO = N*(Refclk_Freq/R)
However, the PLL in the Max2118 is unstable if you divide down the reference clock frequency to below 250 kHz, this effectively limits the frequency resolution at which you can command the LO frequency.
Taken from an email to discuss-gnuradio on 11 Jul 2007 from Matt Ettus:
Shorting J101 puts 5 Volts (up to 500 mA I believe) on the antenna line. Applying voltage to J100 pin 1 allows you to send bias other than 5V.
Nice Block diagram produced by Gregory W Heckler.

Specifications
RX: DC - 30MHz
TX: N/A
While the LFRX has two antennas (A and B), the driver presents 3 subdevices: 0, 1 and 2.
Subdevice0 is the antenna A, Subdevice1 is the antenna B. You can use both subdevice 0 and 1 at the same time on two different ddc inputs and tune them separately. These subdevices are used as real inputs, and the Q inputs to the ddc are set to zero.
The third possibility is to use subdevice2 which treats the antenna A and B as a single complex input (I and Q), and connects them to the I and Q inputs of the DDC input0. When using subdevice2, you cannot use subdevice 0 and 1.
(Thanks to Josh Blum for the clarification)

Specifications
RX: N/A
TX: DC - 30MHz

Specifications
RX: 1150MHz - 1450MHz
TX: 1150MHz - 1450MHz @ 200+mW

Specifications
RX: 1.5GHz - 2.1GHz
TX: 1.5GHz - 2.1GHz @ 100+mW

Specifications
RX: 2.3GHz - 2.9GHz
TX: 2.3GHz - 2.9GHz @ 10+mW
The board features an ISM band filter that suppresses the RF signal outside the 2402-2480 MHz band and attenuates it within such band by one dB or two.
If usage of the board outside the ISM band is required (and authorized by terms of applicable law in the country of operation), the filter can be bypassed by cutting the traces to the filter FIL.1 and soldering a 20pF to 220pF capacitor (0603 size) in parallel to it.

RX: 400MHz - 500MHz
TX: 400MHz - 500MHz @ 100+mW
The RFX400 uses 2 of the ADF4360-7 VCO/PLL chips from Analog Devices, one on TX and one on RX. The way the board is designed, the output frequency of the VCO/PLL is divided by 2 to give the actual channel frequency. For example, since the RFX400 covers 400-500 MHz, the VCO/PLL actually tunes from 800-1000 MHz. If you want to cover 136-174MHz, you would have to design for 272-348 MHz.
The frequency range of the ADF4360-7 is controlled by 2 inductors, L31 and L32 on RX, and L105 and L116 on TX. They are 0402-sized, and ship with 4.3nH installed. The ADF4360-7 datasheet has instructions on how to select the inductors for your desired frequency range. If you are ordering the inductors, I would suggest not only ordering the value you think you need, but also ordering at least one bigger and one smaller value since the calculations in the datasheet are not exact.
Other things to note:

Specifications
RX: 800MHz - 1000MHz
TX: 800MHz - 1000MHz @ 200+mW

The board features an ISM band filter that suppresses the RF signal outside the 902-928 MHz band and attenuates it within such band by one dB or two.
If usage of the board outside the ISM band is required (and authorized by terms of applicable law in the country of operation), the filter can be bypassed by cutting the traces to the filter FIL.1 and soldering a 100pF capacitor in parallel to it.
Specifications
RX: 50MHz - 860MHz
TX: N/A

Specifications
RX: 50MHz - 2.2GHz
TX: 50MHz - 2.2GHz
This section intends to clarify various issues that might arise while using the USRP. This section has been prepared based on the document The USRP under 1.5X Magnifying Lens.
| << FPGAVerilog Questions | ^ Top ^ | Controlling FPGA Registers >> |
| << FPGAVerilog Questions | ^ Top ^ | Controlling FPGA Registers >> |
| << Motherboard Re-Clocking | ^ Top ^ | Timing Latency >> |
When using GNU Radio USRP functions, the host library takes care of loading the “.rbf” file into the FPGA for you. This takes place over the USB.
However, you can manually load the .rbf using the usrper command:
$ usrper --help
usage:
usrper [-v] [-w <which_board>] [-x] ...
usrper load_standard_bits
usrper load_firmware <file.ihx>
usrper load_fpga <file.rbf>
usrper write_fpga_reg <reg8> <value32>
usrper set_fpga_reset {on|off}
usrper set_fpga_tx_enable {on|off}
usrper set_fpga_rx_enable {on|off}
----- diagnostic routines -----
usrper led0 {on|off}
usrper led1 {on|off}
usrper set_hash0 <hex-string>
usrper get_hash0
usrper i2c_read i2c_addr len
usrper i2c_write i2c_addr <hex-string>
usrper 9862a_write regno value
usrper 9862b_write regno value
usrper 9862a_read regno
usrper 9862b_read regno
$ usrper load_fpga <name of your .rbf file>will load the .rbf file into the FPGA. Please note that it is possible to permanently damage the USRP by loading buggy code into the FPGA.
The files aren't generated, they are loaded. By default, an rbf is loaded from /usr/local/share/usrp/rev{2,4}. The one used unless you specify the fpga_filename constructor argument when instantiating a usrp source or sink is std_2rxhb_2tx.rbf. FYI, we load std.ihx, standard firmware for the Cypress FX2 USB controller, before loading the FPGA .rbf file. We load the FX2 firmware over the USB. That firmware implements additional control endpoint commands, including those that know how to load an .rbf into the FPGA.
| << Motherboard Re-Clocking | ^ Top ^ | Timing Latency >> |
| << RSSI Measurement | ^ Top ^ | Loading FPGA Bit Stream >> |
FIXME this section is outdated, from before c++ drivers.
You need a new crystal or an external oscillator. You'll need to change the definition of
1 /*!
2 **** \brief return frequency of master oscillator on USRP
3 */
4 long fpga_master_clock_freq () const { return 64000000; }
in source:usrp/host/include/usrp/usrp_basic.h
Procedure:
I purchased a 44 MHz oscillator from digi-key (p/n 300-7254-1-ND, CSX750FJC44) for $3.38. The first attempt to remove the USRP 64 MHz failed miserably with a pen iron. I purchased a heat gun from digi-key (MA1008-ND) for $52, set it to the 1000 degree setting and the old oscillator came up in about 10 seconds. Installed the new oscillator and checked the 44 MHz clock with a scope. I am using the std_4rx_0tx.rbf FPGA image.
I then tried to run my customized dbs application that records 8-bit I/Q data to a file for me from any of the 802.11b channels. I got all zeros in the data. Then remembered Eric told me to change the clock in source:usrp/host/lib/db_dbs_rx.cc.
My code is a little older than current but here are my modifications:
In source:usrp/host/lib/db_dbs_rx.c changed line 493 from
return 16;to
return 11;
I have been working with fractional rate decimeter/interpolators inside the USRP FPGA. You can put a fractional rate decimeter inside the FPGA which decimates by 6.4.
It is a bit hard to get them to fit but you get a lot of flexibility out of them without changing the clocks. .(#FIXME# is this correct ?)
long fpga_master_clock_freq () const { return 64000000; }
If I want my system to work at 50 MHz, will I need to change this constant?
Yes. The idea was that there was a single place in the code (fpga_master_clock_freq) that "knows" the actual frequency.
You need to go into the [source:gnuradio/trunk/gr-usrp/src/db_flexrf.py db_flexrf.py] and [source:gnuradio/trunk/gr-usrp/src/db_flexrf_mimo.py db_flexrf_mimo.py] files in the [source:gnuradio/trunk/gr-usrp/src gr-usrp/src] directory. Any references to 64 MHz need to be changed to 13 MHz. You also need to make sure that you tell the usrp object what its sampling rate is.
Yes 1V p-p for USRP rev 4. Use 3.3V for rev 2 and 3.
You can drive the clock line anywhere between about 10MHz and 65MHz. Be sure to edit usrp_basic: :fpga_master_clock_freq() to return the new value.
That's an odd problem. Sounds like a timing issue. Keep in mind that the ADCs are only specified to work to 64 MHz and the FPGA image is compiled to meet timing at 64 MHz. You might need to recompile it with the stricter timing numbers. All of the DSP stuff in the FPGA should not care about the absolute frequency as long as it meets timing.
| << RSSI Measurement | ^ Top ^ | Loading FPGA Bit Stream >> |
| << Daughterboards | ^ Top ^ | RSSI Measurement >> |
Here it how we can do it:
The gnuradio project provides a complete USRP interface library. When compiling the interface program, these library must be linked with our code by using G++ library command (-lusrp).
To show the used procedure, suppose we have written a C++ USRP interface program called usrp_test_c++.cpp. To compile this program, we use the following command:
$ g++ usrp_test_c++.cpp -o testusrp -lusrpwhere g++ is the GNU C++ compiler, usrp_test_c++.cpp is our c++ source file, testusrp is our output file, -lusrp is the USRP C++ library. Note: The following USRP two header files should be in the same compilation directory: fpga_regs_common.h, fpga_regs_standard.h To run the output file from Linux command line:
./testusrp
Below is the list for such program
// Simple C++ USRP interfacing demonstration program
//
//
// This program was derived and modified from test_usrp_standard_rx.cc
/* -*- c++ -*- */
/*
** Copyright 2003,2006,2007,2008 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.
*/
#include "usrp_standard.h"
// Dummy Function to process USRP data
void process_data(int *buffer)
{
/*
Each buffer element, for example bufferr0 contains 4 bytes
2 bytes For (I) and 2 bytes for (Q).
*/
}
#define SAMPELS_PER_READ (512) // Must be a multiple of 128
/*
SAMPELS_PER_READ :Each sample is consists of 4 bytes (2 bytes for I and
2 bytes for Q. Since the reading length from USRP should be multiple of 512
bytes see "usrp_basic.h", then we have to read multiple of 128 samples each
time (4 bytes * 128 sample = 512 bytes)
*/
int
main (int argc, char **argv)
{
bool loopback_p = false;
bool counting_p = false;
bool width_8_p = false;
int which_board = 0;
int decim = 8; // 32 MB/sec
double center_freq = 0;
int fusb_block_size = 0;
int fusb_nblocks = 0;
int nchannels = 1;
int gain = 0;
int mode = 0;
int noverruns = 0;
bool overrun;
int total_reads = 10000;
int i;
int buf[SAMPELS_PER_READ];
int bufsize = SAMPELS_PER_READ*4; // Should be multiple of 512 Bytes
if (loopback_p) mode |= usrp_standard_rx::FPGA_MODE_LOOPBACK;
if (counting_p) mode |= usrp_standard_rx::FPGA_MODE_COUNTING;
usrp_standard_rx_sptr urx = usrp_standard_rx::make (which_board, decim, 1, -1, mode,
fusb_block_size, fusb_nblocks);
if (!urx)
{
fprintf (stderr, "Error: usrp_standard_rx::make\n");
exit (1);
}
if (width_8_p)
{
int width = 8;
int shift = 8;
bool want_q = true;
if (!urx->set_format(usrp_standard_rx::make_format(width, shift, want_q)))
{
fprintf (stderr, "Error: urx->set_format\n");
exit (1);
}
}
// Set DDC center frequency
urx->set_rx_freq (0, center_freq);
// Set Number of channels
urx->set_nchannels(1);
// Set ADC PGA gain
urx->set_pga(0,gain);
// Set FPGA Mux
urx->set_mux(0x32103210); // Board A only
// Set DDC decimation rate
urx->set_decim_rate(decim);
// Set DDC phase
urx->set_ddc_phase(0,0);
urx->start(); // Start data transfer
printf("USRP Transfer Started\n");
// Do USRP Samples Reading
for (i = 0; i < total_reads; i++)
{
urx->read(&bufr0, bufsize, &overrun);
if (overrun)
{
printf ("USRP Rx Overrun\n");
noverruns++;
}
// Do whatever you want with the data
process_data(&bufr0);
}
urx->stop(); // Stop data transfer
printf("USRP Transfer Stoped\n");
delete urx;
return 0;
}
The gnuradio team is developing an all C++ daughterboards drivers [I don’t know if they finished it]. There are some gnuradio users that developed their own C++ drivers but they did not publish it yet [I Think They Should].
The only published C++ driver is for DBSRX daughterboard by Gregory W Heckler.
The DBSRX C++ driver can be obtained from GPS-SDR code repo.
We can use:
$ g++ db_dbs_rx.cpp usrp_sdr.cpp -o testdriver -lm -lusrp -lpthreadNote: The following files should be in the same compilation directory: db-dbs_rx.cpp, db_dbs_rx.h, fpga_regs_common.h, fpga_regs_standard.h.
| << Daughterboards | ^ Top ^ | RSSI Measurement >> |
<< Digital IO Pins Control ^ Top ^ C++ Interfacing >>
When you plug-in daughterboards, follow these rules:
Just connect the real input to the input connector, and use 0xf0f0f0f0 setting for the mux value of the USRP source. This feeds a zero into each of the DDC Q inputs and ADC0 into the DDC I inputs. For your receiver with the 10.7 MHz IF, set the DDC frequency to -10.7e6 and you'll get complex baseband across the USB. Pick the decimation value to set the width of the the channel you're interested in. The ADC sample rate is 64e6 (adc_freq()). Divide that by the decimation factor and that will give you the sample rate across the USB. The USB samples are 16-bit I and 16-bit Q. i.e., 4 bytes/sample. There's a fourth-order CIC filter in the FPGA, so there's some roll-off across the band.
Using high accuracy function generator and USRP with Basic-RX at 0 dB gain with decimation of 8.
a) With Sine wave signal at frequency 250 KHz and 0dBm input power to BasicRX we get:
Theoretical calculations:
When 0dBm signal injected into 50 Ohm load, then we should have signal RMS = 0.225Volt and Signal voltage P-P = 0.636396103Volt.
USRP readings:
The maximum counting obtained from USRP for this signal was 4845.
b) With Sine wave signal at frequency =250 KHz and 5dBm input power to BasicRX we get:
Theoretical calculations:
When +5dBm signal injected into 50 Ohm load, then signal RMS = 0.4Volt and Signal P-P = 1.13137085Volt.
USRP readings:
The maximum counting obtained from USRP for this signal was 8337.
c) With Sine wave signal at frequency =250 KHz and 9dBm input power to BasicRX we get:
Theoretical calculations :
When +9dBm signal injected into 50 Ohm load, then signal RMS = 0.64Volt and Signal P-P = 1.81019336Volt.
USRP readings:
The maximum counting obtained from USRP for this signal was 13096.
d) With Sine wave signal at frequency =250 KHz and 10dBm input power to BasicRX we get:
Theoretical calculations:
When +10dBm signal injected into 50 Ohm load, then signal RMS = 0.71Volt and Signal P-P = 2.008183259Volt.
USRP readings:
The maximum counting obtained from USRP for this signal was 13570 (Saturated).
From the above results we see that the BASIC-RX is saturated when the input signal power was +10dBm. This is logical, since the maximum input signal to the USRP ADC AD9862 is 2Volt P-P (according to its data sheets). The value obtained from USRP FPGA for input signal of 2V P-P was about 13570.
We have to understand the comments about tuning being a "two-step process"? First we ask the front-end to tune as close to the desired frequency as it can (For example, on the RFX boards, the PLL step size is 4 MHz.). Then we use the result of that operation and our target_frequency to determine the value for the digital down converter.
The return value from tune software function is an instance of tune_result which can be examined to see how everything was setup:
baseband_freq is the RF frequency that corresponds to DC in the RF front-end IF output (the input to the A/D's and from there to the digital down-converter). Note that this isn't necessarily the location of the signal of interest. Some daughterboards have the signal of interest at a non-zero IF frequency. dxc_freq is the frequency value used in the digital down or up converter. residual_freq is a very small number on the order of 1/100 of a Hz. It can be ignored. inverted is true if the spectrum is inverted, and we weren't able to fix it for you.On the receive path, the end result of tune is that the signal at the given target RF frequency ends up at DC in the complex baseband input from the USRP.
Note: Abstractly, TX and RX daughterboards can be split into two general categories: those that use both converters as a pair (boards doing quadrature up or down conversion) and those that can use the converters independently.
Because we're using the digital up converter in the AD9862 in "Dual Channel Complex DAC Data Mode", both D/A outputs are related (I&Q) and as a result, all TX daughterboards are "quadrature" boards. On the receive side we've got a bit more variation. The TV_RX board (for example) is not a quadrature board, since it only uses a single A/D.
On the RFX transceiver boards (400, 900, 1200 and 2400), both the Tx side and Rx side are quadrature.
The TX or RX daughterboard consists of either one or two subdevices. Quadrature boards have a single subdevice. Non-quadrature boards have one or two subdevices and it is depending on the daughterboard design.
The fundamental capabilities of a subdevice are the ability to tune and set gain. Each subdevice has a daughterboard specific class that is derived from db_base.py (in gr-usrp).
The visible methods are:
def dbid(self):
"""
Returns integer daughterboard ID from EEPROM
"""
def name(self):
"""
Name of daughterboard. E.g., "TV Rx"
"""
def freq_range(self):
"""
Return range of frequencies in Hz that can be tuned by this daughterboard.
@returns (min_freq, max_freq, step_size)
@rtype tuple
"""
def set_freq(self, target_freq):
"""
Set the frequency.
@param freq: target RF frequency in Hz
@type freq: float
@returns (ok, actual_baseband_freq) where:
ok is True or False and indicates success or failure,
actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
"""
def gain_range(self):
"""
Return range of gain that can be set by this daughterboard.
@returns (min_gain, max_gain, step_size)
Where gains are expressed in decibels (your mileage may vary)
"""
def set_gain(self, gain):
"""
Set the gain.
@param gain: gain in decibels
@returns True/False
"""
def is_quadrature(self):
"""
Return True if this daughterboard does quadrature up or down conversion.
That is, return True if this board requires both I & Q analog channels.
This bit of info is useful when setting up the USRP Rx mux register.
"""
When we create an instance of a usrp source or sink, we now get an additional attribute, "db", that lets us control the daughterboard subdevices.
u = usrp.source_c(0, 64) u.db is a tuple of length 2. u.dbr0 contains a tuple of the subdevices for "side A" u.dbr1 contains a tuple of the subdevices for "side B"
The tuples of subdevices each have either 1 or 2 elements depending on the daughterboard installed on the respective side. Each subdevice is an instance of a class that's derived from db_base and exports the methods listed above. When we're tuning, there are really at least two knobs to twist:
def set_freq(self, target_freq):
"""
Set the center frequency we're interested in.
@param target_freq: frequency in Hz
@rtype: bool
Tuning is a two step process. First we ask the front-end to
tune as close to the desired frequency as it can. Then we use
the result of that operation and our target_frequency to
determine the value for the digital down converter.
"""
# self.subdev is the subdevice we are controlling
ok, baseband_freq = subdev.set_freq(target_freq)
ddc_freq, inverted = usrp.calc_dxc_freq(target_freq, baseband_freq, self.u.converter_rate())
ok &= self.u.set_rx_freq(0, ddc_freq)
The Local Oscillator (LO) frequency of the RFX boards is set automatically when we set the frequency of reception or transmission. The LO is a multiple of 2 or 4 MHz depending on which RFX board we have. We can change that to be a multiple of 1MHz, but we will have worse phase noise.
If you connect a 50 ohm resistor across the SMA, you do indeed get 62mV at the connector, but 0V at the ADC, which is what we really care about. If you leave the SMA open, you do get a small voltage being read at the ADC.
So yes, the LFRX does have DC bias on its input, but as long as you drive it with a 50 ohm load, you get the right answer at the ADC. The LFRX wasn't designed for measuring DC voltages, although it can as long as you have a 50 ohm source. And if your source is not 50 ohms, you can do the calculations necessary to scale the gain. Also, please note that the amp is inverting, so if you put 1V through 50 ohms into the SMA, the ADC will tell you that it is -1V.
The RFX daughterboard PCBs were designed using a commercial program called PADS, not using PCB from the gEDA suite.
0.570 inches
You can find out what version you have by running usrp_print_db.py in the gr-utils/src/python directory.
The TVRX is really 75 ohms, but putting in 50 ohms is not a problem. The DBSRX tuner chip is 75 ohms, but we have a 50 ohm input impedance because of the LNA ahead of it.
To convert to an RFX1200, you need to:
usrp/host/apps/burn-db-eeprom -A -f -t rfx1200_mimo_b
You can also change some of the final amp tuning components if the power out is a little low.This is not always necessary, but sometimes gets another dB of extra power.
To convert the you only have to do 3 things:
./burn-db-eeprom -A --force -t rfx1800_mimo_b
If you cut the filter out you need to complete the signal path by populating C204 with a capacitor in roughly the 100pF to 10,000pF range (#FIXME#). Very high capacitor values have bad parasitic effects -- 0.1uF is fine but don't use 10uF.
To turn it back into a RFX900 again, or to turn your RFX1800 into a RFX900, you can run the command:./burn-db-eeprom -A --force -t rfx900_mimo_b
The EEPROMs on the daughterboards basically store an identifier for the type of board, and can store some DC offsets and the like. The daughterboard EEPROM format is defined in [source:gnuradio/trunk/usrp/firmware/include/usrp_i2c_addr.h usrp/firmware/include/usrp_i2c_addr.h].
The format of the ROM is documented in [source:gnuradio/trunk/usrp/firmware/include/usrp_i2c_addr.h usrp/firmware/include/usrp_i2c_addr.h]. Just be sure that bytes 0x00 through 0x02 make sense. You can set the remainder to 0x00, but be sure to set the checksum correctly in 0x1f. There's a script that will do this for you over the USB. See [source:gnuradio/trunk/usrp/host/apps/burn-db-eeprom usrp/host/apps/burn-db-eeprom].
The relevant portion is:// format of daughterboard EEPROM // 00: 0xDB code for @@I'm a daughterboard_ // 01: .. Daughterboard ID (LSB) // 02: .. Daughterboard ID (MSB) // 03: .. io bits 7-0 direction (bit set if it's an output from motherboard) // 04: .. io bits 15-8 direction (bit set if it's an output from motherboard) // 05: .. ADC0 DC offset correction (LSB) // 06: .. ADC0 DC offset correction (MSB) // 07: .. ADC1 DC offset correction (LSB) // 08: .. ADC1 DC offset correction (MSB) // ... // 1f: .. negative of the sum of bytes [0x00, 0x1e] #define DB_EEPROM_MAGIC 0x00 #define DB_EEPROM_MAGIC_VALUE 0xDB #define DB_EEPROM_ID_LSB 0x01 #define DB_EEPROM_ID_MSB 0x02 #define DB_EEPROM_OE_LSB 0x03 #define DB_EEPROM_OE_MSB 0x04 #define DB_EEPROM_OFFSET_0_LSB 0x05 // offset correction for ADC or DAC 0 #define DB_EEPROM_OFFSET_0_MSB 0x06 #define DB_EEPROM_OFFSET_1_LSB 0x07 // offset correction for ADC or DAC 1 #define DB_EEPROM_OFFSET_1_MSB 0x08 #define DB_EEPROM_CHKSUM 0x1f #define DB_EEPROM_CLEN 0x20 // length of common portion of EEPROM
You can use the existing "Experimental Rx" daughterboard id, 0xffff, or define a new one. See [source:gnuradio/trunk/usrp/host/lib/usrp_dbid.dat usrp/host/lib/usrp_dbid.dat].
The dbid is read from the daughterboards and is use to instantiate the correct daughterboard code. You can see what you've got by calling u.daughterboard_id(0) and u.daughterboard_id(1) to retrieve the dbid's from slots 0 and 1.
To talk to your daughterboard using our standard interface, you'll need to write a bit of python. Take a look at gr-usrp/src/db_*.py. Start with db_base.py, then maybe db_basic.py
<< Digital IO Pins Control ^ Top ^ C++ Interfacing >>
<< Controlling FPGA Registers^ Top ^Digital Up Converter >>
The ADC interface module takes care of demuxing the received signal into I and Q signals. Then every pair of IQ is routed to a DDC.
The MUX is like a router or a circuit switcher. It determines which ADC (or constant zero) is connected to each DDC input. There are 4 DDCs. Each has two inputs. We can control the MUX using usrp.set_mux() method in Python.
The Mux value is calculated by:
3 2 1
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+-------+-------+-------+-------+-------+-------+-------+-------+
| Q3 | I3 | Q2 | I2 | Q1 | I1 | Q0 | I0 |
+-------+-------+-------+-------+-------+-------+-------+-------+
Each 4-bit I field is either ADC 0,1,2,3
Each 4-bit Q field is either ADC 0,1,2,3 or 0xf (input is const zero)
All FPGA DDC Q's must be 0xf or none of them may be 0xf.
We tell each input DDC input (I0, Q0, I1 ... I3, Q3) which ADC is connected to it by using 4 bits (0, 1, 2, 3 or 0xf). So a 32-bit integer would be enough for all 8 inputs to know which ADC is connected. Of course an integer in hexadecimal system will be more convenient if we want to use the set_mux() method. For most real sampling applications, the Q input of each DDC is constant zero. So quite often we don't need to modify the standard configuration of the FPGA. Actually it is anticipated that the majority of USRP users will never need to use anything other than the standard FPGA configuration.
The sample rate of the ADC is 64Msps. The samples then go through the CORDIC to generate complex pairs, then through a CIC with minimum decimation of 4, and then through a halfband 2:1 decimating filter. The lack of hardware multipliers inside the FPGA requires you to run a relatively simple filter unless you are running at "low" sample rates which allow you to serialize the data going through one or two multipliers and accumulate the output.
It has 31 taps. The current implementation of the halfband filter in the FPGA requires 8 clocks to process the 31 taps. See the comments about timing in source:gnuradio/trunk/usrp/fpga/sdr_lib/hb/halfband_decim.v.
This works fine with decimation 8 or higher. To run at decimation 4, you'll need to use a build of the FPGA that does not contain the halfband filter, or you'll need to re-implement the halfband, such that it uses two multipliers instead of one. In addition to the standard 2 Rx (with halfband) 2 Tx build, the current code contains an FPGA image with 4 RX paths (without the halfband) and with 0 transmit paths. It's not installed by default.
Yes. Note that some FPGA builds don't contain the half-band.
With 16-bit I & Q decim = 8 -> 8MS/sec -> 32MB/sec.
With 8-bit I & Q decim = 4 -> 16MS/sec -> 32MB/sec
The decim_rate sets how much decimation is done in the FPGA. You can of course perform additional decimation in software. You'd probably want to use gr.fir_filter_ccf for that job. The first argument is the decimation rate.
Note:
To use 4 channels, you must use the std_4rx_0tx.rbf FPGA image. If you use the std_4rx_0tx.rbf image, the decimation rate must be <= 128. If you need more decimation, you must do it in software.
With the std_4rx_0tx.rbf image, I believe odd numbers will work. They will not work with std_2rxhb_2tx.rbf
This paper is really good for understanding the CORDIC: CORDIC Algorithm
It is specifically written to look at FPGA implementations, which is nice. As I understand it, the USRP uses the CORDIC as described in section 3.1 of that paper. A phase accumulator is used to spin the angle around, and the modulated sin/cos or xi is the output on xo and yo after 12 iterations of the algorithm. The value of zo should be zero, and any error leftover should be represented on that output. The resolution should really be how slowly you can spin the zi component while maintaining accuracy out of the CORDIC. It may be that with 12 iterations and 16-bit inputs 0.01 Hz is possible, whereas more iterations or larger inputs might get better resolution, but I suspect you're really past the point of diminishing returns at that point.
The "phase generator" part of the CORDIC block works by incrementing a 32-bit phase register by a fixed amount per clock cycle. The full size of the register represents 2*PI() of phase, or one cycle of the waveform. The user programmed phase increment per clock cycle then represents frequency.
In the receive chain of the FPGA, the phase generator is clocked at 64 MHz. Thus, the minimum delta-frequency (a one bit change in the phase increment register) is 64 MHz / pow(2, 32) = 0.0149 Hz.
Thus, for DC, the phase increment value is zero, for 0.0149 Hz, it is 1, for 0.0298 Hz, it is 2, all the way up to 32 MHz, where it is pow(2, 31). You can also tune negative frequencies, where -1 creates -0.0149Hz, etc.
The CORDIC block then uses the resulting "sawtooth" phase value to rotate the incoming signal by that amount, resulting in complex frequency conversion. The FPGA CORDIC deals with phase and not frequency, so there is no concept of frequency resolution for it. The one being used in the USRP has 14 bits of PHASE resolution. Frequency resolution is controlled by the NCO, or phase accumulator. In our case it has 32 bits of resolution. 64 MHz/2^32 is your frequency resolution in Hz.
For decimation 32, the response of the CIC (4 stages) frequency response from 0 to 2MHz is shown below:

The HBF frequency response is shown below (normalized frequency):


The cascaded response (CIC + HBF) is shown below (normalized frequency):
(was at http://img180.imageshack.us/img180/488/CICHBF.jpg, no longer available?)
<< Controlling FPGA Registers^ Top ^ Digital Up Converter >>
| << Digital Down Converter | ^ Top ^ | Digital IO Pins Control >> |
On the transmit side we use our own CIC to interpolate from whatever ratio comes over the USB to 32 MS/s. This is sent to the 9862 which then interpolates again by a factor of four to bring us to 128 MS/s. The up converter is in the 9862 as you say. In the receive side, the down conversion is done in the FPGA, because the 9862 does not have a down converter in the RX path. The bus going to the TX path on the 9862 is multiplexed (I then Q samples), and we run it at our normal clock rate of 64 MHz. This means we can only get 32 MS/s complex across it. If we did the up conversion in the FPGA, we would thus be limited to about a 12 MHz carrier.
We use those interpolation filters already, but they only do a factor of 4, so we still need a CIC in the FPGA.
It's still in: [source:gnuradio/trunk/usrp/fpga/sdr_lib/cic_int_shifter.v usrp/fpga/sdr_lib/cic_int_shifter.v]
More precisely, there are two interleaved channels, each running at 32MS/s. The AD9862 interpolates each stream by 4, giving two streams at 128MS/s.
Yes.
It's probably 1 or 2, though I doubt it's been tested. The (workable) maximum is determined by the width of the intermediate stages of the CIC. I believe we're good to 128 in the FPGA CIC.
The code in usrp_standard.cc controls the FPGA interpolation rate. The rates do not have to be powers of two. From the user point of view the net interpolation rate must be in [4, 512] and a multiple of 4. This is all controlled in usrp_standard.cc.
Yes.
Its set by the passband of the interpolator in the AD9862. The digital up converters in the AD9862 don't allow you to set the frequency to values close to the Nyquist frequencies (from 44MHz to 84MHz). Since it samples at 128 MHz, the prohibited ranges are around multiples of 64 MHz.
As the software is currently built, you cannot send two independent, real-valued signals to different connectors on the same transmit daughterboard. The reason is that we are using the digital up-converters in the AD9862, and have the AD9862's configured in "Dual Channel Complex DAC Data" mode. See pages 20-21 of the AD9862 datasheet. If you only need two independent TX channels, the quick fix is to use two Basic Tx daughterboards. This is supported. Just tell the USRP that you're using two channels of data, and then provide a stream with two interleaved channels of I & Q data. An additional thought is that if you don't need digital up-conversion, I don't think it would take much to get two independent channels out. You should be able to use the existing FPGA and host code, and just manually jam the right magic values into the AD9862 registers 19 and 20. Make sure that you continue to run the 4x interpolator on the AD9862 so all the data rates remain the same. You can write the AD9862 regs from python using:
u = usrp.sink_s(...)
u._write_9862(which_codec, regno, value) # note the leading _ character
# which_codec is 0 or 1 for side A or B
Look in [source:gnuradio/trunk/usrp/host/lib/usrp_standard.cc usrp_standard.cc] to see how we normally setup these registers.
The minimum interpolation rate is 4 due to the CIC filter limitations, so once every 4 will yield one side of the spectrum. I believe 128 is the other end of the spectrum, but you should set a constant for the rate so we can test with different ones. The tx_strobe happens once every rate clock cycles - with which it will send in a new sample. That strobe sends a new value down the TX stream and reads a new one ready for the next tx_strobe.
I am not sure of this - but I am assuming to stop/reset the transmit path and clear any status messages respectively.
We have gotten multiple USRPs synchronized for receive. That FPGA code and host code is in the subversion. For transmit, the problem could be a bit more difficult, depending on whether you can deal with a constant phase difference between the transmitting USRPs or not (MIMO vs beam forming). If you need the phases to be identical between the USRPs then you will have to change the verilog such that you are no longer using the digital up converters in the AD9862 and instead implement the DUC in the FPGA. This is because there's no way to directly control the phase accumulator in the AD9862. If you can deal with a constant phase offset, then a strategy similar to what Marin used for Rx should work for TX.
This is just wiring a couple things together to get the transmission chain to work at the full clock rate. There are 3 main components here: a phase accumulator, a CORDIC and an interpolating CIC filter. The baseband signals are fed into the CORDIC along with a phase from the phase accumulator. For each sample that goes in, the phase accumulator rotates. This generates an IF that is mixed with your baseband signal. The interpolating CIC filter gets your baseband signal up to the proper sample rate to feed the DACs.
| << Digital Down Converter | ^ Top ^ | Digital IO Pins Control >> |
| << AD9862 Codec | ^ Top ^ | Digital Down Converter >> |
Once you create a usrp.source_c() or usrp.sink_c() object, you can call:
u = usrp.source_c() u._write_fpga_reg(regno, val)The FPGA registers are write-only. You may call:
u._read_fpga_reg(regno)but the return value will either be zero or a semi-documented set of debugging values unrelated to the register number you put. The FPGA register definitions are in: [source:gnuradio/trunk/usrp/firmware/include/fpga_regs_common.h usrp/firmware/include/fpga_regs_common.h], [source:gnuradio/trunk/usrp/firmware/include/fpga_regs_common.h usrp/firmware/include/fpga_regs_standard.h]. NOTE: It is possible to damage your hardware by incorrectly setting these registers I believe setting_reg.v is instantiated wherever there is a register which can be written to. Being able to have access to every register makes for a very hairy problem. The FPGA registers are not set using I2C, they are set with SPI. There is already a mechanism for reading back values over SPI, but it is only set up to read back 8 values now, mostly for reading I/O pins and RSSI levels, but not every register. See [source:gnuradio/trunk/usrp/fpga/sdr_lib/serial_io.v serial_io.v] and [source:gnuradio/trunk/usrp/fpga/sdr_lib/setting_reg.v setting_reg.v].
All the I2C and SPI stuff is outside the FPGA. The SPI is a serial bus which is used to set registers on the daughterboards, the FPGA, and the AD9862 are controlled from the FX2 only.
if (utx->_write_fpga_reg(FR_ADC_OFFSET_0,0x7777)) int readregvalue2 = (utx->_read_fpga_reg(FR_ADC_OFFSET_0));The FPGA registers are write-only. When reading, instead of the register contents, you get 'readback' register contents which are actually a number of useful signals inside the FPGA. See line numbers 304 and 305 of [source: gnuradio/trunk/usrp/fpga/toplevel/usrp_std/usrp_std.v usrp_std.v] to see what signals are read back. The typical way of dealing with write-only registers is to maintain a shadow copy in your code that you update every time you write to a register, and then if you later want to "read" the register, just look at the shadow copy. You can also use this if you want to do a read-modify-write.
Correct. The actual registers are not instantiated (they would get pruned out anyway during synthesis if you did.) If you are writing custom FPGA code, you can instantiate any number of:
setting_reg #(FR_USER_XX) user_reg(...);...in whatever verilog module you create, and just be sure to include: [source:gnuradio/trunk/usrp/firmware/include/fpga_regs_standard.h usrp/firmware/include/fpga_regs_standard.h]. The path in the include statement will vary depending on where your verilog module is in the file system. Also, if you are adding setting registers to existing modules, then the “include” may already be done it for you. Finally, the constants FR_USER_0 through FR_USER_15 are available from C++ by including:
No. From python:
# returns 32-bit int v = u._read_fpga_reg(regno)
Note that there are only 4 readable registers, and I strongly suggest that you use u.read_io(which_dboard) instead of directly reading register 1 or 2.
Refer Table:
| regno | result | |
| 1 | (io_rx_a << 16) OR io_tx_a | # read daughterboard i/o pins |
| 2 | (io_rx_b << 16) OR io_tx_b | # read daughterboard i/o pins |
| 3 | returns const 0xaa55ff77 | # don't count on this |
| 4 | returns const 0xf0f0931a | # don't count on this |
FYI, the "normal" python interface to the usrp is defined in gr-usrp/src/usrp1.i
| << AD9862 Codec | ^ Top ^ | Digital Down Converter >> |
| << General Questions | ^ Top ^ | AD9862 Codec >> |
Yes. It is possible. The top level of the verilog source for the FPGA can be found in usrp/fpga/toplevel/usrp_std/usrp_std.v and the bulk of the code in usrp/fpga/sdr_lib.
If you want to build the FPGA .rbf file from source (not required; we provide pre-compiled .rbf files in usrp/fpga/rbf directory), you'll need Altera's no cost Quartus II development tools. We're currently building with Quartus II Web Edition.
In the FPGA RX Side, in the DC offset removal process, they are assigned on input. Here is where it happens:
We can see that the input of the rx_dcoffset module is assigned:
.adc_in({adc0r11,adc0,3'b0})
which is a 1 bit sign extension, the 12 original bits, then 3 bits of 0's.
While in the FPGA TX Side, See [source:gnuradio/trunk/usrp/fpga/toplevel/usrp_std/usrp_std.v#L179 usrp_std.v] whatever 16-bits are coming from the tx_chain module is truncated by 2-bits and sent out to the DACs.
It is not enabled. If enabled, this code would implement digital up conversion in the FPGA, instead of using the DUC in the AD9862. N.B., this code hasn't been tested in something like a couple of years and may have suffered bit rot.
The serial_io.v is only used for writing and reading the FPGA registers.
The actual data to/from the DACs/ADCs (DUCs/DDCs) goes across the 16-bit GPIF bus.(#FIXME# not all the asked question is answered)
Refer to attachment:AD9860_9862.pdf #FIXME: cannot reference attachments of other objects
The USB clock is 48 MHz, provided by the FX2.
The 8051 bit-bangs the SDI data, clock, and strobe lines. They are "slow" compared to other FPGA actions. See [source:gnuradio/trunk/usrp/firmware/src/usrp2/spi.c usrp/firmware/src/usrp2/spi.c].
The FIFOs are 4K lines long, with each line 16 bits.
Yes
Here how it goes. If the angle is positive, it is reduced. If the angle is negative, it is increased. It always gets closer to zero.
To write a test bench, you would need to set the interpolation frequency properly and if you wanted to use the CORDIC, that would have to be setup properly as well for the phase accumulator. You would then strobe your samples in at a rate of Fs where Fs is some fraction of the total clock speed and Fs*interp_rate = the clock rate. You then have to strobe every Fs to send your samples through the chain.
You also need to assert the interpolator_strobe and sample_strobe on a consistent frequency basis - eg: once every 15 clock cycles. You can't just randomly assert and de-asserts them.
You have no frequency set. I believe this frequency should be the phase difference between samples of the CORDIC for each sample that goes in where 2^31^-1 is equal to 2*PI. You probably want to see a sine wave or some filtered signal - try a pulse train, {1, 0, 1, 0, ...} or you can download the [source:gnuradio/branches/developers/zhuochen/simulations/burst_test/math_real.v math_real.v] module. The test bench here can be used to create some sines and cosines - [source:gnuradio/branches/developers/zhuochen/simulations/burst_test/test_chan_fifo_reader.v test_chan_fifo_reader.v].
For pre-synthesis, RTL simulation and testing, I use ICARUS Verilog under Linux and GTKWave. Note that if you plan on using it with ICARUS Verilog, you will need one of the latest developer snapshots as the code I wrote found some problems in their real value handling.
It is definitely NOT recommended you just put it into an FPGA and run with it as you really have no idea what's going on inside there. Accurate modeling can really help with your debugging time.
The header file config.vh (trunk?) controls the build configuration and is now functional. Modify it to use the file:
// Uncomment this for 1 RX channel (w/ halfband) & 1 transmit channel @include "../include/common_config_1rxhb_1tx.vh"This will free up a lot of space on the FPGA for experimentation!
For informational purposes, the interpolation strobes and filtering modules are found here - [source:gnuradio/trunk/usrp/fpga/sdr_lib/master_control.v master_control.v],
It is a pipelined module which takes samples at the full rate and through 12 pipeline stages outputs the rotated vector. Why 12 was picked is probably a size issue since you create registers and flops for each stage. You can make the pipeline deeper and even variable if you want. There is a TODO in there which suggests making it a variable length - not sure if the comment means at runtime or at build time, but have a go at it.
Yes. For example, like the tx_usb_fifo and rx_usb_fifo, you can just tell Quartus to generate the appropriate dual clock FIFO "megacell" for you. In this way, Matt did that to generate the fifo_2k and fifo_4k blocks that we're currently using. See the Quartus manual and the "Cyclone Device Handbook" for supported configurations.
module setting_reg(input clock, input reset, input strobe, input wire [6:0] addr, input wire [31:0] in, output reg [31:0] out, output reg changed);In the [source:gnuradio/trunk/usrp/fpga/sdr_lib/master_control.v master_control.v] module,I see setting_reg module is called as follow:
setting_reg #(@FR_MASTER_CTRL) sr_mstr_ctrl(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe), .addr(serial_addr),.in(serial_data),.out(master_controls));However, in [source:gnuradio/trunk/usrp/fpga/sdr_lib/setting_reg.v setting_reg.v] module, the setting_reg module has an output signal called "changed". Can anyone please tell me what will happen to that "changed" signal? The "changed" signal is not used in most places, and is left out.
| << General Questions | ^ Top ^ | AD9862 Codec >> |
| << Timing Latency | ^ Top ^ |
It's a little more complicated than that, but that's the basic idea. USB supports three kinds of transfers across the USB: command, bulk read/write and isochronous. We use command packets to configure the USRP, load firmware, the FPGA bitstream, etc. We use endpoint 0 for that interface. In addition, we use two other endpoints, one for streaming input data and the other for streaming output data. These endpoints are used with bulk transfers, since they are the USB transfers that support the highest throughput. I suggest reading chapter 9, "USB Device Framework" of the USB 2.0 specification. It covers most of what you need to know to build a USB peripheral.
The FX2 is limited in the number of endpoints that it supports. See page 15 of the CY7C68013 datasheet. Right now we are running with endpoints 2 and 6 "quad buffered", 4 512 byte buffers each. One is used for Tx data, the other for Rx data. It would be possible with a bit of hacking to run endpoints 2, 4, 6 and 8 "double buffered", 2 512 byte buffers each. That would give us 4 bulk endpoints to work with (and would also lower the worst case latency).
It implements the transmit direction part of the FX2/FPGA GPIF interface. It also demuxes the data to be transmitted and sends it to the appropriate DACs.
No. The formatting of the data is all handled in the FPGA. The FX2 firmware doesn't even see the bulk data going in and out. The data is transferred by DMA to/from the GPIF from/to the FPGA USB buffers.
On the FX2, the WR pulse is asserted one clock longer than it should be.
wrreq tells the FIFO when data should be written to the FIFO. So, we write when (WR & ~write_countr8). That is, when WR is asserted, but the count does not have 0x100 bit set. As I recall, WR is asserted an extra cycle, and the counter trick works around this.
Yes. Have_space is used by the feeding FX2 to know if the FPGA can handle one more packet. The have_space pin is used by the FX2 to know if the FPGA FIFO can store AT LEAST one more packet.
Yes. That shouldn't be a problem. There's software inside the FX2 that polls the pin. You've got at least 100 ns between packets, probably more.
On the motherboard, we're currently using a "C2" formatted EEPROM so that we can run code at power-up time to get the 9862's into a reasonably low-power state. The details of the C0 vs C2 FX2 boot can be found in the FX2 Technical Reference Manual.
The EEPROM on the motherboard stores some USB info, and some very simple code to put the board in a low power state when it powers up. It also blinks one LED quickly. Once you start running anything on the USRP, a more complete firmware (which is much bigger than the EEPROM would hold) is sent over the USB bus.
Many points:
1) There's the Official documentation
2) The main controlling program is usrp_main.c (compiled firmware for the 8051 in the FX2 USB chip by SDCC) found in source:usrp/firmware/src/usrp2.
3) The following loops were examined from the source:usrp/firmware/src/usrp2/usrp_main.c
main( )
{
Initialize USRP
Initialize GPIF
Patch USB Descriptors (read from EEPROM, set HW device ID)
Setup Autovectors
Install USB Handlers
Re-enumerate
Run main_loop( )
}
main_loop( )
{
Check for USB setup packets
Check and log the RX Overruns and the TX Underruns
Check for packets to send back to host
Check for packets to send to FPGA
}
4) USB Endpoints:
Different USB endpoints (EP) are used to logically separate different operations occurring on the bus into separate flows. There are currently 3 USB endpoints checked/used within the main_loop() as described earlier.
| Endpoint | Description |
| 0 | Control/status |
| 2 | Host -> FPGA |
| 6 | FPGA -> Host |
5) USB Transfers are always 512-byte bulk transfers. All control information is written using endpoint 0 and the vendor commands. These commands are separated into two different categories: VRT_VENDOR_IN and VRT_VENDOR_OUT. These are processed in the app_vendor_cmd( ) function seen in source:usrp/firmware/src/usrp2/usrp_main.c.
All control communication between the FPGA and FX2 microcontroller is done over the SPI. Daughterboards all seem to be controlled by the generic VRQ_I2C_* and VRQ_SPI_* commands.
6) VRT_VENDOR_IN Commands:
VRQ_GET_STATUS
GS_TX_UNDERRUN
GS_RX_OVERRUN
VRQ_I2C_READ
VRQ_SPI_READ
7) VRT_VENDOR_OUT Commands:
VRQ_SET_LED
VRQ_FPGA_LOAD
FL_BEGIN
FL_XFER
FL_END
VRQ_FPGA_SET_RESET
VRQ_FPGA_SET_TX_ENABLE
VRQ_FPGA_SET_RX_ENABLE
VRQ_FPGA_SET_TX_RESET
VRQ_FPGA_SET_RX_RESET
VRQ_I2C_WRITE
VRQ_SPI_WRITE
The FX2 microcontroller contains an embedded USB 2.0 transceiver and handles all USB transfers with the upstream USB host. It presents a data bus to the outside world (in this case the FPG , with generic control signals which can be programmed to behave in a custom manner. This interface is called the GPIF (General Purpose Interface).
The FX2 also handles all USB control requests (via endpoint 0), which all USB-enabled devices must support to fully comply with the USB standard. These include responses to device capability interrogations and standard setup requests.
FX2 Internal Block Diagram (From Kalen Thesis)

A simplified view of the FX2 is shown in Figure above. It houses an industry-standard 8051 microcontroller core (with several extensions and enhancements), which handles all internal control. The 8051 initializes the transceiver, which handles the actual USB transactions. It is also responsible for configuring the FX2's general-purpose I/O ports (not shown) and the GPIF state machine. Data is transferred in a USB system via endpoints, which are similar to Ethernet network socket. Each endpoint must have a specified data-flow direction, either IN or OUT (USB-centric), except the control endpoint 0 which is bidirectional. The endpoints, must also have defined data transaction types which indicate their bandwidth requirements.
Data entering or leaving the FX2 on the USB host side is stored in the endpoint FIFO’s, which can be configured to have various sizes and levels of buffering. The GPIF has direct access to these FIFO’s, allowing for seamless data transfer between an external device and the USB host through a series of buffered FIFO’s.
As well as general house-keeping and configuration, the FX2 firmware is responsible for the following areas:
GPIF initialization: Rather than attempt to handle data transfers directly at USB 2.0 high-speed (480MBits/s), data transfers are carried out by the GPIF. The FX2's 8051 core initializes this interface.
USB control request handling: The 8051 core responds to control requests sent by the USB host over endpoint 0. All USB compliant devices must return responses in a pre-determined format to standard requests about the device (e.g. GetDeviceName which returns the device's description).
USB transfer requests: These are implemented as a polling loop that loads GPIF setup registers with the transfer parameters as and when requests are received from the host. The FX2 firmware is written in C, and compiled with the open-source compiler, SDCC (Small Device Cross Compiler). The embedded functions are invoked using the usrp_basic and usrp_prims libraries.
The GPIF (General Purpose Interface) is a mechanism implemented by the FX2 to allow for simple interfacing with many different types of devices. Essentially it is a bi-directional data bus with a set of generic control signals which are governed by a configurable state machine. The GPIF can be configured to be the interface bus master or can be driven as a slave by the device itself. The GPIF is the bus master. Six states can be defined for a particular waveform, with decision points that dictate the state transitions depending on the values of the generic control lines.
There are four bus cycle waveforms available which can be configured. These are:
Single Write: This bus cycle writes a single data word from the USB to the device (all transactions are defined to be USB-centric)
Single Read: This cycle reads a single word from the device.
FIFO Write: This cycle writes a block of data based on some previously setup parameters. During the transfer state, data flow can be throttled by the receiving device.
FIFO Read: This cycle reads a block of data from the device, and is used to stream ADC data up to the host. An example of a simple GPIF FIFO read waveform is shown in figure below.
GPIF waveform Example (From Kalen Thesis)

The GPIF has six control inputs RDY5:0, and six control outputs CTL5:0. These can be used to implement a great variety of standard and proprietary bus control cycles. In the figure above, the decision point in state 1 will hold the cycle in a stalled state until RDY0 (in this case representing FIFO Empty Flag) is de-asserted when the GPIF state machine will advance to state 2 and latch in the data presented on the DATA bus. The FX2 implements the USB endpoints as internal endpoints EP0, EP1, EP2, EP4, EP6 and EP8, which can be configured in various ways to suit the application’s buffering requirements. EP0 is always a 64 byte CONTROL endpoint and EP1 may only be of the BULK or INTERRUPT types (also 64 bytes). The remaining endpoint FIFO’s can be configured to be double-, triple- or quad-buffered, with a maximum total buffer size of 4K. In this manner, data can be continually streamed to or from the host, provided adequate flow control is in place.
Cypress Semiconductor has developed GPIF Designer, a freely available application which can be used to design GPIF state machines with a graphical interface. The application allows a user to customize the state machines, after which the appropriate configuration and initialization source code is generated which can be included with the main FX2 firmware. This simplifies the process of configuring the GPIF waveform registers which would otherwise have to be coded manually. In the USRP's case, the developers chose to parse the GPIF Designer's output code, and to insert their own initialization routines. This was done in part because the output code generated by GPIFDesigner is somewhat ambiguous (bugs have been encountered by the GnuRadio team).
Internally in USRP, the GPIF acts autonomously from the actual FX2 8051 core and provides data to and from the internal endpoint FIFO’s for streaming up to and down from the USB host. The USRP FX2 interface at the application level is defined and implemented in the usrp_prims and usrp_basic source and header files.
The Usrp_prims defines a set of functions implemented on the FX2 in response to control requests via USB endpoint 0 that extend the generic USB function set. These function primitives typically write to or read from various FX2 registers, or initiate data transfers via the GPIF.
The Usrp_basic provides a simple API to the usrp_prims functions in the form of an object-oriented structure. The interface to the system provides higher-level functionality, hiding most of the underlying interface mechanisms.
It is a data streaming test application. It can load FPGA configuration data (fed serially into the configuration lines of the FPGA bitwise), assert debug USRP LEDs, read and write data to the USRP.
On start up, usrper first attempts to create an interface object that can communicate with a valid USRP device. This creates a handle to a generic USB device, and then traverses all the devices found attached to the USB, searching for the FX2's vendor and product ID numbers (0x04B4 and 0x8613 respectively). On successfully locating a powered, un-configured FX2 device, usrper then downloads the GnuRadio firmware to the FX2, which sets up the system. After system setup, the firmware loads custom values into the Vendor and Product ID fields and initiates a software reset, causing the FX2 device to disconnect and then reconnect to the USB bus.
This process is called re-enumeration, and the Linux kernel now sees the USRP board as a USB device with the Product ID and Vendor ID 0xFFFE and 0x0002, which correspond to a configured USRP device developed by the Free Software Foundation.
Once this has been achieved, calls are made to USRP-specific methods which can be reads, writes or control requests.
Control requests
These enable or configure various aspects of the USRP system, and are made to USB endpoint 0. The firmware intercepts these calls (interrupts are generated on all USB control requests that are received from the host) and services them. They form vendor-extension functions, and carry out various data transfers to and from internal registers based on the host's control request parameters.
For example to download the FPGA’s firmware, the configuration bit stream data is sent via endpoint 0 with the appropriate control parameters indicating a request to configure the FPGA. The FX2 intercepts each byte in this stream, and sends it bitwise over the FPGA’s configuration lines (the Altera EP1C12 FPGA supports serial configuration modes). While servicing the control request, the FX2 firmware sends back the appropriate handshaking signals to the host to indicate that the control request is being handled correctly.
Read requests
The USB requests data from the USRP by making read requests over endpoint 2 (set up for 512 byte bulk IN transfers). The FX2 intercepts these requests and primes the GPIF transfer state machine with the transfer parameters before relinquishing control to the GPIF.
The GPIF enters the FIFO read state machine and remains in this configuration until the transfer is complete, or an error has occurred. The FX2 handles all acknowledge and handshaking signals with the USB host transparently from the firmware.
Write requests
As with read requests, the host PC makes generic USB write requests, this time to endpoint 6 (configured for 512 byte bulk OUT transfers). The GPIF in this time set up for the FIFO write state machine, and transfers data until the transaction is complete, or an error is encountered.
This library code forms the direct interface with the FX2 as a set of low-level functions. Data transfers and various control requests are passed to the FX2 via USB endpoint 0, while the data received is sent back via endpoint 2.
This library presents a higher-level interface to the FX2, in the form of object-oriented methods which call the functions in source:usrp/host/lib/legacy/usrp_prims.cc.
We use the FX2 in GPIF mode because it allows us to burst data across the GPIF interface at 96 MB/sec.
Yes
Two: FIFORd and FIFOWr
We bit bang the FPGA configuration from the 8051.
We used the Cypress GPIF designer. See source:usrp/firmware/src/common/gpif.gpf.
You probably also need to modify some firmware. Also you have to decimate the source down to a very low data rate, so it won't overflow.
Note: There is a suggested patch to make USRP able to use USB 1.1.
Unless your FX2 code sets up the transfer size to 64, then this is probably what is happening. That is, the host is sending 64 bytes, but the FX2 is ignoring the real length, and is assuming that it's 512 bytes. Remember that the GPIF is currently set up to DMA 256 16-bit values. Perhaps that part needs changing. The magic value is probably buried in the WaveData table in usrp_gpif.c.
Another thing you could try is to set up the GPIF in a non-flowstate mode. You'd need to use the Cypress tool to do this (or Larry Doolittle's perl (?) code. Running in full speed, you don't need to be able to burst data at 96MB/sec between the FX2 and FPGA.
Nope. The GPIF is in charge of the transfer. I'm assuming that what you are seeing is that the FX2 is bursting a 256 word transfer, given how you have programmed everything. BTW, I'm not kidding about this being nearly impossible without a logic analyzer. What's currently really happening on the GPIF bus? (Bring out the relevant GPIF pins to the daughterboard debug headers.)
Looking at page 10-16 (10.3.2.2.2 Decision Point States) of the FX2 Technical Reference Manual (and dusting off my memory), the waveform decision point is controlled by the "Transaction Count Expired" signal. Page 10-24, "LOGIC FUNCTION Register", TERMA and/or TERMB will be coded as RDY5 (or Transaction-Count Expiration, if GPIFREADYCFG.5 = 1 (which it is)). See page 10-41, 10.4.3.1 "Transaction Counter".
To use the Transaction Counter for FIFO "x" load GPIFTCB3:0 with the desired number of transactions. When a FIFO-READ or -WRITE waveform is triggered on that FIFO, the GPIF will transfer the specified number of bytes (or words, if WORDWIDE=1).
See ### HERE ### below (from source:usrp/firmware/src/usrp2/usrp_main.c):
Are you setting these to 32 instead of 256? If not, that's probably the root of the problem.
// Next see if there are any "OUT" packets waiting for our attention,
// and if so, if there's room in the FPGA's FIFO for them.
if (g_tx_enable && !(EP24FIFOFLGS & 0x02)){ // USB end point fifo is not empty...
if (fpga_has_room_for_packet ()){ // ... and FPGA has room for packet
GPIFTCB1 = 0x01; SYNCDELAY; ####### HERE #######
GPIFTCB0 = 0x00; SYNCDELAY; ####### HERE #######
setup_flowstate_write ();
SYNCDELAY;
GPIFTRIG = bmGPIF_EP2_START | bmGPIF_WRITE; // start the xfer
SYNCDELAY;
while (!(GPIFTRIG & bmGPIF_IDLE)){
// wait for the transaction to complete
}
}
}
// See if there are any requests for "IN" packets, and if so
// whether the FPGA's got any packets for us.
if (g_rx_enable && !(EP6CS & bmEPFULL)){ // USB end point FIFO is not full...
if (fpga_has_packet_avail ()){ // ... and FPGA has packet available
GPIFTCB1 = 0x01; SYNCDELAY; ####### HERE #######
GPIFTCB0 = 0x00; SYNCDELAY; ####### HERE #######
setup_flowstate_read ();
SYNCDELAY;
GPIFTRIG = bmGPIF_EP6_START | bmGPIF_READ; // start the xfer
SYNCDELAY;
while (!(GPIFTRIG & bmGPIF_IDLE)){
// wait for the transaction to complete
}
SYNCDELAY;
INPKTEND = 6; // tell USB we filled buffer (6 is our endpoint num)
}
}
Unless you get lucky and the modification above labeled "HERE" works, you're really going to want access to a logic analyzer.
See:
Another thing I was wondering, since the vendor id is a standard free for all type, how do you actually determine if it is indeed a USRP that you are connected to, and on top of that if you are connected to an FX2 chip which is not the USRP and has not been initialized, can you determine that it is an FX2 that in on a USRP or not?
All the shipped USRPs have a non-Cypress USB VID/PID burned into them. There is no confusion between a USRP and an un-programmed FX2. We use: VID = 0xfffe, PID = 0x0002. We distinguish board revs and whether or not we've loaded our firmware via the DID.
See source:usrp/firmware/include/usrp_ids.h.
Pretty much every question about how to control the USRP is answered in one of the .h files in source:usrp/firmware/include. In particular; see source:usrp/firmware/include/fpga_regs_common.h and source:usrp/firmware/include/fpga_regs_standard.h for the definitions of the configuration registers in the FPGA.
No need for any driver programming. Just use libusb.
Here is the outline of a few steps:
Absolutely. You can use a slightly modified usrper and test_usrp_standard_rx to get yourself going until you build your own customized executable from the libraries.
No command. In USRP we run the FX2 at 48 MHz after our firmware is loaded.
No, it means 2K lines, each line is 32 bits. The FX2 also implements quad buffering in both TX and RX directions, each buffer is 512 bytes.
The fusb_block_size is the size in bytes of the maximum transfer that we will ask the kernel to make to/from user-space. The fusb_nblock is the maximum number of transfers (of maximum size fusb_block_size) that we can have in flight at any given time. Take a look at source:usrp/host/lib/fusb_linux.h and source:usrp/host/lib/fusb_linux.cc for the details.
Yes. The USRP packages data into 512 byte USB packets and sends them as soon as it can. That's 128 complex samples (16-bit I & Q).
Its 512 bytes. It's set in the FX2 firmware.
Yes, modulo problem with signals being asserted one cycle too long on WR.
None.
Nope, not that either.
| << Timing Latency | ^ Top ^ |
Back to UsrpFAQ
Once the "regular" firmware is loaded, the slow blinking is done in the timer interrupt service routine, isr_tick. See [source:gnuradio/trunk/usrp/firmware/src/usrp2/usrp_main.c usrp/firmware/src/usrp2/usrp_main.c]
"u" = USRP
"a" = audio (sound card)
"O" = overrun (PC not keeping up with received data from usrp or audio card)
"U" = underrun (PC not providing data quickly enough)
aUaU audio underrun (not enough samples ready to send to sound card sink)
uUuU USRP underrun (not enough sample ready to send to USRP sink)
uOuO == USRP overrun (USRP samples dropped because they weren't read in time.
Yes, a faster machine will generally cure this problem. This assumes that you're not asking the USB to do something that it can't. In our best case, we sustain 32MB/s across the USB. I suggest avoiding Intel Celeron or other "cache crippled" parts.
No. Overrun detection is currently implemented by polling at approximately 10Hz. If you're trying to receive constantly streaming data, you shouldn't see any uO's.
The USRP itself contains no ROM-based firmware, merely a few bytes that specify the vendor ID (VID), product ID (PID) and revision. When the USRP is plugged in to the USB for the first time, the host-side library sees an un-configured USRP. It can tell it's un-configured by reading the VID, PID and revision. The first thing the library code does is download the 8051 code that defines the behavior of the USB peripheral controller. When this code boots, the USRP simulates a USB disconnect and reconnect.
When it reconnects, the host sees a different device: the VID, PID and revision are different. The firmware now running defines the USB endpoints, interfaces and command handlers. One of the commands the USB controller now understands is load the FPGA. The library code, after seeing the USRP reconnect as the new device, goes to the next stage of the boot process and downloads the FPGA configuration bit stream.
Once the firmware has been downloaded to the FX2, it sets an internal register and reboots itself, this time presenting custom product and vendor ID’s, which the host detects as the FX2 disconnecting followed by the connection of a custom USB device.
The FPGA is programmed in Verilog, and compiled with Quartus from Altera. The motherboard layout was done in PADS, but the layout files are not distributed. The schematics are done in gEDA.
The USRP motherboard can operate from 5V, but most of the daughterboards regulate the 6V down to 5V, so we really need about 5.5 to 5.75 V to operate correctly. Only the BasicRX and BasicTX really don't need 6V. Everything else basically does.
No, it isn't. The USRP itself uses a linear regulator, so putting 13.8 V in will result in more than 10 additional watts being dissipated. Also, many of the capacitors on the daughterboards are sized for 6V input, and might blow with more than 10 V.
The fuse size is 0603. Rating is 3Amps.
When the FPGA is routed, there isn't much more slack above the 64MHz for Fmax (or so I thought).
src = usrp.source_c (0, decim)
src.set_rx_freq (0, IF_freq)
src.set_pga(0,20)
Please take a look at the code in usrp_standard.{h,cc}, usrp_basic.{h,cc}, and usrp_prims.{h,cc}. They all go over the USB as control messages to endpoint 0. The control messages are parsed in the FX2 and acted upon. Generally speaking they end up issuing transactions on the I2C bus or SPI bus.
The FPGA registers, AD9862 registers and daughterboards appear on the SPI bus. The configuration EEPROM’s and daughterboards appear on the I2C bus. See the USRP schematics for details. The [source:gnuradio/trunk/usrp/firmware/include/usrp_spi_defs.h usrp/firmware/include/usrp_spi_defs.h] contains the definition for the SPI bus. The [source:gnuradio/trunk/usrp/firmware/include/usrp_i2c_addr.h usrp/firmware/include/usrp_i2c_addr.h] contains the standard I2C addresses. Some daughterboards use others that are a function of which slot the daughterboard is plugged into.
The USRP has buffers at three points in the path:
On the host: currently 8MB TX, 8MB Rx. ( #FIXME# )
On the Cypress FX2 USB peripheral: 2KB TX and 2KB Rx. ( #FIXME# )
On the FPGA: 4KB TX and 4KB RX.
The different paths alternate in the FIFO. The data is in this order:
CH1-I
CH1-Q
CH2-I
CH2-Q
etc...
Edit the file config.vh , then uncomment the line:
//@include "../include/common_config_1rxhb_1tx.vh"
And comment the line:
@include "../include/common_config_2rxhb_2tx.vh"
By using “//”, this will now includes 1 TX and 1 RX with halfband filter.
The ADCs always sample at 12 bits. The DACs are always 14 bits. The data processed in the USRP is always 16 bits. From python you can switch to 8-bit samples over the USB. This allows you to double your sample rate make it (16MSPS).
I usually prefer to do this kind of experimentation from Python, but in any event you're probably using an invalid I2C address. See [source:gnuradio/trunk/usrp/firmware/include/usrp_i2c_addr.h usrp/firmware/include/usrp_i2c_addr.h].
Note also, that if what you're really trying to do is read the contents of one of the EEPROM's, you're much better off using read_eeprom.
From python:
u = usrp.sink_c(0) # or u = usrp.source_c(0)
# returns a string
s = u.read_eeprom(i2c_addr, eeprom_offset, nbytes)
print s
# returns a string
s = u.read_i2c(i2c_addr, nbytes)
print s
This allows someone (from Python) to manually adjust the timing offset of the auto-transmit/receive switching to better align with the transmitted data when using an external transmit/receive switch.
In a previous code, the auto transmit/receive function would switch based on whether or not there was data in the transmit FIFO of the FPGA. Unfortunately, this would not take into account the pipeline delay of the FPGA interpolator and AD9862 DAC up converter. Depending on the interpolation ratio used in the transmit side, this could result in the ATR switching signal going high up to 25 us early, and going low up to 35 us before the data was completely transmitted. If someone were using a fast external Rx/Tx switch, this could result in slicing off the end of a transmission.
The new capability adds an independent, configurable delay to the rising and falling edges of the ATR signal, measured in clock ticks. To use, once one has already configured ATR operation as needed, one needs to call two new daughterboard functions:
subdev.set_atr_tx_delay(clock_ticks_to_delay_tx) # Rising edge subdev.set_atr_rx_delay(clock_ticks_to_delay_rx) # Falling edge...where 'subdev' is the object created for the daughterboard in use. Unfortunately, the best way (right now) is to figure out what values to poke in here are to measure the offset on an oscilloscope between the onset of the ATR signal and the power output from the daughterboard. We're working on a way to ask the FPGA itself what values should be set (or even set these by default), but haven't worked out yet the best way to do this. Different external Rx/Tx switches have different needs so there isn't a one size fits all. Empirically measured, though, the pipeline delay through the USRP transmit path is about 50 ticks + 3 ticks * interpolation rate. It seems the falling edge needs somewhat longer than this to completely drop to zero energy and this may be data dependent, so again, the best course is to measure with your particular application.
The clock has a 20 ppm specification, but at room temperature, It is typically within 5 ppm.
All of the chips in the USRP are specified over at least the 0-70C range. At room temperature the USRP can run all-out continuously for days at a time. Any enclosure should take the power consumption of the system into account. This can be as high as 15-18 Watts depending on what daughterboards you use.
There is a loopback interface in the current FPGA code. It's enabled by writing to the FR_MODE register. Grep the verilog for "loopback", and look at fpga_regs_common.{h,v}
The USRP easily does 256 megabits per second (32 megabytes/s). The USB 2.0 raw signaling rate is 480 megabits per second, or 60 megabytes per second. You can't get the full 480 because there is overhead from packet headers, time between packets, etc. We could probably squeeze a little more bandwidth out of the bus, but it isn't a priority for now. The USRP needs data to go both ways, so there are some firmware delays in the 8-bit processor that runs in the interface chip.
If someone cared, it is probably possible to reprogram the firmware so that when no data is being transmitted, the automatic hardware mode is used. The firmware would have to know, or be told, when to switch in and out of this mode. But this would gain 25% more bandwidth!
20 MHz bandwidth indicates the width of the baseband filters. Thus, you can tune digitally anywhere +/- 10 MHz from the LO. If you use 16 bit samples, you can't get that much over the USB bus at once.
So why is 20 MHz useful? Here are 3 example scenarios:
See: USRP FPGA Under "Common Registers" 15 FR_DC_OFFSET_CL_EN DC offset control loop enable
Back to UsrpFAQ
Back to UsrpFAQ
The Universal Software Radio Peripheral, or USRP (pronounced usurp) is designed to allow general purpose computers to function as high bandwidth software radios. In essence, it serves as a digital baseband and IF section of a radio communication system.
The basic design philosophy behind the USRP has been to do all of the waveform-specific processing, like modulation and demodulation, on the host CPU. All of the high-speed general purpose operations like digital up and down conversion, decimation and interpolation are done on the FPGA.
The true value of the USRP is in what it enables engineers and designers to create on a low budget and with a minimum of effort. A large community of developers and users have contributed to a substantial code base and provided many practical applications for the hardware and software. The powerful combination of flexible hardware, open-source software and a community of experienced users make it the ideal platform for your software radio development.
Back to UsrpFAQ
| << USRP Motherboard | ^ Intro ^ | DAC >> |
There are 4 high-speed 12-bit AD converters. The sampling rate is 64M samples per second. In principle, it could digitize a band as wide as 32MHz. The AD converters can bandpass-sample signals of up to about 200MHz. If several decibels of loss is tolerable, then, IF frequency as high as 500 MHz can be digitized. However, if we sample a signal with the IF larger than 32MHz, we will introduce aliasing and actually the band of the signal of interest is mapped to some places between -32MHz and 32MHz. Sometimes this can be useful, for example, we could listen to the FM stations without any RF front end. The higher the frequency of the sampled signal, the more the SNR will be degraded by jitter. 100MHz is the recommended upper limit.
The full range of the ADCs is 2V peak to peak, and the input is 50 ohms differential. This is 10mW, or 10dBm. There is a programmable gain amplifier (PGA) before the ADCs to amplify the input signal to utilize the entire input range of the ADCs, in case the signal is weak. The PGA is up to 20dB. With gain set to zero, full scale inputs are 2 Volts peak-to-peak differential. When set to 20 dB, only .2 V p-p differential input signal is needed to reach full scale. This PGA is software programmable.
If signals are AC-coupled, there is no need to provide DC bias as long as the internal buffer is turned on. It will provide an approximately 2V bias. If signals are DC-couple, a DC bias of VCC/2 (1.65V) should be provided to both the positive and negative inputs, and the internal buffer should be turned off. The ADC VREF provides a clean 1 V reference.
| << USRP Motherboard | ^ Intro ^ | DAC >> |
| << DAC | ^ Intro ^ | Aux Digital IO Ports >> |
There are 8 Auxiliary analog input channels connected to low speed 10 bit ADC inputs (labeled AUX_ADC_A1_A, AUX_ADC_B1_A, AUX_ADC_A2_A, AUX_ADC_B2_A, AUX_ADC_A1_B, AUX_ADC_B1_B, AUX_ADC_A2_B, and AUX_ADC_B2_B) which can be read from software. These ADCs can convert up to 1.25MSPS and have a bandwidth of around 200 KHz. These analog channels are useful for sensing the RSSI signal levels, temperatures, bias levels, etc.
Additionally, there are 8 analog output channels connected low-speed 8bit DAC outputs. These are AUX_DAC_A_A, AUX_DAC_B_A, AUX_DAC_C_A, AUX_DAC_A_B, AUX_DAC_B_B and AUX_DAC_C_B. These DACs can be used for supplying various control voltages such as external variable gain amplifiers control. In addition, there are two additional DACs (labeled AUX_DAC_D_A and AUX_DAC_D_B) which are constructed using 12 bit sigma-delta modulator with external simple low pass filter.
The USRP motherboard connectors (RXA and TXA) share one set of the 4 analog output channels (AUX_DAC_A_A to AUX_DAC_D_A for RXA and TXA) and each have 2 independent analog input channels (AUX_ADC_A1_A and AUX_ADC_B1_A for RXA and AUX_ADC_A2_A and AUX_ADC_B2_A for TXA). The RXB and TXB share their other own independent set. There is also AUX_ADC_REF which can provide a reference level for gain setting if it is necessary.
| << DAC | ^ Intro ^ | Aux Digital IO Ports >> |
| << Aux Analog IO Ports | ^ Intro ^ | FPGA >> |
The USRP motherboard has high speed 64 bit digital I/O ports. These are divided in two groups (32 bit for IO_RX and 32 bit for IO_TX). These digital I/O pins are connected to the daughterboards interface connecters (RxA, TxA, RxB and TxB). Each of these connectors has 16 bit digital I/O bits. These signals can be controlled from software by reading/writing to special FPGA registers and each can be independently configured either as digital input or digital output.
Some of these pins are used to control specific operations on the installed daughterboards such as controlling the selection of receiving RF input port, in automatic transmit/receive mode, controlling power supply feeding for different TX and RX parts, synthesizer lock detection,…etc. It can be also used to implement AGC processing and can be very helpful in debugging FPGA implementations when connected to a logic analyzer.
| << Aux Analog IO Ports | ^ Intro ^ | FPGA >> |
| << ADC | ^ Intro ^ | Aux Analog IO Ports >> |
At the transmitting path, there are also 4 high-speed 14-bit DA converters. The DAC clock frequency is 128 MS/s, so Nyquist frequency is 64MHz. However, we will probably want to stay below it to make filtering easier. A useful output frequency range is from DC to about 44MHz. The DACs can supply 1V peak to a 50 ohm differential load, or 10mW (10dBm). There is also PGA used after the DAC, providing up to 20dB gain. This PGA is software programmable. The DAC signals (IOUTP_A/IOUTN_A and IOUTP_B/IOUTN_B) are current-output, each varying between 0 and 20 mA. They can be converted into differential voltages with a resistor.
| << ADC | ^ Intro ^ | Aux Analog IO Ports >> |
| << FPGA | ^ Intro ^ | Power >> |
On the mother board there are four slots, where you can plug in up to 2 RX basic daughter boards and 2 TX basic daughter boards or 2 RFX boards. The daughter boards are used to hold the RF receiver interface or tuner and the RF transmitter. There are slots for 2 TX daughter boards, labeled TXA and TXB, and 2 corresponding RX daughter boards, RXA and RXB. Each daughter board slot has access to 2 of the 4 high-speed AD / DA converters (DAC outputs for TX, ADC inputs for RX).
This allows each daughter board which uses real (not IQ) sampling to have 2 independent RF sections, and 2 antennas (4 total for the system). If complex IQ sampling is used, each board can support a single RF section, for a total of 2 for the whole system. Normally, we can see that there are two SMA connectors on each daughter board. We usually use them to connect the input or output signals. No anti-alias or reconstruction filtering is provided on the USRP motherboard. This allows for maximum flexibility in frequency planning for the daughterboards.
Every daughterboard has an I2C EEPROM (24LC024 or 24LC025) onboard which identifies the board to the system. This allows the host software to automatically set up the system properly based on the installed daughterboard. The EEPROM may also store calibration values like DC offsets or IQ imbalances. If this EEPROM is not programmed, a warning message is printed every time USRP software is run.
Each TX daughterboard has a pair of differential analog outputs which are updated at 128 MS/s. The signals (IOUTP_A/IOUTN_A and IOUTP_B/IOUTN_B) are current-output. Also Each RX daughterboard has 2 differential analog inputs (VINP_A/VINN_A and VINP_B/VINN_B) which are sampled at a rate of 64 MS/s.
Each has two SMA connectors that can be used to connect external up/down tuners or signal generators. We can treat it as an entrance or an exit for the signal without affecting it. Some form of external RF front end is required. The ADC inputs and DAC outputs are directly transformer-coupled to SMA connectors (50? impedance) with no mixers, filters, or amplifiers. The Basic TX and Basic RX give direct access to all of the signals on the daughterboard interface (including 16 bits of high-speed digital I/O, SPI and I2C buses, and the low-speed ADCs and DACs). Each of the Basic TX/RX boards has logic analyzer connecters for the 16 general purpose IOs. These pins can be used to help debugging your FPGA design by providing access to internal signals.
The LFTX and LFRX are very similar to the Basic TX and Basic RX, respectively, with 2 main differences. Because the LFTX and LFRX use differential amplifiers instead of transformers, their frequency response extends down to DC. The LFTX and LFRX also have 30 MHz low pass filters for anti-aliasing.
This is a receive-only daughter board. It is a complete VHF and UHF receiver system based on a TV tuner module. The RF frequency ranges from 50MHz to 860MHz, with an IF bandwidth of 6MHz.
All tuning and AGC functions can be controlled from software. Typical noise figure is 8 dB. This board is the only USRP daughterboard which is NOT MIMO capable.
Similar to the TVRX board, this is also a receive-only. It is a complete receiver system for 800 MHz to 2.4 GHz with a 3 -5 dB noise figure. The DBSRX features a software controllable channel filter which can be made as narrow as 1 MHz, or as wide as 60 MHz. The DBSRX is MIMO capable, and can power an active antenna via the SMA.
The RFX family of daughterboards is a complete RF transceiver system. They have Independent local oscillators (RF synthesizers) for both TX and RX which enables a split-frequency operation. Also, it has a built-in T/R switching and signal TX and RX can be on same RF port (connector) or in case of RX only, we can use auxiliary RX port. Most boards have built-in analog RSSI measurement. All boards are fully synchronous design and MIMO capable. For RFX daughterboards RF frequency range, check: Ettus Research
For detailed reference and images, check the List of USRP daughterboards
| << FPGA | ^ Intro ^ | Power >> |
| << Aux Digital IO Ports | ^ Intro ^ | Daughterboards >> |
Probably understanding what goes on the USRP FPGA is the most important part for the GNU Radio users. As shown in the figure below, all the ADCs and DACs are connected to the FPGA. This piece of FPGA plays a key role in the USRP system. Basically what it does is to perform high bandwidth math, and to reduce the data rates to something you can squirt over USB2.0. The FPGA connects to a USB2 interface chip, the Cypress FX2. Everything (FPGA circuitry and USB Microcontroller) is programmable over the USB2 bus.

The standard FPGA configuration includes digital down converters (DDC) implemented with 4 stages cascaded integrator-comb (CIC) filters. CIC filters are very high-performance filters using only adders and delays. For spectral shaping and out of band signals rejection, there are also 31 tap halfband filters cascaded with the CIC filters to form complete DDC stage. The standard FPGA configuration implements 2 complete digital down converters (DDC). Also there is a configuration with 4 DDCs but without halfband filters, which allows 1, 2 or 4 separate RX channels.
In the 4 DDC implementation, in the RX path we have 4 ADCs, and 4 DDCs. Each DDC has two inputs I and Q. Each of the 4 ADCs can be routed to either of I or the Q input of any of the 4 DDCs. This allows for having multiple channels selected out of the same ADC sample stream.
The figure below shows the block diagram of the USRP digital down converter.

Now let's see the digital down converter (DDC). First, it down converts the signal from the IF band to the base band. Second, it decimates the signal so that the data rate can be adapted by the USB 2.0 and is reasonable for the computers' computing capability. The complex input signal (IF) is multiplied by the constant frequency (usually also the IF) exponential signal. The resulting signal is also complex and centered at 0. Then we decimate the signal with a factor N.
The decimator can be treated as a low pass filter followed by a down sampler. Suppose the decimation factor is N. If we look at the digital spectrum, the low pass filter selects out the band [-Fs/N, Fs/N], and then the down sampler de-spread the spectrum from [-Fs, Fs] to [-Fs/N, Fs/N]. So in fact, we have narrowed the bandwidth of the digital signal of interest by a factor of N.
Regarding the bandwidth, we can sustain 32MB/sec across the USB. All samples sent over the USB interface are in 16-bit signed integers in IQ format, i.e. 16-bit I and 16-bit Q data (complex) which means 4 bytes per complex sample. This resulting in a (32MByte per sec/4Byte) 8Mega complex samples/sec across the USB. Since complex processing was used, this provides a maximum effective total spectral bandwidth of about 8MHz by Nyquist criteria. Of course we can select much narrower ranges by changing the decimation rate. For example, suppose we want to design an FM receiver. The bandwidth of a FM station is generally 200 kHz. So we can select the decimation factor to be 250. Then the data rate across the USB is 64MHz / 250 = 256 kHz, which is well suited for the 200 kHz bandwidth without losing any spectral information. The decimation rate must be in [8, 256]. Finally the complex I/Q signal enters the computer via the USB. That's the software world!
Note that when there are multiple channels (up to 4), the channels are interleaved. For example, with 4 channels, the sequence sent over the USB would be I0 Q0 I1 Q1 I2 Q2 I3 Q3 I0 Q0 I1 Q1, …etc. In multiple RX channels (1,2, or 4) , all input channels must be the same data rate (i.e. same decimation ratio).
At the TX path, the story is pretty much the same, except that it happens reversely. We need to send a baseband I/Q complex signal to the USRP board. The digital up converter (DUC) will interpolate the signal, up convert it to the IF band and finally send it through the DAC.

The digital up converters (DUC) on the transmit side are actually contained in the AD9862 CODEC chips, not in the FPGA (as shown in the figure below). The only transmit signal processing blocks in the FPGA are the CIC interpolators. The interpolator outputs can be routed to any of the 4 CODEC inputs.
In multiple TX channels (1 or 2) all output channels must be the same data rate (i.e. same interpolation ratio). Note that Tx rate may be different from the RX rate.
The USRP can operate in full duplex mode. In this mode, transmit and receive sides are completely independent of one another. The only consideration is that the combined data rate over the bus must be 32 Megabytes per second or less.
| << Aux Digital IO Ports | ^ Intro ^ | Daughterboards >> |
| ^ Intro ^ | ADC >> |
The USRP has 4 high-speed analog to digital converters (ADCs), each at 12 bits per sample, 64MSamples/sec. There are also 4 high-speed digital to analog converters (DACs), each at 14 bits per sample, 128MSamples/sec. These 4 input and 4 output channels are connected to an Altera Cyclone EP1C12 FPGA. The FPGA, in turn, connects to a USB2 interface chip, the Cypress FX2, and on to the computer. The USRP connects to the computer via a high speed USB2 interface only, and will not work with USB1.1.
So in principle, we have 4 input and 4 output channels if we use real sampling. However, we can have more flexibility (and bandwidth) if we use complex (IQ) sampling. Then we have to pair them up, so we get 2 complex inputs and 2 complex outputs.

| ^ Intro ^ | ADC >> |
| << Daughterboards | ^ Intro ^ | Trouble Shooting >> |
The USRP is powered by a 6V 4A AC/DC power converter. The converter is capable of 90-260VAC, 50/60 Hz operation, and so should work in any country. If there is a need to use another power supply, the connector is a standard 2.1mm/5.5mm DC power connector. The USRP motherboard itself only needs 5V, but a 6V supply is needed to supply its daughterboards. It draws about 1.6A with 2 daughterboards fixed on it. The power can be checked to be connected to the USRP by seeing a blinking LED on it. If there is no blinking LED, check all power connections, and check for continuity in the power fuse (F501, near the power connector). If the fuse needs replacement, it is size 0603, rating 3 amps.
| << Daughterboards | ^ Intro ^ | Trouble Shooting >> |
| << Power | ^ Intro ^ |
(FIXME: add more ;))
When first powered up, a LED on the USRP should be flashing at about 3-4 times per second. This indicates that the processor is running, and has put the device in a low power mode. Once firmware has been downloaded to the USRP, the LED will blink at a slower rate.
| << Power | ^ Intro ^ |
| << Digital Up Converter | ^ Top ^ | Daughterboards >> |
All the signals are LVCMOS, 0 to 3.3V. The correct threshold is 1.65V (3.3V/2)
There are two ways to control the I/O pins, either from the host, or from within the FPGA.
To control them from the host no changes are required in the verilog. From python you need to tell it to "output enable" the pins you are interested, and then write whatever values you like to them.
From [source:gnuradio/trunk/gr-usrp/src/usrp1.i gr-usrp/src/usrp1.i]:
/*!
**** \brief Write direction register (output enables) for pins that go to daughterboard.
****
**** \param which_dboard [0,1] which daughterboard
**** \param value value to write into register
**** \param mask which bits of value to write into reg
****
**** Each daughterboard has 16-bits of general purpose i/o.
**** Setting the bit makes it an output from the FPGA to the daughterboard.
****
**** This register is initialized based on a value stored in the
**** daughterboard EEPROM. In general, you shouldn't be using this routine
**** without a very good reason. Using this method incorrectly will
**** kill your USRP motherboard and/or daughterboard.
*/
bool _write_oe (int which_dboard, int value, int mask);
/*!
**** \brief Write daughterboard i/o pin value
****
**** \param which_dboard [0,1] which daughterboard
**** \param value value to write into register
**** \param mask which bits of value to write into reg
*/
bool write_io (int which_dboard, int value, int mask);
/*!
**** \brief Read daughterboard i/o pin value
****
**** \param which_dboard [0,1] which daughterboard
**** \returns register value if successful, else READ_FAILED
*/
int read_io (int which_dboard);
E.g.,
# Assumes Basic_Tx in slot A. Do not do this blindly! Output enabling all the i/o pins
# on other daughterboards will cause problems (burn up daughterboard and/or FPGA)
u = usrp.sink_c(0, 64)
side = 0 # side A
u._write_oe(side, 0xffff, 0xffff) # set all i/o pins as outputs
counter = 0
while 1:
u.write_io(side, counter, 0xffff)
counter = (counter + 1) & 0xffff
If however, you're trying to control the debug pins from the FPGA, you'll need to output enable them from the host, and enable them as debug outputs. You do the last step by writing to the FR_DEBUG_ENABLE FPGA register:
From [source:gnuradio/trunk/usrp/firmware/include/fpga_regs_common.h usrp/firmware/include/fpga_regs_common.h]:
// If the corresponding bit is set, internal FPGA debug circuitry // controls the i/o pins for the associated bank of daughterboard // i/o pins. Typically used for debugging FPGA designs. #define FR_DEBUG_EN 14 # define bmFR_DEBUG_EN_TX_A (1 << 0) // debug controls TX_A i/o # define bmFR_DEBUG_EN_RX_A (1 << 1) // debug controls RX_A i/o # define bmFR_DEBUG_EN_TX_B (1 << 2) // debug controls TX_B i/o # define bmFR_DEBUG_EN_RX_B (1 << 3) // debug controls RX_B i/oThese defines are available in python like this:
from usrp_fpga_regs import * u = usrp.sink_c(0, 64) u._write_oe(0, 0xffff, 0xffff) u._write_fpga_reg(FR_DEBUG_EN, bmFR_DEBUG_EN_TX_A)
Look at [source:gnuradio/trunk/usrp/fpga/toplevel/usrp_std/usrp_std.v usrp/fpga/toplevel/usrp_std/usrp_std.v]:
wire [15:0] reg_0,reg_1,reg_2,reg_3;
master_control master_control
( .master_clk(clk64),.usbclk(usbclk),
.serial_addr(serial_addr),.serial_data(serial_data),.serial_strobe(serial_strobe),
.tx_bus_reset(tx_bus_reset),.rx_bus_reset(rx_bus_reset),
.tx_dsp_reset(tx_dsp_reset),.rx_dsp_reset(rx_dsp_reset),
.enable_tx(enable_tx),.enable_rx(enable_rx),
.interp_rate(interp_rate),.decim_rate(decim_rate),
.tx_sample_strobe(tx_sample_strobe),.strobe_interp(strobe_interp),
.rx_sample_strobe(rx_sample_strobe),.strobe_decim(strobe_decim),
.tx_empty(tx_empty),
//.debug_0(rx_a_a),.debug_1(ddc0_in_i),
.debug_0(tx_debugbus[15:0]),.debug_1(tx_debugbus[31:16]),
.debug_2(rx_debugbus[15:0]),.debug_3(rx_debugbus[31:16]),
.reg_0(reg_0),.reg_1(reg_1),.reg_2(reg_2),.reg_3(reg_3) );
The arguments .debug_0(...) through .debug_3(...) are the signals that get connected to the debug pins.
debug_0 -> TX_AThe external IO pins should not have to be mapped if you use Matt's Quartus II project. It will already have the pins mapped to where they have to be mapped.
You are safe with both the basic boards and the TVRX, since they don't drive any of the pins.
There are several ways to do this. All of the daughterboard IO pins can be controlled from software, all the way up to the python application level. However, if you want the pins to change quickly, you need to do it in the FPGA. There is already a mechanism for antenna switching. Look in the auto_tr code in db_flexrf.py. Also you can use the gr_gpio.
gr-gpio is an extension to the normal USRP firmware, implemented as an alternative FPGA bit stream, using the existing USRP host code. With the gr-gpio component you can transmit and receive a digital stream to and from the USRP which is aligned with the existing analog stream. Digital data is sent to or received from the daughterboard GPIO pins and sacrifice one bit each from the I and the Q analog streams to transport the digital bits. See CompGrGpio.
/* Each daughterboard has 16-bits of general purpose i/o. * Setting the bit makes it an output from the FPGA to the daughterboard. * This register is initialized based on a value stored in the * daughterboard EEPROM. In general, you shouldn't be using this routine * without a very good reason. Using this method incorrectly will * kill your USRP motherboard and/or daughterboard. */ bool _write_oe (int which_dboard, int value, int mask); u = usrp.sink_c(0, 64) side0 = 0 # side A u._write_oe(side0, 0xffff, 0xffff) # set all i/o pins as outputs side1=1 # side B u._write_oe(side1, 0xffff, 0xffff) # set all i/o pins as outputsThe daughterboard and the FPGA are both driving at least pin 2. Though the pins are called "general purpose i/o", that doesn't mean the user should mess with all of them. Some of them are used by the daughterboard code to control or read status from parts on the daughterboards. Which pins are safe for the user to mess with depends on the design of the given daughterboard. Hence our scary warning on _write_oe. Look at the schematics for the RFX-2400 board and figure out which of the 16 I/O pins are actually used by the TX and RX halves of the transceiver daughterboard, and which ones are available for your use. See which of the I/O pins actually makes it to the header on the board. Look again and check your work. Look at the daughterboard code ([source:gnuradio/trunk/gr-usrp/src/db_flexrf.py db_flexrf.py]). See what it's doing to the various output enables and I/O pins. Does this match your understanding of which pins are available for your use? Confirm again which pins are safe for you to be messing with.
u._write_fpga_reg(FR_DEBUG_EN, ??)All the output enables are controlled using _write_oe. FR_DEBUG_EN determines whether the debug pins are routed to the i/o pins or whether the normal write_io and auto T/R values make it to the header. See the bottom of master_control.v for the details. Given what you'll find out after you look at the schematics, no value of FR_DEBUG_EN except for 0 is safe when you're using two RFX-2400 boards. If you can get by with a single RFX-2400, my suggestion is that you put it on the A-side, and then put a Basic Tx and a Basic Rx on the B-side. Then you've got a total of 32 uncommitted I/O pins on the B-side. The FR_DEBUG_EN register wasn't designed to solve every possible problem. It solved the one we had, which was getting debug info out to a Basic Rx and/or Basic Tx.
| << Digital Up Converter | ^ Top ^ | Daughterboards >> |
| << Loading FPGA Bit Stream | ^ Top ^ | FX2 USB Controller |
Tu = f(512, fusb_block_size*fusb_nblock) / (fs*sample_size )Where:f(x,y) is depends on the data in the buffer and it is at least x and at most y and fs is the sampling frequency. Since we use complex 16 bit samples, the sample size is
sample_ size = 2 * 16bit= 4 bytesSo, does that mean if we have large product of fusb_block_size and fusb_nblock, then the theoretical maximum delay will be increased? Yes that is true. If you're trying to minimize latency you want the smallest values that work reliably (no over/underruns) and with acceptable overhead. If you enable real time scheduling, you can reliably use smaller values. Try fusb_block_size 2048 and fusb_nblock 4 or 8. You may be able to run with fusb_block_size 1024. It depends on your data rate across the USB.
Different cases:
Theoretical Calculations:
Let the PKTSIZE = 512. In both directions we can't start the transport until you've assembled a full packet. Assume we're running at 32MB/sec, t0 = 16usec. The transport time of a single packet from the host controller to the FX2 is
t1 = PKTSIZE (bytes)/32(Mbyte/sec) = 16 usec
The transport time of a single packet from the FX2 to the FPGA is about
t2 = 4 us + PKTSIZE (bytes)/96(Mbyte/sec) = 9.33 usec
[The 4 us is firmware overhead in the FX2. It could be improved]
The best case:
Outbound looks like = t0 + t1 + t2 = 41.33 usec. Inbound is the same 41.33 usec.
With 512 byte packets, total round trip latency
2 * (t0 + t1 + t2) = 83 usec
Lowering the packet size to 64 bytes would reduce this to
2 * (2 + 2 + 4.7) = 8.7 us
[This is optimistic, since our throughput will drop, and there are lots of other unaccounted factors. E.g., greater USB overhead because of the small packets]
Here's an easy way to measure round trip latency:
Hook up a signal generator to one of the Rx basic inputs and to one input of an oscilloscope. Hook up one Tx basic output to another input on the o'scope. Write some code on the host that reads from usrp.source_c and writes to usrp.sink_c Look at the delay between the two traces on your o'scope.
| << Loading FPGA Bit Stream | ^ Top ^ | FX2 USB Controller |
| << C++ Interfacing | ^ Top ^ | Motherboard Re-Clocking >> |
The RSSI on the motherboard will tell you the power within approx. +/- 15 MHz from your carrier. You can also get a digital RSSI which will tell you the power within your signal of interest. The way we have envisioned RSSI is as a 3-part measurement:
If you want to use the measured analog RSSI, it will measure whatever passes through the analog channel filter. You can only change that bandwidth by changing inductors and capacitors. Note also that analog RSSI is only on the RFX900, RFX1200, RFX1800, and RFX2400. The RFX400, TVRX, and DBSRX do not have that capability.
The RFX900, 1200, 1800, and 2400 have an RSSI circuit on board. The RFX400 does not.
To read the RSSI value, use read_aux_adc(side,0). The RSSI measures the analog signal level after the lowpass filters on the board. These filters are about 15-20 MHz wide. Thus, anything falling in that band will cause a rise in the RSSI value. It is connected to the low-speed adc AUX_ADC_A1, so you need to read that with read_aux_adc(which_dboard,0) See [source:gnuradio/trunk/gr-usrp/src/usrp1.i usrp1.i] (and in usrp_basic.{[source:gnuradio/trunk/usrp/host/lib/legacy/usrp_basic.cc cc],[source:gnuradio/trunk/usrp/host/lib/legacy/usrp_basic.h h]):
int read_aux_adc (int which_dboard, int which_adc);The RSSI reads the power in the analog baseband signals (power (I) + power (Q)). The analog baseband will contain signals from approximately +/- 15 MHz from the LO frequency.
Yes, that is correct. You can reconfigure the board by moving some resistors around to make it automatic if you wanted.
You don't use the mux register to read the AUX_ADCs. See usrp/host/lib/usrp_{[[source:gnuradio/trunk/usrp/host/lib/legacy/usrp_basic.h basic],[source:gnuradio/trunk/usrp/host/lib/legacy/usrp_standard.h standard]}.h for docs on all of this stuff.
See especially usrp_basic_rx: :read_aux_adc and usrp_basic_tx: :read_aux_adc
1 /*!
2 **** \brief Read auxiliary analog to digital converter.
3 ****
4 **** \param which_dboard [0,1] which daughterboard
5 **** \param which_adc [0,1]
6 **** \param value return 12-bit value [0,4095]
7 **** \returns true iff successful
8 */
9 bool read_aux_adc (int which_dboard, int which_adc, int *value);
10
11 /*!
12 **** \brief Read auxiliary analog to digital converter.
13 ****
14 **** \param which_dboard [0,1] which daughterboard
15 **** \param which_adc [0,1]
16 **** \returns value in the range [0,4095] if successful, else READ_FAILED.
17 */
18 int read_aux_adc (int which_dboard, int which_adc);
The second version has a python binding:
v = u.read_aux_adc(0, 0)where u is an instance of a usrp.source_c or usrp.sink_c The bad news is that these are read asynchronously using a slow path over the USB. You probably can't read them fast enough to sample to your input signal, and the sampling is asynchronous.
| << C++ Interfacing | ^ Top ^ | Motherboard Re-Clocking >> |
The FPGA being used on the USRP is an Altera Cyclone EP1C12Q240C8.
Features of the EP1C12:| LEs | 12,060 | |||
| M4k RAM blocks (128 x 36 bits) | 52 | |||
| Total RAM bits | 239,616 | |||
| PLLs | 2 | |||
| Maximum user I/O pins | 173 |
The hardware language used to describe the functionality within the FPGA is written in Verilog and synthesized using Altera's free web tool Quartus II. It should be noted that Quartus II can run free only within a Windows environment, though there are ways to run Quartus II under Linux without the need for Windows - YMMV.
The FPGA runs off a 64MHz clock with every internal component synchronous to that global clock. Due to the relatively high clocking frequency, everything within the FPGA is highly pipelined to achieve the highest speed possible.
See UsrpRfxDiagrams.
AD9862 -> CORDIC -> Decimating CIC Filter (4 stage, Programmable decimation rate [4,128]) -> Halfband Decimation Filter (Fixed decimation by 2) -> RX FIFO.
This yields possible decimation rates of all even numbers between [8,256].
Here is a rough diagram of the transmit chain:
For a more complete diagram see UsrpRfxDiagrams.
http://img213.imageshack.us/img213/8275/tx2ph9.png
There are two clocks: one for the USB bus (up to the FIFO) and one for the transmit chain itself. Channel 0 has a loop back facility. The Cascaded Integrator Comb (CIC) interpolation filter rate is controlled by the register FR_INTERP_RATE. The CORDIC transformation is currently disabled in svn HEAD.
Link to the way the AD9862 MxFE is controlled and how the filters in that component is controlled.
Describe how the host communicates with the USRP device.
Registers are separated out into three different sections - common, standard, and custom. The registers
are write only with values shadowed on the host for readback except for three readable standard registers in their own
address space from the writable registers.
| Address | Register | Brief Description | ||||
| 0 | FR_TX_SAMPLE_RATE_DIV |
Transmit sample rate divisor | ||||
| 1 | FR_RX_SAMPLE_RATE_DIV |
Receive sample rate divisor | ||||
| 2 | UNUSED |
Unused Register | ||||
| 3 | UNUSED |
Unused Register | ||||
| 4 | FR_MASTER_CTRL |
Master Reset and Enable controls | ||||
| 5 | FR_OE_0 |
IO Buffer direction settings for pins that go to daugherboards | ||||
| 6 | FR_OE_1 |
IO Buffer direction settings for pins that go to daugherboards | ||||
| 7 | FR_OE_2 |
IO Buffer direction settings for pins that go to daugherboards | ||||
| 8 | FR_OE_3 |
IO Buffer direction settings for pins that go to daugherboards | ||||
| 9 | FR_IO_0 |
IO Registers for pins that go to daugherboards | ||||
| 10 | FR_IO_1 |
IO Registers for pins that go to daugherboards | ||||
| 11 | FR_IO_2 |
IO Registers for pins that go to daugherboards | ||||
| 12 | FR_IO_3 |
IO Registers for pins that go to daugherboards | ||||
| 13 | FR_MODE |
Sets RX Mode [NORMAL,LOOPBACK,RX_COUNTING,RX_COUNTING_32BIT] | ||||
| 14 | FR_DEBUG_EN |
Enables debug settings for debugging FPGA designs | ||||
| 15 | FR_DC_OFFSET_CL_EN |
DC offset control loop enable | ||||
| 16 | FR_ADC_OFFSET_0 |
ADC/DAC DC correction offset value (2's compliment) | ||||
| 17 | FR_ADC_OFFSET_1 |
ADC/DAC DC correction offset value (2's compliment) | ||||
| 18 | FR_ADC_OFFSET_2 |
ADC/DAC DC correction offset value (2's compliment) | ||||
| 19 | FR_ADC_OFFSET_3 |
ADC/DAC DC correction offset value (2's compliment) | ||||
| 20 | FR_ATR_MASK_0 |
Automatic Transmit/Receive Enable (Slot 0) | ||||
| 21 | FR_ATR_TXVAL_0 |
Automatic Transmit/Receive TX Pin Values (Slot 0) | ||||
| 22 | FR_ATR_RXVAL_0 |
Automatic Transmit/Receive RX Pin Values (Slot 0) | ||||
| 23 | FR_ATR_MASK_1 |
Automatic Transmit/Receive Enable (Slot 1) | ||||
| 24 | FR_ATR_TXVAL_1 |
Automatic Transmit/Receive TX Pin Values (Slot 1) | ||||
| 25 | FR_ATR_RXVAL_1 |
Automatic Transmit/Receive RX Pin Values (Slot 1) | ||||
| 26 | FR_ATR_MASK_2 |
Automatic Transmit/Receive Enable (Slot 2) | ||||
| 27 | FR_ATR_TXVAL_2 |
Automatic Transmit/Receive TX Pin Values (Slot 2) | ||||
| 28 | FR_ATR_RXVAL_2 |
Automatic Transmit/Receive RX Pin Values (Slot 2) | ||||
| 29 | FR_ATR_MASK_3 |
Automatic Transmit/Receive Enable (Slot 3) | ||||
| 30 | FR_ATR_TXVAL_3 |
Automatic Transmit/Receive TX Pin Values (Slot 3) | ||||
| 31 | FR_ATR_RXVAL_3 |
Automatic Transmit/Receive RX Pin Values (Slot 3) |
Writable Address Range: 32 - 63
| Address | Register | Brief Description | ||||
| 32 | FR_INTERP_RATE |
Transmit interpolation rate [1,1024] | ||||
| 33 | FR_DECIM_RATE |
Receive decimation rate [1,256] | ||||
| 34 | FR_RX_FREQ_0 |
DDC Center Frequency (word 0) | ||||
| 35 | FR_RX_FREQ_1 |
DDC Center Frequency (word 1) | ||||
| 36 | FR_RX_FREQ_2 |
DDC Center Frequency (word 2) | ||||
| 37 | FR_RX_FREQ_3 |
DDC Center Frequency (word 3) | ||||
| 38 | FR_RX_MUX |
Configure the RX muxing stream of I/Q data | ||||
| 39 | FR_TX_MUX |
Configure the TX muxing stream of I/Q data | ||||
| 40 | FR_TX_A_REFCLK |
Configures a reference clock sent to daughterboard A (TX) | ||||
| 41 | FR_RX_A_REFCLK |
Configures a reference clock sent to daughterboard A (RX) | ||||
| 42 | FR_TX_B_REFCLK |
Configures a reference clock sent to daughterboard B (TX) | ||||
| 43 | FR_RX_B_REFCLK |
Configures a reference clock sent to daughterboard B (RX) | ||||
| 44 | FR_RX_PHASE_0 |
RX DDC Starting Phase (word 0) | ||||
| 45 | FR_RX_PHASE_1 |
RX DDC Starting Phase (word 1) | ||||
| 46 | FR_RX_PHASE_2 |
RX DDC Starting Phase (word 2) | ||||
| 47 | FR_RX_PHASE_3 |
RX DDC Starting Phase (word 3) | ||||
| 48 | FR_TX_FORMAT |
Configures TX Format | ||||
| 49 | FR_RX_FORMAT |
Configures RX Format | ||||
| 50 | AVAILABLE |
Available for future use | ||||
| 51 | AVAILABLE |
Available for future use | ||||
| 52 | AVAILABLE |
Available for future use | ||||
| 53 | AVAILABLE |
Available for future use | ||||
| 54 | AVAILABLE |
Available for future use | ||||
| 55 | AVAILABLE |
Available for future use | ||||
| 56 | AVAILABLE |
Available for future use | ||||
| 57 | AVAILABLE |
Available for future use | ||||
| 58 | AVAILABLE |
Available for future use | ||||
| 59 | AVAILABLE |
Available for future use | ||||
| 60 | AVAILABLE |
Available for future use | ||||
| 61 | AVAILABLE |
Available for future use | ||||
| 62 | AVAILABLE |
Available for future use | ||||
| 63 | AVAILABLE |
Available for future use |
Readable Address Range: 1 - 3
There are only three readable registers, and they are in a separate 'address space' from the writable registers.
They are defined at the bottom of
/>
(Search for READBACK Registers.)
| Address | Register | Brief Description | ||||
| 1 | FR_RB_IO_RX_A_IO_TX_A |
Readback A-Side I/O pins | ||||
| 2 | FR_RB_IO_RX_B_IO_TX_B |
Readback B-Side I/O pins | ||||
| 3 | FR_RB_CAPS |
Readback FPGA capabilities |
Writable Address Range: 64 - 79
These register addresses are guaranteed to never be used within the standard or common definitions and are
therefore reserved for custom USRP FPGA implementations.
How to write to the USB interface to control things such as frequency tuning or filtering. Timing diagrams or links to
daughterboard specific PLL locking times, synthesizer lock times, etc might be useful here as well as links to different daughterboard pages here on the Wiki.
See List of USRP daughterboards
Describe or link to the message block component of the FPGA allowing for tightly timed transmit and receive functionality.
This page contains block diagrams of the USRP and RFX2400
daughterboard. I generated these by aggregating information from a number
of places. I'm not sure they're 100% correct. So, use them at your own risk.
I've annotated a few corrections. -eb

Right idea, except that there is effectively a single complex multipler.
I.e., I2+jQ2 = (I1+jQ1) * exp(jwt).
The effect of the NCO and multiplier are implemented using the CORDIC algorithm.

Right idea, except that there is effectively a single complex multipler.
I.e., I2+jQ2 = (I1+jQ1) * exp(jwt).

In the diagram, G=gain and N=noise figure (dB) at 2.4 GHz

In the diagram, G=gain and N=noise figure (dB) at 2.4 GHz

If anyone's interested in updating or correcting these diagrams, the OpenOffice source file is
source:gnuradio/trunk/usrp/doc/usrp_rfx_diagrams.odp. The originals were exported as JPG, and then
imagemagick was used to convert them to a reasonable size for web viewing. (If you do update these images,
please send them and the updated source file to eb@comsec.com for posting.)
USRPs with a serial number lower than 500 don't send the clock signal to the daughterboards. At that time (March 2005) all daughterboards had their own local oscillators.
The result is that old USRPs (serial < 500) cannot use newer daughterboards, which expect the clock signal to come from the USRP (newer USRPs have no trouble using old daughterboards, which simply ignore the USRP's clock signal).

Here is a block diagram representing how the USB packets will be handled in the USRP.
http://andrew.cmu.edu/user/thottelt/tx_block.png
The first block (USB block) will be in charge of the separation of packet per channel.
The USB packets are progressively stored in the tx_usb_fifo as they arrive but the padding is removed.
Once one packet is completely stored in the tx_usb_fifo it is pushed to the next processing block, either the command block (channel == 0x1F)
or the data block (channel != 0x1F). The data block as one tx_chan_fifo_X per channel.
Fifos size:
tx_usb_fifo: 16 bits in, 32 bits out.
tx_chan_fifo_X: 32 bits in and out.
tx_cmd_fifo: 32 bits in and out.
The data bus between usb_block and data_block is 32 bits wide. I am wondering if this is not too much.
All the arrows that loop on the same state and have no action are not shown.
This process fills in the tx_usb_fifo while removing the padding from the usb_packet:
http://andrew.cmu.edu/user/thottelt/usb_block_process0.png
This process forward each packet stored into tx_usb_fifo to a channel specific fifo (tx_chan_fifo_X or tx_cmd_fifo):
http://andrew.cmu.edu/user/thottelt/usb_block_process1.png
There is one variable that is shared between the two processes: #packet_in_usb_fifo.
This process sends the samples to the Tx_chain at the time specified in the packet header.
There is one process like this per channel.
http://andrew.cmu.edu/user/thottelt/data_block_processX.png
This process executes the sub-commands stored in tx_cmd_fifo. This is the only process in command block.
http://andrew.cmu.edu/user/thottelt/cmd_block_process0.png
gnuradio/usrp/usrp.inf
* /usr/lib/libusb/libusb0.sys
* /usr/bin/cygusb0.dll$ cd gnuradio/usrp $ cp /usr/lib/libusb/libusb0.sys . $ cp /usr/bin/cygusb0.dll libusb0.dll
(2) If the driver is not installed correctly or if you need to reinstall the driver, go to the "Driver" tab of the USRP filter Properties window and click the "Update Driver" or "Uninstall" buttons. (You must have administrator privileges to do this.) You can then disconnect the USRP and reconnect it to restart the New Hardware Installation Wizard.
You can install the binary for LibUsb-Win32 from http://libusb-win32.sourceforge.net/ and then you can install USB in automatic mode.
Below is a copy of mail from Nor, sent to OpenBTS mailing list. It provides a great insight of what can be done to improve USRP RF performance. Thanks, Nor!
I'm using a single RFX900. After I removed C202 the isolation was app. 50 dB and it was possible to send to and receive from a phone anywhere in the same room. I then grounded pin 8 on U209 and that raised the isolation to 65 dB. That made it possible to take the phone to the next room. I wanted more isolation and tried shielding the TX amplifer. Took me a whole day to make and solder a box around the tx amplifers, but the improvement was only 2 - 3 dB. At this point I actually considered cutting the RFX900 in two to separate the transmitter and receiver, but I had one more idea first. I completely removed the trace from U209 pin 3 to C205 and soldered a new SMA connector to the board, placed directly above C205 with the center pin soldered to C205. This seems to have (I'm not able to measure accurately) increased the isolation to 90 dB.
Even with the improved isolation, it was still not possible to setup a call from outside the house. To avoid receiver saturation because of tx leaking into rx, I had to reduce the rx gain from 80 dB to 30 dB. To compensate for the loss of sensitivity, a 40 dB amplifer (Lucent KS21583 L9, $20 on ebay) was connected outside the USRP. I now have a good balance between up-/down-link range, and are able to setup a call when the Nokia Field Test Display indicates a signal strength of -100 dBm. With a small whip antenna on the BTS that is 1/2 mile away. With a decent antenna it would be a lot more.
I'm using a "G-way Microwave Diplexer P/N CD940/6SK-E" (I know a diplexer is supposed to be different from a duplexer, but it works fine, so I don't care). It has 6 cavities on each side and provides more isolation than I can measure. This was also $20 on ebay.
This page is dedicated to the Hackfest to take place at Virginia Tech in June, 2007. This page will try to provide everyone with the necessary information to getting here, getting set up, and getting ready to work.
The work identified for this session includes:436 Whittemore Hall
Virginia Tech
Blacksburg, VA 24060
Phone: (540) 552-7001
"h3. The Inn at Virginia Tech
901 Prices Fork Road, Blacksburg, VA http://www.ichotelsgroup.com/h/d/hi/1/en/hotel/roabb?_requestid=73285
Phone: (540) 231-8000
Roanoke Regional Airport (ROA)
1. Head south on Aviation Dr NW toward Thirlane Rd 0.2 mi (1 min) BR
2. Take the VA-101 W/Hershberger Rd ramp to I-581 0.2 mi
3. Merge onto Hershberger Rd NW/VA-101 W 0.2 mi
4. Merge onto I-581 N/US-220 N via the ramp to Lexington/Bristol 2.5 mi (3 mins)
5. Take the exit onto I-81 S toward Bristol 24.8 mi (24 mins)
6. Take exit 118C-B-A to merge onto US-460 W toward Christiansburg/Blacksburg 10.8 mi (13 mins)
7. Exit onto Prices Fork Rd/VA-412 E 0.7 mi (1 min)
8. Turn left at University City Blvd 39 ft
9. Turn left at Prices Fork Rd 3 ft
The lab is located at 436 Whittemore Hall. The building is locked at night and on weekends and the lab has a keypad lock on it as well. I will give everyone access when they get here, including the keycode to the lab which will be temporarily changed for the Hackfest.
If bringing/renting a car, you will need a parking pass to park on campus. We will have them ready for you. I will need the name of the car owner/renter as well as the license plate (both can be worked out when you get here). If you think I'm kidding about this, ask Bob, who managed to get a ticket after parking for 5 minutes on campus while we were getting his pass (no worries, we'll take care of the ticket; I just think it's funny how quickly they respond).
I have a GigE switch in the lab that is almost completely full, but I have a few stray plugs for people. However, access for the most part will be done wirelessly through VT's system.
This is kind of a pain, but hopefully we'll work it out before anyone shows up. Follow these instructions to create a temporary account for however long you're here (and a few days on either side, just in case).
Fill out the form at:
Sponsoring Organization: ICTAS BR
VT Contact: James Lane
I'll ask everyone to put down their schedule, including flight number and arrival time if flying. If there are multiple people coming into Roanoke at the same time, I can pick people up. Hopefully, we can work some carpooling to ease the arrival.
Tom Rondeau (VT, your host)
cell: 540-557-7375
Eric Blossom
Matt Ettus
Bob McGwier
Johnathan Corgan
George Nychis
Thibaud Hottelier
Wireless@VT will host its annual symposium June 6 - 8 at the Inn at Virginia Tech and Skelton Conference Center. It's costly to attend, and I can probably get a few of you in at a time if you have a real desire to attend any of the sessions. My team will have to have representatives for posters/presentations throughout the conference, but that won't affect me or any of you.
The only thing to note here is that there is an Open Source Software SDR track going on the morning of June 7 (8:10 AM - 12:15 PM). I suspect we'll all be wanting to attend this. Bob is giving a talk on OSS for satellite communications, Eric will be giving a talk on the GNU Radio, and Matt and/or Tom will be giving a briefing on the OFDM implementation in the GNU Radio.
Version 0.21 7 November 2006
What you will need:
Boot from the DVD. Don't use the CD version; it is missing fftw3f.pc and the FFTW package will not install.
Choose your language of choice and click on NEXT.
Select "YES" to accept the license and click on NEXT.
On the "System Analysis" screen select "New Installation" and click on NEXT.
On the "Time Zone" screen set up your clock and click on NEXT.
On the "Desktop" screen select "Gnome" and click on NEXT.
On the "Installation Summary" screen click on "Software" (it should be displaying "Standard Software Gnome 2").
The "Software Selection" screen appears. Click on "Details" to customize your selection.
Select "Package Groups" as the Filter; you should get a tree on the left of the screen.
Click on the "development" branch; click on the "package" menu on the toolbar, scroll down to "All in this list," in the pull down menu, then select "Install."
Under the "Development" tree, click on "KDE" sub-branch; click on the "package" menu on the toolbar, scroll down to "All in this list," in the pull down menu, then select "Do not install."
Under the "Productivity" tree, click on "Scientific" sub-branch; click on the "package" menu on the toolbar, scroll down to "All in this list," in the pull down menu, then select "Install."
Click on the "Libraries" tree; click on the "package" menu on the toolbar, scroll down to "All in this list," in the pull down menu, then select "Install."
Click on "Accept."
You will get a pop-up window with three warnings. Click on the circles next to "do not install flex-old" for the first two warnings and click on the circle next to "do not install gtkl-compat-devel" for the remaining warning.
Click on the "OK, try again" button at the bottom of the pop up window.
An Adobe license window appears; click on the "Accept" button.
A flash player license window appears, click on the "Cancel" button.
The "Installation Settings" window reappears after a long pause.
Click on "Accept" at the lower right hand corner.
A "Confirm" window appears; click "Install."
A "Package Installation" screen appears. Click on the "Details" tab to watch the progress of the install. This would be a good time to take a break; installation will
take about 1 hour to complete.
The system will reboot and the Install screen re-appears.
Enter your hostname and domain and click on Next.
Enter your root password and click on Next. Write down your root password so you don't forget it!
A "Network Configuration" screen appears. If you have DHCP set up, select that option and click on Next.
A "Test Connection" window appears. Click on Next. Assuming all is well with the connection, click on Next again after the test is complete.
An "Online Update" screen appears; select "Configure now" and click on Next.
Wait for a while for the server to be selected.
An "Online Update Configuration" window appears; click on "OK."
Click on the circle next to "Run Update," then click on Next.
An "Update Select" screen appears; click on "Accept"
The YAST package will now be updated. You can update the rest of your system later.
After "Total Progress" reaches 100%, click on Next.
After a pause, the "Update Select" screen reappears. Click on Cancel.
The "Authentication Method" screen appears. Click on the circle next to "Local."
The "New Local User" screen appears. Enter your name, username, and password.
The "Release Notes" screen appears. Click on Next.
The "Hardware Configuration" screen appears. Click on Next.
The "Installation Complete" screen appears. Click on Finish.
Congratulations! You have a shiny new Suse 10.1 box!
Log on to your account (not root).
You need to install the SDCC package. You can install from source or use the Suse RPMs.
Installing from source:
Get the source tarball from Sourceforge at
http://sourceforge.net/project/showfiles.php?group_id=599.
(it will be called "sdcc-src-2.6.0.tar.gz" unless a newer version is available now)
Put the tarball in your home directory.
Double-click on the icon for the tarball. A window will appear; click on "Extract."
Click on "Extract" in the new window that appears. This will create a directory called
"SDCC" in your home directory.
Open up a terminal. (Click on "Applications" on the menu toolbar,scroll up to
"System" in the menu that appears,scroll down to "Terminal" in the next menu that
appears, then click on "Gnome Terminal" in yet another menu that appears)
In the terminal window, type "cd SDCC" and hit Enter.
Now type "./configure" and hit Enter.
Now type "make" and hit Enter.
now type "sudo make install" and hit Enter.
When asked for the root password, enter it.
type "cd .." and hit Enter.
Installing from Suse RPMs
Get the RPMs from sourceforge:
http://sourceforge.net/project/showfiles.php?group_id=599&package_id=111949
You need two packages, sdcc-common-2.4.0-1.noarch.rpm and sdcc-2.4.0-1-SL90.i586.rpm.
Open up a terminal. (Click on "Applications" on the menu toolbar,scroll up to
"System" in the menu that appears,scroll down to "Terminal" in the next menu that
appears, then click on "Gnome Terminal" in yet another menu that appears)
Install both RPMs with the command
rpm -ivh sdcc*.rpm
Now it's time to install GnuRadio itself.
Type "svn co !http://gnuradio.org/svn/gnuradio/trunk gnuradio" and hit Enter.
The most current version of GnuRadio is now being loaded onto you machine. When
it's done, note the revision number for future reference.
Type "cd gnuradio" and hit Enter.
Type "./bootstrap" and hit Enter.
Type "./configure" and hit Enter.
You are now ready to install everything except:
gr-audio-osx
gr-audio-portaudio
gr-audio-windows
gr-comedi
gr-ezdop
ezdop
If you needed any of these you willl need to track down the missing dependencies and
install them.
type "make" and hit Enter.
type "make check" and hit Enter.
type "sudo make install" and hit Enter.
When asked for the root password, enter it.
At this point, with a little luck, you have an operational installation.
Connect your USRP (power and USB 2 cables)
There is a tiny little green LED underneath the "A" side receive daughtercard.
It should be flashing at a few times per second.
For the moment you will need to have root priviledges to access the USRP. A procedure to
remove this requirement will appear in the next version of this walkthrough.
type "su" and hit Enter. When prompted for a password, type the root password and hit Enter.
type "export PYTHONPATH=~/gnuradio/lib/python2.4/site-packages" and hit Enter.
You should put this command in your startup file so you won't have to enter it
every time you start up a shell. Instructions will appear will appear in the next version
of this walkthrough.
Type "cd gnuradio-examples/python/usrp" and hit Enter.
Type "python test_counting.py" and hit Enter.
The green LED should be blinking more slowly to indicate a successful load.
You should see messages from "gr_check_counting," with the final message saying something about "enter_LOCKED."
Type a "control-C" character to exit the test.
Type "python benchmark_usb.py" anfd hit Enter.
You should see tests of the USB link up to 32 MB/sec with "OK" displayed after each test.
If you have a daughtercard installed in the "A" connector, you can run a spectrum analyzer.
Type "python usrp_fft.py -d 64 -f 10000000" and hit Enter.
You are now looking at a GUI display of a 1 MHz segment of spectrum centered at 10 MHz.
To change the bandwidth, enter an even decimation factor (256 or lower down to 4) into the "Decim" field.
To change the center frequency, enter the frequency (in Hz) into the "Center freq" field.
You can also enter the frequency in Mhz followed by a capital "M"
At this point you are ready to start exploring the full potential of your new system!
GNU Radio is a free software development toolkit that provides the signal processing runtime and processing blocks to implement software radios using readily-available, low-cost external RF hardware and commodity processors. It is widely used in hobbyist, academic and commercial environments to support wireless communications research as well as to implement real-world radio systems.
GNU Radio applications are primarily written using the Python programming language, while the supplied, performance-critical signal processing path is implemented in C++ using processor floating point extensions where available. Thus, the developer is able to implement real-time, high-throughput radio systems in a simple-to-use, rapid-application-development environment.
While not primarily a simulation tool, GNU Radio does support development of signal processing algorithms using pre-recorded or generated data, avoiding the need for actual RF hardware.
GNU Radio is licensed under the GNU General Public License (GPL) version 3. All of the code is copyright of the Free Software Foundation.
GNU Radio is a collection of software that when combined with minimal hardware, allows the construction of radios where the actual waveforms transmitted and received are defined by software. What this means is that the digital modulation schemes used in today's high performance wireless devices are now software problems.
1 <table>
2 <tr>
3 <td valign=top width=48% class="wikipage">
1 </td>
2 <td valign=top width=48% class="wikipage">
1 No more than 3 entries
* November 5, 2007 - GNU Radio 3.1.1 Release:
1 </td>
2 </tr>
3 </table>
Installing GNU Radio and USRP on Windows is not yet routine. Please report any success or failures. Patches and enhancements are especially welcome!
Considerable effort has been put into making the GNU Radio code portable among various operating systems, but there are several reasons why it cannot be "simply" compiled and run under Windows:
The following sections show how these issues can be addressed.
GNU Radio is designed to be flexible. It has a number of modules, capabilities, and options that can be enabled or disabled to suit the needs of the user, and the user can add custom blocks or modules to the system.
To support this flexibility, it comes with a set of files and scripts to be used with GNU software build tools (sh, make, autoconf, automake, etc.). These tools use Linux-like commands and filenames that are not normally available on Windows systems.
Fortunately, we are not the first to face this problem, and several solutions exist. These are presented in order of increasing difficulty:
Cygwin (http://www.cygwin.com/) is a Linux-like environment for Windows.
It provides the Linux-like shell, file naming, and build tools we need and also makes it easy to install many of the third-party libraries required by GNU Radio. It also provides a Linux programming interface (API); this is not required by GNU Radio, but it lets us use the better-tested Linux versions of some functions.
Because the Linux API uses its own C runtime library, it is best to use Cygwin versions of Python and the third-party libraries when building GNU Radio with Cygwin.
For detailed installation instructions using Cygwin see Installing GNU Radio with Cygwin.
MinGW (http://www.mingw.org/) provides GNU compilers and Window-specific header files for compiling native Windows applications.
MSYS (http://www.mingw.org/msys.shtml) is a companion set of Linux-like commands, shell, and build tools.
MinGW does not include a Linux programming interface; programs should be smaller and faster than with Cygwin (in theory), but will require more Windows-specific code.
MSYS is intended primarily as a build environment, making it more compact than Cygwin.
Because there is no Linux API emulation, GNU Radio built with MinGW should be used with standard Windows versions of Python and the third-party libraries.
MinGW does not provide as much support as Cygwin for installing third-party libraries, but in many cases precompiled binaries are available.
For detailed installation instructions using MinGW and MSYS see Installing GNU Radio with [[MinGW]].
In principle, it should be possible to build and install GNU Radio on Windows using your choice of compiler (Microsoft, Borland, GNU, etc.) and build tools (IDE or scripting languages). There is an attempt in progress described on the WindowsNativeInstall page.
In the future, we may be able to package pre-built binary files for Windows. This would make installation easier, but might preclude users from modifying or adding signal-processing blocks or modules.
So far, we have workarounds for all reported problems:
[[TicketQuery(status!=closed&type=defect&summary~=cygwin|mingw|windows)]]
WARNING: This page is a work-in-progress.
Two developers, Andrew Rose and Geof Nieboer, have taken up the challenge to get a windows native install complete. For the moment, this is note of their independent attempts to get it going.
Geof's methodology is to use Managed C++ to add a shim to .NET managed code, and then use C# instead of Python. So Managed C++ would replace SWIG and C# Python.
[2009-06-12] Andrew abandoned his attempt on discovering that it was considerably easier to dual-boot Windows & Ubuntu and install GNURadio on Ubuntu.
| Library | Priority | Status (C++) | Status (C#) | |||||
| Omnithread | Done-GA | |||||||
| GR_Core | HP | In Progress | ||||||
| * filter | Done-G | |||||||
| * g72x | Done-A | |||||||
| * general | Done-GA | |||||||
| * gengen | Done*-G | Wrappers done | ||||||
| * io | Done-GA | |||||||
| * missing | ||||||||
| * reed-solomon | ||||||||
| * runtime | Done-GA | |||||||
| * swig | NA | NA | ||||||
| USRP | LP: I can't afford one | Done-G | ||||||
| GNU_Radio_USRP | LP: requires URSP | Done-G | ||||||
| GR_Audio_Alsa | LP: appears to be Linux specific | |||||||
| GR_Audio_Jack | LP: Ditto | |||||||
| GR_Audio_OSS | LP: Ditto | |||||||
| GR_Audio_OSX | ||||||||
| GR_Audio_PortAudio | HP | |||||||
| GR_Audio_Windows | HP | |||||||
| GR_ATSC | ||||||||
| GR_Comedi | ||||||||
| GR_GSM_FR_VOCODER | ||||||||
| GR_Pager | ||||||||
| GR_Radio_Mono | ||||||||
| GR_Radio_Astronomy | ||||||||
| GR_Trellis | ||||||||
| GR_WXGUI | ||||||||
| GR_Sounder | LP: requires USRP | |||||||
| GR_Utils | NA | |||||||
| GNU_Radio_Examples | HP: Get the "audio" examples working as proof-of-concept |
lib /machine:i386 /def:libfftw3f-3.def* libusb-win32. Only applies if using USRP. Use version 0.1.10.1 for the moment. The 0.1.12 versions include #windows.h which complicates build process.
for (unsigned int i=0; i<n; i++) {}
for (unsigned int i=0; i<n; i++) {}
FYI: known issue. can be worked around by wrapping the first for loop with {}:
{for (unsigned int i=0; i<n; i++) {}}
for (unsigned int i=0; i<n; i++) {}
* Install Visual C++ 2008 Express Edition (http://www.microsoft.com/express/vc/), which is free (beer).
* Discover that GCC allows the following (valid C99) syntax, but MSVC doesn't.
void funcname(int n)
{
int foo[n];
}
* Fix is to replace all instances with the following. If I ever get this install working, I'll submit all such fixes for inclusion in the main codebase.
void funcname(int n)
{
int *foo = (int *)malloc(n * sizeof(int));
...
free(foo);
}
FYI, it's probably easier to use "alloca" if it's supported by MS. it does stack-based dynamic allocation.
void funcname(int n)
{
int *foo = (int *)alloca(n * sizeof(int));
...
}
The following topics may be useful to users of GNU Radio on Windows. Note that some of the Cygwin topics may also apply to MinGW/MSYS and vice versa.
Instructions for installing GNU Radio on Windows are given elsewhere. This page describes potential difficulties.
UNIX and Linux use the newline character (sometimes written as LF; sometimes displayed as ^J; '\n' in C) to separate lines in a text file, while Windows uses a two-character sequence of carriage-return followed by newline (CRLF or ^M^J; "\r\n" in C). Cygwin and MSYS tend to follow the UNIX/Linux convention, so if your text files use the Windows convention you may see extra ^M characters in unexpected places (like in error messages!). One way to tell if a file has Windows or UNIX line endings is to open it with Windows Notepad: If the file looks normal it uses CRLF, but if the lines are run together with little boxes between them it uses LF only.
Subversion (the svn program) is designed to convert files (if requested by the developer) to use the "native" line separators of the target machine when checking out code. That means that a Windows version of svn will use CRLF separators and a UNIX/Linux version of svn will use LF. Thus if you go to http://subversion.tigris.org and download and install Windows binary version of svn (or use TortoiseSVN), you will get CRLF line separators. If you install the Cygwin subversion package (using Cygwin setup), you will get LF separators.
svn repository. If any new problems are introduced, they might look like:config.status: creating \^M config.status: error: cannot find input file: \^M.in
^M characters in some of the .m4 files in the config directory are being treated as ordinary characters instead of as line separators. This can be fixed with:$ cd gnuradio $ dos2unix config/*.m4 configure.ac
dos2unix program can be found in the Cygwin cygutils package or in the mingw-utils package.)
Sometimes when you download a package (such as FFTW) labelled "thing.tar.gz" it will be put on your system with the filename "thing.tar.tar". This does not cause any problems except that you must change any commands that refer to the downloaded file to use the actual filename on your system.
/usr/bin/install -c -d /usr/local/bin /usr/bin/install: cannot change permissions of @/usr/local/bin': Permission denied
/usr/local/bin and /usr/local/lib directories. To do this, first find your username with the whoami command. Then find the current owner of the directories in question with
ls -ld /usr/local/{lib,bin}
chown username /usr/local/{lib,bin}
/usr/local/bin and /usr/local/lib.
Please note for Windows Vista, make sure the User Account Control is turned OFF. That blocks the permission to the folders, even though you have the ownership.
With libtool 2.2 we no longer need to patch Makefiles before building on Cygwin or MinGW. When building from an older tarball (3.1.2 or earlier) you will get a bunch of warnings running ./bootstrap, but it should work; building from the svn trunk should give only a few warnings.
But there is a problem with libtool 2.2: When running make check it tends to find installed libraries instead of the ones you want to test. Thus you either need to make uninstall any old version you may have or make install the new version before running make check.
/mingw it with:$ tar -zxf libtool-2.2.4.tar.gz $ cd libtool-2.2.4 $ ./configure --prefix=/mingw $ make $ make install
$ cd /usr/src $ tar -jxf boost_1_40_0.tar.bz2 $ cd boost_1_40_0 $ ./bootstrap.sh --with-libraries=thread,date_time,program_options $ ./bjam install
/usr/local/include/boost, the import libraries in /usr/local/lib, and the .dll files in /usr/local/bin. The libraries and DLLs have funny names, but GNU Radio will find them.
Note: Boost 1.41.0 fails with some gcc 3.4.x compilers with errors about "looser throw specifier" in exception_ptr_base.hpp; use version 1.40.0 instead, or try 1.42.0 when it is available.
$ ./bootstrap.sh --with-toolset=mingw $ ./bootstrap.sh --with-libraries=thread,date_time,program_options --with-bjam=tools/jam/src/bin.ntx86/bjam $ ./bjam --prefix=/usr/local link=shared install $ mv /usr/local/lib/*boost*.dll /usr/local/bin
./boostrap.sh creates the bjam program for MinGW, but then can't find it. On the second ./bootstrap.sh we tell it where the find bjam so it can complete the build. The extra arguments to ./bjam are needed to get shared libraries and include files in the proper places.
Installing the boost libraries is one of the most time-consuming steps in installing GNU Radio. Time for a nice, long walk?
The boost thread library is used by the svn trunk version of GNU Radio to provide thread-per-block (TPB) scheduling. For this to work on MinGW, you must specify the environment variable$ export CXX="g++ -mthreads"
./configure. You can go back to the original single-threaded scheduler (on either Cygwin of MinGW) by setting the environment variable$ export GR_SCHEDULER=STS
.stabn and .stabs¶gnuradio_swig_python.cc you may get a lot(!) of warnings like:/cygdrive/c/DOCUME~1/Don/LOCALS~1/Temp/ccr02wlm.s:2443775: Warning: .stabn: description field '20a34' too big, try a different debug format /cygdrive/c/DOCUME~1/Don/LOCALS~1/Temp/ccr02wlm.s:2443818: Warning: .stabs: description field '1ebc9' too big, try a different debug format
xmlto on Cygwin ===¶Attempting to generate HTML documentation with xmlto on Cygwin may produce errors like
xmlto: input does not validate (status 1) http://www.oasis-open.org/docbook/xml/4.2/:1: parser error : Content error in the external subset <!DOCTYPE html ^
xmlto or by removing or disabling it if it is already installed.
make check to fail while looking for usable circular buffer strategySome Cygwin setup mirror sites may contain out-of-date versions of some Cygwin packages. If demo.py did nothing when you installed wxPython or if dial_tone.py does nothing (exits immediately or produces a Windows error pop-up), you may have obsolete packages. Check to see that the mirror you are using in Cygwin setup is on the current list. In any case, you may want to try a different mirror to see if it has more up-to-date packages. You may need to make uninstall and delete your GNU Radio directory and start over with a new tarball or svn checkout.
libgnuradio-core.la-3.0; use 2.17.50-20060824 insteadfoo and foo.exe as the same file, even when libtool wants them to be different; the result is that make check in GNU Radio hangs when running test_*; to fix, install MSYS-1.0.11-20060807.tar.bz2; 1.0.10 doesn't have this problemfor loop (e.g., "for i in ;") to be a syntax error; fix by installing bash-3.1-MSYS-1.0.11-snapshot.tar.bz2cd or exec); use bash 3.1 insteadlibtool script that can't find necessary library files (e.g., -lwinmm) causing static archives (useless for GNU Radio) to be built instead of DLLs; fix by installing automake-1.9.5-mingwPORT.tar.bz2; this is only needed if building from svn; (msys-automake-1.8.2.tar.bz2 may work, but hasn't been tested)Some of the MinGW/MSYS packages you want may be missing from http://www.mingw.org/download.shtml, but they are all on http://sourceforge.net/project/showfiles.php?group_id=2435 (note that you may need to click on the "View older releases" link to find them, even when looking in the "Current" or "Snapshot" sections).
Some MinGW packages are available as mingwPORT packages. These are scripts that download, patch (if necessary), and install components. To use these you must first download wget-1.9.1-mingwPORT.tar.bz2, unpack it, find wget.exe and copy it to /mingw/bin or /usr/local/bin. Then you can install a mingwPORT package by downloading the file to /usr/src, unpacking it, going to the directory with the mingwPORT.sh file and running ./mingwPORT.sh and answering the questions (default answers work if you downloaded to /usr/src).
ok_to_block parameter so programs like multi_tone.py (in gnuradio-examples/python/audio) fail with the message:
File "/usr/local/lib/python2.4/site-packages/gnuradio/audio_windows.py", line 201, in sink
return _audio_windows.sink(*args)
NotImplementedError: No matching function for overloaded 'sink'
ok_to_block parameter when creating an audio sink.
OSS Audio. OSS (Open Sound System) audio (gr-audio-oss or audio_oss in Python) is designed for UNIX systems but is available on Windows under Cygwin. The Cygwin implementation can capture and play sounds (i.e., audio source and sink both work) but not at the same time. OSS audio is not available under MinGW.
!PortAudio. PortAudio (gr-audio-portaudio or audio_portaudio) is a portable audio library that lets programmers access a variety of audio devices and libraries using a single programming interface. On Windows, it can be used to do audio capture and play using the traditional Windows interface, DirectX, kernel streaming, ASIO, or WASAPI (new in Windows Vista) interfaces. It can capture and play sounds (i.e., use the source and the sink) at the same time.
To use PortAudio, you must download and build the v19-devel version of the
PortAudio library. This is easy on Cygwin and MSYS (see PortAudioInstall).
audio.py~/.gnuradio/config.conf--disable-gr-audio-xxx on ./configure. For example, if you have PortAudio and don't wish to use Windows audio or OSS audio, you can say:$ ./configure ... --disable-gr-audio-oss --disable-gr-audio-windows ...
audio.py. When you tell Pythonfrom gnuradio import audio
audio.py returns the first module that loads successfully from the following list:
* audio_alsa
* audio_oss
* audio_osx
* audio_jack
* audio_portaudioaudio_oss is the first choice and audio_portaudio is the second choice. Note that audio_windows is not on the list and will not be chosen.
Specify a device in ~/.gnuradio/config.conf. The file .gnuradio/config.conf in your home directory can be used to specify defaults for GNU Radio. For example, to tellfrom gnuradio import audio
audio_windows, include the following lines[audio] audio_module: audio_windows
config.conf.
Specify a device in your Python program. If a particular Python program needs a particular audio device, you can request that device on the import statement:from gnuradio import audio_portaudio as audio
as audio, you can reference the imported module as audio (e.g., audio.sink); if you later want to use a different audio module, you only need to change the import statement.
usrp: failed to find usrpr0 [Python traceback appears here] RuntimeError: can't open usrp1
[first part of Python traceback]
File "/usr/local/lib/python2.4/site-packages/gnuradio/usrp.py", line 245, in +init+
_ensure_rev2(which)
File "/usr/local/lib/python2.4/site-packages/gnuradio/usrp.py", line 82, in _ensure_rev2
v = _look_for_usrp(which)
File "/usr/local/lib/python2.4/site-packages/gnuradio/usrp.py", line 76, in _look_for_usrp
raise RuntimeError, "Unable to find USRP #%d" % (which,)
RuntimeError: Unable to find USRP #0
can't open usrp1 error; after that it should work.
The Wireless@VT Symposium was held in the Skelton Conference Center on Virginia Tech Campus in Blacksburg, VA June 6 - 8.
Thursday morning included an Open Source Software SDR Track that included the attached presentation about the GNU Radio OFDM implementation by Matt Ettus, Tom Rondeau, and Bob McGwier, presented by Tom Rondeau.
This procedure produces a version of wxPython that works with the Cygwin build of Python 2.5 (using the Cygwin C runtime library) and uses native Windows graphics (i.e., direct GDI calls, not X Window calls). This combination is intended to work with a Cygwin version of GNU Radio (one that also uses the Cygwin C runtime library).
These instructions are current as of September 2009 and assume you are using wxPython 2.8.10.1 and current versions of all Cygwin tools and libraries. They will probably work with later releases as well, but this remains to be seen.
Feel free to modify this recipe to suit your preferences:
(1) Download the wxWidgets and wxPython source code from the wxPython-src link at http://www.wxpython.org/download.php#sources to /usr/src.
(2) Unpack the source distribution:cd /usr/src tar -jxf wxPython-src-2.8.10.1.tar.bz2
$WXDIR in what follows. To make the commands work as written, run the command export WXDIR=/usr/src/wxPython-src-2.8.10.1(3) Create a build directory:
cd $WXDIR mkdir build-local
build-local here.
(4) Configure wxWidgets:cd $WXDIR/build-local ../configure --with-msw
(4a) Apply patches:
These instructions apply to release 2.8.10.1. They may not be needed in later versions.
Download attachment:wxPython-2.8.10.1.patch to $WXDIR. Apply the patches withcd $WXDIR patch -p0 -b -i wxPython-2.8.10.1.patchYou will also need to find the file
build-local/lib/wx/include/msw-ansi-release-2.8/wx/setup.h and after the line:#define wxUSE_DATEPICKCTRL 1
#define wxUSE_DATEPICKCTRL_GENERIC 1(5) Compile and link wxWidgets:
cd $WXDIR/build-local make make -C contrib/src/stc
make -C contrib/src/gizmos to compile and link the gizmos package. The gizmos package has some fun tools for developing Python programs but is not required for GNU Radio. make about conflicts between winsock.h and select.h. You can work around this error by temporarily renaming select.h:cd /usr/include/sys mv select.h select.h-x
make. You will need to undo the renamingcd /usr/include/sys mv select.h-x select.h
cd $WXDIR/build-local make install make -C contrib/src/stc install
make -C contrib/src/gizmos install.
Depending on how you installed Cygwin, you might get an error like/usr/bin/install -c -d /usr/local/lib /usr/bin/install: cannot change permissions of @/usr/local/lib': Permission denied
mv /usr/local/lib/cygwx*.dll /usr/local/bin
cd $WXDIR/build-local/samples/minimal make ./minimal.exe
cd $WXDIR/wxPython python setup.py build_ext --inplace WXPORT=msw COMPILER=cygwin BUILD_GLCANVAS=0 BUILD_GIZMOS=0 UNICODE=0
BUILD_GIZMOS=0 flag.
cd $WXDIR/wxPython python setup.py install WXPORT=msw COMPILER=cygwin BUILD_GLCANVAS=0 BUILD_GIZMOS=0 UNICODE=0
BUILD_GIZMOS=0 flag.
cd $WXDIR/wxPython/demo python demo.py
If demo.py doesn't work your version of Cygwin may be out of date (see hints, tips, known problems, and solutions for Windows).
statbmp.patch is not needed with wxPython 2.8.0.1 or laterconfig.patch and treelistctrl.cpp.patch are not needed with wxPython 2.8.7.1