mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-trx.git
synced 2025-11-17 20:31:41 +00:00
Compare commits
6 Commits
mstx_newtr
...
fairwaves/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2518186b45 | ||
|
|
6512812e43 | ||
|
|
ded68da44f | ||
|
|
37bbfa2125 | ||
|
|
fdbf914584 | ||
|
|
bbef7e4d70 |
@@ -206,7 +206,7 @@ Log::~Log()
|
|||||||
if (gLogToConsole||gLogToFile) {
|
if (gLogToConsole||gLogToFile) {
|
||||||
int mlen = mStream.str().size();
|
int mlen = mStream.str().size();
|
||||||
int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
|
int neednl = (mlen==0 || mStream.str()[mlen-1] != '\n');
|
||||||
gLogToLock.lock();
|
ScopedLock lock(gLogToLock);
|
||||||
if (gLogToConsole) {
|
if (gLogToConsole) {
|
||||||
// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
|
// The COUT() macro prevents messages from stomping each other but adds uninteresting thread numbers,
|
||||||
// so just use std::cout.
|
// so just use std::cout.
|
||||||
@@ -218,7 +218,6 @@ Log::~Log()
|
|||||||
if (neednl) {fputc('\n',gLogToFile);}
|
if (neednl) {fputc('\n',gLogToFile);}
|
||||||
fflush(gLogToFile);
|
fflush(gLogToFile);
|
||||||
}
|
}
|
||||||
gLogToLock.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <iomanip> // std::setprecision
|
||||||
#include "Transceiver.h"
|
#include "Transceiver.h"
|
||||||
#include <Logger.h>
|
#include <Logger.h>
|
||||||
|
|
||||||
@@ -140,13 +141,15 @@ bool TransceiverState::init(int filler, size_t sps, float scale, size_t rtsc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Transceiver::Transceiver(int wBasePort,
|
Transceiver::Transceiver(int wBasePort,
|
||||||
const char *wTRXAddress,
|
const char *wTRXAddress,
|
||||||
size_t wSPS, size_t wChans,
|
size_t wSPS, size_t wChans,
|
||||||
GSM::Time wTransmitLatency,
|
GSM::Time wTransmitLatency,
|
||||||
RadioInterface *wRadioInterface)
|
RadioInterface *wRadioInterface,
|
||||||
|
double wRssiOffset)
|
||||||
: mBasePort(wBasePort), mAddr(wTRXAddress),
|
: mBasePort(wBasePort), mAddr(wTRXAddress),
|
||||||
mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
|
mClockSocket(wBasePort, wTRXAddress, mBasePort + 100),
|
||||||
mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
|
mTransmitLatency(wTransmitLatency), mRadioInterface(wRadioInterface),
|
||||||
|
rssiOffset(wRssiOffset),
|
||||||
mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
|
mSPSTx(wSPS), mSPSRx(1), mChans(wChans), mOn(false),
|
||||||
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0)
|
mTxFreq(0.0), mRxFreq(0.0), mTSC(0), mMaxExpectedDelay(0)
|
||||||
{
|
{
|
||||||
@@ -531,9 +534,9 @@ Transceiver::CorrType Transceiver::expectedCorrType(GSM::Time currTime,
|
|||||||
* Detect RACH synchronization sequence within a burst. No equalization
|
* Detect RACH synchronization sequence within a burst. No equalization
|
||||||
* is used or available on the RACH channel.
|
* is used or available on the RACH channel.
|
||||||
*/
|
*/
|
||||||
bool Transceiver::detectRACH(TransceiverState *state,
|
int Transceiver::detectRACH(TransceiverState *state,
|
||||||
signalVector &burst,
|
signalVector &burst,
|
||||||
complex &, float &toa)
|
complex &, float &toa)
|
||||||
{
|
{
|
||||||
float threshold = 6.0;
|
float threshold = 6.0;
|
||||||
|
|
||||||
@@ -545,9 +548,10 @@ bool Transceiver::detectRACH(TransceiverState *state,
|
|||||||
* state information and channel estimate if necessary. Equalization
|
* state information and channel estimate if necessary. Equalization
|
||||||
* is currently disabled.
|
* is currently disabled.
|
||||||
*/
|
*/
|
||||||
bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
|
int Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
|
||||||
complex &, float &toa, GSM::Time &time)
|
complex &, float &toa, GSM::Time &time)
|
||||||
{
|
{
|
||||||
|
int success;
|
||||||
int tn = time.TN();
|
int tn = time.TN();
|
||||||
float chanOffset, threshold = 5.0;
|
float chanOffset, threshold = 5.0;
|
||||||
bool noise, needDFE = false, estimateChan = false;
|
bool noise, needDFE = false, estimateChan = false;
|
||||||
@@ -565,10 +569,11 @@ bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Detect normal burst midambles */
|
/* Detect normal burst midambles */
|
||||||
if (!analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, &,
|
success = analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, &,
|
||||||
&toa, mMaxExpectedDelay, estimateChan,
|
&toa, mMaxExpectedDelay, estimateChan,
|
||||||
&chanResp, &chanOffset)) {
|
&chanResp, &chanOffset);
|
||||||
return false;
|
if (success <= 0) {
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
noise = state->mNoiseLev;
|
noise = state->mNoiseLev;
|
||||||
@@ -588,7 +593,7 @@ bool Transceiver::detectTSC(TransceiverState *state, signalVector &burst,
|
|||||||
state->chanEstimateTime[tn] = time;
|
state->chanEstimateTime[tn] = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -615,10 +620,12 @@ SoftVector *Transceiver::demodulate(TransceiverState *state,
|
|||||||
* Pull bursts from the FIFO and handle according to the slot
|
* Pull bursts from the FIFO and handle according to the slot
|
||||||
* and burst correlation type. Equalzation is currently disabled.
|
* and burst correlation type. Equalzation is currently disabled.
|
||||||
*/
|
*/
|
||||||
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
|
SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI,
|
||||||
int &timingOffset, size_t chan)
|
double &timingOffset, double &noise,
|
||||||
|
size_t chan)
|
||||||
{
|
{
|
||||||
bool success, equalize = false;
|
int success;
|
||||||
|
bool equalize = false;
|
||||||
complex amp;
|
complex amp;
|
||||||
float toa, pow, max = -1.0, avg = 0.0;
|
float toa, pow, max = -1.0, avg = 0.0;
|
||||||
int max_i = -1;
|
int max_i = -1;
|
||||||
@@ -669,12 +676,12 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
|
|||||||
|
|
||||||
/* Update noise average if no bust detected or alert on error */
|
/* Update noise average if no bust detected or alert on error */
|
||||||
if (success <= 0) {
|
if (success <= 0) {
|
||||||
if (!success) {
|
if (success == SIGERR_NONE) {
|
||||||
state->mNoises.insert(avg);
|
state->mNoises.insert(avg);
|
||||||
} else if (success == -SIGERR_CLIP) {
|
} else if (success == -SIGERR_CLIP) {
|
||||||
LOG(ALERT) << "Clipping detected on RACH input";
|
LOG(WARNING) << "Clipping detected on received RACH or Normal Burst";
|
||||||
} else if (success < 0) {
|
} else {
|
||||||
LOG(ALERT) << "Unhandled RACH error";
|
LOG(WARNING) << "Unhandled RACH or Normal Burst detection error";
|
||||||
}
|
}
|
||||||
|
|
||||||
delete radio_burst;
|
delete radio_burst;
|
||||||
@@ -689,8 +696,9 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, int &RSSI,
|
|||||||
bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
|
bits = demodulate(state, *burst, amp, toa, time.TN(), equalize);
|
||||||
|
|
||||||
wTime = time;
|
wTime = time;
|
||||||
RSSI = (int) floor(20.0 * log10(rxFullScale / avg));
|
RSSI = 20.0 * log10(rxFullScale / avg);
|
||||||
timingOffset = (int) round(toa * 256.0 / mSPSRx);
|
timingOffset = toa / mSPSRx;
|
||||||
|
noise = 20.0 * log10(rxFullScale / state->mNoiseLev);
|
||||||
|
|
||||||
delete radio_burst;
|
delete radio_burst;
|
||||||
|
|
||||||
@@ -892,27 +900,33 @@ void Transceiver::driveReceiveRadio()
|
|||||||
void Transceiver::driveReceiveFIFO(size_t chan)
|
void Transceiver::driveReceiveFIFO(size_t chan)
|
||||||
{
|
{
|
||||||
SoftVector *rxBurst = NULL;
|
SoftVector *rxBurst = NULL;
|
||||||
int RSSI;
|
double RSSI; // in dBFS
|
||||||
int TOA; // in 1/256 of a symbol
|
double dBm; // in dBm
|
||||||
|
double TOA; // in symbols
|
||||||
|
int TOAint; // in 1/256 symbols
|
||||||
|
double noise; // noise level in dBFS
|
||||||
GSM::Time burstTime;
|
GSM::Time burstTime;
|
||||||
|
|
||||||
rxBurst = pullRadioVector(burstTime, RSSI, TOA, chan);
|
rxBurst = pullRadioVector(burstTime, RSSI, TOA, noise, chan);
|
||||||
|
|
||||||
if (rxBurst) {
|
if (rxBurst) {
|
||||||
|
dBm = RSSI+rssiOffset;
|
||||||
|
TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer
|
||||||
|
|
||||||
|
LOG(DEBUG) << std::fixed << std::right
|
||||||
|
<< " time: " << burstTime
|
||||||
|
<< " RSSI: " << std::setw(5) << std::setprecision(1) << RSSI << "dBFS/" << std::setw(6) << -dBm << "dBm"
|
||||||
|
<< " noise: " << std::setw(5) << std::setprecision(1) << noise << "dBFS/" << std::setw(6) << -(noise+rssiOffset) << "dBm"
|
||||||
|
<< " TOA: " << std::setw(5) << std::setprecision(2) << TOA
|
||||||
|
<< " bits: " << *rxBurst;
|
||||||
|
|
||||||
LOG(DEBUG) << "burst parameters: "
|
|
||||||
<< " time: " << burstTime
|
|
||||||
<< " RSSI: " << RSSI
|
|
||||||
<< " TOA: " << TOA
|
|
||||||
<< " bits: " << *rxBurst;
|
|
||||||
|
|
||||||
char burstString[gSlotLen+10];
|
char burstString[gSlotLen+10];
|
||||||
burstString[0] = burstTime.TN();
|
burstString[0] = burstTime.TN();
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
|
burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff;
|
||||||
burstString[5] = RSSI;
|
burstString[5] = (int)dBm;
|
||||||
burstString[6] = (TOA >> 8) & 0x0ff;
|
burstString[6] = (TOAint >> 8) & 0x0ff;
|
||||||
burstString[7] = TOA & 0x0ff;
|
burstString[7] = TOAint & 0x0ff;
|
||||||
SoftVector::iterator burstItr = rxBurst->begin();
|
SoftVector::iterator burstItr = rxBurst->begin();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < gSlotLen; i++) {
|
for (unsigned int i = 0; i < gSlotLen; i++) {
|
||||||
|
|||||||
@@ -97,10 +97,11 @@ public:
|
|||||||
@param radioInterface associated radioInterface object
|
@param radioInterface associated radioInterface object
|
||||||
*/
|
*/
|
||||||
Transceiver(int wBasePort,
|
Transceiver(int wBasePort,
|
||||||
const char *TRXAddress,
|
const char *TRXAddress,
|
||||||
size_t wSPS, size_t chans,
|
size_t wSPS, size_t chans,
|
||||||
GSM::Time wTransmitLatency,
|
GSM::Time wTransmitLatency,
|
||||||
RadioInterface *wRadioInterface);
|
RadioInterface *wRadioInterface,
|
||||||
|
double wRssiOffset);
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~Transceiver();
|
~Transceiver();
|
||||||
@@ -181,6 +182,8 @@ private:
|
|||||||
double txFullScale; ///< full scale input to radio
|
double txFullScale; ///< full scale input to radio
|
||||||
double rxFullScale; ///< full scale output to radio
|
double rxFullScale; ///< full scale output to radio
|
||||||
|
|
||||||
|
double rssiOffset; ///< RSSI to dBm conversion offset
|
||||||
|
|
||||||
/** modulate and add a burst to the transmit queue */
|
/** modulate and add a burst to the transmit queue */
|
||||||
void addRadioVector(size_t chan, BitVector &bits,
|
void addRadioVector(size_t chan, BitVector &bits,
|
||||||
int RSSI, GSM::Time &wTime);
|
int RSSI, GSM::Time &wTime);
|
||||||
@@ -192,8 +195,9 @@ private:
|
|||||||
void pushRadioVector(GSM::Time &nowTime);
|
void pushRadioVector(GSM::Time &nowTime);
|
||||||
|
|
||||||
/** Pull and demodulate a burst from the receive FIFO */
|
/** Pull and demodulate a burst from the receive FIFO */
|
||||||
SoftVector *pullRadioVector(GSM::Time &wTime, int &RSSI,
|
SoftVector *pullRadioVector(GSM::Time &wTime, double &RSSI,
|
||||||
int &timingOffset, size_t chan = 0);
|
double &timingOffset, double &noise,
|
||||||
|
size_t chan = 0);
|
||||||
|
|
||||||
/** Set modulus for specific timeslot */
|
/** Set modulus for specific timeslot */
|
||||||
void setModulus(size_t timeslot, size_t chan);
|
void setModulus(size_t timeslot, size_t chan);
|
||||||
@@ -205,14 +209,14 @@ private:
|
|||||||
void writeClockInterface(void);
|
void writeClockInterface(void);
|
||||||
|
|
||||||
/** Detect RACH bursts */
|
/** Detect RACH bursts */
|
||||||
bool detectRACH(TransceiverState *state,
|
int detectRACH(TransceiverState *state,
|
||||||
signalVector &burst,
|
signalVector &burst,
|
||||||
complex &, float &toa);
|
complex &, float &toa);
|
||||||
|
|
||||||
/** Detect normal bursts */
|
/** Detect normal bursts */
|
||||||
bool detectTSC(TransceiverState *state,
|
int detectTSC(TransceiverState *state,
|
||||||
signalVector &burst,
|
signalVector &burst,
|
||||||
complex &, float &toa, GSM::Time &time);
|
complex &, float &toa, GSM::Time &time);
|
||||||
|
|
||||||
/** Demodulat burst and output soft bits */
|
/** Demodulat burst and output soft bits */
|
||||||
SoftVector *demodulate(TransceiverState *state,
|
SoftVector *demodulate(TransceiverState *state,
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ struct trx_config {
|
|||||||
Transceiver::FillerType filler;
|
Transceiver::FillerType filler;
|
||||||
bool diversity;
|
bool diversity;
|
||||||
double offset;
|
double offset;
|
||||||
|
double rssi_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
ConfigurationTable gConfig;
|
ConfigurationTable gConfig;
|
||||||
@@ -185,6 +186,7 @@ bool trx_setup_config(struct trx_config *config)
|
|||||||
ost << " C0 Filler Table......... " << fillstr << std::endl;
|
ost << " C0 Filler Table......... " << fillstr << std::endl;
|
||||||
ost << " Diversity............... " << divstr << std::endl;
|
ost << " Diversity............... " << divstr << std::endl;
|
||||||
ost << " Tuning offset........... " << config->offset << std::endl;
|
ost << " Tuning offset........... " << config->offset << std::endl;
|
||||||
|
ost << " RSSI to dBm offset...... " << config->rssi_offset << std::endl;
|
||||||
std::cout << ost << std::endl;
|
std::cout << ost << std::endl;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -240,7 +242,7 @@ Transceiver *makeTransceiver(struct trx_config *config, RadioInterface *radio)
|
|||||||
VectorFIFO *fifo;
|
VectorFIFO *fifo;
|
||||||
|
|
||||||
trx = new Transceiver(config->port, config->addr.c_str(), config->sps,
|
trx = new Transceiver(config->port, config->addr.c_str(), config->sps,
|
||||||
config->chans, GSM::Time(3,0), radio);
|
config->chans, GSM::Time(3,0), radio, config->rssi_offset);
|
||||||
if (!trx->init(config->filler, config->rtsc)) {
|
if (!trx->init(config->filler, config->rtsc)) {
|
||||||
LOG(ALERT) << "Failed to initialize transceiver";
|
LOG(ALERT) << "Failed to initialize transceiver";
|
||||||
delete trx;
|
delete trx;
|
||||||
@@ -292,7 +294,8 @@ static void print_help()
|
|||||||
" -c Number of ARFCN channels (default=1)\n"
|
" -c Number of ARFCN channels (default=1)\n"
|
||||||
" -f Enable C0 filler table\n"
|
" -f Enable C0 filler table\n"
|
||||||
" -o Set baseband frequency offset (default=auto)\n"
|
" -o Set baseband frequency offset (default=auto)\n"
|
||||||
" -r Random burst test mode with TSC\n",
|
" -r Random burst test mode with TSC\n"
|
||||||
|
" -R RSSI to dBm offset in dB (default=0)\n",
|
||||||
"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
|
"EMERG, ALERT, CRT, ERR, WARNING, NOTICE, INFO, DEBUG");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,8 +311,9 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
|||||||
config->filler = Transceiver::FILLER_ZERO;
|
config->filler = Transceiver::FILLER_ZERO;
|
||||||
config->diversity = false;
|
config->diversity = false;
|
||||||
config->offset = 0.0;
|
config->offset = 0.0;
|
||||||
|
config->rssi_offset = 0.0;
|
||||||
|
|
||||||
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:")) != -1) {
|
while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:")) != -1) {
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case 'h':
|
case 'h':
|
||||||
print_help();
|
print_help();
|
||||||
@@ -349,6 +353,9 @@ static void handle_options(int argc, char **argv, struct trx_config *config)
|
|||||||
config->rtsc = atoi(optarg);
|
config->rtsc = atoi(optarg);
|
||||||
config->filler = Transceiver::FILLER_RAND;
|
config->filler = Transceiver::FILLER_RAND;
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
config->rssi_offset = atof(optarg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print_help();
|
print_help();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
#include "sigProcLib.h"
|
#include "sigProcLib.h"
|
||||||
#include "GSMCommon.h"
|
#include "GSMCommon.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "convolve.h"
|
#include "convolve.h"
|
||||||
@@ -43,6 +44,9 @@ using namespace GSM;
|
|||||||
/* Clipping detection threshold */
|
/* Clipping detection threshold */
|
||||||
#define CLIP_THRESH 30000.0f
|
#define CLIP_THRESH 30000.0f
|
||||||
|
|
||||||
|
/* GSM 4 sps burst length */
|
||||||
|
#define GSM_BURST_LEN_4SPS 625
|
||||||
|
|
||||||
/** Lookup tables for trigonometric approximation */
|
/** Lookup tables for trigonometric approximation */
|
||||||
float cosTable[TABLESIZE+1]; // add 1 element for wrap around
|
float cosTable[TABLESIZE+1]; // add 1 element for wrap around
|
||||||
float sinTable[TABLESIZE+1];
|
float sinTable[TABLESIZE+1];
|
||||||
@@ -696,27 +700,22 @@ static signalVector *rotateBurst(const BitVector &wBurst,
|
|||||||
return shaped;
|
return shaped;
|
||||||
}
|
}
|
||||||
|
|
||||||
static signalVector *modulateBurstLaurent(const BitVector &bits,
|
/*
|
||||||
int guard_len, int sps)
|
* Laurent decomposition based GMSK modulator - 4 SPS only
|
||||||
|
*/
|
||||||
|
static signalVector *modulateBurstLaurent(const BitVector &bits)
|
||||||
{
|
{
|
||||||
int burst_len;
|
const int burst_len = GSM_BURST_LEN_4SPS;
|
||||||
|
const int sps = 4;
|
||||||
|
|
||||||
float phase;
|
float phase;
|
||||||
signalVector *c0_pulse, *c1_pulse, *c0_burst;
|
signalVector *c0_pulse, *c1_pulse, *c0_burst;
|
||||||
signalVector *c1_burst, *c0_shaped, *c1_shaped;
|
signalVector *c1_burst, *c0_shaped, *c1_shaped;
|
||||||
signalVector::iterator c0_itr, c1_itr;
|
signalVector::iterator c0_itr, c1_itr;
|
||||||
|
|
||||||
/*
|
|
||||||
* Apply before and after bits to reduce phase error at burst edges.
|
|
||||||
* Make sure there is enough room in the burst to accomodate all bits.
|
|
||||||
*/
|
|
||||||
if (guard_len < 4)
|
|
||||||
guard_len = 4;
|
|
||||||
|
|
||||||
c0_pulse = GSMPulse->c0;
|
c0_pulse = GSMPulse->c0;
|
||||||
c1_pulse = GSMPulse->c1;
|
c1_pulse = GSMPulse->c1;
|
||||||
|
|
||||||
burst_len = sps * (bits.size() + guard_len);
|
|
||||||
|
|
||||||
c0_burst = new signalVector(burst_len, c0_pulse->size());
|
c0_burst = new signalVector(burst_len, c0_pulse->size());
|
||||||
c0_burst->isReal(true);
|
c0_burst->isReal(true);
|
||||||
c0_itr = c0_burst->begin();
|
c0_itr = c0_burst->begin();
|
||||||
@@ -825,7 +824,7 @@ signalVector *modulateBurst(const BitVector &wBurst, int guardPeriodLength,
|
|||||||
if (emptyPulse)
|
if (emptyPulse)
|
||||||
return rotateBurst(wBurst, guardPeriodLength, sps);
|
return rotateBurst(wBurst, guardPeriodLength, sps);
|
||||||
else if (sps == 4)
|
else if (sps == 4)
|
||||||
return modulateBurstLaurent(wBurst, guardPeriodLength, sps);
|
return modulateBurstLaurent(wBurst);
|
||||||
else
|
else
|
||||||
return modulateBurstBasic(wBurst, guardPeriodLength, sps);
|
return modulateBurstBasic(wBurst, guardPeriodLength, sps);
|
||||||
}
|
}
|
||||||
@@ -1284,12 +1283,12 @@ static float computePeakRatio(signalVector *corr,
|
|||||||
complex *peak;
|
complex *peak;
|
||||||
float rms, avg = 0.0;
|
float rms, avg = 0.0;
|
||||||
|
|
||||||
peak = corr->begin() + (int) rint(toa);
|
|
||||||
|
|
||||||
/* Check for bogus results */
|
/* Check for bogus results */
|
||||||
if ((toa < 0.0) || (toa > corr->size()))
|
if ((toa < 0.0) || (toa > corr->size()))
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
|
peak = corr->begin() + (int) rint(toa);
|
||||||
|
|
||||||
for (int i = 2 * sps; i <= 5 * sps; i++) {
|
for (int i = 2 * sps; i <= 5 * sps; i++) {
|
||||||
if (peak - i >= corr->begin()) {
|
if (peak - i >= corr->begin()) {
|
||||||
avg += (peak - i)->norm2();
|
avg += (peak - i)->norm2();
|
||||||
@@ -1372,16 +1371,17 @@ static int detectBurst(signalVector &burst,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int detectClipping(signalVector &burst, float thresh)
|
static float maxAmplitude(signalVector &burst)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < burst.size(); i++) {
|
float max = 0.0;
|
||||||
if (fabs(burst[i].real()) > thresh)
|
for (size_t i = 0; i < burst.size(); i++) {
|
||||||
return 1;
|
if (fabs(burst[i].real()) > max)
|
||||||
if (fabs(burst[i].imag()) > thresh)
|
max = fabs(burst[i].real());
|
||||||
return 1;
|
if (fabs(burst[i].imag()) > max)
|
||||||
}
|
max = fabs(burst[i].imag());
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1399,6 +1399,7 @@ int detectRACHBurst(signalVector &rxBurst,
|
|||||||
float *toa)
|
float *toa)
|
||||||
{
|
{
|
||||||
int rc, start, target, head, tail, len;
|
int rc, start, target, head, tail, len;
|
||||||
|
bool clipping = false;
|
||||||
float _toa;
|
float _toa;
|
||||||
complex _amp;
|
complex _amp;
|
||||||
signalVector *corr;
|
signalVector *corr;
|
||||||
@@ -1407,8 +1408,14 @@ int detectRACHBurst(signalVector &rxBurst,
|
|||||||
if ((sps != 1) && (sps != 4))
|
if ((sps != 1) && (sps != 4))
|
||||||
return -SIGERR_UNSUPPORTED;
|
return -SIGERR_UNSUPPORTED;
|
||||||
|
|
||||||
if (detectClipping(rxBurst, CLIP_THRESH))
|
// Detect potential clipping
|
||||||
return -SIGERR_CLIP;
|
// We still may be able to demod the burst, so we'll give it a try
|
||||||
|
// and only report clipping if we can't demod.
|
||||||
|
float maxAmpl = maxAmplitude(rxBurst);
|
||||||
|
if (maxAmpl > CLIP_THRESH) {
|
||||||
|
LOG(DEBUG) << "max burst amplitude: " << maxAmpl << " is above the clipping threshold: " << CLIP_THRESH << std::endl;
|
||||||
|
clipping = true;
|
||||||
|
}
|
||||||
|
|
||||||
target = 8 + 40;
|
target = 8 + 40;
|
||||||
head = 4;
|
head = 4;
|
||||||
@@ -1430,7 +1437,7 @@ int detectRACHBurst(signalVector &rxBurst,
|
|||||||
*amp = 0.0f;
|
*amp = 0.0f;
|
||||||
if (toa)
|
if (toa)
|
||||||
*toa = 0.0f;
|
*toa = 0.0f;
|
||||||
return 0;
|
return clipping?-SIGERR_CLIP:SIGERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subtract forward search bits from delay */
|
/* Subtract forward search bits from delay */
|
||||||
@@ -1455,6 +1462,7 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
|
|||||||
bool chan_req, signalVector **chan, float *chan_offset)
|
bool chan_req, signalVector **chan, float *chan_offset)
|
||||||
{
|
{
|
||||||
int rc, start, target, head, tail, len;
|
int rc, start, target, head, tail, len;
|
||||||
|
bool clipping = false;
|
||||||
complex _amp;
|
complex _amp;
|
||||||
float _toa;
|
float _toa;
|
||||||
signalVector *corr;
|
signalVector *corr;
|
||||||
@@ -1463,8 +1471,14 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
|
|||||||
if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
|
if ((tsc < 0) || (tsc > 7) || ((sps != 1) && (sps != 4)))
|
||||||
return -SIGERR_UNSUPPORTED;
|
return -SIGERR_UNSUPPORTED;
|
||||||
|
|
||||||
if (detectClipping(rxBurst, CLIP_THRESH))
|
// Detect potential clipping
|
||||||
return -SIGERR_CLIP;
|
// We still may be able to demod the burst, so we'll give it a try
|
||||||
|
// and only report clipping if we can't demod.
|
||||||
|
float maxAmpl = maxAmplitude(rxBurst);
|
||||||
|
if (maxAmpl > CLIP_THRESH) {
|
||||||
|
LOG(DEBUG) << "max burst amplitude: " << maxAmpl << " is above the clipping threshold: " << CLIP_THRESH << std::endl;
|
||||||
|
clipping = true;
|
||||||
|
}
|
||||||
|
|
||||||
target = 3 + 58 + 16 + 5;
|
target = 3 + 58 + 16 + 5;
|
||||||
head = 4;
|
head = 4;
|
||||||
@@ -1486,7 +1500,7 @@ int analyzeTrafficBurst(signalVector &rxBurst, unsigned tsc, float thresh,
|
|||||||
*amp = 0.0f;
|
*amp = 0.0f;
|
||||||
if (toa)
|
if (toa)
|
||||||
*toa = 0.0f;
|
*toa = 0.0f;
|
||||||
return 0;
|
return clipping?-SIGERR_CLIP:SIGERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Subtract forward search bits from delay */
|
/* Subtract forward search bits from delay */
|
||||||
|
|||||||
Reference in New Issue
Block a user