Merge pull request #4 from libLTE/master

Merge with master fork
This commit is contained in:
Ismael Gómez-Miguelez 2014-07-22 16:59:20 +02:00
commit 67977f7974
2 changed files with 69 additions and 62 deletions

View File

@ -11,15 +11,15 @@ Current Status
===============
The following parts are available:
* Physical Broadcast channel (PBCH) eNodeB and UE part. The UE supports multi-antenna transmitters
* Physical Channels: PBCH, PCFICH, PDCCH, PHICH, PDSCH eNodeB and UE side
* Synchronization and CFO estimation/correction
* Equalization
* UE receiver verified with live LTE signals
* UE receiver (MIB + SIB1 decoding) verified with live LTE signals
Hardware
========
The library currently uses Ettus Universal Hardware Driver (UHD). Thus, any hardware supported by UHD can be used. There is no sampling rate conversion, therefore the hardware should support 30.72 MHz clock in order to work correctly with LTE sampling frequencies and decode signals from live LTE base stations.
The library currently uses Ettus Universal Hardware Driver (UHD). Thus, any hardware supported by UHD can be used. There is no sampling rate conversion, therefore the hardware should support 30.72 MHz clock in order to work correctly with LTE sampling frequencies and decode signals from live LTE base stations. We are using the B210 USRP.
Download & Install Instructions
@ -50,12 +50,12 @@ PHY Examples
Setup one or two computers connected to two USRP or UHD-compatible hardware. From the eNodeB, type
```
lte/phy/examples/pbch_enodeb -f [frequency_in_Hz] -c [cell_id] [-a [UHD args]] [-h for more commands]
lte/phy/examples/pdsch_enodeb -f [frequency_in_Hz] -c [cell_id] [-a [UHD args]] [-h for more commands]
```
From the UE, type
```
lte/phy/examples/pbch_ue -f [frequency_in_Hz] -c [cell_id] [-a [UHD args]] [-h for more commands]
lte/phy/examples/pdsch_ue -f [frequency_in_Hz] [-a [UHD args]] [-h for more commands]
```
And the output should look something like the following video. In this example, we removed the transmitter and receiver antennas in the middle of the demonstration, showing how reception is still possible (despite with some erros).
@ -65,17 +65,26 @@ https://www.dropbox.com/s/txh1nuzdb0igq5n/demo_pbch.ogv
![Screenshopt of the PBCH example output](pbch_capture.png "Screenshopt of the PBCH example output")
The SIB1 message is decoded and shown on the console, for example:
```
Decoded SIB1 Message: [40 48 50 03 02 0b 14 4a 30 18 28 20 90 81 84 79 a0 00 ];
```
Then, you can use any ASN.1 SIB decoder to read the message. This site http://www.marben-products.com/asn.1/services/decoder-asn1-lte.html is a good example.
If you don't have a pair of USRP, you can also test the demo by writing the samples to a file and then reading them:
From the eNodeB, type
```
lte/phy/examples/pbch_enodeb -o [output_file] -c [cell_id] [-h for more commands]
lte/phy/examples/pdsch_enodeb -o [output_file] -c [cell_id] [-h for more commands]
```
From the UE, type
```
lte/phy/examples/pbch_ue -i [input_file] -c [cell_id] [-h for more commands]
lte/phy/examples/pdsch_ue -i [input_file] -c [cell_id] [-h for more commands]
```

View File

