From: baobrien Date: Mon, 9 Mar 2015 02:54:54 +0000 (+0000) Subject: Verified IIR upconverter, modified fast_dac_ut.c to run upconverter X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=1a12d4203542c39229a4dd5da97b2ebd62739e58;p=freetel-svn-tracking.git Verified IIR upconverter, modified fast_dac_ut.c to run upconverter git-svn-id: https://svn.code.sf.net/p/freetel/code@2061 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/dacres.m b/codec2-dev/octave/dacres.m index 155a65ae..3d179639 100644 --- a/codec2-dev/octave/dacres.m +++ b/codec2-dev/octave/dacres.m @@ -17,7 +17,7 @@ t = (0:(fs-1)); beta1 = 0.999; b1x = -2*sqrt(beta1)*cos(2*pi*fb/(fs*M)) -beta2 = 1 - (1-0.999)*M; +beta2 = beta1 - (1-0.999)*M; s1 = [fs zeros(1,fs-1)]; % noise floor, continuous interferers s2 = 100*4*cos(t*2*pi*f2/fs); % wanted signal 40dB above interferers diff --git a/codec2-dev/stm32/Makefile b/codec2-dev/stm32/Makefile index 7a4ca399..5c83e667 100644 --- a/codec2-dev/stm32/Makefile +++ b/codec2-dev/stm32/Makefile @@ -158,6 +158,8 @@ dac_ut.elf: $(DAC_UT_SRCS) FAST_DAC_UT_SRCS=\ src/fast_dac_ut.c \ ../src/fifo.c \ +src/iir_duc.c \ +src/gdb_stdio.c \ src/stm32f4_dacduc.c \ src/debugblinky.c \ src/system_stm32f4xx.c \ @@ -165,7 +167,7 @@ src/startup_stm32f4xx.s \ src/init.c fast_dac_ut.elf: $(FAST_DAC_UT_SRCS) - $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS) + $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS) $(OBJCOPY) -O binary fast_dac_ut.elf fast_dac_ut.bin ADCDAC_UT_SRCS=\ diff --git a/codec2-dev/stm32/inc/stm32f4_dacduc.h b/codec2-dev/stm32/inc/stm32f4_dacduc.h index 580bfcc2..ecadf14f 100644 --- a/codec2-dev/stm32/inc/stm32f4_dacduc.h +++ b/codec2-dev/stm32/inc/stm32f4_dacduc.h @@ -29,12 +29,12 @@ #ifndef __STM32F4_DAC__ #define __STM32F4_DAC__ -#define DUC_N 100 +#define DUC_N 160 #define DUC_M 25 #define DAC_DUC_BUF_SZ DUC_M*DUC_N #define DAC_BUF_SZ 2048 -void dac_open(int fifo_sz); +void fast_dac_open(int fifo_sz); 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 bc19547a..d1848c55 100644 --- a/codec2-dev/stm32/src/fast_dac_ut.c +++ b/codec2-dev/stm32/src/fast_dac_ut.c @@ -27,9 +27,15 @@ */ #include +#include #include "stm32f4_dacduc.h" +#include "iir_duc.h" +#include "stm32f4xx.h" +#include +#include +#include "gdb_stdio.h" -#define SINE_SAMPLES 60 +#define SINE_SAMPLES 32 /* 32 sample sine wave which at Fs=16kHz will be 500Hz. Note samples @@ -39,17 +45,49 @@ short aWave[] = {4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0, 4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,}; -short aSine[] = {390, 3981, 1410, 841, 4080, 841, 1410, 3981, 390, 2040, 3691, 100, 2671, 3240, 0, 3240, 2671, 100, 3691, 2040, 390, 3981, 1410, 841, 4080, 841, 1410, 3981, 390, 2040, 3691, 100, 2671, 3240, 0, 3240, 2671, 100, 3691, 2040,390, 3981, 1410, 841, 4080, 841, 1410, 3981, 390, 2040, 3691, 100, 2671, 3240, 0, 3240, 2671, 100, 3691, 2040 +short aSine[] = {1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1600, 0, 1600, 3200, 1601, 0 }; +//Sine at Fs/4 +float f4sine[] = {1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0, + -1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0, + 1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0, + -1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,}; + +unsigned short outbuf[DAC_DUC_BUF_SZ]; + +void setup_timer() +{ + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + + TIM_TimeBaseInitTypeDef timerInitStructure; + timerInitStructure.TIM_Prescaler = 84; + timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up; + timerInitStructure.TIM_Period = 0x8FFFFFFF; + timerInitStructure.TIM_ClockDivision = 0; + timerInitStructure.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIM2, &timerInitStructure); + TIM_Cmd(TIM2, ENABLE); +} + int main(void) { + int tstart,tend,cyc; - dac_open(4*DAC_DUC_BUF_SZ); - while (1) { + memset((void*)outbuf,0,sizeof(short)*DAC_DUC_BUF_SZ); + setup_timer(); + dac_open(2*DAC_DUC_BUF_SZ,2*DAC_BUF_SZ); + tstart=tend=0; + while (1) { + cyc++; + if(cyc%100000==0){ + printf("upconvert takes %d uSecs\n",tend-tstart); + } /* keep DAC FIFOs topped up */ - - dac1_write((short*)aWave, SINE_SAMPLES); + tstart = TIM_GetCounter(TIM2); + iir_upconv(f4sine,outbuf); + tend = TIM_GetCounter(TIM2); + dac1_write((short*)outbuf,DAC_DUC_BUF_SZ); } } diff --git a/codec2-dev/stm32/src/iir_duc.c b/codec2-dev/stm32/src/iir_duc.c index d4191717..d4661131 100644 --- a/codec2-dev/stm32/src/iir_duc.c +++ b/codec2-dev/stm32/src/iir_duc.c @@ -8,8 +8,8 @@ Unit testing: - ~/codec2-dev/stm32$ gcc -D__UNITTEST__ -Iinc src/iir_tuner.c -o iir_tuner -lm -Wall - ~/codec2-dev/stm32$ ./iir_tuner + ~/codec2-dev/stm32$ gcc -D__UNITTEST__ -Iinc src/iir_duc.c -o iir_duc -lm -Wall + ~/codec2-dev/stm32$ ./iir_duc \*---------------------------------------------------------------------------*/ @@ -30,51 +30,125 @@ along with this program; if not, see . */ -#define BETA1 .9990234375 // B1MUL/(2**B1SHFT) -#define B1MUL 1023 -#define B1SMUL 1204 -#define B1SHFT 10 // 10 bits gives us plenty of headroom between 31 bits of int and 14 bits of ADC -#define B2MUL 979 // This actually matches BETA2 exactly with the supplied BETA1 -#define B2SHFT 10 // 10 is also the lowest we can go without beta1=1 -#define BETA2 (1.0 - (1.0-BETA1)*DUC_M)// B2MUL/(2**B2SHFT) -#define IN_SCALE 1.0 //Input scaling factor +#include "stm32f4_dacduc.h" +#include "iir_duc.h" + +#define BETA1 0.99002 // B1MUL/(2**B1SHFT) +#define B1MUL 32441 +#define B1SMUL -38328 +#define B1SHFT 15 // 10 bits gives us plenty of headroom between 31 bits of int and 14 bits of ADC +#define B2MUL 24593 // This actually matches BETA2 exactly with the supplied BETA1 +#define B2SHFT 15 // 10 is also the lowest we can go without beta1=1 +#define BETA2 (1.0 - (1.0-BETA1)*DUC_M) // B2MUL/(2**B2SHFT) +#define IN_SCALE 2.0 //Input scaling factor. Should be as large as the amplitude of the incoming samples #define DAC_SCALE 4096 //Maximum output to DAC +#define DAC_SCALE_2 2040 +//IIR and FIR filter states. Global for go fast. +float f_1,f_2,f; +int n_1,n_2,n; + /* Upconvert and bandpass filter a chunk of spectrum from Fs/M to Fs. We're going for 700khz here. modin needs to be DUC_N long and dac_out needs to be DUC_N*DUC_M long. This */ -float f_1,f_2,f; -int n_1,n_2,n; -int dac_temp[DUC_N*DUC_M]; //Temporary storage for samples before IIR. - -void iir_upconv(float modin[],unsigned short dac_out[]){ - memset((void*)dac_temp,0,sizeof(int)*DUC_N*DUC_M); //Preset output array for interpolation - int i,j,k; - int m; - k=0; - //Iterate through input samples and apply pre-eq FIR, interpolate, and apply BPF IIR - for(i=0;i>B1SHFT) - ((B1MUL*n_2)>>B1SHFT); +void iir_upconv(float modin[], unsigned short dac_out[]){ + int i,j,k; + int m; + k=0; + //Iterate through input samples and apply pre-eq FIR, interpolate, and apply BPF IIR + for(i=0;i>B1SHFT) - ((B1MUL*n_2)>>B1SHFT); //Apply one cycle of IIR. This feeds the fir-ed sample into the output filter + n_2 = n_1; + n_1 = n; + dac_out[k]=(unsigned short)(n+DAC_SCALE_2); + k++; + //now do the rest of the filtering. Because we're zero-stuffing we can neglect the sample from the fir filter. + for(j=1;j>B1SHFT) - ((B1MUL*n_2)>>B1SHFT); n_2 = n_1; n_1 = n; - dac_out[k]=(unsigned short)(n+DAC_SCALE/2); - } - } - + dac_out[k]=(unsigned short)((n)+DAC_SCALE_2); + } + } } +#ifdef __UNITTEST__ + +#include +#include +#include +#include + +#define FS 80000 +#define AMP_MAX 1 + +#define NOUT_BUFS 401 +#define NIN (NOUT_BUFS*DUC_N) +#define NOUT (NIN*DUC_M) + +void synth_line(float us[], float f, float amp, int n) { + float w, sam; + int i; + + w = 2*M_PI*f/(float)FS; + + for(i=0; i