#include #include #include #include #include #include #include "ubitx_iop.h" #define BOUNCE_WITH_PROMPT_DETECTION // GUItool: begin automatically generated code AudioInputI2S inI2S; //xy=224,194 AudioInputUSB inUSB; //xy=224,303 AudioAnalyzeRMS rmsRX; //xy=399,71 AudioAnalyzePeak peakRX; //xy=403,122 AudioMixer4 mixRX; //xy=460,187 AudioMixer4 mixTX; //xy=460,303 AudioAmplifier ampTX; //xy=601,302 AudioAmplifier ampRX; //xy=602,176 AudioAnalyzeRMS rmsTX; //xy=788,424 AudioAnalyzePeak peakTX; //xy=789,378 AudioOutputAnalog outDAC; //xy=836,110 AudioOutputI2S outI2S; //xy=836,183 AudioOutputUSB outUSB; //xy=836,300 AudioConnection patchCord1(inI2S, 0, rmsRX, 0); AudioConnection patchCord2(inI2S, 0, peakRX, 0); AudioConnection patchCord3(inI2S, 0, mixRX, 0); AudioConnection patchCord4(inI2S, 1, mixTX, 0); AudioConnection patchCord5(inUSB, 0, mixRX, 1); AudioConnection patchCord6(inUSB, 1, mixTX, 1); AudioConnection patchCord7(mixRX, ampRX); AudioConnection patchCord8(mixTX, ampTX); AudioConnection patchCord9(ampTX, 0, outI2S, 1); AudioConnection patchCord10(ampTX, peakTX); AudioConnection patchCord11(ampTX, rmsTX); AudioConnection patchCord12(ampTX, 0, outUSB, 1); AudioConnection patchCord13(ampRX, 0, outUSB, 0); AudioConnection patchCord14(ampRX, 0, outI2S, 0); AudioConnection patchCord15(ampRX, outDAC); AudioControlSGTL5000 audioCtrl; //xy=517,485 // GUItool: end automatically generated code //AudioStream* tx_inputs[4] = { // NULL, NULL, NULL, NULL //}; enum io_t { IO_NONE = 0, IO_RIG = 1, IO_LINE = 2, IO_USB = 3, IO_MIC = 4, IO_SPKR = 5, }; #define DEFAULT_RX_SRC IO_RIG #define DEFAULT_RX_DST IO_SPKR #define DEFAULT_TX_SRC IO_MIC #define DEFAULT_TX_DST IO_RIG class RXAudio { public: RXAudio() { } void init() { mix.gain(0, 0.0); mix.gain(1, 0.0); mix.gain(2, 0.0); mix.gain(3, 0.0); } void selectRigIn() { // disable other input(s) mix.gain(1, 0.0); // enable the rig's receiver input mix.gain(0, 1.0); } void selectUSBIn() { // disable other input(s) mix.gain(0, 0.0); // enable the USB input mix.gain(1, 1.0); } void setTransmit(bool tx) { if (tx) { mix.gain(0, 0.0); } else { mix.gain(0, 1.0); } } private: static constexpr AudioMixer4& mix = mixRX; static constexpr AudioControlSGTL5000& ctrl = audioCtrl; }; class TXAudio { public: TXAudio() { } void init() { mix.gain(0, 0.0); mix.gain(1, 0.0); mix.gain(2, 0.0); mix.gain(3, 0.0); ctrl.micGain(0); //ctrl.dacVolume(1.0, 0.0); } void selectMicIn() { if (src != IO_MIC) { src = IO_MIC; // disable other input(s) mix.gain(1, 0.0); // enable the I2C input mix.gain(0, 1.0); } } void selectLineIn() { if (src != IO_LINE) { src = IO_LINE; // disable other input(s) mix.gain(1, 0.0); // enable the I2C input mix.gain(0, 1.0); } } void selectUSBIn() { if (src != IO_USB) { src = IO_USB; // disable other input(s) mix.gain(0, 0.0); // enable USB input mix.gain(1, 1.0); } } void setTransmit(bool tx) { if (src == IO_MIC) { if (tx) { // drop the gain down, switch to Mic, bring it back up mix.gain(0, 0.0); ctrl.inputSelect(AUDIO_INPUT_MIC); mix.gain(0, 1.0); } else { // drop the gain down, switch to Line, bring it back up mix.gain(0, 0.0); ctrl.inputSelect(AUDIO_INPUT_LINEIN); mix.gain(0, 1.0); } } } private: io_t src = DEFAULT_TX_SRC; static constexpr AudioMixer4& mix = mixTX; static constexpr AudioControlSGTL5000& ctrl = audioCtrl; }; /* enum io_mode_t { MODE_KEY = 0, MODE_MIC = 1, // use AUDIO_INPUT_MIC; switches it in based on the PTT MODE_LINE = 2, // use AUDIO_INPUT_LINEIN MODE_USB = 3, // use AUDIO_INPUT_LINEIN, but mute it and use USB audio instead } io_mode = MODE_USB; enum tr_mode_t { MODE_RX = 0, MODE_TX = 1, } tr_mode = MODE_RX; int setIOMode(io_mode_t m) { // Check for error conditions, return -1 if we can't set the mode. if (tr_mode == MODE_TX) { // Don't allow mode changes while transmitting. return -1; } io_mode = m; switch (io_mode) { case MODE_KEY: break; case MODE_MIC: break; case MODE_LINE: break; case MODE_USB: break; default: break; } return 0; } int setTRMode(tr_mode_t m) { // Check for error conditions, return -1 if we can't set the mode. // NONE tr_mode = m; switch (tr_mode) { case MODE_RX: if (io_mode == MODE_MIC) { audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); } break; case MODE_TX: if (io_mode == MODE_MIC) { audioCtrl.inputSelect(AUDIO_INPUT_MIC); } break; default: break; } return 0; } */ RXAudio rxio = RXAudio(); TXAudio txio = TXAudio(); #define MIC_PTT_PIN 21 #define LINE_PTT_PIN 20 #define PTT_KEY_OUT_PIN 2 Bounce micPTT = Bounce(); Bounce linePTT = Bounce(); bool micPTT_active = false; bool linePTT_active = false; enum key_state_t { NONE = 0, KEY = 1, MIC_PTT = 2, LINE_PTT = 3, } keyState = NONE; enum trx_mode_t { SSB = 0, CW = 1, } trxMode = SSB; void checkPTT() { // Update the PTT lines. micPTT.update(); linePTT.update(); if (trxMode == SSB) { if (micPTT_active) { // ignore line PTT; just wait for release of mic PTT if (micPTT.rose()) { txio.setTransmit(false); micPTT_active = false; digitalWrite(PTT_KEY_OUT_PIN, HIGH); rxio.setTransmit(false); } } else if (linePTT_active) { // ignore mic PTT; just wait for release of line PTT if (linePTT.rose()) { txio.setTransmit(false); linePTT_active = false; digitalWrite(PTT_KEY_OUT_PIN, HIGH); rxio.setTransmit(false); } } else { // Whichever PTT source was last active, will determine the TX audio source. Need to incorporate USB into this. if (micPTT.fell()) { rxio.setTransmit(true); txio.setTransmit(true); micPTT_active = true; digitalWrite(PTT_KEY_OUT_PIN, LOW); txio.selectMicIn(); } else if (linePTT.fell()) { rxio.setTransmit(true); txio.setTransmit(true); linePTT_active = true; digitalWrite(PTT_KEY_OUT_PIN, LOW); txio.selectLineIn(); } } } else if (trxMode == CW) { // ignoring for now... } // For now, if either PTT line goes low (active), we're simply going to set the PTT/key line to the Raduino. // In the future, we'll plan on changing audio inputs depending on what button is pressed. digitalWrite(PTT_KEY_OUT_PIN, (micPTT.read() && linePTT.read() ? HIGH : LOW)); #if defined(DEBUG) if (micPTT.fell()) { USBSERIAL.println("Mic PTT pressed!"); } else if (micPTT.rose()) { USBSERIAL.println("Mic PTT released!"); } if (linePTT.fell()) { USBSERIAL.println("Line PTT pressed!"); } else if (linePTT.rose()) { USBSERIAL.println("Line PTT released!"); } #endif } 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); // Enable the audio shield, enable I/O. audioCtrl.enable(); audioCtrl.muteHeadphone(); audioCtrl.unmuteLineout(); audioCtrl.volume(1.0); rxio.init(); rxio.selectRigIn(); txio.init(); txio.selectMicIn(); } void loop() { elapsedMillis frame_timer = 0; checkPTT(); serviceCAT(); /* #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 //======================================================================