@ -54,45 +54,40 @@ void llr_approx(const _Complex float *in, float *out, int N, int M, int B,
_Complex float *symbols, uint32_t (*S)[6][32], float sigma2) {
int i, s, b;
float num, den;
float new_num, new_den;
float idiff0, qdiff0, idiff1, qdiff1;
int change_sign = -1;
float x, y, d[64];
for (s=0; s<N; s++) { /* recevied symbols */
for (b=0; b<B; b++) {/* bits per symbol*/
/* initiate num[b] and den[b] */
idiff0 = __real__ in[s] - __real__ symbols[S[0][b][0]];
qdiff0 = __imag__ in[s] - __imag__ symbols[S[0][b][0]];
num = idiff0*idiff0 + qdiff0*qdiff0;
for (s=0; s<N; s++) { /* recevied symbols */
/* Compute the distances squared d[i] between the received symbol and all constellation points */
for (i=0; i<M; i++) {
x = __real__ in[s] - __real__ symbols[i];
y = __imag__ in[s] - __imag__ symbols[i];
d[i] = x*x + y*y;
}
idiff1 = __real__ in[s] - __real__ symbols[S[1][b][0]];
qdiff1 = __imag__ in[s] - __imag__ symbols[S[1][b][0]];
den = idiff1*idiff1 + qdiff1*qdiff1;
for (b=0; b<B; b++) {/* bits per symbol*/
/* initiate num[b] and den[b] */
num = d[S[0][b][0]];
den = d[S[1][b][0]];
/* half the constellation symbols have '1'|'0' at any bit pos. */
for (i=1; i<M/2; i++) {
idiff0 = __real__ in[s] - __real__ symbols[S[0][b][i]];
qdiff0 = __imag__ in[s] - __imag__ symbols[S[0][b][i]];
new_num = idiff0*idiff0 + qdiff0*qdiff0;
idiff1 = __real__ in[s] - __real__ symbols[S[1][b][i]];
qdiff1 = __imag__ in[s] - __imag__ symbols[S[1][b][i]];
new_den = idiff1*idiff1 + qdiff1*qdiff1;
if (new_num < num) {
num = new_num;
}
if (new_den < den) {
den = new_den;
}
}
/* Theoretical LLR and approximate LLR values are positive if
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer.
* Change sign if mapping negative to '0' and positive to '1' */
out[s*B+b] = change_sign*(den-num)/sigma2;
}
/* Minimum distance squared search between recevied symbol and a constellation point with a
'1' and a '0' for each bit position */
for (i=1; i<M/2; i++) { /* half the constellation points have '1'|'0' at any given bit position */
if (d[S[0][b][i]] < num) {
num = d[S[0][b][i]];
}
if (d[S[1][b][i]] < den) {
den = d[S[1][b][i]];
}
}
/* Theoretical LLR and approximate LLR values are positive if
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer.
* Change sign if mapping negative to '0' and positive to '1' */
out[s*B+b] = change_sign*(den-num)/sigma2;
}
}
}
/**
@ -115,29 +110,32 @@ void llr_exact(const _Complex float *in, float *out, int N, int M, int B,
_Complex float *symbols, uint32_t (*S)[6][32], float sigma2) {
int i, s, b;
float num, den;
float idiff0, qdiff0, idiff1, qdiff1;
int change_sign = -1;
float x, y, d[64];
for (s=0; s<N; s++) { /* recevied symbols */
for (b=0; b<B; b++) {/* bits per symbol*/
/* initiate num[b] and den[b] */
num = 0;
den = 0;
/* half the constellation symbols have '1'|'0' at any bit pos. */
for (i=0; i<M/2; i++) {
idiff0 = __real__ in[s] - __real__ symbols[S[0][b][i]];
qdiff0 = __imag__ in[s] - __imag__ symbols[S[0][b][i]];
num += exp(-1*(idiff0*idiff0 + qdiff0*qdiff0)/sigma2);
for (s=0; s<N; s++) { /* recevied symbols */
/* Compute exp{·} of the distances squared d[i] between the received symbol and all constellation points */
for (i=0; i<M; i++) {
x = __real__ in[s] - __real__ symbols[i];
y = __imag__ in[s] - __imag__ symbols[i];
d[i] = exp(-1*(x*x + y*y)/sigma2);
}
idiff1 = __real__ in[s] - __real__ symbols[S[1][b][i]];
qdiff1 = __imag__ in[s] - __imag__ symbols[S[1][b][i]];
den += exp(-1*(idiff1*idiff1 + qdiff1*qdiff1)/sigma2);
}
/* Theoretical LLR and approximate LLR values are positive if
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer.
* Change sign if mapping negative to '0' and positive to '1' */
out[s*B+b] = change_sign*log(num/den);
}
/* Sum up the corresponding d[i]'s for each bit position */
for (b=0; b<B; b++) {/* bits per symbol*/
/* initiate num[b] and den[b] */
num = 0;
den = 0;
for (i=0; i<M/2; i++) { /* half the constellation points have '1'|'0' at any given bit position */
num += d[S[0][b][i]];
den += d[S[1][b][i]];
}
/* Theoretical LLR and approximate LLR values are positive if
* symbol(s) with '0' is/are closer and negative if symbol(s)
* with '1' are closer.
* Change sign if mapping negative to '0' and positive to '1' */
out[s*B+b] = change_sign*log(num/den);
}
}
}