//====================================================================== // ubitx_iop.ino //====================================================================== #include #include #include "audio.h" #include "config.h" #include "ubitx_iop.h" #include "keyer.h" #include "menu.h" #include "rig.h" #include "TxSwitch.h" Keyer keyer{15, 3.0}; // NOTE: make configurable RigConfig rigConfig; RigAudio rigAudio{rigConfig.audio}; Rig rig{rigConfig, rigAudio}; BPFilter rxFilter{300, 3100, false}; SSBMode lsbMode{rigConfig.lsb, rigAudio, rxFilter}; SSBMode usbMode{rigConfig.usb, rigAudio, rxFilter}; CWMode cwlMode{rigConfig.cwl, rigAudio, rxFilter}; CWMode cwuMode{rigConfig.cwu, rigAudio, rxFilter}; DGTMode dglMode{rigConfig.dgl, rigAudio, rxFilter}; DGTMode dguMode{rigConfig.dgu, rigAudio, rxFilter}; TTMode ttlMode{rigConfig.ttl, rigAudio, rxFilter}; TTMode ttuMode{rigConfig.ttu, rigAudio, rxFilter}; CATSwitch catPTT; //MicSwitch micPTTHelper; GPIOSwitch micPTT(true, MIC_PTT_PIN); //LineSwitch linePTTHelper; GPIOSwitch linePTT(false, LINE_PTT_PIN); Encoder knob(ENCODER_A_PIN, ENCODER_B_PIN); long knobPos = 0; Bounce btn; elapsedMillis btnMillis; Main_menu main_menu(rig); Menu_item* menu_item = &main_menu; elapsedMillis frameMillis; unsigned frameTime; unsigned frameCounter; unsigned audioProcUsage; unsigned audioMemUsage; //====================================================================== void setup() { // put your setup code here, to run once: initCAT(38400, SERIAL_8N1); USBDEBUG("setup started"); AudioMemory(16); // NOTE: Need to fine tune this. Have had errors due to this being too low. // initialize the filter(s) rxFilter.init(); // adding all of the modes to the rig rig.addNewMode(RIG_MODE_LSB, &lsbMode); rig.addNewMode(RIG_MODE_USB, &usbMode); rig.addNewMode(RIG_MODE_CWL, &cwlMode); rig.addNewMode(RIG_MODE_CWU, &cwuMode); rig.addNewMode(RIG_MODE_DGL, &dglMode); rig.addNewMode(RIG_MODE_DGU, &dguMode); rig.addNewMode(RIG_MODE_TTL, &ttlMode); rig.addNewMode(RIG_MODE_TTU, &ttuMode); initKeyLine(); rigAudio.init(); frameCounter = 0; frameMillis = 0; knob.write(0); btn.attach(ENCODER_SW_PIN, INPUT_PULLUP); btn.interval(25); rig.init(); USBDEBUG("setup completed"); // audioInit(); /* #if defined(FACTORY_CALIBRATION) setRigMode(RIG_MODE_TEST); #else setRigMode(RIG_MODE_SSB); #endif */ } //====================================================================== void update_io_menu(Menu_item* item, bool is_active) { Menu_string text; if (!is_active || (is_active && item == nullptr)) { sendIOPMenuInactive(); } else { item->get_text(text); sendIOPMenuDisplay(text.data()); } } //====================================================================== void loop() { static bool menu_is_active = false; static bool menu_updated = false; static char frame_status[100]; static char old_mode_text[17] = " "; static bool paddle_loop = false; // long oldPos = knobPos; RigMode oldRigMode; frameCounter++; if (rig.isCWMode()) { if (keyer.do_paddles()) { // Checking for T/R separately from the paddle loop, because it's // possible we're already transmitting (PTT/Key being held), and // we don't want to run the tx() actions if we're already in TX. if (rig.isRx()) { USBDEBUG("entered TX via paddles"); rig.tx(); } paddle_loop = true; if (keyer.is_down()) { setKeyDown(); } else { setKeyUp(); } return; // return early for paddle responsiveness } else { if (paddle_loop) { // If we exit the paddle loop (i.e. keyer completes its keying // sequence), then we'll go back to receive, even if one of the // PTT/Key lines is still held separately. General principle is // that if "something" stops transmitting, then the rig will // stop transmitting. paddle_loop = false; rig.rx(); USBDEBUG("exited TX from paddles"); } } } rig.update(); oldRigMode = rig.modeNum(); // Update the mic PTT. We need to tell it if we're in SSB mode, so that // it knows if it should switch to the mic input if pressed. We also // need to make it inactive if we're in DGT mode, since only CAT will be // used to start transmitting in that case. micPTT.setSSBMode(rig.isSSBMode()); micPTT.update(rig.mode(), !rig.isDGTMode()); // Update the line PTT. We need to tell it if we're in SSB mode, so that // it knows if it should switch to the line input if pressed. We also // need to make it inactive if we're in DGT mode, since only CAT will be // used to start transmitting in that case. linePTT.setSSBMode(rig.isSSBMode()); linePTT.update(rig.mode(), !rig.isDGTMode()); serviceCAT(); menu_updated = false; btn.update(); knobPos = knob.read(); if (btn.fell()) { btnMillis = 0; USBDEBUG("button pressed"); // cancel out any knob rotation that occurred during in conjunction with press/release knob.write(0); } else if (btn.rose()) { menu_updated = true; if (btnMillis > 1000) { // long press - exit menu_item = menu_item->exit(); USBDEBUG("button released - long (exit)"); } else if (btnMillis > 500) { // medium press - altSelect if (menu_is_active) { menu_item = menu_item->altSelect(); } else { menu_item = audio_config_menu; menu_is_active = true; } USBDEBUG("button released - medium (altSelect)"); } else { // short press - select if (menu_is_active) { menu_item = menu_item->select(); } else { menu_item = &main_menu; menu_is_active = true; } USBDEBUG("button released - short (select)"); } // cancel out any knob rotation that occurred during in conjunction with press/release knob.write(0); } else if (knobPos > 3 && menu_is_active) { // left menu_item->prev(); knob.write(0); menu_updated = true; USBDEBUG("knob turned left"); } else if (knobPos < -3 && menu_is_active) { // right menu_item->next(); knob.write(0); menu_updated = true; USBDEBUG("knob turned right"); } if (menu_item == nullptr) { menu_item = &main_menu; menu_is_active = false; menu_updated = true; USBDEBUG("null menu - reset to main menu"); } if (menu_updated) { update_io_menu(menu_item, menu_is_active); USBDEBUG("updated main menu"); } // update the speech compressor. Really should do this elsewhere. if (speechCompressor.isEnabled()) speechCompressor.update(); if (frameMillis > 5000) { #if defined(DEBUG) frameTime = frameMillis; audioProcUsage = AudioProcessorUsageMax(); audioMemUsage = AudioMemoryUsageMax(); sprintf(frame_status, "update: %u ms, %u frames, %d %% CPU max, %d %% mem max\n", frameTime, frameCounter, audioProcUsage, audioMemUsage); USBDEBUG(frame_status); #endif frameMillis = 0; frameCounter = 0; } //audioUpdate(); // was used to update the speech compressor } //====================================================================== // EOF //======================================================================