Arkadi Rafalovich / Mbed 2 deprecated TAU_ReSpeaker_Switch_V02

Dependencies:   mbed MbedJSONValue

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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