Added a crude Automatic Gain Control (AGC) that's happening on the audio output side. I want to add one for the RF side as well, but I'll need to change the hardware to do it.

Also fixed some weirdness with the filter menu items.
Verified that the recent changes to applyCoefficients() function are good and necessary to the proper operation of the filter.
This commit is contained in:
Michael Colton 2014-07-08 09:56:47 -06:00
parent 28ebb2009f
commit 71b87a38d7
2 changed files with 30 additions and 18 deletions

View file

@ -760,7 +760,7 @@
</toolChain> </toolChain>
</folderInfo> </folderInfo>
<sourceEntries> <sourceEntries>
<entry excluding="Source/TransformFunctions/arm_cfft_radix2_q31.c|Source/TransformFunctions/arm_cfft_radix2_q15.c|Source/TransformFunctions/arm_cfft_radix2_init_q31.c|Source/TransformFunctions/arm_cfft_radix2_init_q15.c|Source/TransformFunctions/arm_cfft_radix2_init_f32.c|Source/TransformFunctions/arm_cfft_radix2_f32.c|Source/FilteringFunctions|Source/ControllerFunctions|Source/MatrixFunctions|Source/StatisticsFunctions|Source/SupportFunctions|Source/BasicMathFunctions" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="DSP_Lib"/> <entry excluding="Source/TransformFunctions/arm_cfft_radix2_q31.c|Source/TransformFunctions/arm_cfft_radix2_q15.c|Source/TransformFunctions/arm_cfft_radix2_init_q31.c|Source/TransformFunctions/arm_cfft_radix2_init_q15.c|Source/TransformFunctions/arm_cfft_radix2_init_f32.c|Source/TransformFunctions/arm_cfft_radix2_f32.c|Source/FilteringFunctions|Source/ControllerFunctions|Source/MatrixFunctions|Source/StatisticsFunctions|Source/SupportFunctions" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="DSP_Lib"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
<entry excluding="src/stm32f4-hal/stm32f4xx_hal_adc_ex.c|src/stm32f4-hal/stm32f4xx_hal_can.c|src/stm32f4-hal/stm32f4xx_hal_crc.c|src/stm32f4-hal/stm32f4xx_hal_cryp.c|src/stm32f4-hal/stm32f4xx_hal_cryp_ex.c|src/stm32f4-hal/stm32f4xx_hal_dac_ex.c|src/stm32f4-hal/stm32f4xx_hal_dcmi.c|src/stm32f4-hal/stm32f4xx_hal_dma2d.c|src/stm32f4-hal/stm32f4xx_hal_dma_ex.c|src/stm32f4-hal/stm32f4xx_hal_eth.c|src/stm32f4-hal/stm32f4xx_hal_hash.c|src/stm32f4-hal/stm32f4xx_hal_hash_ex.c|src/stm32f4-hal/stm32f4xx_hal_hcd.c|src/stm32f4-hal/stm32f4xx_hal_i2c.c|src/stm32f4-hal/stm32f4xx_hal_i2c_ex.c|src/stm32f4-hal/stm32f4xx_hal_i2s.c|src/stm32f4-hal/stm32f4xx_hal_i2s_ex.c|src/stm32f4-hal/stm32f4xx_hal_irda.c|src/stm32f4-hal/stm32f4xx_hal_ltdc.c|src/stm32f4-hal/stm32f4xx_hal_msp_template.c|src/stm32f4-hal/stm32f4xx_hal_nand.c|src/stm32f4-hal/stm32f4xx_hal_nor.c|src/stm32f4-hal/stm32f4xx_hal_pccard.c|src/stm32f4-hal/stm32f4xx_hal_pcd.c|src/stm32f4-hal/stm32f4xx_hal_rng.c|src/stm32f4-hal/stm32f4xx_hal_rtc.c|src/stm32f4-hal/stm32f4xx_hal_rtc_ex.c|src/stm32f4-hal/stm32f4xx_hal_sai.c|src/stm32f4-hal/stm32f4xx_hal_sd.c|src/stm32f4-hal/stm32f4xx_hal_sdram.c|src/stm32f4-hal/stm32f4xx_hal_smartcard.c|src/stm32f4-hal/stm32f4xx_hal_sram.c|src/stm32f4-hal/stm32f4xx_hal_uart.c|src/stm32f4-hal/stm32f4xx_hal_usart.c|src/stm32f4-hal/stm32f4xx_hal_wwdg.c|src/stm32f4-hal/stm32f4xx_ll_fmc.c|src/stm32f4-hal/stm32f4xx_ll_fsmc.c|src/stm32f4-hal/stm32f4xx_ll_sdmmc.c|src/stm32f4-hal/stm32f4xx_ll_usb.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="system"/> <entry excluding="src/stm32f4-hal/stm32f4xx_hal_adc_ex.c|src/stm32f4-hal/stm32f4xx_hal_can.c|src/stm32f4-hal/stm32f4xx_hal_crc.c|src/stm32f4-hal/stm32f4xx_hal_cryp.c|src/stm32f4-hal/stm32f4xx_hal_cryp_ex.c|src/stm32f4-hal/stm32f4xx_hal_dac_ex.c|src/stm32f4-hal/stm32f4xx_hal_dcmi.c|src/stm32f4-hal/stm32f4xx_hal_dma2d.c|src/stm32f4-hal/stm32f4xx_hal_dma_ex.c|src/stm32f4-hal/stm32f4xx_hal_eth.c|src/stm32f4-hal/stm32f4xx_hal_hash.c|src/stm32f4-hal/stm32f4xx_hal_hash_ex.c|src/stm32f4-hal/stm32f4xx_hal_hcd.c|src/stm32f4-hal/stm32f4xx_hal_i2c.c|src/stm32f4-hal/stm32f4xx_hal_i2c_ex.c|src/stm32f4-hal/stm32f4xx_hal_i2s.c|src/stm32f4-hal/stm32f4xx_hal_i2s_ex.c|src/stm32f4-hal/stm32f4xx_hal_irda.c|src/stm32f4-hal/stm32f4xx_hal_ltdc.c|src/stm32f4-hal/stm32f4xx_hal_msp_template.c|src/stm32f4-hal/stm32f4xx_hal_nand.c|src/stm32f4-hal/stm32f4xx_hal_nor.c|src/stm32f4-hal/stm32f4xx_hal_pccard.c|src/stm32f4-hal/stm32f4xx_hal_pcd.c|src/stm32f4-hal/stm32f4xx_hal_rng.c|src/stm32f4-hal/stm32f4xx_hal_rtc.c|src/stm32f4-hal/stm32f4xx_hal_rtc_ex.c|src/stm32f4-hal/stm32f4xx_hal_sai.c|src/stm32f4-hal/stm32f4xx_hal_sd.c|src/stm32f4-hal/stm32f4xx_hal_sdram.c|src/stm32f4-hal/stm32f4xx_hal_smartcard.c|src/stm32f4-hal/stm32f4xx_hal_sram.c|src/stm32f4-hal/stm32f4xx_hal_uart.c|src/stm32f4-hal/stm32f4xx_hal_usart.c|src/stm32f4-hal/stm32f4xx_hal_wwdg.c|src/stm32f4-hal/stm32f4xx_ll_fmc.c|src/stm32f4-hal/stm32f4xx_ll_fsmc.c|src/stm32f4-hal/stm32f4xx_ll_sdmmc.c|src/stm32f4-hal/stm32f4xx_ll_usb.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="system"/>
</sourceEntries> </sourceEntries>

