From caf7075d7f84c8083fd5b30c2f7b4ace243441c2 Mon Sep 17 00:00:00 2001 From: baobrien Date: Fri, 13 Mar 2015 01:12:05 +0000 Subject: [PATCH] cic 8k complex to 80k real converter confirmed in C. More work still needed. git-svn-id: https://svn.code.sf.net/p/freetel/code@2070 01035d8c-6547-0410-b346-abe4f91aad63 --- codec2-dev/octave/dacres.m | 6 +- codec2-dev/stm32/inc/iir_duc.h | 2 + codec2-dev/stm32/inc/stm32f4_dacduc.h | 2 +- codec2-dev/stm32/src/fast_dac_ut.c | 2 +- codec2-dev/stm32/src/iir_duc.c | 150 +++++++++++++++++++++++--- 5 files changed, 146 insertions(+), 16 deletions(-) diff --git a/codec2-dev/octave/dacres.m b/codec2-dev/octave/dacres.m index a57ea309..d584d35d 100644 --- a/codec2-dev/octave/dacres.m +++ b/codec2-dev/octave/dacres.m @@ -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 diff --git a/codec2-dev/stm32/inc/iir_duc.h b/codec2-dev/stm32/inc/iir_duc.h index 42f9d15e..3148855d 100644 --- a/codec2-dev/stm32/inc/iir_duc.h +++ b/codec2-dev/stm32/inc/iir_duc.h @@ -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 diff --git a/codec2-dev/stm32/inc/stm32f4_dacduc.h b/codec2-dev/stm32/inc/stm32f4_dacduc.h index ecadf14f..05dfd238 100644 --- a/codec2-dev/stm32/inc/stm32f4_dacduc.h +++ b/codec2-dev/stm32/inc/stm32f4_dacduc.h @@ -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 */ diff --git a/codec2-dev/stm32/src/fast_dac_ut.c b/codec2-dev/stm32/src/fast_dac_ut.c index d1848c55..0790f3a1 100644 --- a/codec2-dev/stm32/src/fast_dac_ut.c +++ b/codec2-dev/stm32/src/fast_dac_ut.c @@ -75,7 +75,7 @@ int main(void) { memset((void*)outbuf,0,sizeof(short)*DAC_DUC_BUF_SZ); setup_timer(); - dac_open(2*DAC_DUC_BUF_SZ,2*DAC_BUF_SZ); + fast_dac_open(2*DAC_DUC_BUF_SZ,2*DAC_BUF_SZ); tstart=tend=0; while (1) { diff --git a/codec2-dev/stm32/src/iir_duc.c b/codec2-dev/stm32/src/iir_duc.c index 25f3944a..60fc601b 100644 --- a/codec2-dev/stm32/src/iir_duc.c +++ b/codec2-dev/stm32/src/iir_duc.c @@ -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;iF8C80R_LEN) + ptr_8c80r=0; + } + for(j=0;j>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