Haven't committed in a while :o . Currently waterfall is disabled while I work on audio processing. I am capturing, FFT, filter, IFFT, and output. It seems to be working partly. I don't think I am doing things right yet.

Also, starting to implement the menu system. Oh, and fixed some indentation, so it looks like there was more changed to main() than there really was....
This commit is contained in:
Michael Colton 2014-07-06 21:20:00 -06:00
parent 8c308e12c0
commit 7b1da77c21
6 changed files with 728 additions and 336 deletions

View file

@ -181,9 +181,6 @@
<outputType id="org.eclipse.cdt.managedbuilder.ui.rcbs.outputtype.1815660056" name="Resource Custom Build Step Output Type"/>
</tool>
</fileInfo>
<fileInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1375704298.664833074" name="stm32f4xx_hal_tim_ex.c" rcbsApplicability="disable" resourcePath="system/src/stm32f4-hal/stm32f4xx_hal_tim_ex.c" toolsToInvoke="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.98059731.495344797">
<tool id="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.98059731.495344797" name="Cross ARM C Compiler" superClass="ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.98059731"/>
</fileInfo>
<folderInfo id="ilg.gnuarmeclipse.managedbuild.cross.config.elf.debug.1375704298.608015733" name="/" resourcePath="DSP_Lib">
<toolChain id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug.425450735" name="Cross ARM GCC" superClass="ilg.gnuarmeclipse.managedbuild.cross.toolchain.elf.debug" unusedChildren="">
<option id="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1067485307.697494564" name="Optimization Level" superClass="ilg.gnuarmeclipse.managedbuild.cross.option.optimization.level.1067485307"/>
@ -763,7 +760,7 @@
</toolChain>
</folderInfo>
<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/FastMathFunctions|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|Source/BasicMathFunctions" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="DSP_Lib"/>
<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"/>
</sourceEntries>

View file

@ -93,6 +93,8 @@
extern const Gpio_Pin encoderA;
extern const Gpio_Pin encoderB;
extern const Gpio_Pin encoderP;
extern const Gpio_Pin dac1;
extern const Gpio_Pin dac2;
// extern const Gpio_Pin NC_1;

View file

@ -17,6 +17,7 @@
#include "Adafruit_ILI9340.h"
#include "stm32f4xx_hal.h"
#include "string.h"
#include "math.h"
#include "arm_math.h"
//#include "stm32f4xx_hal_rtc.h"
//#include "stm32f4xx_hal_adc.h"
@ -24,5 +25,6 @@
#include "stm32f4xx_hal_tim.h"
#include "stm32f4xx_hal_cortex.h"
#include "misc.h"
#include "stm32f4xx_hal_dac.h"
TIM_HandleTypeDef TimHandle;

View file

@ -88,6 +88,19 @@ void initAdc()
}
}
void adcGetConversion()
{
HAL_ADC_PollForConversion(&AdcHandle, 10);
HAL_ADC_PollForConversion(&AdcHandle2, 10);
/* Check if the continous conversion of regular channel is finished */
if(HAL_ADC_GetState(&AdcHandle) == HAL_ADC_STATE_EOC_REG && HAL_ADC_GetState(&AdcHandle2) == HAL_ADC_STATE_EOC_REG)
{
/*##-5- Get the converted value of regular channel ########################*/
uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
uhADCxConvertedValue2 = HAL_ADC_GetValue(&AdcHandle2);
}
}
void adcStartConversion()
@ -105,26 +118,6 @@ void initAdc()
//Error_Handler();
wrongThings++;
}
HAL_ADC_PollForConversion(&AdcHandle, 10);
HAL_ADC_PollForConversion(&AdcHandle2, 10);
/* Check if the continous conversion of regular channel is finished */
if(HAL_ADC_GetState(&AdcHandle) == HAL_ADC_STATE_EOC_REG && HAL_ADC_GetState(&AdcHandle2) == HAL_ADC_STATE_EOC_REG)
{
/*##-5- Get the converted value of regular channel ########################*/
uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle);
uhADCxConvertedValue2 = HAL_ADC_GetValue(&AdcHandle2);
}
// if(HAL_ADC_Start_IT(&AdcHandle) != HAL_OK)
// {
// /* Start Conversation Error */
// //Error_Handler();
// wrongThings++;
// }
}

View file

