ubitx-v5d-xcvr/ubitx_iop/ubitx_iop.ino
Rob French c27e2eddd6 More robust menu system, slightly. But still doesn't get correctly
displayed on the Raduino.  See most recently Raduino (ubitx-v5d) commit.
2020-06-06 22:28:11 -05:00

290 lines
7.6 KiB
C++

//======================================================================
// ubitx_iop.ino
//======================================================================
#include <Encoder.h>
#include <iopcomm.h>
#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;
TopMenu topMenu(rig);
MenuItem* menu = &topMenu;
elapsedMillis menuUpdateMillis;
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;
menuUpdateMillis = 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 loop()
{
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();
/*
// send current status @ 10 Hz
//if (frame10Hz > 100) {
if ((rig.modeNum() != oldRigMode)) { // || (rxFilter != oldRxFilter)) {
USBDEBUG("mode changed");
switch(rig.modeNum()) {
case RIG_MODE_LSB:
USBDEBUG("sending LSB mode status");
sendIOPSSBStatus(rigConfig.lsb);
break;
case RIG_MODE_USB:
USBDEBUG("sending USB mode status");
sendIOPSSBStatus(rigConfig.usb);
break;
case RIG_MODE_DGL:
USBDEBUG("sending DGL mode status");
sendIOPDGTStatus(rigConfig.dgl);
break;
case RIG_MODE_DGU:
USBDEBUG("sending DGU mode status");
sendIOPDGTStatus(rigConfig.dgu);
break;
case RIG_MODE_CWL:
USBDEBUG("sending CWL mode status");
sendIOPCWStatus(rigConfig.cwl);
break;
case RIG_MODE_CWU:
USBDEBUG("sending CWU mode status");
sendIOPCWStatus(rigConfig.cwu);
break;
case RIG_MODE_TTL:
USBDEBUG("sending TTL mode status");
sendIOPTestStatus();
break;
case RIG_MODE_TTU:
USBDEBUG("sending TTU mode status");
sendIOPTestStatus();
break;
}
//frame10Hz = 0;
}
*/
btn.update();
if (btn.fell()) {
//sendIOPMenuDisplay("PRESSED ", 2);
btnMillis = 0;
USBDEBUG("button pressed");
} else if (btn.rose()) {
if (btnMillis > 1000) {
// long press - exit
//sendIOPMenuDisplay("REL-LONG ", 2);
menu->exit();
USBDEBUG("button released - long (exit)");
} if (btnMillis > 500) {
// medium press - altSelect
menu->altSelect();
USBDEBUG("button released - medium (altSelect)");
} else {
// short press - select
//sendIOPMenuDisplay("REL-SHORT ", 2);
menu->select();
USBDEBUG("button released - short (select)");
}
// menu->update();
}
knobPos = knob.read();
// wait til we turn greater than 3 pos in either direction, for "debouncing"
if (knobPos > 3) {
// left
//sendIOPMenuDisplay("LEFT ", 5);
menu->prev();
// menu->update();
knob.write(0);
USBDEBUG("knob turned left");
} else if (knobPos < -3) {
// right
//sendIOPMenuDisplay("RIGHT ", 5);
menu->next();
// menu->update();
knob.write(0);
USBDEBUG("knob turned right");
}
// if (strcmp(old_mode_text, rig.modeText())) {
// menu->update();
// strcpy(old_mode_text, rig.modeText());
// }
// update the menu at a 10 Hz rate
if (menuUpdateMillis > 100) {
menu->update();
menuUpdateMillis = 0;
}
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
//======================================================================