mirror of https://github.com/drowe67/librtlsdr.git
merge of great additions, e.g. rtlsdr_set_tuner_sideband()
* rtlsdr_set_tuner_sideband(): - "HF-Hase" Bernhard Kistinger (DB9PP) found out, that one of the undocumented I2C register bits of R820T tuner controls the used tuner/mixer lower or supper sideband. That was by testing/playing with a special QIRX version, showing and allowing change of all I2C registers. - previous additions in rtl_tcp allowed control of I2C registers; in addition register contents can be transmitted periodically (to QIRX) - "Oldenburger" developed a first version controlling the sideband bit, and additional spectral flipping (spectrum inversion) in the RTL2832 - i've merged Oldenburger's changes with my rtlsdr_set_tuner_band_center() => altogether, there's no spectrum inversion, the band center stays, just the IF filters (steep lowpass and not-so-steep highpass) switch positions * Oldenburger's changes for FC0012 tuner * Oldenburger added description of R820T's I2C registers * rtl_tcp's new response channel now occupies an additional port, usally 1235, which is +1 of default control port. this can be deactivated by command line Signed-off-by: hayati ayguen <h_ayguen@web.de>development
parent
75f97e566d
commit
22a920d0a6
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver
|
||||
* Copyright (C) 2019 <>
|
||||
*
|
||||
* 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_CONTROL_THREAD_H
|
||||
#define __RTL_CONTROL_THREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
rtlsdr_dev_t *dev;
|
||||
SOCKET port;
|
||||
int wait;
|
||||
int report_i2c;
|
||||
char *addr;
|
||||
int* pDoExit;
|
||||
}
|
||||
ctrl_thread_data_t;
|
||||
void *ctrl_thread_fn(void *arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -253,6 +253,15 @@ RTLSDR_API int rtlsdr_set_tuner_bandwidth(rtlsdr_dev_t *dev, uint32_t bw );
|
|||
*/
|
||||
RTLSDR_API int rtlsdr_set_tuner_band_center(rtlsdr_dev_t *dev, int32_t if_band_center_freq );
|
||||
|
||||
/*!
|
||||
* Set the mixer sideband for the device.
|
||||
*
|
||||
* \param dev the device handle given by rtlsdr_open()
|
||||
* \param sideband mixer sideband 0 means lower sideband, 1 means upper sideband.
|
||||
* \return 0 on success
|
||||
*/
|
||||
RTLSDR_API int rtlsdr_set_tuner_sideband(rtlsdr_dev_t *dev, int sideband);
|
||||
|
||||
/*!
|
||||
* Get actual gain the device is configured to.
|
||||
*
|
||||
|
|
|
@ -65,6 +65,9 @@ enum RTL_TCP_COMMANDS {
|
|||
* the bandwidth (from SET_TUNER_BANDWIDTH)
|
||||
* is set to be centered at given IF frequency */
|
||||
SET_TUNER_AGC_VARIANT = 0x46, /* set tuner agc algorithm/variant */
|
||||
SET_SIDEBAND = 0x47, /* Mixer Sideband for R820T */
|
||||
REPORT_I2C_REGS = 0x48, /* perodically report I2C registers
|
||||
* - if reverse channel is enabled */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -32,5 +32,7 @@
|
|||
int fc0012_init(void *dev);
|
||||
int fc0012_set_params(void *dev, uint32_t freq, uint32_t bandwidth);
|
||||
int fc0012_set_gain(void *dev, int gain);
|
||||
int fc0012_set_i2c_register(void *dev, unsigned i2c_register, unsigned data);
|
||||
int fc0012_get_i2c_register(void *dev, unsigned char* data, int len);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define R82XX_IF_FREQ 3570000
|
||||
|
||||
#define REG_SHADOW_START 5
|
||||
#define NUM_REGS 30
|
||||
#define NUM_REGS 32
|
||||
#define NUM_IMR 5
|
||||
#define IMR_TRIAL 9
|
||||
|
||||
|
@ -89,6 +89,7 @@ struct r82xx_priv {
|
|||
uint8_t input;
|
||||
int has_lock;
|
||||
int init_done;
|
||||
int sideband;
|
||||
|
||||
/* Store current mode */
|
||||
uint32_t delsys;
|
||||
|
@ -140,14 +141,17 @@ 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_gain(struct r82xx_priv *priv, int set_manual_gain, int gain, int extended_mode, int lna_gain, int mixer_gain, int vga_gain, int *rtl_vga_control);
|
||||
int r82xx_set_agc_mode(struct r82xx_priv *priv, int agc_mode, int *rtl_vga_control);
|
||||
|
||||
int r82xx_set_i2c_register(struct r82xx_priv *priv, unsigned i2c_register, unsigned data, unsigned mask);
|
||||
int r82xx_get_i2c_register(struct r82xx_priv *priv, unsigned char* data, int len);
|
||||
int r82xx_set_i2c_override(struct r82xx_priv *priv, unsigned i2c_register, unsigned data, unsigned mask);
|
||||
|
||||
int r82xx_set_bandwidth(struct r82xx_priv *priv, int bandwidth, uint32_t rate, uint32_t * applied_bw, int apply);
|
||||
int r82xx_set_bw_center(struct r82xx_priv *priv, int32_t if_band_center_freq);
|
||||
/* Mixer Sideband: 0: lower, 1: upper */
|
||||
int r82xx_set_sideband(struct r82xx_priv *priv, int sideband);
|
||||
|
||||
int r82xx_read_cache_reg(struct r82xx_priv *priv, int reg);
|
||||
int r82xx_write_reg_mask(struct r82xx_priv *priv, uint8_t reg, uint8_t val,uint8_t bit_mask);
|
||||
|
|
|
@ -119,7 +119,7 @@ endif()
|
|||
# Build utility
|
||||
########################################################################
|
||||
add_executable(rtl_sdr rtl_sdr.c)
|
||||
add_executable(rtl_tcp rtl_tcp.c)
|
||||
add_executable(rtl_tcp rtl_tcp.c controlThread.c)
|
||||
add_executable(rtl_udp rtl_udp.c)
|
||||
add_executable(rtl_test rtl_test.c)
|
||||
add_executable(rtl_fm rtl_fm.c)
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* rtl-sdr, turns your Realtek RTL2832 based DVB dongle into a SDR receiver
|
||||
* Copyright (C) 2012 by Steve Markgraf <steve@steve-m.de>
|
||||
* Copyright (C) 2012-2013 by Hoernchen <la@tfc-server.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
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#include "getopt/getopt.h"
|
||||
#define usleep(x) Sleep(x/1000)
|
||||
#endif
|
||||
|
||||
#ifdef NEED_PTHREADS_WORKARROUND
|
||||
#define HAVE_STRUCT_TIMESPEC
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
|
||||
#include "rtl-sdr.h"
|
||||
#include "rtl_tcp.h"
|
||||
#include "controlThread.h"
|
||||
#include "convenience/convenience.h"
|
||||
|
||||
#include "tuner_r82xx.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
|
||||
typedef int socklen_t;
|
||||
|
||||
#else
|
||||
#define closesocket close
|
||||
#define SOCKADDR struct sockaddr
|
||||
#define SOCKET int
|
||||
#define SOCKET_ERROR -1
|
||||
#endif
|
||||
|
||||
/* we need a message id in the protocol: 1st 2 byte (little endian) == message id */
|
||||
#define USE_MSGID_IN_PROTOCOL 1
|
||||
|
||||
#define NUM_I2C_REGISTERS 32
|
||||
#define TX_BUF_LEN (NUM_I2C_REGISTERS +4) //2 len, 1 head, 1 tail
|
||||
|
||||
|
||||
ctrl_thread_data_t ctrl_thread_data;
|
||||
|
||||
void *ctrl_thread_fn(void *arg)
|
||||
{
|
||||
unsigned char reg_values [NUM_I2C_REGISTERS];
|
||||
#if USE_MSGID_IN_PROTOCOL
|
||||
unsigned char txbuf [2+2 +1+NUM_I2C_REGISTERS+1]; //2 type, 2 length, 1 head, 1 tail
|
||||
#else
|
||||
unsigned char txbuf [NUM_I2C_REGISTERS+4]; //2 length, 1 head, 1 tail
|
||||
#endif
|
||||
int r = 1;
|
||||
struct timeval tv = { 1,0 };
|
||||
struct linger ling = { 1,0 };
|
||||
SOCKET listensocket;
|
||||
SOCKET controlSocket;
|
||||
struct sockaddr_in local, remote;
|
||||
socklen_t rlen;
|
||||
|
||||
int error = 0;
|
||||
int ret = 0, len, result;
|
||||
fd_set connfds;
|
||||
fd_set writefds;
|
||||
int bytesleft, bytessent, index;
|
||||
|
||||
ctrl_thread_data_t *data = (ctrl_thread_data_t *)arg;
|
||||
|
||||
rtlsdr_dev_t *dev = data->dev;
|
||||
int port = data->port;
|
||||
int wait = data->wait;
|
||||
int report_i2c = data->report_i2c;
|
||||
char *addr = data->addr;
|
||||
int* do_exit = data->pDoExit;
|
||||
u_long blockmode = 1;
|
||||
|
||||
|
||||
memset(reg_values, 0, NUM_I2C_REGISTERS);
|
||||
|
||||
memset(&local, 0, sizeof(local));
|
||||
local.sin_family = AF_INET;
|
||||
local.sin_port = htons(port);
|
||||
local.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
listensocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
setsockopt(listensocket, SOL_SOCKET, SO_REUSEADDR, (char *)&r, sizeof(int));
|
||||
setsockopt(listensocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
|
||||
int retval = bind(listensocket, (struct sockaddr *)&local, sizeof(local));
|
||||
if (retval == SOCKET_ERROR)
|
||||
error = WSAGetLastError();
|
||||
#ifdef _WIN32
|
||||
ioctlsocket(listensocket, FIONBIO, &blockmode);
|
||||
#else
|
||||
r = fcntl(listensocket, F_GETFL, 0);
|
||||
r = fcntl(listensocket, F_SETFL, r | O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
printf("listening on Control port %d...\n", port);
|
||||
retval = listen(listensocket, 1);
|
||||
if (retval == SOCKET_ERROR)
|
||||
#ifdef _WIN32
|
||||
error = WSAGetLastError();
|
||||
#else
|
||||
;
|
||||
#endif
|
||||
while (1) {
|
||||
FD_ZERO(&connfds);
|
||||
FD_SET(listensocket, &connfds);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
r = select(listensocket + 1, &connfds, NULL, NULL, &tv);
|
||||
if (*do_exit) {
|
||||
goto close;
|
||||
}
|
||||
else if (r) {
|
||||
rlen = sizeof(remote);
|
||||
controlSocket = accept(listensocket, (struct sockaddr *)&remote, &rlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
setsockopt(controlSocket, SOL_SOCKET, SO_LINGER, (char *)&ling, sizeof(ling));
|
||||
|
||||
printf("Control client accepted!\n");
|
||||
usleep(5000000);
|
||||
|
||||
while (1) {
|
||||
|
||||
/* check if i2c reporting is to be (de)activated */
|
||||
if ( report_i2c && !data->report_i2c )
|
||||
report_i2c = 0;
|
||||
else if ( !report_i2c && data->report_i2c )
|
||||
report_i2c = 1;
|
||||
|
||||
/* @TODO: check if something else has to be transmitted */
|
||||
|
||||
if ( !report_i2c )
|
||||
goto sleep;
|
||||
|
||||
result = rtlsdr_get_tuner_i2c_register(dev, reg_values, NUM_I2C_REGISTERS);
|
||||
/* printf("rtlsdr_get_tuner_i2c_register\n"); */
|
||||
memset(txbuf, 0, TX_BUF_LEN);
|
||||
if (result)
|
||||
goto sleep;
|
||||
|
||||
/* Little Endian */
|
||||
len = 0;
|
||||
/* we need some message id: use enum RTL_TCP_COMMANDS */
|
||||
#if USE_MSGID_IN_PROTOCOL
|
||||
txbuf[len++] = REPORT_I2C_REGS & 0x0FF;
|
||||
txbuf[len++] = (REPORT_I2C_REGS >> 8) & 0x0FF;
|
||||
/* following message length in Little Endian */
|
||||
txbuf[len++] = TX_BUF_LEN - 2 - 2; /* sub message id and length field */
|
||||
#else
|
||||
txbuf[len++] = TX_BUF_LEN - 2; /* sub message id and length field */
|
||||
#endif
|
||||
txbuf[len++] = 0;
|
||||
|
||||
/* now the message contents */
|
||||
txbuf[len++] = 0x55; /* @CS: do we need this? */
|
||||
memcpy(&txbuf[len], reg_values, NUM_I2C_REGISTERS);
|
||||
txbuf[TX_BUF_LEN - 1] = 0xaa; /* @CS: do we need this? */
|
||||
len = sizeof(txbuf);
|
||||
|
||||
/* now start (possibly blocking) transmission */
|
||||
bytessent = 0;
|
||||
bytesleft = len;
|
||||
index = 0;
|
||||
|
||||
while (bytesleft > 0) {
|
||||
FD_ZERO(&writefds);
|
||||
FD_SET(controlSocket, &writefds);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
r = select(controlSocket + 1, NULL, &writefds, NULL, &tv);
|
||||
if (r) {
|
||||
bytessent = send(controlSocket, &txbuf[index], bytesleft, 0);
|
||||
bytesleft -= bytessent;
|
||||
index += bytessent;
|
||||
}
|
||||
if (bytessent == SOCKET_ERROR || *do_exit) {
|
||||
goto close;
|
||||
}
|
||||
}
|
||||
sleep:
|
||||
usleep(wait);
|
||||
}
|
||||
close:
|
||||
closesocket(controlSocket);
|
||||
if (*do_exit)
|
||||
{
|
||||
closesocket(listensocket);
|
||||
printf("Control Thread terminates\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
270
src/librtlsdr.c
270
src/librtlsdr.c
|
@ -107,7 +107,9 @@ typedef struct rtlsdr_tuner_iface {
|
|||
int (*set_gain_mode)(void *, int manual);
|
||||
int (*set_i2c_register)(void *, unsigned i2c_register, unsigned data /* byte */, unsigned mask /* byte */ );
|
||||
int (*set_i2c_override)(void *, unsigned i2c_register, unsigned data /* byte */, unsigned mask /* byte */ );
|
||||
unsigned (*get_i2c_register)(void *, int i2c_register);
|
||||
unsigned (*get_i2c_register)(void *, int i2c_register); /* read single register */
|
||||
int (*get_i2c_reg_array)(void *, unsigned char* data, int len); /* -cs- */
|
||||
int (*set_sideband)(void *, int sideband);
|
||||
} rtlsdr_tuner_iface_t;
|
||||
|
||||
enum rtlsdr_async_status {
|
||||
|
@ -206,6 +208,8 @@ struct rtlsdr_dev {
|
|||
uint32_t bw;
|
||||
uint32_t offs_freq; /* Hz */
|
||||
int32_t if_band_center_freq; /* Hz - rtlsdr_set_tuner_band_center() */
|
||||
int tuner_if_freq;
|
||||
int tuner_sideband;
|
||||
int corr; /* ppm */
|
||||
int gain; /* tenth dB */
|
||||
enum rtlsdr_ds_mode direct_sampling_mode;
|
||||
|
@ -216,6 +220,9 @@ struct rtlsdr_dev {
|
|||
/* soft tuner agc */
|
||||
struct softagc_state softagc;
|
||||
|
||||
/* -cs- Concurrent lock for the periodic reading of I2C registers */
|
||||
pthread_mutex_t cs_mutex;
|
||||
|
||||
/* UDP controller server */
|
||||
#ifdef WITH_UDP_SERVER
|
||||
#define UDP_TX_BUFLEN 1024
|
||||
|
@ -241,14 +248,13 @@ struct rtlsdr_dev {
|
|||
int rc_active;
|
||||
int verbose;
|
||||
int dev_num;
|
||||
uint8_t saved_27;
|
||||
int handled;
|
||||
};
|
||||
|
||||
void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
|
||||
static void rtlsdr_set_gpio_bit(rtlsdr_dev_t *dev, uint8_t gpio, int val);
|
||||
static int rtlsdr_demod_write_reg(rtlsdr_dev_t *dev, uint8_t page, uint16_t addr, uint16_t val, uint8_t len);
|
||||
static int rtlsdr_set_if_freq(rtlsdr_dev_t *dev, uint32_t freq);
|
||||
static int rtlsdr_update_ds(rtlsdr_dev_t *dev, uint32_t freq);
|
||||
static int rtlsdr_set_spectrum_inversion(rtlsdr_dev_t *dev, int sideband);
|
||||
|
||||
static void softagc_init(rtlsdr_dev_t *dev);
|
||||
static void softagc_uninit(rtlsdr_dev_t *dev);
|
||||
|
@ -310,7 +316,6 @@ int e4000_set_gain_mode(void *dev, int manual) {
|
|||
return e4k_enable_manual_gain(&devt->e4k_s, manual);
|
||||
}
|
||||
|
||||
int _fc0012_init(void *dev) { return fc0012_init(dev); }
|
||||
int fc0012_exit(void *dev) { return 0; }
|
||||
int fc0012_set_freq(void *dev, uint32_t freq) {
|
||||
/* select V-band/U-band filter */
|
||||
|
@ -318,8 +323,10 @@ int fc0012_set_freq(void *dev, uint32_t freq) {
|
|||
return fc0012_set_params(dev, freq, 6000000);
|
||||
}
|
||||
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; }
|
||||
int _fc0012_set_i2c_register(void *dev, unsigned i2c_register, unsigned data, unsigned mask ) {
|
||||
return fc0012_set_i2c_register(dev, i2c_register, data);
|
||||
}
|
||||
|
||||
int _fc0013_init(void *dev) { return fc0013_init(dev); }
|
||||
int fc0013_exit(void *dev) { return 0; }
|
||||
|
@ -372,7 +379,6 @@ int r820t_set_freq(void *dev, uint32_t freq) {
|
|||
return r82xx_set_freq(&devt->r82xx_p, freq);
|
||||
}
|
||||
|
||||
#define BWC_MUL_SIGN +
|
||||
|
||||
int r820t_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) {
|
||||
int r, iffreq;
|
||||
|
@ -383,15 +389,27 @@ int r820t_set_bw(void *dev, int bw, uint32_t *applied_bw, int apply) {
|
|||
return 0;
|
||||
if(iffreq < 0) {
|
||||
r = iffreq;
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_bw(%d): r82xx_set_bandwidth() returned error %d\n", bw, r);
|
||||
return r;
|
||||
}
|
||||
devt->tuner_if_freq = iffreq;
|
||||
|
||||
iffreq = (devt->tuner_sideband) /* -1 for USB; +1 for LSB */
|
||||
? ( devt->tuner_if_freq - devt->if_band_center_freq )
|
||||
: ( devt->tuner_if_freq + devt->if_band_center_freq );
|
||||
r = rtlsdr_set_if_freq(devt, iffreq );
|
||||
if (r)
|
||||
{
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_bw(%d): rtlsdr_set_if_freq(%d) returned error %d\n", bw, iffreq, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
iffreq = iffreq BWC_MUL_SIGN devt->if_band_center_freq;
|
||||
r = rtlsdr_set_if_freq(devt, iffreq );
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return rtlsdr_set_center_freq(devt, devt->freq);
|
||||
r = rtlsdr_set_center_freq(devt, devt->freq);
|
||||
if ( r && devt->verbose )
|
||||
fprintf(stderr, "r820t_set_bw(%d): rtlsdr_set_center_freq(%d) returned error %d\n", bw, devt->freq, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
int r820t_set_bw_center(void *dev, int32_t if_band_center_freq) {
|
||||
|
@ -401,16 +419,28 @@ int r820t_set_bw_center(void *dev, int32_t if_band_center_freq) {
|
|||
iffreq = r82xx_set_bw_center(&devt->r82xx_p, if_band_center_freq);
|
||||
if(iffreq < 0) {
|
||||
r = iffreq;
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_bw_center(%d): r82xx_set_bw_center() returned error %d\n", if_band_center_freq, r);
|
||||
return r;
|
||||
}
|
||||
devt->tuner_if_freq = iffreq;
|
||||
devt->if_band_center_freq = if_band_center_freq;
|
||||
|
||||
iffreq = (devt->tuner_sideband) /* -1 for USB; +1 for LSB */
|
||||
? ( devt->tuner_if_freq - devt->if_band_center_freq )
|
||||
: ( devt->tuner_if_freq + devt->if_band_center_freq );
|
||||
r = rtlsdr_set_if_freq(devt, iffreq );
|
||||
if (r)
|
||||
{
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_bw_center(%d): rtlsdr_set_if_freq(%d) returned error %d\n", if_band_center_freq, iffreq, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
devt->if_band_center_freq = if_band_center_freq;
|
||||
iffreq = iffreq BWC_MUL_SIGN devt->if_band_center_freq;
|
||||
r = rtlsdr_set_if_freq(devt, iffreq );
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return rtlsdr_set_center_freq(devt, devt->freq);
|
||||
r = rtlsdr_set_center_freq(devt, devt->freq);
|
||||
if ( r && devt->verbose )
|
||||
fprintf(stderr, "r820t_set_bw_center(%d): rtlsdr_set_center_freq(%d) returned error %d\n", if_band_center_freq, devt->freq, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtlsdr_vga_control( rtlsdr_dev_t* devt, int rc, int rtl_vga_control ) {
|
||||
|
@ -469,6 +499,49 @@ int r820t_set_i2c_register(void *dev, unsigned i2c_register, unsigned data, unsi
|
|||
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
|
||||
return r82xx_set_i2c_register(&devt->r82xx_p, i2c_register, data, mask);
|
||||
}
|
||||
|
||||
|
||||
/* -cs- */
|
||||
int r820t_get_i2c_reg_array(void *dev, unsigned char* data, int len) {
|
||||
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
|
||||
return r82xx_get_i2c_register(&devt->r82xx_p, data, len);
|
||||
}
|
||||
|
||||
int r820t_set_sideband(void *dev, int sideband) {
|
||||
int r;
|
||||
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
|
||||
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_sideband(%d): r82xx_set_sideband() ..\n", sideband);
|
||||
r = r82xx_set_sideband(&devt->r82xx_p, sideband);
|
||||
if(r < 0) {
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_sideband(%d): r82xx_set_sideband() returned %d\n", sideband, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_sideband(%d): rtlsdr_set_spectrum_inversion() ..\n", sideband);
|
||||
r = rtlsdr_set_spectrum_inversion(devt, sideband);
|
||||
if (r) {
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_sideband(%d): rtlsdr_set_spectrum_inversion() returned %d\n", sideband, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!devt->freq)
|
||||
return r;
|
||||
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_sideband(%d): rtlsdr_set_center_freq(%d) ..\n", sideband, devt->freq);
|
||||
r = rtlsdr_set_center_freq(devt, devt->freq);
|
||||
if (r) {
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "r820t_set_sideband(%d): rtlsdr_set_center_freq(%d) returned %d\n", sideband, devt->freq, r);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
int r820t_set_i2c_override(void *dev, unsigned i2c_register, unsigned data, unsigned mask ) {
|
||||
rtlsdr_dev_t* devt = (rtlsdr_dev_t*)dev;
|
||||
return r82xx_set_i2c_override(&devt->r82xx_p, i2c_register, data, mask);
|
||||
|
@ -478,37 +551,40 @@ int r820t_set_i2c_override(void *dev, unsigned i2c_register, unsigned data, unsi
|
|||
/* definition order must match enum rtlsdr_tuner */
|
||||
static rtlsdr_tuner_iface_t tuners[] = {
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL /* dummy for unknown tuners */
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL /* dummy for unknown tuners */
|
||||
},
|
||||
{
|
||||
e4000_init, e4000_exit,
|
||||
e4000_set_freq, e4000_set_bw, NULL, e4000_set_gain, e4000_set_if_gain,
|
||||
e4000_set_gain_mode, NULL, NULL, NULL
|
||||
e4000_set_gain_mode, NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
|
||||
{
|
||||
_fc0012_init, fc0012_exit,
|
||||
fc0012_set_freq, fc0012_set_bw, NULL, _fc0012_set_gain, NULL,
|
||||
fc0012_set_gain_mode, NULL, NULL, NULL
|
||||
fc0012_init, fc0012_exit,
|
||||
fc0012_set_freq, fc0012_set_bw, NULL, fc0012_set_gain, NULL,
|
||||
fc0012_set_gain_mode, _fc0012_set_i2c_register, NULL, NULL, fc0012_get_i2c_register, NULL
|
||||
},
|
||||
{
|
||||
_fc0013_init, fc0013_exit,
|
||||
fc0013_set_freq, fc0013_set_bw, NULL, _fc0013_set_gain, NULL,
|
||||
fc0013_set_gain_mode, NULL, NULL, NULL
|
||||
fc0013_set_gain_mode, NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
fc2580_init, fc2580_exit,
|
||||
_fc2580_set_freq, fc2580_set_bw, NULL, fc2580_set_gain, NULL,
|
||||
fc2580_set_gain_mode, NULL, NULL, NULL
|
||||
fc2580_set_gain_mode, NULL, NULL, NULL, NULL, NULL
|
||||
},
|
||||
{
|
||||
r820t_init, r820t_exit,
|
||||
r820t_set_freq, r820t_set_bw, r820t_set_bw_center, r820t_set_gain, NULL,
|
||||
r820t_set_gain_mode, r820t_set_i2c_register, r820t_set_i2c_override, r820t_get_i2c_register
|
||||
r820t_set_gain_mode, r820t_set_i2c_register, r820t_set_i2c_override, r820t_get_i2c_register, r820t_get_i2c_reg_array,
|
||||
r820t_set_sideband
|
||||
},
|
||||
{
|
||||
r820t_init, r820t_exit,
|
||||
r820t_set_freq, r820t_set_bw, r820t_set_bw_center, r820t_set_gain, NULL,
|
||||
r820t_set_gain_mode, r820t_set_i2c_register, r820t_set_i2c_override, r820t_get_i2c_register
|
||||
r820t_set_gain_mode, r820t_set_i2c_register, r820t_set_i2c_override, r820t_get_i2c_register, r820t_get_i2c_reg_array,
|
||||
r820t_set_sideband
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -848,7 +924,13 @@ void rtlsdr_set_gpio_output(rtlsdr_dev_t *dev, uint8_t gpio)
|
|||
|
||||
void rtlsdr_set_i2c_repeater(rtlsdr_dev_t *dev, int on)
|
||||
{
|
||||
if (on)
|
||||
pthread_mutex_lock(&dev->cs_mutex);
|
||||
|
||||
rtlsdr_demod_write_reg(dev, 1, 0x01, on ? 0x18 : 0x10, 1);
|
||||
|
||||
if (!on)
|
||||
pthread_mutex_unlock(&dev->cs_mutex);
|
||||
}
|
||||
|
||||
int rtlsdr_set_fir(rtlsdr_dev_t *dev)
|
||||
|
@ -996,6 +1078,18 @@ static int rtlsdr_set_if_freq(rtlsdr_dev_t *dev, uint32_t freq)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int rtlsdr_set_spectrum_inversion(rtlsdr_dev_t *dev, int sideband)
|
||||
{
|
||||
int r;
|
||||
if(sideband)
|
||||
/* disable spectrum inversion */
|
||||
r = rtlsdr_demod_write_reg(dev, 1, 0x15, 0x00, 1);
|
||||
else
|
||||
/* enable spectrum inversion */
|
||||
r = rtlsdr_demod_write_reg(dev, 1, 0x15, 0x01, 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtlsdr_set_sample_freq_correction(rtlsdr_dev_t *dev, int ppm)
|
||||
{
|
||||
int r = 0;
|
||||
|
@ -1223,7 +1317,6 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
|
|||
rtlsdr_set_i2c_repeater(dev, 1);
|
||||
r = dev->tuner->set_freq(dev, freq - dev->offs_freq);
|
||||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
reactivate_softagc(dev, SOFTSTATE_RESET);
|
||||
}
|
||||
|
||||
if (!r)
|
||||
|
@ -1231,13 +1324,6 @@ int rtlsdr_set_center_freq(rtlsdr_dev_t *dev, uint32_t freq)
|
|||
else
|
||||
dev->freq = 0;
|
||||
|
||||
/* restore filters */
|
||||
if (dev->handled) {
|
||||
rtlsdr_set_i2c_repeater(dev, 1);
|
||||
dev->tuner->set_i2c_register(dev, 27, dev->saved_27, 255);
|
||||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1585,6 +1671,56 @@ int rtlsdr_set_tuner_gain_mode(rtlsdr_dev_t *dev, int mode)
|
|||
return r;
|
||||
}
|
||||
|
||||
int rtlsdr_set_tuner_sideband(rtlsdr_dev_t *dev, int sideband)
|
||||
{
|
||||
int r = 0, iffreq;
|
||||
rtlsdr_dev_t *devt = dev;
|
||||
|
||||
if (!dev || !dev->tuner)
|
||||
return -1;
|
||||
|
||||
if (dev->tuner->set_sideband) {
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "rtlsdr_set_tuner_sideband(%d): tuner.set_sideband() ..\n", sideband);
|
||||
|
||||
rtlsdr_set_i2c_repeater(dev, 1);
|
||||
r = dev->tuner->set_sideband((void *)dev, sideband);
|
||||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
|
||||
if (r)
|
||||
{
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "rtlsdr_set_tuner_sideband(%d): tuner.set_sideband() returned error %d\n", sideband, r);
|
||||
return r;
|
||||
}
|
||||
devt->tuner_sideband = sideband;
|
||||
|
||||
iffreq = (devt->tuner_sideband) /* -1 for USB; +1 for LSB */
|
||||
? ( devt->tuner_if_freq - devt->if_band_center_freq )
|
||||
: ( devt->tuner_if_freq + devt->if_band_center_freq );
|
||||
fprintf(stderr, "rtlsdr_set_tuner_sideband(%d): rtlsdr_set_if_freq(%d) ..\n", sideband, iffreq);
|
||||
r = rtlsdr_set_if_freq(devt, iffreq );
|
||||
if (r)
|
||||
{
|
||||
if ( devt->verbose )
|
||||
fprintf(stderr, "rtlsdr_set_tuner_sideband(%d): rtlsdr_set_if_freq(%d) returned error %d\n", sideband, iffreq);
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!devt->freq)
|
||||
return r;
|
||||
if (devt->verbose )
|
||||
fprintf(stderr, "rtlsdr_set_tuner_sideband(%d): rtlsdr_set_center_freq(%d) ..\n", sideband, devt->freq);
|
||||
r = rtlsdr_set_center_freq(devt, devt->freq);
|
||||
if (r && devt->verbose )
|
||||
fprintf(stderr, "rtlsdr_set_tuner_sideband(%d): rtlsdr_set_center_freq(%d) returned error %d\n", sideband, devt->freq, r);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int rtlsdr_set_tuner_i2c_register(rtlsdr_dev_t *dev, unsigned i2c_register, unsigned mask /* byte */, unsigned data /* byte */ )
|
||||
{
|
||||
int r = 0;
|
||||
|
@ -1608,6 +1744,23 @@ int rtlsdr_set_tuner_i2c_register(rtlsdr_dev_t *dev, unsigned i2c_register, unsi
|
|||
return r;
|
||||
}
|
||||
|
||||
/* -cs- */
|
||||
int rtlsdr_get_tuner_i2c_register(rtlsdr_dev_t *dev, unsigned char* data, int len)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
if (!dev || !dev->tuner)
|
||||
return -1;
|
||||
|
||||
if (dev->tuner->get_i2c_register) {
|
||||
rtlsdr_set_i2c_repeater(dev, 1);
|
||||
r = dev->tuner->get_i2c_reg_array((void *)dev, data, len);
|
||||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int rtlsdr_set_tuner_i2c_override(rtlsdr_dev_t *dev, unsigned i2c_register, unsigned mask /* byte */, unsigned data /* byte */ )
|
||||
{
|
||||
int r = 0;
|
||||
|
@ -2242,6 +2395,7 @@ static int parse(char *message, rtlsdr_dev_t *dev)
|
|||
uint8_t mask = 0xff, reg=0;
|
||||
uint32_t freq;
|
||||
int32_t bandcenter;
|
||||
int sideband;
|
||||
int retCode;
|
||||
|
||||
str1 = message;
|
||||
|
@ -2270,7 +2424,8 @@ static int parse(char *message, rtlsdr_dev_t *dev)
|
|||
* f <RFfrequency> # set rtl center frequency
|
||||
* b <bandwidth> # set tuner bandwidth
|
||||
* c <frequency> # set tuner bandwidth center in output. value in [ -1 600 000 .. 1 600 000 ]
|
||||
*
|
||||
* v <sideband> # set tuner sideband inversion
|
||||
*
|
||||
* a <tunerAgcVariant> # 0: LNA/Mixer = auto; VGA = fixed 26.5 dB
|
||||
* # -1: LNA/Mixer = last value from prev rtlsdr_set_tuner_gain; VGA = auto
|
||||
* # >0: LNA/Mixer = from rtlsdr_set_tuner_gain(tunerAgcMode); VGA = auto
|
||||
|
@ -2304,6 +2459,7 @@ static int parse(char *message, rtlsdr_dev_t *dev)
|
|||
if (!strcmp(token, "f")) comm = 256 + 1;
|
||||
if (!strcmp(token, "b")) comm = 256 + 2;
|
||||
if (!strcmp(token, "c")) comm = 256 + 3;
|
||||
if (!strcmp(token, "v")) comm = 256 + 4;
|
||||
if (!strcmp(token, "a")) comm = 512 + 1;
|
||||
if (!strcmp(token, "m")) comm = 512 + 2;
|
||||
if (!strcmp(token, "M")) comm = 512 + 3;
|
||||
|
@ -2367,7 +2523,6 @@ static int parse(char *message, rtlsdr_dev_t *dev)
|
|||
return -1;
|
||||
}
|
||||
} else if (comm == 64 +2 || comm == 64 +3 ) {
|
||||
dev->saved_27 = dev->tuner->get_i2c_register(dev,27);
|
||||
if ( dev->verbose )
|
||||
{
|
||||
fprintf(stderr, "parsed 'set i2c register %s %d = x%02X value %d = %s = %s with mask %s = %s'\n"
|
||||
|
@ -2451,6 +2606,15 @@ static int parse(char *message, rtlsdr_dev_t *dev)
|
|||
if ( dev->verbose )
|
||||
fprintf(stderr, " rtlsdr_set_tuner_band_center() returned %d\n", retCode);
|
||||
break;
|
||||
case 4: /* sideband */
|
||||
sideband = (int32_t)freqVal;
|
||||
if ( dev->verbose )
|
||||
fprintf(stderr, "parsed sideband = %d = %s from token '%s'\n",
|
||||
sideband, (sideband ? "USB" : "LSB"), token);
|
||||
retCode = rtlsdr_set_tuner_sideband(dev, sideband);
|
||||
if ( dev->verbose )
|
||||
fprintf(stderr, " rtlsdr_set_tuner_sideband() returned %d\n", retCode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2505,6 +2669,7 @@ static int parse(char *message, rtlsdr_dev_t *dev)
|
|||
"f <RFfrequency>\n"
|
||||
"b <bandwidth>\n"
|
||||
"c <frequency>\n"
|
||||
"v <sideband>\n"
|
||||
"a <tunerAgcVariant>\n"
|
||||
"m <tuner gain>\n"
|
||||
"M <gainMode>\n" );
|
||||
|
@ -2614,6 +2779,13 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
|
|||
dev->softagc.rpcNumGains = 0;
|
||||
dev->softagc.rpcGainValues = NULL;
|
||||
|
||||
/* -cs- */
|
||||
#ifdef __MINGW32__
|
||||
dev->cs_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
|
||||
#else
|
||||
dev->cs_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
#endif
|
||||
|
||||
/* UDP controller server */
|
||||
#ifdef WITH_UDP_SERVER
|
||||
dev->udpPortNo = 0; /* default port 32323 .. but deactivated - by default */
|
||||
|
@ -2745,6 +2917,8 @@ int rtlsdr_open(rtlsdr_dev_t **out_dev, uint32_t index)
|
|||
fprintf(stderr, "Found Fitipower FC0012 tuner\n");
|
||||
rtlsdr_set_gpio_output(dev, 6);
|
||||
dev->tuner_type = RTLSDR_TUNER_FC0012;
|
||||
/* rtlsdr_set_gpio_output(dev, 5); */
|
||||
/* rtlsdr_set_gpio_bit(dev, 5, 1); */
|
||||
goto found;
|
||||
}
|
||||
|
||||
|
@ -2785,7 +2959,6 @@ found:
|
|||
rtlsdr_set_i2c_repeater(dev, 0);
|
||||
|
||||
*out_dev = dev;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (dev) {
|
||||
|
@ -2843,10 +3016,6 @@ int rtlsdr_close(rtlsdr_dev_t *dev)
|
|||
|
||||
libusb_exit(dev->ctx);
|
||||
|
||||
if (dev->handled) {
|
||||
dev->handled = 0;
|
||||
}
|
||||
|
||||
free(dev);
|
||||
|
||||
return 0;
|
||||
|
@ -3508,7 +3677,6 @@ static int rtlsdr_read_regs(rtlsdr_dev_t *dev, uint8_t block, uint16_t addr, uin
|
|||
static int rtlsdr_write_reg_mask(rtlsdr_dev_t *d, int block, uint16_t reg, uint8_t val,
|
||||
uint8_t mask)
|
||||
{
|
||||
int ret;
|
||||
uint8_t tmp;
|
||||
|
||||
/* no need for read if whole reg is written */
|
||||
|
@ -3561,7 +3729,7 @@ int rtlsdr_ir_query(rtlsdr_dev_t *d, uint8_t *buf, size_t buf_len)
|
|||
ret = rtlsdr_write_reg_mask(d, init_tab[i].block, init_tab[i].reg,
|
||||
init_tab[i].val, init_tab[i].mask);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "write %zd reg %d %.4x %.2x %.2x failed\n", i, init_tab[i].block,
|
||||
fprintf(stderr, "write %ld reg %d %.4x %.2x %.2x failed\n", (unsigned long)i, init_tab[i].block,
|
||||
init_tab[i].reg, init_tab[i].val, init_tab[i].mask);
|
||||
goto err;
|
||||
}
|
||||
|
@ -3639,7 +3807,7 @@ const char * rtlsdr_get_opt_help(int longInfo)
|
|||
if ( longInfo )
|
||||
return
|
||||
"\t[-O\tset RTL options string seperated with ':' ]\n"
|
||||
"\t\tverbose:f=<freqHz>:bw=<bw_in_kHz>:bc=<if_in_Hz>\n"
|
||||
"\t\tverbose:f=<freqHz>:bw=<bw_in_kHz>:bc=<if_in_Hz>:sb=<sideband>\n"
|
||||
"\t\tagc=<tuner_gain_mode>:agcv=<>:gain=<tenth_dB>:dagc=<rtl_agc>\n"
|
||||
"\t\tds=<direct_sampling_mode>:T=<bias_tee>\n"
|
||||
#ifdef WITH_UDP_SERVER
|
||||
|
@ -3694,6 +3862,12 @@ int rtlsdr_set_opt_string(rtlsdr_dev_t *dev, const char *opts, int verbose)
|
|||
fprintf(stderr, "\nrtlsdr_set_opt_string(): parsed band center %d\n", (int)if_band_center_freq);
|
||||
ret = rtlsdr_set_tuner_band_center(dev, if_band_center_freq );
|
||||
}
|
||||
else if (!strncmp(optPart, "sb=", 3)) {
|
||||
int32_t sideband = (int32_t)(atoi(optPart +3));
|
||||
if (verbose)
|
||||
fprintf(stderr, "\nrtlsdr_set_opt_string(): parsed sideband %d == %s\n", (int)sideband, (sideband ? "Upper" : "Lower") );
|
||||
ret = rtlsdr_set_tuner_sideband(dev, sideband );
|
||||
}
|
||||
else if (!strncmp(optPart, "agc=", 4)) {
|
||||
int manual = 1 - atoi(optPart +4); /* invert logic */
|
||||
if (verbose)
|
||||
|
@ -3781,8 +3955,6 @@ int rtlsdr_set_opt_string(rtlsdr_dev_t *dev, const char *opts, int verbose)
|
|||
|
||||
#ifdef WITH_UDP_SERVER
|
||||
if (dev->udpPortNo && dev->srv_started == 0 && dev->tuner_type==RTLSDR_TUNER_R820T) {
|
||||
dev->handled = 1;
|
||||
dev->saved_27 = dev->tuner->get_i2c_register(dev,27); /* highest/lowest corner for LPNF and LPF */
|
||||
/* signal(SIGPIPE, SIG_IGN); */
|
||||
if(pthread_create(&dev->srv_thread, NULL, srv_server, dev)) {
|
||||
fprintf(stderr, "Error creating thread\n");
|
||||
|
|
|
@ -61,6 +61,10 @@ typedef int socklen_t;
|
|||
#define SOCKET_ERROR -1
|
||||
#endif
|
||||
|
||||
#include "controlThread.h"
|
||||
|
||||
static ctrl_thread_data_t ctrldata;
|
||||
|
||||
static SOCKET s;
|
||||
|
||||
static pthread_t tcp_worker_thread;
|
||||
|
@ -108,7 +112,8 @@ void usage(void)
|
|||
);
|
||||
|
||||
fprintf(stderr, "Usage:\t[-a listen address]\n"
|
||||
"\t[-p listen port (default: 1234)]\n"
|
||||
"\t[-p control listen port (default: 1234)]\n"
|
||||
"\t[-r response listen port: 0 = off; 1 (=default) for On at control listen port +1; or port]\n"
|
||||
"\t[-I infrared sensor listen port (default: 0=none)]\n"
|
||||
"\t[-W infrared sensor query wait interval usec (default: 10000)]\n"
|
||||
"\t[-f frequency to tune to [Hz]]\n"
|
||||
|
@ -434,6 +439,19 @@ static void *command_worker(void *arg)
|
|||
printf("set tuner agc variant to %i\n", itmp);
|
||||
rtlsdr_set_tuner_agc_mode(dev, itmp);
|
||||
break;
|
||||
case SET_SIDEBAND:
|
||||
tmp = ntohl(cmd.param);
|
||||
if(tmp)
|
||||
tmp = 1;
|
||||
printf("set to %s sideband\n", (tmp ? "upper" : "lower") );
|
||||
rtlsdr_set_tuner_sideband(dev, tmp);
|
||||
break;
|
||||
case REPORT_I2C_REGS:
|
||||
tmp = ntohl(cmd.param);
|
||||
if(tmp)
|
||||
tmp = 1;
|
||||
ctrldata.report_i2c = tmp; /* (de)activate reporting */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -521,6 +539,10 @@ int main(int argc, char **argv)
|
|||
int port_ir = 0;
|
||||
int wait_ir = 10000;
|
||||
pthread_t thread_ir;
|
||||
pthread_t thread_ctrl; /* -cs- for periodically reading the register values */
|
||||
int port_resp = 1;
|
||||
int report_i2c = 0;
|
||||
int do_exit_thrd_ctrl = 0;
|
||||
|
||||
uint32_t frequency = 100000000, samp_rate = 2048000;
|
||||
enum rtlsdr_ds_mode ds_mode = RTLSDR_DS_IQ;
|
||||
|
@ -563,7 +585,7 @@ int main(int argc, char **argv)
|
|||
struct sigaction sigact, sigign;
|
||||
#endif
|
||||
|
||||
opt_str = "a:p:f:g:s:b:n:d:P:O:TI:W:l:w:D:v";
|
||||
opt_str = "a:p:f:g:s:b:n:d:P:O:TI:W:l:w:D:vr:";
|
||||
while ((opt = getopt(argc, argv, opt_str)) != -1) {
|
||||
switch (opt) {
|
||||
case 'd':
|
||||
|
@ -585,6 +607,10 @@ int main(int argc, char **argv)
|
|||
case 'p':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
port_resp = atoi(optarg);
|
||||
report_i2c = 0;
|
||||
break;
|
||||
case 'I':
|
||||
port_ir = atoi(optarg);
|
||||
break;
|
||||
|
@ -724,6 +750,25 @@ int main(int argc, char **argv)
|
|||
pthread_create(&thread_ir, NULL, &ir_thread_fn, (void *)(&data));
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "enabling Response channel with I2C reporting\n");
|
||||
port_resp = 1;
|
||||
report_i2c = 1;
|
||||
#endif
|
||||
if ( port_resp == 1 )
|
||||
port_resp = port + 1;
|
||||
ctrldata.port = port_resp;
|
||||
ctrldata.dev = dev;
|
||||
ctrldata.addr = addr;
|
||||
ctrldata.wait = 500000; /* = 0.5 sec */
|
||||
ctrldata.report_i2c = report_i2c;
|
||||
ctrldata.pDoExit = &do_exit_thrd_ctrl;
|
||||
if ( port_resp ) {
|
||||
fprintf(stderr, "activating Response channel on port %d with %s I2C reporting\n"
|
||||
, port_resp, (report_i2c ? "active" : "inactive") );
|
||||
pthread_create(&thread_ctrl, NULL, &ctrl_thread_fn, &ctrldata);
|
||||
}
|
||||
|
||||
memset(&local,0,sizeof(local));
|
||||
local.sin_family = AF_INET;
|
||||
local.sin_port = htons(port);
|
||||
|
@ -825,6 +870,11 @@ out:
|
|||
closesocket(listensocket);
|
||||
/* if (port_ir) pthread_join(thread_ir, &status); */
|
||||
|
||||
if ( port_resp ) {
|
||||
do_exit_thrd_ctrl = 1;
|
||||
pthread_join(thread_ctrl, &status);
|
||||
}
|
||||
|
||||
closesocket(s);
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
|
|
|
@ -440,6 +440,15 @@ static void *command_worker(void *arg)
|
|||
printf("set tuner agc variant to %i\n", itmp);
|
||||
rtlsdr_set_tuner_agc_mode(dev, itmp);
|
||||
break;
|
||||
case SET_SIDEBAND:
|
||||
tmp = ntohl(cmd.param);
|
||||
if(tmp) {
|
||||
tmp = 1;
|
||||
printf("set to upper sideband\n");
|
||||
} else
|
||||
printf("set to lower sideband\n");
|
||||
rtlsdr_set_tuner_sideband(dev, tmp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -54,38 +54,92 @@ static int fc0012_readreg(void *dev, uint8_t reg, uint8_t *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* expose/permit tuner specific i2c register hacking! */
|
||||
int fc0012_set_i2c_register(void *dev, unsigned i2c_register, unsigned data)
|
||||
{
|
||||
uint8_t reg = i2c_register & 0xFF;
|
||||
uint8_t reg_val = data & 0xFF;
|
||||
return fc0012_writereg(dev, reg, reg_val);
|
||||
}
|
||||
|
||||
int fc0012_get_i2c_register(void *dev, unsigned char* data, int len)
|
||||
{
|
||||
int len1;
|
||||
|
||||
data[0] = 0;
|
||||
/* The lower 16 I2C registers can be read with the normal read fct,
|
||||
* the upper ones are read from the cache */
|
||||
if(len < 16)
|
||||
len1 = len;
|
||||
else
|
||||
len1 = 16;
|
||||
if (rtlsdr_i2c_write_fn(dev, FC0012_I2C_ADDR, data, 1) < 0)
|
||||
return -1;
|
||||
if (rtlsdr_i2c_read_fn(dev, FC0012_I2C_ADDR, data, len1) < 0)
|
||||
return -1;
|
||||
|
||||
if(len > 16)
|
||||
{
|
||||
len1 = len - 16;
|
||||
data[16] = 16;
|
||||
if (rtlsdr_i2c_write_fn(dev, FC0012_I2C_ADDR, data+16, 1) < 0)
|
||||
return -1;
|
||||
if (rtlsdr_i2c_read_fn(dev, FC0012_I2C_ADDR, data+16, len1) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_registers(void *dev)
|
||||
{
|
||||
uint8_t data[32];
|
||||
unsigned int i;
|
||||
|
||||
if (fc0012_get_i2c_register(dev, data, 32) < 0)
|
||||
return -1;
|
||||
for(i=0; i<16; i++)
|
||||
printf("%02x ", data[i]);
|
||||
printf("\n");
|
||||
for(i=16; i<32; i++)
|
||||
printf("%02x ", data[i]);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Incomplete list of register settings:
|
||||
*
|
||||
* Name Reg Bits Desc
|
||||
* CHIP_ID 0x00 0-7 Chip ID (constant 0xA1)
|
||||
* RF_A 0x01 0-3 Number of count-to-9 cycles in RF
|
||||
* divider (suggested: 2..9)
|
||||
* RF_M 0x02 0-7 Total number of cycles (to-8 and to-9)
|
||||
* in RF divider
|
||||
* Name Reg BitsDesc
|
||||
* CHIP_ID 0x00 0-7 Chip ID (constant 0xA1)
|
||||
* RF_A 0x01 0-3 Number of count-to-9 cycles in RF
|
||||
* divider (suggested: 2..9)
|
||||
* RF_M 0x02 0-7 Total number of cycles (to-8 and to-9)
|
||||
* in RF divider
|
||||
* RF_K_HIGH 0x03 0-6 Bits 8..14 of fractional divider
|
||||
* RF_K_LOW 0x04 0-7 Bits 0..7 of fractional RF divider
|
||||
* RF_K_LOW 0x04 0-7 Bits 0..7 of fractional RF divider
|
||||
* RF_OUTDIV_A 0x05 3-7 Power of two required?
|
||||
* LNA_POWER_DOWN 0x06 0 Set to 1 to switch off low noise amp
|
||||
* RF_OUTDIV_B 0x06 1 Set to select 3 instead of 2 for the
|
||||
* RF output divider
|
||||
* RF output divider
|
||||
* VCO_SPEED 0x06 3 Select tuning range of VCO:
|
||||
* 0 = Low range, (ca. 1.1 - 1.5GHz)
|
||||
* 1 = High range (ca. 1.4 - 1.8GHz)
|
||||
* 0 = Low range, (ca. 1.1 - 1.5GHz)
|
||||
* 1 = High range (ca. 1.4 - 1.8GHz)
|
||||
* BANDWIDTH 0x06 6-7 Set bandwidth. 6MHz = 0x80, 7MHz=0x40
|
||||
* 8MHz=0x00
|
||||
* 8MHz=0x00
|
||||
* XTAL_SPEED 0x07 5 Set to 1 for 28.8MHz Crystal input
|
||||
* or 0 for 36MHz
|
||||
* or 0 for 36MHz
|
||||
* <agc params> 0x08 0-7
|
||||
* EN_CAL_RSSI 0x09 4 Enable calibrate RSSI
|
||||
* (Receive Signal Strength Indicator)
|
||||
* (Receive Signal Strength Indicator)
|
||||
* LNA_FORCE 0x0d 0
|
||||
* AGC_FORCE 0x0d ?
|
||||
* LNA_GAIN 0x13 3-4 Low noise amp gain
|
||||
* LNA_COMPS 0x15 3 ?
|
||||
* VCO_CALIB 0x0e 7 Set high then low to calibrate VCO
|
||||
* (fast lock?)
|
||||
* (fast lock?)
|
||||
* VCO_VOLTAGE 0x0e 0-6 Read Control voltage of VCO
|
||||
* (big value -> low freq)
|
||||
* (big value -> low freq)
|
||||
* LNA_GAIN 0x13 3-4 Low noise amp gain
|
||||
* LNA_COMPS 0x15 3 ?
|
||||
*/
|
||||
|
||||
int fc0012_init(void *dev)
|
||||
|
@ -112,8 +166,8 @@ int fc0012_init(void *dev)
|
|||
0x00, /* reg. 0x0e */
|
||||
0x00, /* reg. 0x0f */
|
||||
0x00, /* reg. 0x10: may also be 0x0d */
|
||||
0x00, /* reg. 0x11 */
|
||||
0x1f, /* reg. 0x12: Set to maximum gain */
|
||||
0x0a, /* reg. 0x11 */
|
||||
0x51, /* reg. 0x12: Set to maximum gain */
|
||||
0x08, /* reg. 0x13: Set to Middle Gain: 0x08,
|
||||
Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
|
||||
0x00, /* reg. 0x14 */
|
||||
|
@ -133,7 +187,7 @@ int fc0012_init(void *dev)
|
|||
#endif
|
||||
reg[0x07] |= 0x20;
|
||||
|
||||
// if (priv->dual_master)
|
||||
/* if (priv->dual_master) */
|
||||
reg[0x0c] |= 0x02;
|
||||
|
||||
for (i = 1; i < sizeof(reg); i++) {
|
||||
|
@ -278,7 +332,7 @@ int fc0012_set_params(void *dev, uint32_t freq, uint32_t bandwidth)
|
|||
ret = fc0012_writereg(dev, 0x0e, 0x00);
|
||||
|
||||
if (!ret) {
|
||||
// msleep(10);
|
||||
/* msleep(10); */
|
||||
ret = fc0012_readreg(dev, 0x0e, &tmp);
|
||||
}
|
||||
if (ret)
|
||||
|
@ -340,6 +394,6 @@ int fc0012_set_gain(void *dev, int gain)
|
|||
}
|
||||
|
||||
ret = fc0012_writereg(dev, 0x13, tmp);
|
||||
|
||||
/* print_registers(dev); */
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -30,26 +30,277 @@
|
|||
#include "rtlsdr_i2c.h"
|
||||
#include "tuner_r82xx.h"
|
||||
|
||||
#define WITH_ASYM_FILTER 1
|
||||
#define WITH_ASYM_FILTER 0
|
||||
|
||||
|
||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
#define MHZ(x) ((x)*1000*1000)
|
||||
#define KHZ(x) ((x)*1000)
|
||||
|
||||
/*
|
||||
Reg Bitmap Symbol Description
|
||||
------------------------------------------------------------------------------------
|
||||
R0 [7:0] CHIP_ID reference check point for read mode
|
||||
0x00 0x96
|
||||
------------------------------------------------------------------------------------
|
||||
R1 ?
|
||||
0x01
|
||||
------------------------------------------------------------------------------------
|
||||
R2 [7] 0
|
||||
0x02 [6:0] VCO_INDICATOR
|
||||
------------------------------------------------------------------------------------
|
||||
R3 [7:4] RF_INDICATOR LNA gain
|
||||
0x03 0: Lowest, 15: Highest
|
||||
[3:0] Mixer gain
|
||||
0: Lowest, 15: Highest
|
||||
------------------------------------------------------------------------------------
|
||||
R4 ?
|
||||
0x04
|
||||
------------------------------------------------------------------------------------
|
||||
R5 [7] PWD_LT Loop through ON/OFF
|
||||
0x05 0: on, 1: off
|
||||
[6] 0
|
||||
[5] PWD_LNA1 LNA 1 power control
|
||||
0:on, 1:off
|
||||
[4] LNA_GAIN_MODE LNA gain mode switch
|
||||
0: auto, 1: manual
|
||||
[3:0] LNA_GAIN LNA manual gain control
|
||||
15: max gain, 0: min gain
|
||||
------------------------------------------------------------------------------------
|
||||
R6 [7] PWD_PDET1 Power detector 1 on/off
|
||||
0x06 0: on, 1: off
|
||||
[6] PWD_PDET3 Power detector 3 on/off
|
||||
0: off, 1: on
|
||||
[5] FILT_3DB Filter gain 3db
|
||||
0:0db, 1:+3db
|
||||
[4:3] 10
|
||||
[2:0] PW_LNA LNA power control
|
||||
000: max, 111: min
|
||||
------------------------------------------------------------------------------------
|
||||
R7 [7] Mixer Sideband
|
||||
0x07 0: lower, 1: upper
|
||||
[6] PWD_MIX Mixer power
|
||||
0:off, 1:on
|
||||
[5] PW0_MIX Mixer current control
|
||||
0:max current, 1:normal current
|
||||
[4] MIXGAIN_MODE Mixer gain mode
|
||||
0:manual mode, 1:auto mode
|
||||
[3:0] MIX_GAIN Mixer manual gain control
|
||||
0000->min, 1111->max
|
||||
------------------------------------------------------------------------------------
|
||||
R8 [7] PWD_AMP Mixer buffer power on/off
|
||||
0x08 0: off, 1:on
|
||||
[6] PW0_AMP Mixer buffer current setting
|
||||
0: high current, 1: low current
|
||||
[5:0] IMR_G Image Gain Adjustment
|
||||
0: min, 63: max
|
||||
------------------------------------------------------------------------------------
|
||||
R9 [7] PWD_IFFILT IF Filter power on/off
|
||||
0x09 0: filter on, 1: off
|
||||
[6] PW1_IFFILT IF Filter current
|
||||
0: high current, 1: low current
|
||||
[5:0] IMR_P Image Phase Adjustment
|
||||
0: min, 63: max
|
||||
------------------------------------------------------------------------------------
|
||||
R10 [7] PWD_FILT Filter power on/off
|
||||
0x0A 0: channel filter off, 1: on
|
||||
[6:5] PW_FILT Filter power control
|
||||
00: highest power, 11: lowest power
|
||||
[4] 1
|
||||
[3:0] FILT_CODE Filter bandwidth manual fine tune
|
||||
0000 Widest, 1111 narrowest
|
||||
------------------------------------------------------------------------------------
|
||||
R11 [7:5] FILT_BW Filter bandwidth manual course tunnel
|
||||
0x0B 000: widest
|
||||
010 or 001: middle
|
||||
111: narrowest
|
||||
[4] 0
|
||||
[3:0] HPF High pass filter corner control
|
||||
0000: highest
|
||||
1111: lowest
|
||||
------------------------------------------------------------------------------------
|
||||
R12 [7] 1
|
||||
0x0C [6] PWD_VGA VGA power control
|
||||
0: vga power off, 1: vga power on
|
||||
[5] 1
|
||||
[4] VGA_MODE VGA GAIN manual / pin selector
|
||||
1: IF vga gain controlled by vagc pin
|
||||
0: IF vga gain controlled by vga_code[3:0]
|
||||
[3:0] VGA_CODE IF vga manual gain control
|
||||
0000: -12.0 dB
|
||||
1111: +40.5 dB; -3.5dB/step
|
||||
------------------------------------------------------------------------------------
|
||||
R13 [7:4] LNA_VTHH LNA agc power detector voltage threshold high setting
|
||||
0x0D 1111: 1.94 V
|
||||
0000: 0.34 V, ~0.1 V/step
|
||||
[3:0] LNA_VTHL LNA agc power detector voltage threshold low setting
|
||||
1111: 1.94 V
|
||||
0000: 0.34 V, ~0.1 V/step
|
||||
------------------------------------------------------------------------------------
|
||||
R14 [7:4] MIX_VTH_H MIXER agc power detector voltage threshold high setting
|
||||
0x0E 1111: 1.94 V
|
||||
0000: 0.34 V, ~0.1 V/step
|
||||
[3:0] MIX_VTH_L MIXER agc power detector voltage threshold low setting
|
||||
1111: 1.94 V
|
||||
0000: 0.34 V, ~0.1 V/step
|
||||
------------------------------------------------------------------------------------
|
||||
R15 [7] filter extension widest
|
||||
0: off, 1: on
|
||||
0x0F [4] CLK_OUT_ENB Clock out pin control
|
||||
0: clk output on, 1: off
|
||||
[3] 1
|
||||
[2] set cali clk
|
||||
0: off, 1: on
|
||||
[1] CLK_AGC_ENB AGC clk control
|
||||
0: internal agc clock on, 1: off
|
||||
[0] GPIO 0
|
||||
------------------------------------------------------------------------------------
|
||||
R16 [7:5] SEL_DIV PLL to Mixer divider number control
|
||||
0x10 000: mixer in = vco out /2
|
||||
001: mixer in = vco out / 4
|
||||
010: mixer in = vco out / 8
|
||||
011: mixer in = vco out
|
||||
[4] REFDIV PLL Reference frequency Divider
|
||||
0 -> fref=xtal_freq
|
||||
1 -> fref=xta_freql / 2 (for Xtal >24MHz)
|
||||
[3:2] 01
|
||||
[1:0] CAPX Internal xtal cap setting
|
||||
00->no cap
|
||||
01->10pF
|
||||
10->20pF
|
||||
11->30pF
|
||||
------------------------------------------------------------------------------------
|
||||
R17 [7:6] PW_LDO_A PLL analog low drop out regulator switch
|
||||
0x11 00: off
|
||||
01: 2.1V
|
||||
10: 2.0V
|
||||
11: 1.9V
|
||||
[5:3] cp_cur
|
||||
101: 0.2, 111: auto
|
||||
[2:0] 011
|
||||
------------------------------------------------------------------------------------
|
||||
R18 [7:5] set VCO current
|
||||
0x12 [4] PW_SDM 0
|
||||
[3:0] 000
|
||||
------------------------------------------------------------------------------------
|
||||
R19 [7:6] 00
|
||||
[5:0] VER_NUM 0x31
|
||||
------------------------------------------------------------------------------------
|
||||
R20 [7:6] SI2C PLL integer divider number input Si2c
|
||||
0x14 Nint=4*Ni2c+Si2c+13
|
||||
PLL divider number Ndiv = (Nint + Nfra)*2
|
||||
[5:0] NI2C PLL integer divider number input Ni2c
|
||||
------------------------------------------------------------------------------------
|
||||
R21 [7:0] SDM_IN[8:1] PLL fractional divider number input SDM[16:1]
|
||||
0x15 Nfra=SDM_IN[16]*2^-1+SDM_IN[15]*2^-2+...
|
||||
R22 [7:0] SDM_IN[16:9] +SDM_IN[2]*2^-15+SDM_IN[1]*2^-16
|
||||
0x16
|
||||
------------------------------------------------------------------------------------
|
||||
R23 [7:6] PW_LDO_D PLL digital low drop out regulator supply current switch
|
||||
0x17 00: 1.8V,8mA
|
||||
01: 1.8V,4mA
|
||||
10: 2.0V,8mA
|
||||
11: OFF
|
||||
[5:4] div_buf_cur
|
||||
10: 200u, 11: 150u
|
||||
[3] OPEN_D Open drain
|
||||
0: High-Z, 1: Low-Z
|
||||
[2:0] 100
|
||||
------------------------------------------------------------------------------------
|
||||
R25 [7] PWD_RFFILT RF Filter power
|
||||
0x19 0: off, 1:on
|
||||
[6:5] RF poly filter current
|
||||
00: min
|
||||
[4] SW_AGC Switch agc_pin
|
||||
0:agc=agc_in
|
||||
1:agc=agc_in2
|
||||
[3:2] 11
|
||||
------------------------------------------------------------------------------------
|
||||
R26 [7:6] RFMUX Tracking Filter switch
|
||||
0x1A 00: TF on
|
||||
01: Bypass
|
||||
[5:4] AGC clk
|
||||
00: 300ms, 01: 300ms, 10: 80ms, 11: 20ms
|
||||
[3:2] PLL_AUTO_CLK PLL auto tune clock rate
|
||||
00: 128 kHz
|
||||
01: 32 kHz
|
||||
10: 8 kHz
|
||||
[1:0] RFFILT RF FILTER band selection
|
||||
00: highest band
|
||||
01: med band
|
||||
10: low band
|
||||
------------------------------------------------------------------------------------
|
||||
R27 [7:4] TF_NCH 0000 highest corner for LPNF
|
||||
0x1B 1111 lowerst corner for LPNF
|
||||
[3:0] TF_LP 0000 highest corner for LPF
|
||||
1111 lowerst corner for LPF
|
||||
------------------------------------------------------------------------------------
|
||||
R28 [7:4] PDET3_GAIN Power detector 3 (Mixer) TOP(take off point) control
|
||||
0x1C 0: Highest, 15: Lowest
|
||||
[3] discharge mode
|
||||
0: on
|
||||
[2] 1
|
||||
[0] 0
|
||||
------------------------------------------------------------------------------------
|
||||
R29 [7:6] 11
|
||||
0x1D [5:3] PDET1_GAIN Power detector 1 (LNA) TOP(take off point) control
|
||||
0: Highest, 7: Lowest
|
||||
[2:0] PDET2_GAIN Power detector 2 TOP(take off point) control
|
||||
0: Highest, 7: Lowest
|
||||
------------------------------------------------------------------------------------
|
||||
R30 [7] 0
|
||||
0x1E [6] FILTER_EXT Filter extension under weak signal
|
||||
0: Disable, 1: Enable
|
||||
[5:0] PDET_CLK Power detector timing control (LNA discharge current)
|
||||
111111: max, 000000: min
|
||||
------------------------------------------------------------------------------------
|
||||
R31 [7] Loop through attenuation
|
||||
0x1F 0: Enable, 1: Disable
|
||||
[6:2] 10000
|
||||
------------------------------------------------------------------------------------
|
||||
R0...R4 read, R5...R15 read/write, R16..R31 write
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Static constants
|
||||
*/
|
||||
|
||||
/* Those initial values start from REG_SHADOW_START */
|
||||
static const uint8_t r82xx_init_array[NUM_REGS] = {
|
||||
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 */
|
||||
0x0f, 0x00, 0xc0, 0x30, /* 14 to 17 */
|
||||
0x48, 0xcc, 0x60, 0x00, /* 18 to 1b */
|
||||
0x54, 0xae, 0x4a, 0xc0 /* 1c to 1f */
|
||||
static const uint8_t r82xx_init_array[] = {
|
||||
0x80, /* Reg 0x05 */
|
||||
0x12, /* Reg 0x06 */
|
||||
0x70, /* Reg 0x07 */
|
||||
|
||||
0xc0, /* Reg 0x08 */
|
||||
0x40, /* Reg 0x09 */
|
||||
0xdb, /* Reg 0x0a */
|
||||
0x6b, /* Reg 0x0b */
|
||||
|
||||
0xf0, /* Reg 0x0c */
|
||||
0x53, /* Reg 0x0d */
|
||||
0x75, /* Reg 0x0e */
|
||||
0x68, /* Reg 0x0f */
|
||||
|
||||
0x6c, /* Reg 0x10 */
|
||||
0xbb, /* Reg 0x11 */
|
||||
0x80, /* Reg 0x12 */
|
||||
VER_NUM & 0x3f, /* Reg 0x13 */
|
||||
|
||||
0x0f, /* Reg 0x14 */
|
||||
0x00, /* Reg 0x15 */
|
||||
0xc0, /* Reg 0x16 */
|
||||
0x30, /* Reg 0x17 */
|
||||
|
||||
0x48, /* Reg 0x18 */
|
||||
0xec, /* Reg 0x19 */
|
||||
0x60, /* Reg 0x1a */
|
||||
0x00, /* Reg 0x1b */
|
||||
|
||||
0x24, /* Reg 0x1c */
|
||||
0xdd, /* Reg 0x1d */
|
||||
0x0e, /* Reg 0x1e */
|
||||
0x40 /* Reg 0x1f */
|
||||
};
|
||||
|
||||
/* Tuner frequency ranges */
|
||||
|
@ -225,14 +476,6 @@ static const struct r82xx_freq_range freq_ranges[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static int r82xx_xtal_capacitor[][2] = {
|
||||
{ 0x0b, XTAL_LOW_CAP_30P },
|
||||
{ 0x02, XTAL_LOW_CAP_20P },
|
||||
{ 0x01, XTAL_LOW_CAP_10P },
|
||||
{ 0x00, XTAL_LOW_CAP_0P },
|
||||
{ 0x10, XTAL_HIGH_CAP_0P },
|
||||
};
|
||||
|
||||
/*
|
||||
* I2C read/write code and shadow registers logic
|
||||
*/
|
||||
|
@ -369,11 +612,6 @@ static int r82xx_read(struct r82xx_priv *priv, uint8_t reg, uint8_t *val, int le
|
|||
uint8_t *p = &priv->buf[1];
|
||||
|
||||
priv->buf[0] = reg;
|
||||
|
||||
rc = rtlsdr_i2c_write_fn(priv->rtl_dev, priv->cfg->i2c_addr, priv->buf, 1);
|
||||
if (rc < 1)
|
||||
return rc;
|
||||
|
||||
rc = rtlsdr_i2c_read_fn(priv->rtl_dev, priv->cfg->i2c_addr, p, len);
|
||||
|
||||
if (rc != len) {
|
||||
|
@ -391,6 +629,23 @@ static int r82xx_read(struct r82xx_priv *priv, uint8_t reg, uint8_t *val, int le
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void print_registers(struct r82xx_priv *priv)
|
||||
{
|
||||
uint8_t data[5];
|
||||
int rc;
|
||||
unsigned int i;
|
||||
|
||||
rc = r82xx_read(priv, 0x00, data, sizeof(data));
|
||||
if (rc < 0)
|
||||
return;
|
||||
for(i=0; i<sizeof(data); i++)
|
||||
printf("%02x ", data[i]);
|
||||
printf("\n");
|
||||
for(i=sizeof(data); i<32; i++)
|
||||
printf("%02x ", r82xx_read_cache_reg(priv, i));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* r82xx tuning logic
|
||||
*/
|
||||
|
@ -443,14 +698,6 @@ static int r82xx_set_mux(struct r82xx_priv *priv, uint32_t freq)
|
|||
break;
|
||||
}
|
||||
rc = r82xx_write_reg_mask(priv, 0x10, val, 0x0b);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = r82xx_write_reg_mask(priv, 0x08, 0x00, 0x3f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = r82xx_write_reg_mask(priv, 0x09, 0x00, 0x3f);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -534,13 +781,13 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
|
|||
* nint + sdm/65536
|
||||
*
|
||||
* where nint,sdm are integers and 0 < nint, 0 <= sdm < 65536
|
||||
*
|
||||
*
|
||||
* Scaling to fixed point and rounding:
|
||||
*
|
||||
* vco_div = 65536*(nint + sdm/65536) = int( 0.5 + 65536 * vco_freq / (2 * pll_ref) )
|
||||
* vco_div = 65536*nint + sdm = int( (pll_ref + 65536 * vco_freq) / (2 * pll_ref) )
|
||||
*/
|
||||
|
||||
|
||||
vco_div = (pll_ref + 65536 * vco_freq) / (2 * pll_ref);
|
||||
nint = (uint32_t) (vco_div / 65536);
|
||||
sdm = (uint32_t) (vco_div % 65536);
|
||||
|
@ -583,7 +830,6 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
|
|||
return rc;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
// usleep_range(sleep_time, sleep_time + 1000);
|
||||
|
||||
/* Check if PLL has locked */
|
||||
rc = r82xx_read(priv, 0x00, data, 3);
|
||||
|
@ -614,76 +860,15 @@ static int r82xx_set_pll(struct r82xx_priv *priv, uint32_t freq)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
||||
enum r82xx_tuner_type type,
|
||||
uint32_t delsys)
|
||||
static int r82xx_sysfreq_sel(struct r82xx_priv *priv,
|
||||
enum r82xx_tuner_type type)
|
||||
{
|
||||
int rc;
|
||||
uint8_t mixer_top, lna_top, cp_cur, div_buf_cur, lna_vth_l, mixer_vth_l;
|
||||
uint8_t air_cable1_in, cable2_in, pre_dect, lna_discharge, filter_cur;
|
||||
|
||||
switch (delsys) {
|
||||
case SYS_DVBT:
|
||||
if ((freq == 506000000) || (freq == 666000000) ||
|
||||
(freq == 818000000)) {
|
||||
mixer_top = 0x14; /* mixer top:14 , top-1, low-discharge */
|
||||
lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
|
||||
cp_cur = 0x28; /* 101, 0.2 */
|
||||
div_buf_cur = 0x20; /* 10, 200u */
|
||||
} else {
|
||||
mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
|
||||
lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
|
||||
cp_cur = 0x38; /* 111, auto */
|
||||
div_buf_cur = 0x30; /* 11, 150u */
|
||||
}
|
||||
lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
|
||||
mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
|
||||
air_cable1_in = 0x00;
|
||||
cable2_in = 0x00;
|
||||
pre_dect = 0x40;
|
||||
lna_discharge = 14;
|
||||
filter_cur = 0x40; /* 10, low */
|
||||
break;
|
||||
case SYS_DVBT2:
|
||||
mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
|
||||
lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
|
||||
lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
|
||||
mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
|
||||
air_cable1_in = 0x00;
|
||||
cable2_in = 0x00;
|
||||
pre_dect = 0x40;
|
||||
lna_discharge = 14;
|
||||
cp_cur = 0x38; /* 111, auto */
|
||||
div_buf_cur = 0x30; /* 11, 150u */
|
||||
filter_cur = 0x40; /* 10, low */
|
||||
break;
|
||||
case SYS_ISDBT:
|
||||
mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
|
||||
lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
|
||||
lna_vth_l = 0x75; /* lna vth 1.04 , vtl 0.84 */
|
||||
mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
|
||||
air_cable1_in = 0x00;
|
||||
cable2_in = 0x00;
|
||||
pre_dect = 0x40;
|
||||
lna_discharge = 14;
|
||||
cp_cur = 0x38; /* 111, auto */
|
||||
div_buf_cur = 0x30; /* 11, 150u */
|
||||
filter_cur = 0x40; /* 10, low */
|
||||
break;
|
||||
default: /* DVB-T 8M */
|
||||
mixer_top = 0x24; /* mixer top:13 , top-1, low-discharge */
|
||||
lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
|
||||
lna_vth_l = 0x53; /* lna vth 0.84 , vtl 0.64 */
|
||||
mixer_vth_l = 0x75; /* mixer vth 1.04, vtl 0.84 */
|
||||
air_cable1_in = 0x00;
|
||||
cable2_in = 0x00;
|
||||
pre_dect = 0x40;
|
||||
lna_discharge = 14;
|
||||
cp_cur = 0x38; /* 111, auto */
|
||||
div_buf_cur = 0x30; /* 11, 150u */
|
||||
filter_cur = 0x40; /* 10, low */
|
||||
break;
|
||||
}
|
||||
uint8_t lna_top = 0xe5; /* detect bw 3, lna top:4, predet top:2 */
|
||||
uint8_t pre_dect = 0x40;
|
||||
uint8_t air_cable1_in = 0x00;
|
||||
uint8_t cable2_in = 0x00;
|
||||
|
||||
if (priv->cfg->use_predetect) {
|
||||
rc = r82xx_write_reg_mask(priv, 0x06, pre_dect, 0x40);
|
||||
|
@ -691,19 +876,6 @@ static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
|||
return rc;
|
||||
}
|
||||
|
||||
rc = r82xx_write_reg_mask(priv, 0x1d, lna_top, 0xc7);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = r82xx_write_reg_mask(priv, 0x1c, mixer_top, 0xf8);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = r82xx_write_reg(priv, 0x0d, lna_vth_l);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = r82xx_write_reg(priv, 0x0e, mixer_vth_l);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
priv->input = air_cable1_in;
|
||||
|
||||
/* Air-IN only for Astrometa */
|
||||
|
@ -714,16 +886,6 @@ static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = r82xx_write_reg_mask(priv, 0x11, cp_cur, 0x38);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = r82xx_write_reg_mask(priv, 0x17, div_buf_cur, 0x30);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
rc = r82xx_write_reg_mask_ext(priv, 0x0a, filter_cur, 0x60, __FUNCTION__);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* Set LNA
|
||||
*/
|
||||
|
@ -734,11 +896,6 @@ static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* 0: normal mode */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1c, 0, 0x04);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* 0: PRE_DECT off */
|
||||
rc = r82xx_write_reg_mask(priv, 0x06, 0, 0x40);
|
||||
if (rc < 0)
|
||||
|
@ -749,27 +906,11 @@ static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
// msleep(250);
|
||||
|
||||
/* write LNA TOP = 3 */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1d, 0x18, 0x38);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* write discharge mode
|
||||
* FIXME: IMHO, the mask here is wrong, but it matches
|
||||
* what's there at the original driver
|
||||
*/
|
||||
rc = r82xx_write_reg_mask(priv, 0x1c, mixer_top, 0x04);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* LNA discharge current */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1e, lna_discharge, 0x1f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* agc clk 60hz */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1a, 0x20, 0x30);
|
||||
if (rc < 0)
|
||||
|
@ -785,20 +926,6 @@ static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* write discharge mode
|
||||
* FIXME: IMHO, the mask here is wrong, but it matches
|
||||
* what's there at the original driver
|
||||
*/
|
||||
rc = r82xx_write_reg_mask(priv, 0x1c, mixer_top, 0x04);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* LNA discharge current */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1e, lna_discharge, 0x1f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* agc clk 1Khz, external det1 cap 1u */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1a, 0x00, 0x30);
|
||||
if (rc < 0)
|
||||
|
@ -812,75 +939,40 @@ static int r82xx_sysfreq_sel(struct r82xx_priv *priv, uint32_t freq,
|
|||
}
|
||||
|
||||
static int r82xx_set_tv_standard(struct r82xx_priv *priv,
|
||||
unsigned bw,
|
||||
enum r82xx_tuner_type type,
|
||||
uint32_t delsys)
|
||||
|
||||
{
|
||||
int rc, i;
|
||||
uint32_t if_khz, filt_cal_lo;
|
||||
uint8_t data[5];
|
||||
uint8_t filt_gain, img_r, filt_q, hp_cor, ext_enable, loop_through;
|
||||
uint8_t lt_att, flt_ext_widest, polyfil_cur;
|
||||
int need_calibration;
|
||||
|
||||
int need_calibration = 1;
|
||||
|
||||
/* BW < 6 MHz */
|
||||
if_khz = 3570;
|
||||
filt_cal_lo = 56000; /* 52000->56000 */
|
||||
filt_gain = 0x10; /* +3db, 6mhz on */
|
||||
img_r = 0x00; /* image negative */
|
||||
filt_q = 0x10; /* r10[4]:low q(1'b1) */
|
||||
hp_cor = 0x6b; /* 1.7m disable, +2cap, 1.0mhz */
|
||||
ext_enable = 0x60; /* r30[6]=1 ext enable; r30[5]:1 ext at lna max-1 */
|
||||
loop_through = 0x01; /* r5[7], lt off */
|
||||
lt_att = 0x00; /* r31[7], lt att enable */
|
||||
flt_ext_widest = 0x00; /* r15[7]: flt_ext_wide off */
|
||||
polyfil_cur = 0x60; /* r25[6:5]:min */
|
||||
|
||||
/* Initialize the shadow registers */
|
||||
memcpy(priv->regs, r82xx_init_array, sizeof(r82xx_init_array));
|
||||
|
||||
/* Init Flag & Xtal_check Result (inits VGA gain, needed?)*/
|
||||
rc = r82xx_write_reg_mask(priv, 0x0c, 0x00, 0x0f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* version */
|
||||
rc = r82xx_write_reg_mask(priv, 0x13, VER_NUM, 0x3f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
uint32_t filt_cal_lo = 56000; /* 52000->56000 */
|
||||
uint8_t filt_q = 0x10; /* r10[4]:low q(1'b1) */
|
||||
|
||||
/* for LT Gain test */
|
||||
if (type != TUNER_ANALOG_TV) {
|
||||
rc = r82xx_write_reg_mask(priv, 0x1d, 0x00, 0x38);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
// usleep_range(1000, 2000);
|
||||
}
|
||||
priv->if_band_center_freq = 0;
|
||||
priv->int_freq = if_khz * 1000;
|
||||
priv->int_freq = 3570 * 1000;
|
||||
priv->sideband = 0;
|
||||
|
||||
/* Check if standard changed. If so, filter calibration is needed */
|
||||
/* as we call this function only once in rtlsdr, force calibration */
|
||||
need_calibration = 1;
|
||||
|
||||
if (need_calibration) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Set filt_cap */
|
||||
rc = r82xx_write_reg_mask_ext(priv, 0x0b, hp_cor, 0x60, __FUNCTION__);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* set cali clk =on */
|
||||
rc = r82xx_write_reg_mask(priv, 0x0f, 0x04, 0x04);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* X'tal cap 0pF for PLL */
|
||||
rc = r82xx_write_reg_mask(priv, 0x10, 0x00, 0x03);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = r82xx_set_pll(priv, filt_cal_lo * 1000);
|
||||
if (rc < 0 || !priv->has_lock)
|
||||
return rc;
|
||||
|
@ -890,8 +982,6 @@ static int r82xx_set_tv_standard(struct r82xx_priv *priv,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
// usleep_range(1000, 2000);
|
||||
|
||||
/* Stop Trigger */
|
||||
rc = r82xx_write_reg_mask_ext(priv, 0x0b, 0x00, 0x10, __FUNCTION__);
|
||||
if (rc < 0)
|
||||
|
@ -921,50 +1011,10 @@ static int r82xx_set_tv_standard(struct r82xx_priv *priv,
|
|||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Set BW, Filter_gain, & HP corner */
|
||||
rc = r82xx_write_reg_mask_ext(priv, 0x0b, hp_cor, 0xef, __FUNCTION__);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Set Img_R */
|
||||
rc = r82xx_write_reg_mask(priv, 0x07, img_r, 0x80);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Set filt_3dB, V6MHz */
|
||||
rc = r82xx_write_reg_mask(priv, 0x06, filt_gain, 0x30);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* channel filter extension */
|
||||
rc = r82xx_write_reg_mask_ext(priv, 0x1e, ext_enable, 0x60, __FUNCTION__);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Loop through */
|
||||
rc = r82xx_write_reg_mask(priv, 0x05, loop_through, 0x80);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Loop through attenuation */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1f, lt_att, 0x80);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* filter extension widest */
|
||||
rc = r82xx_write_reg_mask(priv, 0x0f, flt_ext_widest, 0x80);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* RF poly filter current */
|
||||
rc = r82xx_write_reg_mask(priv, 0x19, polyfil_cur, 0x60);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Store current standard. If it changes, re-calibrate the tuner */
|
||||
priv->delsys = delsys;
|
||||
priv->type = type;
|
||||
priv->bw = bw;
|
||||
priv->bw = 3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1125,6 +1175,26 @@ int r82xx_set_i2c_register(struct r82xx_priv *priv, unsigned i2c_register, unsig
|
|||
return r82xx_write_reg_mask(priv, reg, reg_val, reg_mask);
|
||||
}
|
||||
|
||||
//-cs-
|
||||
int r82xx_get_i2c_register(struct r82xx_priv *priv, unsigned char* data, int len)
|
||||
{
|
||||
int rc, i, len1;
|
||||
|
||||
// The lower 5 I2C registers can be read with the normal read fct, the upper ones are read from the cache
|
||||
if(len < 5)
|
||||
len1 = len;
|
||||
else
|
||||
len1 = 5;
|
||||
rc = r82xx_read(priv, 0x00, data, len1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if(len > 5)
|
||||
for (i = 5; i < len; i++)
|
||||
data[i] = r82xx_read_cache_reg(priv, i);
|
||||
return 0;
|
||||
}
|
||||
//-cs- end
|
||||
|
||||
int r82xx_set_i2c_override(struct r82xx_priv *priv, unsigned i2c_register, unsigned data, unsigned mask)
|
||||
{
|
||||
uint8_t reg = i2c_register & 0xFF;
|
||||
|
@ -1170,11 +1240,6 @@ int r82xx_set_i2c_override(struct r82xx_priv *priv, unsigned i2c_register, unsig
|
|||
}
|
||||
|
||||
|
||||
/* 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
|
||||
};
|
||||
|
||||
|
||||
struct IFinfo
|
||||
{
|
||||
|
@ -1261,6 +1326,15 @@ static const struct IFinfo IFi[] = {
|
|||
{ 3, 1950+3, 1500, 30, 0x0F, 0x8F, 0x60 }
|
||||
};
|
||||
|
||||
|
||||
/* settings from Oldenburger:
|
||||
static const int r82xx_bws[]= { 300, 450, 600, 900, 1100, 1200, 1300, 1500, 1800, 2200, 3000, 5000 };
|
||||
static const uint8_t r82xx_0xa[]= { 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0f, 0x0f, 0x04, 0x0b };
|
||||
static const uint8_t r82xx_0xb[]= { 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xaf, 0x8f, 0x8f, 0x6b };
|
||||
static const int r82xx_if[] = { 1700, 1650, 1600, 1500, 1400, 1350, 1320, 1270, 1400, 1600, 2000, 3570 };
|
||||
*/
|
||||
|
||||
|
||||
static const int r82xx_bw_tablen = sizeof(IFi) / sizeof(IFi[0]);
|
||||
|
||||
|
||||
|
@ -1456,17 +1530,33 @@ int r82xx_set_bw_center(struct r82xx_priv *priv, int32_t if_band_center_freq)
|
|||
return priv->int_freq;
|
||||
}
|
||||
|
||||
int r82xx_set_sideband(struct r82xx_priv *priv, int sideband)
|
||||
{
|
||||
int rc;
|
||||
priv->sideband = sideband;
|
||||
rc = r82xx_write_reg_mask(priv, 0x07, (sideband << 7) & 0x80, 0x80);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r82xx_set_freq(struct r82xx_priv *priv, uint32_t freq)
|
||||
{
|
||||
int rc = -1;
|
||||
uint32_t lo_freq = freq + priv->int_freq + priv->if_band_center_freq;
|
||||
uint32_t lo_freq;
|
||||
uint8_t air_cable1_in;
|
||||
|
||||
if(priv->sideband)
|
||||
lo_freq = freq - priv->int_freq + priv->if_band_center_freq;
|
||||
else
|
||||
lo_freq = freq + priv->int_freq + priv->if_band_center_freq;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "%s(freq = %u) --> intfreq %u, ifcenter %d --> f %u\n"
|
||||
, __FUNCTION__, (unsigned)freq
|
||||
fprintf(stderr, "%s(freq = %u) @ %s--> intfreq %u, ifcenter %d --> f %u\n"
|
||||
, __FUNCTION__, (unsigned)freq, (priv->sideband ? "USB" : "LSB")
|
||||
, (unsigned)priv->int_freq, (int)priv->if_band_center_freq
|
||||
, (unsigned)lo_freq );
|
||||
#endif
|
||||
uint8_t air_cable1_in;
|
||||
|
||||
rc = r82xx_set_mux(priv, lo_freq);
|
||||
if (rc < 0)
|
||||
|
@ -1548,65 +1638,6 @@ int r82xx_standby(struct r82xx_priv *priv)
|
|||
* r82xx device init logic
|
||||
*/
|
||||
|
||||
static int r82xx_xtal_check(struct r82xx_priv *priv)
|
||||
{
|
||||
int rc;
|
||||
unsigned int i;
|
||||
uint8_t data[3], val;
|
||||
|
||||
/* Initialize the shadow registers */
|
||||
memcpy(priv->regs, r82xx_init_array, sizeof(r82xx_init_array));
|
||||
|
||||
/* cap 30pF & Drive Low */
|
||||
rc = r82xx_write_reg_mask(priv, 0x10, 0x0b, 0x0b);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* set pll autotune = 128kHz */
|
||||
rc = r82xx_write_reg_mask(priv, 0x1a, 0x00, 0x0c);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* set manual initial reg = 111111; */
|
||||
rc = r82xx_write_reg_mask(priv, 0x13, 0x7f, 0x7f);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* set auto */
|
||||
rc = r82xx_write_reg_mask(priv, 0x13, 0x00, 0x40);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Try several xtal capacitor alternatives */
|
||||
for (i = 0; i < ARRAY_SIZE(r82xx_xtal_capacitor); i++) {
|
||||
rc = r82xx_write_reg_mask(priv, 0x10,
|
||||
r82xx_xtal_capacitor[i][0], 0x1b);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
// usleep_range(5000, 6000);
|
||||
|
||||
rc = r82xx_read(priv, 0x00, data, sizeof(data));
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (!(data[2] & 0x40))
|
||||
continue;
|
||||
|
||||
val = data[2] & 0x3f;
|
||||
|
||||
if (priv->cfg->xtal == 16000000 && (val > 29 || val < 23))
|
||||
break;
|
||||
|
||||
if (val != 0x3f)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_SIZE(r82xx_xtal_capacitor))
|
||||
return -1;
|
||||
|
||||
return r82xx_xtal_capacitor[i][1];
|
||||
}
|
||||
|
||||
int r82xx_init(struct r82xx_priv *priv)
|
||||
{
|
||||
int rc;
|
||||
|
@ -1629,11 +1660,11 @@ int r82xx_init(struct r82xx_priv *priv)
|
|||
rc = r82xx_write_arr(priv, 0x05,
|
||||
r82xx_init_array, sizeof(r82xx_init_array));
|
||||
|
||||
rc = r82xx_set_tv_standard(priv, 3, TUNER_DIGITAL_TV, 0);
|
||||
rc = r82xx_set_tv_standard(priv, TUNER_DIGITAL_TV, 0);
|
||||
if (rc < 0)
|
||||
goto err;
|
||||
|
||||
rc = r82xx_sysfreq_sel(priv, 0, TUNER_DIGITAL_TV, SYS_DVBT);
|
||||
rc = r82xx_sysfreq_sel(priv, TUNER_DIGITAL_TV);
|
||||
|
||||
#if USE_R82XX_ENV_VARS
|
||||
priv->printI2C = 0;
|
||||
|
|
Loading…
Reference in New Issue