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

@ -29,94 +29,94 @@
#define E4K_CHECK_VAL 0x40
enum e4k_reg {
E4K_REG_MASTER1 = 0x00,
E4K_REG_MASTER2 = 0x01,
E4K_REG_MASTER3 = 0x02,
E4K_REG_MASTER4 = 0x03,
E4K_REG_MASTER5 = 0x04,
E4K_REG_CLK_INP = 0x05,
E4K_REG_REF_CLK = 0x06,
E4K_REG_SYNTH1 = 0x07,
E4K_REG_SYNTH2 = 0x08,
E4K_REG_SYNTH3 = 0x09,
E4K_REG_SYNTH4 = 0x0a,
E4K_REG_SYNTH5 = 0x0b,
E4K_REG_SYNTH6 = 0x0c,
E4K_REG_SYNTH7 = 0x0d,
E4K_REG_SYNTH8 = 0x0e,
E4K_REG_SYNTH9 = 0x0f,
E4K_REG_FILT1 = 0x10,
E4K_REG_FILT2 = 0x11,
E4K_REG_FILT3 = 0x12,
E4K_REG_MASTER1 = 0x00,
E4K_REG_MASTER2 = 0x01,
E4K_REG_MASTER3 = 0x02,
E4K_REG_MASTER4 = 0x03,
E4K_REG_MASTER5 = 0x04,
E4K_REG_CLK_INP = 0x05,
E4K_REG_REF_CLK = 0x06,
E4K_REG_SYNTH1 = 0x07,
E4K_REG_SYNTH2 = 0x08,
E4K_REG_SYNTH3 = 0x09,
E4K_REG_SYNTH4 = 0x0a,
E4K_REG_SYNTH5 = 0x0b,
E4K_REG_SYNTH6 = 0x0c,
E4K_REG_SYNTH7 = 0x0d,
E4K_REG_SYNTH8 = 0x0e,
E4K_REG_SYNTH9 = 0x0f,
E4K_REG_FILT1 = 0x10,
E4K_REG_FILT2 = 0x11,
E4K_REG_FILT3 = 0x12,
// gap
E4K_REG_GAIN1 = 0x14,
E4K_REG_GAIN2 = 0x15,
E4K_REG_GAIN3 = 0x16,
E4K_REG_GAIN4 = 0x17,
E4K_REG_GAIN1 = 0x14,
E4K_REG_GAIN2 = 0x15,
E4K_REG_GAIN3 = 0x16,
E4K_REG_GAIN4 = 0x17,
// gap
E4K_REG_AGC1 = 0x1a,
E4K_REG_AGC2 = 0x1b,
E4K_REG_AGC3 = 0x1c,
E4K_REG_AGC4 = 0x1d,
E4K_REG_AGC5 = 0x1e,
E4K_REG_AGC6 = 0x1f,
E4K_REG_AGC7 = 0x20,
E4K_REG_AGC8 = 0x21,
E4K_REG_AGC1 = 0x1a,
E4K_REG_AGC2 = 0x1b,
E4K_REG_AGC3 = 0x1c,
E4K_REG_AGC4 = 0x1d,
E4K_REG_AGC5 = 0x1e,
E4K_REG_AGC6 = 0x1f,
E4K_REG_AGC7 = 0x20,
E4K_REG_AGC8 = 0x21,
// gap
E4K_REG_AGC11 = 0x24,
E4K_REG_AGC12 = 0x25,
E4K_REG_AGC11 = 0x24,
E4K_REG_AGC12 = 0x25,
// gap
E4K_REG_DC1 = 0x29,
E4K_REG_DC2 = 0x2a,
E4K_REG_DC3 = 0x2b,
E4K_REG_DC4 = 0x2c,
E4K_REG_DC5 = 0x2d,
E4K_REG_DC6 = 0x2e,
E4K_REG_DC7 = 0x2f,
E4K_REG_DC8 = 0x30,
E4K_REG_DC1 = 0x29,
E4K_REG_DC2 = 0x2a,
E4K_REG_DC3 = 0x2b,
E4K_REG_DC4 = 0x2c,
E4K_REG_DC5 = 0x2d,
E4K_REG_DC6 = 0x2e,
E4K_REG_DC7 = 0x2f,
E4K_REG_DC8 = 0x30,
// gap
E4K_REG_QLUT0 = 0x50,
E4K_REG_QLUT1 = 0x51,
E4K_REG_QLUT2 = 0x52,
E4K_REG_QLUT3 = 0x53,
E4K_REG_QLUT0 = 0x50,
E4K_REG_QLUT1 = 0x51,
E4K_REG_QLUT2 = 0x52,
E4K_REG_QLUT3 = 0x53,
// gap
E4K_REG_ILUT0 = 0x60,
E4K_REG_ILUT1 = 0x61,
E4K_REG_ILUT2 = 0x62,
E4K_REG_ILUT3 = 0x63,
E4K_REG_ILUT0 = 0x60,
E4K_REG_ILUT1 = 0x61,
E4K_REG_ILUT2 = 0x62,
E4K_REG_ILUT3 = 0x63,
// gap
E4K_REG_DCTIME1 = 0x70,
E4K_REG_DCTIME2 = 0x71,
E4K_REG_DCTIME3 = 0x72,
E4K_REG_DCTIME4 = 0x73,
E4K_REG_PWM1 = 0x74,
E4K_REG_PWM2 = 0x75,
E4K_REG_PWM3 = 0x76,
E4K_REG_PWM4 = 0x77,
E4K_REG_BIAS = 0x78,
E4K_REG_CLKOUT_PWDN = 0x7a,
E4K_REG_DCTIME1 = 0x70,
E4K_REG_DCTIME2 = 0x71,
E4K_REG_DCTIME3 = 0x72,
E4K_REG_DCTIME4 = 0x73,
E4K_REG_PWM1 = 0x74,
E4K_REG_PWM2 = 0x75,
E4K_REG_PWM3 = 0x76,
E4K_REG_PWM4 = 0x77,
E4K_REG_BIAS = 0x78,
E4K_REG_CLKOUT_PWDN = 0x7a,
E4K_REG_CHFILT_CALIB = 0x7b,
E4K_REG_I2C_REG_ADDR = 0x7d,
// FIXME
};
#define E4K_MASTER1_RESET (1 << 0)
#define E4K_MASTER1_RESET (1 << 0)
#define E4K_MASTER1_NORM_STBY (1 << 1)
#define E4K_MASTER1_POR_DET (1 << 2)
#define E4K_MASTER1_POR_DET (1 << 2)
#define E4K_SYNTH1_PLL_LOCK (1 << 0)
#define E4K_SYNTH1_PLL_LOCK (1 << 0)
#define E4K_SYNTH1_BAND_SHIF 1
#define E4K_SYNTH7_3PHASE_EN (1 << 3)
#define E4K_SYNTH8_VCOCAL_UPD (1 << 2)
#define E4K_FILT3_DISABLE (1 << 5)
#define E4K_FILT3_DISABLE (1 << 5)
#define E4K_AGC1_LIN_MODE (1 << 4)
#define E4K_AGC1_LNA_UPDATE (1 << 5)
#define E4K_AGC1_LNA_G_LOW (1 << 6)
#define E4K_AGC1_LNA_G_HIGH (1 << 7)
#define E4K_AGC1_LIN_MODE (1 << 4)
#define E4K_AGC1_LNA_UPDATE (1 << 5)
#define E4K_AGC1_LNA_G_LOW (1 << 6)
#define E4K_AGC1_LNA_G_HIGH (1 << 7)
#define E4K_AGC6_LNA_CAL_REQ (1 << 4)
@ -127,27 +127,27 @@ enum e4k_reg {
#define E4K_AGC11_LNA_GAIN_ENH (1 << 0)
#define E4K_DC1_CAL_REQ (1 << 0)
#define E4K_DC1_CAL_REQ (1 << 0)
#define E4K_DC5_I_LUT_EN (1 << 0)
#define E4K_DC5_Q_LUT_EN (1 << 1)
#define E4K_DC5_I_LUT_EN (1 << 0)
#define E4K_DC5_Q_LUT_EN (1 << 1)
#define E4K_DC5_RANGE_DET_EN (1 << 2)
#define E4K_DC5_RANGE_EN (1 << 3)
#define E4K_DC5_TIMEVAR_EN (1 << 4)
#define E4K_DC5_RANGE_EN (1 << 3)
#define E4K_DC5_TIMEVAR_EN (1 << 4)
#define E4K_CLKOUT_DISABLE 0x96
#define E4K_CLKOUT_DISABLE 0x96
#define E4K_CHFCALIB_CMD (1 << 0)
#define E4K_CHFCALIB_CMD (1 << 0)
#define E4K_AGC1_MOD_MASK 0xF
#define E4K_AGC1_MOD_MASK 0xF
enum e4k_agc_mode {
E4K_AGC_MOD_SERIAL = 0x0,
E4K_AGC_MOD_SERIAL = 0x0,
E4K_AGC_MOD_IF_PWM_LNA_SERIAL = 0x1,
E4K_AGC_MOD_IF_PWM_LNA_AUTONL = 0x2,
E4K_AGC_MOD_IF_PWM_LNA_SUPERV = 0x3,
E4K_AGC_MOD_IF_SERIAL_LNA_PWM = 0x4,
E4K_AGC_MOD_IF_PWM_LNA_PWM = 0x5,
E4K_AGC_MOD_IF_PWM_LNA_PWM = 0x5,
E4K_AGC_MOD_IF_DIG_LNA_SERIAL = 0x6,
E4K_AGC_MOD_IF_DIG_LNA_AUTON = 0x7,
E4K_AGC_MOD_IF_DIG_LNA_SUPERV = 0x8,
@ -159,7 +159,7 @@ enum e4k_band {
E4K_BAND_VHF2 = 0,
E4K_BAND_VHF3 = 1,
E4K_BAND_UHF = 2,
E4K_BAND_L = 3,
E4K_BAND_L = 3,
};
enum e4k_mixer_filter_bw {

View File

@ -1,9 +1,9 @@
#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 OFS_RSSI 57
#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
#define FC2580_CHECK_ADDR 0x01

40
include/tuner_r82xx.h 100644 → 100755
View File

@ -35,11 +35,11 @@
#define R82XX_IF_FREQ 3570000
#define REG_SHADOW_START 5
#define NUM_REGS 30
#define NUM_IMR 5
#define IMR_TRIAL 9
#define NUM_REGS 30
#define NUM_IMR 5
#define IMR_TRIAL 9
#define VER_NUM 49
#define VER_NUM 49
enum r82xx_chip {
CHIP_R820T,
@ -75,23 +75,21 @@ struct r82xx_config {
struct r82xx_priv {
struct r82xx_config *cfg;
uint8_t regs[NUM_REGS];
uint8_t buf[NUM_REGS + 1];
uint8_t regs[NUM_REGS];
uint8_t buf[NUM_REGS + 1];
enum r82xx_xtal_cap_value xtal_cap_sel;
uint16_t pll; /* kHz */
uint32_t int_freq;
uint8_t fil_cal_code;
uint8_t input;
int has_lock;
int init_done;
uint16_t pll; /* kHz */
uint32_t int_freq;
uint8_t fil_cal_code;
uint8_t input;
int has_lock;
int init_done;
/* Store current mode */
uint32_t delsys;
enum r82xx_tuner_type type;
uint32_t bw; /* in MHz */
void *rtl_dev;
uint32_t delsys;
enum r82xx_tuner_type type;
uint32_t bw; /* in MHz */
void *rtl_dev;
};
struct r82xx_freq_range {
@ -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

26
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,7 +201,12 @@ int verbose_offset_tuning(rtlsdr_dev_t *dev)
int r;
r = rtlsdr_set_offset_tuning(dev, 1);
if (r != 0) {
fprintf(stderr, "WARNING: Failed to set offset tuning.\n");
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

@ -10,11 +10,11 @@
*
* 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
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <errno.h>
@ -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;
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 */
@ -361,19 +376,19 @@ static rtlsdr_dongle_t known_devices[] = {
#define MIN_RTL_XTAL_FREQ (DEF_RTL_XTAL_FREQ - 1000)
#define MAX_RTL_XTAL_FREQ (DEF_RTL_XTAL_FREQ + 1000)
#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN)
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT)
#define CTRL_IN (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_IN)
#define CTRL_OUT (LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_ENDPOINT_OUT)
#define CTRL_TIMEOUT 300
#define BULK_TIMEOUT 0
#define EEPROM_ADDR 0xa0
enum usb_reg {
USB_SYSCTL = 0x2000,
USB_CTRL = 0x2010,
USB_STAT = 0x2014,
USB_EPA_CFG = 0x2144,
USB_EPA_CTL = 0x2148,
USB_SYSCTL = 0x2000,
USB_CTRL = 0x2010,
USB_STAT = 0x2014,
USB_EPA_CFG = 0x2144,
USB_EPA_CTL = 0x2148,
USB_EPA_MAXPKT = 0x2158,
USB_EPA_MAXPKT_2 = 0x215a,
USB_EPA_FIFO_CFG = 0x2160,
@ -381,10 +396,10 @@ enum usb_reg {
enum sys_reg {
DEMOD_CTL = 0x3000,
GPO = 0x3001,
GPI = 0x3002,
GPO = 0x3001,
GPI = 0x3002,
GPOE = 0x3003,
GPD = 0x3004,
GPD = 0x3004,
SYSINTE = 0x3005,
SYSINTS = 0x3006,
GP_CFG0 = 0x3007,
@ -446,7 +461,7 @@ enum blocks {
SYSB = 2,
TUNB = 3,
ROMB = 4,
IRB = 5,
IRB = 5,
IICB = 6,
};
@ -683,7 +698,7 @@ void rtlsdr_init_baseband(rtlsdr_dev_t *dev)
rtlsdr_demod_write_reg(dev, 1, 0x15, 0x00, 1);
rtlsdr_demod_write_reg(dev, 1, 0x16, 0x0000, 2);
/* clear both DDC shift and IF frequency registers */
/* clear both DDC shift and IF frequency registers */
for (i = 0; i < 6; i++)
rtlsdr_demod_write_reg(dev, 1, 0x16 + i, 0x00, 1);
@ -802,7 +817,7 @@ int rtlsdr_set_xtal_freq(rtlsdr_dev_t *dev, uint32_t rtl_freq, uint32_t tuner_fr
/* read corrected clock value into e4k and r82xx structure */
if (rtlsdr_get_xtal_freq(dev, NULL, &dev->e4k_s.vco.fosc) ||
rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal))
rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal))
return -3;
/* update xtal-dependent settings */
@ -830,7 +845,7 @@ int rtlsdr_get_xtal_freq(rtlsdr_dev_t *dev, uint32_t *rtl_freq, uint32_t *tuner_
}
int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product,
char *serial)
char *serial)
{
struct libusb_device_descriptor dd;
libusb_device *device = NULL;
@ -849,22 +864,22 @@ int rtlsdr_get_usb_strings(rtlsdr_dev_t *dev, char *manufact, char *product,
if (manufact) {
memset(manufact, 0, buf_max);
libusb_get_string_descriptor_ascii(dev->devh, dd.iManufacturer,
(unsigned char *)manufact,
buf_max);
(unsigned char *)manufact,
buf_max);
}
if (product) {
memset(product, 0, buf_max);
libusb_get_string_descriptor_ascii(dev->devh, dd.iProduct,
(unsigned char *)product,
buf_max);
(unsigned char *)product,
buf_max);
}
if (serial) {
memset(serial, 0, buf_max);
libusb_get_string_descriptor_ascii(dev->devh, dd.iSerialNumber,
(unsigned char *)serial,
buf_max);
(unsigned char *)serial,
buf_max);
}
return 0;
@ -980,7 +995,7 @@ int rtlsdr_set_freq_correction(rtlsdr_dev_t *dev, int ppm)
/* read corrected clock value into e4k and r82xx structure */
if (rtlsdr_get_xtal_freq(dev, NULL, &dev->e4k_s.vco.fosc) ||
rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal))
rtlsdr_get_xtal_freq(dev, NULL, &dev->r82xx_c.xtal))
return -3;
if (dev->freq) /* retune to apply new correction value */
@ -1009,16 +1024,16 @@ int rtlsdr_get_tuner_gains(rtlsdr_dev_t *dev, int *gains)
{
/* all gain values are expressed in tenths of a dB */
const int e4k_gains[] = { -10, 15, 40, 65, 90, 115, 140, 165, 190, 215,
240, 290, 340, 420 };
240, 290, 340, 420 };
const int fc0012_gains[] = { -99, -40, 71, 179, 192 };
const int fc0013_gains[] = { -99, -73, -65, -63, -60, -58, -54, 58, 61,
63, 65, 67, 68, 70, 71, 179, 181, 182,
184, 186, 188, 191, 197 };
63, 65, 67, 68, 70, 71, 179, 181, 182,
184, 186, 188, 191, 197 };
const int fc2580_gains[] = { 0 /* no gain values */ };
const int r82xx_gains[] = { 0, 9, 14, 27, 37, 77, 87, 125, 144, 157,
166, 197, 207, 229, 254, 280, 297, 328,
338, 364, 372, 386, 402, 421, 434, 439,
445, 480, 496 };
166, 197, 207, 229, 254, 280, 297, 328,
338, 364, 372, 386, 402, 421, 434, 439,
445, 480, 496 };
const int unknown_gains[] = { 0 /* no gain values */ };
const int *ptr = NULL;
@ -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)
@ -1150,7 +1204,7 @@ int rtlsdr_set_sample_rate(rtlsdr_dev_t *dev, uint32_t samp_rate)
/* check if the rate is supported by the resampler */
if ((samp_rate <= 225000) || (samp_rate > 3200000) ||
((samp_rate > 300000) && (samp_rate <= 900000))) {
((samp_rate > 300000) && (samp_rate <= 900000))) {
fprintf(stderr, "Invalid sample rate: %u Hz\n", samp_rate);
return -EINVAL;
}
@ -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);
}
@ -1250,7 +1305,7 @@ int rtlsdr_set_direct_sampling(rtlsdr_dev_t *dev, int on)
}
if ((dev->tuner_type == RTLSDR_TUNER_R820T) ||
(dev->tuner_type == RTLSDR_TUNER_R828D)) {
(dev->tuner_type == RTLSDR_TUNER_R828D)) {
r |= rtlsdr_set_if_freq(dev, R82XX_IF_FREQ);
/* enable spectrum inversion */
@ -1294,7 +1349,7 @@ int rtlsdr_set_offset_tuning(rtlsdr_dev_t *dev, int on)
return -1;
if ((dev->tuner_type == RTLSDR_TUNER_R820T) ||
(dev->tuner_type == RTLSDR_TUNER_R828D))
(dev->tuner_type == RTLSDR_TUNER_R828D))
return -2;
if (dev->direct_sampling)
@ -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);
@ -1411,7 +1471,7 @@ const char *rtlsdr_get_device_name(uint32_t index)
}
int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact,
char *product, char *serial)
char *product, char *serial)
{
int r = -2;
int i;
@ -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);
@ -1439,9 +1501,9 @@ int rtlsdr_get_device_usb_strings(uint32_t index, char *manufact,
r = libusb_open(list[i], &devt.devh);
if (!r) {
r = rtlsdr_get_usb_strings(&devt,
manufact,
product,
serial);
manufact,
product,
serial);
libusb_close(devt.devh);
}
break;
@ -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;
@ -1747,7 +1813,7 @@ static void LIBUSB_CALL _libusb_callback(struct libusb_transfer *xfer)
dev->xfer_errors++;
if (dev->xfer_errors >= dev->xfer_buf_num ||
LIBUSB_TRANSFER_NO_DEVICE == xfer->status) {
LIBUSB_TRANSFER_NO_DEVICE == xfer->status) {
#endif
dev->dev_lost = 1;
rtlsdr_cancel_async(dev);
@ -1773,7 +1839,7 @@ static int _rtlsdr_alloc_async_buffers(rtlsdr_dev_t *dev)
if (!dev->xfer) {
dev->xfer = malloc(dev->xfer_buf_num *
sizeof(struct libusb_transfer *));
sizeof(struct libusb_transfer *));
for(i = 0; i < dev->xfer_buf_num; ++i)
dev->xfer[i] = libusb_alloc_transfer(0);
@ -1781,7 +1847,7 @@ static int _rtlsdr_alloc_async_buffers(rtlsdr_dev_t *dev)
if (!dev->xfer_buf) {
dev->xfer_buf = malloc(dev->xfer_buf_num *
sizeof(unsigned char *));
sizeof(unsigned char *));
for(i = 0; i < dev->xfer_buf_num; ++i)
dev->xfer_buf[i] = malloc(dev->xfer_buf_len);
@ -1822,7 +1888,7 @@ static int _rtlsdr_free_async_buffers(rtlsdr_dev_t *dev)
}
int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx,
uint32_t buf_num, uint32_t buf_len)
uint32_t buf_num, uint32_t buf_len)
{
unsigned int i;
int r = 0;
@ -1856,13 +1922,13 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx,
for(i = 0; i < dev->xfer_buf_num; ++i) {
libusb_fill_bulk_transfer(dev->xfer[i],
dev->devh,
0x81,
dev->xfer_buf[i],
dev->xfer_buf_len,
_libusb_callback,
(void *)dev,
BULK_TIMEOUT);
dev->devh,
0x81,
dev->xfer_buf[i],
dev->xfer_buf_len,
_libusb_callback,
(void *)dev,
BULK_TIMEOUT);
r = libusb_submit_transfer(dev->xfer[i]);
if (r < 0) {
@ -1874,7 +1940,7 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx,
while (RTLSDR_INACTIVE != dev->async_status) {
r = libusb_handle_events_timeout_completed(dev->ctx, &tv,
&dev->async_cancel);
&dev->async_cancel);
if (r < 0) {
/*fprintf(stderr, "handle_events returned: %d\n", r);*/
if (r == LIBUSB_ERROR_INTERRUPTED) /* stray signal */
@ -1899,7 +1965,7 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx,
* to allow transfer status to
* propagate */
libusb_handle_events_timeout_completed(dev->ctx,
&zerotv, NULL);
&zerotv, NULL);
if (r < 0)
continue;
@ -1912,7 +1978,7 @@ int rtlsdr_read_async(rtlsdr_dev_t *dev, rtlsdr_read_async_cb_t cb, void *ctx,
* be handled before exiting after we
* just cancelled all transfers */
libusb_handle_events_timeout_completed(dev->ctx,
&zerotv, NULL);
&zerotv, NULL);
break;
}
}

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
@ -74,7 +76,7 @@ int quality = 10;
int allowed_errors = 5;
FILE *file;
int adsb_frame[14];
#define preamble_len 16
#define preamble_len 16
#define long_frame 112
#define short_frame 56

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
@ -29,23 +30,23 @@
* (no many-to-many locks)
*
* todo:
* sanity checks
* scale squelch to other input parameters
* test all the demodulations
* pad output on hop
* frequency ranges could be stored better
* scaled AM demod amplification
* auto-hop after time limit
* peak detector to tune onto stronger signals
* fifo for active hop frequency
* clips
* noise squelch
* merge stereo patch
* merge soft agc patch
* merge udp patch
* testmode to detect overruns
* watchdog to reset bad dongle
* fix oversampling
* sanity checks
* scale squelch to other input parameters
* test all the demodulations
* pad output on hop
* frequency ranges could be stored better
* scaled AM demod amplification
* auto-hop after time limit
* peak detector to tune onto stronger signals
* fifo for active hop frequency
* clips
* noise squelch
* merge stereo patch
* merge soft agc patch
* merge udp patch
* testmode to detect overruns
* watchdog to reset bad dongle
* fix oversampling
*/
#include <errno.h>
@ -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
@ -79,8 +80,8 @@
#define DEFAULT_BUF_LENGTH (1 * 16384)
#define MAXIMUM_OVERSAMPLE 16
#define MAXIMUM_BUF_LENGTH (MAXIMUM_OVERSAMPLE * DEFAULT_BUF_LENGTH)
#define AUTO_GAIN -100
#define BUFFER_DUMP 4096
#define AUTO_GAIN -100
#define BUFFER_DUMP 4096
#define FREQUENCIES_LIMIT 1000
@ -92,54 +93,63 @@ 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;
int exit_flag;
pthread_t thread;
rtlsdr_dev_t *dev;
int dev_index;
int dev_index;
uint32_t freq;
uint32_t rate;
int gain;
uint16_t buf16[MAXIMUM_BUF_LENGTH];
uint32_t bandwidth;
int gain;
int16_t buf16[MAXIMUM_BUF_LENGTH];
uint32_t buf_len;
int ppm_error;
int offset_tuning;
int direct_sampling;
int mute;
int ppm_error;
int offset_tuning;
int direct_sampling;
int mute;
struct demod_state *demod_target;
};
struct demod_state
{
int exit_flag;
int exit_flag;
pthread_t thread;
int16_t lowpassed[MAXIMUM_BUF_LENGTH];
int lp_len;
int lp_len;
int16_t lp_i_hist[10][6];
int16_t lp_q_hist[10][6];
int16_t result[MAXIMUM_BUF_LENGTH];
int16_t droop_i_hist[9];
int16_t droop_q_hist[9];
int result_len;
int rate_in;
int rate_out;
int rate_out2;
int now_r, now_j;
int pre_r, pre_j;
int prev_index;
int downsample; /* min 1, max 256 */
int post_downsample;
int output_scale;
int squelch_level, conseq_squelch, squelch_hits, terminate_on_squelch;
int downsample_passes;
int comp_fir_size;
int custom_atan;
int deemph, deemph_a;
int now_lpr;
int prev_lpr_index;
int dc_block, dc_avg;
void (*mode_demod)(struct demod_state*);
int result_len;
int rate_in;
int rate_out;
int rate_out2;
int now_r, now_j;
int pre_r, pre_j;
int prev_index;
int downsample; /* min 1, max 256 */
int post_downsample;
int output_scale;
int squelch_level, conseq_squelch, squelch_hits, terminate_on_squelch;
int downsample_passes;
int comp_fir_size;
int custom_atan;
int deemph, deemph_a;
int now_lpr;
int prev_lpr_index;
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;
pthread_mutex_t ready_m;
@ -148,13 +158,13 @@ struct demod_state
struct output_state
{
int exit_flag;
int exit_flag;
pthread_t thread;
FILE *file;
char *filename;
FILE *file;
char *filename;
int16_t result[MAXIMUM_BUF_LENGTH];
int result_len;
int rate;
int result_len;
int rate;
pthread_rwlock_t rw;
pthread_cond_t ready;
pthread_mutex_t ready_m;
@ -162,13 +172,13 @@ struct output_state
struct controller_state
{
int exit_flag;
int exit_flag;
pthread_t thread;
uint32_t freqs[FREQUENCIES_LIMIT];
int freq_len;
int freq_now;
int edge;
int wb_mode;
int freq_len;
int freq_now;
int edge;
int wb_mode;
pthread_cond_t hop;
pthread_mutex_t hop_m;
};
@ -185,35 +195,46 @@ void usage(void)
"rtl_fm, a simple narrow band FM demodulator for RTL2832 based DVB-T receivers\n\n"
"Use:\trtl_fm -f freq [-options] [filename]\n"
"\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 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 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 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 for fm squelch is inverted\n"
//"\t[-o oversampling (default: 1, 4 recommended)]\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[-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 deemp: enable de-emphasis filter\n"
"\t direct: enable direct sampling\n"
"\t offset: enable offset tuning\n"
"\t use multiple -E to enable multiple options\n"
"\t edge: enable lower edge tuning\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 (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"
"\t omitting the filename also uses stdout\n\n"
"Experimental options:\n"
"\t[-r resample_rate (default: none / same as -s)]\n"
"\t[-t squelch_delay (default: 10)]\n"
"\t +values will mute/scan, -values will exit\n"
"\t +values will mute/scan, -values will exit\n"
"\t[-F fir_size (default: off)]\n"
"\t enables low-leakage downsample filter\n"
"\t size can be 0 or 9. 0 has bad roll off\n"
"\t enables low-leakage downsample filter\n"
"\t size can be 0 or 9. 0 has bad roll off\n"
"\t[-A std/fast/lut choose atan math (default: std)]\n"
//"\t[-C clip_path (default: off)\n"
//"\t (create time stamped raw clips, requires squelch)\n"
@ -223,7 +244,7 @@ void usage(void)
"\n"
"Produces signed 16 bit ints, use Sox or aplay to hear them.\n"
"\trtl_fm ... | play -t raw -r 24k -es -b 16 -c 1 -V1 -\n"
"\t | aplay -r 24k -f S16_LE -t raw -c 1\n"
"\t | aplay -r 24k -f S16_LE -t raw -c 1\n"
"\t -M wbfm | play -r 32k ... \n"
"\t -s 22050 | multimon -t raw /dev/stdin\n\n");
exit(1);
@ -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] */
@ -401,7 +443,7 @@ void generic_fir(int16_t *data, int length, int *fir, int16_t *hist)
sum += (hist[1] + hist[7]) * fir[2];
sum += (hist[2] + hist[6]) * fir[3];
sum += (hist[3] + hist[5]) * fir[4];
sum += hist[4] * fir[5];
sum += hist[4] * fir[5];
data[d] = sum >> 15 ;
hist[0] = hist[1];
hist[1] = hist[2];
@ -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)
@ -960,17 +1073,22 @@ void demod_init(struct demod_state *s)
s->downsample_passes = 0;
s->comp_fir_size = 0;
s->prev_index = 0;
s->post_downsample = 1; // once this works, default = 4
s->post_downsample = 1; // once this works, default = 4
s->custom_atan = 0;
s->deemph = 0;
s->rate_out2 = -1; // flag for disabled
s->rate_out2 = -1; // flag for disabled
s->mode_demod = &fm_demod;
s->pre_j = s->pre_r = s->now_r = s->now_j = 0;
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
@ -69,8 +69,8 @@
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define DEFAULT_BUF_LENGTH (1 * 16384)
#define AUTO_GAIN -100
#define BUFFER_DUMP (1<<12)
#define AUTO_GAIN -100
#define BUFFER_DUMP (1<<12)
#define MAXIMUM_RATE 2800000
#define MINIMUM_RATE 1000000
@ -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 (num_queued > global_numq)
printf("ll+, now %d\n", num_queued);
else if (num_queued < global_numq)
printf("ll-, now %d\n", num_queued);
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

