[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