Commit 7bdbd161 authored by Ben Wojtowicz's avatar Ben Wojtowicz

Version 0.9.2: Added support for setting the sample rate and output data type...

Version 0.9.2: Added support for setting the sample rate and output data type in the LTE_fdd_dl_file_gen app and the sample rate and input data type in the LTE_fdd_dl_file_scan app to make the LTE_fdd_dl_file_gen, LTE_fdd_dl_file_scan, and LTE_file_recorder applications compatible, added uplink demodulation reference signal generation to the octave code
parent 4a10f2c7
......@@ -23,7 +23,7 @@
########################################################################
cmake_minimum_required(VERSION 2.6)
project(openLTE CXX C)
set(openLTE_version 0.9.1)
set(openLTE_version 0.9.2)
enable_testing()
#select the release build type by default to get optimization flags
......
......@@ -68,3 +68,9 @@ v00.09.01 Implemented liblte_phy routines for determining TBS, MCS, N_prb, a
checking on sizes passed to memcpy in liblte_rrc, added support for
changing the sample rate in the LTE_fdd_dl_file_gen app, and added
finding FFTW to cmake.
v00.09.02 Added support for setting the sample rate and output data type in the
LTE_fdd_dl_file_gen app and the sample rate and input data type in the
LTE_fdd_dl_file_scan app to make the LTE_fdd_dl_file_gen,
LTE_fdd_dl_file_scan, and LTE_file_recorder applications compatible,
added uplink demodulation reference signal generation to the octave
code.
......@@ -35,6 +35,8 @@
07/21/2013 Ben Wojtowicz Using the latest LTE library.
08/26/2013 Ben Wojtowicz Updates to support GnuRadio 3.7.
09/16/2013 Ben Wojtowicz Added support for changing the sample rate.
09/28/2013 Ben Wojtowicz Added support for setting the sample rate
and output data type.
*******************************************************************************/
......@@ -58,6 +60,7 @@
// Configurable Parameters
#define BANDWIDTH_PARAM "bandwidth"
#define FS_PARAM "fs"
#define FREQ_BAND_PARAM "freq_band"
#define N_FRAMES_PARAM "n_frames"
#define N_ANT_PARAM "n_ant"
......@@ -89,11 +92,16 @@ class LTE_fdd_dl_fg_samp_buf;
typedef boost::shared_ptr<LTE_fdd_dl_fg_samp_buf> LTE_fdd_dl_fg_samp_buf_sptr;
typedef enum{
LTE_FDD_DL_FG_OUT_SIZE_INT8 = 0,
LTE_FDD_DL_FG_OUT_SIZE_GR_COMPLEX,
}LTE_FDD_DL_FG_OUT_SIZE_ENUM;
/*******************************************************************************
CLASS DECLARATIONS
*******************************************************************************/
LTE_FDD_DL_FG_API LTE_fdd_dl_fg_samp_buf_sptr LTE_fdd_dl_fg_make_samp_buf();
LTE_FDD_DL_FG_API LTE_fdd_dl_fg_samp_buf_sptr LTE_fdd_dl_fg_make_samp_buf(size_t out_size_val);
class LTE_FDD_DL_FG_API LTE_fdd_dl_fg_samp_buf : public gr::sync_block
{
public:
......@@ -104,9 +112,12 @@ public:
gr_vector_void_star &output_items);
private:
friend LTE_FDD_DL_FG_API LTE_fdd_dl_fg_samp_buf_sptr LTE_fdd_dl_fg_make_samp_buf();
friend LTE_FDD_DL_FG_API LTE_fdd_dl_fg_samp_buf_sptr LTE_fdd_dl_fg_make_samp_buf(size_t out_size_val);
LTE_fdd_dl_fg_samp_buf(size_t out_size_val);
LTE_fdd_dl_fg_samp_buf();
// Input parameters
LTE_FDD_DL_FG_OUT_SIZE_ENUM out_size;
// Sample buffer
float *i_buf;
......@@ -152,6 +163,7 @@ private:
void print_config(void);
void change_config(char *line);
bool set_bandwidth(char *char_value);
bool set_fs(char *char_value);
bool set_n_ant(char *char_value);
bool set_n_id_cell(char *char_value);
bool set_mcc(char *char_value);
......
......@@ -15,16 +15,26 @@ class LTE_fdd_dl_file_gen(gr.top_block):
usage = "usage: %prog [options] file"
parser=OptionParser(option_class=eng_option, usage=usage)
# Add options here
parser.add_option("-d", "--data-type", type="string", default="int8",
help="Output file data type, default=%default, options=[int8, gr_complex]")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.print_help()
sys.exit(1)
if options.data_type == "gr_complex":
size = gr.sizeof_gr_complex
elif options.data_type == "int8":
size = gr.sizeof_char
else:
print("Invalid data type using int8")
size = gr.sizeof_char
output_filename = args[0]
# Build flow graph
self.samp_buf = LTE_fdd_dl_fg.samp_buf()
self.fsink = blocks.file_sink(gr.sizeof_char, output_filename)
self.samp_buf = LTE_fdd_dl_fg.samp_buf(size)
self.fsink = blocks.file_sink(size, output_filename)
self.connect(self.samp_buf, self.fsink)
if __name__ == '__main__':
......
......@@ -37,6 +37,8 @@
03/17/2013 Ben Wojtowicz Added paging message printing.
07/21/2013 Ben Wojtowicz Using the latest LTE library.
08/26/2013 Ben Wojtowicz Updates to support GnuRadio 3.7.
09/28/2013 Ben Wojtowicz Added support for setting the sample rate
and input data type.
*******************************************************************************/
......@@ -56,10 +58,14 @@
DEFINES
*******************************************************************************/
#define LTE_FDD_DL_FS_SAMP_BUF_SIZE (307200*10)
#define LTE_FDD_DL_FS_SAMP_BUF_SIZE (LIBLTE_PHY_N_SAMPS_PER_FRAME_30_72MHZ*10)
#define LTE_FDD_DL_FS_SAMP_BUF_NUM_FRAMES (10)
#define LTE_FDD_DL_FS_SAMP_BUF_N_DECODED_CHANS_MAX 10
// Configurable Parameters
#define FS_PARAM "fs"
/*******************************************************************************
FORWARD DECLARATIONS
*******************************************************************************/
......@@ -72,6 +78,11 @@ class LTE_fdd_dl_fs_samp_buf;
typedef boost::shared_ptr<LTE_fdd_dl_fs_samp_buf> LTE_fdd_dl_fs_samp_buf_sptr;
typedef enum{
LTE_FDD_DL_FS_IN_SIZE_INT8 = 0,
LTE_FDD_DL_FS_IN_SIZE_GR_COMPLEX,
}LTE_FDD_DL_FS_IN_SIZE_ENUM;
typedef enum{
LTE_FDD_DL_FS_SAMP_BUF_STATE_COARSE_TIMING_SEARCH = 0,
LTE_FDD_DL_FS_SAMP_BUF_STATE_PSS_AND_FINE_TIMING_SEARCH,
......@@ -85,7 +96,7 @@ typedef enum{
CLASS DECLARATIONS
*******************************************************************************/
LTE_FDD_DL_FS_API LTE_fdd_dl_fs_samp_buf_sptr LTE_fdd_dl_fs_make_samp_buf ();
LTE_FDD_DL_FS_API LTE_fdd_dl_fs_samp_buf_sptr LTE_fdd_dl_fs_make_samp_buf(size_t in_size_val);
class LTE_FDD_DL_FS_API LTE_fdd_dl_fs_samp_buf : public gr::sync_block
{
public:
......@@ -96,9 +107,12 @@ public:
gr_vector_void_star &output_items);
private:
friend LTE_FDD_DL_FS_API LTE_fdd_dl_fs_samp_buf_sptr LTE_fdd_dl_fs_make_samp_buf();
friend LTE_FDD_DL_FS_API LTE_fdd_dl_fs_samp_buf_sptr LTE_fdd_dl_fs_make_samp_buf(size_t in_size_val);
LTE_fdd_dl_fs_samp_buf();
LTE_fdd_dl_fs_samp_buf(size_t in_size_val);
// Input parameters
LTE_FDD_DL_FS_IN_SIZE_ENUM in_size;
// LTE library
LIBLTE_PHY_STRUCT *phy_struct;
......@@ -107,6 +121,7 @@ private:
LIBLTE_RRC_MIB_STRUCT mib;
LIBLTE_RRC_BCCH_DLSCH_MSG_STRUCT bcch_dlsch_msg;
LIBLTE_RRC_PCCH_MSG_STRUCT pcch_msg;
LIBLTE_PHY_FS_ENUM fs;
// Sample buffer
float *i_buf;
......@@ -147,7 +162,7 @@ private:
// Helpers
void init(void);
void copy_input_to_samp_buf(const int8 *in, int32 ninput_items);
void copy_input_to_samp_buf(gr_vector_const_void_star &input_items, int32 ninput_items);
void freq_shift(uint32 start_idx, uint32 num_samps, float freq_offset);
void print_mib(LIBLTE_RRC_MIB_STRUCT *mib);
void print_sib1(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_1_STRUCT *sib1);
......@@ -159,6 +174,12 @@ private:
void print_sib7(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_7_STRUCT *sib7);
void print_sib8(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_8_STRUCT *sib8);
void print_page(LIBLTE_RRC_PAGING_STRUCT *page);
// Configuration
void print_config(void);
void change_config(char *line);
bool set_fs(char *char_value);
bool need_config;
};
#endif /* __LTE_FDD_DL_FS_SAMP_BUF_H__ */
......@@ -15,16 +15,26 @@ class LTE_fdd_dl_file_scan(gr.top_block):
usage = "usage: %prog [options] file"
parser=OptionParser(option_class=eng_option, usage=usage)
# Add options here
parser.add_option("-d", "--data-type", type="string", default="int8",
help="Input file data type, default=%default, options=[int8, gr_complex]")
(options, args) = parser.parse_args()
if len(args) != 1:
parser.print_help()
sys.exit(1)
if options.data_type == "gr_complex":
size = gr.sizeof_gr_complex
elif options.data_type == "int8":
size = gr.sizeof_char
else:
print("Invalid data type using int8")
size = gr.sizeof_char
input_filename = args[0]
# Build flow graph
self.fsrc = blocks.file_source(gr.sizeof_char, input_filename, False)
self.samp_buf = LTE_fdd_dl_fs.samp_buf()
self.fsrc = blocks.file_source(size, input_filename, False)
self.samp_buf = LTE_fdd_dl_fs.samp_buf(size)
self.connect(self.fsrc, self.samp_buf)
if __name__ == '__main__':
......
......@@ -43,10 +43,20 @@ and specify a recorded LTE file as the input. For example:
$ LTE_fdd_dl_file_scan.py lte_file.bin
The recorded LTE file currently must be interleaved 8-bit I and
Q samples recorded at 30.72MHz. NOTE: Files generated by the
file generator app can be used with the file scanner app only if
generated with 20MHz or 15MHz of bandwidth.
To see a list of options, use the -h option:
$ LTE_fdd_dl_file_scan.py -h
To change the input file data type (int8 or gr_complex), use the
-d/--data-type option:
$ LTE_fdd_dl_file_scan.py -d int8 lte_file.bin
For int8 data type, the recorded LTE file must be interleaved signed
8-bit I and Q samples. For the gr_complex data type, the recorded
LTE file must be sequential gr_complex I/Q samples. Files recorded
with LTE_file_recorder or generated with LTE_fdd_dl_file_gen can be
scanned with this application.
####################
# FILE GENERATOR #
......@@ -62,12 +72,20 @@ For example:
$ LTE_fdd_dl_file_gen.py lte_file.bin
The generated LTE file contains interleaved 8-bit I and Q samples
at a sample rate specified by the bandwidth (i.e. 30.72Msps for
20MHz or 15MHz, 15.36Msps for 10MHz, 7.68MHz for 5MHz, 3.84Msps
for 3MHz, or 1.92Msps for 1.4MHz). The output file can be used as
the input for the LTE_fdd_dl_file_scan application when the
bandwidth is set to 20MHz or 15MHz.
To see a list of options, use the -h option:
$ LTE_fdd_dl_file_gen.py -h
To change the output file data type (int8 or gr_complex), use the
-d/--data-type option:
$ LTE_fdd_dl_file_gen.py -d gr_complex lte_file.bin
For int8 data type, the generated LTE file contains interleaved
signed 8-bit I and Q samples. For the gr_complex data type, the
generated LTE file contains sequential gr_complex I/Q samples.
Files generated with this application can be scanned with
LTE_fdd_dl_file_scan.
#############
# SCANNER #
......@@ -88,9 +106,11 @@ is set to /usr/local/lib (export LD_LIBRARY_PATH=/usr/local/lib),
plug in rtl-sdr or hackrf hardware, run LTE_file_recorder, and connect
(via telnet, nc, etc) to the control port at port number 25000.
Recording parameters can be changed on the control port. For a list
of parameters simply type help on the control port. NOTE: This does
not currently support recording files for use with the file scanner
application.
of parameters simply type help on the control port. File recorded
using hackRF hardware are recorded using a sample rate of 15.36MHz.
Files recorded with all other hardware are recorded using a sample
rate of 1.92MHz. All files recorded with this application can be
scanned with LTE_fdd_dl_file_scan.
############
# OCTAVE #
......
......@@ -52,6 +52,8 @@
be non-ambiguous.
09/16/2013 Ben Wojtowicz Implemented routines for determine TBS, MCS,
N_prb, and N_cce.
09/28/2013 Ben Wojtowicz Reordered sample rate enum and added a text
version.
*******************************************************************************/
......@@ -148,12 +150,14 @@
*******************************************************************************/
typedef enum{
LIBLTE_PHY_FS_30_72MHZ = 0, // 20MHz and 15MHz bandwidths
LIBLTE_PHY_FS_15_36MHZ, // 10MHz bandwidth
LIBLTE_PHY_FS_7_68MHZ, // 5MHz bandwidth
LIBLTE_PHY_FS_3_84MHZ, // 3MHz bandwidth
LIBLTE_PHY_FS_1_92MHZ, // 1.4MHz bandwidth
LIBLTE_PHY_FS_1_92MHZ = 0, // 1.4MHz bandwidth
LIBLTE_PHY_FS_3_84MHZ, // 3MHz bandwidth
LIBLTE_PHY_FS_7_68MHZ, // 5MHz bandwidth
LIBLTE_PHY_FS_15_36MHZ, // 10MHz bandwidth
LIBLTE_PHY_FS_30_72MHZ, // 20MHz and 15MHz bandwidths
LIBLTE_PHY_FS_N_ITEMS,
}LIBLTE_PHY_FS_ENUM;
static const char liblte_phy_fs_text[LIBLTE_PHY_FS_N_ITEMS][20] = {"1.92", "3.84", "7.68", "15.36", "30.72"};
typedef enum{
LIBLTE_PHY_PRE_CODER_TYPE_TX_DIVERSITY = 0,
......
%
% Copyright 2013 Ben Wojtowicz
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU Affero General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program 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 Affero General Public License for more details.
%
% You should have received a copy of the GNU Affero General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.
%
% Function: lte_generate_dmrs_pusch
% Description: Generates LTE demodulation reference signal for PUSCH
% Inputs: N_s - Slot number within a radio frame
% N_id_cell - Physical layer cell identity
% delta_ss - Configurable portion of the sequence-shift pattern for PUSCH (sib2 groupAssignmentPUSCH)
% group_hopping_enabled - Boolean value determining if group hopping is enabled (sib2 groupHoppingEnabled)
% sequence_hopping_enabled - Boolean value determining if sequence hopping is enabled (sib2 sequenceHoppingEnabled)
% cyclic_shift - Broadcast cyclic shift to apply to base reference signal (sib2 cyclicShift)
% cyclic_shift_dci - Scheduled cyclic shift to apply to base reference signal
% w_config - fixed or table
% N_prbs - Number of PRBs used for the uplink grant
% layer - Which diversity layer to generate reference signals for
% Outputs: r - Demodulation reference signal for PUSCH
% Spec: 3GPP TS 36.211 section 5.5.2.1 v10.1.0
% Notes: Currently only handles normal CP
% Rev History: Ben Wojtowicz 09/28/2013 Created
%
function [r] = lte_generate_dmrs_pusch(N_s, N_id_cell, delta_ss, group_hopping_enabled, sequence_hopping_enabled, cyclic_shift, cyclic_shift_dci, w_config, N_prbs, layer)
% Defines
N_rb_ul_max = 110;
N_ul_symb = 7; % Only dealing with normal cp at this time
N_sc_rb = 12;
N_1_DMRS = [0,2,3,4,6,8,9,10];
N_2_DMRS_LAMBDA(0+1,:) = [ 0, 6, 3, 9];
N_2_DMRS_LAMBDA(1+1,:) = [ 6, 0, 9, 3];
N_2_DMRS_LAMBDA(2+1,:) = [ 3, 9, 6, 0];
N_2_DMRS_LAMBDA(3+1,:) = [ 4,10, 7, 1];
N_2_DMRS_LAMBDA(4+1,:) = [ 2, 8, 5,11];
N_2_DMRS_LAMBDA(5+1,:) = [ 8, 2,11, 5];
N_2_DMRS_LAMBDA(6+1,:) = [10, 4, 1, 7];
N_2_DMRS_LAMBDA(7+1,:) = [ 9, 3, 0, 6];
W_VECTOR(0+1,:,:) = [ 1, 1; 1, 1; 1,-1; 1,-1];
W_VECTOR(1+1,:,:) = [ 1,-1; 1,-1; 1, 1; 1, 1];
W_VECTOR(2+1,:,:) = [ 1,-1; 1,-1; 1, 1; 1, 1];
W_VECTOR(3+1,:,:) = [ 1, 1; 1, 1; 1, 1; 1, 1];
W_VECTOR(4+1,:,:) = [ 1, 1; 1, 1; 1, 1; 1, 1];
W_VECTOR(5+1,:,:) = [ 1,-1; 1,-1; 1,-1; 1,-1];
W_VECTOR(6+1,:,:) = [ 1,-1; 1,-1; 1,-1; 1,-1];
W_VECTOR(7+1,:,:) = [ 1, 1; 1, 1; 1,-1; 1,-1];
% Validate N_s
if(~(N_s >= 0 && N_s <= 19))
printf("ERROR: Invalid N_s (%u)\n", N_s);
r = 0;
return;
endif
% Validate N_id_cell
if(~(N_id_cell >= 0 && N_id_cell <= 503))
printf("ERROR: Invalid N_id_cell (%u)\n", N_id_cell);
r = 0;
return;
endif
% Validate delta_ss
if(~(delta_ss >= 0 && delta_ss <= 29))
printf("ERROR: Invalid delta_ss (%u)\n", delta_ss);
r = 0;
return;
endif
% Validate group_hopping_enabled
if(~(group_hopping_enabled == 1 || group_hopping_enabled == 0))
printf("ERROR: Invalid group_hopping_enabled (%u)\n", group_hopping_enabled);
r = 0;
return;
endif
% Validate sequence_hopping_enabled
if(~(sequence_hopping_enabled == 1 || sequence_hopping_enabled == 0))
printf("ERROR: Invalid sequence_hopping_enabled (%u)\n", sequence_hopping_enabled);
r = 0;
return;
endif
% Validate cyclic_shift
if(~(cyclic_shift >= 0 && cyclic_shift <= 7))
printf("ERROR: Invalid cyclic_shift (%u)\n", cyclic_shift);
r = 0;
return;
endif
% Validate cyclic_shift_dci
if(~(cyclic_shift_dci >= 0 && cyclic_shift_dci <= 7))
printf("ERROR: Invalid cyclic_shift_dci (%u)\n", cyclic_shift_dci);
r = 0;
return;
endif
% Validate w_config
if(~(w_config == "fixed" || w_config == "table"))
printf("ERROR: Invalid w_config (%s)\n", w_config);
r = 0;
return;
endif
% Validate N_prbs
if(~(N_prbs >= 1 && N_prbs <= N_rb_ul_max))
printf("ERROR: Invalid N_prbs (%u)\n", N_prbs);
r = 0;
return;
endif
% Validate layer
if(~(layer >= 0 && layer <= 3))
printf("ERROR: Invalid layer (%u)\n", layer);
r = 0;
return;
endif
% Set lambda
lambda = layer;
% Calculate f_ss_pusch
f_ss_pusch = mod(mod(N_id_cell, 30) + delta_ss, 30);
% Generate c
c_init = floor(N_id_cell/30)*2^5 + f_ss_pusch;
c = lte_generate_prs_c(c_init, 8*N_ul_symb*20);
% Calculate n_pn_ns
n_pn_ns = 0;
for(n=0:7)
n_pn_ns = n_pn_ns + c(8*N_ul_symb*N_s + n + 1)*2^n;
endfor
% Determine n_1_dmrs
n_1_dmrs = N_1_DMRS(cyclic_shift+1);
% Determine n_2_dmrs_lambda
n_2_dmrs_lambda = N_2_DMRS_LAMBDA(cyclic_shift_dci+1, lambda+1);
% Calculate n_cs_lambda
n_cs_lambda = mod(n_1_dmrs + n_2_dmrs_lambda + n_pn_ns, 12);
% Calculate alpha_lambda
alpha_lambda = 2*pi*n_cs_lambda/12;
% Generate the base reference signal
r_u_v_alpha_lambda = lte_generate_ul_rs(N_s, N_id_cell, "pusch", delta_ss, group_hopping_enabled, sequence_hopping_enabled, alpha_lambda, N_prbs);
% Determine w vector
if(w_config == "fixed")
w_vector = [1, 1];
else
w_vector = reshape(W_VECTOR(cyclic_shift_dci+1, lambda+1, :), 1, 2);
endif
% Calculate M_sc_rb
M_sc_rb = N_prbs*N_sc_rb;
% Generate the PUSCH demodulation reference signal sequence
for(m=0:1)
for(n=0:M_sc_rb-1)
r(m*M_sc_rb + n + 1) = w_vector(m+1)*r_u_v_alpha_lambda(n+1);
endfor
endfor
endfunction
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment