Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed MbedJSONValue
main.cpp
00001 //////////////////////////////////////// 00002 // Tau_ReSpeaker_DSP V02 // 00003 // Arkadiraf@gmail.com - 08/06/2019 // 00004 //////////////////////////////////////// 00005 /* 00006 Json Format: json:{"name":"dsp","mode":"off"}\r\n 00007 */ 00008 00009 00010 00011 /* 00012 Board : Nucleo STM32F446RE 00013 Power Source : DC-DC 5V Regulator E5V Jumper 00014 */ 00015 00016 /* 00017 Pinout: 00018 PC - Serial 2 00019 PA_2 (Tx) --> STLINK 00020 PA_3 (Rx) --> STLINK 00021 00022 Switch - Serial 3 00023 PC_10 (Tx) --> SW_Rx 00024 PC_11 (Rx) --> SW_Tx 00025 00026 Digital output 00027 PA_5 --> led (DigitalOut) 00028 PA_10 --> DSP_Trigger 00029 00030 Digital Input 00031 PC_13 --> BTN (Blue) 00032 00033 PA_6 --> Toggle Pin (Loop Freq D12) 00034 00035 Analog Input 00036 PA_0 --> SIG_IN_DSP (A0) 00037 00038 Analog Output 00039 PA_4 --> SIG_OUT_DSP (A2) 00040 00041 */ 00042 00043 /////////////// 00044 // Libraries // 00045 /////////////// 00046 #include "mbed.h" 00047 #include "MbedJSONValue.h" 00048 #include "chirp.h" 00049 /////////////// 00050 // #defines // 00051 /////////////// 00052 00053 //#define TOGGLE_IO_MODE // loop frequency indicator 00054 00055 // UART debug modes: 00056 //#define DEBUG_MOD1 // json packet recognise 00057 //#define DEBUG_MOD2 // json parse 00058 //#define DEBUG_MOD3 // dsp handler 00059 //#define DEBUG_MOD10 // responsivity msges to gui 00060 00061 // PI variable 00062 #define PI_DOUBLE (3.141592653589793238462) 00063 #define PI_FLOAT (3.14159f) 00064 00065 // json commad 00066 #define MSG_BUFFER_SIZE 1024 00067 #define HEADER_SIZE 5 00068 #define FOOTER_SIZE 2 00069 00070 // Frequency counter 00071 #define TICKS2TOGGLE 1000000 00072 00073 ///////////// 00074 // Objects // 00075 ///////////// 00076 // json 00077 MbedJSONValue guiCmd; 00078 00079 // uart 00080 Serial pc(USBTX, USBRX); 00081 00082 // uart switch_dsp 00083 Serial switch_dsp(PC_10, PC_11); 00084 00085 // digital 00086 DigitalIn user_button(PC_13); 00087 DigitalOut dsp_trigger(PA_10);// D2 00088 DigitalOut led(PA_5); // D13 00089 DigitalOut mytoggle(PA_6); // D12 00090 00091 // analog / define to init at mbed initialization. work directly with registers 00092 AnalogOut dsp_output(PA_4); 00093 AnalogIn dsp_input(PA_0); 00094 00095 00096 // ADC/DAC declarations 00097 ADC_HandleTypeDef hadc1; 00098 DAC_HandleTypeDef hdac1; 00099 00100 /////////////// 00101 // variables // 00102 /////////////// 00103 00104 // Frequency counter 00105 uint32_t toggleCounter = 0; 00106 // toogle pin state 00107 bool toggleCounterState = 0; 00108 // toogle pin state 00109 bool toggelState=0; 00110 00111 // json buffer 00112 char json[MSG_BUFFER_SIZE]; 00113 00114 // packet variables 00115 struct packetMSG_struct { 00116 // recieve message variables 00117 uint8_t header[HEADER_SIZE]; 00118 uint8_t footer[FOOTER_SIZE]; 00119 uint8_t syncIndex; // sync index for header / footer 00120 uint8_t syncFlag; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer 00121 // buffer 00122 uint16_t bufferIndex; // buffer index 00123 uint8_t buffer[MSG_BUFFER_SIZE]; 00124 } ; 00125 packetMSG_struct packetMSG; 00126 00127 00128 // Dac Register for direct method of setting DAC value`s 00129 __IO uint32_t Dac_Reg = 0; 00130 00131 // create function pointer 00132 typedef void(*functionPtr)(void); 00133 functionPtr FilterFunction; 00134 00135 // alternative functuin selection (faster mcu process) 00136 volatile uint8_t operationMode = 1; 00137 // 0 - off 00138 // 1 - passthrough - no filter 00139 // 2 - highpass - High Pass filter 00140 // 3 - hpf_trig - High Pass filter + Trigger mode 00141 // 4 - gains_trig - highpass filter + trigger mode + Gains vector 00142 00143 /////////////// 00144 // Functions // 00145 /////////////// 00146 00147 // init functions header //hadc1 needs to be defined preiod #incude 00148 #include "adc_init.h" // initialize adc/dac directly for continious sample 00149 #include "filters.h" 00150 00151 // nop operation 00152 inline void NOP() 00153 { 00154 __ASM volatile ("nop"); // one tick operation, Use to adjust frequency by slowing down the proccess 00155 } 00156 00157 // Serial Event function 00158 void rxCallback(void); 00159 00160 // initialize packet struct 00161 void initPacket(void); 00162 00163 // Packet Parser 00164 void parsePacket(void); 00165 00166 // DSP Packet Handler 00167 void dspPacket(void); 00168 00169 // DSP Param Packet Handler 00170 void dspParamPacket(void); 00171 00172 // DSP Filter Packet Handler 00173 void dspFilterPacket(void); 00174 00175 // DSP Play Packet Handler 00176 void dspPlayPacket(void); 00177 00178 // initialize DSP 00179 void initDSP(void); 00180 00181 //////////////////////// 00182 // Main Code Setup : // 00183 //////////////////////// 00184 int main() 00185 { 00186 // init packet: 00187 initPacket(); 00188 00189 // initialize DSP 00190 initDSP(); 00191 00192 pc.baud(57600); 00193 switch_dsp.baud(57600); 00194 00195 00196 // pc is used for debbuging, in application mode the commands are from the switch_dsp. 00197 // attach serial event interrupt 00198 pc.attach(&rxCallback, Serial::RxIrq); 00199 00200 // attach serial event interrupt 00201 switch_dsp.attach(&rxCallback, Serial::RxIrq); 00202 00203 #ifdef DEBUG_MOD1 00204 pc.printf("ReSpeaker Test \r\n"); 00205 #endif 00206 00207 /////////////////////// 00208 // Main Code Loop : // 00209 /////////////////////// 00210 while(1) { 00211 // run selected filter 00212 if (operationMode == 0) { 00213 offMode(); 00214 } else if (operationMode == 1) { 00215 passthrough(); 00216 } else if (operationMode == 2) { 00217 highpass(); 00218 } else if (operationMode == 3) { 00219 highpassTrig(); 00220 } else if (operationMode == 4) { 00221 GainsTrig(); 00222 } 00223 // more elegant but much slower option: 00224 //FilterFunction(); 00225 #ifdef TOGGLE_IO_MODE 00226 // toggle pin, Loop frequency indicator 00227 toggelState=!toggelState; 00228 mytoggle.write(toggelState); 00229 #endif 00230 // Frequency counter 00231 toggleCounter++; 00232 if (toggleCounter == TICKS2TOGGLE) { 00233 toggleCounter=0; 00234 toggleCounterState = !toggleCounterState; 00235 dsp_trigger.write(toggleCounterState); 00236 } 00237 } // end loop 00238 } // end main 00239 00240 /////////////// 00241 // Functions // 00242 /////////////// 00243 00244 // initialize DSP 00245 void initDSP(void) 00246 { 00247 // init dac 00248 ADC1_Init(); 00249 DAC1_Init(); 00250 00251 HAL_ADC_Start(&hadc1); 00252 HAL_DAC_Start(&hdac1, DAC_CHANNEL_1); 00253 00254 // define Dac Register for direct method of setting DAC value`s 00255 Dac_Reg = (uint32_t) (hdac1.Instance); 00256 Dac_Reg += __HAL_DHR12R1_ALIGNEMENT(DAC_ALIGN_12B_R); 00257 00258 // intialize filter function pointer 00259 FilterFunction = offMode;//highpass_filter; 00260 operationMode = 0 ; 00261 } 00262 00263 // Serial Event function 00264 void rxCallback(void) 00265 { 00266 while ((pc.readable()) || (switch_dsp.readable())) { 00267 // read icoming 00268 uint8_t in_byte=0; 00269 //led = !led; 00270 if (pc.readable()) { 00271 in_byte = pc.getc(); 00272 } else if (switch_dsp.readable()) { 00273 in_byte = switch_dsp.getc(); 00274 } 00275 #ifdef DEBUG_MOD1 00276 pc.putc(in_byte); 00277 #endif 00278 // detect start message , end message 00279 switch (packetMSG.syncFlag) { 00280 // waiting for header 00281 case 0: { 00282 if (packetMSG.header[packetMSG.syncIndex] == in_byte) { 00283 packetMSG.syncIndex++; 00284 if (packetMSG.syncIndex == HEADER_SIZE) { // finish header SYNC 00285 packetMSG.syncFlag = 1; // start collecting data, wait for footer 00286 packetMSG.bufferIndex = 0; 00287 packetMSG.syncIndex=0; 00288 } 00289 } else { // reinit sync 00290 packetMSG.syncIndex=0; 00291 } 00292 //pc.printf("case 0 , %d \r\n",packetMSG.syncIndex); 00293 break; 00294 } 00295 // waiting for footer 00296 case 1: { 00297 // add byte to buffer 00298 packetMSG.buffer[packetMSG.bufferIndex] = in_byte; 00299 packetMSG.bufferIndex++; 00300 if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow 00301 // reset buffer 00302 packetMSG.bufferIndex = 0; 00303 packetMSG.syncIndex = 0; 00304 packetMSG.syncFlag = 0; 00305 } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved 00306 packetMSG.syncIndex++; 00307 packetMSG.syncFlag=2; // move to verify footer 00308 } 00309 //pc.printf("case 2 , %d \r\n",packetMSG.syncIndex); 00310 break; 00311 } 00312 // verify footer 00313 case 2: { 00314 // add byte to buffer 00315 packetMSG.buffer[packetMSG.bufferIndex] = in_byte; 00316 packetMSG.bufferIndex++; 00317 if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow 00318 // reset buffer 00319 packetMSG.bufferIndex = 0; 00320 packetMSG.syncIndex = 0; 00321 packetMSG.syncFlag = 0; 00322 } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved 00323 packetMSG.syncIndex++; 00324 if (packetMSG.syncIndex == FOOTER_SIZE) { // finish footer SYNC 00325 packetMSG.syncFlag = 3; 00326 // copy packet to json buffer 00327 memcpy (&json, &packetMSG.buffer, packetMSG.bufferIndex); 00328 json[packetMSG.bufferIndex]=NULL; // end with NULL to indicate end of string 00329 // copy packet to json buffer with sprintf 00330 //sprintf(json, "%.*s", packetMSG.bufferIndex, packetMSG.buffer ); 00331 // send msg to parse. 00332 parsePacket(); 00333 // reset buffer 00334 packetMSG.bufferIndex = 0; 00335 packetMSG.syncIndex = 0; 00336 packetMSG.syncFlag = 0; 00337 } 00338 } else { // footer broke restart wait for footer 00339 packetMSG.syncFlag=1; 00340 // verify that it didnt broke on first footer char 00341 if (packetMSG.footer[0] == in_byte) { 00342 packetMSG.syncIndex=1; 00343 } else { 00344 packetMSG.syncIndex=0; 00345 } 00346 } 00347 break; 00348 } 00349 default: { 00350 pc.printf("Sonmething went wrong \r\n"); 00351 break; 00352 } 00353 } // end switch 00354 }// end uart readable 00355 } // end rxCallback 00356 00357 // initialize packet struct 00358 void initPacket(void) 00359 { 00360 // init variables to default: 00361 packetMSG.header[0] = 'j'; 00362 packetMSG.header[1] = 's'; 00363 packetMSG.header[2] = 'o'; 00364 packetMSG.header[3] = 'n'; 00365 packetMSG.header[4] = ':'; 00366 00367 packetMSG.footer[0]= 13; // /r 00368 packetMSG.footer[1]= 10; // /n 00369 00370 packetMSG.syncIndex=0; // sync index for header / footer 00371 packetMSG.syncFlag=0; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer 00372 packetMSG.bufferIndex=0; // buffer index 00373 }// end init Packet struct 00374 00375 00376 00377 // Packet Parser 00378 void parsePacket(void) 00379 { 00380 string targetName; 00381 #ifdef DEBUG_MOD2 00382 // write buffer to screen 00383 //pc.printf("%d, %.*s", packetMSG.bufferIndex ,packetMSG.bufferIndex, packetMSG.buffer ); 00384 pc.printf("%s", json); 00385 #endif 00386 00387 // GUI message format Switch: {"name":"switch","mic":0, "spk": [0,1,0,0,0]} 00388 parse(guiCmd, json); 00389 00390 // get target: 00391 targetName = guiCmd["name"].get<string>(); // switch / dsp 00392 00393 #ifdef DEBUG_MOD2 00394 // send parsed values 00395 pc.printf("targetName: %s \r\n", targetName.c_str()); 00396 #endif 00397 00398 // select handler based on target mcu 00399 if (targetName == "dsp") { 00400 dspPacket(); 00401 } else if (targetName == "dspParam") { 00402 dspParamPacket(); 00403 } else if (targetName == "dspFilter") { 00404 dspFilterPacket(); 00405 } else if (targetName == "dspPlay") { 00406 dspPlayPacket(); 00407 } else { 00408 #ifdef DEBUG_MOD2 00409 // unrecognised target 00410 pc.printf("unrecognised target: %s \r\n", targetName.c_str()); 00411 #endif 00412 } 00413 // led blink 00414 led = !led; 00415 }// end parse 00416 00417 00418 // DSP Packet Handler 00419 void dspPacket(void) 00420 { 00421 string modeType; 00422 // get operation mode 00423 modeType = guiCmd["mode"].get<string>(); 00424 00425 #ifdef DEBUG_MOD10 00426 // send parsed values 00427 pc.printf("mode: %s\r\n", modeType.c_str()); 00428 //switch_dsp.printf("mode: %s\r\n", modeType.c_str()); 00429 #endif 00430 // selected operation mode 00431 if ( modeType == "off" ) { 00432 FilterFunction = offMode; 00433 operationMode = 0 ; 00434 } else if( modeType == "passthrough" ) { 00435 FilterFunction = passthrough; 00436 operationMode = 1 ; 00437 } else if( modeType == "highpass" ) { 00438 FilterFunction = highpass; 00439 operationMode = 2 ; 00440 } else if( modeType == "hpf_trig" ) { 00441 FilterFunction = highpassTrig; 00442 operationMode = 3 ; 00443 } else if( modeType == "gain_trig" ) { 00444 FilterFunction = GainsTrig; 00445 operationMode = 4 ; 00446 } else { 00447 switch_dsp.printf("undefined mode %s \r\n", modeType.c_str()); 00448 FilterFunction = offMode; 00449 operationMode = 0 ; 00450 } 00451 // succesfull parse 00452 switch_dsp.printf("{\"Ack\":\"dsp\",\"mode\":\"%s\"}\r\n",modeType.c_str()); 00453 }// end dspPacket 00454 // DSP Param Packet Handler 00455 void dspParamPacket(void) 00456 { 00457 // get values. 00458 signalGain = ((float)guiCmd["gain"].get<int>())/1000; // issue in parsing doubles when the number is round 00459 trigTresh = ((float)guiCmd["trigTresh"].get<int>()) / 100.0f; 00460 trigDelaySet = (uint32_t)guiCmd["trigPass"].get<int>(); 00461 trigPause = (uint32_t)guiCmd["trigPause"].get<int>(); 00462 00463 trigDelay = trigDelaySet; 00464 #ifdef DEBUG_MOD10 00465 // send parsed values 00466 pc.printf("SignalGain: %.3f , trigTresh: %.3f , trigDelaySet %d , trigPause: %d\r\n", signalGain , trigTresh , trigDelaySet , trigPause); 00467 #endif 00468 // succesfull parse 00469 switch_dsp.printf("{\"Ack\":\"dspParam\",\"SignalGain\":%.3f,\"trigTresh\":%.3f,\"trigDelaySet\":%d,\"trigPause\":%d}\r\n", signalGain , trigTresh , trigDelaySet , trigPause); 00470 } // end dspParamPacket 00471 00472 // DSP Filter Packet Handler 00473 void dspFilterPacket(void) 00474 { 00475 // get values. 00476 FilterSections = (guiCmd["Sections"].get<int>()); 00477 Gscale = ((float)(guiCmd["Gscale"].get<int>()))/10000.0f; // issue in parsing doubles 00478 00479 // get SOSMat 00480 for (int jj=0 ; jj < FilterSections ; jj++) { 00481 for (int ii=0 ; ii < 6 ; ii++) { 00482 SOSMat[jj][ii] = ((float)guiCmd["SOSMat"][ii+jj*6].get<int>())/10000.0f; 00483 } 00484 } 00485 #ifdef DEBUG_MOD10 00486 // send parsed values 00487 pc.printf("FilterSections: %d , Gscale: %.3f\r\n", FilterSections , Gscale); 00488 pc.printf("SOSMat \r\n"); 00489 for (int jj=0 ; jj < FilterSections ; jj++) { 00490 pc.printf("%.3f , %.3f , %.3f , %.3f , %.3f , %.3f \r\n",SOSMat[jj][0] ,SOSMat[jj][1],SOSMat[jj][2],SOSMat[jj][3] ,SOSMat[jj][4] ,SOSMat[jj][5]); 00491 } 00492 #endif 00493 // succesfull parse 00494 switch_dsp.printf("{\"Ack\":\"dspFilter\",\"FilterSections\":%d,\"Gscale\":%.3f}\r\n", FilterSections , Gscale); 00495 } // end dspFilterPacket 00496 00497 // DSP Play Packet Handler 00498 void dspPlayPacket(void) 00499 { 00500 // get values. 00501 float playGain = ((float)guiCmd["gain"].get<int>())/1000; // issue in parsing doubles when the number is round 00502 uint32_t playFile = (uint32_t)guiCmd["file"].get<int>(); // file to play 00503 00504 // succesfull parse 00505 switch_dsp.printf("{\"Ack\":\"dspPlay\",\"file\":%d,\"gain\":%.3f}\r\n", playFile, playGain); 00506 ////////////////////////////////////////////////////////////////// 00507 // Temp mode - need to update file selection , gain settings // 00508 ////////////////////////////////////////////////////////////////// 00509 __disable_irq(); // Disable Interrupts 00510 // generate chirp out 00511 for (int ii=0; ii<NUM_SAMPLES; ii++) { 00512 // toogle io for loop frequency 00513 toggelState=!toggelState; 00514 mytoggle.write(toggelState); 00515 // generate delay for 1MHz Sample rate 00516 for (int jj=0; jj<31; jj++) { 00517 NOP(); 00518 } 00519 // micro nops :) 00520 NOP(); 00521 NOP(); 00522 NOP(); 00523 NOP(); 00524 NOP(); 00525 NOP(); 00526 NOP(); 00527 // Output value using DAC 00528 // HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValueOut); 00529 *(__IO uint32_t *) Dac_Reg = chirpData[ii]; 00530 } 00531 // Output value using DAC 00532 // HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, ADCValueOut); 00533 *(__IO uint32_t *) Dac_Reg = (uint16_t)(4095/2); 00534 __enable_irq(); // Enable Interrupts 00535 00536 // Option to reset play mode after file has been played 00537 //operationMode = 0; 00538 } // end dspPlayPacket
Generated on Fri Jul 22 2022 10:49:57 by
1.7.2