Merge branch 'development' into ir

Change infrared wait time flag to -W to fix conflict with the
new development-branch -w flag for tuner bandwidth

Conflicts:
	src/rtl_tcp.c
master
rxseger 2016-07-03 23:42:53 +00:00
commit a577352932
23 changed files with 1198 additions and 455 deletions

12
.gitignore vendored
View File

@ -39,3 +39,15 @@ CMakeCache.txt
*/CMakeFiles
CMakeFiles
*.cmake
build
**/*.o
**/*.so*
**/*.a
src/rtl_adsb
src/rtl_eeprom
src/rtl_fm
src/rtl_power
src/rtl_test
debianize/*.deb

View File

@ -1,8 +0,0 @@
dependencies:
pre:
- sudo apt-get update; sudo apt-get install libusb-1.0-0-dev;
override:
- cd ~/; git clone https://github.com/librtlsdr/librtlsdr.git; cd librtlsdr; mkdir build; cd build; cmake ../; make; sudo make install; sudo ldconfig;
test:
override:
- echo "----- done -----";

1
debian/.gitignore vendored 100644
View File

@ -0,0 +1 @@
*.deb

119
debian/debianize vendored 100755
View File

@ -0,0 +1,119 @@
#!/bin/bash
REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/../"
G_REV=`git rev-parse --short=8 HEAD`
DATE=`date +"%Y%m%d%H%M%S"`
#VERSION="0.5.3-git+${DATE}.${G_REV}~$1"
VERSION=`git describe | cut -dv -f2`
#
# librtlsdr0
#
rm -fr /tmp/librtlsdr0/
mkdir -p /tmp/librtlsdr0/
mkdir -p /tmp/librtlsdr0/usr/lib/x86_64-linux-gnu/
mkdir -p /tmp/librtlsdr0/DEBIAN
cat <<- EOF > /tmp/librtlsdr0/DEBIAN/control
Package: librtlsdr0
Source: rtl-sdr
Version: ${VERSION}
Architecture: amd64
Maintainer: Lucas Teske <lucas@teske.net.br>
Pre-Depends: multiarch-support
Depends: libc6 (>= 2.14), libusb-1.0-0 (>= 2:1.0.9)
Section: libs
Priority: extra
Multi-Arch: same
Homepage: http://sdr.osmocom.org/trac/wiki/rtl-sdr
Description: Software defined radio receiver for Realtek RTL2832U (library)
rtl-sdr is a software defined radio (SDR) receiver software for certain
low-cost DVB-T/DAB(+) USB dongles based on the Realtek RTL2832U chip.
.
This package contains the shared library.
EOF
DEB_PKG="librtlsdr0_${VERSION}_amd64.deb"
cp -rf ${REPO_DIR}/build/src/lib*so* /tmp/librtlsdr0/usr/lib/x86_64-linux-gnu/
dpkg-deb -b /tmp/librtlsdr0/ ./${DEB_PKG}
echo ${DEB_PKG}
#
# rtl-sdr
#
rm -fr /tmp/rtl-sdr/
mkdir -p /tmp/rtl-sdr/
mkdir -p /tmp/rtl-sdr/usr/bin/
mkdir -p /tmp/rtl-sdr/DEBIAN
cat <<- EOF > /tmp/rtl-sdr/DEBIAN/control
Package: rtl-sdr
Version: ${VERSION}
Architecture: amd64
Maintainer: Lucas Teske <lucas@teske.net.br>
Depends: librtlsdr0 (= ${VERSION}), libc6 (>= 2.15)
Section: libs
Priority: extra
Homepage: http://sdr.osmocom.org/trac/wiki/rtl-sdr
Description: Software defined radio receiver for Realtek RTL2832U (tools)
rtl-sdr is a software defined radio (SDR) receiver software for certain
low-cost DVB-T/DAB(+) USB dongles based on the Realtek RTL2832U chip.
.
This package contains a set of command line utilities:
* rtl_adsb: a simple ADS-B decoder for RTL2832 based DVB-T receivers
* rtl_eeprom: an EEPROM programming tool for RTL2832 based DVB-T receivers
* rtl_fm: a narrow band FM demodulator for RTL2832 based DVB-T receivers
* rtl_sdr: an I/Q recorder for RTL2832 based DVB-T receivers
* rtl_tcp: an I/Q spectrum server for RTL2832 based DVB-T receivers
* rtl_test: a benchmark tool for RTL2832 based DVB-T receivers
EOF
DEB_PKG="rtl-sdr_${VERSION}_amd64.deb"
cp -rf ${REPO_DIR}/build/src/rtl_* /tmp/rtl-sdr/usr/bin/
dpkg-deb -b /tmp/rtl-sdr/ ./${DEB_PKG}
echo ${DEB_PKG}
#
# librtlsdr-dev
#
rm -fr /tmp/librtlsdr-dev/
mkdir -p /tmp/librtlsdr-dev/
mkdir -p /tmp/librtlsdr-dev/usr/include
mkdir -p /tmp/librtlsdr-dev/usr/lib/x86_64-linux-gnu/pkgconfig
mkdir -p /tmp/librtlsdr-dev/DEBIAN
cat <<- EOF > /tmp/librtlsdr-dev/DEBIAN/control
Package: librtlsdr-dev
Source: rtl-sdr
Version: ${VERSION}
Architecture: amd64
Maintainer: Lucas Teske <lucas@teske.net.br>
Pre-Depends: multiarch-support
Depends: librtlsdr0 (= ${VERSION})
Section: libdevel
Priority: extra
Homepage: http://sdr.osmocom.org/trac/wiki/rtl-sdr
Description: Software defined radio receiver for Realtek RTL2832U (development files)
rtl-sdr is a software defined radio (SDR) receiver software for certain
low-cost DVB-T/DAB(+) USB dongles based on the Realtek RTL2832U chip.
.
This package contains development files.
EOF
DEB_PKG="librtlsdr-dev_${VERSION}_amd64.deb"
cp -rf ${REPO_DIR}/include/*.h /tmp/librtlsdr-dev/usr/include
dpkg-deb -b /tmp/librtlsdr-dev/ ./${DEB_PKG}
echo ${DEB_PKG}

26
include/rtl-sdr.h 100644 → 100755
View File

@ -26,6 +26,7 @@ extern "C" {
#include <stdint.h>
#include <rtl-sdr_export.h>
#include <rtl_tcp.h>
typedef struct rtlsdr_dev rtlsdr_dev_t;
@ -142,6 +143,13 @@ RTLSDR_API int rtlsdr_write_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
RTLSDR_API int rtlsdr_read_eeprom(rtlsdr_dev_t *dev, uint8_t *data,
uint8_t offset, uint16_t len);
/*!
* Set the frequency the device is tuned to.
*
* \param dev the device handle given by rtlsdr_open()
* \param frequency in Hz
* \return 0 on error, frequency in Hz otherwise
*/
RTLSDR_API int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq);
/*!
@ -220,9 +228,14 @@ RTLSDR_API int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain);
*
* \param dev the device handle given by rtlsdr_open()
* \param bw bandwidth in Hz. Zero means automatic BW selection.
* \param applied_bw is applied bandwidth in Hz, or 0 if unknown
* \param apply_bw: 1 to really apply configure the tuner chip; 0 for just returning applied_bw
* \return 0 on success
*/
RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw);
RTLSDR_API int rtlsdr_set_and_get_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw, uint32_t *applied_bw, int apply_bw );
RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw );
/*!
* Get actual gain the device is configured to.
@ -232,6 +245,17 @@ RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw);
*/
RTLSDR_API int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev);
/*!
* Set LNA / Mixer / VGA Device Gain for R820T device is configured to.
*
* \param dev the device handle given by rtlsdr_open()
* \param lna_gain in tenths of a dB, -30 means -3.0 dB.
* \param mixer_gain in tenths of a dB, -30 means -3.0 dB.
* \param vga_gain in tenths of a dB, -30 means -3.0 dB.
* \return 0 on success
*/
RTLSDR_API int rtlsdr_set_tuner_gain_ext(rtlsdr_dev_t *dev, int lna_gain, int mixer_gain, int vga_gain);
/*!
* Set the intermediate frequency gain for the device.
*

51
include/rtl_tcp.h 100644
View File

@ -0,0 +1,51 @@
/*
* rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver
* Copyright (C) 2012-2013 by Steve Markgraf <steve@steve-m.de>
* Copyright (C) 2012 by Dimitri Stolnikov <horiz0n@gmx.net>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __RTL_TCP_H
#define __RTL_TCP_H
#ifdef __cplusplus
extern "C" {
#endif
/*!
* This enum defines the possible commands in rtl_tcp
*/
enum RTL_TCP_COMMANDS {
SET_FREQUENCY = 0x01,
SET_SAMPLE_RATE = 0x02,
SET_GAIN_MODE = 0x03,
SET_GAIN = 0x04,
SET_FREQUENCY_CORRECTION = 0x05,
SET_IF_STAGE = 0x06,
SET_TEST_MODE = 0x07,
SET_AGC_MODE = 0x08,
SET_DIRECT_SAMPLING = 0x09,
SET_OFFSET_TUNING = 0x0A,
SET_RTL_CRYSTAL = 0x0B,
SET_TUNER_CRYSTAL = 0x0C,
SET_TUNER_GAIN_BY_INDEX = 0x0D,
SET_TUNER_BANDWIDTH = 0x0E
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,8 +1,8 @@
#ifndef __TUNER_FC2580_H
#define __TUNER_FC2580_H
#define BORDER_FREQ 2600000 //2.6GHz : The border frequency which determines whether Low VCO or High VCO is used
#define USE_EXT_CLK 0 //0 : Use internal XTAL Oscillator / 1 : Use External Clock input
#define BORDER_FREQ 2600000 /* 2.6GHz : The border frequency which determines whether Low VCO or High VCO is used */
#define USE_EXT_CLK 0 /* 0 : Use internal XTAL Oscillator / 1 : Use External Clock input */
#define OFS_RSSI 57
#define FC2580_I2C_ADDR 0xac

8
include/tuner_r82xx.h 100644 → 100755
View File

@ -88,9 +88,7 @@ struct r82xx_priv {
/* Store current mode */
uint32_t delsys;
enum r82xx_tuner_type type;
uint32_t bw; /* in MHz */
void *rtl_dev;
};
@ -114,7 +112,9 @@ enum r82xx_delivery_system {
int r82xx_standby(struct r82xx_priv *priv);
int r82xx_init(struct r82xx_priv *priv);
int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq);
int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain);
int r82xx_set_bandwidth(struct r82xx_priv *priv, int bandwidth, uint32_t rate);
//int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain);
int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, int extended_mode, int lna_gain, int mixer_gain, int vga_gain);
int r82xx_set_bandwidth(struct r82xx_priv *priv, int bandwidth, uint32_t rate, uint32_t * applied_bw, int apply);
#endif

