ReSpeaker Switch V02
Dependencies: mbed MbedJSONValue
main.cpp
- Committer:
- Arkadi
- Date:
- 2018-07-12
- Revision:
- 8:5f6b8bffe9b9
- Parent:
- 7:9153b6566524
- Child:
- 9:e893fa820315
File content as of revision 8:5f6b8bffe9b9:
//////////////////////////////////////// // Tau_ReSpeaker_Sitch_V01 // // Arkadiraf@gmail.com - 12/06/2018 // //////////////////////////////////////// /* json format: json:{"name":"auto"} - automatic mode Json Format: json:{"name":"switch","mic":0, "spk": [0,1,0,0,0]} - manual mode */ /* Bugs: PA_14 and PA_13 are share with stlink - not available as interrupt pins Used in polling mode instead didnt switch to spk 5 - changed spk limits in auto switch perhaps this was the issue. */ /* Board : Nucleo STM32F446RE Power Source : USB || Jumper 5V source from STM32 DSP board */ /* Nucleo board modification: to use PH_0(MUX_S2) as IO modify boards as followed: SB54 and SB55 ON SB16 and SB50 (MCO) OFF For use GPIO PC15 , PC14 SB48 and SB49 ON R34 and R36 removed 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 */ /* Pinout: PC - Serial 2 PA_2 (Tx) --> STLINK PA_3 (Rx) --> STLINK Switch - Serial 3 PC_10 (Tx) --> SW_Rx PC_11 (Rx) --> SW_Tx I2C_Bus PB_8 --> SCL PB_9 --> SDA Digital output : PA_5 --> led (DigitalOut) PA_10 --> SW_Trigger MUX: CD74HC4067 PC_12 --> MUX_S0 PD_2 --> MUX_S1 PH_0 --> MUX_S2 PH_1 --> MUX_S3 Speaker Switch : SN74LVC1G3157 PB_2 --> EN_SPK_1 PB_1 --> EN_SPK_2 PB_15 --> EN_SPK_3 PB_14 --> EN_SPK_4 PB_13 --> EN_SPK_5 MIC Interrupts: PC_15 --> INTER_1 PC_14 --> INTER_2 PA_15 --> INTER_3 PA_14 --> INTER_4 PA_13 --> INTER_5 Digital Input PC_13 --> BTN (Blue) Analog Input PA_0 --> A_DATA_1 PA_1 --> A_DATA_2 PA_4 --> A_DATA_3 PB_0 --> A_DATA_4 PC_1 --> A_DATA_5 Analog Output */ /////////////// // Libraries // /////////////// #include "mbed.h" #include "MbedJSONValue.h" //#include <string> /////////////// // #defines // /////////////// //#define DEBUG_MOD1 // json packet recognise //#define DEBUG_MOD2 // json parse //#define DEBUG_MOD3 // switch handler //#define DEBUG_MOD4 // serial with dsp module //#define DEBUG_MOD10 // responsivity msges to gui bool debuggingEn = 0; #define MSG_BUFFER_SIZE 512 #define HEADER_SIZE 5 #define FOOTER_SIZE 2 ///////////// // Objects // ///////////// // Time stamp timer Timer timeStamp; // json MbedJSONValue guiCmd; // uart Serial pc(USBTX, USBRX); // uart switch_dsp Serial dsp(PC_10, PC_11); // digital input DigitalIn user_button(PC_13); // digital output DigitalOut led(PA_5); DigitalOut sw_trigger(PA_10); // MUX: CD74HC4067 DigitalOut mux_s0(PC_12); DigitalOut mux_s1(PD_2); DigitalOut mux_s2(PH_0); DigitalOut mux_s3(PH_1); // speaker switch DigitalOut en_spk_1(PB_2); DigitalOut en_spk_2(PB_1); DigitalOut en_spk_3(PB_15); DigitalOut en_spk_4(PB_14); DigitalOut en_spk_5(PB_13); // MIC interrupts DigitalIn inter_1(PC_15 , PullDown); DigitalIn inter_2(PC_14 , PullDown); DigitalIn inter_3(PA_15 , PullDown); DigitalIn inter_4(PA_14 , PullDown); DigitalIn inter_5(PA_13 , PullDown); // analog input AnalogIn a_data_1(PA_0); AnalogIn a_data_2(PA_1); AnalogIn a_data_3(PA_4); AnalogIn a_data_4(PB_0); AnalogIn a_data_5(PC_1); /////////////// // variables // /////////////// // analog input from microphone uint16_t micAData[5]= {0}; // mic interrupt flag int micInterrupt = 0; bool autoFlag = 0; // automatic mode flag // json buffer char json[MSG_BUFFER_SIZE]; // packet variables struct packetMSG_struct { // recieve message variables uint8_t header[HEADER_SIZE]; uint8_t footer[FOOTER_SIZE]; uint8_t syncIndex; // sync index for header / footer uint8_t syncFlag; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer // buffer uint16_t bufferIndex; // buffer index uint8_t buffer[MSG_BUFFER_SIZE]; } ; packetMSG_struct packetMSG; /////////////// // Functions // /////////////// // mic interrupt functions - not used, Polling mode //void micInt_1() //{ // micInterrupt = 1; //} //void micInt_2() //{ // micInterrupt = 2; //} //void micInt_3() //{ // micInterrupt = 3; //} //void micInt_4() //{ // micInterrupt = 4; //} //void micInt_5() //{ // micInterrupt = 5; //} // Serial Event function void rxCallback(void); // serial event from DSP void rxDspCallback(void); // initialize packet struct void initPacket(void); // Packet Parser void parsePacket(void); // switch Packet Handler void switchPacket(void); // initialize switch void initSwitch(void); // poll mic interrupt gpio bool micPolling(void); // Atuomatic Switch Handler void autoSwitch(int micEvent); //////////////////////// // Main Code Setup : // //////////////////////// int main() { // init packet: initPacket(); // init uart pc.baud(57600); dsp.baud(57600); // attach serial event interrupt pc.attach(&rxCallback, Serial::RxIrq); // attach serial event interrupt dsp.attach(&rxDspCallback, Serial::RxIrq); // initialize switch initSwitch(); #ifdef DEBUG_MOD1 pc.printf("ReSpeaker Test \r\n"); #endif /////////////////////// // Main Code Loop : // /////////////////////// while(1) { // GPIO polling for mic events if(0) { // no analog data to read (not implemented yet micAData[0] = a_data_1.read_u16(); micAData[1] = a_data_2.read_u16(); micAData[2] = a_data_3.read_u16(); micAData[3] = a_data_4.read_u16(); micAData[4] = a_data_5.read_u16(); pc.printf("Data:%d,%d,%d,%d,%d\r\n",micAData[0],micAData[1],micAData[2],micAData[3],micAData[4]); wait(1); } // change to interrupt - Problematic as PA_14 and PA_13 are share with stlink if (micPolling()) { // simple polling of interrupt signals if (autoFlag) { // update switch based on automatic selection autoSwitch(micInterrupt); } if (1) { // send to pc event time float callTime = timeStamp.read(); //pc.printf("IntMic: %d time: %.3f \r\n",micInterrupt,callTime); // Printf generates delay of about 5 millis // send json formatted pc.printf("{\"event\":\"micInt\",\"mic\":%d,\"time\":%.3f}\r\n",micInterrupt,callTime); // Printf generates delay of about 5 millis // led blink led = !led; //wait(0.1); // reset micInterrupt flag micInterrupt=0; } } }// end main loop }// end main /////////////// // Functions // /////////////// // Atuomatic Switch Handler void autoSwitch(int micEvent) { int micChannle = 0; bool spkChannle[5]= {0}; // speaker selection: // simple selection mode micChannle = micEvent; if ((micChannle >= 1) && (micChannle <= 5)) {// verify mic is in the limit spkChannle[micChannle-1] = 1; } // update hardware // update mic select mux uint8_t micByte = (uint8_t) micChannle; mux_s0.write((bool)(micByte & 0b00000001)); mux_s1.write((bool)(micByte & 0b00000010)); mux_s2.write((bool)(micByte & 0b00000100)); mux_s3.write((bool)(micByte & 0b00001000)); // update speakers: en_spk_1.write(spkChannle[0]); en_spk_2.write(spkChannle[1]); en_spk_3.write(spkChannle[2]); en_spk_4.write(spkChannle[3]); en_spk_5.write(spkChannle[4]); // send updated values json formatted 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 }// end autoSwitch // initialize switch void initSwitch(void) { // attach serial event interrupt pc.attach(&rxCallback, Serial::RxIrq); // initialize timer timeStamp.start(); // attach mic interrupts - Not used, polling mode //inter_1.rise(&micInt_1); //inter_2.rise(&micInt_2); //inter_3.rise(&micInt_3); //inter_4.rise(&micInt_4); //inter_5.rise(&micInt_5); // reset output / input mux_s0.write(0); mux_s1.write(0); mux_s2.write(0); mux_s3.write(0); en_spk_1.write(0); en_spk_2.write(0); en_spk_3.write(0); en_spk_4.write(0); en_spk_5.write(0); }// end init switch // poll mic interrupt gpio bool micPolling(void) { bool eventFlag=0; // implementation of rising interrupt in polling mode: if (inter_1.read() && (micInterrupt != 1)) { eventFlag=1; micInterrupt=1; } if (inter_2.read() && (micInterrupt != 2)) { eventFlag=1; micInterrupt=2; } if (inter_3.read() && (micInterrupt != 3)) { eventFlag=1; micInterrupt=3; } if (inter_4.read() && (micInterrupt != 4)) { eventFlag=1; micInterrupt=4; } if (inter_5.read() && (micInterrupt != 5)) { eventFlag=1; micInterrupt=5; } return eventFlag; } // serial event from DSP void rxDspCallback(void) { while (dsp.readable()) { uint8_t in_byte = dsp.getc(); #ifdef DEBUG_MOD4 pc.putc(in_byte); #endif } } // end rxDspCallback // Serial Event function void rxCallback(void) { while (pc.readable()) { // read icoming //led = !led; uint8_t in_byte = pc.getc(); #ifdef DEBUG_MOD1 pc.putc(in_byte); #endif // detect start message , end message switch (packetMSG.syncFlag) { // waiting for header case 0: { if (packetMSG.header[packetMSG.syncIndex] == in_byte) { packetMSG.syncIndex++; if (packetMSG.syncIndex == HEADER_SIZE) { // finish header SYNC packetMSG.syncFlag = 1; // start collecting data, wait for footer packetMSG.bufferIndex = 0; packetMSG.syncIndex=0; } } else { // reinit sync packetMSG.syncIndex=0; } //pc.printf("case 0 , %d \r\n",packetMSG.syncIndex); break; } // waiting for footer case 1: { // add byte to buffer packetMSG.buffer[packetMSG.bufferIndex] = in_byte; packetMSG.bufferIndex++; if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow // reset buffer packetMSG.bufferIndex = 0; packetMSG.syncIndex = 0; packetMSG.syncFlag = 0; } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved packetMSG.syncIndex++; packetMSG.syncFlag=2; // move to verify footer } //pc.printf("case 2 , %d \r\n",packetMSG.syncIndex); break; } // verify footer case 2: { // add byte to buffer packetMSG.buffer[packetMSG.bufferIndex] = in_byte; packetMSG.bufferIndex++; if (packetMSG.bufferIndex >= MSG_BUFFER_SIZE) { // buffer overflow // reset buffer packetMSG.bufferIndex = 0; packetMSG.syncIndex = 0; packetMSG.syncFlag = 0; } else if (packetMSG.footer[packetMSG.syncIndex] == in_byte) { // footer char recieved packetMSG.syncIndex++; if (packetMSG.syncIndex == FOOTER_SIZE) { // finish footer SYNC packetMSG.syncFlag = 3; // copy packet to json buffer memcpy (&json, &packetMSG.buffer, packetMSG.bufferIndex); json[packetMSG.bufferIndex]=NULL; // end with NULL to indicate end of string // copy packet to json buffer with sprintf //sprintf(json, "%.*s", packetMSG.bufferIndex, packetMSG.buffer ); // send msg to parse. parsePacket(); // reset buffer packetMSG.bufferIndex = 0; packetMSG.syncIndex = 0; packetMSG.syncFlag = 0; } } else { // footer broke restart wait for footer packetMSG.syncFlag=1; // verify that it didnt broke on first footer char if (packetMSG.footer[0] == in_byte) { packetMSG.syncIndex=1; } else { packetMSG.syncIndex=0; } } break; } default: { pc.printf("Sonmething went wrong \r\n"); break; } } // end switch }// end uart readable } // end rxCallback // initialize packet struct void initPacket(void) { // init variables to default: packetMSG.header[0] = 'j'; packetMSG.header[1] = 's'; packetMSG.header[2] = 'o'; packetMSG.header[3] = 'n'; packetMSG.header[4] = ':'; packetMSG.footer[0]= 13; // /r packetMSG.footer[1]= 10; // /n packetMSG.syncIndex=0; // sync index for header / footer packetMSG.syncFlag=0; // 0 - waiting for header, 1 - waiting for footer, 2 - verify footer, 3 - finish footer send to parser, flash buffer packetMSG.bufferIndex=0; // buffer index } // Packet Parser void parsePacket(void) { string targetName; #ifdef DEBUG_MOD2 // write buffer to screen //pc.printf("%d, %.*s", packetMSG.bufferIndex ,packetMSG.bufferIndex, packetMSG.buffer ); pc.printf("%s", json); #endif // GUI message format Switch: {"name":"switch","mic":0, "spk": [0,1,0,0,0]} parse(guiCmd, json); if (debuggingEn){ pc.printf("%s", json); } // get target: targetName = guiCmd["name"].get<string>(); // switch / dsp #ifdef DEBUG_MOD2 // send parsed values pc.printf("targetName: %s \r\n", targetName.c_str()); #endif // select handler based on target mcu if (targetName == "switch") { // disable automatic mode autoFlag=0; // update controls switchPacket(); } else if (targetName == "dsp") { // send msg to dsp dsp.printf("json:%s", json); #ifdef DEBUG_MOD2 pc.printf("json:%s", json); #endif } if (targetName == "auto") { // automatic mode autoFlag=1; } else { #ifdef DEBUG_MOD2 // unrecognised target pc.printf("unrecognised target: %s \r\n", targetName.c_str()); #endif } // led blink led = !led; }// end parse // switch Packet Handler void switchPacket(void) { int micChannle = 0; bool spkChannle[5]= {0}; // get debbug status debuggingEn = guiCmd["debug"].get<int>(); // get mic channle micChannle = guiCmd["mic"].get<int>(); // get speakers output for (int ii=0 ; ii < 5 ; ii++) { spkChannle[ii] = guiCmd["spk"][ii].get<bool>(); } #ifdef DEBUG_MOD10 // send parsed values pc.printf("mic: %d , spk: [%d,%d,%d,%d,%d]\r\n", micChannle,spkChannle[0],spkChannle[1],spkChannle[2],spkChannle[3],spkChannle[4]); #endif // update hardware // update mic select mux uint8_t micByte = (uint8_t) micChannle; mux_s0.write((bool)(micByte & 0b00000001)); mux_s1.write((bool)(micByte & 0b00000010)); mux_s2.write((bool)(micByte & 0b00000100)); mux_s3.write((bool)(micByte & 0b00001000)); // update speakers: en_spk_1.write(spkChannle[0]); en_spk_2.write(spkChannle[1]); en_spk_3.write(spkChannle[2]); en_spk_4.write(spkChannle[3]); en_spk_5.write(spkChannle[4]); // end switch target parse }// end switch packet