1
0
mirror of https://github.com/JvanKatwijk/dabradio synced 2025-10-06 00:02:49 +02:00
Files
SDR-DAB_dabradio/devices/elad-s1-handler/elad-handler.cpp
JvanKatwijk ea6f006b3e first commit
2018-03-06 20:05:31 +01:00

220 lines
6.0 KiB
C++

#
/*
* Copyright (C) 2014
* Jan van Katwijk (J.vanKatwijk@gmail.com)
* Lazy Chair Programming
*
* This file is part of the Qt-DAB program
* Qt-DAB 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.
*
* Qt-DAB 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 Qt-DAB; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <QThread>
#include <QSettings>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
#include <QDir>
#include "elad-handler.h" // our header
#include "elad-worker.h" // the thread, reading in the data
#include "elad-loader.h" // function loader
#include <stdio.h>
#define RATE 3072000
// Currently, we do not have lots of settings,
// it just might change suddenly, but not today
eladHandler::eladHandler (QSettings *s) {
int16_t success;
this -> eladSettings = s;
this -> myFrame = new QFrame (NULL);
setupUi (myFrame);
myFrame -> show ();
_I_Buffer = NULL;
theLoader = NULL;
theWorker = NULL;
vfoOffset =
eladSettings -> value ("elad-offset", 0). toInt ();
//
// sometimes problems with dynamic linkage of libusb, it is
// loaded indirectly through the dll
if (libusb_init (NULL) < 0) {
fprintf (stderr, "libusb problem\n"); // should not happen
throw (21);
}
libusb_exit (NULL);
theLoader = new eladLoader (RATE, &success);
if (success != 0) {
if (success == -1)
QMessageBox::warning (myFrame, tr ("sdr"),
tr ("No success in loading libs\n"));
else
if (success == -2)
QMessageBox::warning (myFrame, tr ("sdr"),
tr ("No success in setting up USB\n"));
else
if (success == -3)
QMessageBox::warning (myFrame, tr ("sdr"),
tr ("No success in FPGA init\n"));
else
if (success == -4)
QMessageBox::warning (myFrame, tr ("sdr"),
tr ("No success in hardware init\n"));
statusLabel -> setText ("not functioning");
delete theLoader;
theLoader = NULL;
delete myFrame;
throw (21);
}
//
// Note (10.10.2014:
// It turns out that the elad provides for 32 bit samples
// packed as bytes
statusLabel -> setText ("Loaded");
//
// buffersize app 0.5 seconds of data
_I_Buffer = new RingBuffer<std::complex<float>>(32 * 32768);
vfoFrequency = Khz (220000);
//
// since localFilter and gainReduced are also used as
// parameter for the API functions, they are int's rather
// than bool.
localFilter = 0;
filterText -> setText ("no filter");
gainReduced = 0;
gainLabel -> setText ("0");
connect (hzOffset, SIGNAL (valueChanged (int)),
this, SLOT (setOffset (int)));
connect (gainReduction, SIGNAL (clicked (void)),
this, SLOT (setGainReduction (void)));
connect (filter, SIGNAL (clicked (void)),
this, SLOT (setFilter (void)));
}
//
eladHandler::~eladHandler (void) {
eladSettings -> setValue ("elad-offset", vfoOffset);
stopReader ();
if (_I_Buffer != NULL)
delete _I_Buffer;
if (theLoader != NULL)
delete theLoader;
if (theWorker != NULL)
delete theWorker;
}
int32_t eladHandler::defaultFrequency (void) {
return Khz (220000);
}
void eladHandler::setVFOFrequency (int32_t newFrequency) {
int32_t realFreq = newFrequency - vfoOffset;
if (theWorker == NULL) {
vfoFrequency = newFrequency - vfoOffset;
return;
}
theWorker -> setVFOFrequency (realFreq);
vfoFrequency = theWorker -> getVFOFrequency ();
}
int32_t eladHandler::getVFOFrequency (void) {
return vfoFrequency + vfoOffset;
}
bool eladHandler::restartReader (void) {
bool success;
if (theWorker != NULL)
return true;
_I_Buffer -> FlushRingBuffer ();
theWorker = new eladWorker (vfoFrequency,
theLoader,
this,
_I_Buffer,
&success);
fprintf (stderr, "worker started, success = %d\n", success);
return success;
}
void eladHandler::stopReader (void) {
if (theWorker == NULL)
return;
theWorker -> stop ();
while (theWorker -> isRunning ())
usleep (100);
delete theWorker;
theWorker = NULL;
}
// we are - in this context - certain that whenever getSamples
// is called, there are sufficient samples available.
int32_t eladHandler::getSamples (std::complex<float> *V, int32_t size) {
return _I_Buffer -> getDataFromBuffer (V, size);
}
int32_t eladHandler::Samples (void) {
return _I_Buffer -> GetRingBufferReadAvailable () / 2;
}
void eladHandler::resetBuffer (void) {
_I_Buffer -> FlushRingBuffer ();
}
//
// Although we are getting 30-more bits in, the adc in the
// elad gives us 14 bits. That + 20 db gain results in app 105 db
// plus a marge it is app 120 a 130 db, so the bit depth for the scope
// is 21
int16_t eladHandler::bitDepth (void) {
return 21;
}
//
void eladHandler::setOffset (int k) {
vfoOffset = k;
}
void eladHandler::setGainReduction (void) {
gainReduced = gainReduced == 1 ? 0 : 1;
theLoader -> set_en_ext_io_ATT20 (theLoader -> getHandle (),
&gainReduced);
gainLabel -> setText (gainReduced == 1 ? "-20" : "0");
}
void eladHandler::setFilter (void) {
localFilter = localFilter == 1 ? 0 : 1;
theLoader -> set_en_ext_io_LP30 (theLoader -> getHandle (),
&localFilter);
filterText -> setText (localFilter == 1 ? "30 Mhz" : "no filter");
}
void eladHandler::show_eladFrequency (int f) {
eladFrequency -> display (f);
}
void eladHandler::show_iqSwitch (bool b) {
if (b)
elad_iqSwitch -> setText ("reversed IQ");
else
elad_iqSwitch -> setText ("normal IQ");
}