Chirp Signal Generator

Dependencies:   mbed

Fork of TAU_ZOOLOG_Playback_Rev1_1 by Yossi_Students

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)
+    }