View file

@ -67,8 +67,10 @@ long vfoAFrequency = 7260000;
long vfoALastFreq = 7260000; long vfoALastFreq = 7260000;
int encoderPos, encoderLastPos; int encoderPos, encoderLastPos;
uint16_t filterUpperLimit = 10; int16_t filterUpperLimit = 10;
uint16_t filterLowerLimit = 0; int16_t filterLowerLimit = 0;
float agcLevel = 0;
void polarToRect(float m, float a, float32_t* x, float32_t* y) void polarToRect(float m, float a, float32_t* x, float32_t* y)
{ {
@ -188,7 +190,6 @@ void applyCoeficient(float *samples)
int i; int i;
for(i = 0; i < FFT_SIZE; i++) for(i = 0; i < FFT_SIZE; i++)
{ {
//samples[i] = samples[i] * fftFilterCoeficient[i];
filterTemp[i * 2] = samples[i * 2] * fftFilterCoeficient[i * 2] - samples[i * 2 + 1] * fftFilterCoeficient[i * 2 + 1]; filterTemp[i * 2] = samples[i * 2] * fftFilterCoeficient[i * 2] - samples[i * 2 + 1] * fftFilterCoeficient[i * 2 + 1];
filterTemp[i * 2 + 1] = samples[i * 2 + 1] * fftFilterCoeficient[i * 2 + 1] + samples[i * 2] * fftFilterCoeficient[i * 2]; filterTemp[i * 2 + 1] = samples[i * 2 + 1] * fftFilterCoeficient[i * 2 + 1] + samples[i * 2] * fftFilterCoeficient[i * 2];
} }
@ -324,28 +325,39 @@ int isFwd;
samplesA[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048; samplesA[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048;
samplesA[sampleIndex*2 + 1] = ((uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0; samplesA[sampleIndex*2 + 1] = ((uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0;
dac1SetValue(samplesB[sampleIndex*2] * 4096 * gain + 2048);
dac2SetValue(samplesB[sampleIndex*2+1] * 4096 * gain + 2048); if(samplesB[sampleIndex*2] > agcLevel) agcLevel = samplesB[sampleIndex*2];
if(samplesB[sampleIndex*2+1] > agcLevel) agcLevel = samplesB[sampleIndex*2+1];
dac1SetValue(samplesB[sampleIndex*2] / (agcLevel * 40) * 4096 * gain + 2048);
dac2SetValue(samplesB[sampleIndex*2+1] / (agcLevel * 40) * 4096 * gain + 2048);
break; break;
case 1: case 1:
samplesB[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048; samplesB[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048;
samplesB[sampleIndex*2 + 1] = ((uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0; samplesB[sampleIndex*2 + 1] = ((uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0;
dac1SetValue(samplesC[sampleIndex*2] * 4096 * gain + 2048);
dac2SetValue(samplesC[sampleIndex*2+1] * 4096 * gain + 2048); if(samplesC[sampleIndex*2] > agcLevel) agcLevel =samplesC[sampleIndex*2];
if(samplesC[sampleIndex*2+1] > agcLevel) agcLevel = samplesC[sampleIndex*2+1];
dac1SetValue(samplesC[sampleIndex*2] / (agcLevel * 40) * 4096 * gain + 2048);
dac2SetValue(samplesC[sampleIndex*2+1] / (agcLevel * 40) * 4096 * gain + 2048);
break; break;
case 2: case 2:
samplesC[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048; samplesC[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048;
samplesC[sampleIndex*2 + 1] = ((uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0; samplesC[sampleIndex*2 + 1] = ((uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0;
dac1SetValue(samplesA[sampleIndex*2] * 4096 * gain + 2048);
dac2SetValue(samplesA[sampleIndex*2+1] * 4096 * gain + 2048); if(samplesA[sampleIndex*2] > agcLevel) agcLevel = samplesA[sampleIndex*2];
if(samplesA[sampleIndex*2+1] > agcLevel) agcLevel = samplesA[sampleIndex*2+1];
dac1SetValue(samplesA[sampleIndex*2] / (agcLevel * 40) * 4096 * gain + 2048);
dac2SetValue(samplesA[sampleIndex*2+1] / (agcLevel * 40) * 4096 * gain + 2048);
break; break;
} }
//dac1SetValue(outputSamplesA[sampleIndex*2]); //dac1SetValue(outputSamplesA[sampleIndex*2]);
agcLevel = agcLevel * (1 - 0.0001);
sampleIndex++; sampleIndex++;
if(sampleIndex >= FFT_SIZE - filterKernelLength) if(sampleIndex >= FFT_SIZE - filterKernelLength)
{ {
@ -654,13 +666,13 @@ main(int argc, char* argv[])
encoderPos = getPos(); encoderPos = getPos();
if(encoderPos != encoderLastPos) if(encoderPos != encoderLastPos)
{ {
filterLowerLimit += 5 * (encoderLastPos - encoderPos); filterLowerLimit += 1 * (encoderLastPos - encoderPos);
if(filterLowerLimit <= 0) filterLowerLimit = 0; if(filterLowerLimit <= 0) filterLowerLimit = 0;
if(filterLowerLimit >= 10000) filterLowerLimit = 10000; if(filterLowerLimit >= 100) filterLowerLimit = 100;
if(filterLowerLimit >= filterUpperLimit) filterLowerLimit = filterUpperLimit - 10; if(filterLowerLimit >= filterUpperLimit) filterLowerLimit = filterUpperLimit - 1;
encoderLastPos = encoderPos; encoderLastPos = encoderPos;
populateCoeficients(filterUpperLimit - filterLowerLimit, 0, filterLowerLimit); populateCoeficients(filterUpperLimit - filterLowerLimit, 0, filterLowerLimit);
sprintf(&freqChar, "%5d", filterLowerLimit * 4); sprintf(&freqChar, "%5d", filterLowerLimit * 40);
Adafruit_GFX_setTextSize(1); Adafruit_GFX_setTextSize(1);
Adafruit_GFX_setCursor(150, 150 ); Adafruit_GFX_setCursor(150, 150 );
int i; int i;
@ -675,13 +687,13 @@ main(int argc, char* argv[])
encoderPos = getPos(); encoderPos = getPos();
if(encoderPos != encoderLastPos) if(encoderPos != encoderLastPos)
{ {
filterUpperLimit += 5 * (encoderLastPos - encoderPos); filterUpperLimit += 1 * (encoderLastPos - encoderPos);
if(filterUpperLimit <= 0) filterUpperLimit = 0; if(filterUpperLimit <= 0) filterUpperLimit = 0;
if(filterUpperLimit >= 10000) filterUpperLimit = 10000; if(filterUpperLimit >= 100) filterUpperLimit = 100;
if(filterUpperLimit <= filterLowerLimit) filterUpperLimit = filterLowerLimit + 10; if(filterUpperLimit <= filterLowerLimit) filterUpperLimit = filterLowerLimit + 1;
encoderLastPos = encoderPos; encoderLastPos = encoderPos;
populateCoeficients(filterUpperLimit - filterLowerLimit, 0, filterLowerLimit); populateCoeficients(filterUpperLimit - filterLowerLimit, 0, filterLowerLimit);
sprintf(&freqChar, "%5d", filterUpperLimit * 4); sprintf(&freqChar, "%5d", filterUpperLimit * 40);
Adafruit_GFX_setTextSize(1); Adafruit_GFX_setTextSize(1);
Adafruit_GFX_setCursor(150, 170 ); Adafruit_GFX_setCursor(150, 170 );
int i; int i;