From 7b1da77c21b35113f966ef976838ef37576f2d0b Mon Sep 17 00:00:00 2001 From: Michael Colton Date: Sun, 6 Jul 2014 21:20:00 -0600 Subject: [PATCH] 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.... --- Source/.cproject | 5 +- Source/include/hal.h | 2 + Source/include/main.h | 2 + Source/src/adc.c | 39 +- Source/src/hal.c | 7 + Source/src/main.c | 1009 ++++++++++++++++++++++++++++------------- 6 files changed, 728 insertions(+), 336 deletions(-) diff --git a/Source/.cproject b/Source/.cproject index 02ad332..e268f7c 100644 --- a/Source/.cproject +++ b/Source/.cproject @@ -181,9 +181,6 @@ - - - - + diff --git a/Source/include/hal.h b/Source/include/hal.h index 1f43728..da15be5 100644 --- a/Source/include/hal.h +++ b/Source/include/hal.h @@ -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; diff --git a/Source/include/main.h b/Source/include/main.h index 37db84b..859f194 100644 --- a/Source/include/main.h +++ b/Source/include/main.h @@ -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; diff --git a/Source/src/adc.c b/Source/src/adc.c index fe273e8..dbefbbb 100644 --- a/Source/src/adc.c +++ b/Source/src/adc.c @@ -88,24 +88,8 @@ void initAdc() } } - - - void adcStartConversion() + void adcGetConversion() { - if(HAL_ADC_Start(&AdcHandle) != HAL_OK) - { - /* Start Conversation Error */ - //Error_Handler(); - wrongThings++; - } - - if(HAL_ADC_Start(&AdcHandle2) != HAL_OK) - { - /* Start Conversation Error */ - //Error_Handler(); - wrongThings++; - } - HAL_ADC_PollForConversion(&AdcHandle, 10); HAL_ADC_PollForConversion(&AdcHandle2, 10); @@ -116,15 +100,24 @@ void initAdc() uhADCxConvertedValue = HAL_ADC_GetValue(&AdcHandle); uhADCxConvertedValue2 = HAL_ADC_GetValue(&AdcHandle2); } + } + void adcStartConversion() + { + if(HAL_ADC_Start(&AdcHandle) != HAL_OK) + { + /* Start Conversation Error */ + //Error_Handler(); + wrongThings++; + } -// if(HAL_ADC_Start_IT(&AdcHandle) != HAL_OK) -// { -// /* Start Conversation Error */ -// //Error_Handler(); -// wrongThings++; -// } + if(HAL_ADC_Start(&AdcHandle2) != HAL_OK) + { + /* Start Conversation Error */ + //Error_Handler(); + wrongThings++; + } } diff --git a/Source/src/hal.c b/Source/src/hal.c index ade49dc..dd09b0c 100644 --- a/Source/src/hal.c +++ b/Source/src/hal.c @@ -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; diff --git a/Source/src/main.c b/Source/src/main.c index 4918279..4ba1994 100644 --- a/Source/src/main.c +++ b/Source/src/main.c @@ -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,119 +395,130 @@ 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). - trace_puts("Hello ARM World!"); + // Send a greeting to the trace device (skipped on Release). + trace_puts("Hello ARM World!"); - // At this stage the system clock should have already been configured - // at high speed. - trace_printf("System clock: %uHz\n", SystemCoreClock); + // At this stage the system clock should have already been configured + // at high speed. + trace_printf("System clock: %uHz\n", SystemCoreClock); - setupPeripheralPower(); + setupPeripheralPower(); -//initDdsPins(); -hal_setupPins(); -spi_init(); + //initDdsPins(); + hal_setupPins(); + spi_init(); - timer_start(); + timer_start(); - blink_led_init(); - blink_led_on(); - uint32_t seconds = 0; + blink_led_init(); + blink_led_on(); + uint32_t seconds = 0; -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; - Adafruit_GFX_setTextSize(3); - Adafruit_GFX_setTextWrap(1); - Adafruit_GFX_setTextColor(ILI9340_WHITE, ILI9340_BLACK); - char freqChar[14]; - sprintf(&freqChar, "%8d", 28000000); - long counter = 9700000; + populateCoeficients(100, 0, 00); - long lastCounter = counter; - int encoderPos, encoderLastPos; - char lastFreqChar[] = {'$','$','$','$','$','$','$','$','$','$','$','$','$','$',}; + // 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; + Adafruit_GFX_setTextSize(3); + Adafruit_GFX_setTextWrap(1); + Adafruit_GFX_setTextColor(ILI9340_WHITE, ILI9340_BLACK); + char freqChar[14]; + sprintf(&freqChar, "%8d", 28000000); + long counter = 7260000; + + + long lastCounter = counter; + int encoderPos, encoderLastPos; + char lastFreqChar[] = {'$','$','$','$','$','$','$','$','$','$','$','$','$','$',}; - initAdc(); + initAdc(); - adcConfigured = 1; + adcConfigured = 1; - adcStartConversion(); + adcStartConversion(); - float magnitudes[256]; + float magnitudes[256]; - uint8_t rawGradient[96] = - { - 30,30,11, - 13,13,100, - 18,13,107, - 27,13,122, - 40,13,140, - 56,13,160, - 72,13,175, - 88,13,188, - 106,13,201, - 125,13,214, - 145,13,226, - 163,13,234, - 177,15,238, - 185,25,237, - 192,41,233, - 198,58,227, - 205,78,219, - 209,98,210, - 215,120,202, - 219,141,193, - 224,162,186, - 228,181,180, - 231,197,176, - 236,210,175, - 240,225,180, - 244,234,190, - 247,242,203, - 249,246,217, - 251,249,232, - 253,252,245, - 255,254,253, - 255,255,254 - }; + uint8_t rawGradient[96] = + { + 30,30,11, + 13,13,100, + 18,13,107, + 27,13,122, + 40,13,140, + 56,13,160, + 72,13,175, + 88,13,188, + 106,13,201, + 125,13,214, + 145,13,226, + 163,13,234, + 177,15,238, + 185,25,237, + 192,41,233, + 198,58,227, + 205,78,219, + 209,98,210, + 215,120,202, + 219,141,193, + 224,162,186, + 228,181,180, + 231,197,176, + 236,210,175, + 240,225,180, + 244,234,190, + 247,242,203, + 249,246,217, + 251,249,232, + 253,252,245, + 255,254,253, + 255,255,254 + }; - uint16_t gradient[32]; + uint16_t gradient[32]; - int k; - for(k = 0; k <32; k++) - { - gradient[k] = Adafruit_ILI9340_Color565(0.5 * rawGradient[k*3], 0.5 * rawGradient[k*3+1], 0.5 * rawGradient[k*3+2]); - } + int k; + for(k = 0; k <32; k++) + { + gradient[k] = Adafruit_ILI9340_Color565(0.5 * rawGradient[k*3], 0.5 * rawGradient[k*3+1], 0.5 * rawGradient[k*3+2]); + } - float mags; - uint8_t waterfallScanLine = 0; + float mags; + 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,221 +531,259 @@ 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) -{ - - 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); - - //arm_cfft_radix4_init_f32(&fft_inst, FFT_SIZE, 0, 2); - arm_cfft_radix4_f32(&fft_inst, samples); - // Calculate magnitude of complex numbers output by the FFT. - arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE); - 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); - - - //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++) - // { - // Adafruit_GFX_write(chrisABaby[j]); - // } - - - - 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) + while(1) { - setFreq(counter); - sprintf(&freqChar, "%8d", counter); + //********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); - if(freqChar[0] != lastFreqChar[0]) - { - Adafruit_GFX_setCursor(freqHOffset + 18*0, freqVOffset + 0); - Adafruit_GFX_write(freqChar[0]); - } - if(freqChar[1] != lastFreqChar[1]) - { - Adafruit_GFX_setCursor(freqHOffset + 18*1, freqVOffset + 0); - Adafruit_GFX_write(freqChar[1]); + menuLastState = getMenuPos(); } - if(freqChar[2] != lastFreqChar[2]) + + + + //captureSamples(); + + float fftMaxMax = 0; + if(sampleRun) { - Adafruit_GFX_setCursor(freqHOffset + 18*3, freqVOffset + 0); - Adafruit_GFX_write(freqChar[2]); - } - if(freqChar[3] != lastFreqChar[3]) - { - Adafruit_GFX_setCursor(freqHOffset + 18*4, freqVOffset + 0); - Adafruit_GFX_write(freqChar[3]); - } - if(freqChar[4] != lastFreqChar[4]) - { - Adafruit_GFX_setCursor(freqHOffset + 18*5, freqVOffset + 0); - Adafruit_GFX_write(freqChar[4]); + + 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, samplesB); + // Calculate magnitude of complex numbers output by the FFT. + //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); + + + //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); + + sampleRun = 0; } - if(freqChar[5] != lastFreqChar[5]) + if(counter != lastCounter) { - Adafruit_GFX_setCursor(freqHOffset + 18*7, freqVOffset + 0); - Adafruit_GFX_write(freqChar[5]); - } - if(freqChar[6] != lastFreqChar[6]) - { - Adafruit_GFX_setCursor(freqHOffset + 18*8, freqVOffset + 0); - Adafruit_GFX_write(freqChar[6]); - } - if(freqChar[7] != lastFreqChar[7]) - { - Adafruit_GFX_setCursor(freqHOffset + 18*9, freqVOffset + 0); - Adafruit_GFX_write(freqChar[7]); + + setFreq(counter); + sprintf(&freqChar, "%8d", counter); + + if(freqChar[0] != lastFreqChar[0]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*0, freqVOffset + 0); + Adafruit_GFX_write(freqChar[0]); + } + if(freqChar[1] != lastFreqChar[1]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*1, freqVOffset + 0); + Adafruit_GFX_write(freqChar[1]); + } + + if(freqChar[2] != lastFreqChar[2]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*3, freqVOffset + 0); + Adafruit_GFX_write(freqChar[2]); + } + if(freqChar[3] != lastFreqChar[3]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*4, freqVOffset + 0); + Adafruit_GFX_write(freqChar[3]); + } + if(freqChar[4] != lastFreqChar[4]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*5, freqVOffset + 0); + Adafruit_GFX_write(freqChar[4]); + } + + if(freqChar[5] != lastFreqChar[5]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*7, freqVOffset + 0); + Adafruit_GFX_write(freqChar[5]); + } + if(freqChar[6] != lastFreqChar[6]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*8, freqVOffset + 0); + Adafruit_GFX_write(freqChar[6]); + } + if(freqChar[7] != lastFreqChar[7]) + { + Adafruit_GFX_setCursor(freqHOffset + 18*9, freqVOffset + 0); + Adafruit_GFX_write(freqChar[7]); + } + + lastCounter = counter; + strcpy(lastFreqChar, freqChar); } - lastCounter = counter; - strcpy(lastFreqChar, freqChar); + + encoderPos = getPos(); + if(encoderPos != encoderLastPos) + { + + counter += frequencyDialMultiplier * (encoderLastPos - encoderPos); + + if(counter < 1) counter = 1; + if(counter > 37500000) counter = 37500000; + + encoderLastPos = encoderPos; + } } - - -encoderPos = getPos(); -if(encoderPos != encoderLastPos) -{ - - counter += 1000 * (encoderLastPos - encoderPos); - - //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) { - doNothing(); - if(ledState) + 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) { - blink_led_off(); - ledState = 0; + /* Initiliazation Error */ + // Error_Handler(); + doNothing(); } - 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