diff options
author | Tom Tsou <tom.tsou@ettus.com> | 2016-03-06 03:44:34 -0800 |
---|---|---|
committer | Tom Tsou <tom.tsou@ettus.com> | 2016-03-08 17:44:53 -0800 |
commit | b0aefcbf47ed2eec1e4f3fd9bed72dde999913bf (patch) | |
tree | c9c605a9cca3890fc9c5c9e64c42279465bc1b3f | |
parent | d325343ecca5c6484eeda5ebf9e230c810ea4b82 (diff) |
EDGE: Add interfaces to enable EDGE transceiver
Create EDGE slot type in the Transceiver. When EDGE mode is enabled
for a particular slot, blind detection will be performed by
correlating against EDGE followed by normal bursts if no EDGE burst
is found.
Signed-off-by: Tom Tsou <tom.tsou@ettus.com>
-rw-r--r-- | Transceiver52M/Transceiver.cpp | 105 | ||||
-rw-r--r-- | Transceiver52M/Transceiver.h | 5 | ||||
-rw-r--r-- | Transceiver52M/osmo-trx.cpp | 23 | ||||
-rw-r--r-- | Transceiver52M/sigProcLib.h | 5 |
4 files changed, 99 insertions, 39 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp index 2be7ab0..255e120 100644 --- a/Transceiver52M/Transceiver.cpp +++ b/Transceiver52M/Transceiver.cpp @@ -367,7 +367,12 @@ void Transceiver::addRadioVector(size_t chan, BitVector &bits, return; } - burst = modulateBurst(bits, 8 + (wTime.TN() % 4 == 0), mSPSTx); + /* Use the number of bits as the EDGE burst indicator */ + if (bits.size() == EDGE_BURST_NBITS) + burst = modulateEdgeBurst(bits, mSPSTx); + else + burst = modulateBurst(bits, 8 + (wTime.TN() % 4 == 0), mSPSTx); + scaleVector(*burst, txFullScale * pow(10, -RSSI / 10)); radio_burst = new radioVector(wTime, burst); @@ -561,6 +566,13 @@ int Transceiver::detectBurst(TransceiverState *state, signalVector &burst, float threshold = 5.0, rc = 0; switch (type) { + case EDGE: + rc = detectEdgeBurst(burst, mTSC, threshold, mSPSRx, + amp, toa, mMaxExpectedDelay); + if (rc > 0) + break; + else + type = TSC; case TSC: rc = analyzeTrafficBurst(burst, mTSC, threshold, mSPSRx, amp, toa, mMaxExpectedDelay); @@ -573,6 +585,8 @@ int Transceiver::detectBurst(TransceiverState *state, signalVector &burst, LOG(ERR) << "Invalid correlation type"; } + if (rc > 0) + return type; return rc; } @@ -583,8 +597,11 @@ int Transceiver::detectBurst(TransceiverState *state, signalVector &burst, */ SoftVector *Transceiver::demodulate(TransceiverState *state, signalVector &burst, complex amp, - float toa) + float toa, CorrType type) { + if (type == EDGE) + return demodEdgeBurst(burst, mSPSRx, amp, toa); + return demodulateBurst(burst, mSPSRx, amp, toa); } @@ -606,7 +623,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i double &timingOffset, double &noise, size_t chan) { - int success; + int rc; complex amp; float toa, pow, max = -1.0, avg = 0.0; int max_i = -1; @@ -677,13 +694,14 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i } /* Detect normal or RACH bursts */ - success = detectBurst(state, *burst, amp, toa, type); + rc = detectBurst(state, *burst, amp, toa, type); - /* Alert an error and exit */ - if (success <= 0) { - if (success == -SIGERR_CLIP) { + if (rc > 0) { + type = (CorrType) rc; + } else if (rc <= 0) { + if (rc == -SIGERR_CLIP) { LOG(WARNING) << "Clipping detected on received RACH or Normal Burst"; - } else if (success != SIGERR_NONE) { + } else if (rc != SIGERR_NONE) { LOG(WARNING) << "Unhandled RACH or Normal Burst detection error"; } @@ -693,7 +711,7 @@ SoftVector *Transceiver::pullRadioVector(GSM::Time &wTime, double &RSSI, bool &i timingOffset = toa / mSPSRx; - bits = demodulate(state, *burst, amp, toa); + bits = demodulate(state, *burst, amp, toa, type); delete radio_burst; return bits; @@ -916,6 +934,19 @@ void Transceiver::driveReceiveRadio() } } +void Transceiver::logRxBurst(SoftVector *burst, GSM::Time time, double dbm, + double rssi, double noise, double toa) +{ + LOG(DEBUG) << std::fixed << std::right + << " time: " << time + << " 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: " << *burst; +} + void Transceiver::driveReceiveFIFO(size_t chan) { SoftVector *rxBurst = NULL; @@ -926,37 +957,39 @@ void Transceiver::driveReceiveFIFO(size_t chan) double noise; // noise level in dBFS GSM::Time burstTime; bool isRssiValid; // are RSSI, noise and burstTime valid + unsigned nbits = gSlotLen; rxBurst = pullRadioVector(burstTime, RSSI, isRssiValid, TOA, noise, chan); + if (!rxBurst) + return; - 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; - - char burstString[gSlotLen+10]; - burstString[0] = burstTime.TN(); - for (int i = 0; i < 4; i++) - burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff; - burstString[5] = (int)dBm; - burstString[6] = (TOAint >> 8) & 0x0ff; - burstString[7] = TOAint & 0x0ff; - SoftVector::iterator burstItr = rxBurst->begin(); - - for (unsigned int i = 0; i < gSlotLen; i++) { - burstString[8+i] =(char) round((*burstItr++)*255.0); - } - burstString[gSlotLen+9] = '\0'; - delete rxBurst; + /* + * EDGE demodulator returns 444 (148 * 3) bits + */ + if (rxBurst->size() == gSlotLen * 3) + nbits = gSlotLen * 3; - mDataSockets[chan]->write(burstString,gSlotLen+10); - } + dBm = RSSI + rssiOffset; + logRxBurst(rxBurst, burstTime, dBm, RSSI, noise, TOA); + + TOAint = (int) (TOA * 256.0 + 0.5); // round to closest integer + + char burstString[nbits + 10]; + burstString[0] = burstTime.TN(); + for (int i = 0; i < 4; i++) + burstString[1+i] = (burstTime.FN() >> ((3-i)*8)) & 0x0ff; + burstString[5] = (int)dBm; + burstString[6] = (TOAint >> 8) & 0x0ff; + burstString[7] = TOAint & 0x0ff; + SoftVector::iterator burstItr = rxBurst->begin(); + + for (unsigned i = 0; i < nbits; i++) + burstString[8 + i] = (char) round((*burstItr++) * 255.0); + + burstString[nbits + 9] = '\0'; + delete rxBurst; + + mDataSockets[chan]->write(burstString, nbits + 10); } void Transceiver::driveTxFIFO() diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h index 2fd1aea..fa58053 100644 --- a/Transceiver52M/Transceiver.h +++ b/Transceiver52M/Transceiver.h @@ -147,6 +147,7 @@ public: OFF, ///< timeslot is off TSC, ///< timeslot should contain a normal burst RACH, ///< timeslot should contain an access burst + EDGE, ///< timeslot should contain an EDGE burst IDLE ///< timeslot is an idle (or dummy) burst } CorrType; @@ -214,7 +215,7 @@ private: /** Demodulate burst and output soft bits */ SoftVector *demodulate(TransceiverState *state, signalVector &burst, - complex amp, float toa); + complex amp, float toa, CorrType type); int mSPSTx; ///< number of samples per Tx symbol int mSPSRx; ///< number of samples per Rx symbol @@ -272,6 +273,8 @@ protected: /** set priority on current thread */ void setPriority(float prio = 0.5) { mRadioInterface->setPriority(prio); } + void logRxBurst(SoftVector *burst, GSM::Time time, double dbm, + double rssi, double noise, double toa); }; void *RxUpperLoopAdapter(TransceiverChannel *); diff --git a/Transceiver52M/osmo-trx.cpp b/Transceiver52M/osmo-trx.cpp index c8fd9a8..e7b2a16 100644 --- a/Transceiver52M/osmo-trx.cpp +++ b/Transceiver52M/osmo-trx.cpp @@ -81,6 +81,7 @@ struct trx_config { double offset; double rssi_offset; bool swap_channels; + bool edge; }; ConfigurationTable gConfig; @@ -130,7 +131,7 @@ bool testConfig() */ bool trx_setup_config(struct trx_config *config) { - std::string refstr, fillstr, divstr; + std::string refstr, fillstr, divstr, edgestr; if (!testConfig()) return false; @@ -170,6 +171,7 @@ bool trx_setup_config(struct trx_config *config) if (config->diversity) config->chans = 2; + edgestr = config->edge ? "Enabled" : "Disabled"; refstr = config->extref ? "Enabled" : "Disabled"; divstr = config->diversity ? "Enabled" : "Disabled"; switch (config->filler) { @@ -192,6 +194,7 @@ bool trx_setup_config(struct trx_config *config) ost << " TRX Address............. " << config->addr << std::endl; ost << " Channels................ " << config->chans << std::endl; ost << " Tx Samples-per-Symbol... " << config->tx_sps << std::endl; + ost << " EDGE support............ " << edgestr << std::endl; ost << " External Reference...... " << refstr << std::endl; ost << " C0 Filler Table......... " << fillstr << std::endl; ost << " Diversity............... " << divstr << std::endl; @@ -215,6 +218,10 @@ RadioInterface *makeRadioInterface(struct trx_config *config, { RadioInterface *radio = NULL; + if ((config->rx_sps != 1) && (type != RadioDevice::NORMAL)) { + LOG(ALERT) << "Unsupported radio interface configuration"; + } + switch (type) { case RadioDevice::NORMAL: radio = new RadioInterface(usrp, config->tx_sps, @@ -301,6 +308,7 @@ static void print_help() " -l Logging level (%s)\n" " -i IP address of GSM core\n" " -p Base port number\n" + " -e Enable EDGE receiver\n" " -d Enable dual channel diversity receiver\n" " -x Enable external 10 MHz reference\n" " -s Samples-per-symbol (1 or 4)\n" @@ -328,8 +336,9 @@ static void handle_options(int argc, char **argv, struct trx_config *config) config->offset = 0.0; config->rssi_offset = 0.0; config->swap_channels = false; + config->edge = false; - while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:S")) != -1) { + while ((option = getopt(argc, argv, "ha:l:i:p:c:dxfo:s:r:R:Se")) != -1) { switch (option) { case 'h': print_help(); @@ -375,6 +384,10 @@ static void handle_options(int argc, char **argv, struct trx_config *config) case 'S': config->swap_channels = true; break; + case 'e': + config->edge = true; + config->rx_sps = 4; + break; default: print_help(); exit(0); @@ -387,6 +400,12 @@ static void handle_options(int argc, char **argv, struct trx_config *config) exit(0); } + if (config->edge && (config->tx_sps != 4)) { + printf("EDGE only supported at 4 samples per symbol\n\n"); + print_help(); + exit(0); + } + if (config->rtsc > 7) { printf("Invalid training sequence %i\n\n", config->rtsc); print_help(); diff --git a/Transceiver52M/sigProcLib.h b/Transceiver52M/sigProcLib.h index 2dcc97d..4f9f849 100644 --- a/Transceiver52M/sigProcLib.h +++ b/Transceiver52M/sigProcLib.h @@ -20,6 +20,11 @@ #include "BitVector.h" #include "signalVector.h" +/* Burst lengths */ +#define NORMAL_BURST_NBITS 148 +#define EDGE_BURST_NBITS 444 +#define EDGE_BURST_NSYMS (EDGE_BURST_NBITS / 3) + /** Convolution type indicator */ enum ConvType { START_ONLY, |