[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/IQ_Analyzer/src/IQ_Decoder.py b/mcu/tools/IQ_Analyzer/src/IQ_Decoder.py
new file mode 100644
index 0000000..d2d9a56
--- /dev/null
+++ b/mcu/tools/IQ_Analyzer/src/IQ_Decoder.py
@@ -0,0 +1,188 @@
+import numpy as np
+from IQ_Utils import L
+
+class SS_Decoder:
+ def __init__(self, params, signals):
+ # 10 Last samples used only on drawing.
+ self.PSS_corr_magSQR_output_frame_main = [0] * 10 * params.analysis_frame_len
+ self.SSS_corr_magSQR_output_frame_main = [0] * 10 * params.analysis_frame_len
+ # We have found PSS singal
+ self.PSS_peak_detected = 0
+ # We have found SSS signal
+ self.SSS_peak_detected = 0
+ # Index in our buffer, previous index
+ self.hold_PSS_max_idx = 0
+ self.hold_SSS_max_idx = 0
+ # Do Inverse Fast Fourier Transformation
+ self.doIFFT = 0
+ # Index on our index current.
+ self.PSS_Subframe_max_idx = 0
+ self.SSS_Subframe_max_idx = 0
+ self.params = params
+ self.signals = signals
+ self.PSS_Subframe_max_val = 0
+ self.SSS_Subframe_max_val = 0
+ # 3 Samples.
+ self.IQ_ThreeframeBuffer_main = [0] * 3 * params.analysis_frame_len
+
+ def pss_run(self, IQ_frame_main_norm):
+ params = self.params
+
+ # Keep feeding our 3 sample buffer, newest data to last
+ self.IQ_ThreeframeBuffer_main[:2*params.analysis_frame_len] = self.IQ_ThreeframeBuffer_main[params.analysis_frame_len:]
+ self.IQ_ThreeframeBuffer_main[2*params.analysis_frame_len:] = IQ_frame_main_norm
+ #if (params.is_NR==1):
+ if (0):
+ # Reset 4 symbols of extension
+ self.IQ_ThreeframeBuffer_main[3*params.analysis_frame_len-params.analysis_frame_overlap:] = [0] * params.analysis_frame_overlap
+
+ PSS_TD_seq = self.signals.PSS_TD_complex_pad_fftSize_wShift_ifft # Local
+
+ # Cross-correlation with our reference signal to find reference singal
+ IQ_ThreeframeBuffer_PSScorr_main = np.correlate(self.IQ_ThreeframeBuffer_main,PSS_TD_seq,'full')
+ #print [len(IQ_ThreeframeBuffer_PSScorr_main), len(self.IQ_ThreeframeBuffer_main), len(PSS_TD_seq)]
+
+ # Get middle sample.
+ IQ_frame_PSScorr_main = IQ_ThreeframeBuffer_PSScorr_main[params.analysis_frame_len:2*params.analysis_frame_len]
+
+ # Convert our sample to abs.
+ IQ_frame_ABS_PSScorr_main = np.absolute(IQ_frame_PSScorr_main)
+
+ # Keep feeding our 10 sample buffer (10ms one radioframe). Add current sample to last.
+ self.PSS_corr_magSQR_output_frame_main[:9*params.analysis_frame_len] = self.PSS_corr_magSQR_output_frame_main[params.analysis_frame_len:]
+ self.PSS_corr_magSQR_output_frame_main[9*params.analysis_frame_len:] = IQ_frame_ABS_PSScorr_main
+
+ self.PSS_Subframe_max_idx = np.argmax(IQ_frame_ABS_PSScorr_main) # Find maximun value from our data "Maximum Likehood"
+ self.PSS_Subframe_max_val = IQ_frame_ABS_PSScorr_main[self.PSS_Subframe_max_idx]
+
+ # Calculate average level
+ PSS_Subframe_mean = np.mean(IQ_frame_ABS_PSScorr_main)
+
+ # Find peak
+ if (params.is_TDD == 1):
+ PSS_threshold = 0.2
+ else:
+ PSS_threshold = 0.1
+
+ if ((self.PSS_Subframe_max_val > 2.0*PSS_Subframe_mean)and(self.PSS_Subframe_max_val > PSS_threshold)):
+ self.doIFFT = 1
+ self.PSS_peak_detected = 1
+
+ if (self.hold_PSS_max_idx == 0):
+ self.hold_PSS_max_idx = self.PSS_Subframe_max_idx
+
+
+ L.info( 'PSS peak idx: ' + str(self.PSS_Subframe_max_idx) )
+ L.info( 'PSS max: ' +str(self.PSS_Subframe_max_val) )
+
+ else:
+ self.doIFFT = 0
+ self.PSS_peak_detected = 0
+
+ def nr_sss_run(self, fetch_SSS_seq):
+ params = self.params
+
+ SSS_TD_seq = self.signals.SSS_TD_complex_pad_fftSize_wShift_ifft # Local
+
+ # Cross-correlation with our reference signal to find reference singal
+ IQ_ThreeframeBuffer_SSScorr_main = np.correlate(self.IQ_ThreeframeBuffer_main,SSS_TD_seq,'full')
+
+ # Get middle sample.
+ IQ_frame_SSScorr_main = IQ_ThreeframeBuffer_SSScorr_main[params.analysis_frame_len:2*params.analysis_frame_len]
+
+ # Convert our sample to abs.
+ IQ_frame_ABS_SSScorr_main = np.absolute(IQ_frame_SSScorr_main)
+
+ # Keep feeding our 10 sample buffer (10ms one radioframe). Add current sample to last.
+ self.SSS_corr_magSQR_output_frame_main[:9*params.analysis_frame_len] = self.SSS_corr_magSQR_output_frame_main[params.analysis_frame_len:]
+ self.SSS_corr_magSQR_output_frame_main[9*params.analysis_frame_len:] = IQ_frame_ABS_SSScorr_main
+
+ self.SSS_Subframe_max_idx = np.argmax(IQ_frame_ABS_SSScorr_main) # Find maximun value from our data "Maximum Likehood"
+ self.SSS_Subframe_max_val = IQ_frame_ABS_SSScorr_main[self.SSS_Subframe_max_idx]
+
+ # Calculate average level
+ SSS_Subframe_mean = np.mean(IQ_frame_ABS_SSScorr_main)
+
+ # Find peak
+ if (params.is_TDD == 1):
+ SSS_threshold = 0.2
+ else:
+ SSS_threshold = 0.1
+
+ if ((self.SSS_Subframe_max_val > 2.0*SSS_Subframe_mean)and(self.SSS_Subframe_max_val > SSS_threshold)):
+ self.SSS_peak_detected = 1
+ L.info( 'SSS peak idx: ' + str(self.SSS_Subframe_max_idx) )
+ L.info( 'SSS max: ' +str(self.SSS_Subframe_max_val) )
+ else:
+ self.SSS_peak_detected = 0
+ #Correlation Subframe
+ SSS_corr = np.sum(np.multiply(fetch_SSS_seq,self.signals.d_sss))
+ SSS_corr_abs_sqr = np.square(np.absolute(SSS_corr))
+ return 0
+
+ def lte_sss_run(self, fetch_SSS_seq):
+ # Deinterleave SSS
+ SSS_seq_2k = fetch_SSS_seq[::2]
+ SSS_seq_2kPlus1 = fetch_SSS_seq[1::2]
+
+ # ***** 2k processing part *****
+
+ # Pre-generate seq for correlation with SSS (2k)
+ s0c0_ = np.multiply(self.signals.s0_,self.signals.c0_) #For Subfame_0
+ s1c0_ = np.multiply(self.signals.s1_,self.signals.c0_) #For Subfame_5
+
+ # Correlation Subframe_0
+ SSS_corr_s0c0 = np.sum(np.multiply(SSS_seq_2k,s0c0_))
+ SSS_corr_abs_sqr_s0c0 = np.square(np.absolute(SSS_corr_s0c0))
+
+ # Correlation Subframe_5
+ SSS_corr_s1c0 = np.sum(np.multiply(SSS_seq_2k,s1c0_))
+ SSS_corr_abs_sqr_s1c0 = np.square(np.absolute(SSS_corr_s1c0))
+
+ #print [SSS_corr_abs_sqr_s0c0, SSS_corr_abs_sqr_s1c0]
+ #print ['SSS subframe',np.argmax([SSS_corr_abs_sqr_s0c0, SSS_corr_abs_sqr_s1c0])]
+
+ # ***** 2k+1 processing part *****
+
+ # Pre-generate seq for correlation with SSS (2k)
+ #For Subfame_0
+ s1c1_ = np.multiply(self.signals.s1_,self.signals.c1_)
+ s1c1z1m0 = np.multiply(s1c1_,self.signals.z1_m0)
+ #For Subfame_5
+ s0c1_ = np.multiply(self.signals.s0_,self.signals.c1_)
+ s0c1z1m1 = np.multiply(s0c1_,self.signals.z1_m1)
+
+ # Correlation Subframe_0
+ SSS_corr_s1c1z1m0 = np.sum(np.multiply(SSS_seq_2kPlus1,s1c1z1m0))
+ SSS_corr_abs_sqr_s1c1z1m0 = np.square(np.absolute(SSS_corr_s1c1z1m0))
+
+ # Correlation Subframe_5
+ SSS_corr_s0c1z1m1 = np.sum(np.multiply(SSS_seq_2kPlus1,s0c1z1m1))
+ SSS_corr_abs_sqr_s0c1z1m1 = np.square(np.absolute(SSS_corr_s0c1z1m1))
+
+ #print [SSS_corr_abs_sqr_s1c1z1m0, SSS_corr_abs_sqr_s0c1z1m1]
+
+ # Frame Timing Decision module
+ SSS_metric_Subframe0 = SSS_corr_abs_sqr_s0c0 + SSS_corr_abs_sqr_s1c1z1m0
+ SSS_metric_Subframe5 = SSS_corr_abs_sqr_s1c0 + SSS_corr_abs_sqr_s0c1z1m1
+ #print[SSS_metric_Subframe0,SSS_metric_Subframe5]
+
+ #ToDo: Revise threshold condition below
+ if (SSS_metric_Subframe0 > 10.0*SSS_metric_Subframe5):
+ start_half_frame = 0
+ #ToDo: Revise threshold condition below
+ if (SSS_metric_Subframe5 > 10.0*SSS_metric_Subframe0):
+ start_half_frame = 1
+
+# else:
+# start_half_frame = 1
+ #print "half_frame = " + str(start_half_frame)
+ half_subframe_offset = start_half_frame * 70
+
+ # SSS HACK!!! (Needed for LowRX)
+ if (start_half_frame == 1):
+ start_half_frame = 0
+ else:
+ start_half_frame = 1
+ self.SSS_peak_detected = 0
+ return half_subframe_offset
\ No newline at end of file