@ -48,7 +48,7 @@
#define MINIMAL_BUF_LENGTH 512
#define MAXIMAL_BUF_LENGTH (256 * 16384)
#define MHZ(x) ((x)*1000*1000)
#define MHZ(x) ((x)*1000*1000)
#define PPM_DURATION 10
#define PPM_DUMP_TIME 5

View File

@ -342,7 +342,7 @@ int e4k_if_filter_bw_get(struct e4k_state *e4k, enum e4k_if_filter filter)
#define E4K_FVCO_MIN_KHZ 2600000 /* 2.6 GHz */
#define E4K_FVCO_MAX_KHZ 3900000 /* 3.9 GHz */
#define E4K_PLL_Y 65536
#define E4K_PLL_Y 65536
#ifdef OUT_OF_SPEC
#define E4K_FLO_MIN_MHZ 50
@ -646,10 +646,10 @@ static const struct reg_field if_stage_gain_regs[] = {
static const int32_t lnagain[] = {
-50, 0,
-25, 1,
0, 4,
25, 5,
50, 6,
75, 7,
0, 4,
25, 5,
50, 6,
75, 7,
100, 8,
125, 9,
150, 10,

View File

@ -455,14 +455,14 @@ int fc0013_lna_gains[] ={
-60, 0x07,
-58, 0x01,
-54, 0x06,
58, 0x0f,
61, 0x0e,
63, 0x0d,
65, 0x0c,
67, 0x0b,
68, 0x0a,
70, 0x09,
71, 0x08,
58, 0x0f,
61, 0x0e,
63, 0x0d,
65, 0x0c,
67, 0x0b,
68, 0x0a,
70, 0x09,
71, 0x08,
179, 0x17,
181, 0x16,
182, 0x15,

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,14 +181,14 @@ 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;
unsigned char pre_shift_bits = 4;// number of preshift to prevent overflow in shifting f_diff to f_diff_shifted
unsigned char data_0x18;
unsigned char data_0x02 = (USE_EXT_CLK<<5)|0x0E;
fc2580_band_type band = ( f_lo > 1000000 )? FC2580_L_BAND : ( f_lo > 400000 )? FC2580_UHF_BAND : FC2580_VHF_BAND;
fc2580_fci_result_type result = FC2580_FCI_SUCCESS;
@ -208,19 +197,19 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne
r_val = ( f_vco >= 2*76*freq_xtal )? 1 : ( f_vco >= 76*freq_xtal )? 2 : 4;
f_comp = freq_xtal/r_val;
n_val = ( f_vco / 2 ) / f_comp;
f_diff = f_vco - 2* f_comp * n_val;
f_diff_shifted = f_diff << ( 20 - pre_shift_bits );
k_val = f_diff_shifted / ( ( 2* f_comp ) >> pre_shift_bits );
if( f_diff_shifted - k_val * ( ( 2* f_comp ) >> pre_shift_bits ) >= ( f_comp >> pre_shift_bits ) )
k_val = k_val + 1;
if( f_vco >= BORDER_FREQ ) //Select VCO Band
data_0x02 = data_0x02 | 0x08; //0x02[3] = 1;
else
data_0x02 = data_0x02 & 0xF7; //0x02[3] = 0;
// if( band != curr_band ) {
switch(band)
{
@ -237,7 +226,7 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne
if( f_lo < 538000 )
result &= fc2580_i2c_write(pTuner, 0x5F, 0x13);
else
else
result &= fc2580_i2c_write(pTuner, 0x5F, 0x15);
if( f_lo < 538000 )
@ -345,7 +334,7 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne
//A command about UHF LNA Load Cap
if( band == FC2580_UHF_BAND )
result &= fc2580_i2c_write(pTuner, 0x2D, ( f_lo <= (unsigned int)794000 )? 0x9F : 0x8F ); //LNA_OUT_CAP
return result;
}
@ -366,10 +355,10 @@ fc2580_fci_result_type fc2580_set_freq( void *pTuner, unsigned int f_lo, unsigne
6 : 6MHz (Bandwidth 6MHz)
7 : 6.8MHz (Bandwidth 7MHz)
8 : 7.8MHz (Bandwidth 8MHz)
==============================================================================*/
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;
@ -403,7 +392,7 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw,
result &= fc2580_i2c_write(pTuner, 0x2E, 0x09);
}
for(i=0; i<5; i++)
{
fc2580_wait_msec(pTuner, 5);//wait 5ms
@ -426,7 +415,7 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw,
fc2580 RSSI function
This function is a generic function which returns fc2580's
current RSSI value.
<input parameter>
@ -438,7 +427,7 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw,
==============================================================================*/
//int fc2580_get_rssi(void) {
//
//
// unsigned char s_lna, s_rfvga, s_cfs, s_ifvga;
// int ofs_lna, ofs_rfvga, ofs_csf, ofs_ifvga, rssi;
//
@ -446,9 +435,9 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw,
// fc2580_i2c_read(0x72, &s_rfvga );
// fc2580_i2c_read(0x73, &s_cfs );
// fc2580_i2c_read(0x74, &s_ifvga );
//
//
// ofs_lna =
//
// ofs_lna =
// (curr_band==FC2580_UHF_BAND)?
// (s_lna==0)? 0 :
// (s_lna==1)? -6 :
@ -470,18 +459,18 @@ fc2580_fci_result_type fc2580_set_filter( void *pTuner, unsigned char filter_bw,
// ofs_ifvga = s_ifvga/4;
//
// return rssi = ofs_lna+ofs_rfvga+ofs_csf+ofs_ifvga+OFS_RSSI;
//
//
//}
/*==============================================================================
fc2580 Xtal frequency Setting
This function is a generic function which sets
This function is a generic function which sets
the frequency of xtal.
<input parameter>
frequency
frequency value of internal(external) Xtal(clock) in kHz unit.

View File

@ -39,7 +39,7 @@
/* Those initial values start from REG_SHADOW_START */
static const uint8_t r82xx_init_array[NUM_REGS] = {
0x83, 0x32, 0x75, /* 05 to 07 */
0x83, 0x32, 0x75, /* 05 to 07 */
0xc0, 0x40, 0xd6, 0x6c, /* 08 to 0b */
0xf5, 0x63, 0x75, 0x68, /* 0c to 0f */
0x6c, 0x83, 0x80, 0x00, /* 10 to 13 */
@ -51,173 +51,173 @@ static const uint8_t r82xx_init_array[NUM_REGS] = {
/* Tuner frequency ranges */
static const struct r82xx_freq_range freq_ranges[] = {
{
/* .freq = */ 0, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .freq = */ 0, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0xdf, /* R27[7:0] band2,band0 */
/* .tf_c = */ 0xdf, /* R27[7:0] band2,band0 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 50, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .freq = */ 50, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0xbe, /* R27[7:0] band4,band1 */
/* .tf_c = */ 0xbe, /* R27[7:0] band4,band1 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 55, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .freq = */ 55, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x8b, /* R27[7:0] band7,band4 */
/* .tf_c = */ 0x8b, /* R27[7:0] band7,band4 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 60, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .freq = */ 60, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x7b, /* R27[7:0] band8,band4 */
/* .tf_c = */ 0x7b, /* R27[7:0] band8,band4 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 65, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .freq = */ 65, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x69, /* R27[7:0] band9,band6 */
/* .tf_c = */ 0x69, /* R27[7:0] band9,band6 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 70, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .freq = */ 70, /* Start freq, in MHz */
/* .open_d = */ 0x08, /* low */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x58, /* R27[7:0] band10,band7 */
/* .tf_c = */ 0x58, /* R27[7:0] band10,band7 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 75, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 75, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */
/* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 80, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 80, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */
/* .tf_c = */ 0x44, /* R27[7:0] band11,band11 */
/* .xtal_cap20p = */ 0x02, /* R16[1:0] 20pF (10) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 90, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 90, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */
/* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */
/* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 100, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 100, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */
/* .tf_c = */ 0x34, /* R27[7:0] band12,band11 */
/* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 110, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 110, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */
/* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */
/* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 120, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 120, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */
/* .tf_c = */ 0x24, /* R27[7:0] band13,band11 */
/* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 140, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 140, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x14, /* R27[7:0] band14,band11 */
/* .tf_c = */ 0x14, /* R27[7:0] band14,band11 */
/* .xtal_cap20p = */ 0x01, /* R16[1:0] 10pF (01) */
/* .xtal_cap10p = */ 0x01,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 180, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 180, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */
/* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 220, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 220, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */
/* .tf_c = */ 0x13, /* R27[7:0] band14,band12 */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 250, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 250, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x11, /* R27[7:0] highest,highest */
/* .tf_c = */ 0x11, /* R27[7:0] highest,highest */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 280, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 280, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x02, /* R26[7:6]=0 (LPF) R26[1:0]=2 (low) */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 310, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 310, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x41, /* R26[7:6]=1 (bypass) R26[1:0]=1 (middle) */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 450, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 450, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x41, /* R26[7:6]=1 (bypass) R26[1:0]=1 (middle) */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 588, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 588, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x40, /* R26[7:6]=1 (bypass) R26[1:0]=0 (highest) */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}, {
/* .freq = */ 650, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .freq = */ 650, /* Start freq, in MHz */
/* .open_d = */ 0x00, /* high */
/* .rf_mux_ploy = */ 0x40, /* R26[7:6]=1 (bypass) R26[1:0]=0 (highest) */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .tf_c = */ 0x00, /* R27[7:0] highest,highest */
/* .xtal_cap20p = */ 0x00, /* R16[1:0] 0pF (00) */
/* .xtal_cap10p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
/* .xtal_cap0p = */ 0x00,
}
};
@ -250,7 +250,7 @@ static void shadow_store(struct r82xx_priv *priv, uint8_t reg, const uint8_t *va
}
static int r82xx_write(struct r82xx_priv *priv, uint8_t reg, const uint8_t *val,
unsigned int len)
unsigned int len)
{
int rc, size, pos = 0;
@ -561,8 +561,8 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
}
static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
enum r82xx_tuner_type type,
uint32_t delsys)
enum r82xx_tuner_type type,
uint32_t delsys)
{
int rc;
uint8_t mixer_top, lna_top, cp_cur, div_buf_cur, lna_vth_l, mixer_vth_l;
@ -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,27 +1197,35 @@ 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;
priv->int_freq = 4570000;
if (apply)
priv->int_freq = 4570000;
} else if (bw > 6000000) {
// BW: 7 MHz
*applied_bw = 7000000;
reg_0a = 0x10;
reg_0b = 0x2a;
priv->int_freq = 4570000;
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;
priv->int_freq = 3570000;
if (apply)
priv->int_freq = 3570000;
} else {
reg_0a = 0x00;
reg_0b = 0x80;
priv->int_freq = 2300000;
if (apply)
priv->int_freq = 2300000;
if (bw > r82xx_if_low_pass_bw_table[0] + FILT_HP_BW1) {
bw -= FILT_HP_BW2;
priv->int_freq += FILT_HP_BW2;
if (apply)
priv->int_freq += FILT_HP_BW2;
real_bw += FILT_HP_BW2;
} else {
reg_0b |= 0x20;
@ -1118,7 +1233,8 @@ 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;
priv->int_freq += FILT_HP_BW1;
if (apply)
priv->int_freq += FILT_HP_BW1;
real_bw += FILT_HP_BW1;
} else {
reg_0b |= 0x40;
@ -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];
priv->int_freq -= real_bw / 2;
*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;
@ -1170,7 +1292,7 @@ int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq)
air_cable1_in = (freq > MHZ(345)) ? 0x00 : 0x60;
if ((priv->cfg->rafael_chip == CHIP_R828D) &&
(air_cable1_in != priv->input)) {
(air_cable1_in != priv->input)) {
priv->input = air_cable1_in;
rc = r82xx_write_reg_mask(priv, 0x05, air_cable1_in, 0x60);
}

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