@ -74,6 +74,8 @@ const Gpio_Pin encoderB = { GPIOC, GPIO_PIN_3 };
const Gpio_Pin encoderP = { GPIOC, GPIO_PIN_15 };
const Gpio_Pin ADC_1 = { GPIOA, GPIO_PIN_1 };
const Gpio_Pin ADC_2 = { GPIOA, GPIO_PIN_2 };
const Gpio_Pin dac1 = { GPIOA, GPIO_PIN_4 };
const Gpio_Pin dac2 = { GPIOA, GPIO_PIN_5 };
//const Gpio_Pin NC_1 = { GPIOC, GPIO_Pin_0 }; // this is the Closure Sensor Pin near the 3v3 regulator, fyi
//const Gpio_Pin DAC_SWITCHES = { GPIOC, GPIO_Pin_5 }; // currently labeled LIGHT_SENSOR on schem (TODO)
@ -354,6 +356,11 @@ void hal_setupPins(void)
gpioInitStructure.Pin = dac1.pin | dac2.pin;
gpioInitStructure.Mode = GPIO_MODE_ANALOG;
gpioInitStructure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(dac1.port, &gpioInitStructure);
// Power Switch
// gpioInitStructure.GPIO_Pin = POWER_SWITCH.pin;
// gpioInitStructure.GPIO_Speed = GPIO_Speed_2MHz;

View file

