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_Sitch_V02 // 00003 // Arkadiraf@gmail.com - 08/06/2019 // 00004 //////////////////////////////////////// 00005 /* 00006 json format: json:{"name":"auto"} - automatic mode 00007 Json Format: json:{"name":"switch","mic":0, "spk": [0,1,0,0,0]} - manual mode 00008 */ 00009 00010 /* 00011 Board : Nucleo STM32F446RE 00012 Power Source : DC-DC 5V Regulator E5V Jumper 00013 */ 00014 00015 /* 00016 Nucleo board modification: 00017 XBee UART Shield 00018 SB13 , SB14 Off 00019 SB62 , SB63 On 00020 00021 to use PH_0 / PH_1 (MUX_S2/S3) as IO modify boards as followed: 00022 SB54 and SB55 ON 00023 SB16 and SB50 (MCO) OFF 00024 http://www.st.com/content/ccc/resource/technical/document/user_manual/98/2e/fa/4b/e0/82/43/b7/DM00105823.pdf/files/DM00105823.pdf/jcr:content/translations/en.DM00105823.pdf 00025 */ 00026 00027 /* 00028 Pinout: 00029 PC - Serial 2 00030 PA_2 (Tx) --> STLINK 00031 PA_3 (Rx) --> STLINK 00032 00033 Switch - Serial 3 00034 PC_10 (Tx) --> SW_Rx 00035 PC_11 (Rx) --> SW_Tx 00036 00037 Digital output : 00038 PA_5 --> led 00039 PC_8 --> led1 00040 PC_6 --> led2 00041 PA_15 --> TRIG 00042 00043 00044 MUX: CD74HC4067 00045 PC_12 --> MUX_S0 00046 PD_2 --> MUX_S1 00047 PH_0 --> MUX_S2 00048 PH_1 --> MUX_S3 00049 00050 Speaker Switch : SN74LVC1G3157 00051 PB_2 --> EN_SPK_1 00052 PB_1 --> EN_SPK_2 00053 PB_15 --> EN_SPK_3 00054 PB_14 --> EN_SPK_4 00055 PB_13 --> EN_SPK_5 00056 00057 DSP Interrupt 00058 PA_10 --> DSP_Trigger 00059 00060 MIC Interrupts: 00061 PA_6 --> INTER_1 00062 PA_7 --> INTER_2 00063 PB_6 --> INTER_3 00064 PC_7 --> INTER_4 00065 PA_9 --> INTER_5 00066 00067 Digital Input 00068 PC_13 --> BTN (Blue) 00069 00070 Analog Input 00071 PA_0 --> A_DATA_1 00072 PA_1 --> A_DATA_2 00073 PA_4 --> A_DATA_3 00074 PB_0 --> A_DATA_4 00075 PC_1 --> A_DATA_5 00076 00077 Analog Output 00078 00079 00080 */ 00081 00082 /////////////// 00083 // Libraries // 00084 /////////////// 00085 #include "mbed.h" 00086 #include "MbedJSONValue.h" 00087 //#include <string> 00088 00089 /////////////// 00090 // #defines // 00091 /////////////// 00092 00093 //#define DEBUG_MOD1 // json packet recognise 00094 //#define DEBUG_MOD2 // json parse 00095 //#define DEBUG_MOD3 // switch handler 00096 //#define DEBUG_MOD4 // serial with dsp module 00097 //#define DEBUG_MOD10 // responsivity msges to gui 00098 bool debuggingEn = 0; 00099 00100 #define MSG_BUFFER_SIZE 1024 00101 #define HEADER_SIZE 5 00102 #define FOOTER_SIZE 2 00103 00104 #define TICKS2TOGGLE 1000000 00105 ///////////// 00106 // Objects // 00107 ///////////// 00108 00109 // Time stamp timer 00110 Timer timeStamp; 00111 00112 // Frequency Counter timer 00113 Timer freqTimer; 00114 00115 // json 00116 MbedJSONValue guiCmd; 00117 00118 // uart 00119 Serial pc(USBTX, USBRX); 00120 00121 // uart switch_dsp 00122 Serial dsp(PC_10, PC_11); 00123 00124 // digital input 00125 DigitalIn user_button(PC_13); 00126 00127 // digital output 00128 DigitalOut led(PA_5); 00129 DigitalOut led1(PC_8); 00130 DigitalOut led2(PC_6); 00131 DigitalOut trigger(PA_15); 00132 00133 // interrup from dsp mcu (frequency counter) 00134 InterruptIn dsp_trigger(PA_10); 00135 00136 // MUX: CD74HC4067 00137 DigitalOut mux_s0(PC_12); 00138 DigitalOut mux_s1(PD_2); 00139 DigitalOut mux_s2(PH_0); 00140 DigitalOut mux_s3(PH_1); 00141 00142 // speaker switch 00143 DigitalOut en_spk_1(PB_2); 00144 DigitalOut en_spk_2(PB_1); 00145 DigitalOut en_spk_3(PB_15); 00146 DigitalOut en_spk_4(PB_14); 00147 DigitalOut en_spk_5(PB_13); 00148 00149 // MIC interrupts 00150 DigitalIn inter_1(PA_6, PullDown); 00151 DigitalIn inter_2(PA_7, PullDown); 00152 DigitalIn inter_3(PB_6, PullDown); 00153 DigitalIn inter_4(PC_7, PullDown); 00154 DigitalIn inter_5(PA_9, PullDown); 00155 00156 // analog input 00157 AnalogIn a_data_1(PA_0); 00158 AnalogIn a_data_2(PA_1); 00159 AnalogIn a_data_3(PA_4); 00160 AnalogIn a_data_4(PB_0); 00161 AnalogIn a_data_5(PC_1); 00162 00163 /////////////// 00164 // variables // 00165 /////////////// 00166 // analog input from microphone 00167 uint16_t micAData[5]= {0}; 00168 00169 // mic interrupt flag 00170 int micInterrupt = 0; 00171 bool autoFlag = 0; // automatic mode flag 00172 00173 // json buffer 00174 char json[MSG_BUFFER_SIZE]; 00175 00176 // packet variables 00177 struct packetMSG_struct { 00178 // recieve message variables 00179 uint8_t header[HEADER_SIZE]; 00180 uint8_t footer[FOOTER_SIZE]; 00181 uint8_t syncIndex; // sync index for header / footer 00182 uint8_t syncFlag; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer 00183 // buffer 00184 uint16_t bufferIndex; // buffer index 00185 uint8_t buffer[MSG_BUFFER_SIZE]; 00186 } ; 00187 packetMSG_struct packetMSG; 00188 00189 00190 // Frequency calculator 00191 volatile int freqTimeInterval = 0; 00192 volatile bool dspIntFlag = 0; 00193 volatile bool loopFreqFlag = 0; 00194 /////////////// 00195 // Functions // 00196 /////////////// 00197 00198 // mic interrupt functions - not used, Polling mode 00199 //void micInt_1() 00200 //{ 00201 // micInterrupt = 1; 00202 //} 00203 //void micInt_2() 00204 //{ 00205 // micInterrupt = 2; 00206 //} 00207 //void micInt_3() 00208 //{ 00209 // micInterrupt = 3; 00210 //} 00211 //void micInt_4() 00212 //{ 00213 // micInterrupt = 4; 00214 //} 00215 //void micInt_5() 00216 //{ 00217 // micInterrupt = 5; 00218 //} 00219 // Serial Event function 00220 void rxCallback(void); 00221 00222 // serial event from DSP 00223 void rxDspCallback(void); 00224 00225 // initialize packet struct 00226 void initPacket(void); 00227 00228 // Packet Parser 00229 void parsePacket(void); 00230 00231 // switch Packet Handler 00232 void switchPacket(void); 00233 00234 // initialize switch 00235 void initSwitch(void); 00236 00237 // poll mic interrupt gpio 00238 bool micPolling(void); 00239 00240 // Atuomatic Switch Handler 00241 void autoSwitch(int micEvent); 00242 00243 // interrup event from the dsp (frequency counter) 00244 void dspInterrupt(); 00245 00246 //////////////////////// 00247 // Main Code Setup : // 00248 //////////////////////// 00249 int main() 00250 { 00251 // init packet: 00252 initPacket(); 00253 // init uart 00254 pc.baud(57600); 00255 dsp.baud(57600); 00256 // attach serial event interrupt 00257 pc.attach(&rxCallback, Serial::RxIrq); 00258 00259 // attach serial event interrupt 00260 dsp.attach(&rxDspCallback, Serial::RxIrq); 00261 00262 // initialize switch 00263 initSwitch(); 00264 #ifdef DEBUG_MOD1 00265 pc.printf("ReSpeaker Test \r\n"); 00266 #endif 00267 /////////////////////// 00268 // Main Code Loop : // 00269 /////////////////////// 00270 while(1) { // GPIO polling for mic events 00271 // frquency counter 00272 if (dspIntFlag) { 00273 double calculatedFrequencyDouble = (double) (TICKS2TOGGLE * 2.0 ) / freqTimeInterval; // Calculated in MHz 00274 int calculatedFrequency = (int) (calculatedFrequencyDouble * 1000000); // convert to hz 00275 if ((calculatedFrequency < 10000000) && loopFreqFlag) { // cannot be larger, update when requested 00276 pc.printf("{\"event\":\"dspFreq\",\"Freq\":%d}\r\n",calculatedFrequency); // Printf 00277 } 00278 dspIntFlag=0; 00279 } 00280 if(0) { // no analog data to read (not implemented yet 00281 micAData[0] = a_data_1.read_u16(); 00282 micAData[1] = a_data_2.read_u16(); 00283 micAData[2] = a_data_3.read_u16(); 00284 micAData[3] = a_data_4.read_u16(); 00285 micAData[4] = a_data_5.read_u16(); 00286 pc.printf("Data:%d,%d,%d,%d,%d\r\n",micAData[0],micAData[1],micAData[2],micAData[3],micAData[4]); 00287 wait(1); 00288 } 00289 // change to interrupt - Problematic as PA_14 and PA_13 are share with stlink 00290 if (micPolling()) { // simple polling of interrupt signals 00291 if (autoFlag) { // update switch based on automatic selection 00292 autoSwitch(micInterrupt); 00293 } 00294 00295 if (1) { // send to pc event time 00296 float callTime = timeStamp.read(); 00297 //pc.printf("IntMic: %d time: %.3f \r\n",micInterrupt,callTime); // Printf generates delay of about 5 millis 00298 // send json formatted 00299 pc.printf("{\"event\":\"micInt\",\"mic\":%d,\"time\":%.3f}\r\n",micInterrupt,callTime); // Printf generates delay of about 5 millis 00300 00301 // led blink 00302 led2 = !led2; 00303 //wait(0.1); 00304 } 00305 // reset micInterrupt flag 00306 trigger = 0; // pull trigger down 00307 micInterrupt=0; 00308 } 00309 }// end main loop 00310 }// end main 00311 /////////////// 00312 // Functions // 00313 /////////////// 00314 00315 // Interrup event from the dsp (frequency counter) 00316 void dspInterrupt() 00317 { 00318 freqTimeInterval = freqTimer.read_us() + 1; // compensate the time takes to read / reset 00319 freqTimer.reset(); 00320 dspIntFlag = 1; 00321 }//end dspInterrupt 00322 00323 // Atuomatic Switch Handler 00324 void autoSwitch(int micEvent) 00325 { 00326 int micChannle = 0; 00327 bool spkChannle[5]= {0}; 00328 00329 // speaker selection: 00330 00331 // simple selection mode 00332 micChannle = micEvent; 00333 if ((micChannle >= 1) && (micChannle <= 5)) {// verify mic is in the limit 00334 spkChannle[micChannle-1] = 1; 00335 } 00336 00337 // update hardware 00338 // update mic select mux 00339 uint8_t micByte = (uint8_t) micChannle; 00340 // flip mic order around 3, I guess it is the stupidest implementation but hey :) tada. 00341 if (micByte != 0) { 00342 micByte = ((~(micByte + 0b00001001)) & 0b00001111); 00343 } 00344 mux_s0.write((bool)(micByte & 0b00000001)); 00345 mux_s1.write((bool)(micByte & 0b00000010)); 00346 mux_s2.write((bool)(micByte & 0b00000100)); 00347 mux_s3.write((bool)(micByte & 0b00001000)); 00348 00349 // update speakers: 00350 en_spk_1.write(spkChannle[0]); 00351 en_spk_2.write(spkChannle[1]); 00352 en_spk_3.write(spkChannle[2]); 00353 en_spk_4.write(spkChannle[3]); 00354 en_spk_5.write(spkChannle[4]); 00355 00356 // send updated values json formatted 00357 pc.printf("{\"event\":\"switch\",\"mic\":%d,\"spk\":[%d,%d,%d,%d,%d]}\r\n",micChannle,spkChannle[0],spkChannle[1],spkChannle[2],spkChannle[3],spkChannle[4]); // Printf generates delay of about 5 millis 00358 00359 }// end autoSwitch 00360 00361 // initialize switch 00362 void initSwitch(void) 00363 { 00364 // attach serial event interrupt 00365 pc.attach(&rxCallback, Serial::RxIrq); 00366 00367 // attach interrupt event for frequency counting 00368 dsp_trigger.rise(&dspInterrupt); 00369 00370 // start timer 00371 freqTimer.start(); 00372 00373 // initialize timer 00374 timeStamp.start(); 00375 00376 // attach mic interrupts - Not used, polling mode 00377 //inter_1.rise(&micInt_1); 00378 //inter_2.rise(&micInt_2); 00379 //inter_3.rise(&micInt_3); 00380 //inter_4.rise(&micInt_4); 00381 //inter_5.rise(&micInt_5); 00382 00383 // reset output / input 00384 mux_s0.write(0); 00385 mux_s1.write(0); 00386 mux_s2.write(0); 00387 mux_s3.write(0); 00388 en_spk_1.write(0); 00389 en_spk_2.write(0); 00390 en_spk_3.write(0); 00391 en_spk_4.write(0); 00392 en_spk_5.write(0); 00393 }// end init switch 00394 00395 // poll mic interrupt gpio 00396 bool micPolling(void) 00397 { 00398 bool eventFlag=0; 00399 // implementation of rising interrupt in polling mode: 00400 if (inter_1.read() && (micInterrupt != 1)) { 00401 eventFlag=1; 00402 micInterrupt=1; 00403 trigger=1; 00404 } 00405 if (inter_2.read() && (micInterrupt != 2)) { 00406 eventFlag=1; 00407 micInterrupt=2; 00408 trigger=1; 00409 } 00410 if (inter_3.read() && (micInterrupt != 3)) { 00411 eventFlag=1; 00412 micInterrupt=3; 00413 trigger=1; 00414 } 00415 if (inter_4.read() && (micInterrupt != 4)) { 00416 eventFlag=1; 00417 micInterrupt=4; 00418 trigger=1; 00419 } 00420 if (inter_5.read() && (micInterrupt != 5)) { 00421 eventFlag=1; 00422 micInterrupt=5; 00423 trigger=1; 00424 } 00425 return eventFlag; 00426 } 00427 00428 // serial event from DSP 00429 void rxDspCallback(void) 00430 { 00431 while (dsp.readable()) { 00432 uint8_t in_byte = dsp.getc(); 00433 pc.putc(in_byte); 00434 } 00435 } // end rxDspCallback 00436 00437 // Serial Event function 00438 void rxCallback(void) 00439 { 00440 while (pc.readable()) { 00441 // read icoming 00442 led = !led; 00443 uint8_t in_byte = pc.getc(); 00444 #ifdef DEBUG_MOD1 00445 pc.putc(in_byte); 00446 #endif 00447 // detect start message , end message 00448 switch (packetMSG.syncFlag) { 00449 // waiting for header 00450 case 0: { 00451 if (packetMSG.header[packetMSG.syncIndex] == in_byte) { 00452 packetMSG.syncIndex++; 00453 if (packetMSG.syncIndex == HEADER_SIZE) { // finish header SYNC 00454 packetMSG.syncFlag = 1; // start collecting data, wait for footer 00455 packetMSG.bufferIndex = 0; 00456 packetMSG.syncIndex=0; 00457 } 00458 } else { // reinit sync 00459 packetMSG.syncIndex=0; 00460 } 00461 //pc.printf("case 0 , %d \r\n",packetMSG.syncIndex); 00462 break; 00463 } 00464 // waiting for footer 00465 case 1: { 00466 // add byte to buffer 00467 packetMSG.buffer[packetMSG.bufferIndex] = in_byte; 00468 packetMSG.bufferIndex++; 00469 if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow 00470 // reset buffer 00471 packetMSG.bufferIndex = 0; 00472 packetMSG.syncIndex = 0; 00473 packetMSG.syncFlag = 0; 00474 } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved 00475 packetMSG.syncIndex++; 00476 packetMSG.syncFlag=2; // move to verify footer 00477 } 00478 //pc.printf("case 2 , %d \r\n",packetMSG.syncIndex); 00479 break; 00480 } 00481 // verify footer 00482 case 2: { 00483 // add byte to buffer 00484 packetMSG.buffer[packetMSG.bufferIndex] = in_byte; 00485 packetMSG.bufferIndex++; 00486 if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow 00487 // reset buffer 00488 packetMSG.bufferIndex = 0; 00489 packetMSG.syncIndex = 0; 00490 packetMSG.syncFlag = 0; 00491 } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved 00492 packetMSG.syncIndex++; 00493 if (packetMSG.syncIndex == FOOTER_SIZE) { // finish footer SYNC 00494 packetMSG.syncFlag = 3; 00495 // copy packet to json buffer 00496 memcpy (&json, &packetMSG.buffer, packetMSG.bufferIndex); 00497 json[packetMSG.bufferIndex]=NULL; // end with NULL to indicate end of string 00498 // copy packet to json buffer with sprintf 00499 //sprintf(json, "%.*s", packetMSG.bufferIndex, packetMSG.buffer ); 00500 // send msg to parse. 00501 parsePacket(); 00502 // reset buffer 00503 packetMSG.bufferIndex = 0; 00504 packetMSG.syncIndex = 0; 00505 packetMSG.syncFlag = 0; 00506 } 00507 } else { // footer broke restart wait for footer 00508 packetMSG.syncFlag=1; 00509 // verify that it didnt broke on first footer char 00510 if (packetMSG.footer[0] == in_byte) { 00511 packetMSG.syncIndex=1; 00512 } else { 00513 packetMSG.syncIndex=0; 00514 } 00515 } 00516 break; 00517 } 00518 default: { 00519 pc.printf("Sonmething went wrong \r\n"); 00520 break; 00521 } 00522 } // end switch 00523 }// end uart readable 00524 } // end rxCallback 00525 00526 00527 // initialize packet struct 00528 void initPacket(void) 00529 { 00530 // init variables to default: 00531 packetMSG.header[0] = 'j'; 00532 packetMSG.header[1] = 's'; 00533 packetMSG.header[2] = 'o'; 00534 packetMSG.header[3] = 'n'; 00535 packetMSG.header[4] = ':'; 00536 00537 packetMSG.footer[0]= 13; // /r 00538 packetMSG.footer[1]= 10; // /n 00539 00540 packetMSG.syncIndex=0; // sync index for header / footer 00541 packetMSG.syncFlag=0; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer 00542 packetMSG.bufferIndex=0; // buffer index 00543 } 00544 00545 // Packet Parser 00546 void parsePacket(void) 00547 { 00548 string targetName; 00549 #ifdef DEBUG_MOD2 00550 // write buffer to screen 00551 //pc.printf("%d, %.*s", packetMSG.bufferIndex ,packetMSG.bufferIndex, packetMSG.buffer ); 00552 pc.printf("%s", json); 00553 #endif 00554 // verification its a full json 00555 if ((json[0] == '{') && (json[strlen(json)-3] == '}')) { 00556 // GUI message format Switch: {"name":"switch","mic":0, "spk": [0,1,0,0,0]} 00557 parse(guiCmd, json); 00558 if (debuggingEn) { 00559 pc.printf("%s", json); 00560 } 00561 // get target: 00562 targetName = guiCmd["name"].get<string>(); // switch / dsp 00563 00564 #ifdef DEBUG_MOD2 00565 // send parsed values 00566 pc.printf("targetName: %s \r\n", targetName.c_str()); 00567 #endif 00568 00569 // select handler based on target mcu 00570 if (targetName == "switch") { 00571 // disable automatic mode 00572 autoFlag=0; 00573 // update controls 00574 switchPacket(); 00575 } else if ((targetName == "dsp") || (targetName == "dspParam") || (targetName == "dspFilter") || (targetName == "dspPlay")) { 00576 if (targetName == "dspPlay"){ 00577 // if target is to play a sound, trigger the daq to record. 00578 trigger = 1; 00579 wait(0.001); 00580 trigger = 0; 00581 } 00582 // send msg to dsp 00583 dsp.printf("json:%s", json); 00584 #ifdef DEBUG_MOD2 00585 pc.printf("json:%s", json); 00586 #endif 00587 } 00588 if (targetName == "auto") { 00589 // automatic mode 00590 autoFlag=1; 00591 pc.printf("{\"Ack\":\"switch\",\"auto\":%d}\r\n",autoFlag); // Printf 00592 } else { 00593 #ifdef DEBUG_MOD2 00594 // unrecognised target 00595 pc.printf("unrecognised target: %s \r\n", targetName.c_str()); 00596 #endif 00597 } 00598 } else { // not a full json message 00599 pc.printf("Error: %s", json); 00600 } 00601 // led blink 00602 led1 = !led1; 00603 }// end parse 00604 00605 // switch Packet Handler 00606 void switchPacket(void) 00607 { 00608 int micChannle = 0; 00609 bool spkChannle[5]= {0}; 00610 00611 // get debbug status 00612 debuggingEn = guiCmd["debug"].get<bool>(); 00613 00614 // get mic channle 00615 micChannle = guiCmd["mic"].get<int>(); 00616 00617 // get loop frequency calculator flag 00618 loopFreqFlag = guiCmd["LoopFreq"].get<bool>(); 00619 00620 // get speakers output 00621 for (int ii=0 ; ii < 5 ; ii++) { 00622 spkChannle[ii] = guiCmd["spk"][ii].get<bool>(); 00623 } 00624 #ifdef DEBUG_MOD10 00625 // send parsed values 00626 pc.printf("mic: %d , spk: [%d,%d,%d,%d,%d]\r\n", micChannle,spkChannle[0],spkChannle[1],spkChannle[2],spkChannle[3],spkChannle[4]); 00627 #endif 00628 // update hardware 00629 // update mic select mux 00630 uint8_t micByte = (uint8_t) micChannle; 00631 // flip mic order around 3, I guess it is the stupidest implementation but hey :) tada. 00632 if (micByte != 0) { 00633 micByte = ((~(micByte + 0b00001001)) & 0b00001111); 00634 } 00635 mux_s0.write((bool)(micByte & 0b00000001)); 00636 mux_s1.write((bool)(micByte & 0b00000010)); 00637 mux_s2.write((bool)(micByte & 0b00000100)); 00638 mux_s3.write((bool)(micByte & 0b00001000)); 00639 // update speakers: 00640 en_spk_1.write(spkChannle[0]); 00641 en_spk_2.write(spkChannle[1]); 00642 en_spk_3.write(spkChannle[2]); 00643 en_spk_4.write(spkChannle[3]); 00644 en_spk_5.write(spkChannle[4]); 00645 // end switch target parse 00646 pc.printf("{\"Ack\":\"switch\",\"mic\":%d,\"spk\":[%d,%d,%d,%d,%d],\"loopFreqFlag\":%d}\r\n",micChannle,spkChannle[0],spkChannle[1],spkChannle[2],spkChannle[3],spkChannle[4],loopFreqFlag); 00647 }// end switch packet
Generated on Thu Jul 21 2022 22:12:41 by
1.7.2