926b8d3600
kill my Teensy 3.2. I unplugged the Teensy-to-Raduino comm lines in order to program the Raduino. When I plugged them back in, I didn't realize that I was off by one pin. So I believe something that should've only gotten 3.3V, got more. No light on the Teensy. This development effort, while it has been fruitful, is definitely complicated. I don't think I have the bandwidth to continue it. I plan on merging all the branches back to master, collecting the pieces-parts of uBITX V5D, and calling it "done". I will rebuild my uBITX V5 back into a relatively stock configuration, and use an external digital interface (see KK5JY).
236 lines
6.2 KiB
C++
236 lines
6.2 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};
|
|
basic_rig rig{rigConfig, rigAudio};
|
|
|
|
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.
|
|
|
|
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");
|
|
}
|
|
|
|
//======================================================================
|
|
|
|
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;
|
|
|
|
rig_mode oldRigMode;
|
|
|
|
frameCounter++;
|
|
|
|
if (rig.is_cw_mode()) {
|
|
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.is_rx()) {
|
|
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.get_rig_mode();
|
|
|
|
// 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.is_ssb_mode());
|
|
micPTT.update(rig.mode(), !rig.is_digi_mode());
|
|
|
|
// 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.is_ssb_mode());
|
|
linePTT.update(rig.mode(), !rig.is_digi_mode());
|
|
|
|
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 = menu_item->prev();
|
|
knob.write(0);
|
|
menu_updated = true;
|
|
USBDEBUG("knob turned left");
|
|
|
|
} else if (knobPos < -3 && menu_is_active) {
|
|
// right
|
|
menu_item = 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");
|
|
}
|
|
|
|
rig.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
|
|
//======================================================================
|