Chirp Signal Generator
Dependencies: mbed
Fork of TAU_ZOOLOG_Playback_Rev1_1 by
Diff: main_filter3.cpp
- Revision:
- 3:25cd717ad782
- Child:
- 4:85dbf3e4d432
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_filter3.cpp Tue Jun 27 13:01:03 2017 +0000 @@ -0,0 +1,358 @@ +/* +General Biquadratic Digital Filter Implementation +ADC --> Filter --> DAC , Based on NUCLEO - F303RE + +Pinout: +ADC -- PA_0 -- A0 +DAC -- PA_4 -- A2 + +I/O -- PA_5 -- D13 (Status LED, Condition) +I/O -- PA_6 -- D12 (Toggle Pin, Loop Freq) +I/O -- PA_7 -- D11 (General Output Pin ) + +Make sure to use float variables in filter (Not double!). +*/ +#include "mbed.h" +#include "config.h" +#include "sounddata.h" + +#define TEST_OUTPUT_MODE 4 + +// mbed variables, Settings +AnalogIn in(A0); +AnalogOut out(PA_4); + +// DigitalOut led(LED1); +DigitalOut mytoggle(PA_6); + +// User Button as interrupt +InterruptIn mybutton(USER_BUTTON); + +// Serial over USB as input device +Serial pc(SERIAL_TX, SERIAL_RX); + +// ADC/DAC declarations +ADC_HandleTypeDef hadc1; +DAC_HandleTypeDef hdac1; + +// Dac Register for direct method of setting DAC value`s +__IO uint32_t Dac_Reg = 0; + +// Variables +uint16_t ADCValueIn=0; +uint16_t ADCValueOut=0; +float ADCFloat=0; +float ADCFloatFiltered=0; +float OutputADCFloat=0; +float ADC2Float=(2.0f/4095.0f); //ADCvalue*(2/0xFFF)-1.0f // 12 bits range +float Float2ADC=(4095.0f/2.0f); //(ADCvalue+1.0f)*(0xFFF/2) // 12 bits range +// float ADC2Float= 1.0; +// float Float2ADC= 1.0; +uint16_t ADCValueMax = 0; +uint16_t ADCValueMin = 0xfff; + +// Definitions for software developer +#define NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT ((long)300000) // 0 - not check keyboard input +#define SAMPLING_FREQUENCY_DELAY 2 // microseconds +#define CONSTANT_SIGNAL_LEVEL_FOR_TEST 0.2 +#define NUM_OF_CYCLES_BACK_TO_NORMAL 0 // User can play with this. Hysteresis, 0 - no hysteresis + +float scale_for_predefined_output = (float)SCALE_FOR_PREDEFINED_OUTPUT; +int sampling_frequency_delay = SAMPLING_FREQUENCY_DELAY; +int delay_after_signal_transmission = DELAY_AFTER_SIGNAL_TRANSMISSION; +bool use_filter_with_predefined_output = USE_FILTER_WITH_PREDEFINED_OUTPUT; +int num_of_cycles_to_detect_threshold_crossing = NUM_OF_CYCLES_TO_DETECT_THRESHOLD_CROSSING; + +int startPredefinedOutput = 0; +int num_threshold_crossing = 0; +int num_back_to_normal = 0; +int signal_low_threshold = SIGNAL_LOW_THRESHOD; + +int UserButtonPressed; +long NumCycles; + +// second-order sections filter variables - upto 8 sections +#define MAX_SECTION_NUMBER 8 +int NumSections = sizeof(SOSMat)/sizeof(float)/6; +int NumSectionsHP = sizeof(SOSMatHP)/sizeof(float)/6; + +// Inputs +float CurrInput [MAX_SECTION_NUMBER+1]; +float LastInput [MAX_SECTION_NUMBER+1]; +float LLastInput [MAX_SECTION_NUMBER+1]; + +float scaled_sounddata[AMOUNT_OF_SIGNIFICANT_SAMPLES]; +char FilterType[5][32]; +int LoopCount = 0; + +inline void NOP() +{ + __ASM volatile ("nop"); // one tick operation, Use to adjust frequency by slowing down the proccess +} + +// User Button Interrupt Service Routine (ISR) +void pressed() +{ + UserButtonPressed = 0; +} + +int checkKeyboardInput(void) +{ + if (pc.readable()) + return 0; // means has input + else + return 1; // means no input +} + +#include "adc_init.h" + +#include "iirlpnorm_filter.h" + +#include "high_path_filter.h" + +#include "no_filter.h" + +#include "predefined_output.h" + +void print_parameters() +{ + printf("\n%s Digital Filter.\nSTART MAIN LOOP, use mode %d, loop #%d, number of sections: %d\n", + FilterType[UseFilterMode], UseFilterMode, LoopCount, + (UseFilterMode == IIRLPNORM_FILTER_MODE) ? NumSections : NumSectionsHP); + if (UseFilterMode == PREDEFINED_OUTPUT_MODE) { + printf("Signal threshould: %d\nSignal scale: %5.2f\nNumber of cycles to detect threshold crossing: %d\nDelay after signal in microseconds: %d\nUse filter: %s\n", + signal_low_threshold, scale_for_predefined_output, num_of_cycles_to_detect_threshold_crossing, delay_after_signal_transmission, + use_filter_with_predefined_output ? "Y" : "N"); + } +} + +// Main procedure + int main() { + char command[64]; + int isInputNotValid; + int k; + bool isSignalClipped = false; + + strcpy(FilterType[0], "IIRLPNORM filter"); + strcpy(FilterType[1], "High Pass filter"); + strcpy(FilterType[2], "No filter"); + strcpy(FilterType[3], "Predefined Output"); + strcpy(FilterType[4], "Test Output"); + + ADC1_Init(); + DAC1_Init(); + + HAL_ADC_Start(&hadc1); + HAL_DAC_Start(&hdac1, DAC_CHANNEL_1); + + // define Dac Register for direct method of setting DAC value`s + Dac_Reg = (uint32_t) (hdac1.Instance); + Dac_Reg += __HAL_DHR12R1_ALIGNEMENT(DAC_ALIGN_12B_R); + + typedef void(*functionPtr)(void); + functionPtr FilterFunction; + + // Assign ISR + mybutton.fall(&pressed); + + LoopCount++; + print_parameters(); + + if (UseFilterMode == PREDEFINED_OUTPUT_MODE) { + // Prepare scaled sound data + isSignalClipped = false; + for (k=0; k < AMOUNT_OF_SIGNIFICANT_SAMPLES; k++ ) { + scaled_sounddata[k] = sounddata[k]* scale_for_predefined_output; + if (scaled_sounddata[k] < (float)-1.0) { + scaled_sounddata[k] = (float)-1.0; + isSignalClipped = true; + } + if (scaled_sounddata[k] > (float)1.0) { + scaled_sounddata[k] = (float)1.0; + isSignalClipped = true; + } + } + } + + // Infinite loop + while(true) { + switch (UseFilterMode) { + case IIRLPNORM_FILTER_MODE: + FilterFunction = iirlpnorm_filter; + printf("Running IIRLPNORM filter\n"); + memset(CurrInput, 0, sizeof(CurrInput)); + memset(LastInput, 0, sizeof(LastInput)); + memset(LLastInput, 0, sizeof(LLastInput)); + break; + // end of case IIRLPNORM_FILTER_MODE + + case HIGH_PASS_FILTER_MODE: + FilterFunction = highpath_filter; + printf("Running High Path filter\n"); + memset(CurrInput, 0, sizeof(CurrInput)); + memset(LastInput, 0, sizeof(LastInput)); + memset(LLastInput, 0, sizeof(LLastInput)); + break; + // end of case HIGH_PASS_FILTER_MODE + + case PREDEFINED_OUTPUT_MODE: + FilterFunction = predefined_output; + printf("Running Predefined Output\n"); + memset(CurrInput, 0, sizeof(CurrInput)); + memset(LastInput, 0, sizeof(LastInput)); + memset(LLastInput, 0, sizeof(LLastInput)); + num_threshold_crossing = 0; + startPredefinedOutput = 0; + num_back_to_normal = 0; + break; + // end of case PREDEFINED_OUTPUT_MODE + + case NO_FILTER_MODE: + FilterFunction = no_filter; + printf("Running No filter\n"); + break; + // end of case NO_FILTER_MODE + + case TEST_OUTPUT_MODE: + FilterFunction = test_output; + printf("Running test output\n"); + break; + // end of case TEST_OUTPUT_MODE + + default: + printf("Wrong User Filter Mode"); + // Default - no filter + FilterFunction = no_filter; + printf("No filter\n"); + break; + + } // end of switch (UserFilterMode) + + UserButtonPressed = 1; + NumCycles = 0; + ADCValueMax = 0; + ADCValueMin = 0xfff; + + // ==================================================== + // Start signal processing + while(UserButtonPressed) { + FilterFunction(); + NumCycles++; + // Check keyboard input each NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT cycles + if((NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT > 0) && (NumCycles % NUM_CYCLES_TO_CHECK_KEYBOARD_INPUT == 0)) { + // printf("Check keyboard input. Cycle: %d\n", NumCycles); + UserButtonPressed = checkKeyboardInput(); + } + } // end of while(UserButtonPressed) + // End of signal processing + // ==================================================== + + // User button pressed + // Main loop working with ADC/DAC is stopped + // Here should be functionality which should be done before start another loop with ADC/DAC + printf("\nKeyboard key or User button pressed! Exit from main loop.\n"); + + // Init filter variables + memset(CurrInput, 0, sizeof(CurrInput)); + memset(LastInput, 0, sizeof(LastInput)); + memset(LLastInput, 0, sizeof(LLastInput)); + + // Input new use mode + isInputNotValid = 1; + while (isInputNotValid) { + printf("Please, select use mode: \n"); + printf("%d - IIRLPNORM filter\n", IIRLPNORM_FILTER_MODE); + printf("%d - High Pass filter\n", HIGH_PASS_FILTER_MODE); + printf("%d - No filter\n", NO_FILTER_MODE); + printf("%d - Predefined Output\n", PREDEFINED_OUTPUT_MODE); + printf("Input your choice or hit Enter to continue main loop in the same use mode: "); + memset(command, 0, sizeof(command)); + gets(command); + // printf("Command:%s; command length:%d\n", command, strlen(command)); + if (strlen(command)-2 != 0 ) { + // convert characters to integer; if convertion not succeeded return 0 (i.e. IIRLPNORM_FILTER_MODE) + UseFilterMode = atoi(&command[strlen(command)-2]); + } + + if (UseFilterMode >= IIRLPNORM_FILTER_MODE && UseFilterMode <= PREDEFINED_OUTPUT_MODE) { + if (UseFilterMode == PREDEFINED_OUTPUT_MODE) { + printf("Enter signal amplitude threshold to start generate predefined signal (default - %d): ", SIGNAL_LOW_THRESHOD); + memset(command, 0, sizeof(command)); + gets(command); + signal_low_threshold = atoi(command); + if (signal_low_threshold == 0) { + printf("\nWrong input - default is taken\n"); + signal_low_threshold = SIGNAL_LOW_THRESHOD; + } + + isSignalClipped = true; + while (isSignalClipped) { + printf("Enter amplitude scale parameter for predefined signal (default - %5.2f): ", SCALE_FOR_PREDEFINED_OUTPUT); + memset(command, 0, sizeof(command)); + gets(command); + scale_for_predefined_output = atof(command); + if (scale_for_predefined_output == float(0.0)) { + printf("\nWrong input - default is taken\n"); + scale_for_predefined_output = SCALE_FOR_PREDEFINED_OUTPUT; + } + isSignalClipped = false; + for (k=0; k < AMOUNT_OF_SIGNIFICANT_SAMPLES; k++ ) { + scaled_sounddata[k] = sounddata[k]* scale_for_predefined_output; + if (scaled_sounddata[k] < (float)-1.0) { + scaled_sounddata[k] = (float)-1.0; + isSignalClipped = true; + } + if (scaled_sounddata[k] > (float)1.0) { + scaled_sounddata[k] = (float)1.0; + isSignalClipped = true; + } + } + if (isSignalClipped) { + printf("With amplitude scale %5.2f, signal will be clipped !!!. Select smaller scale.\n",scale_for_predefined_output); + } + } // end of while (isSignalClipped) + printf("Enter delay after signal in microseconds (default - %d): ", DELAY_AFTER_SIGNAL_TRANSMISSION); + memset(command, 0, sizeof(command)); + gets(command); + delay_after_signal_transmission = atoi(command); + if (delay_after_signal_transmission == 0) { + printf("\nWrong input - default is taken\n"); + delay_after_signal_transmission = DELAY_AFTER_SIGNAL_TRANSMISSION; + } + printf("Enter number of cycles to detect threshold crossing (default - %d): ", NUM_OF_CYCLES_TO_DETECT_THRESHOLD_CROSSING); + memset(command, 0, sizeof(command)); + gets(command); + num_of_cycles_to_detect_threshold_crossing = atoi(command); + if (num_of_cycles_to_detect_threshold_crossing == 0) { + printf("\nWrong input - default is taken\n"); + num_of_cycles_to_detect_threshold_crossing = NUM_OF_CYCLES_TO_DETECT_THRESHOLD_CROSSING; + } + printf("Use high pass filter with predefined output: Y/N (default - %s): ", + USE_FILTER_WITH_PREDEFINED_OUTPUT ? "Y" : "N" ); + memset(command, 0, sizeof(command)); + gets(command); + if ((command[0] == 'Y') || (command[0] == 'y')) { + use_filter_with_predefined_output = true; + } else if ((command[0] == 'N') || (command[0] == 'n')) { + use_filter_with_predefined_output = false; + } else { + use_filter_with_predefined_output = USE_FILTER_WITH_PREDEFINED_OUTPUT; + } + + if (delay_after_signal_transmission == 0) { + delay_after_signal_transmission = USE_FILTER_WITH_PREDEFINED_OUTPUT; + } + memset(command, 0, sizeof(command)); + } + isInputNotValid = 0; + } else if (UseFilterMode == TEST_OUTPUT_MODE) { + isInputNotValid = 0; + } else { + printf("\nWrong input - try again\n"); + } + } + LoopCount++; + print_parameters(); + + } // end while(True) + }