cic 8k complex to 80k real converter confirmed in C. More work still needed.
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 13 Mar 2015 01:12:05 +0000 (01:12 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 13 Mar 2015 01:12:05 +0000 (01:12 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2070 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/dacres.m
codec2-dev/stm32/inc/iir_duc.h
codec2-dev/stm32/inc/stm32f4_dacduc.h
codec2-dev/stm32/src/fast_dac_ut.c
codec2-dev/stm32/src/iir_duc.c

index a57ea309aee22f2b068fd2a7d57b296fcfaa31de..d584d35db96e81091c53e07a07ae9f3a9730d5ab 100644 (file)
@@ -15,11 +15,13 @@ fi = 2E6/M;                     %freq of first interpolation
 fb = 7E5;                       %Bandpass frequency
 fc1 = fi/4;                     %Frequency of initial upconversion
 ciccb=[-0.029626    0.252638   -2.304683   16.332166   -2.304683    0.252638   -0.029626]; %CIC Compensation FIR
-pcicfb = fir1(20,.5); %Interpolation LPF Fir
+pcicfb = fir1(21,.5); %Interpolation LPF Fir
 s1fir = filter(ciccb,1,pcicfb); %Combine compensation and LPF
+s1fir = [-0.00000215, -0.00008715, 0.00073915, -0.00674415, 0.05618415, 0.01629015, -0.19074815, -0.04231615, 0.53620515, 0.09933915, -1.32978715, -0.38797815, 3.97887715, 6.70888315, 3.97887715, -0.38797815, -1.32978715, 0.09933915, 0.53620515, -0.04231615, -0.19074815, ];
 
 t = (1:fs/2);
-scpin = e.^(i*(t*pi*2*(3000/8000)));       % initial complex input
+%scpin = e.^(i*(t*pi*2*(3000/8000)));       % initial complex input
+scpin = zeros(1,length(t));
 scpin(1) = 1+i;
 
 intstage1 = zeros(1,2*length(scpin));   %First stage of interpolation, 2x
index 42f9d15e9d72726305ab0dc8636816e4c208cbe6..3148855dca68dc7a5a4e4a65648f2cfefc94feea 100644 (file)
@@ -27,7 +27,9 @@
 
 #ifndef __IIR_DUC_H
 #define __IIR_DUC_H
+#include "comp.h"
 
 void iir_upconv(float modin[],unsigned short dac_out[]);
+void upconv_8c_80r(COMP comp_8[],float real_80[],int count);
 
 #endif
index ecadf14f4aaf9847e9fb1866cf947b5857395e41..05dfd238ae97dbf1cfb1cc76c922900673b851e8 100644 (file)
@@ -34,7 +34,7 @@
 #define DAC_DUC_BUF_SZ DUC_M*DUC_N
 #define DAC_BUF_SZ 2048
 
-void fast_dac_open(int fifo_sz);
+void fast_dac_open(int dac1_fifo_size,int dac2_fifo_size);
 int dac1_write(short buf[], int n); /* DAC1 pin PA4 */
 int dac2_write(short buf[], int n); /* DAC2 pin PA5 */
 
index d1848c55eb594c8794b5412b804e6910c8c13b3c..0790f3a1918f879e67019b9bfd653cbfd6a0a8d2 100644 (file)
@@ -75,7 +75,7 @@ int main(void) {
 \r
     memset((void*)outbuf,0,sizeof(short)*DAC_DUC_BUF_SZ);\r
     setup_timer();\r
-    dac_open(2*DAC_DUC_BUF_SZ,2*DAC_BUF_SZ);\r
+    fast_dac_open(2*DAC_DUC_BUF_SZ,2*DAC_BUF_SZ);\r
 \r
     tstart=tend=0;\r
     while (1) {\r
index 25f3944ab0ddea71d4a1175f8386702422db69b8..60fc601bb586db83c3502a1384832afba41e4137 100644 (file)
@@ -79,6 +79,97 @@ void iir_upconv(float modin[], unsigned short dac_out[]){
     }
 }
 
+#define F8C80R_LEN 21                                       //Number of taps in the 8C80R filters
+#define F8C80R_MUL 1024
+static int int1r,int2r,int3r,int4r,cmb1r,cmb2r,cmb3r,cmb4r; //States for re combs and integrators
+static int int1i,int2i,int3i,int4i,cmb1i,cmb2i,cmb3i,cmb4i; //States for im combs and integrators
+static float fir_8c80r_cic[];                               //FIR Coeffs
+static float fir_8c80r_re[F8C80R_LEN*2];                    //FIR delay line for re
+static float fir_8c80r_im[F8C80R_LEN*2];                    //FIR delay line for im
+static float f8c80r_temp_re[DUC_N/5];
+static float f8c80r_temp_im[DUC_N/5];
+static int ptr_8c80r;                                       //circular buffer ptr fir_8c80r_re
+static int w8c80r = 0;                                      //Omega for upconversion
+static int cosf4[] = {1,0,-1,0};                            //Cosine table for fs/4. precomputed by meat computer
+static int sinf4[] = {0,1,0,-1};                            //Sine table for fs/4.
+/*
+   Interpolate and shift from 8k complex to 80k real, centered on Fs/4.
+    comp_8 - Input samples - 8Kc complex - must be (DUC_N/10)*count long
+    upout - Output samples - must be DUC_N*count long
+    count - how many chunks of samples must be processed
+*/
+
+void upconv_8c_80r(COMP comp_8[],float real_80[],int count){
+    int i,j,k;
+    float nr,ni,ret;
+    int cmbr,cmbi,cmbrr,cmbii,rein,imin;
+    for(i=0;i<count;i++){                //Iterate through chunks of samples
+        for(j=0;j<DUC_N/10;j++){          //zero stuff
+            f8c80r_temp_re[ j*2   ] = comp_8[j + (i * (DUC_N/10)) ].real;
+            f8c80r_temp_re[(j*2)+1] = 0; //Stuff a zero in here
+            f8c80r_temp_im[ j*2   ] = comp_8[j + (i * (DUC_N/10)) ].imag;
+            f8c80r_temp_im[(j*2)+1] = 0; //Stuff a zero in here
+        }
+        for(j=0;j<DUC_N/5;j++){          //run samples through a fir
+            fir_8c80r_re[ptr_8c80r]=f8c80r_temp_re[j];
+            fir_8c80r_im[ptr_8c80r]=f8c80r_temp_im[j];
+            fir_8c80r_re[ptr_8c80r+F8C80R_LEN]=f8c80r_temp_re[j];
+            fir_8c80r_im[ptr_8c80r+F8C80R_LEN]=f8c80r_temp_im[j];
+            nr=0; ni=0;
+            for(k=0;k<F8C80R_LEN;k++){
+                nr=nr+fir_8c80r_cic[k]*fir_8c80r_re[(ptr_8c80r+F8C80R_LEN)-k];
+                ni=ni+fir_8c80r_cic[k]*fir_8c80r_im[(ptr_8c80r+F8C80R_LEN)-k];
+            }
+            f8c80r_temp_re[j]=nr; //Can be optimized out. Will do later
+            f8c80r_temp_im[j]=ni; //Ditto
+            ptr_8c80r++;
+            if(ptr_8c80r>F8C80R_LEN)
+                ptr_8c80r=0;
+        }
+        for(j=0;j<DUC_N/5;j++){   //Comb and Integrate
+            rein = (int)(f8c80r_temp_re[j]*F8C80R_MUL); //Can be optimized out. Will do later
+            imin = (int)(f8c80r_temp_im[j]*F8C80R_MUL); //Ditto
+           
+            cmbr =  rein - cmb1r; cmb1r = rein;   //Comb 1 real
+            cmbrr = cmbr - cmb2r; cmb2r = cmbr;   //Comb 2 real
+            cmbr = cmbrr - cmb3r; cmb3r = cmbrr;  //Comb 3 real
+            cmbrr = cmbr - cmb4r; cmb4r = cmbr;   //Comb 4 real
+
+            cmbi =  imin - cmb1i; cmb1i = imin;   //Comb 1 im
+            cmbii = cmbi - cmb2i; cmb2i = cmbi;   //Comb 2 im
+            cmbi = cmbii - cmb3i; cmb3i = cmbii;  //Comb 3 im
+            cmbii = cmbi - cmb4i; cmb4i = cmbi;   //Comb 4 im
+            //Do one cycle of integration
+            int1r = cmbrr + int1r;                //Integrator stage 1 re
+            int2r = int1r + int2r;                //Integrator stage 2 re
+            int3r = int2r + int3r;                //Integrator stage 3 re
+            int4r = int3r + int4r;                //Integrator stage 4 re
+
+            int1i = cmbii + int1i;                //Integrator stage 1 im
+            int2i = int1i + int2i;                //Integrator stage 2 im
+            int3i = int2i + int3i;                //Integrator stage 3 im
+            int4i = int3i + int4i;                //Integrator stage 4 im
+            //Convert this complex into real and cancel out the gain from CIC
+           ret = (float) (((-cosf4[w8c80r]*int4r)+(sinf4[w8c80r]*int4i))>>0);
+            real_80[(i*DUC_N)+(j*5)] = ret/F8C80R_MUL;
+            w8c80r = (w8c80r+1)&0x3;
+            for(k=1;k<5;k++){                     //Next 4 stages of integration
+                //int1r = 0 + int1r;            //Integrator stage 1 re
+                int2r = int1r + int2r;            //Integrator stage 2 re
+                int3r = int2r + int3r;            //Integrator stage 3 re
+                int4r = int3r + int4r;            //Integrator stage 4 re
+                //int1i = 0 + int1i;            //Integrator stage 1 im
+                int2i = int1i + int2i;            //Integrator stage 2 im
+                int3i = int2i + int3i;            //Integrator stage 3 im
+                int4i = int3i + int4i;            //Integrator stage 4 im
+               ret = (float)(((-cosf4[w8c80r]*int4r)+(sinf4[w8c80r]*int4i))>>0);
+               // printf("%f,",ret);
+                real_80[(i*DUC_N)+(j*5)+k] = ret/F8C80R_MUL;
+               w8c80r = (w8c80r+1)&0x3;
+            }
+        }
+    } 
+}
 
 #ifdef __UNITTEST__
 
@@ -90,7 +181,7 @@ void iir_upconv(float modin[], unsigned short dac_out[]){
 #define FS     80000
 #define AMP_MAX 1
 
-#define NOUT_BUFS    401
+#define NOUT_BUFS    1000
 #define NIN          (NOUT_BUFS*DUC_N)
 #define NOUT         (NIN*DUC_M)
 
@@ -106,6 +197,7 @@ void synth_line(float us[], float f, float amp, int n) {
     }
 }
 
+COMP       in[NIN/10];
 float     s[NIN];
 float      fout[NIN];
 unsigned short todac[NOUT];
@@ -119,36 +211,70 @@ int main(void) {
     f2 = f1;     /* wanted */
     f3 = f1 + 7E3;        /* wanted */
 
-
-    for(i=0; i<NIN; i++)
-        s[i] = 0.01;
-    synth_line(s, f2, 0.5, NIN);
-    synth_line(s, f3, 0.5, NIN);
-    for(i=0;i<NOUT_BUFS;i++)
-        iir_upconv(&s[i*(DUC_N)],&todac[i*(DUC_N*DUC_M)]);
+    for(i=0;i<NIN/10;i++){
+        in[i].real=cos((float)i*(M_PI*.25));
+        printf("%f\n",in[i].real);
+        //in[i].real=0.70710678118;
+        in[i].imag=0;
+    }
+    //in[0].real=1;
+    /*for(i=0; i<NIN; i++)
+        s[i] = 0.01;*/
+    /*synth_line(s, f2, 0.5, NIN);
+    synth_line(s, f3, 0.5, NIN);*/
+    printf("\n");
+    upconv_8c_80r(in,s,NOUT_BUFS);
+    printf("\n");
+    //for(i=0;i<NOUT_BUFS;i++)
+    //    iir_upconv(&s[i*(DUC_N)],&todac[i*(DUC_N*DUC_M)]);
     
     f = fopen("iir_duc_s.txt", "wt");  assert(f != NULL);
-    for(i=DUC_N; i<NIN; i++)
+    for(i=0; i<NIN; i++)
         fprintf(f, "%f\n", s[i]);
     fprintf(f, "\n");
     fclose(f);
 
     f = fopen("iir_duc_f.txt", "wt");  assert(f != NULL);
-    for(i=DUC_N; i<NIN; i++)
+    for(i=0; i<NIN; i++)
         fprintf(f, "%f\n", fout[i]);
     fprintf(f, "\n");
     fclose(f);
 
     f = fopen("iir_duc.txt", "wt");  assert(f != NULL);
-    for(i=DUC_N*DUC_M; i<NOUT; i++)
+    for(i=0; i<NOUT; i++)
         fprintf(f, "%d\n", todac[i]);
     fprintf(f, "\n");
     fclose(f);
-
     return 0;
 }
 
 #endif
 
+// constants for a fir filter used to convert 8kc complex to 80kc real
+static float fir_8c80r_cic[] = {
+-0.00000215,
+-0.00008715,
+0.00073915,
+-0.00674415,
+0.05618415,
+0.01629015,
+-0.19074815,
+-0.04231615,
+0.53620515,
+0.09933915,
+-1.32978715,
+-0.38797815,
+3.97887715,
+6.70888315,
+3.97887715,
+-0.38797815,
+-1.32978715,
+0.09933915,
+0.53620515,
+-0.04231615,
+-0.19074815,
+};
+
+