@ -43,12 +43,155 @@
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#pragma GCC diagnostic ignored "-Wreturn-type"
void dac1SetValue(uint16_t value);
void dac2SetValue(uint16_t value);
void ddsPrefix();
void sendToDds(uint16_t data1, uint16_t data2);
#define FFT_SIZE 256 //supported sizes are 16, 64, 256, 1024
#define FFT_BUFFER_SIZE 512 //double the FFT_SIZE above.
__IO long long millis = 0;
float gain = 1;
float fftFilterCoeficient[FFT_BUFFER_SIZE];
float filterTemp[FFT_BUFFER_SIZE];
uint16_t filterKernelLength = 100; //what's a good value? How does it relate to the FFT size?
uint16_t menuState = 0;
uint16_t menuLastState = 1;
uint16_t menuCount = 8;
uint32_t frequencyDialMultiplier = 1;
void polarToRect(float m, float a, float32_t* x, float32_t* y)
{
*y = m * arm_sin_f32(a);
*x = m * arm_cos_f32(a);
}
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;
//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* 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];
// }
}
void applyCoeficient(float *samples)
{
//See DSP Guide Chapter 9 (Equation 9-1)
int 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 + 1] = samples[i * 2 + 1] * fftFilterCoeficient[i * 2 + 1] + samples[i * 2] * fftFilterCoeficient[i * 2];
}
for(i = 0; i < FFT_BUFFER_SIZE; i++)
{
samples[i] = filterTemp[i];
}
}
void setupPeripheralPower()
{
@ -104,8 +247,17 @@ int isFwd;
{
isFwd = ((Position == 0) && (Position2 == 1)) || ((Position == 1) && (Position2 == 3)) ||
((Position == 3) && (Position2 == 2)) || ((Position == 2) && (Position2 == 0));
if (!HAL_GPIO_ReadPin(encoderP.port, encoderP.pin)) { if (isFwd) Pos += clickMultiply; else Pos -= clickMultiply; }
else { if (isFwd) Pos++; else Pos--; }
if (!HAL_GPIO_ReadPin(encoderP.port, encoderP.pin))
{
if (isFwd) menuState = (menuState + 1);
else menuState = (menuState - 1);
menuState = menuState % (menuCount * 2);
}
else
{
if (isFwd) Pos++;
else Pos--;
}
//if (Pos < Min) Pos = Min;
//if (Pos > Max) Pos = Max;
}
@ -117,6 +269,11 @@ int isFwd;
return (Pos/2);
}
uint16_t getMenuPos(void)
{
return (menuState/2);
}
void setMinMax(int _Min, int _Max)
{
Min = _Min*4;
@ -133,29 +290,104 @@ int isFwd;
float samples[512];
const int FFT_SIZE = 256;
float samplesA[FFT_BUFFER_SIZE];
float samplesB[FFT_BUFFER_SIZE];
float samplesC[FFT_BUFFER_SIZE];
int sampleBankAReady = 0;
int sampleBankBReady = 0;
int sampleBankCReady = 0;
//float outputSamplesA[512];
//float outputSamplesB[512];
int sampleBank = 0;
//int sampleCounter = 0;
//const int FFT_SIZE = 256;
float observerA, observerB, observerC;
void captureSamples()
{
if(adcConfigured)
{
if(!sampleRun)
//if(!sampleRun)
{
adcStartConversion();
samples[sampleIndex*2] = ((float)(uhADCxConvertedValue - 2048)/4096.0); // - 2048;
samples[sampleIndex*2 + 1] = ((float)(uhADCxConvertedValue2 - 2048)/4096.0); // - 2048;//0.0;
adcGetConversion();
switch (sampleBank)
{
case 0:
samplesA[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048;
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);
break;
case 1:
samplesB[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048;
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);
break;
case 2:
samplesC[sampleIndex*2] = ((uhADCxConvertedValue - 2048)/4096.0); // - 2048;
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);
break;
}
//dac1SetValue(outputSamplesA[sampleIndex*2]);
sampleIndex++;
if(sampleIndex >= 256)
if(sampleIndex >= FFT_SIZE - filterKernelLength)
{
sampleRun = 1;
sampleIndex = 0;
switch(sampleBank)
{
case 0:
sampleBankAReady = 1;
sampleBank = 1;
zeroSampleBank(samplesB);
break;
case 1:
sampleBankBReady = 1;
sampleBank = 2;
zeroSampleBank(samplesC);
break;
case 2:
sampleBankCReady = 1;
sampleBank = 0;
zeroSampleBank(samplesA);
break;
}
//sampleBank = sampleBank++ % 3;
// if(sampleBank == 0)
// {
// sampleBankAReady = 1;
// sampleBank = 1;
//
// } else {
// sampleBankBReady = 1;
// sampleBank = 0;
// }
}
adcStartConversion();
}
}
}
void zeroSampleBank(float *samples)
{
uint16_t i;
for(i = 0; i < FFT_BUFFER_SIZE; i++) samples[i] = 0;
}
int
@ -163,16 +395,16 @@ main(int argc, char* argv[])
{
HAL_Init();
//HAL_RCC_OscConfig()
// RCC_ClkInitStruct clockInitStructure;
// clockInitStructure.
// HAL_RCC_ClockConfig()
// SystemClock_Config();
// RCC_ClkInitStruct clockInitStructure;
// clockInitStructure.
// HAL_RCC_ClockConfig()
// SystemClock_Config();
// void (*systicker)();
// systicker = &doNothing();
//
//
// HAL_SYSTICK_Callback(systicker);
// void (*systicker)();
// systicker = &doNothing();
//
//
// HAL_SYSTICK_Callback(systicker);
//hal_setSysTickCallback(doNothing());
// Send a greeting to the trace device (skipped on Release).
@ -184,9 +416,9 @@ main(int argc, char* argv[])
setupPeripheralPower();
//initDdsPins();
hal_setupPins();
spi_init();
//initDdsPins();
hal_setupPins();
spi_init();
timer_start();
@ -195,12 +427,23 @@ spi_init();
uint32_t seconds = 0;
Adafruit_ILI9340_begin();
Adafruit_ILI9340_setRotation(3);
Adafruit_GFX_fillScreen(ILI9340_BLACK);
Adafruit_GFX_fillScreen(ILI9340_BLACK);
populateCoeficients(100, 0, 00);
Encoder();
// float real = 3, imag = 2;
// float mag = 0, angle = 0;
// rectToPolar(real, imag, mag, angle);
// polarToRect(mag, angle, real, imag);
initDac1();
Adafruit_ILI9340_begin();
Adafruit_ILI9340_setRotation(3);
Adafruit_GFX_fillScreen(ILI9340_BLACK);
Adafruit_GFX_fillScreen(ILI9340_BLACK);
Encoder();
char chrisABaby[] = "Chris a baby!";
int j;
@ -209,7 +452,7 @@ Encoder();
Adafruit_GFX_setTextColor(ILI9340_WHITE, ILI9340_BLACK);
char freqChar[14];
sprintf(&freqChar, "%8d", 28000000);
long counter = 9700000;
long counter = 7260000;
long lastCounter = counter;
@ -275,7 +518,7 @@ Encoder();
uint8_t waterfallScanLine = 0;
Adafruit_GFX_drawTriangle(121,119,131,124,131,114,ILI9340_WHITE);
Adafruit_GFX_drawTriangle(121,119,131,124,131,114,ILI9340_WHITE);
uint16_t freqVOffset = 120 - (8*3/2);
@ -288,102 +531,193 @@ Adafruit_GFX_drawTriangle(121,119,131,124,131,114,ILI9340_WHITE);
Adafruit_GFX_write('.');
//TIM_setup();
//TIM_Config();
TIM_Try();
//TIM_setup();
//TIM_Config();
TIM_Try();
Adafruit_ILI9340_setVerticalScrollDefinition(200,120,0);
long long timeMeasurement = 0;
while(1)
{
while(1)
{
captureSamples();
//********MENU SYSTEM*********************************
if(getMenuPos() != menuLastState)
{
switch(getMenuPos())
{
case 0: //1,000,000 place
frequencyDialMultiplier = 1000000;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 33, ILI9340_RED);
break;
case 1: //100,000 place
frequencyDialMultiplier = 100000;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset + 18*3, freqVOffset + 25, 15, ILI9340_RED);
break;
case 2: //10,000 place
frequencyDialMultiplier = 10000;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset + 18*4, freqVOffset + 25, 15, ILI9340_RED);
break;
case 3: //1,000 place
frequencyDialMultiplier = 1000;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset + 18*5, freqVOffset + 25, 15, ILI9340_RED);
break;
case 4: //100 place
frequencyDialMultiplier = 100;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset + 18*7, freqVOffset + 25, 15, ILI9340_RED);
break;
case 5: //10 place
frequencyDialMultiplier = 10;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset + 18*8, freqVOffset + 25, 15, ILI9340_RED);
break;
case 6: //1 place
frequencyDialMultiplier = 1;
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
Adafruit_GFX_drawFastHLine(freqHOffset + 18*9, freqVOffset + 25, 15, ILI9340_RED);
break;
default:
Adafruit_GFX_drawFastHLine(freqHOffset, freqVOffset + 25, 178, ILI9340_BLACK);
break;
}
// sprintf(&freqChar, "%8d", getMenuPos());
// Adafruit_GFX_setTextSize(1);
// Adafruit_GFX_setCursor(150, 150 );
// int i;
// for(i = 0; i < 8; i++)
// {
// Adafruit_GFX_write(freqChar[i]);
// }
// sprintf(&freqChar, "%8d", frequencyDialMultiplier);
// Adafruit_GFX_setTextSize(1);
// Adafruit_GFX_setCursor(150, 170 );
// for(i = 0; i < 8; i++)
// {
// Adafruit_GFX_write(freqChar[i]);
// }
// Adafruit_GFX_setTextSize(3);
float fftMaxMax = 0;
menuLastState = getMenuPos();
}
//captureSamples();
float fftMaxMax = 0;
if(sampleRun)
{
timeMeasurement = millis;
arm_cfft_radix4_instance_f32 fft_inst;
//arm_cfft_radix4_init_q31(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
if (sampleBankAReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesA);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
applyCoeficient(samplesA);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesA);
sampleBankAReady = 0;
blink_led_off();
} else if(sampleBankBReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samples);
arm_cfft_radix4_f32(&fft_inst, samplesB);
// Calculate magnitude of complex numbers output by the FFT.
arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesB, magnitudes, FFT_SIZE);
applyCoeficient(samplesB);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesB);
sampleBankBReady = 0;
blink_led_off();
} else if (sampleBankCReady == 1)
{
blink_led_on();
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 1);
//arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2);
arm_cfft_radix4_f32(&fft_inst, samplesC);
// Calculate magnitude of complex numbers output by the FFT.
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
//arm_cmplx_mag_f32(samplesA, magnitudes, FFT_SIZE);
applyCoeficient(samplesC);
arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 1, 1);
arm_cfft_radix4_f32(&fft_inst, samplesC);
sampleBankCReady = 0;
blink_led_off();
}
timeMeasurement = millis - timeMeasurement;
float fftMax = 0;
float fftMin = 100;
float logMax;
uint8_t i;
for(i = 0; i < 255; i++)
{
float mags = magnitudes[i];
if(mags > fftMax) fftMax = mags;
if(mags < fftMin) fftMin = mags;
}
//logMax = log2(fftMax);
if(fftMax > fftMaxMax) fftMaxMax = fftMax;
logMax = log2(fftMaxMax);
// float fftMin = 100;
// float logMax;
// uint8_t i;
// for(i = 0; i < 255; i++)
// {
// float mags = magnitudes[i];
// if(mags > fftMax) fftMax = mags;
// if(mags < fftMin) fftMin = mags;
// }
// //logMax = log2(fftMax);
//
// if(fftMax > fftMaxMax) fftMaxMax = fftMax;
// logMax = log2(fftMaxMax);
//TODOne: SWITCH THESE AND FLIP THEM. So that higher frequencies appear higher on screen.
//TODO: Got rid of the first bin because it's just DC offset, right?
//but now narrow signal can disappear when they are right at the center....
//Will that be better when I lower the sample frequency? Maybe I should do that next.
for(i = 1; i < 120; i++)
{
mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
//mags = magnitudes[i] / fftMaxMax * 32;
Adafruit_ILI9340_drawPixel(waterfallScanLine, (120 - i), gradient[(uint8_t) mags]);
}
for(i = 135; i < 255; i++)
{
mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
//mags = magnitudes[i] / fftMaxMax * 32;
Adafruit_ILI9340_drawPixel(waterfallScanLine, 359 - (i - 15), gradient[(uint8_t) mags]);
}
waterfallScanLine++;
if(waterfallScanLine > 119) waterfallScanLine = 0;
Adafruit_ILI9340_setVertialScrollStartAddress((119 - waterfallScanLine) + 200);
// Adafruit_GFX_setCursor(3, 200);
// Adafruit_GFX_setTextColor(ILI9340_CYAN, ILI9340_RED);
// Adafruit_GFX_setTextSize(1);
// //char chrisABaby[] = {'C','h','r','i','s',' ','A',' ','B','a','b','y'};
// char chrisABaby[] = "Chris a baby!";
// int j;
// for(j = 0; j < 13; j++)
// for(i = 1; i < 120; i++)
// {
// Adafruit_GFX_write(chrisABaby[j]);
// mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
// //mags = magnitudes[i] / fftMaxMax * 32;
// Adafruit_ILI9340_drawPixel(waterfallScanLine, (120 - i), gradient[(uint8_t) mags]);
// }
//
// for(i = 135; i < 255; i++)
// {
// mags = (log2(magnitudes[i] + 1)) / fftMaxMax * 32;
// //mags = magnitudes[i] / fftMaxMax * 32;
// Adafruit_ILI9340_drawPixel(waterfallScanLine, 359 - (i - 15), gradient[(uint8_t) mags]);
// }
//
// waterfallScanLine++;
// if(waterfallScanLine > 119) waterfallScanLine = 0;
// Adafruit_ILI9340_setVertialScrollStartAddress((119 - waterfallScanLine) + 200);
sampleRun = 0;
}
//Adafruit_ILI9340_fillScreen(ILI9340_BLUE);
//counter = 9700000;
//Adafruit_GFX_drawLine(oscilloscope,50,oscilloscope, 240, ILI9340_BLACK);
//Adafruit_ILI9340_drawFastVLine(oscilloscope, 50, 210, ILI9340_BLACK);
//adcStartConversion();
//pixV = (uhADCxConvertedValue - (4096/2));
//Adafruit_ILI9340_drawPixel(oscilloscope++, pixV + 100, ILI9340_CYAN);
if(counter != lastCounter)
{
@ -438,71 +772,18 @@ float fftMaxMax = 0;
}
encoderPos = getPos();
if(encoderPos != encoderLastPos)
{
encoderPos = getPos();
if(encoderPos != encoderLastPos)
{
counter += 1000 * (encoderLastPos - encoderPos);
counter += frequencyDialMultiplier * (encoderLastPos - encoderPos);
if(counter < 1) counter = 1;
if(counter > 37500000) counter = 37500000;
//Adafruit_GFX_setCursor(0, 100);
//char encoderChar[5];
//sprintf(&encoderChar, "%4d", encoderPos);
//Adafruit_GFX_write(encoderChar[0]);
//Adafruit_GFX_write(encoderChar[1]);
//Adafruit_GFX_write(encoderChar[2]);
//Adafruit_GFX_write(encoderChar[3]);
encoderLastPos = encoderPos;
}
//Adafruit_ILI9340_fillScreen(ILI9340_YELLOW);
//char chrisABaby[] = {'C','h','r','i','s',' ','A',' ','B','a','b','y'};
// for(j = 0; j < 13; j++)
// {
// Adafruit_GFX_write(freqChar[j]);
// }
//while(1);
}
while(1)
{
}
counter = 0;
// Infinite loop
while (1)
{
blink_led_on();
timer_sleep(BLINK_ON_TICKS);
//HAL_GPIO_WritePin(ddsReset.port, ddsReset.pin, 1);
blink_led_off();
timer_sleep(BLINK_OFF_TICKS);
//HAL_GPIO_WritePin(ddsReset.port, ddsReset.pin, 0);
//sendToDds(counter++);
//++seconds;
// Count seconds on the trace device.
//trace_printf("Second %u\n", seconds);
}
// Infinite loop, never return.
}
//TIM_TimeBaseInitTypeDef timeBaseStructure;
@ -614,13 +895,13 @@ TIM_TypeDef timTimBase;
void TIM_Try(void)
{
uwPrescalerValue = (uint32_t) ((SystemCoreClock/2) / 60000) - 1;
uwPrescalerValue = (uint32_t) ((SystemCoreClock/2) / 21000000) - 1;
//NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
__TIM3_CLK_ENABLE();
TimHandle.Instance = TIM3;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TimHandle.Init.Period = 65535;
TimHandle.Init.Period = 1050;
TimHandle.Init.Prescaler = uwPrescalerValue;
TimHandle.Init.ClockDivision = 0;
HAL_TIM_Base_Init(&TimHandle);
@ -646,17 +927,127 @@ void TIM_Try(void)
int ledState = 0;
HAL_TIM_PeriodElapsedCallback(htim)
{
captureSamples();
// doNothing();
// if(ledState)
// {
// blink_led_off();
// ledState = 0;
// }
// else
// {
// blink_led_on();
// ledState = 1;
// }
}
//void rectToPolar(float real, float imag, float mag, float angle)
//{
// mag = sqrtf((real * real) + (imag * imag));
// angle = atan2f(imag,real);
//}
//
//void polarToRect(float mag, float angle, float real, float imag)
//{
// real = mag * cosf(angle);
// imag = mag * sinf(angle);
//}
/* Definition for DACx clock resources */
#define DACx DAC
#define DACx_CLK_ENABLE() __DAC_CLK_ENABLE()
#define DACx_CHANNEL_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
#define DACx_FORCE_RESET() __DAC_FORCE_RESET()
#define DACx_RELEASE_RESET() __DAC_RELEASE_RESET()
/* Definition for ADCx Channel Pin */
#define DACx_CHANNEL_PIN GPIO_PIN_4
#define DACx_CHANNEL_GPIO_PORT GPIOA
/* Definition for ADCx's Channel */
#define DACx_CHANNEL DAC_CHANNEL_1
DAC_HandleTypeDef DacHandle;
static DAC_ChannelConfTypeDef dacSConfig;
void initDac1()
{
DACx_CLK_ENABLE();
/*##-1- Configure the DAC peripheral #######################################*/
DacHandle.Instance = DACx;
if(HAL_DAC_Init(&DacHandle) != HAL_OK)
{
/* Initiliazation Error */
// Error_Handler();
doNothing();
if(ledState)
{
blink_led_off();
ledState = 0;
}
else
/*##-2- Configure DAC channel1 #############################################*/
dacSConfig.DAC_Trigger = DAC_TRIGGER_NONE;
dacSConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
if(HAL_DAC_ConfigChannel(&DacHandle, &dacSConfig, DAC_CHANNEL_1) != HAL_OK)
{
blink_led_on();
ledState = 1;
/* Channel configuration Error */
// Error_Handler();
doNothing();
}
if(HAL_DAC_ConfigChannel(&DacHandle, &dacSConfig, DAC_CHANNEL_2) != HAL_OK)
{
/* Channel configuration Error */
// Error_Handler();
doNothing();
}
/*##-3- Set DAC Channel1 DHR register ######################################*/
if(HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_8B_R, 0x88) != HAL_OK)
{
/* Setting value Error */
// Error_Handler();
doNothing();
}
/*##-3- Set DAC Channel1 DHR register ######################################*/
if(HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_8B_R, 0x88) != HAL_OK)
{
/* Setting value Error */
// Error_Handler();
doNothing();
}
/*##-4- Enable DAC Channel1 ################################################*/
if(HAL_DAC_Start(&DacHandle, DAC_CHANNEL_1) != HAL_OK)
{
/* Start Error */
// Error_Handler();
doNothing();
}
/*##-4- Enable DAC Channel1 ################################################*/
if(HAL_DAC_Start(&DacHandle, DAC_CHANNEL_2) != HAL_OK)
{
/* Start Error */
// Error_Handler();
doNothing();
}
}
void dac1SetValue(uint16_t value)
{
value = value & 0b0000111111111111;
HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
}
void dac2SetValue(uint16_t value)
{
value = value & 0b0000111111111111;
HAL_DAC_SetValue(&DacHandle, DAC_CHANNEL_2, DAC_ALIGN_12B_R, value);
}
#pragma GCC diagnostic pop