2011-09-24 14:01:05 +02:00
|
|
|
/* -*- c++ -*- */
|
|
|
|
|
/*
|
2012-02-23 21:55:43 +01:00
|
|
|
* Copyright 2011-2012 Alexandru Csete OZ9AEC.
|
2011-09-24 14:01:05 +02:00
|
|
|
*
|
|
|
|
|
* Gqrx is free software; you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation; either version 3, or (at your option)
|
|
|
|
|
* any later version.
|
|
|
|
|
*
|
|
|
|
|
* Gqrx 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 Gqrx; see the file COPYING. If not, write to
|
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
|
*/
|
2012-02-25 00:00:00 +01:00
|
|
|
#include <iostream>
|
2012-05-12 15:47:27 +02:00
|
|
|
#include "input/fcdctl/fcd.h"
|
|
|
|
|
#include "input/fcdctl/fcdhidcmd.h"
|
2012-02-23 21:55:43 +01:00
|
|
|
#include "rx_source_fcd.h"
|
2011-09-24 14:01:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
rx_source_fcd_sptr make_rx_source_fcd(const std::string device_name)
|
|
|
|
|
{
|
|
|
|
|
return gnuradio::get_initial_sptr(new rx_source_fcd(device_name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rx_source_fcd::rx_source_fcd(const std::string device_name)
|
|
|
|
|
: rx_source_base("rx_source_fcd"),
|
|
|
|
|
d_freq(144.5e6),
|
2012-05-06 15:59:48 +02:00
|
|
|
d_freq_corr(-12), // S/N 820 or greater
|
2011-09-24 14:01:05 +02:00
|
|
|
d_gain(20.0)
|
|
|
|
|
{
|
2012-02-23 21:55:43 +01:00
|
|
|
d_audio_src = make_pa_source(device_name, 96000, 2, "GQRX", "I/Q input");
|
2011-09-24 14:01:05 +02:00
|
|
|
/** TODO: check error */
|
|
|
|
|
|
2012-02-23 21:55:43 +01:00
|
|
|
d_f2c = gr_make_float_to_complex(1);
|
|
|
|
|
|
2011-09-24 14:01:05 +02:00
|
|
|
// populate supported sample rates
|
|
|
|
|
d_sample_rates.push_back(96000.0);
|
|
|
|
|
|
2012-02-23 21:55:43 +01:00
|
|
|
connect(d_audio_src, 0, d_f2c, 0);
|
|
|
|
|
connect(d_audio_src, 1, d_f2c, 1);
|
|
|
|
|
connect(d_f2c, 0, self(), 0);
|
2012-02-25 00:00:00 +01:00
|
|
|
|
|
|
|
|
set_freq(144.5e6f);
|
|
|
|
|
set_gain(20.0f);
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rx_source_fcd::~rx_source_fcd()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void rx_source_fcd::select_device(const std::string device_name)
|
|
|
|
|
{
|
2012-02-23 21:55:43 +01:00
|
|
|
d_audio_src->select_device(device_name);
|
|
|
|
|
|
|
|
|
|
/** FIXME **/
|
|
|
|
|
//d_fcd_src->set_freq((float) d_freq);
|
|
|
|
|
//d_fcd_src->set_lna_gain((float) d_gain);
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rx_source_fcd::set_freq(double freq)
|
|
|
|
|
{
|
2012-02-25 00:00:00 +01:00
|
|
|
FCD_MODE_ENUM fme;
|
2012-05-06 15:59:48 +02:00
|
|
|
double f = freq;
|
2012-02-25 00:00:00 +01:00
|
|
|
|
|
|
|
|
if ((freq >= get_freq_min()) && (freq <= get_freq_max()))
|
|
|
|
|
{
|
2011-09-24 14:01:05 +02:00
|
|
|
d_freq = freq;
|
2012-05-06 15:59:48 +02:00
|
|
|
|
|
|
|
|
f *= 1.0 + d_freq_corr/1000000.0;
|
|
|
|
|
fme = fcdAppSetFreq((int)f);
|
2012-02-25 00:00:00 +01:00
|
|
|
|
|
|
|
|
if (fme != FCD_MODE_APP)
|
|
|
|
|
{
|
|
|
|
|
/** FIXME: error message **/
|
|
|
|
|
}
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|
2012-02-25 00:00:00 +01:00
|
|
|
|
|
|
|
|
#ifndef QT_NO_DEBUG_OUTPUT
|
2012-03-03 15:21:05 +01:00
|
|
|
std::cout << "FCD source new freq: " << (int) d_freq << " Hz" << std::endl;
|
2012-02-25 00:00:00 +01:00
|
|
|
#endif
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_freq()
|
|
|
|
|
{
|
|
|
|
|
return d_freq;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_freq_min()
|
|
|
|
|
{
|
|
|
|
|
return 50.0e6;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_freq_max()
|
|
|
|
|
{
|
|
|
|
|
return 2.0e9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rx_source_fcd::set_gain(double gain)
|
|
|
|
|
{
|
2012-02-25 00:00:00 +01:00
|
|
|
FCD_MODE_ENUM fme;
|
|
|
|
|
unsigned char g;
|
|
|
|
|
|
|
|
|
|
if ((gain >= get_gain_min()) && (gain <= get_gain_max()))
|
|
|
|
|
{
|
2011-09-24 14:01:05 +02:00
|
|
|
d_gain = gain;
|
2012-02-25 00:00:00 +01:00
|
|
|
|
|
|
|
|
/* convert gain to nearest discrete value */
|
|
|
|
|
if (gain > 27.5)
|
|
|
|
|
g = 14; // 30.0 dB
|
|
|
|
|
else if (gain > 22.5)
|
|
|
|
|
g = 13; // 25.0 dB
|
|
|
|
|
else if (gain > 18.75)
|
|
|
|
|
g = 12; // 20.0 dB
|
|
|
|
|
else if (gain > 16.25)
|
|
|
|
|
g = 11; // 17.5 dB
|
|
|
|
|
else if (gain > 13.75)
|
|
|
|
|
g = 10; // 15.0 dB
|
|
|
|
|
else if (gain > 11.25)
|
|
|
|
|
g = 9; // 12.5 dB
|
|
|
|
|
else if (gain > 8.75)
|
|
|
|
|
g = 8; // 10.0 dB
|
|
|
|
|
else if (gain > 6.25)
|
|
|
|
|
g = 7; // 7.5 dB
|
|
|
|
|
else if (gain > 3.75)
|
|
|
|
|
g = 6; // 5.0 dB
|
|
|
|
|
else if (gain > 1.25)
|
|
|
|
|
g = 5; // 2.5 dB
|
|
|
|
|
else if (gain > -1.25)
|
|
|
|
|
g = 4; // 0.0 dB
|
|
|
|
|
else if (gain > -3.75)
|
|
|
|
|
g = 1; // -2.5 dB
|
|
|
|
|
else
|
|
|
|
|
g = 0; // -5.0 dB
|
|
|
|
|
|
|
|
|
|
fme = fcdAppSetParam(FCD_CMD_APP_SET_LNA_GAIN, &g, 1);
|
|
|
|
|
if (fme != FCD_MODE_APP)
|
|
|
|
|
{
|
|
|
|
|
/** FIUXME: error message **/
|
|
|
|
|
}
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_gain()
|
|
|
|
|
{
|
|
|
|
|
return d_gain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_gain_min()
|
|
|
|
|
{
|
|
|
|
|
return -5.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_gain_max()
|
|
|
|
|
{
|
|
|
|
|
return 30.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rx_source_fcd::set_sample_rate(double sps)
|
|
|
|
|
{
|
|
|
|
|
// nothing to do;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double rx_source_fcd::get_sample_rate()
|
|
|
|
|
{
|
|
|
|
|
return 96000.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<double> rx_source_fcd::get_sample_rates()
|
|
|
|
|
{
|
|
|
|
|
return d_sample_rates;
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-23 21:55:43 +01:00
|
|
|
/** FIXME: Remove? */
|
2012-02-01 14:54:10 -05:00
|
|
|
void rx_source_fcd::set_freq_corr(int ppm)
|
|
|
|
|
{
|
2012-05-06 15:59:48 +02:00
|
|
|
d_freq_corr = ppm;
|
|
|
|
|
set_freq(d_freq);
|
2012-02-01 14:54:10 -05:00
|
|
|
}
|
|
|
|
|
|
2012-02-23 21:55:43 +01:00
|
|
|
/** FIXME: Remove? */
|
2011-09-24 14:01:05 +02:00
|
|
|
void rx_source_fcd::set_dc_corr(double dci, double dcq)
|
|
|
|
|
{
|
2012-02-23 21:55:43 +01:00
|
|
|
//d_fcd_src->set_dc_corr(dci, dcq);
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|
|
|
|
|
|
2012-02-23 21:55:43 +01:00
|
|
|
/** FIXME: Remove? */
|
2012-05-06 22:17:09 +02:00
|
|
|
void rx_source_fcd::set_iq_corr(double _gain, double _phase)
|
2011-09-24 14:01:05 +02:00
|
|
|
{
|
2012-05-06 22:17:09 +02:00
|
|
|
FCD_MODE_ENUM fme;
|
|
|
|
|
union {
|
|
|
|
|
unsigned char auc[4];
|
|
|
|
|
struct {
|
|
|
|
|
signed short phase;
|
|
|
|
|
signed short gain;
|
|
|
|
|
};
|
|
|
|
|
} iqinfo;
|
|
|
|
|
|
|
|
|
|
if ((_gain < -1.0) || (_gain > 1.0) || (_phase < -1.0) || (_phase > 1.0))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
#ifndef QT_NO_DEBUG_OUTPUT
|
|
|
|
|
std::cout << "FCD source I/Q corr phase:" << _phase << " gain:" << _gain << std::endl;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
iqinfo.phase = static_cast<signed short>(_phase*32768.0);
|
|
|
|
|
iqinfo.gain = static_cast<signed short>(_gain*32768.0);
|
|
|
|
|
|
|
|
|
|
fme = fcdAppSetParam(FCD_CMD_APP_SET_IQ_CORR, iqinfo.auc, 4);
|
|
|
|
|
if (fme != FCD_MODE_APP)
|
|
|
|
|
{
|
|
|
|
|
/** FIUXME: error message **/
|
|
|
|
|
}
|
2011-09-24 14:01:05 +02:00
|
|
|
}
|