int32_t splot_buff_2(void) { arm_status status; /* Status of the example */ arm_cfft_radix4_instance_f32 cfft_instance; /* CFFT Structure instance */ /* CFFT Structure instance pointer */ arm_cfft_radix4_instance_f32 *cfft_instance_ptr = (arm_cfft_radix4_instance_f32*) &cfft_instance; /* Initialise the fft input buffers with all zeros */ arm_fill_f32(0.0, buff_wej_dodatkowy_1, ile_probek); arm_fill_f32(0.0, buff_wej_dodatkowy_2, ile_probek); /* Copy the input values to the fft input buffers */ arm_copy_f32(ADC3ConvertedValue1, buff_wej_dodatkowy_1, ile_probek); arm_copy_f32(buff_odp_imp_filtr, buff_wej_dodatkowy_2, ile_probek); /* Initialize the CFFT function to compute 64 point fft */ status = arm_cfft_radix4_init_f32(cfft_instance_ptr, 64, 0, 1); /* Transform input a[n] from time domain to frequency domain A[k] */ arm_cfft_radix4_f32(cfft_instance_ptr, buff_wej_dodatkowy_1); /* Transform input b[n] from time domain to frequency domain B[k] */ arm_cfft_radix4_f32(cfft_instance_ptr, buff_wej_dodatkowy_2); /* Complex Multiplication of the two input buffers in frequency domain */ arm_cmplx_mult_cmplx_f32(buff_wej_dodatkowy_1, buff_wej_dodatkowy_2, buff_wyj1, ile_probek); /* Initialize the CIFFT function to compute 64 point ifft */ status = arm_cfft_radix4_init_f32(cfft_instance_ptr, 64, 1, 1); /* Transform the multiplication output from frequency domain to time domain, that gives the convolved output */ arm_cfft_radix4_f32(cfft_instance_ptr, buff_wyj1); status = ARM_MATH_SUCCESS; }
int32_t main(void) { arm_status status; /* Status of the example */ arm_cfft_radix4_instance_f32 cfft_instance; /* CFFT Structure instance */ /* CFFT Structure instance pointer */ arm_cfft_radix4_instance_f32 *cfft_instance_ptr = (arm_cfft_radix4_instance_f32*) &cfft_instance; /* output length of convolution */ outLen = srcALen + srcBLen - 1; /* Initialise the fft input buffers with all zeros */ arm_fill_f32(0.0, Ak, MAX_BLOCKSIZE); arm_fill_f32(0.0, Bk, MAX_BLOCKSIZE); /* Copy the input values to the fft input buffers */ arm_copy_f32(testInputA_f32, Ak, MAX_BLOCKSIZE/2); arm_copy_f32(testInputB_f32, Bk, MAX_BLOCKSIZE/2); /* Initialize the CFFT function to compute 64 point fft */ status = arm_cfft_radix4_init_f32(cfft_instance_ptr, 64, 0, 1); /* Transform input a[n] from time domain to frequency domain A[k] */ arm_cfft_radix4_f32(cfft_instance_ptr, Ak); /* Transform input b[n] from time domain to frequency domain B[k] */ arm_cfft_radix4_f32(cfft_instance_ptr, Bk); /* Complex Multiplication of the two input buffers in frequency domain */ arm_cmplx_mult_cmplx_f32(Ak, Bk, AxB, MAX_BLOCKSIZE/2); /* Initialize the CIFFT function to compute 64 point ifft */ status = arm_cfft_radix4_init_f32(cfft_instance_ptr, 64, 1, 1); /* Transform the multiplication output from frequency domain to time domain, that gives the convolved output */ arm_cfft_radix4_f32(cfft_instance_ptr, AxB); /* SNR Calculation */ snr = arm_snr_f32((float32_t *)testRefOutput_f32, AxB, srcALen + srcBLen - 1); /* Compare the SNR with threshold to test whether the computed output is matched with the reference output values. */ if( snr > SNR_THRESHOLD) { status = ARM_MATH_SUCCESS; } if( status != ARM_MATH_SUCCESS) { while(1); } while(1); /* main function does not return */ }
void fft(){ uint32_t i; arm_cfft_radix4_instance_f32 S; /* ARM CFFT module */ float32_t maxValue; /* Max FFT value is stored here */ uint32_t maxIndex; /* Index in Output array where max value is */ uint32_t height; for(i = 0; i < SIZE; i+=2) { INPUT[i] = ((samples[i]+CAP_FACTOR)/((float32_t) MAX_VALUE/2) - 1); INPUT[i+1] = 0; } /* Initialize the CFFT/CIFFT module, intFlag = 0, doBitReverse = 1 */ arm_cfft_radix4_init_f32(&S, SIZE/2, 0, 1); /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, INPUT); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(INPUT, Output, SIZE/2); /* Calculates maxValue and returns corresponding value */ arm_max_f32(Output, SIZE, &maxValue, &maxIndex); if(maxIndex>SIZE/4){ maxIndex=SIZE/2-maxIndex; //Dla lustrzanych } BSP_LCD_Clear(LCD_COLOR_WHITE); /* Display data on LCD */ for (i = 0; i < SIZE; i++) { /* Draw FFT results */ height = (uint16_t)(((float32_t)Output[i] / (float32_t)maxValue) * 180); BSP_LCD_DrawLine(0, 30+i, height, 30+i); } char str[16]; sprintf(str,"%d",(uint32_t)((float32_t)maxIndex*FREQ_FACTOR)); //Model matematyczny BSP_LCD_DisplayStringAtLine(1,(uint8_t *) str); }
void fft_gen(void){ //TODO:バッファをstaticにして関数切り出し.割り込みから呼ぶ,切り出し先はfft.c arm_cfft_radix4_instance_f32 S; /* ARM CFFT module */ float32_t Input[FFT_SAMPLES]; uint32_t maxIndex; /* Index in Output array where max value is */ //ジェネレータのバッファを埋める(ジェネレータ入力時の不足データを繰り返しで埋める)(TODO:ADとgenを振り分け) uint16_t i; int j; j = 0; for (i=buf.numLUTEntries; i < FFT_SIZE; i++) { buf.LUT_BUFFER[i] = buf.LUT_BUFFER[j]; if(j==buf.numLUTEntries-1) { j=0; }else{ j++; } } /* Initialize the CFFT/CIFFT module, intFlag = 0, doBitReverse = 1 */ arm_cfft_radix4_init_f32(&S, FFT_SIZE, 0, 1); for (i = 0; i < FFT_SAMPLES; i += 2) { Input[(uint16_t)i] = (float32_t)((float32_t)buf.LUT_BUFFER[i/2] - (float32_t)2048.0) / (float32_t)2048.0; Input[(uint16_t)(i + 1)] = 0; } /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, Input); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(Input, Output, FFT_SIZE); /* Calculates maxValue and returns corresponding value */ arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); //DA=30000sps/4096bit=7.32421875Hzステップでデータが格納されている }
int32_t main(void) { volatile int32_t iCount; arm_status status; arm_cfft_radix4_instance_f32 S; float32_t maxValue; STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED6); STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED6); status = ARM_MATH_SUCCESS; /* Initialize the CFFT/CIFFT module */ status = arm_cfft_radix4_init_f32(&S, fftSize, ifftFlag, doBitReverse); /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, testInput_f32_10khz); /* Process the data through the Complex Magnitude Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize); /* Calculates maxValue and returns corresponding BIN value */ arm_max_f32(testOutput, fftSize, &maxValue, &testIndex); if(testIndex != refIndex) { status = ARM_MATH_TEST_FAILURE; STM_EVAL_LEDOn(LED3); } /* ---------------------------------------------------------------------- ** Loop here if the signals fail the PASS check. ** This denotes a test failure ** ------------------------------------------------------------------- */ if( status != ARM_MATH_SUCCESS) { while(1); } while(1) { STM_EVAL_LEDOn(LED6); for (iCount = 0; iCount < 1000000; iCount++); STM_EVAL_LEDOff(LED6); for (iCount = 0; iCount < 1000000; iCount++); } }
void fft_adc(void){ uint16_t i; //TODO:バッファをstaticにして関数切り出し.割り込みから呼ぶ,切り出し先はfft.c arm_cfft_radix4_instance_f32 S; /* ARM CFFT module */ float32_t Input[FFT_SAMPLES]; uint32_t maxIndex; /* Index in Output array where max value is */ /* Initialize the CFFT/CIFFT module, intFlag = 0, doBitReverse = 1 */ arm_cfft_radix4_init_f32(&S, FFT_SIZE, 0, 1); for (i = 0; i < FFT_SAMPLES; i += 2) { Input[(uint16_t)i] = (float32_t)((float32_t)adc_buf[i/2] - (float32_t)2048.0) / (float32_t)2048.0; Input[(uint16_t)(i + 1)] = 0; } /* Process the data through the CFFT/CIFFT module */ arm_cfft_radix4_f32(&S, Input); /* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */ arm_cmplx_mag_f32(Input, Output, FFT_SIZE); /* Calculates maxValue and returns corresponding value */ arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); //AD=79872sps/4096bit=19.5Hzステップでデータが格納される }
void populateCoeficients(int bandwidth, int sideband, int offset) { //Chapter 17 of DSP Guide* //TODO: Make a bibliography! //1. Take as input, desired filter response in array, both magnitude and phase (it's okay for phase to be zero) // Looks like magnitude can be any non-negative value. First and last values of Phase must be zero. //2. Convert to rectangular form. ***I really wish there was a built in function for this :< //3. Run through an inverse FFT. //4. Shift //5. Truncate //6. Window //7. Reverse the FFT in preparation for FFT Convolution? uint16_t filterKernelLength = 100; //what's a good value? How does it relate to the FFT size? //1: //sideband: 0 = LSB, 1 = USB, 2 = Both (AM) //I think the code below is all wrong. At least for LSB, if the magnitude is zero, then phase doesn't matter, yeah? if(sideband > 2) return; //Error int i; for(i = 0; i < FFT_BUFFER_SIZE; i++) { switch(sideband) { case 0: if((i > FFT_BUFFER_SIZE - (offset + bandwidth)) && (i < FFT_BUFFER_SIZE - offset)) fftFilterCoeficient[i] = 1; else fftFilterCoeficient[i] = 0; break; case 1: if((i > offset) && (i < offset + bandwidth)) fftFilterCoeficient[i] = 1; else fftFilterCoeficient[i] = 0; break; case 2: if(((i > FFT_BUFFER_SIZE - (offset + bandwidth)) && (i < FFT_BUFFER_SIZE - offset)) || ((i > offset) && (i < offset + bandwidth))) fftFilterCoeficient[i] = 1; else fftFilterCoeficient[i] = 0; break; } } fftFilterCoeficient[FFT_BUFFER_SIZE / 2] = 0; fftFilterCoeficient[FFT_BUFFER_SIZE - 1] = 0; //return; //Skipping all the later stuff doesn't seem to make a huge difference yet... //2: // float x, y; // for(i = 0; i < FFT_SIZE; i++) // { // polarToRect(fftFilterCoeficient[i], fftFilterCoeficient[FFT_BUFFER_SIZE - 1 - i], &x, &y); // fftFilterCoeficient[i] = x; // fftFilterCoeficient[FFT_BUFFER_SIZE - 1 - i] = y; // } //3: arm_cfft_radix4_instance_f32 fft_co; arm_cfft_radix4_init_f32(&fft_co, FFT_SIZE, 1, 1); arm_cfft_radix4_f32(&fft_co, fftFilterCoeficient); //4: int index; for (i = 0; i < FFT_BUFFER_SIZE; i++) { index = i + filterKernelLength/2; if(index > FFT_BUFFER_SIZE - 1) index = index - FFT_BUFFER_SIZE; filterTemp[index] = fftFilterCoeficient[i]; } for(i = 0; i < FFT_BUFFER_SIZE; i++) { fftFilterCoeficient[i] = filterTemp[i]; } //5 & 6: for(i = 0; i < FFT_BUFFER_SIZE; i++) { if(i <= filterKernelLength) fftFilterCoeficient[i] = fftFilterCoeficient[i] * (0.54 - 0.46 * arm_cos_f32(2.0 * 3.14159265 * i / filterKernelLength)); if(i > filterKernelLength) fftFilterCoeficient[i] = 0; } // arm_cfft_radix4_instance_f32 fft_co; arm_cfft_radix4_init_f32(&fft_co, FFT_SIZE, 0, 1); arm_cfft_radix4_f32(&fft_co, fftFilterCoeficient); // for(i = 0; i < FFT_SIZE; i++) // { // filterTemp[i] = fftFilterCoeficient[i * 2]; // filterTemp[FFT_BUFFER_SIZE - 1 - i] = fftFilterCoeficient[i * 2 + 1]; // } // // for(i = 0; i < FFT_BUFFER_SIZE; i++) // { // fftFilterCoeficient[i] = filterTemp[i]; // } }