ReSpeaker DSP V02

Dependencies:   mbed MbedJSONValue

Committer:
Arkadi
Date:
Thu Jun 20 09:06:46 2019 +0000
Revision:
14:8a4699aa69b5
Parent:
12:9d30df1529be
experiments version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Arkadi 12:9d30df1529be 1 //////////////////////
Arkadi 12:9d30df1529be 2 // Operation Modes //
Arkadi 12:9d30df1529be 3 //////////////////////
Arkadi 1:574b54755983 4
Arkadi 12:9d30df1529be 5 /////////////////
Arkadi 12:9d30df1529be 6 // Variables: //
Arkadi 12:9d30df1529be 7 /////////////////
Arkadi 1:574b54755983 8
Arkadi 12:9d30df1529be 9 // Filter mode - Regular / efficient
Arkadi 12:9d30df1529be 10 //#define EFFICIENT_FILTER
Arkadi 1:574b54755983 11
Arkadi 1:574b54755983 12 // second-order sections filter variables - upto 8 sections
Arkadi 12:9d30df1529be 13 #define MAX_SECTION_NUMBER 5
Arkadi 1:574b54755983 14
Arkadi 1:574b54755983 15 // convertions
Arkadi 4:59319802012b 16 #define ADC2Float (2.0f/4095.0f) // 0.0004884f//
Arkadi 4:59319802012b 17 #define Float2ADC (4095.0f/2.0f) // 2047.5f //
Arkadi 12:9d30df1529be 18
Arkadi 12:9d30df1529be 19 // Filter variables
Arkadi 12:9d30df1529be 20 //SOS Matrix limited to order 10
Arkadi 12:9d30df1529be 21 int FilterSections=1;
Arkadi 12:9d30df1529be 22 float SOSMat[5][6]= { // Predefined SOS Matrix (second order 5Khz filter
Arkadi 12:9d30df1529be 23 1, -2, 1, 1, -1.961, 0.9624,
Arkadi 12:9d30df1529be 24 0, 0, 0, 0, 0, 0,
Arkadi 12:9d30df1529be 25 0, 0, 0, 0, 0, 0,
Arkadi 12:9d30df1529be 26 0, 0, 0, 0, 0, 0,
Arkadi 12:9d30df1529be 27 0, 0, 0, 0, 0, 0
Arkadi 12:9d30df1529be 28 };
Arkadi 12:9d30df1529be 29 float Gscale = 0.9810f;
Arkadi 12:9d30df1529be 30 float filterCurrInput[MAX_SECTION_NUMBER+1] = {0};
Arkadi 12:9d30df1529be 31 float filterLastInput[MAX_SECTION_NUMBER+1] = {0};
Arkadi 12:9d30df1529be 32 float filterLLastInput[MAX_SECTION_NUMBER+1] = {0};
Arkadi 12:9d30df1529be 33
Arkadi 12:9d30df1529be 34 // Trigger mode variables
Arkadi 12:9d30df1529be 35 float signalGain = 1.0; // Signal Gain
Arkadi 12:9d30df1529be 36 float trigTresh = 0.5; // threshold for trigger mode
Arkadi 12:9d30df1529be 37 uint32_t trigDelaySet = 5000; // counter for pulse pass
Arkadi 12:9d30df1529be 38 uint32_t trigDelay = trigDelaySet; // counter for pulse pass
Arkadi 12:9d30df1529be 39 uint32_t trigPause = 10; // pause after trigger in microseconds
Arkadi 12:9d30df1529be 40
Arkadi 12:9d30df1529be 41 // Buffer mode variables - Mid work
Arkadi 12:9d30df1529be 42 uint32_t bufferSizeSet = 5000;
Arkadi 12:9d30df1529be 43 uint32_t bufferSize = bufferSizeSet;
Arkadi 12:9d30df1529be 44 uint32_t preBufferSizeSet = 1000;
Arkadi 12:9d30df1529be 45 uint32_t bufferCountDown = bufferSizeSet - preBufferSizeSet;
Arkadi 12:9d30df1529be 46 float bufferADC[5000] = {0};
Arkadi 12:9d30df1529be 47
Arkadi 12:9d30df1529be 48 // gains vector
Arkadi 12:9d30df1529be 49 #define GAIN_VECTOR_SIZE 5
Arkadi 12:9d30df1529be 50 int gainsVectorSize = 5;
Arkadi 12:9d30df1529be 51 float GainVector[] = {0.1 , 0.2 , 0.4 , 0.8 , 1.6};
Arkadi 1:574b54755983 52
Arkadi 1:574b54755983 53 ///////////////////////////////
Arkadi 1:574b54755983 54 // available filters: //
Arkadi 1:574b54755983 55 ///////////////////////////////
Arkadi 4:59319802012b 56 // off mode, output vdd/2
Arkadi 4:59319802012b 57 inline void offMode(void);
Arkadi 4:59319802012b 58 // passthrough function (output equals input)
Arkadi 4:59319802012b 59 inline void passthrough(void);
Arkadi 4:59319802012b 60 // highpass filter
Arkadi 4:59319802012b 61 inline void highpass(void);
Arkadi 4:59319802012b 62 // highpass filter + trigger mode
Arkadi 4:59319802012b 63 inline void highpassTrig(void);
Arkadi 7:25c81cb23e42 64 // highpass filter + trigger mode + Gains vector
Arkadi 7:25c81cb23e42 65 inline void GainsTrig(void);
Arkadi 7:25c81cb23e42 66 // highpass filter + trigger mode + Delays vector
Arkadi 7:25c81cb23e42 67 inline void DelaysTrig(void);
Arkadi 7:25c81cb23e42 68 // highpass filter + trigger mode + FIR Filter (Convolution)
Arkadi 7:25c81cb23e42 69 inline void FIRTrig(void);
Arkadi 12:9d30df1529be 70 // filter_implementation
Arkadi 12:9d30df1529be 71 inline float HPF_Function(float ADCFloat);
Arkadi 12:9d30df1529be 72
Arkadi 12:9d30df1529be 73 //////////////////////////////
Arkadi 12:9d30df1529be 74 // Filter Function: //
Arkadi 12:9d30df1529be 75 //////////////////////////////
Arkadi 12:9d30df1529be 76 // filter_implementation
Arkadi 12:9d30df1529be 77 inline float HPF_Function(float ADCFloat)
Arkadi 12:9d30df1529be 78 {
Arkadi 12:9d30df1529be 79 // filter local variable
Arkadi 12:9d30df1529be 80 float ADCFloatFiltered;
Arkadi 12:9d30df1529be 81 // filter mode:
Arkadi 12:9d30df1529be 82 #ifdef EFFICIENT_FILTER
Arkadi 12:9d30df1529be 83 // filter coeficients best performance if defined in loop
Arkadi 12:9d30df1529be 84 float SOSMatHP[2][6] = { // 25khz cutoff at 920 kHz sample rate // closer to 30kHz when io toggle switched off.
Arkadi 12:9d30df1529be 85 1.000000, -2.000000, 1.000000, 1.000000, -1.706510, 0.731145,
Arkadi 12:9d30df1529be 86 1.000000, -2.000000, 1.000000, 1.000000, -1.852377, 0.879117
Arkadi 12:9d30df1529be 87 };
Arkadi 12:9d30df1529be 88 float GscaleHP = 0.801724;
Arkadi 12:9d30df1529be 89 // num sections
Arkadi 12:9d30df1529be 90 int NumSectionsHP = sizeof(SOSMatHP)/sizeof(float)/6;
Arkadi 12:9d30df1529be 91 // filter stages variables
Arkadi 12:9d30df1529be 92 static float CurrInput [MAX_SECTION_NUMBER+1];
Arkadi 12:9d30df1529be 93 static float LastInput [MAX_SECTION_NUMBER+1];
Arkadi 12:9d30df1529be 94 static float LLastInput [MAX_SECTION_NUMBER+1];
Arkadi 12:9d30df1529be 95
Arkadi 12:9d30df1529be 96 //////////////////
Arkadi 12:9d30df1529be 97 // Apply Filter //
Arkadi 12:9d30df1529be 98 //////////////////
Arkadi 12:9d30df1529be 99 LLastInput[0] = LastInput[0];
Arkadi 12:9d30df1529be 100 LastInput[0] = CurrInput[0];
Arkadi 12:9d30df1529be 101 CurrInput[0] = ADCFloat;
Arkadi 12:9d30df1529be 102 for (int ii=1; ii <= NumSectionsHP; ii++) {
Arkadi 12:9d30df1529be 103 LLastInput[ii] = LastInput[ii];
Arkadi 12:9d30df1529be 104 LastInput[ii] = CurrInput[ii];
Arkadi 12:9d30df1529be 105 CurrInput[ii] = SOSMatHP[ii-1][0]*CurrInput[ii-1] + SOSMatHP[ii-1][1]*LastInput[ii-1] +
Arkadi 12:9d30df1529be 106 SOSMatHP[ii-1][2]*LLastInput[ii-1] -
Arkadi 12:9d30df1529be 107 SOSMatHP[ii-1][4]*LastInput[ii] - SOSMatHP[ii-1][5]*LLastInput[ii];
Arkadi 12:9d30df1529be 108 ADCFloatFiltered = CurrInput[ii];
Arkadi 12:9d30df1529be 109 }
Arkadi 12:9d30df1529be 110
Arkadi 12:9d30df1529be 111 ADCFloatFiltered = ADCFloatFiltered * GscaleHP * signalGain;
Arkadi 12:9d30df1529be 112
Arkadi 12:9d30df1529be 113 #else
Arkadi 12:9d30df1529be 114 filterLLastInput[0] = filterLastInput[0];
Arkadi 12:9d30df1529be 115 filterLastInput[0] = filterCurrInput[0];
Arkadi 12:9d30df1529be 116 filterCurrInput[0] = ADCFloat;
Arkadi 12:9d30df1529be 117 for (int ii=1; ii <= FilterSections; ii++) {
Arkadi 12:9d30df1529be 118 filterLLastInput[ii] = filterLastInput[ii];
Arkadi 12:9d30df1529be 119 filterLastInput[ii] = filterCurrInput[ii];
Arkadi 12:9d30df1529be 120 filterCurrInput[ii] = SOSMat[ii-1][0]*filterCurrInput[ii-1] + SOSMat[ii-1][1]*filterLastInput[ii-1] +
Arkadi 12:9d30df1529be 121 SOSMat[ii-1][2]*filterLLastInput[ii-1] -
Arkadi 12:9d30df1529be 122 SOSMat[ii-1][4]*filterLastInput[ii] - SOSMat[ii-1][5]*filterLLastInput[ii];
Arkadi 12:9d30df1529be 123
Arkadi 12:9d30df1529be 124 }
Arkadi 12:9d30df1529be 125 ADCFloatFiltered = filterCurrInput[FilterSections];
Arkadi 12:9d30df1529be 126 ADCFloatFiltered = ADCFloatFiltered * Gscale * signalGain;
Arkadi 12:9d30df1529be 127 #endif
Arkadi 12:9d30df1529be 128 return ADCFloatFiltered;
Arkadi 12:9d30df1529be 129 }
Arkadi 12:9d30df1529be 130
Arkadi 1:574b54755983 131
Arkadi 1:574b54755983 132 ///////////////////////////////
Arkadi 12:9d30df1529be 133 // Operation Functions: //
Arkadi 1:574b54755983 134 ///////////////////////////////
Arkadi 4:59319802012b 135 // off mode, output vdd/2
Arkadi 5:ec6f2323a263 136 inline void offMode(void)
Arkadi 5:ec6f2323a263 137 {
Arkadi 10:273127efdc6e 138 // generate some delay (limit loop speeds, creates crashes to the Switch mcu
Arkadi 10:273127efdc6e 139 // for (int ii=0; ii<10; ii++){
Arkadi 10:273127efdc6e 140 // __ASM volatile ("nop"); // one tick operation, Use to adjust frequency by slowing down the proccess
Arkadi 10:273127efdc6e 141 // }
Arkadi 4:59319802012b 142 uint16_t ADCValueOut;
Arkadi 4:59319802012b 143 // set to vdd/2
Arkadi 4:59319802012b 144 ADCValueOut=(uint16_t)((0.0f +1.0f) * Float2ADC);
Arkadi 4:59319802012b 145 // Output value using DAC
Arkadi 5:ec6f2323a263 146 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 4:59319802012b 147 }// end off mode
Arkadi 4:59319802012b 148
Arkadi 4:59319802012b 149 // passthrough function (output equals input)
Arkadi 4:59319802012b 150 inline void passthrough(void)
Arkadi 1:574b54755983 151 {
Arkadi 1:574b54755983 152 uint32_t ADCValue;
Arkadi 1:574b54755983 153
Arkadi 1:574b54755983 154 // Read ADC input
Arkadi 1:574b54755983 155 ADCValue = hadc1.Instance->DR;
Arkadi 1:574b54755983 156 // Output value using DAC
Arkadi 1:574b54755983 157 *(__IO uint32_t *) Dac_Reg = ADCValue;
Arkadi 1:574b54755983 158
Arkadi 4:59319802012b 159 } // end passthrough
Arkadi 1:574b54755983 160
Arkadi 3:48258b86e182 161
Arkadi 1:574b54755983 162 // high pass filter
Arkadi 4:59319802012b 163 inline void highpass(void)
Arkadi 1:574b54755983 164 {
Arkadi 12:9d30df1529be 165 // Dac output variable
Arkadi 1:574b54755983 166 uint16_t ADCValueOut;
Arkadi 1:574b54755983 167
Arkadi 12:9d30df1529be 168 // Read ADC input
Arkadi 12:9d30df1529be 169 float ADCFloat=((uint16_t)(hadc1.Instance->DR) * ADC2Float)-1.0f;
Arkadi 1:574b54755983 170
Arkadi 12:9d30df1529be 171 // Apply Filter
Arkadi 12:9d30df1529be 172 float ADCFloatFiltered = HPF_Function( ADCFloat );
Arkadi 1:574b54755983 173
Arkadi 12:9d30df1529be 174 // Apply Saturation to Output
Arkadi 1:574b54755983 175 if (ADCFloatFiltered < -1.0f) {
Arkadi 1:574b54755983 176 ADCValueOut=0; // Min value
Arkadi 1:574b54755983 177 } else if (ADCFloatFiltered > 1.0f) {
Arkadi 1:574b54755983 178 ADCValueOut=0xFFF; // Max value
Arkadi 1:574b54755983 179 } else {
Arkadi 1:574b54755983 180 ADCValueOut=(uint16_t)((ADCFloatFiltered +1.0f) * Float2ADC);
Arkadi 1:574b54755983 181 }
Arkadi 1:574b54755983 182
Arkadi 1:574b54755983 183 // Output value using DAC
Arkadi 1:574b54755983 184 // HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValueOut);
Arkadi 1:574b54755983 185 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 4:59319802012b 186
Arkadi 4:59319802012b 187 } // end high pass filter
Arkadi 4:59319802012b 188
Arkadi 4:59319802012b 189 // highpass filter + trigger mode
Arkadi 5:ec6f2323a263 190 inline void highpassTrig(void)
Arkadi 5:ec6f2323a263 191 {
Arkadi 5:ec6f2323a263 192 // trigger variables
Arkadi 5:ec6f2323a263 193 static bool trigFlag=0; // flag to indicate trigger event
Arkadi 5:ec6f2323a263 194
Arkadi 12:9d30df1529be 195 // Dac output variable
Arkadi 12:9d30df1529be 196 uint16_t ADCValueOut;
Arkadi 4:59319802012b 197
Arkadi 12:9d30df1529be 198 // Read ADC input
Arkadi 12:9d30df1529be 199 float ADCFloat=((uint16_t)(hadc1.Instance->DR) * ADC2Float)-1.0f;
Arkadi 4:59319802012b 200
Arkadi 12:9d30df1529be 201 // Apply Filter
Arkadi 12:9d30df1529be 202 float ADCFloatFiltered = HPF_Function( ADCFloat );
Arkadi 4:59319802012b 203
Arkadi 5:ec6f2323a263 204 ///////////////////////////////////////////////
Arkadi 5:ec6f2323a263 205 // Event detection //
Arkadi 5:ec6f2323a263 206 ///////////////////////////////////////////////
Arkadi 5:ec6f2323a263 207 if (trigFlag) { // event already detected
Arkadi 5:ec6f2323a263 208 trigDelay--;
Arkadi 5:ec6f2323a263 209 if (trigDelay == 0) { // pulse pass run out, perform delay and reset variables
Arkadi 5:ec6f2323a263 210 trigDelay = trigDelaySet; //reset counter for next iteration
Arkadi 5:ec6f2323a263 211 trigFlag=0;
Arkadi 5:ec6f2323a263 212 // reset filter
Arkadi 12:9d30df1529be 213 ADCFloatFiltered = 0;
Arkadi 5:ec6f2323a263 214 // update dac
Arkadi 5:ec6f2323a263 215 ADCValueOut=(uint16_t)((ADCFloatFiltered +1.0f) * Float2ADC);
Arkadi 5:ec6f2323a263 216 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 6:e8b4ca41c691 217 //*(__IO uint32_t *) Dac_Reg = 0; // test triggered mode
Arkadi 5:ec6f2323a263 218 // delay for set time
Arkadi 8:8a3e6241c104 219 wait_ms(trigPause);
Arkadi 5:ec6f2323a263 220 }
Arkadi 12:9d30df1529be 221 } else if (ADCFloatFiltered >= trigTresh) {
Arkadi 5:ec6f2323a263 222 trigFlag=1;
Arkadi 5:ec6f2323a263 223 }
Arkadi 7:25c81cb23e42 224 ////////////////////////////////
Arkadi 7:25c81cb23e42 225 // Apply Saturation to Output //
Arkadi 7:25c81cb23e42 226 ////////////////////////////////
Arkadi 4:59319802012b 227
Arkadi 4:59319802012b 228 if (ADCFloatFiltered < -1.0f) {
Arkadi 4:59319802012b 229 ADCValueOut=0; // Min value
Arkadi 4:59319802012b 230 } else if (ADCFloatFiltered > 1.0f) {
Arkadi 4:59319802012b 231 ADCValueOut=0xFFF; // Max value
Arkadi 4:59319802012b 232 } else {
Arkadi 4:59319802012b 233 ADCValueOut=(uint16_t)((ADCFloatFiltered +1.0f) * Float2ADC);
Arkadi 4:59319802012b 234 }
Arkadi 4:59319802012b 235
Arkadi 4:59319802012b 236 // Output value using DAC
Arkadi 4:59319802012b 237 // HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValueOut);
Arkadi 6:e8b4ca41c691 238 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 4:59319802012b 239 //wait_us(1);
Arkadi 7:25c81cb23e42 240 } // end high pass filter + trigger mode
Arkadi 7:25c81cb23e42 241
Arkadi 7:25c81cb23e42 242
Arkadi 7:25c81cb23e42 243 // highpass filter + trigger mode + Gains vector
Arkadi 7:25c81cb23e42 244 inline void GainsTrig(void)
Arkadi 7:25c81cb23e42 245 {
Arkadi 12:9d30df1529be 246 // Gains variables:
Arkadi 12:9d30df1529be 247 static int GainVectorIndex = 0;
Arkadi 12:9d30df1529be 248 // trigger variables
Arkadi 12:9d30df1529be 249 static bool trigFlag=0; // flag to indicate trigger event
Arkadi 12:9d30df1529be 250 // Dac output variable
Arkadi 12:9d30df1529be 251 uint16_t ADCValueOut;
Arkadi 12:9d30df1529be 252
Arkadi 12:9d30df1529be 253 // Read ADC input
Arkadi 12:9d30df1529be 254 float ADCFloat=((uint16_t)(hadc1.Instance->DR) * ADC2Float)-1.0f;
Arkadi 12:9d30df1529be 255
Arkadi 12:9d30df1529be 256 // Apply Filter
Arkadi 12:9d30df1529be 257 float ADCFloatFiltered = HPF_Function( ADCFloat );
Arkadi 12:9d30df1529be 258
Arkadi 12:9d30df1529be 259
Arkadi 12:9d30df1529be 260 ///////////////////////////////////////////////
Arkadi 12:9d30df1529be 261 // Event detection //
Arkadi 12:9d30df1529be 262 ///////////////////////////////////////////////
Arkadi 12:9d30df1529be 263 if (trigFlag) { // event already detected
Arkadi 12:9d30df1529be 264 trigDelay--;
Arkadi 12:9d30df1529be 265 if (trigDelay == 0) { // pulse pass run out, perform delay and reset variables
Arkadi 12:9d30df1529be 266 trigDelay = trigDelaySet; //reset counter for next iteration
Arkadi 12:9d30df1529be 267 trigFlag=0;
Arkadi 12:9d30df1529be 268 // reset filter
Arkadi 12:9d30df1529be 269 ADCFloatFiltered = 0;
Arkadi 12:9d30df1529be 270 // update dac
Arkadi 12:9d30df1529be 271 ADCValueOut=(uint16_t)((ADCFloatFiltered +1.0f) * Float2ADC);
Arkadi 12:9d30df1529be 272 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 12:9d30df1529be 273 //*(__IO uint32_t *) Dac_Reg = 0; // test triggered mode
Arkadi 12:9d30df1529be 274 // delay for set time
Arkadi 12:9d30df1529be 275 wait_ms(trigPause);
Arkadi 12:9d30df1529be 276
Arkadi 12:9d30df1529be 277 // change gain settings
Arkadi 12:9d30df1529be 278 GainVectorIndex++;
Arkadi 12:9d30df1529be 279 GainVectorIndex = GainVectorIndex % gainsVectorSize;
Arkadi 12:9d30df1529be 280 }
Arkadi 12:9d30df1529be 281 } else if (ADCFloatFiltered >= trigTresh) {
Arkadi 12:9d30df1529be 282 trigFlag=1;
Arkadi 12:9d30df1529be 283 }
Arkadi 12:9d30df1529be 284 //////////////////////////
Arkadi 12:9d30df1529be 285 // Apply Gain to Output //
Arkadi 12:9d30df1529be 286 //////////////////////////
Arkadi 12:9d30df1529be 287 ADCFloatFiltered = ADCFloatFiltered * GainVector[GainVectorIndex];
Arkadi 12:9d30df1529be 288
Arkadi 12:9d30df1529be 289 if (ADCFloatFiltered < -1.0f) {
Arkadi 12:9d30df1529be 290 ADCValueOut=0; // Min value
Arkadi 12:9d30df1529be 291 } else if (ADCFloatFiltered > 1.0f) {
Arkadi 12:9d30df1529be 292 ADCValueOut=0xFFF; // Max value
Arkadi 12:9d30df1529be 293 } else {
Arkadi 12:9d30df1529be 294 ADCValueOut=(uint16_t)((ADCFloatFiltered +1.0f) * Float2ADC);
Arkadi 12:9d30df1529be 295 }
Arkadi 12:9d30df1529be 296
Arkadi 12:9d30df1529be 297 // Output value using DAC
Arkadi 12:9d30df1529be 298 // HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValueOut);
Arkadi 12:9d30df1529be 299 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 12:9d30df1529be 300 //wait_us(1);
Arkadi 12:9d30df1529be 301 } // end GainsTrig
Arkadi 12:9d30df1529be 302
Arkadi 12:9d30df1529be 303
Arkadi 12:9d30df1529be 304
Arkadi 12:9d30df1529be 305
Arkadi 12:9d30df1529be 306
Arkadi 12:9d30df1529be 307 //////////////////////////////////////////////
Arkadi 12:9d30df1529be 308 /////////////////// Implement
Arkadi 12:9d30df1529be 309 //////////////////////////////////////////////
Arkadi 12:9d30df1529be 310
Arkadi 12:9d30df1529be 311 // highpass filter + trigger mode + Delays vector
Arkadi 12:9d30df1529be 312 inline void DelaysTrig(void) // - mid work feature. (not working yet)
Arkadi 12:9d30df1529be 313 {
Arkadi 7:25c81cb23e42 314 ///////////////////////////////
Arkadi 7:25c81cb23e42 315 // Gains variables: //
Arkadi 7:25c81cb23e42 316 ///////////////////////////////
Arkadi 12:9d30df1529be 317 #define DELAY_VECTOR_SIZE 5
Arkadi 12:9d30df1529be 318 uint32_t DelayVector[] = {100 , 200 , 300 , 400 , 500}; // millis
Arkadi 12:9d30df1529be 319 static uint16_t DelayVectorIndex = 0;
Arkadi 12:9d30df1529be 320 static uint32_t BufferIndex = 0;
Arkadi 12:9d30df1529be 321
Arkadi 12:9d30df1529be 322 //uint32_t bufferSizeSet = 5000;
Arkadi 12:9d30df1529be 323 //uint32_t preBufferSizeSet = 1000;
Arkadi 12:9d30df1529be 324 //uint32_t bufferCountDown = bufferSizeSet - preBufferSizeSet;
Arkadi 12:9d30df1529be 325 //float bufferADC[bufferSizeSet] = {0};
Arkadi 7:25c81cb23e42 326 ///////////////////////////////
Arkadi 7:25c81cb23e42 327 // filter variables: //
Arkadi 7:25c81cb23e42 328 ///////////////////////////////
Arkadi 7:25c81cb23e42 329 // filter coeficients best performance if defined in loop
Arkadi 7:25c81cb23e42 330 float SOSMatHP[2][6] = { // 25khz cutoff at 920 kHz sample rate // closer to 30kHz when io toggle switched off.
Arkadi 7:25c81cb23e42 331 1.000000, -2.000000, 1.000000, 1.000000, -1.706510, 0.731145,
Arkadi 7:25c81cb23e42 332 1.000000, -2.000000, 1.000000, 1.000000, -1.852377, 0.879117
Arkadi 7:25c81cb23e42 333 };
Arkadi 7:25c81cb23e42 334 float GscaleHP = 0.801724;
Arkadi 7:25c81cb23e42 335
Arkadi 7:25c81cb23e42 336 // num sections
Arkadi 7:25c81cb23e42 337 int NumSectionsHP = sizeof(SOSMatHP)/sizeof(float)/6;
Arkadi 7:25c81cb23e42 338
Arkadi 7:25c81cb23e42 339 float ADCFloat;
Arkadi 7:25c81cb23e42 340 float ADCFloatFiltered;
Arkadi 7:25c81cb23e42 341 uint16_t ADCValueOut;
Arkadi 7:25c81cb23e42 342
Arkadi 7:25c81cb23e42 343 // filter stages variables
Arkadi 7:25c81cb23e42 344 static float CurrInput [MAX_SECTION_NUMBER+1];
Arkadi 7:25c81cb23e42 345 static float LastInput [MAX_SECTION_NUMBER+1];
Arkadi 7:25c81cb23e42 346 static float LLastInput [MAX_SECTION_NUMBER+1];
Arkadi 7:25c81cb23e42 347
Arkadi 7:25c81cb23e42 348 // trigger variables
Arkadi 7:25c81cb23e42 349 static bool trigFlag=0; // flag to indicate trigger event
Arkadi 7:25c81cb23e42 350
Arkadi 7:25c81cb23e42 351 ////////////////////
Arkadi 7:25c81cb23e42 352 // Read ADC input //
Arkadi 7:25c81cb23e42 353 ////////////////////
Arkadi 7:25c81cb23e42 354 ADCFloat=((uint16_t)(hadc1.Instance->DR) * ADC2Float)-1.0f;
Arkadi 7:25c81cb23e42 355
Arkadi 7:25c81cb23e42 356 //////////////////////////////////////////////////////
Arkadi 7:25c81cb23e42 357 // Apply Filter to input //
Arkadi 7:25c81cb23e42 358 //////////////////////////////////////////////////////
Arkadi 7:25c81cb23e42 359
Arkadi 7:25c81cb23e42 360 LLastInput[0] = LastInput[0];
Arkadi 7:25c81cb23e42 361 LastInput[0] = CurrInput[0];
Arkadi 7:25c81cb23e42 362 CurrInput[0] = ADCFloat;
Arkadi 7:25c81cb23e42 363 for (int ii=1; ii <= NumSectionsHP; ii++) {
Arkadi 7:25c81cb23e42 364 LLastInput[ii] = LastInput[ii];
Arkadi 7:25c81cb23e42 365 LastInput[ii] = CurrInput[ii];
Arkadi 7:25c81cb23e42 366 CurrInput[ii] = SOSMatHP[ii-1][0]*CurrInput[ii-1] + SOSMatHP[ii-1][1]*LastInput[ii-1] +
Arkadi 7:25c81cb23e42 367 SOSMatHP[ii-1][2]*LLastInput[ii-1] -
Arkadi 7:25c81cb23e42 368 SOSMatHP[ii-1][4]*LastInput[ii] - SOSMatHP[ii-1][5]*LLastInput[ii];
Arkadi 7:25c81cb23e42 369 ADCFloatFiltered = CurrInput[ii];
Arkadi 7:25c81cb23e42 370 }
Arkadi 7:25c81cb23e42 371
Arkadi 7:25c81cb23e42 372 ADCFloatFiltered = ADCFloatFiltered * GscaleHP;
Arkadi 7:25c81cb23e42 373
Arkadi 8:8a3e6241c104 374 ////////////////////////////////
Arkadi 8:8a3e6241c104 375 // Fill in buffer //
Arkadi 8:8a3e6241c104 376 ////////////////////////////////
Arkadi 8:8a3e6241c104 377 bufferADC[BufferIndex] = ADCFloatFiltered;
Arkadi 8:8a3e6241c104 378 BufferIndex++;
Arkadi 8:8a3e6241c104 379 BufferIndex = BufferIndex % bufferSize;
Arkadi 8:8a3e6241c104 380 ///////////////////////////////////////////////
Arkadi 8:8a3e6241c104 381 // Event detection //
Arkadi 8:8a3e6241c104 382 ///////////////////////////////////////////////
Arkadi 8:8a3e6241c104 383 if (trigFlag) { // event already detected
Arkadi 8:8a3e6241c104 384 bufferCountDown--; // count down
Arkadi 8:8a3e6241c104 385 if (bufferCountDown == 0) { // pulse pass run out, perform delay and reset variables
Arkadi 8:8a3e6241c104 386 bufferCountDown = bufferSizeSet - preBufferSizeSet; //reset counter for next iteration
Arkadi 8:8a3e6241c104 387 trigFlag=0;
Arkadi 8:8a3e6241c104 388 // reset filter
Arkadi 8:8a3e6241c104 389 for (int ii=1; ii <= NumSectionsHP; ii++) {
Arkadi 8:8a3e6241c104 390 LLastInput[ii] = 0;
Arkadi 8:8a3e6241c104 391 LastInput[ii] = 0;
Arkadi 8:8a3e6241c104 392 CurrInput[ii] = 0;
Arkadi 8:8a3e6241c104 393 ADCFloatFiltered = 0;
Arkadi 8:8a3e6241c104 394 }
Arkadi 12:9d30df1529be 395
Arkadi 8:8a3e6241c104 396 // generate delay
Arkadi 8:8a3e6241c104 397 // delay for set time
Arkadi 8:8a3e6241c104 398 wait_ms(DelayVector[DelayVectorIndex]);
Arkadi 8:8a3e6241c104 399 // change delay settings
Arkadi 8:8a3e6241c104 400 DelayVectorIndex++;
Arkadi 8:8a3e6241c104 401 DelayVectorIndex = DelayVectorIndex % DELAY_VECTOR_SIZE;
Arkadi 12:9d30df1529be 402
Arkadi 12:9d30df1529be 403
Arkadi 8:8a3e6241c104 404 // play out buffer
Arkadi 8:8a3e6241c104 405 for (int ii=0 ; ii<bufferSize ; ii++) {
Arkadi 12:9d30df1529be 406
Arkadi 8:8a3e6241c104 407 ADCFloatFiltered = bufferADC[BufferIndex];
Arkadi 8:8a3e6241c104 408 BufferIndex++;
Arkadi 8:8a3e6241c104 409 BufferIndex = BufferIndex % bufferSize;
Arkadi 8:8a3e6241c104 410 ////////////////////////////////
Arkadi 8:8a3e6241c104 411 // Apply Saturation to Output //
Arkadi 8:8a3e6241c104 412 ////////////////////////////////
Arkadi 8:8a3e6241c104 413
Arkadi 8:8a3e6241c104 414 if (ADCFloatFiltered < -1.0f) {
Arkadi 8:8a3e6241c104 415 ADCValueOut=0; // Min value
Arkadi 8:8a3e6241c104 416 } else if (ADCFloatFiltered > 1.0f) {
Arkadi 8:8a3e6241c104 417 ADCValueOut=0xFFF; // Max value
Arkadi 8:8a3e6241c104 418 } else {
Arkadi 8:8a3e6241c104 419 ADCValueOut=(uint16_t)((ADCFloatFiltered +1.0f) * Float2ADC);
Arkadi 8:8a3e6241c104 420 }
Arkadi 8:8a3e6241c104 421
Arkadi 8:8a3e6241c104 422 // Output value using DAC
Arkadi 8:8a3e6241c104 423 // HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValueOut);
Arkadi 8:8a3e6241c104 424 *(__IO uint32_t *) Dac_Reg = ADCValueOut;
Arkadi 8:8a3e6241c104 425 //wait_us(1);
Arkadi 12:9d30df1529be 426 }
Arkadi 8:8a3e6241c104 427 }
Arkadi 8:8a3e6241c104 428 } else if (ADCFloatFiltered >= trigTresh) {
Arkadi 8:8a3e6241c104 429 trigFlag=1;
Arkadi 8:8a3e6241c104 430 }
Arkadi 12:9d30df1529be 431
Arkadi 7:25c81cb23e42 432 } // end GainsTrig