24
src/convenience/convenience.c 100644 → 100755
View File

@ -160,6 +160,25 @@ int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate)
return r;
}
int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth)
{
int r;
uint32_t applied_bw = 0;
/* r = rtlsdr_set_tuner_bandwidth(dev, bandwidth); */
r = rtlsdr_set_and_get_tuner_bandwidth(dev, bandwidth, &applied_bw, 1 /* =apply_bw */);
if (r < 0) {
fprintf(stderr, "WARNING: Failed to set bandwidth.\n");
} else if (bandwidth > 0) {
if (applied_bw)
fprintf(stderr, "Bandwidth parameter %u Hz resulted in %u Hz.\n", bandwidth, applied_bw);
else
fprintf(stderr, "Set bandwidth parameter %u Hz.\n", bandwidth);
} else {
fprintf(stderr, "Bandwidth set to automatic resulted in %u Hz.\n", applied_bw);
}
return r;
}
int verbose_direct_sampling(rtlsdr_dev_t *dev, int on)
{
int r;
@ -182,6 +201,11 @@ int verbose_offset_tuning(rtlsdr_dev_t *dev)
int r;
r = rtlsdr_set_offset_tuning(dev, 1);
if (r != 0) {
if ( r == -2 )
fprintf(stderr, "WARNING: Failed to set offset tuning: tuner doesn't support offset tuning!\n");
else if ( r == -3 )
fprintf(stderr, "WARNING: Failed to set offset tuning: direct sampling not combinable with offset tuning!\n");
else
fprintf(stderr, "WARNING: Failed to set offset tuning.\n");
} else {
fprintf(stderr, "Offset tuning mode enabled.\n");

View File

@ -14,6 +14,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CONVENIENCE_H
#define __CONVENIENCE_H
/* a collection of user friendly tools */
@ -74,6 +77,17 @@ int verbose_set_frequency(rtlsdr_dev_t *dev, uint32_t frequency);
int verbose_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate);
/*!
* Set device bandwidth and report status on stderr
*
* \param dev the device handle given by rtlsdr_open()
* \param frequency in Hz
* \return 0 on success
*/
int verbose_set_bandwidth(rtlsdr_dev_t *dev, uint32_t bandwidth);
/*!
* Enable or disable the direct sampling mode and report status on stderr
*
@ -140,3 +154,4 @@ int verbose_reset_buffer(rtlsdr_dev_t *dev);
int verbose_device_search(char *s);
#endif /*__CONVENIENCE_H*/

View File

@ -60,7 +60,7 @@ typedef struct rtlsdr_tuner_iface {
int (*init)(void *);
int (*exit)(void *);
int (*set_freq)(void *, uint32_t freq /* Hz */);
int (*set_bw)(void *, int bw /* Hz */);
int (*set_bw)(void *, int bw /* Hz */, uint32_t *applied_bw /* configured bw in Hz */, int apply /* 1 == configure it!, 0 == deliver applied_bw */);
int (*set_gain)(void *, int gain /* tenth dB */);
int (*set_if_gain)(void *, int stage, int gain /* tenth dB */);
int (*set_gain_mode)(void *, int manual);
@ -147,9 +147,11 @@ int e4000_set_freq(void *dev, uint32_t freq) {
return e4k_tune_freq(&devt->e4k_s, freq);
}
int e4000_set_bw(void *dev, int bw) {
int e4000_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) {
int r = 0;
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
if(!apply)
return 0;
r |= e4k_if_filter_bw_set(&devt->e4k_s, E4K_IF_FILTER_MIX, bw);
r |= e4k_if_filter_bw_set(&devt->e4k_s, E4K_IF_FILTER_RC, bw);
@ -191,7 +193,7 @@ int fc0012_set_freq(void *dev, uint32_t freq) {
rtlsdr_set_gpio_bit(dev, 6, (freq > 300000000) ? 1 : 0);
return fc0012_set_params(dev, freq, 6000000);
}
int fc0012_set_bw(void *dev, int bw) { return 0; }
int fc0012_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { return 0; }
int _fc0012_set_gain(void *dev, int gain) { return fc0012_set_gain(dev, gain); }
int fc0012_set_gain_mode(void *dev, int manual) { return 0; }
@ -200,7 +202,7 @@ int fc0013_exit(void *dev) { return 0; }
int fc0013_set_freq(void *dev, uint32_t freq) {
return fc0013_set_params(dev, freq, 6000000);
}
int fc0013_set_bw(void *dev, int bw) { return 0; }
int fc0013_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) { return 0; }
int _fc0013_set_gain(void *dev, int gain) { return fc0013_set_lna_gain(dev, gain); }
int fc2580_init(void *dev) { return fc2580_Initialize(dev); }
@ -208,7 +210,11 @@ int fc2580_exit(void *dev) { return 0; }
int _fc2580_set_freq(void *dev, uint32_t freq) {
return fc2580_SetRfFreqHz(dev, freq);
}
int fc2580_set_bw(void *dev, int bw) { return fc2580_SetBandwidthMode(dev, 1); }
int fc2580_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) {
if(!apply)
return 0;
return fc2580_SetBandwidthMode(dev, 1);
}
int fc2580_set_gain(void *dev, int gain) { return 0; }
int fc2580_set_gain_mode(void *dev, int manual) { return 0; }
@ -242,13 +248,16 @@ int r820t_set_freq(void *dev, uint32_t freq) {
return r82xx_set_freq(&devt->r82xx_p, freq);
}
int r820t_set_bw(void *dev, int bw) {
int r820t_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) {
int r;
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
r = r82xx_set_bandwidth(&devt->r82xx_p, bw, devt->rate);
r = r82xx_set_bandwidth(&devt->r82xx_p, bw, devt->rate, applied_bw, apply);
if(!apply)
return 0;
if(r < 0)
return r;
r = rtlsdr_set_if_freq(devt, r);
if (r)
return r;
@ -257,11 +266,17 @@ int r820t_set_bw(void *dev, int bw) {
int r820t_set_gain(void *dev, int gain) {
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
return r82xx_set_gain(&devt->r82xx_p, 1, gain);
return r82xx_set_gain(&devt->r82xx_p, 1, gain, 0, 0, 0, 0);
}
int r820t_set_gain_ext(void *dev, int lna_gain, int mixer_gain, int vga_gain) {
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
return r82xx_set_gain(&devt->r82xx_p, 0, 0, 1, lna_gain, mixer_gain, vga_gain);
}
int r820t_set_gain_mode(void *dev, int manual) {
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
return r82xx_set_gain(&devt->r82xx_p, manual, 0);
return r82xx_set_gain(&devt->r82xx_p, manual, 0, 0, 0, 0, 0);
}
/* definition order must match enum rtlsdr_tuner */
@ -1059,16 +1074,26 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains)
}
}
int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw)
int rtlsdr_set_and_get_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw, uint32_t *applied_bw, int apply_bw )
{
int r = 0;
*applied_bw = 0; /* unknown */
if (!dev || !dev->tuner)
return -1;
if(!apply_bw)
{
if (dev->tuner->set_bw) {
r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw);
}
return r;
}
if (dev->tuner->set_bw) {
rtlsdr_set_i2c_repeater(dev, 1);
r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate);
r = dev->tuner->set_bw(dev, bw > 0 ? bw : dev->rate, applied_bw, apply_bw);
rtlsdr_set_i2c_repeater(dev, 0);
if (r)
return r;
@ -1077,6 +1102,14 @@ int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw)
return r;
}
int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw )
{
uint32_t applied_bw = 0;
return rtlsdr_set_and_get_tuner_bandwidth(dev, bw, &applied_bw, 1 /* =apply_bw */ );
}
int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain)
{
int r = 0;
@ -1098,6 +1131,27 @@ int rtlsdr_set_tuner_gain(rtlsdr_dev_t *dev, int gain)
return r;
}
int rtlsdr_set_tuner_gain_ext(rtlsdr_dev_t *dev, int lna_gain, int mixer_gain, int vga_gain)
{
int r = 0;
if (!dev || !dev->tuner)
return -1;
if (dev->tuner->set_gain) {
rtlsdr_set_i2c_repeater(dev, 1);
r = r820t_set_gain_ext((void *)dev, lna_gain, mixer_gain, vga_gain);
rtlsdr_set_i2c_repeater(dev, 0);
}
if (!r)
dev->gain = lna_gain + mixer_gain + vga_gain;
else
dev->gain = 0;
return r;
}
int rtlsdr_get_tuner_gain(rtlsdr_dev_t *dev)
{
if (!dev)
@ -1167,8 +1221,9 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate)
dev->rate = (uint32_t)real_rate;
if (dev->tuner && dev->tuner->set_bw) {
uint32_t applied_bw = 0;
rtlsdr_set_i2c_repeater(dev, 1);
dev->tuner->set_bw(dev, dev->bw > 0 ? dev->bw : dev->rate);
dev->tuner->set_bw(dev, dev->bw > 0 ? dev->bw : dev->rate, &applied_bw, 1);
rtlsdr_set_i2c_repeater(dev, 0);
}
@ -1305,6 +1360,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on)
r |= rtlsdr_set_if_freq(dev, dev->offs_freq);
if (dev->tuner && dev->tuner->set_bw) {
uint32_t applied_bw = 0;
rtlsdr_set_i2c_repeater(dev, 1);
if (on) {
bw = 2 * dev->offs_freq;
@ -1313,7 +1369,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on)
} else {
bw = dev->rate;
}
dev->tuner->set_bw(dev, bw);
dev->tuner->set_bw(dev, bw, &applied_bw, 1);
rtlsdr_set_i2c_repeater(dev, 0);
}
@ -1348,14 +1404,16 @@ static rtlsdr_dongle_t *find_known_device(uint16_t vid, uint16_t pid)
uint32_t rtlsdr_get_device_count(void)
{
int i;
int i,r;
libusb_context *ctx;
libusb_device **list;
uint32_t device_count = 0;
struct libusb_device_descriptor dd;
ssize_t cnt;
libusb_init(&ctx);
r = libusb_init(&ctx);
if(r < 0)
return 0;
cnt = libusb_get_device_list(ctx, &list);
@ -1375,7 +1433,7 @@ uint32_t rtlsdr_get_device_count(void)
const char *rtlsdr_get_device_name(uint32_t index)
{
int i;
int i,r;
libusb_context *ctx;
libusb_device **list;
struct libusb_device_descriptor dd;
@ -1383,7 +1441,9 @@ const char *rtlsdr_get_device_name(uint32_t index)
uint32_t device_count = 0;
ssize_t cnt;
libusb_init(&ctx);
r = libusb_init(&ctx);
if(r < 0)
return "";
cnt = libusb_get_device_list(ctx, &list);
@ -1423,7 +1483,9 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact,
uint32_t device_count = 0;
ssize_t cnt;
libusb_init(&ctx);
r = libusb_init(&ctx);
if(r < 0)
return r;
cnt = libusb_get_device_list(ctx, &list);
@ -1497,7 +1559,11 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
memset(dev, 0, sizeof(rtlsdr_dev_t));
memcpy(dev->fir, fir_default, sizeof(fir_default));
libusb_init(&dev->ctx);
r = libusb_init(&dev->ctx);
if(r < 0){
free(dev);
return -1;
}
dev->dev_lost = 1;

View File

@ -45,8 +45,10 @@
#ifdef _WIN32
#define sleep Sleep
#if defined(_MSC_VER) && (_MSC_VER < 1800)
#define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5))
#endif
#endif
#define ADSB_RATE 2000000
#define ADSB_FREQ 1090000000

View File

@ -4,6 +4,7 @@
* Copyright (C) 2012 by Hoernchen <la@tfc-server.de>
* Copyright (C) 2012 by Kyle Keen <keenerd@gmail.com>
* Copyright (C) 2013 by Elias Oenal <EliasOenal@gmail.com>
* Copyright (C) 2015 by Hayati Ayguen <h_ayguen@web.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -62,7 +63,7 @@
#include <io.h>
#include "getopt/getopt.h"
#define usleep(x) Sleep(x/1000)
#ifdef _MSC_VER
#if defined(_MSC_VER) && (_MSC_VER < 1800)
#define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5))
#endif
#define _USE_MATH_DEFINES
@ -92,6 +93,13 @@ static int *atan_lut = NULL;
static int atan_lut_size = 131072; /* 512 KB */
static int atan_lut_coef = 8;
static int verbosity = 0;
static int printLevels = 0;
static int printLevelNo = 1;
static int levelMax = 0;
static int levelMaxMax = 0;
static double levelSum = 0.0;
struct dongle_state
{
int exit_flag;
@ -100,8 +108,9 @@ struct dongle_state
int dev_index;
uint32_t freq;
uint32_t rate;
uint32_t bandwidth;
int gain;
uint16_t buf16[MAXIMUM_BUF_LENGTH];
int16_t buf16[MAXIMUM_BUF_LENGTH];
uint32_t buf_len;
int ppm_error;
int offset_tuning;
@ -138,7 +147,8 @@ struct demod_state
int deemph, deemph_a;
int now_lpr;
int prev_lpr_index;
int dc_block, dc_avg;
int dc_block_audio, dc_avg, adc_block_const;
int dc_block_raw, dc_avgI, dc_avgQ, rdc_block_const;
void (*mode_demod)(struct demod_state*);
pthread_rwlock_t rw;
pthread_cond_t ready;
@ -187,24 +197,35 @@ void usage(void)
"\t-f frequency_to_tune_to [Hz]\n"
"\t use multiple -f for scanning (requires squelch)\n"
"\t ranges supported, -f 118M:137M:25k\n"
"\t[-v increase verbosity (default: 0)]\n"
"\t[-M modulation (default: fm)]\n"
"\t fm, wbfm, raw, am, usb, lsb\n"
"\t fm or nbfm or nfm, wbfm or wfm, raw or iq, am, usb, lsb\n"
"\t wbfm == -M fm -s 170k -o 4 -A fast -r 32k -l 0 -E deemp\n"
"\t raw mode outputs 2x16 bit IQ pairs\n"
"\t[-s sample_rate (default: 24k)]\n"
"\t[-d device_index (default: 0)]\n"
"\t[-g tuner_gain (default: automatic)]\n"
"\t[-w tuner_bandwidth (default: automatic. enables offset tuning)]\n"
"\t[-l squelch_level (default: 0/off)]\n"
"\t[-L N prints levels every N calculations]\n"
"\t output are comma separated values (csv):\n"
"\t mean since last output, max since last output, overall max, squelch\n"
"\t[-c de-emphasis_time_constant in us for wbfm. 'us' or 'eu' for 75/50 us (default: us)]\n"
//"\t for fm squelch is inverted\n"
//"\t[-o oversampling (default: 1, 4 recommended)]\n"
"\t[-o oversampling (default: 1, 4 recommended)]\n"
"\t[-p ppm_error (default: 0)]\n"
"\t[-E enable_option (default: none)]\n"
"\t use multiple -E to enable multiple options\n"
"\t edge: enable lower edge tuning\n"
"\t dc: enable dc blocking filter\n"
"\t rdc: enable dc blocking filter on raw I/Q data at capture rate\n"
"\t adc: enable dc blocking filter on demodulated audio\n"
"\t dc: same as adc\n"
"\t rtlagc: enable rtl2832's digital agc (default: off)\n"
"\t agc: same as rtlagc\n"
"\t deemp: enable de-emphasis filter\n"
"\t direct: enable direct sampling\n"
"\t offset: enable offset tuning\n"
"\t direct: enable direct sampling (bypasses tuner, uses rtl2832 xtal)\n"
"\t offset: enable offset tuning (only e4000 tuner)\n"
"\t[-q dc_avg_factor for option rdc (default: 9)]\n"
"\tfilename ('-' means stdout)\n"
"\t omitting the filename also uses stdout\n\n"
"Experimental options:\n"
@ -271,13 +292,34 @@ int cic_9_tables[][10] = {
{9, -199, -362, 5303, -25505, 77489, -25505, 5303, -362, -199},
};
#ifdef _MSC_VER
#if defined(_MSC_VER) && (_MSC_VER < 1800)
double log2(double n)
{
return log(n) / log(2.0);
}
#endif
void rotate16_90(int16_t *buf, uint32_t len)
/* 90 rotation is 1+0j, 0+1j, -1+0j, 0-1j
or [0, 1, -3, 2, -4, -5, 7, -6] */
{
uint32_t i;
int16_t tmp;
for (i=0; i<len; i+=8) {
tmp = - buf[i+3];
buf[i+3] = buf[i+2];
buf[i+2] = tmp;
buf[i+4] = - buf[i+4];
buf[i+5] = - buf[i+5];
tmp = - buf[i+6];
buf[i+6] = buf[i+7];
buf[i+7] = tmp;
}
}
void rotate_90(unsigned char *buf, uint32_t len)
/* 90 rotation is 1+0j, 0+1j, -1+0j, 0-1j
or [0, 1, -3, 2, -4, -5, 7, -6] */
@ -610,7 +652,7 @@ void deemph_filter(struct demod_state *fm)
}
}
void dc_block_filter(struct demod_state *fm)
void dc_block_audio_filter(struct demod_state *fm)
{
int i, avg;
int64_t sum = 0;
@ -618,13 +660,36 @@ void dc_block_filter(struct demod_state *fm)
sum += fm->result[i];
}
avg = sum / fm->result_len;
avg = (avg + fm->dc_avg * 9) / 10;
avg = (avg + fm->dc_avg * fm->adc_block_const) / ( fm->adc_block_const + 1 );
for (i=0; i < fm->result_len; i++) {
fm->result[i] -= avg;
}
fm->dc_avg = avg;
}
void dc_block_raw_filter(struct demod_state *fm, int16_t *buf, int len)
{
/* derived from dc_block_audio_filter,
running over the raw I/Q components
*/
int i, avgI, avgQ;
int64_t sumI = 0;
int64_t sumQ = 0;
for (i = 0; i < len; i += 2) {
sumI += buf[i];
sumQ += buf[i+1];
}
avgI = sumI / ( len / 2 );
avgQ = sumQ / ( len / 2 );
avgI = (avgI + fm->dc_avgI * fm->rdc_block_const) / ( fm->rdc_block_const + 1 );
avgQ = (avgQ + fm->dc_avgQ * fm->rdc_block_const) / ( fm->rdc_block_const + 1 );
for (i = 0; i < len; i += 2) {
buf[i] -= avgI;
buf[i+1] -= avgQ;
}
fm->dc_avgI = avgI;
fm->dc_avgQ = avgQ;
}
int mad(int16_t *samples, int len, int step)
/* mean average deviation */
{
@ -759,6 +824,23 @@ void full_demod(struct demod_state *d)
} else {
d->squelch_hits = 0;}
}
if (printLevels) {
if (!sr)
sr = rms(d->lowpassed, d->lp_len, 1);
--printLevelNo;
if (printLevels) {
levelSum += sr;
if (levelMax < sr) levelMax = sr;
if (levelMaxMax < sr) levelMaxMax = sr;
if (!printLevelNo) {
printLevelNo = printLevels;
fprintf(stderr, "%f, %d, %d, %d\n", (levelSum / printLevels), levelMax, levelMaxMax, d->squelch_level );
levelMax = 0;
levelSum = 0;
}
}
}
d->mode_demod(d); /* lowpassed -> result */
if (d->mode_demod == &raw_demod) {
return;
@ -769,8 +851,8 @@ void full_demod(struct demod_state *d)
d->result_len = low_pass_simple(d->result, d->result_len, d->post_downsample);}
if (d->deemph) {
deemph_filter(d);}
if (d->dc_block) {
dc_block_filter(d);}
if (d->dc_block_audio) {
dc_block_audio_filter(d);}
if (d->rate_out2 > 0) {
low_pass_real(d);
//arbitrary_resample(d->result, d->result, d->result_len, d->result_len * d->rate_out2 / d->rate_out);
@ -792,10 +874,19 @@ static void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
buf[i] = 127;}
s->mute = 0;
}
if (!s->offset_tuning) {
rotate_90(buf, len);}
/* 1st: convert to 16 bit - to allow easier calculation of DC */
for (i=0; i<(int)len; i++) {
s->buf16[i] = (int16_t)buf[i] - 127;}
s->buf16[i] = ( (int16_t)buf[i] - 127 );
}
/* 2nd: do DC filtering BEFORE up-mixing */
if (d->dc_block_raw) {
dc_block_raw_filter(d, s->buf16, (int)len);
}
/* 3rd: up-mixing */
if (!s->offset_tuning) {
rotate16_90(s->buf16, (int)len);
/* rotate_90(buf, len); */
}
pthread_rwlock_wrlock(&d->rw);
memcpy(d->lowpassed, s->buf16, 2*len);
d->lp_len = len;
@ -862,11 +953,21 @@ static void optimal_settings(int freq, int rate)
dm->downsample_passes = (int)log2(dm->downsample) + 1;
dm->downsample = 1 << dm->downsample_passes;
}
if (verbosity) {
fprintf(stderr, "downsample_passes = %d (= # of fifth_order() iterations), downsample = %d\n", dm->downsample_passes, dm->downsample );
}
capture_freq = freq;
capture_rate = dm->downsample * dm->rate_in;
if (verbosity)
fprintf(stderr, "capture_rate = dm->downsample * dm->rate_in = %d * %d = %d\n", dm->downsample, dm->rate_in, capture_rate );
if (!d->offset_tuning) {
capture_freq = freq + capture_rate/4;}
capture_freq = freq + capture_rate/4;
if (verbosity)
fprintf(stderr, "optimal_settings(freq = %d): capture_freq = freq + capture_rate/4 = %d\n", freq, capture_freq );
}
capture_freq += cs->edge * dm->rate_in / 2;
if (verbosity)
fprintf(stderr, "optimal_settings(freq = %d): capture_freq += cs->edge * dm->rate_in / 2 = %d * %d / 2 = %d\n", freq, cs->edge, dm->rate_in, capture_freq );
dm->output_scale = (1<<15) / (128 * dm->downsample);
if (dm->output_scale < 1) {
dm->output_scale = 1;}
@ -874,6 +975,8 @@ static void optimal_settings(int freq, int rate)
dm->output_scale = 1;}
d->freq = (uint32_t)capture_freq;
d->rate = (uint32_t)capture_rate;
if (verbosity)
fprintf(stderr, "optimal_settings(freq = %d) delivers freq %.0f, rate %.0f\n", freq, (double)d->freq, (double)d->rate );
}
static void *controller_thread_fn(void *arg)
@ -884,6 +987,8 @@ static void *controller_thread_fn(void *arg)
struct controller_state *s = arg;
if (s->wb_mode) {
if (verbosity)
fprintf(stderr, "wbfm: adding 16000 Hz to every input frequency\n");
for (i=0; i < s->freq_len; i++) {
s->freqs[i] += 16000;}
}
@ -896,6 +1001,11 @@ static void *controller_thread_fn(void *arg)
verbose_offset_tuning(dongle.dev);}
/* Set the frequency */
if (verbosity) {
fprintf(stderr, "verbose_set_frequency(%.0f Hz)\n", (double)dongle.freq);
if (!dongle.offset_tuning)
fprintf(stderr, " frequency is away from parametrized one, to avoid negative impact from dc\n");
}
verbose_set_frequency(dongle.dev, dongle.freq);
fprintf(stderr, "Oversampling input by: %ix.\n", demod.downsample);
fprintf(stderr, "Oversampling output by: %ix.\n", demod.post_downsample);
@ -903,6 +1013,8 @@ static void *controller_thread_fn(void *arg)
1000 * 0.5 * (float)ACTUAL_BUF_LENGTH / (float)dongle.rate);
/* Set the sample rate */
if (verbosity)
fprintf(stderr, "verbose_set_sample_rate(%.0f Hz)\n", (double)dongle.rate);
verbose_set_sample_rate(dongle.dev, dongle.rate);
fprintf(stderr, "Output at %u Hz.\n", demod.rate_in/demod.post_downsample);
@ -947,6 +1059,7 @@ void dongle_init(struct dongle_state *s)
s->direct_sampling = 0;
s->offset_tuning = 0;
s->demod_target = &demod;
s->bandwidth = 0;
}
void demod_init(struct demod_state *s)
@ -969,8 +1082,13 @@ void demod_init(struct demod_state *s)
s->prev_lpr_index = 0;
s->deemph_a = 0;
s->now_lpr = 0;
s->dc_block = 0;
s->dc_block_audio = 0;
s->dc_avg = 0;
s->adc_block_const = 9;
s->dc_block_raw = 0;
s->dc_avgI = 0;
s->dc_avgQ = 0;
s->rdc_block_const = 9;
pthread_rwlock_init(&s->rw, NULL);
pthread_cond_init(&s->ready, NULL);
pthread_mutex_init(&s->ready_m, NULL);
@ -1042,12 +1160,14 @@ int main(int argc, char **argv)
int r, opt;
int dev_given = 0;
int custom_ppm = 0;
int timeConstant = 75; /* default: U.S. 75 uS */
int rtlagc = 0;
dongle_init(&dongle);
demod_init(&demod);
output_init(&output);
controller_init(&controller);
while ((opt = getopt(argc, argv, "d:f:g:s:b:l:o:t:r:p:E:F:A:M:h")) != -1) {
while ((opt = getopt(argc, argv, "d:f:g:s:b:l:L:o:t:r:p:E:q:F:A:M:c:h:w:v")) != -1) {
switch (opt) {
case 'd':
dongle.dev_index = verbose_device_search(optarg);
@ -1070,6 +1190,9 @@ int main(int argc, char **argv)
case 'l':
demod.squelch_level = (int)atof(optarg);
break;
case 'L':
printLevels = (int)atof(optarg);
break;
case 's':
demod.rate_in = (uint32_t)atofs(optarg);
demod.rate_out = (uint32_t)atofs(optarg);
@ -1098,14 +1221,21 @@ int main(int argc, char **argv)
case 'E':
if (strcmp("edge", optarg) == 0) {
controller.edge = 1;}
if (strcmp("dc", optarg) == 0) {
demod.dc_block = 1;}
if (strcmp("dc", optarg) == 0 || strcmp("adc", optarg) == 0) {
demod.dc_block_audio = 1;}
if (strcmp("rdc", optarg) == 0) {
demod.dc_block_raw = 1;}
if (strcmp("deemp", optarg) == 0) {
demod.deemph = 1;}
if (strcmp("direct", optarg) == 0) {
dongle.direct_sampling = 1;}
if (strcmp("offset", optarg) == 0) {
dongle.offset_tuning = 1;}
if (strcmp("rtlagc", optarg) == 0 || strcmp("agc", optarg) == 0) {
rtlagc = 1;}
break;
case 'q':
demod.rdc_block_const = atoi(optarg);
break;
case 'F':
demod.downsample_passes = 1; /* truthy placeholder */
@ -1121,9 +1251,9 @@ int main(int argc, char **argv)
demod.custom_atan = 2;}
break;
case 'M':
if (strcmp("fm", optarg) == 0) {
if (strcmp("nbfm", optarg) == 0 || strcmp("nfm", optarg) == 0 || strcmp("fm", optarg) == 0) {
demod.mode_demod = &fm_demod;}
if (strcmp("raw", optarg) == 0) {
if (strcmp("raw", optarg) == 0 || strcmp("iq", optarg) == 0) {
demod.mode_demod = &raw_demod;}
if (strcmp("am", optarg) == 0) {
demod.mode_demod = &am_demod;}
@ -1131,7 +1261,7 @@ int main(int argc, char **argv)
demod.mode_demod = &usb_demod;}
if (strcmp("lsb", optarg) == 0) {
demod.mode_demod = &lsb_demod;}
if (strcmp("wbfm", optarg) == 0) {
if (strcmp("wbfm", optarg) == 0 || strcmp("wfm", optarg) == 0) {
controller.wb_mode = 1;
demod.mode_demod = &fm_demod;
demod.rate_in = 170000;
@ -1142,13 +1272,33 @@ int main(int argc, char **argv)
demod.deemph = 1;
demod.squelch_level = 0;}
break;
case 'c':
if (strcmp("us", optarg) == 0)
timeConstant = 75;
else if (strcmp("eu", optarg) == 0)
timeConstant = 50;
else
timeConstant = (int)atof(optarg);
break;
case 'v':
++verbosity;
break;
case 'w':
dongle.bandwidth = (uint32_t)atofs(optarg);
if (dongle.bandwidth)
dongle.offset_tuning = 1; /* automatically switch offset tuning, when using bandwidth filter */
break;
case 'h':
case '?':
default:
usage();
break;
}
}
if (verbosity)
fprintf(stderr, "verbosity set to %d\n", verbosity);
/* quadruple sample_rate to limit to Δθ to ±π/2 */
demod.rate_in *= demod.post_downsample;
@ -1194,7 +1344,10 @@ int main(int argc, char **argv)
#endif
if (demod.deemph) {
demod.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(demod.rate_out * 75e-6)))));
double tc = (double)timeConstant * 1e-6;
demod.deemph_a = (int)round(1.0/((1.0-exp(-1.0/(demod.rate_out * tc)))));
if (verbosity)
fprintf(stderr, "using wbfm deemphasis filter with time constant %d us\n", timeConstant );
}
/* Set the tuner gain */
@ -1205,8 +1358,27 @@ int main(int argc, char **argv)
verbose_gain_set(dongle.dev, dongle.gain);
}
rtlsdr_set_agc_mode(dongle.dev, rtlagc);
verbose_ppm_set(dongle.dev, dongle.ppm_error);
verbose_set_bandwidth(dongle.dev, dongle.bandwidth);
if (verbosity && dongle.bandwidth)
{
int r;
uint32_t in_bw, out_bw, last_bw = 0;
fprintf(stderr, "Supported bandwidth values in kHz:\n");
for ( in_bw = 1; in_bw < 3200; ++in_bw )
{
r = rtlsdr_set_and_get_tuner_bandwidth(dongle.dev, in_bw*1000, &out_bw, 0 /* =apply_bw */);
if ( r == 0 && out_bw != 0 && ( out_bw != last_bw || in_bw == 1 ) )
fprintf(stderr, "%s%.1f", (in_bw==1 ? "" : ", "), out_bw/1000.0 );
last_bw = out_bw;
}
fprintf(stderr,"\n");
}
if (strcmp(output.filename, "-") == 0) { /* Write samples to stdout */
output.file = stdout;
#ifdef _WIN32

View File

@ -53,7 +53,7 @@
#include <io.h>
#include "getopt/getopt.h"
#define usleep(x) Sleep(x/1000)
#ifdef _MSC_VER
#if defined(_MSC_VER) && (_MSC_VER < 1800)
#define round(x) (x > 0.0 ? floor(x + 0.5): ceil(x - 0.5))
#endif
#define _USE_MATH_DEFINES
@ -220,7 +220,7 @@ int cic_9_tables[][10] = {
{9, -199, -362, 5303, -25505, 77489, -25505, 5303, -362, -199},
};
#ifdef _MSC_VER
#if defined(_MSC_VER) && (_MSC_VER < 1800)
double log2(double n)
{
return log(n) / log(2.0);

View File

@ -78,6 +78,8 @@ typedef struct { /* structure size must be multiple of 2 bytes */
static rtlsdr_dev_t *dev = NULL;
static int verbosity = 0;
static uint32_t bandwidth = 0;
static int global_numq = 0;
static struct llist *ll_buffers = 0;
static int llbuf_num = 500;
@ -90,14 +92,17 @@ void usage(void)
"Usage:\t[-a listen address]\n"
"\t[-p listen port (default: 1234)]\n"
"\t[-I infrared sensor listen port (default: 0=none)]\n"
"\t[-w infrared sensor query wait interval usec (default: 10000)]\n"
"\t[-W infrared sensor query wait interval usec (default: 10000)]\n"
"\t[-f frequency to tune to [Hz]]\n"
"\t[-g gain (default: 0 for auto)]\n"
"\t[-g gain in dB (default: 0 for auto)]\n"
"\t[-s samplerate in Hz (default: 2048000 Hz)]\n"
"\t[-b number of buffers (default: 15, set by library)]\n"
"\t[-l length of single buffer in units of 512 samples (default: 64 was 256)]\n"
"\t[-n max number of linked list buffers to keep (default: 500)]\n"
"\t[-w rtlsdr tuner bandwidth [Hz] (for R820T and E4000 tuners)]\n"
"\t[-d device index (default: 0)]\n"
"\t[-P ppm_error (default: 0)]\n");
"\t[-P ppm_error (default: 0)]\n"
"\t[-v increase verbosity (default: 0)]\n");
exit(1);
}
@ -176,10 +181,13 @@ void rtlsdr_callback(unsigned char *buf, uint32_t len, void *ctx)
cur->next = rpt;
if ( verbosity )
{
if (num_queued > global_numq)
printf("ll+, now %d\n", num_queued);
else if (num_queued < global_numq)
printf("ll-, now %d\n", num_queued);
}
global_numq = num_queued;
}
@ -204,7 +212,7 @@ static void *tcp_worker(void *arg)
pthread_mutex_lock(&ll_mutex);
gettimeofday(&tp, NULL);
ts.tv_sec = tp.tv_sec+5;
ts.tv_sec = tp.tv_sec+1;
ts.tv_nsec = tp.tv_usec * 1000;
r = pthread_cond_timedwait(&cond, &ll_mutex, &ts);
if(r == ETIMEDOUT) {
@ -258,6 +266,8 @@ static int set_gain_by_index(rtlsdr_dev_t *_dev, unsigned int index)
count = rtlsdr_get_tuner_gains(_dev, gains);
res = rtlsdr_set_tuner_gain(_dev, gains[index]);
if (verbosity)
fprintf(stderr, "set tuner gain to %.1f dB\n", gains[index] / 10.0);
free(gains);
}
@ -304,59 +314,65 @@ static void *command_worker(void *arg)
}
}
switch(cmd.cmd) {
case 0x01:
case SET_FREQUENCY:
printf("set freq %d\n", ntohl(cmd.param));
rtlsdr_set_center_freq(dev,ntohl(cmd.param));
break;
case 0x02:
case SET_SAMPLE_RATE:
printf("set sample rate %d\n", ntohl(cmd.param));
rtlsdr_set_sample_rate(dev, ntohl(cmd.param));
/*verbose_set_bandwidth(dev, bandwidth);*/
break;
case 0x03:
case SET_GAIN_MODE:
printf("set gain mode %d\n", ntohl(cmd.param));
rtlsdr_set_tuner_gain_mode(dev, ntohl(cmd.param));
break;
case 0x04:
case SET_GAIN:
printf("set gain %d\n", ntohl(cmd.param));
rtlsdr_set_tuner_gain(dev, ntohl(cmd.param));
break;
case 0x05:
case SET_FREQUENCY_CORRECTION:
printf("set freq correction %d\n", ntohl(cmd.param));
rtlsdr_set_freq_correction(dev, ntohl(cmd.param));
break;
case 0x06:
case SET_IF_STAGE:
tmp = ntohl(cmd.param);
printf("set if stage %d gain %d\n", tmp >> 16, (short)(tmp & 0xffff));
rtlsdr_set_tuner_if_gain(dev, tmp >> 16, (short)(tmp & 0xffff));
break;
case 0x07:
case SET_TEST_MODE:
printf("set test mode %d\n", ntohl(cmd.param));
rtlsdr_set_testmode(dev, ntohl(cmd.param));
break;
case 0x08:
case SET_AGC_MODE:
printf("set agc mode %d\n", ntohl(cmd.param));
rtlsdr_set_agc_mode(dev, ntohl(cmd.param));
break;
case 0x09:
case SET_DIRECT_SAMPLING:
printf("set direct sampling %d\n", ntohl(cmd.param));
rtlsdr_set_direct_sampling(dev, ntohl(cmd.param));
break;
case 0x0a:
case SET_OFFSET_TUNING:
printf("set offset tuning %d\n", ntohl(cmd.param));
rtlsdr_set_offset_tuning(dev, ntohl(cmd.param));
break;
case 0x0b:
case SET_RTL_CRYSTAL:
printf("set rtl xtal %d\n", ntohl(cmd.param));
rtlsdr_set_xtal_freq(dev, ntohl(cmd.param), 0);
break;
case 0x0c:
case SET_TUNER_CRYSTAL:
printf("set tuner xtal %d\n", ntohl(cmd.param));
rtlsdr_set_xtal_freq(dev, 0, ntohl(cmd.param));
break;
case 0x0d:
case SET_TUNER_GAIN_BY_INDEX:
printf("set tuner gain by index %d\n", ntohl(cmd.param));
set_gain_by_index(dev, ntohl(cmd.param));
break;
case SET_TUNER_BANDWIDTH:
bandwidth = ntohl(cmd.param);
printf("set tuner bandwidth to %i Hz\n", bandwidth);
verbose_set_bandwidth(dev, bandwidth);
break;
default:
break;
}
@ -447,6 +463,16 @@ int main(int argc, char **argv)
uint32_t frequency = 100000000, samp_rate = 2048000;
struct sockaddr_in local, remote;
uint32_t buf_num = 0;
/* buf_len:
* -> 256 -> 262 ms @ 250 kS or 20.48 ms @ 3.2 MS (internal default)
* -> 128 -> 131 ms @ 250 kS or 10.24 ms @ 3.2 MS
* -> 64 -> 65 ms @ 250 kS or 5.12 ms @ 3.2 MS (new default)
*
* usual soundcard as reference:
* 512 samples @ 48 kHz ~= 10.6 ms
* 512 samples @ 8 kHz = 64 ms
*/
uint32_t buf_len = 64;
int dev_index = 0;
int dev_given = 0;
int gain = 0;
@ -461,6 +487,7 @@ int main(int argc, char **argv)
fd_set readfds;
u_long blockmode = 1;
dongle_info_t dongle_info;
int gains[100];
#ifdef _WIN32
WSADATA wsd;
i = WSAStartup(MAKEWORD(2,2), &wsd);
@ -468,7 +495,7 @@ int main(int argc, char **argv)
struct sigaction sigact, sigign;
#endif
while ((opt = getopt(argc, argv, "a:p:I:w:f:g:s:b:n:d:P:")) != -1) {
while ((opt = getopt(argc, argv, "a:p:I:W:f:g:s:b:l:n:d:P:w:v")) != -1) {
switch (opt) {
case 'd':
dev_index = verbose_device_search(optarg);
@ -492,18 +519,27 @@ int main(int argc, char **argv)
case 'I':
port_ir = atoi(optarg);
break;
case 'w':
case 'W':
wait_ir = atoi(optarg);
break;
case 'b':
buf_num = atoi(optarg);
break;
case 'l':
buf_len = 512 * atoi(optarg);
break;
case 'n':
llbuf_num = atoi(optarg);
break;
case 'P':
ppm_error = atoi(optarg);
break;
case 'w':
bandwidth = (uint32_t)atofs(optarg);
break;
case 'v':
++verbosity;
break;
default:
usage();
break;
@ -513,6 +549,9 @@ int main(int argc, char **argv)
if (argc < optind)
usage();
if (verbosity)
fprintf(stderr, "verbosity set to %d\n", verbosity);
if (!dev_given) {
dev_index = verbose_device_search("0");
}
@ -574,6 +613,8 @@ int main(int argc, char **argv)
fprintf(stderr, "Tuner gain set to %f dB.\n", gain/10.0);
}
verbose_set_bandwidth(dev, bandwidth);
/* Reset endpoint before we start reading from it (mandatory) */
r = rtlsdr_reset_buffer(dev);
if (r < 0)
@ -645,9 +686,16 @@ int main(int argc, char **argv)
if (r >= 0)
dongle_info.tuner_type = htonl(r);
r = rtlsdr_get_tuner_gains(dev, NULL);
r = rtlsdr_get_tuner_gains(dev, gains);
if (r >= 0)
dongle_info.tuner_gain_count = htonl(r);
if (verbosity)
{
fprintf(stderr, "Supported gain values (%d): ", r);
for (i = 0; i < r; i++)
fprintf(stderr, "%.1f ", gains[i] / 10.0);
fprintf(stderr, "\n");
}
r = send(s, (const char *)&dongle_info, sizeof(dongle_info), 0);
if (sizeof(dongle_info) != r)
@ -659,7 +707,7 @@ int main(int argc, char **argv)
r = pthread_create(&command_thread, &attr, command_worker, NULL);
pthread_attr_destroy(&attr);
r = rtlsdr_read_async(dev, rtlsdr_callback, NULL, buf_num, 0);
r = rtlsdr_read_async(dev, rtlsdr_callback, NULL, buf_num, buf_len);
pthread_join(tcp_worker_thread, &status);
pthread_join(command_thread, &status);

View File

@ -44,10 +44,7 @@ fc2580_fci_result_type fc2580_i2c_read(void *pTuner, unsigned char reg, unsigned
return FC2580_FCI_SUCCESS;
}
int
fc2580_Initialize(
void *pTuner
)
int fc2580_Initialize(void *pTuner)
{
int AgcMode;
unsigned int CrystalFreqKhz;
@ -70,11 +67,7 @@ error_status_initialize_tuner:
return FUNCTION_ERROR;
}
int
fc2580_SetRfFreqHz(
void *pTuner,
unsigned long RfFreqHz
)
int fc2580_SetRfFreqHz(void *pTuner, unsigned long RfFreqHz)
{
unsigned int RfFreqKhz;
unsigned int CrystalFreqKhz;
@ -99,11 +92,7 @@ error_status_set_tuner_rf_frequency:
@brief Set FC2580 tuner bandwidth mode.
*/
int
fc2580_SetBandwidthMode(
void *pTuner,
int BandwidthMode
)
int fc2580_SetBandwidthMode(void *pTuner, int BandwidthMode)
{
unsigned int CrystalFreqKhz;
@ -143,7 +132,7 @@ void fc2580_wait_msec(void *pTuner, int a)
2 : Voltage Control Mode
==============================================================================*/
fc2580_fci_result_type fc2580_set_init( void *pTuner, int ifagc_mode, unsigned int freq_xtal )
fc2580_fci_result_type fc2580_set_init(void *pTuner, int ifagc_mode, unsigned int freq_xtal)
{
fc2580_fci_result_type result = FC2580_FCI_SUCCESS;
@ -192,7 +181,7 @@ fc2580_fci_result_type fc2580_set_init( void *pTuner, int ifagc_mode, unsigned i
ex) 2.6GHz = 2600000
==============================================================================*/
fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigned int freq_xtal )
fc2580_fci_result_type fc2580_set_freq(void *pTuner, unsigned int f_lo, unsigned int freq_xtal)
{
unsigned int f_diff, f_diff_shifted, n_val, k_val;
unsigned int f_vco, r_val, f_comp;
@ -369,7 +358,7 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne
==============================================================================*/
fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw, unsigned int freq_xtal )
fc2580_fci_result_type fc2580_set_filter(void *pTuner, unsigned char filter_bw, unsigned int freq_xtal)
{
unsigned char cal_mon = 0, i;
fc2580_fci_result_type result = FC2580_FCI_SUCCESS;

View File

@ -1004,7 +1004,7 @@ static const int r82xx_mixer_gain_steps[] = {
0, 5, 10, 10, 19, 9, 10, 25, 17, 10, 8, 16, 13, 6, 3, -8
};
int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain)
int r82xx_set_gain_old(struct r82xx_priv *priv, int set_manual_gain, int gain)
{
int rc;
@ -1073,6 +1073,113 @@ int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain)
return 0;
}
int r82xx_set_gain(struct r82xx_priv *priv, int set_manual_gain, int gain,
int extended_mode, int lna_gain, int mixer_gain, int vga_gain)
{
int rc;
int i, total_gain = 0;
uint8_t mix_index = 0, lna_index = 0;
uint8_t data[4];
if (extended_mode) {
/*
// LNA auto off
rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10);
if (rc < 0)
return rc;
// Mixer auto off
rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10);
if (rc < 0)
return rc;
rc = r82xx_read(priv, 0x00, data, sizeof(data));
if (rc < 0)
return rc;
*/
/* Set LNA */
rc = r82xx_write_reg_mask(priv, 0x05, lna_gain, 0x0f);
if (rc < 0)
return rc;
/* Set Mixer */
rc = r82xx_write_reg_mask(priv, 0x07, mixer_gain, 0x0f);
if (rc < 0)
return rc;
/* Set VGA */
rc = r82xx_write_reg_mask(priv, 0x0c, vga_gain, 0x9f);
if (rc < 0)
return rc;
return 0;
}
if (set_manual_gain) {
/* LNA auto off */
rc = r82xx_write_reg_mask(priv, 0x05, 0x10, 0x10);
if (rc < 0)
return rc;
/* Mixer auto off */
rc = r82xx_write_reg_mask(priv, 0x07, 0, 0x10);
if (rc < 0)
return rc;
rc = r82xx_read(priv, 0x00, data, sizeof(data));
if (rc < 0)
return rc;
/* set fixed VGA gain for now (16.3 dB) */
rc = r82xx_write_reg_mask(priv, 0x0c, 0x08, 0x9f);
if (rc < 0)
return rc;
for (i = 0; i < 15; i++) {
if (total_gain >= gain)
break;
total_gain += r82xx_lna_gain_steps[++lna_index];
if (total_gain >= gain)
break;
total_gain += r82xx_mixer_gain_steps[++mix_index];
}
/* set LNA gain */
rc = r82xx_write_reg_mask(priv, 0x05, lna_index, 0x0f);
if (rc < 0)
return rc;
/* set Mixer gain */
rc = r82xx_write_reg_mask(priv, 0x07, mix_index, 0x0f);
if (rc < 0)
return rc;
} else {
/* LNA */
rc = r82xx_write_reg_mask(priv, 0x05, 0, 0x10);
if (rc < 0)
return rc;
/* Mixer */
rc = r82xx_write_reg_mask(priv, 0x07, 0x10, 0x10);
if (rc < 0)
return rc;
/* set fixed VGA gain for now (26.5 dB) */
rc = r82xx_write_reg_mask(priv, 0x0c, 0x0b, 0x9f);
if (rc < 0)
return rc;
}
return 0;
}
/* Bandwidth contribution by low-pass filter. */
static const int r82xx_if_low_pass_bw_table[] = {
1700000, 1600000, 1550000, 1450000, 1200000, 900000, 700000, 550000, 450000, 350000
@ -1080,7 +1187,7 @@ static const int r82xx_if_low_pass_bw_table[] = {
#define FILT_HP_BW1 350000
#define FILT_HP_BW2 380000
int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate)
int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate, uint32_t * applied_bw, int apply)
{
int rc;
unsigned int i;
@ -1090,26 +1197,34 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate)
if (bw > 7000000) {
// BW: 8 MHz
*applied_bw = 8000000;
reg_0a = 0x10;
reg_0b = 0x0b;
if (apply)
priv->int_freq = 4570000;
} else if (bw > 6000000) {
// BW: 7 MHz
*applied_bw = 7000000;
reg_0a = 0x10;
reg_0b = 0x2a;
if (apply)
priv->int_freq = 4570000;
} else if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1 + FILT_HP_BW2) {
// BW: 6 MHz
*applied_bw = 6000000;
reg_0a = 0x10;
reg_0b = 0x6b;
if (apply)
priv->int_freq = 3570000;
} else {
reg_0a = 0x00;
reg_0b = 0x80;
if (apply)
priv->int_freq = 2300000;
if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1) {
bw -= FILT_HP_BW2;
if (apply)
priv->int_freq += FILT_HP_BW2;
real_bw += FILT_HP_BW2;
} else {
@ -1118,6 +1233,7 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate)
if (bw > r82xx_if_low_pass_bw_table[0]) {
bw -= FILT_HP_BW1;
if (apply)
priv->int_freq += FILT_HP_BW1;
real_bw += FILT_HP_BW1;
} else {
@ -1133,9 +1249,15 @@ int r82xx_set_bandwidth(struct r82xx_priv *priv, int bw, uint32_t rate)
reg_0b |= 15 - i;
real_bw += r82xx_if_low_pass_bw_table[i];
*applied_bw = real_bw;
if (apply)
priv->int_freq -= real_bw / 2;
}
if (!apply)
return 0;
rc = r82xx_write_reg_mask(priv, 0x0a, reg_0a, 0x10);
if (rc < 0)
return rc;

View File

@ -0,0 +1,75 @@
project(rtlsdr)
cmake_minimum_required(VERSION 2.8)
# created and tested with
# Qt 5.5.1 for Windows 32-bit (MinGW 4.9.2) from
# https://www.qt.io/download-open-source/#section-2
#
# and QtCreator 4.0.0
#
# and LibUSB 1.0.20 from
# https://sourceforge.net/projects/libusb/files/
# libusb-1.0.20.7z
#
# edit this path
SET( LIBUSBBASE C:/src/_foreign/libusb-1.0.20 )
add_definitions( -DWIN32 -D_WIN32 -DNDEBUG )
include_directories(
../include
${LIBUSBBASE}/include/libusb-1.0
)
SET( LIBUSB ${LIBUSBBASE}/MinGW32/static/libusb-1.0.a )
SET( SOCKLIBS ws2_32 wsock32 )
SET( RTLLIBFILES
../include/rtl_tcp.h
../include/reg_field.h
../include/rtlsdr_i2c.h
../src/convenience/convenience.c
../src/convenience/convenience.h
../src/getopt/getopt.c
../src/getopt/getopt.h
../include/rtl-sdr_export.h
../include/rtl-sdr.h
../src/librtlsdr.c
../include/tuner_e4k.h
../src/tuner_e4k.c
../include/tuner_fc0012.h
../src/tuner_fc0012.c
../include/tuner_fc0013.h
../src/tuner_fc0013.c
../include/tuner_fc2580.h
../src/tuner_fc2580.c
../include/tuner_r82xx.h
../src/tuner_r82xx.c
)
add_executable( rtl_test ../src/rtl_test.c ${RTLLIBFILES} )
target_link_libraries( rtl_test ${LIBUSB} )
add_executable( rtl_fm ../src/rtl_fm.c ${RTLLIBFILES} )
target_link_libraries( rtl_fm ${LIBUSB} )
add_executable( rtl_tcp ../src/rtl_tcp.c ${RTLLIBFILES} )
target_link_libraries( rtl_tcp ${LIBUSB} ${SOCKLIBS} )
add_executable( rtl_adsb ../src/rtl_adsb.c ${RTLLIBFILES} )
target_link_libraries( rtl_adsb ${LIBUSB} )
add_executable( rtl_power ../src/rtl_power.c ${RTLLIBFILES} )
target_link_libraries( rtl_power ${LIBUSB} )

View File

@ -0,0 +1,31 @@
there is an outdated "How to compile new releases of librtlsdr (and tools) on Windows" at
https://www.reddit.com/r/RTLSDR/comments/uce3e/how_to_compile_new_releases_of_librtlsdr_and/
unfortunately the link to the CMakeLists.txt is broken!
so, i needed to find another solution ..
1) aquire and install Qt 5.5.x for Windows 32-bit (MinGW 4.9.2) from
https://www.qt.io/download-open-source/#section-2
2) aquire and install QtCreator 4.0.x
from same site as 1)
probably this step is not necessary and you can use the qtcreator IDE from 1)
3) aquire LibUSB 1.0.20 from
https://sourceforge.net/projects/libusb/files/
last tested: libusb-1.0.20.7z
and place the file at C:/src/_foreign/libusb-1.0.20
or replace LIBUSBBASE path in CMakeLists.txt
4) start qtcreator and open the (modified) CMakeLists.txt
configure compiler/environment and compile
the resulting executables have no other dependencies than libwinpthread-1.dll
from the MINGW system at C:\Qt\Qt5.5.1\Tools\mingw492_32\bin\
or C:\Qt\Qt5.5.1\5.5\mingw492_32\bin