Hoernchen has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-trx/+/33944 )
Change subject: ms: restructure the va code to add rach support
......................................................................
ms: restructure the va code to add rach support
Change-Id: I7275a647428661a788646fec10af429fcdcf577e
new bb
Change-Id: I36dbed6394243c8c2b5e14acbade7b1b82d0708c
XX va trials
Change-Id: Id1de531249922315da35d2d01778a7611879fb92
fugg
Change-Id: Ibe5d538e9970e590877d2a901165defa6dc972fe
tx->va needs scaling by 0.1
Change-Id: Ic3cc5748e00584971c4bd509eed7db9d5f09201c
sch
Change-Id: I41fabcdd5b4a5eb8cff4e42676438b0bffa2e1b9
va1
Change-Id: I93ab3cb8f91bf6e496175ae70e5da0323cabe911
xx
Change-Id: I26b5957f80be02df913e31a370e1e7910f4484df
va2
Change-Id: I09d6b560241e6797a533e7f8e68e899c42517baa
va: max elemn fix
max elem returns the first largest element - but the true value is
skewed to the right in our case.
Change-Id: I1de9b7e280d8723ce9876bef20c790383070e958
SDSD
Change-Id: Ie32fc753548583896be9eef486346617ea8b9e88
adsad
Change-Id: I3a9a2569c2057feae196b182f6e812edd08ccfa4
make ubsan happy
Change-Id: Ic6ddfcf826539dd227e76e8054d3f3d777c97d5e
wtf wip
Change-Id: I0f465da6d17bf91f24a68b3ec2075995478b5fad
a bit of channel impulse resp makes it work (?!)
Change-Id: I2ab1d6bdf89a0d950ebe38b1fd5efb9764c9ba4f
shp
Change-Id: I7f936dd22b55145bd182f3b5e51b9c183ab1725f
finally works as intended.. maybe.
Change-Id: I2af965ab20af74b38975c645093626a81b7fdf72
cleanup
Change-Id: If36f15a5f32465ce04113a669e3875dc19c69d6b
cleanup
Change-Id: I1163a6194570cdce93d46e40e4b710ad5239cce7
iomanip
Change-Id: I20453a5381afcf8a7875b6e82805f7e8595163b2
cleanup3
Change-Id: I8e66f2a447984a1fd5a20814eca3ee019ba59717
cleanup3
Change-Id: Ib499fe0a5d42afd9198da96dbcba2a42705bbe73
use short inted burst
Change-Id: I0bc7a7b35da474bce74f8a36834a22d5885bbdbc
add burst dump
Change-Id: I0ca9114b6a02cac7fb628ac47db2554b3ff3b967
cleanup va
Change-Id: I1697925b0f0f36aaa05ee170a9483750611aef5d
all tests
Change-Id: Ie2db803ccb789699cdfaf82e74acba42123d961a
transceiver: add va
This needs slightly shifted rx windows that need to include the
beginning ot the burst.
Change-Id: I64f4f596875434bf3e7201ddbbe58924482f4559
va offset pretty #1
Change-Id: Ibb6d3b351bfd915d4bfc2587c5f5c47d129de360
va pretty #2
Change-Id: I8bd2cb9dbe449324be64d8514593815c0ca24c0b
makeu
Change-Id: I13ccc55a6f5c0438236490bb1e75f93a0e20fe2e
xx mergeme
Change-Id: Id8edf31fe1bf72a2f254e634edc7c12b3bba8833
sign comp
Change-Id: I4a5cedc8c9a3289c75ce7b914eac286e601ebed0
---
M Transceiver52M/grgsm_vitac/constants.h
M Transceiver52M/grgsm_vitac/grgsm_vitac.cpp
M Transceiver52M/grgsm_vitac/grgsm_vitac.h
M Transceiver52M/ms/ms_rx_lower.cpp
M Transceiver52M/ms/ms_upper.cpp
5 files changed, 255 insertions(+), 96 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-trx refs/changes/44/33944/1
diff --git a/Transceiver52M/grgsm_vitac/constants.h
b/Transceiver52M/grgsm_vitac/constants.h
index 07f2290..27bf6f4 100644
--- a/Transceiver52M/grgsm_vitac/constants.h
+++ b/Transceiver52M/grgsm_vitac/constants.h
@@ -38,6 +38,7 @@
#define STEALING_BIT 1
#define N_TRAIN_BITS 26
#define N_SYNC_BITS 64
+#define N_ACCESS_BITS 41
#define USEFUL_BITS 142 //(2*(DATA_BITS+STEALING_BIT) + N_TRAIN_BITS )
#define FCCH_BITS USEFUL_BITS
#define BURST_SIZE (USEFUL_BITS+2*TAIL_BITS)
@@ -73,6 +74,12 @@
0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1
};
+static const unsigned char ACCESS_BITS [] = {
+ 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0,
+ 0, 1, 1, 1, 1, 0, 0, 0
+};
+
const unsigned FCCH_FRAMES[] = { 0, 10, 20, 30, 40 };
const unsigned SCH_FRAMES[] = { 1, 11, 21, 31, 41 };
diff --git a/Transceiver52M/grgsm_vitac/grgsm_vitac.cpp
b/Transceiver52M/grgsm_vitac/grgsm_vitac.cpp
index 836c555..00e3d5a 100644
--- a/Transceiver52M/grgsm_vitac/grgsm_vitac.cpp
+++ b/Transceiver52M/grgsm_vitac/grgsm_vitac.cpp
@@ -39,13 +39,13 @@
#include "viterbi_detector.h"
#include "grgsm_vitac.h"
-//signalVector mChanResp;
+gr_complex d_sync_training_seq[N_ACCESS_BITS]; ///<encoded training sequence of a SCH
burst
gr_complex d_sch_training_seq[N_SYNC_BITS]; ///<encoded training sequence of a SCH
burst
gr_complex d_norm_training_seq[TRAIN_SEQ_NUM][N_TRAIN_BITS]; ///<encoded training
sequences of a normal and dummy burst
const int d_chan_imp_length = CHAN_IMP_RESP_LENGTH;
-void initvita() {
-
+void initvita()
+{
/**
* Prepare SCH sequence bits
*
@@ -53,59 +53,73 @@
* Burst and two guard periods
* (one guard period is an arbitrary overlap)
*/
- gmsk_mapper(SYNC_BITS, N_SYNC_BITS,
- d_sch_training_seq, gr_complex(0.0, -1.0));
+ gmsk_mapper(SYNC_BITS, N_SYNC_BITS, d_sch_training_seq, gr_complex(0.0, -1.0));
for (auto &i : d_sch_training_seq)
i = conj(i);
+ /* ab */
+ gmsk_mapper(ACCESS_BITS, N_ACCESS_BITS, d_sync_training_seq, gr_complex(0.0, -1.0));
+ for (auto &i : d_sync_training_seq)
+ i = conj(i);
+
/* Prepare bits of training sequences */
for (int i = 0; i < TRAIN_SEQ_NUM; i++) {
/**
* If first bit of the sequence is 0
* => first symbol is 1, else -1
*/
- gr_complex startpoint = train_seq[i][0] == 0 ?
- gr_complex(1.0, 0.0) : gr_complex(-1.0, 0.0);
- gmsk_mapper(train_seq[i], N_TRAIN_BITS,
- d_norm_training_seq[i], startpoint);
+ gr_complex startpoint = train_seq[i][0] == 0 ? gr_complex(1.0, 0.0) : gr_complex(-1.0,
0.0);
+ gmsk_mapper(train_seq[i], N_TRAIN_BITS, d_norm_training_seq[i], startpoint);
for (auto &i : d_norm_training_seq[i])
i = conj(i);
}
-
}
-MULTI_VER_TARGET_ATTR NO_UBSAN
-void detect_burst(const gr_complex *input, gr_complex *chan_imp_resp, int burst_start,
char *output_binary)
+template <unsigned int burst_size>
+NO_UBSAN static void detect_burst_generic(const gr_complex *input, gr_complex
*chan_imp_resp, int burst_start,
+ char *output_binary, int ss)
{
std::vector<gr_complex> rhh_temp(CHAN_IMP_RESP_LENGTH * d_OSR);
unsigned int stop_states[2] = { 4, 12 };
- gr_complex filtered_burst[BURST_SIZE];
+ gr_complex filtered_burst[burst_size];
gr_complex rhh[CHAN_IMP_RESP_LENGTH];
- float output[BURST_SIZE];
- int start_state = 3;
-
- // if(burst_start < 0 ||burst_start > 10)
- // fprintf(stderr, "bo %d\n", burst_start);
-
- // burst_start = burst_start >= 0 ? burst_start : 0;
+ float output[burst_size];
+ int start_state = ss;
autocorrelation(chan_imp_resp, &rhh_temp[0], d_chan_imp_length * d_OSR);
for (int ii = 0; ii < d_chan_imp_length; ii++)
rhh[ii] = conj(rhh_temp[ii * d_OSR]);
- mafi(&input[burst_start], BURST_SIZE, chan_imp_resp,
- d_chan_imp_length * d_OSR, filtered_burst);
+ mafi(&input[burst_start], burst_size, chan_imp_resp, d_chan_imp_length * d_OSR,
filtered_burst);
- viterbi_detector(filtered_burst, BURST_SIZE, rhh,
- start_state, stop_states, 2, output);
+ viterbi_detector(filtered_burst, burst_size, rhh, start_state, stop_states, 2, output);
- for (int i = 0; i < BURST_SIZE; i++)
- output_binary[i] = output[i] * -127; // pre flip bits!
+ for (unsigned int i = 0; i < burst_size; i++)
+ output_binary[i] = (char)(output[i] * -127); // pre flip bits!
}
-void
-gmsk_mapper(const unsigned char* input,
- int nitems, gr_complex* gmsk_output, gr_complex start_point)
+NO_UBSAN void detect_burst_nb(const gr_complex *input, gr_complex *chan_imp_resp, int
burst_start, char *output_binary,
+ int ss)
+{
+ return detect_burst_generic<BURST_SIZE>(input, chan_imp_resp, burst_start,
output_binary, ss);
+}
+NO_UBSAN void detect_burst_access_burst(const gr_complex *input, gr_complex
*chan_imp_resp, int burst_start,
+ char *output_binary, int ss)
+{
+ return detect_burst_generic<8 + 41 + 36 + 3>(input, chan_imp_resp, burst_start,
output_binary, ss);
+}
+
+NO_UBSAN void detect_burst_nb(const gr_complex *input, gr_complex *chan_imp_resp, int
burst_start, char *output_binary)
+{
+ return detect_burst_nb(input, chan_imp_resp, burst_start, output_binary, 3);
+}
+NO_UBSAN void detect_burst_access_burst(const gr_complex *input, gr_complex
*chan_imp_resp, int burst_start,
+ char *output_binary)
+{
+ return detect_burst_access_burst(input, chan_imp_resp, burst_start, output_binary, 3);
+}
+
+void gmsk_mapper(const unsigned char *input, int nitems, gr_complex *gmsk_output,
gr_complex start_point)
{
gr_complex j = gr_complex(0.0, 1.0);
gmsk_output[0] = start_point;
@@ -122,16 +136,13 @@
encoded_symbol = current_symbol * previous_symbol;
/* And do GMSK mapping */
- gmsk_output[i] = j * gr_complex(encoded_symbol, 0.0)
- * gmsk_output[i - 1];
+ gmsk_output[i] = j * gr_complex(encoded_symbol, 0.0) * gmsk_output[i - 1];
previous_symbol = current_symbol;
}
}
-gr_complex
-correlate_sequence(const gr_complex* sequence,
- int length, const gr_complex* input)
+gr_complex correlate_sequence(const gr_complex *sequence, int length, const gr_complex
*input)
{
gr_complex result(0.0, 0.0);
@@ -142,9 +153,7 @@
}
/* Computes autocorrelation for positive arguments */
-inline void
-autocorrelation(const gr_complex* input,
- gr_complex* out, int nitems)
+inline void autocorrelation(const gr_complex *input, gr_complex *out, int nitems)
{
for (int k = nitems - 1; k >= 0; k--) {
out[k] = gr_complex(0, 0);
@@ -153,9 +162,7 @@
}
}
-inline void
-mafi(const gr_complex* input, int nitems,
- gr_complex* filter, int filter_length, gr_complex* output)
+inline void mafi(const gr_complex *input, int nitems, gr_complex *filter, int
filter_length, gr_complex *output)
{
for (int n = 0; n < nitems; n++) {
int a = n * d_OSR;
@@ -170,66 +177,45 @@
}
}
-int get_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, int
search_center, int search_start_pos,
- int search_stop_pos, gr_complex *tseq, int tseqlen, float *corr_max)
+int get_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, int
search_start_pos, int search_stop_pos,
+ gr_complex *tseq, int tseqlen, float *corr_max)
{
- std::vector<gr_complex> correlation_buffer;
+ const int num_search_windows = search_stop_pos - search_start_pos;
+ const int power_search_window_len = d_chan_imp_length * d_OSR;
std::vector<float> window_energy_buffer;
std::vector<float> power_buffer;
+ std::vector<gr_complex> correlation_buffer;
- for (int ii = search_start_pos; ii < search_stop_pos; ii++) {
- gr_complex correlation = correlate_sequence(tseq, tseqlen, &input[ii]);
+ power_buffer.reserve(num_search_windows);
+ correlation_buffer.reserve(num_search_windows);
+ window_energy_buffer.reserve(num_search_windows);
+
+ for (int ii = 0; ii < num_search_windows; ii++) {
+ gr_complex correlation = correlate_sequence(tseq, tseqlen, &input[search_start_pos
+ ii]);
correlation_buffer.push_back(correlation);
power_buffer.push_back(std::pow(abs(correlation), 2));
}
- int strongest_corr_nr = max_element(power_buffer.begin(), power_buffer.end()) -
power_buffer.begin();
-
/* Compute window energies */
- auto window_energy_start_offset = strongest_corr_nr - 6 * d_OSR;
- window_energy_start_offset = window_energy_start_offset < 0 ? 0 :
window_energy_start_offset; //can end up out of range..
- auto window_energy_end_offset = strongest_corr_nr + 6 * d_OSR + d_chan_imp_length *
d_OSR;
- auto iter = power_buffer.begin() + window_energy_start_offset;
- auto iter_end = power_buffer.begin() + window_energy_end_offset;
- while (iter != iter_end) {
- std::vector<float>::iterator iter_ii = iter;
- bool loop_end = false;
- float energy = 0;
+ float windowSum = 0;
- int len = d_chan_imp_length * d_OSR;
- for (int ii = 0; ii < len; ii++, iter_ii++) {
- if (iter_ii == power_buffer.end()) {
- loop_end = true;
- break;
- }
+ // first window
+ for (int i = 0; i < power_search_window_len; i++) {
+ windowSum += power_buffer[i];
+ }
+ window_energy_buffer.push_back(windowSum);
- energy += (*iter_ii);
- }
-
- if (loop_end)
- break;
-
- window_energy_buffer.push_back(energy);
- iter++;
+ // slide windows
+ for (int i = power_search_window_len; i < num_search_windows; i++) {
+ windowSum += power_buffer[i] - power_buffer[i - power_search_window_len];
+ window_energy_buffer.push_back(windowSum);
}
- /* Calculate the strongest window number */
- int strongest_window_nr = window_energy_start_offset +
- max_element(window_energy_buffer.begin(), window_energy_buffer.end()) -
+ int strongest_window_nr = std::max_element(window_energy_buffer.begin(),
window_energy_buffer.end()) -
window_energy_buffer.begin();
- // auto window_search_start = window_energy_buffer.begin() + strongest_corr_nr - 5*
d_OSR;
- // auto window_search_end = window_energy_buffer.begin() + strongest_corr_nr + 10*
d_OSR;
- // window_search_end = window_search_end >= window_energy_buffer.end() ?
window_energy_buffer.end() : window_search_end;
-
- // /* Calculate the strongest window number */
- // int strongest_window_nr = max_element(window_search_start, window_search_end /* -
d_chan_imp_length * d_OSR*/) - window_energy_buffer.begin();
-
- // if (strongest_window_nr < 0)
- // strongest_window_nr = 0;
-
float max_correlation = 0;
- for (int ii = 0; ii < d_chan_imp_length * d_OSR; ii++) {
+ for (int ii = 0; ii < power_search_window_len; ii++) {
gr_complex correlation = correlation_buffer[strongest_window_nr + ii];
if (abs(correlation) > max_correlation)
max_correlation = abs(correlation);
@@ -242,7 +228,27 @@
* Compute first sample position, which corresponds
* to the first sample of the impulse response
*/
- return search_start_pos + strongest_window_nr - search_center * d_OSR;
+ return search_start_pos + strongest_window_nr;
+}
+
+/*
+8 ext tail bits
+41 sync seq
+36 encrypted bits
+3 tail bits
+68.25 extended tail bits (!)
+
+center at 8+5 (actually known tb -> known isi, start at 8?) FIXME
+*/
+int get_access_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, float
*corr_max, int max_delay)
+{
+ const int search_center = 8 + 5;
+ const int search_start_pos = (search_center - 5) * d_OSR + 1;
+ const int search_stop_pos = (search_center + 5 + d_chan_imp_length + max_delay) *
d_OSR;
+ const auto tseq = &d_sync_training_seq[TRAIN_BEGINNING];
+ const auto tseqlen = N_ACCESS_BITS - (2 * TRAIN_BEGINNING);
+ return get_chan_imp_resp(input, chan_imp_resp, search_start_pos, search_stop_pos, tseq,
tseqlen, corr_max) -
+ search_center * d_OSR;
}
/*
@@ -260,8 +266,8 @@
const int search_stop_pos = (search_center + 5 + d_chan_imp_length) * d_OSR;
const auto tseq = &d_norm_training_seq[bcc][TRAIN_BEGINNING];
const auto tseqlen = N_TRAIN_BITS - (2 * TRAIN_BEGINNING);
- return get_chan_imp_resp(input, chan_imp_resp, search_center, search_start_pos,
search_stop_pos, tseq, tseqlen,
- corr_max);
+ return get_chan_imp_resp(input, chan_imp_resp, search_start_pos, search_stop_pos, tseq,
tseqlen, corr_max) -
+ search_center * d_OSR;
}
/*
@@ -281,8 +287,9 @@
// strongest_window_nr + chan_imp_resp_center + SYNC_POS *d_OSR - 48 * d_OSR - 2 * d_OSR
+ 2 ;
float corr_max;
- return get_chan_imp_resp(input, chan_imp_resp, search_center, search_start_pos,
search_stop_pos, tseq, tseqlen,
- &corr_max);
+ return get_chan_imp_resp(input, chan_imp_resp, search_start_pos, search_stop_pos, tseq,
tseqlen, &corr_max) -
+ search_center * d_OSR;
+ ;
}
int get_sch_buffer_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp,
unsigned int len, float *corr_max)
@@ -291,9 +298,9 @@
const int search_center = SYNC_POS + TRAIN_BEGINNING;
const int search_start_pos = 0;
// FIXME: proper end offset
- const int search_stop_pos = len - (N_SYNC_BITS*8);
+ const int search_stop_pos = len - (N_SYNC_BITS * 8);
auto tseq = &d_sch_training_seq[TRAIN_BEGINNING];
- return get_chan_imp_resp(input, chan_imp_resp, search_center, search_start_pos,
search_stop_pos, tseq, tseqlen,
- corr_max);
+ return get_chan_imp_resp(input, chan_imp_resp, search_start_pos, search_stop_pos, tseq,
tseqlen, corr_max) -
+ search_center * d_OSR;
}
\ No newline at end of file
diff --git a/Transceiver52M/grgsm_vitac/grgsm_vitac.h
b/Transceiver52M/grgsm_vitac/grgsm_vitac.h
index 2c89d8c..9d4c300 100644
--- a/Transceiver52M/grgsm_vitac/grgsm_vitac.h
+++ b/Transceiver52M/grgsm_vitac/grgsm_vitac.h
@@ -58,8 +58,13 @@
int process_vita_burst(gr_complex *input, int tsc, unsigned char *output_binary);
int process_vita_sc_burst(gr_complex *input, int tsc, unsigned char *output_binary, int
*offset);
-MULTI_VER_TARGET_ATTR_CLANGONLY
-void detect_burst(const gr_complex *input, gr_complex *chan_imp_resp, int burst_start,
char *output_binary);
+void detect_burst_nb(const gr_complex *input, gr_complex *chan_imp_resp, int burst_start,
char *output_binary, int ss);
+void detect_burst_access_burst(const gr_complex *input, gr_complex *chan_imp_resp, int
burst_start, char *output_binary,
+ int ss);
+void detect_burst_nb(const gr_complex *input, gr_complex *chan_imp_resp, int burst_start,
char *output_binary);
+void detect_burst_access_burst(const gr_complex *input, gr_complex *chan_imp_resp, int
burst_start,
+ char *output_binary);
+
void gmsk_mapper(const unsigned char *input, int nitems, gr_complex *gmsk_output,
gr_complex start_point);
gr_complex correlate_sequence(const gr_complex *sequence, int length, const gr_complex
*input);
inline void autocorrelation(const gr_complex *input, gr_complex *out, int nitems);
@@ -67,6 +72,7 @@
int get_sch_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp);
int get_norm_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, float
*corr_max, int bcc);
int get_sch_buffer_chan_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp,
unsigned int len, float *corr_max);
+int get_access_imp_resp(const gr_complex *input, gr_complex *chan_imp_resp, float
*corr_max, int max_delay);
enum class btype { NB, SCH };
struct fdata {
diff --git a/Transceiver52M/ms/ms_rx_lower.cpp b/Transceiver52M/ms/ms_rx_lower.cpp
index 5a07df5..c2adda3 100644
--- a/Transceiver52M/ms/ms_rx_lower.cpp
+++ b/Transceiver52M/ms/ms_rx_lower.cpp
@@ -170,7 +170,7 @@
start = start < 39 ? start : 39;
start = start > -39 ? start : -39;
}
- detect_burst(&ss[start], &channel_imp_resp[0], 0, sch_demod_bits);
+ detect_burst_nb(&ss[start], &channel_imp_resp[0], 0, sch_demod_bits);
auto sch_decode_success = decode_sch(sch_demod_bits, is_first_sch_acq);
diff --git a/Transceiver52M/ms/ms_upper.cpp b/Transceiver52M/ms/ms_upper.cpp
index 21f70bb..6a83f2a 100644
--- a/Transceiver52M/ms/ms_upper.cpp
+++ b/Transceiver52M/ms/ms_upper.cpp
@@ -196,7 +196,7 @@
// fprintf(stderr, "%s %d\n", (is_nb ? "N":"D"),
burst_time.FN());
// if (is_nb)
#endif
- detect_burst(ss, &chan_imp_resp[0], normal_burst_start, demodded_softbits);
+ detect_burst_nb(ss, &chan_imp_resp[0], normal_burst_start, demodded_softbits);
#ifdef DBGXX
// else
// detect_burst(ss, &chan_imp_resp2[0], dummy_burst_start, outbin);
--
To view, visit
https://gerrit.osmocom.org/c/osmo-trx/+/33944
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-trx
Gerrit-Branch: master
Gerrit-Change-Id: I4a5cedc8c9a3289c75ce7b914eac286e601ebed0
Gerrit-Change-Number: 33944
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <ewild(a)sysmocom.de>
Gerrit-MessageType: newchange