ubitx-v5d-xcvr/ubitx_iop.ino

392 lines
8.7 KiB
Arduino
Raw Normal View History

2020-05-01 16:04:26 +00:00
#include <Bounce2.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#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
//======================================================================