//====================================================================== // ubitx_iop.ino //====================================================================== #include #include "ubitx_iop.h" #include #define BOUNCE_WITH_PROMPT_DETECTION RigMode rigMode = MODE_SSB; IOPConfig iopConfig; #define MIC_PTT_PIN 21 #define LINE_PTT_PIN 20 #define PTT_KEY_OUT_PIN 2 Bounce micPTT = Bounce(); Bounce linePTT = Bounce(); TxState txState = TX_OFF; Keyer keyer(15, 3.0); // need to make configurable //SSBMenu ssbMenu(); //DigiMenu digiMenu(); //CWMenu cwMenu(); //MenuItem* dspMenu = &ssbMenu; //====================================================================== // catPTTOn() // // NOTE: Should probably move this to cat.ino. //====================================================================== void catPTTOn() { // Check if we're already transmitting. If so, then this command // does nothing: existing transmission, from existing source and PTT, // will continue. if (txState != TX_OFF) return; switch(rigMode) { // CAT should not start or stop TX in CW mode... we really should // not even get this command. But maybe the rig control software is // doing it (but then, we should inhibit this in the Raduino). //case MODE_CW: //break; case MODE_SSB: // In SSB mode, CAT-PTT will always (de-)activate the Line-In TX // audio source. txState = TX_CAT; audioSelectTxInput(TX_LINE_IN); // in case Mic-In is selected audioTransmit(); digitalWrite(PTT_KEY_OUT_PIN, LOW); break; case MODE_DIGI: // In Digital (USB) mode, CAT-PTT will always (de-)activate the // USB-In TX audio source. txState = TX_CAT; audioTransmit(); digitalWrite(PTT_KEY_OUT_PIN, LOW); break; } } //====================================================================== // catPTTOff() // // NOTE: Should probably move this to cat.ino. //====================================================================== void catPTTOff() { // If we're not transmitting, or the active PTT is not CAT, then this // command does nothing: CAT cannot interrupt other transmissions. if (txState != TX_CAT) return; switch(rigMode) { // CAT should not start or stop TX in CW mode... we really should // not even get this command. But maybe the rig control software is // doing it (but then, we should inhibit this in the Raduino). //case MODE_CW: //break; case MODE_SSB: // In SSB mode, CAT-PTT will always (de-)activate the Line-In TX // audio source. digitalWrite(PTT_KEY_OUT_PIN, HIGH); audioReceive(); txState = TX_OFF; break; case MODE_DIGI: // In Digital (USB) mode, CAT-PTT will always (de-)activate the // USB-In TX audio source. digitalWrite(PTT_KEY_OUT_PIN, HIGH); audioReceive(); txState = TX_OFF; break; } } //====================================================================== // checkMicPTT() //====================================================================== void checkMicPTT() { micPTT.update(); // If we're transmitting, then we're just going to check if Mic-PTT // was released--the Mic-PTT can always be used to terminate a // transmission from another source. if ((txState != TX_OFF) && micPTT.rose()) { #if defined(DEBUG) USBSERIAL.println("DEBUG: mic PTT released"); #endif digitalWrite(PTT_KEY_OUT_PIN, HIGH); // In CW mode, we get a sidetone from the uBITX, so we don't mute // the receive audio. if (rigMode != MODE_CW) audioReceive(); txState = TX_OFF; return; } if ((txState == TX_OFF) && micPTT.fell()) { #if defined(DEBUG) USBSERIAL.println("DEBUG: mic PTT depressed"); #endif switch(rigMode) { case MODE_CW: txState = TX_MIC; digitalWrite(PTT_KEY_OUT_PIN, LOW); break; case MODE_SSB: txState = TX_MIC; audioSelectTxInput(TX_MIC_IN); audioTransmit(); digitalWrite(PTT_KEY_OUT_PIN, LOW); break; case MODE_DIGI: // Mic PTT actuation during Digital does nothing. break; case MODE_TEST: txState = TX_MIC; audioSelectTxInput(TX_TEST_IN); audioTransmit(); digitalWrite(PTT_KEY_OUT_PIN, LOW); break; } } } //====================================================================== // checkLinePTT() //====================================================================== void checkLinePTT() { linePTT.update(); // If we're transmitting, then we're just going to check if Line-PTT // was released--the Line-PTT can always be used to terminate a // transmission from another source. if ((txState != TX_OFF) && linePTT.rose()) { digitalWrite(PTT_KEY_OUT_PIN, HIGH); // In CW mode, we get a sidetone from the uBITX, so we don't mute // the receive audio. if (rigMode != MODE_CW) audioReceive(); txState = TX_OFF; return; } if ((txState == TX_OFF) && linePTT.fell()) { switch(rigMode) { case MODE_CW: txState = TX_LINE; digitalWrite(PTT_KEY_OUT_PIN, LOW); break; case MODE_SSB: txState = TX_LINE; audioSelectTxInput(TX_LINE_IN); audioTransmit(); digitalWrite(PTT_KEY_OUT_PIN, LOW); break; case MODE_DIGI: // Line PTT actuation during Digital does nothing. break; case MODE_TEST: txState = TX_LINE; audioSelectTxInput(TX_TEST_IN); audioTransmit(); digitalWrite(PTT_KEY_OUT_PIN, LOW); break; } } } //====================================================================== void setRigMode(RigMode m) { rigMode = m; switch(rigMode) { case MODE_SSB: case MODE_TEST: // SSB sets the TX audio input to line-in. Note that this will be // automatically overridden by mic-in, if the mic PTT is pressed. audioSelectTxInput(TX_LINE_IN); audioSSBFilter(); // dspMenu = &ssbMenu; break; case MODE_DIGI: // Digi sets the TX audio input to USB-in. Keying in this case must // be via CAT control. Digital modes can also be used through the // line-in, but the rig mode should be set to SSB in that case, and // the rig could be keyed either via the line-in PTT, or via CAT. // Digimodes could also be used through the mic-in, but in that case, // the mic PTT line would need to be keyed by the computer rather // than using CAT for PTT control. audioSelectTxInput(TX_USB_IN); audioDigiFilter(); // dspMenu = &digiMenu; break; case MODE_CW: // CW just gets the radio off of Mic-In; but it won't use Line-In. audioSelectTxInput(TX_LINE_IN); audioCWFilter(); // dspMenu = &cwMenu; break; } } //====================================================================== void setup() { // put your setup code here, to run once: initCAT(38400, SERIAL_8N1); AudioMemory(12); micPTT.attach(MIC_PTT_PIN, INPUT_PULLUP); micPTT.interval(25); linePTT.attach(LINE_PTT_PIN, INPUT_PULLUP); linePTT.interval(25); pinMode(PTT_KEY_OUT_PIN, OUTPUT); digitalWrite(PTT_KEY_OUT_PIN, HIGH); audioInit(); #if defined(FACTORY_CALIBRATION) setRigMode(MODE_TEST); #else setRigMode(MODE_SSB); #endif } //====================================================================== void loop() { elapsedMillis elapsed = 0; switch(rigMode) { case MODE_CW: if (keyer.do_paddles()) { if (keyer.is_down()) { digitalWrite(PTT_KEY_OUT_PIN, LOW); } else { digitalWrite(PTT_KEY_OUT_PIN, HIGH); } // No break... if the paddle is not active, I want this to fall // through to checkMicPTT etc... but return early if the paddle is // active, to maximize responsiveness. Probably could just use // 'if' statements here instead of the 'switch'. return; } default: checkMicPTT(); checkLinePTT(); serviceCAT(); } //dspMenu->update(); /* #if defined(DEBUG) int frame_skews = 0; // for debugging; see how often we skew frames #endif // put your main code here, to run repeatedly: // Run at a nominal 20 Hz frame rate. #if defined(DEBUG) if (frame_timer > 50) { frame_skews += 1; } #endif while (frame_timer < 50) { // this doesn't seem like a good way to do this } */ } //====================================================================== // EOF //======================================================================