Modifications, mainly based on a code walkthrough as well as adding some
debugging output. Compiles, but untested.
This commit is contained in:
parent
9b7095a6e3
commit
564c35f397
@ -104,13 +104,13 @@ void sendIOPSSBStatus(SSBConfig const &c)
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// DIGI STATUS MESSAGE
|
||||
// DGT STATUS MESSAGE
|
||||
//======================================================================
|
||||
|
||||
void sendIOPDigiStatus(DigiConfig const &c)
|
||||
void sendIOPDGTStatus(DGTConfig const &c)
|
||||
{
|
||||
IOPMessage m;
|
||||
m.id = IOP_DIGI_STATUS_MSG;
|
||||
m.id = IOP_DGT_STATUS_MSG;
|
||||
m.len = 4;
|
||||
m.data[0] = 'D'; // current mode; redundant w/ Raduino mode, but maybe useful for debugging
|
||||
m.data[1] = '-'; // placeholder for future digital submodes?
|
||||
|
@ -71,7 +71,7 @@ enum MessageID {
|
||||
// Requests
|
||||
IOP_MODE_REQUEST,
|
||||
IOP_SSB_STATUS_MSG,
|
||||
IOP_DIGI_STATUS_MSG,
|
||||
IOP_DGT_STATUS_MSG,
|
||||
IOP_CW_STATUS_MSG,
|
||||
IOP_TEST_STATUS_MSG,
|
||||
|
||||
@ -95,12 +95,16 @@ enum MessageID {
|
||||
*/
|
||||
|
||||
enum RigMode {
|
||||
RIG_MODE_SSB = 0,
|
||||
RIG_MODE_DIGI,
|
||||
RIG_MODE_CW,
|
||||
RIG_MODE_TEST,
|
||||
// add any new elements here
|
||||
NUM_RIG_MODES
|
||||
RIG_MODE_LSB = 0,
|
||||
RIG_MODE_USB,
|
||||
RIG_MODE_CWL,
|
||||
RIG_MODE_CWU,
|
||||
RIG_MODE_DGL,
|
||||
RIG_MODE_DGU,
|
||||
RIG_MODE_TTL,
|
||||
RIG_MODE_TTU,
|
||||
// add new items here
|
||||
NUM_RIG_MODES
|
||||
};
|
||||
|
||||
/* Keyer modes.
|
||||
@ -117,15 +121,15 @@ enum KeyerMode {
|
||||
};
|
||||
|
||||
enum RxFilter {
|
||||
RX_FILTER_NORMAL = 0,
|
||||
RX_FILTER_WIDE = 0,
|
||||
RX_FILTER_MEDIUM,
|
||||
RX_FILTER_NARROW,
|
||||
RX_FILTER_WIDE,
|
||||
NUM_RX_FILTERS
|
||||
};
|
||||
|
||||
const unsigned char RIG_MODE_LETTER[NUM_RIG_MODES] = {'S', 'D', 'C', 'T'};
|
||||
const unsigned char RIG_MODE_LETTER[NUM_RIG_MODES] = {'s', 'S', 'c', 'C', 'd', 'D', 't', 'T'};
|
||||
const unsigned char KEYER_MODE_LETTER[NUM_KEYER_MODES] = {'S', 'A', 'B'};
|
||||
const unsigned char RX_FILTER_LETTER[NUM_RX_FILTERS] = {'-', 'N', 'W'};
|
||||
const unsigned char RX_FILTER_LETTER[NUM_RX_FILTERS] = {'W', 'M', 'N'};
|
||||
|
||||
const uint8_t NO_FLAGS = 0;
|
||||
const uint8_t REVERSED = 1;
|
||||
@ -137,28 +141,46 @@ struct IOPMessage {
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// SSB CONFIGURATION
|
||||
// IConfig
|
||||
//
|
||||
// Interface to a configuration object.
|
||||
//======================================================================
|
||||
|
||||
struct SSBConfig {
|
||||
// parameters
|
||||
RxFilter filter = RX_FILTER_NORMAL;
|
||||
class IConfig {
|
||||
public:
|
||||
virtual ~IConfig() {}
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// DIGI CONFIGURATION
|
||||
// SSB CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
struct DigiConfig {
|
||||
class SSBConfig : public IConfig {
|
||||
public:
|
||||
SSBConfig(RxFilter f): filter(f) {}
|
||||
// parameters
|
||||
RxFilter filter = RX_FILTER_NORMAL;
|
||||
RxFilter filter; // = RX_FILTER_MEDIUM;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// DGT CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
class DGTConfig : public IConfig {
|
||||
public:
|
||||
DGTConfig(RxFilter f): filter(f) {}
|
||||
// parameters
|
||||
RxFilter filter = RX_FILTER_MEDIUM;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// CW CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
struct CWConfig {
|
||||
class CWConfig : public IConfig {
|
||||
public:
|
||||
CWConfig(KeyerMode m, bool rev, uint8_t w, float wt, uint16_t st, RxFilter f):
|
||||
mode(m), reversed(rev), wpm(w), weight(wt), sidetone(st), filter(f) {}
|
||||
// mode
|
||||
KeyerMode mode = KEYER_MODE_IAMBIC_A;
|
||||
// flags
|
||||
@ -167,7 +189,18 @@ struct CWConfig {
|
||||
uint8_t wpm = 15;
|
||||
float weight = 3.0;
|
||||
uint16_t sidetone = 700;
|
||||
RxFilter filter = RX_FILTER_NORMAL;
|
||||
RxFilter filter = RX_FILTER_MEDIUM;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// TT CONFIGURATION
|
||||
//======================================================================
|
||||
|
||||
class TTConfig : public IConfig {
|
||||
public:
|
||||
TTConfig(RxFilter f): filter(f) {}
|
||||
// parameters
|
||||
RxFilter filter = RX_FILTER_MEDIUM;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
@ -184,7 +217,7 @@ void sendIOPStopTxCommand();
|
||||
|
||||
void sendIOPModeRequest();
|
||||
void sendIOPSSBStatus(SSBConfig const&);
|
||||
void sendIOPDigiStatus(DigiConfig const&);
|
||||
void sendIOPDGTStatus(DGTConfig const&);
|
||||
void sendIOPCWStatus(CWConfig const&);
|
||||
void sendIOPTestStatus();
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
//======================================================================
|
||||
// audio.h
|
||||
//
|
||||
// NOTE: Let's change the name of this file to RigAudio.h.
|
||||
//======================================================================
|
||||
|
||||
#ifndef __iop_audio_h__
|
||||
@ -8,27 +10,41 @@
|
||||
#include <Audio.h>
|
||||
#include "config.h"
|
||||
|
||||
enum RxInput {
|
||||
RX_RIG_IN = 0,
|
||||
RX_USB_IN = 1,
|
||||
};
|
||||
class RigAudio
|
||||
{
|
||||
public:
|
||||
RigAudio(AudioConfig& c): _config(c) {}
|
||||
|
||||
enum RxOutput {
|
||||
RX_SPEAKER_OUT = 0,
|
||||
RX_LINE_OUT = 1,
|
||||
RX_USB_OUT = 2,
|
||||
};
|
||||
void init() const;
|
||||
|
||||
enum TxInput {
|
||||
TX_MIC_IN = -1,
|
||||
TX_LINE_IN = 0,
|
||||
TX_USB_IN = 1,
|
||||
TX_TEST_IN = 2,
|
||||
};
|
||||
void muteRx() const;
|
||||
void unmuteRx() const;
|
||||
|
||||
enum TxOutput {
|
||||
TX_RIG_OUT = 0,
|
||||
TX_USB_OUT = 1,
|
||||
void muteAllTx() const;
|
||||
|
||||
void muteMicIn() const;
|
||||
void unmuteMicIn() const;
|
||||
|
||||
void muteLineIn() const;
|
||||
void unmuteLineIn() const;
|
||||
|
||||
void muteUSBIn() const;
|
||||
void unmuteUSBIn() const;
|
||||
|
||||
void muteTTIn() const;
|
||||
void unmuteTTIn() const;
|
||||
|
||||
void muteSpkrOut() const;
|
||||
void unmuteSpkrOut() const;
|
||||
|
||||
void muteLineOut() const;
|
||||
void unmuteLineOut() const;
|
||||
|
||||
void muteUSBOut() const;
|
||||
void unmuteUSBOut() const;
|
||||
|
||||
private:
|
||||
AudioConfig _config;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
@ -60,11 +76,13 @@ class BPFilter {
|
||||
|
||||
//======================================================================
|
||||
|
||||
/*
|
||||
void audioInit();
|
||||
void audioSelectTxInput(TxInput);
|
||||
void audioTransmit();
|
||||
void audioReceive();
|
||||
void audioCalibrate(IOPConfig *, char, char, char, float, bool);
|
||||
void audioCalibrate(AudioConfig *, char, char, char, float, bool);
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,19 +1,37 @@
|
||||
//======================================================================
|
||||
// audio.ino
|
||||
//
|
||||
// NOTE: Let's change the name of this file to Rigconfig.cc. Will need
|
||||
// to ensure that "Arduino-isms" are resolved if it's converted to .cc
|
||||
// from .ino, however.
|
||||
//======================================================================
|
||||
|
||||
#include <dynamicFilters.h>
|
||||
#include <effect_compressor_fb.h>
|
||||
|
||||
|
||||
#include "audio.h"
|
||||
#include "tx_audio_proc.h"
|
||||
|
||||
extern IOPConfig iopConfig;
|
||||
short firActive[NUM_COEFFICIENTS];
|
||||
|
||||
#define RX_RIG_IN 0
|
||||
#define RX_USB_IN 1
|
||||
#define RX_ST_IN 2 // sidetone
|
||||
|
||||
#define TX_MIC_IN 0
|
||||
#define TX_LINE_IN 0
|
||||
#define TX_USB_IN 1
|
||||
#define TX_TEST_IN 2
|
||||
|
||||
//extern RigConfig rigConfig;
|
||||
|
||||
/*
|
||||
#define DEFAULT_RX_INPUT RIG
|
||||
#define DEFAULT_RX_OUTPUT SPKR
|
||||
#define DEFAULT_TX_INPUT MIC
|
||||
#define DEFAULT_TX_OUTPUT RIG
|
||||
*/
|
||||
|
||||
#include <Audio.h>
|
||||
#include <Wire.h>
|
||||
@ -75,10 +93,167 @@ AudioConnection patchCord26(calTxUSB, 0, outUSB, 1);
|
||||
AudioControlSGTL5000 audioCtrl; //xy=648,517
|
||||
// GUItool: end automatically generated code
|
||||
|
||||
void RigAudio::init() const {
|
||||
USBDEBUG("audio initialization started");
|
||||
|
||||
audioCtrl.enable();
|
||||
audioCtrl.muteHeadphone(); // not using the headphone output
|
||||
audioCtrl.volume(0.0); // not using the headphone output
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio
|
||||
audioCtrl.unmuteLineout(); // required for RX audio
|
||||
|
||||
audioCtrl.lineInLevel(_config.rxRigInLevel, _config.txLineInLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.lineOutLevel(_config.rxLineOutLevel, _config.txRigOutLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.micGain(_config.txMicInGain); // superfluous, as I have to do this anytime I switch to mic for some reason
|
||||
|
||||
// configure line input
|
||||
audioCtrl.lineInLevel(_config.rxRigInLevel, _config.txLineInLevel);
|
||||
|
||||
// configure line output
|
||||
calTxLine.gain(_config.txRigOutCal);
|
||||
audioCtrl.lineOutLevel(_config.rxLineOutLevel, _config.txRigOutLevel);
|
||||
|
||||
// configure "receive" of USB audio input (debug only)
|
||||
if (_config.rxUSBInEnable) {
|
||||
mixRX.gain(RX_USB_IN, _config.rxUSBInVol * _config.rxUSBInCal);
|
||||
} else {
|
||||
mixRX.gain(RX_USB_IN, 0.0);
|
||||
}
|
||||
|
||||
// configure USB audio output of transmit audio (useful for debug)
|
||||
if (_config.txUSBOutEnable) {
|
||||
calTxUSB.gain(_config.txUSBOutCal);
|
||||
} else {
|
||||
calTxUSB.gain(0.0);
|
||||
}
|
||||
|
||||
// setup the two-tone generator
|
||||
sine1.frequency(700);
|
||||
sine2.frequency(1900);
|
||||
sine1.amplitude(0);
|
||||
sine2.amplitude(0);
|
||||
|
||||
audioFilter(firActive, NUM_COEFFICIENTS, ID_BANDPASS, W_HAMMING, 300.0, 3100.0); // 2.8 kHz filter
|
||||
filterRX.begin(firActive, NUM_COEFFICIENTS);
|
||||
filterAmp.gain(1.0);
|
||||
|
||||
// for now, just pass through the compressor
|
||||
compTX.disable();
|
||||
compAmp.gain(1.0);
|
||||
|
||||
// Hardware should be all setup... now we're going to mute everything
|
||||
// and let the modes take care of enabling/disabling what they should.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
mixRX.gain(i, 0.0);
|
||||
mixTX.gain(i, 0.0);
|
||||
}
|
||||
|
||||
USBDEBUG("audio initialization completed");
|
||||
}
|
||||
|
||||
void RigAudio::muteRx() const {
|
||||
mixRX.gain(RX_RIG_IN, 0.0);
|
||||
USBDEBUG("RX audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteRx() const {
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
mixRX.gain(RX_RIG_IN, _config.rxRigInVol * _config.rxRigInCal);
|
||||
USBDEBUG("RX audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteAllTx() const {
|
||||
muteMicIn();
|
||||
muteLineIn();
|
||||
muteUSBIn();
|
||||
muteTTIn();
|
||||
USBDEBUG("all TX audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::muteMicIn() const {
|
||||
mixTX.gain(TX_LINE_IN, 0.0);
|
||||
USBDEBUG("Mic In audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteMicIn() const {
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_MIC);
|
||||
audioCtrl.micGain(_config.txMicInGain);
|
||||
mixTX.gain(TX_LINE_IN, _config.txMicInVol * _config.txMicInCal);
|
||||
USBDEBUG("Mic In audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteLineIn() const {
|
||||
mixTX.gain(TX_LINE_IN, 0.0);
|
||||
USBDEBUG("Line In audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteLineIn() const {
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
mixTX.gain(TX_LINE_IN, _config.txLineInVol * _config.txLineInCal);
|
||||
USBDEBUG("Line In audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteUSBIn() const {
|
||||
mixTX.gain(TX_USB_IN, 0.0);
|
||||
USBDEBUG("USB In audio muted");
|
||||
}
|
||||
void RigAudio::unmuteUSBIn() const {
|
||||
mixTX.gain(TX_USB_IN, _config.txUSBInVol * _config.txUSBInCal);
|
||||
USBDEBUG("USB In audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteTTIn() const {
|
||||
mixTX.gain(TX_TEST_IN, 0.0);
|
||||
mixTX.gain(TX_TEST_IN + 1, 0.0);
|
||||
sine1.amplitude(0.0);
|
||||
sine2.amplitude(0.0);
|
||||
USBDEBUG("Two Tone audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteTTIn() const {
|
||||
sine1.amplitude(0.5);
|
||||
sine2.amplitude(0.5);
|
||||
mixTX.gain(TX_TEST_IN, _config.txSine1Vol);
|
||||
mixTX.gain(TX_TEST_IN + 1, _config.txSine2Vol);
|
||||
USBDEBUG("Two Tone audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteSpkrOut() const {
|
||||
calRxSpkr.gain(0.0);
|
||||
USBDEBUG("Speaker Out audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteSpkrOut() const {
|
||||
calRxSpkr.gain(_config.rxSpkrOutCal);
|
||||
USBDEBUG("Speaker Out audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteLineOut() const {
|
||||
calRxLine.gain(0.0);
|
||||
USBDEBUG("Line Out audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteLineOut() const {
|
||||
calRxLine.gain(_config.rxLineOutCal);
|
||||
USBDEBUG("Line Out audio unmuted");
|
||||
}
|
||||
|
||||
void RigAudio::muteUSBOut() const {
|
||||
calRxUSB.gain(0.0);
|
||||
USBDEBUG("USB Out audio muted");
|
||||
}
|
||||
|
||||
void RigAudio::unmuteUSBOut() const {
|
||||
calRxUSB.gain(_config.rxUSBOutCal);
|
||||
USBDEBUG("USB Out audio unmuted");
|
||||
}
|
||||
|
||||
/*
|
||||
RxInput audioRxInput;
|
||||
RxOutput audioRxOutput;
|
||||
TxInput audioTxInput;
|
||||
TxOutput audioTxOutput;
|
||||
*/
|
||||
|
||||
//======================================================================
|
||||
|
||||
@ -130,20 +305,13 @@ void BPFilter::update(AudioFilterFIR* filter=NULL, short* coefficients=NULL) {
|
||||
filter->begin(coefficients, NUM_COEFFICIENTS);
|
||||
}
|
||||
|
||||
static AudioFilterFIR* BPFilter::_filter = &filterRX;
|
||||
static short BPFilter::_coefficients[NUM_COEFFICIENTS];
|
||||
AudioFilterFIR* BPFilter::_filter = &filterRX;
|
||||
short BPFilter::_coefficients[NUM_COEFFICIENTS];
|
||||
|
||||
//======================================================================
|
||||
|
||||
enum FilterWidth {
|
||||
FILTER_WIDE = 0,
|
||||
FILTER_NORMAL,
|
||||
FILTER_NARROW,
|
||||
NUM_FILTER_WIDTHS
|
||||
};
|
||||
|
||||
/*
|
||||
// array based on mode right now
|
||||
BPFilter *rxFilter[NUM_RIG_MODES][NUM_FILTER_WIDTHS];
|
||||
BPFilter *rxFilter[NUM_RIG_MODES][NUM_RX_FILTERS];
|
||||
|
||||
//======================================================================
|
||||
|
||||
@ -179,9 +347,9 @@ void audioInit()
|
||||
audioCtrl.volume(0.0); // not using the headphone output
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio
|
||||
audioCtrl.unmuteLineout(); // required for RX audio
|
||||
audioCtrl.lineInLevel(iopConfig.rxRigInLevel, iopConfig.txLineInLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.lineOutLevel(iopConfig.rxLineOutLevel, iopConfig.txRigOutLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.micGain(iopConfig.txMicInGain); // superfluous, as I have to do this anytime I switch to mic for some reason
|
||||
audioCtrl.lineInLevel(rigConfig.rxRigInLevel, rigConfig.txLineInLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.lineOutLevel(rigConfig.rxLineOutLevel, rigConfig.txRigOutLevel); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audioCtrl.micGain(rigConfig.txMicInGain); // superfluous, as I have to do this anytime I switch to mic for some reason
|
||||
//audioCtrl.dacVolumeRamp(); // if this seems too slow, might try dacVolumeRampLinear().
|
||||
//audioCtrl.dacVolume(1.0, 0.0); // we're going to mute TX audio via the DAC unless we're transmitting
|
||||
|
||||
@ -220,293 +388,14 @@ void audioInit()
|
||||
speechCompressor.enable();
|
||||
}
|
||||
|
||||
inline void updateRxRigIn()
|
||||
{
|
||||
audioCtrl.lineInLevel(iopConfig.rxRigInLevel, iopConfig.txLineInLevel);
|
||||
mixRX.gain(RX_RIG_IN, iopConfig.rxRigInVol * iopConfig.rxRigInCal);
|
||||
}
|
||||
|
||||
inline void muteRxRigIn()
|
||||
{
|
||||
mixRX.gain(RX_RIG_IN, 0.0);
|
||||
}
|
||||
|
||||
inline void restoreRxRigIn()
|
||||
{
|
||||
mixRX.gain(RX_RIG_IN, iopConfig.rxRigInVol * iopConfig.rxRigInCal);
|
||||
}
|
||||
|
||||
inline void updateRxUSBIn()
|
||||
{
|
||||
if (iopConfig.rxUSBInEnable) {
|
||||
mixRX.gain(RX_USB_IN, iopConfig.rxUSBInVol * iopConfig.rxUSBInCal);
|
||||
} else {
|
||||
mixRX.gain(RX_USB_IN, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void muteRxUSBIn()
|
||||
{
|
||||
mixRX.gain(RX_USB_IN, 0.0);
|
||||
}
|
||||
|
||||
inline void restoreRxUSBIn()
|
||||
{
|
||||
updateRxUSBIn();
|
||||
}
|
||||
|
||||
inline void updateRxSpkrOut()
|
||||
{
|
||||
calRxSpkr.gain(iopConfig.rxSpkrOutCal);
|
||||
}
|
||||
|
||||
inline void updateRxLineOut()
|
||||
{
|
||||
calRxLine.gain(iopConfig.rxLineOutCal);
|
||||
audioCtrl.lineOutLevel(iopConfig.rxLineOutLevel, iopConfig.txRigOutLevel);
|
||||
}
|
||||
|
||||
inline void updateRxUSBOut()
|
||||
{
|
||||
calRxUSB.gain(iopConfig.rxUSBOutCal);
|
||||
}
|
||||
|
||||
inline void updateTxMicIn()
|
||||
{
|
||||
audioCtrl.micGain(iopConfig.txMicInGain);
|
||||
mixTX.gain(TX_LINE_IN, iopConfig.txMicInVol * iopConfig.txMicInCal);
|
||||
}
|
||||
|
||||
inline void muteTxMicIn()
|
||||
{
|
||||
mixTX.gain(TX_LINE_IN, 0.0);
|
||||
}
|
||||
|
||||
inline void restoreTxMicIn()
|
||||
{
|
||||
mixTX.gain(TX_LINE_IN, iopConfig.txMicInVol * iopConfig.txMicInCal);
|
||||
}
|
||||
|
||||
inline void updateTxLineIn()
|
||||
{
|
||||
audioCtrl.lineInLevel(iopConfig.rxRigInLevel, iopConfig.txLineInLevel);
|
||||
mixTX.gain(TX_LINE_IN, iopConfig.txLineInVol * iopConfig.txLineInCal);
|
||||
}
|
||||
|
||||
inline void muteTxLineIn()
|
||||
{
|
||||
mixTX.gain(TX_LINE_IN, 0.0);
|
||||
}
|
||||
|
||||
inline void restoreTxLineIn()
|
||||
{
|
||||
mixTX.gain(TX_LINE_IN, iopConfig.txLineInVol * iopConfig.txLineInCal);
|
||||
}
|
||||
|
||||
inline void updateTxUSBIn()
|
||||
{
|
||||
mixTX.gain(TX_USB_IN, iopConfig.txUSBInVol * iopConfig.txUSBInCal);
|
||||
}
|
||||
|
||||
inline void muteTxUSBIn()
|
||||
{
|
||||
mixTX.gain(TX_USB_IN, 0.0);
|
||||
}
|
||||
|
||||
inline void restoreTxUSBIn()
|
||||
{
|
||||
mixTX.gain(TX_USB_IN, iopConfig.txUSBInVol * iopConfig.txUSBInCal);
|
||||
}
|
||||
|
||||
inline void updateTxTwoToneIn()
|
||||
{
|
||||
sine1.amplitude(0.5);
|
||||
sine2.amplitude(0.5);
|
||||
mixTX.gain(TX_TEST_IN, iopConfig.txSine1Vol);
|
||||
mixTX.gain(TX_TEST_IN + 1, iopConfig.txSine2Vol);
|
||||
}
|
||||
|
||||
inline void muteTxTwoToneIn()
|
||||
{
|
||||
mixTX.gain(TX_TEST_IN, 0.0);
|
||||
mixTX.gain(TX_TEST_IN + 1, 0.0);
|
||||
sine1.amplitude(0);
|
||||
sine2.amplitude(0);
|
||||
}
|
||||
|
||||
inline void restoreTxTwoToneIn()
|
||||
{
|
||||
sine1.amplitude(0.5);
|
||||
sine2.amplitude(0.5);
|
||||
mixTX.gain(TX_TEST_IN, iopConfig.txSine1Vol);
|
||||
mixTX.gain(TX_TEST_IN + 1, iopConfig.txSine2Vol);
|
||||
}
|
||||
|
||||
inline void updateTxRigOut()
|
||||
{
|
||||
calTxLine.gain(iopConfig.txRigOutCal);
|
||||
audioCtrl.lineOutLevel(iopConfig.rxLineOutLevel, iopConfig.txRigOutLevel);
|
||||
}
|
||||
|
||||
inline void updateTxUSBOut()
|
||||
{
|
||||
if (iopConfig.txUSBOutEnable) {
|
||||
calTxUSB.gain(iopConfig.txUSBOutCal);
|
||||
} else {
|
||||
calTxUSB.gain(0.0);
|
||||
}
|
||||
}
|
||||
|
||||
void audioSelectRxInput(RxInput input)
|
||||
{
|
||||
if (audioRxInput != input) {
|
||||
audioRxInput = input;
|
||||
switch(input) {
|
||||
case RX_RIG_IN:
|
||||
muteRxUSBIn();
|
||||
restoreRxRigIn();
|
||||
mixRX.gain(2, 0);
|
||||
mixRX.gain(3, 0);
|
||||
break;
|
||||
|
||||
case RX_USB_IN:
|
||||
muteRxRigIn();
|
||||
restoreRxUSBIn();
|
||||
mixRX.gain(2, 0);
|
||||
mixRX.gain(3, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void audioSelectTxInput(TxInput input)
|
||||
{
|
||||
if (audioTxInput != input) {
|
||||
audioTxInput = input;
|
||||
//muteTxMicIn(); // redundant w/ Line-In
|
||||
muteTxLineIn();
|
||||
muteTxUSBIn();
|
||||
muteTxTwoToneIn();
|
||||
/* switch(input) {
|
||||
case TX_MIC_IN:
|
||||
muteTxUSBIn();
|
||||
restoreTxMicIn();
|
||||
break;
|
||||
|
||||
case TX_LINE_IN:
|
||||
muteTxUSBIn();
|
||||
restoreTxLineIn();
|
||||
break;
|
||||
|
||||
case TX_USB_IN:
|
||||
muteTxLineIn();
|
||||
restoreTxUSBIn();
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
// audioTransmit()
|
||||
// This should be called anytime transmit mode is entered. It should
|
||||
// in theory be called BEFORE the actual transmit signal (key/PTT) is
|
||||
// sent to the Raduino, in order to ensure that any audio source
|
||||
// transitions occur before transmission begins.
|
||||
void audioTransmit()
|
||||
{
|
||||
switch(rigMode) {
|
||||
// Nothing special for CW, TX audio inputs are already muted.
|
||||
//case RIG_MODE_CW:
|
||||
//break;
|
||||
|
||||
case RIG_MODE_SSB:
|
||||
// Mute the incoming RX audio. Can't think of a good reason
|
||||
// to let RX audio in while we're transmitting.
|
||||
muteRxRigIn();
|
||||
|
||||
if (audioTxInput == TX_MIC_IN) {
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_MIC);
|
||||
updateTxMicIn();
|
||||
#if defined(FACTORY_CALIBRATION)
|
||||
USBSERIAL.println("==============================");
|
||||
USBSERIAL.println("Transmitting with Mic input");
|
||||
USBSERIAL.print("Mic gain: ");
|
||||
USBSERIAL.println(iopConfig.txMicInGain);
|
||||
USBSERIAL.print("Mic volume: ");
|
||||
USBSERIAL.println(iopConfig.txMicInVol);
|
||||
USBSERIAL.print("Mic calibration: ");
|
||||
USBSERIAL.println(iopConfig.txMicInCal);
|
||||
USBSERIAL.print("TX audio level: ");
|
||||
USBSERIAL.println(iopConfig.txRigOutLevel);
|
||||
USBSERIAL.print("TX audio calibration: ");
|
||||
USBSERIAL.println(iopConfig.txRigOutCal);
|
||||
USBSERIAL.println("==============================");
|
||||
#endif
|
||||
} else if (audioTxInput == TX_LINE_IN) {
|
||||
updateTxLineIn();
|
||||
}
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
// Mute the incoming RX audio. Can't think of a good reason
|
||||
// to let RX audio in while we're transmitting.
|
||||
muteRxRigIn();
|
||||
updateTxUSBIn();
|
||||
break;
|
||||
|
||||
case RIG_MODE_TEST:
|
||||
muteRxRigIn();
|
||||
updateTxTwoToneIn();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
// audioReceive()
|
||||
// This should be called anytime receive mode is entered. It should
|
||||
// in theory be called AFTER the actual transmit signal (key/PTT) is
|
||||
// removed from the Raduino, in order to ensure that any audio source
|
||||
// transitions occur before receive begins.
|
||||
void audioReceive()
|
||||
{
|
||||
switch(rigMode) {
|
||||
//case RIG_MODE_CW:
|
||||
//break;
|
||||
|
||||
case RIG_MODE_SSB:
|
||||
if (audioTxInput == TX_MIC_IN) {
|
||||
muteTxMicIn();
|
||||
audioCtrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
} else if (audioTxInput == TX_LINE_IN) {
|
||||
muteTxLineIn();
|
||||
}
|
||||
restoreRxRigIn();
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
muteTxUSBIn();
|
||||
restoreRxRigIn();
|
||||
break;
|
||||
|
||||
case RIG_MODE_TEST:
|
||||
muteTxTwoToneIn();
|
||||
restoreRxRigIn();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
void audioUpdate()
|
||||
{
|
||||
speechCompressor.update();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
void audioCalibrate(IOPConfig* c, char cmd, char subcmd, char parm, float value, bool set_value=true)
|
||||
void audioCalibrate(AudioConfig* c, char cmd, char subcmd, char parm, float value, bool set_value=true)
|
||||
{
|
||||
switch(cmd) {
|
||||
case 'r':
|
||||
@ -807,7 +696,7 @@ void audioDigiFilter()
|
||||
audioCtrl.eqFilter(4, lpFilter);
|
||||
audioCtrl.eqFilter(5, hpFilter);
|
||||
}
|
||||
|
||||
*/
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
||||
|
@ -3,11 +3,15 @@
|
||||
//======================================================================
|
||||
|
||||
#include "cat.h"
|
||||
#include "TxSwitch.h"
|
||||
|
||||
// make these messages static inside a function
|
||||
IOPMessage inBuf; // input message buffer
|
||||
IOPMessage outBuf; // output message buffer
|
||||
|
||||
extern CATSwitch catPTT;
|
||||
extern Rig rig;
|
||||
|
||||
//======================================================================
|
||||
// CAT from PC-to-IOP
|
||||
//
|
||||
@ -50,20 +54,32 @@ void processIOPCommand(IOPMessage const& m)
|
||||
if (m.len < 1) {
|
||||
return;
|
||||
} else {
|
||||
setRigMode(RigMode(m.data[0]));
|
||||
rig.switchMode(RigMode(m.data[0]));
|
||||
#if defined(DEBUG)
|
||||
switch(rigMode) {
|
||||
case RIG_MODE_CW:
|
||||
USBDEBUG("new mode - CW");
|
||||
switch(rig.modeNum()) {
|
||||
case RIG_MODE_CWL:
|
||||
USBDEBUG("new mode - CWL");
|
||||
break;
|
||||
case RIG_MODE_SSB:
|
||||
USBDEBUG("new mode - SSB");
|
||||
case RIG_MODE_CWU:
|
||||
USBDEBUG("new mode - CWU");
|
||||
break;
|
||||
case RIG_MODE_DIGI:
|
||||
USBDEBUG("new mode - DIGI");
|
||||
case RIG_MODE_LSB:
|
||||
USBDEBUG("new mode - LSB");
|
||||
break;
|
||||
case RIG_MODE_TEST:
|
||||
USBDEBUG("new mode - TEST");
|
||||
case RIG_MODE_USB:
|
||||
USBDEBUG("new mode - USB");
|
||||
break;
|
||||
case RIG_MODE_DGL:
|
||||
USBDEBUG("new mode - DGL");
|
||||
break;
|
||||
case RIG_MODE_DGU:
|
||||
USBDEBUG("new mode - DGU");
|
||||
break;
|
||||
case RIG_MODE_TTL:
|
||||
USBDEBUG("new mode - TTL");
|
||||
break;
|
||||
case RIG_MODE_TTU:
|
||||
USBDEBUG("new mode - TTU");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -71,11 +87,11 @@ void processIOPCommand(IOPMessage const& m)
|
||||
break;
|
||||
|
||||
case IOP_START_TX_COMMAND:
|
||||
catPTTOn();
|
||||
catPTT.press(rig.mode());
|
||||
break;
|
||||
|
||||
case IOP_STOP_TX_COMMAND:
|
||||
catPTTOff();
|
||||
catPTT.release(rig.mode());
|
||||
break;
|
||||
|
||||
case IOP_CW_CONFIG_MSG:
|
||||
@ -103,7 +119,7 @@ void processCalCommand(const char* buf)
|
||||
case 'R':
|
||||
case 't':
|
||||
case 'T':
|
||||
audioCalibrate(&iopConfig, cmd, subcmd, parm, value, (count == 4));
|
||||
//audioCalibrate(&rigConfig.audio, cmd, subcmd, parm, value, (count == 4));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1,11 +1,14 @@
|
||||
//======================================================================
|
||||
// config.h
|
||||
//
|
||||
// NOTE: Let's change the name of this file to RigConfig.h.
|
||||
//======================================================================
|
||||
|
||||
#ifndef __iop_config_h__
|
||||
#define __iop_config_h__
|
||||
|
||||
#include <iopcomm.h>
|
||||
//#include "rig.h"
|
||||
|
||||
#define KEYER_LEFT_PADDLE_PIN 16
|
||||
#define KEYER_RIGHT_PADDLE_PIN 17
|
||||
@ -15,12 +18,16 @@
|
||||
// There will be no pass-thru of any CAT.
|
||||
//#define FACTORY_CALIBRATION
|
||||
|
||||
// IOPConfig
|
||||
// Used to store configuration parameters during runtime, as well as to
|
||||
// save them to EEPROM.
|
||||
struct IOPConfig {
|
||||
//======================================================================
|
||||
// AudioConfig
|
||||
//======================================================================
|
||||
|
||||
class AudioConfig {
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// RECEIVE PARAMETERS
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// rig-in parameters (RX)
|
||||
uint8_t rxRigInLevel = 5;
|
||||
@ -38,35 +45,43 @@ struct IOPConfig {
|
||||
// USB-out parameters (RX)
|
||||
float rxUSBOutCal = 1.0;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// TRANSMIT PARAMETERS
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// NOTE: Default rig-out parameters are based on trying to hit a 25mVrms output to the
|
||||
// rig. This is based on some discussion at the following URL:
|
||||
//--------------------------------------------------------------------
|
||||
// NOTE: Default rig-out parameters are based on trying to hit a
|
||||
// 25mVrms output to the rig. This is based on some discussion at the
|
||||
// following URL:
|
||||
//
|
||||
// https://groups.io/g/BITX20/message/58951
|
||||
//
|
||||
// This may or may not be totally applicable. I believe it was for IMD/spurs on a pre-V5
|
||||
// version of the uBITX. So it may be OBE for my V5. It also alludes to modifications
|
||||
// to the transmit audio chain, which may be something I need to look into (i.e. increasing
|
||||
// This may or may not be totally applicable. I believe it was for
|
||||
// IMD/spurs on a pre-V5 version of the uBITX. So it may be OBE for
|
||||
// my V5. It also alludes to modifications to the transmit audio
|
||||
// chain, which may be something I need to look into (i.e. increasing
|
||||
// the gain on the initial mic pre-amp).
|
||||
//
|
||||
// Specifically, for the rig-out parameters:
|
||||
// line out level 31 = 1.16 V p-p
|
||||
// = 0.58 V peak
|
||||
// = 0.41 V rms = 410 mV rms
|
||||
// so output calibration needs to reduce that to 17.5 mV rms (70% of 25 mV rms)
|
||||
// so output calibration needs to reduce that to 17.5 mV rms (70%
|
||||
// of 25 mV rms)
|
||||
// txMicInCal = 0.043 ... seems pretty low...
|
||||
//
|
||||
// Likewise, default line-in (TX) parameters assume consumer line level
|
||||
// input, but with the default audio adaptor line-in level setting (5 = 1.33V p-p).
|
||||
// Likewise, default line-in (TX) parameters assume consumer line
|
||||
// level input, but with the default audio adaptor line-in level
|
||||
// setting (5 = 1.33V p-p).
|
||||
// line in level 5 = 1.33 V p-p
|
||||
// signal in = 0.894 V p-p
|
||||
// = 0.447 V peak
|
||||
// = 0.316 V rms = 316 mV rms
|
||||
// so input calibration needs to convert that to the 410 mV noted above (equivalent
|
||||
// for the microphone), so that when that signal gets to the rig-out, it gets
|
||||
// treated the same as the mic input.
|
||||
// so input calibration needs to convert that to the 410 mV noted
|
||||
// above (equivalent for the microphone), so that when that signal
|
||||
// gets to the rig-out, it gets treated the same as the mic input.
|
||||
// txLineInCal = 1.30
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// microphone-in parameters (TX)
|
||||
uint8_t txMicInGain = 12;
|
||||
@ -88,18 +103,54 @@ struct IOPConfig {
|
||||
// USB-out parameters (TX)- debug/monitor use only
|
||||
bool txUSBOutEnable = true;
|
||||
float txUSBOutCal = 1.0;
|
||||
|
||||
// SSB configuration
|
||||
SSBConfig ssb;
|
||||
|
||||
// Digi configuration
|
||||
DigiConfig digi;
|
||||
|
||||
// CW configuration
|
||||
CWConfig cw;
|
||||
};
|
||||
|
||||
extern IOPConfig iopConfig;
|
||||
//======================================================================
|
||||
// RigConfig
|
||||
// Used to store configuration parameters during runtime, as well as to
|
||||
// save them to EEPROM.
|
||||
//======================================================================
|
||||
|
||||
class RigConfig {
|
||||
public:
|
||||
// audio configuration
|
||||
AudioConfig audio;
|
||||
|
||||
// SSB configuration
|
||||
SSBConfig lsb{RX_FILTER_WIDE};
|
||||
SSBConfig usb{RX_FILTER_WIDE};
|
||||
|
||||
// DGT configuration
|
||||
DGTConfig dgl{RX_FILTER_WIDE};
|
||||
DGTConfig dgu{RX_FILTER_WIDE};
|
||||
|
||||
// CW configuration
|
||||
CWConfig cwl{
|
||||
KEYER_MODE_IAMBIC_A,
|
||||
false,
|
||||
15,
|
||||
3.0,
|
||||
700,
|
||||
RX_FILTER_WIDE,
|
||||
};
|
||||
CWConfig cwu{
|
||||
KEYER_MODE_IAMBIC_A,
|
||||
false,
|
||||
15,
|
||||
3.0,
|
||||
700,
|
||||
RX_FILTER_WIDE,
|
||||
};
|
||||
|
||||
// TT configuration
|
||||
TTConfig ttl{RX_FILTER_WIDE};
|
||||
TTConfig ttu{RX_FILTER_WIDE};
|
||||
|
||||
// General rig configuration entries.
|
||||
RigMode mode = RIG_MODE_LSB;
|
||||
};
|
||||
|
||||
extern RigConfig rigConfig;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -11,8 +11,10 @@
|
||||
#include "eeprom.h"
|
||||
#include "keyer.h"
|
||||
|
||||
#define PTT_KEY_OUT_PIN 2
|
||||
|
||||
// comment this out to disable debugging code
|
||||
//#define DEBUG
|
||||
#define DEBUG
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define USBDEBUG(x) USBSERIAL.print("IOP: "); USBSERIAL.println(x);
|
||||
@ -34,10 +36,35 @@ enum TxState {
|
||||
TX_KEYER,
|
||||
};
|
||||
|
||||
extern RigMode rigMode;
|
||||
//extern RigMode rigMode;
|
||||
|
||||
extern bool keyerKeyDown;
|
||||
|
||||
//======================================================================
|
||||
// Keying functions.
|
||||
//
|
||||
// These are simple functions to assert the key line from the IOP to the
|
||||
// Raduino.
|
||||
//======================================================================
|
||||
|
||||
inline void initKeyLine()
|
||||
{
|
||||
pinMode(PTT_KEY_OUT_PIN, OUTPUT);
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
}
|
||||
|
||||
inline void setKeyDown()
|
||||
{
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
}
|
||||
|
||||
inline void setKeyUp()
|
||||
{
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
|
@ -3,340 +3,175 @@
|
||||
//======================================================================
|
||||
|
||||
#include <iopcomm.h>
|
||||
#include "audio.h"
|
||||
#include "config.h"
|
||||
#include "ubitx_iop.h"
|
||||
#include "keyer.h"
|
||||
#include "rig.h"
|
||||
#include "TxSwitch.h"
|
||||
|
||||
#include <Bounce2.h>
|
||||
#define BOUNCE_WITH_PROMPT_DETECTION
|
||||
Keyer keyer{15, 3.0}; // NOTE: make configurable
|
||||
|
||||
RigMode rigMode = RIG_MODE_SSB;
|
||||
//RxFilter rxFilter = RX_FILTER_NORMAL;
|
||||
IOPConfig iopConfig;
|
||||
RigConfig rigConfig;
|
||||
RigAudio rigAudio{rigConfig.audio};
|
||||
Rig rig{rigConfig, rigAudio};
|
||||
|
||||
#define MIC_PTT_PIN 21
|
||||
#define LINE_PTT_PIN 20
|
||||
#define PTT_KEY_OUT_PIN 2
|
||||
CATSwitch catPTT;
|
||||
//MicSwitch micPTTHelper;
|
||||
GPIOSwitch micPTT(true, MIC_PTT_PIN);
|
||||
//LineSwitch linePTTHelper;
|
||||
GPIOSwitch linePTT(false, LINE_PTT_PIN);
|
||||
|
||||
Bounce micPTT = Bounce();
|
||||
Bounce linePTT = Bounce();
|
||||
|
||||
TxState txState = TX_OFF;
|
||||
|
||||
Keyer keyer(15, 3.0); // need to make configurable
|
||||
|
||||
//SSBMenu ssbMenu();
|
||||
//DigiMenu digiMenu();
|
||||
//CWMenu cwMenu();
|
||||
//MenuItem* dspMenu = &ssbMenu;
|
||||
elapsedMillis frameMillis;
|
||||
unsigned frameCounter;
|
||||
|
||||
//======================================================================
|
||||
// catPTTOn()
|
||||
//
|
||||
// NOTE: Should probably move this to cat.ino.
|
||||
//======================================================================
|
||||
|
||||
void catPTTOn()
|
||||
{
|
||||
// Check if we're already transmitting. If so, then this command
|
||||
// does nothing: existing transmission, from existing source and PTT,
|
||||
// will continue.
|
||||
if (txState != TX_OFF) return;
|
||||
|
||||
switch(rigMode) {
|
||||
// CAT should not start or stop TX in CW mode... we really should
|
||||
// not even get this command. But maybe the rig control software is
|
||||
// doing it (but then, we should inhibit this in the Raduino).
|
||||
//case RIG_MODE_CW:
|
||||
//break;
|
||||
|
||||
case RIG_MODE_SSB:
|
||||
// In SSB mode, CAT-PTT will always (de-)activate the Line-In TX
|
||||
// audio source.
|
||||
txState = TX_CAT;
|
||||
audioSelectTxInput(TX_LINE_IN); // in case Mic-In is selected
|
||||
audioTransmit();
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
// In Digital (USB) mode, CAT-PTT will always (de-)activate the
|
||||
// USB-In TX audio source.
|
||||
txState = TX_CAT;
|
||||
audioTransmit();
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// catPTTOff()
|
||||
//
|
||||
// NOTE: Should probably move this to cat.ino.
|
||||
//======================================================================
|
||||
|
||||
void catPTTOff()
|
||||
{
|
||||
// If we're not transmitting, or the active PTT is not CAT, then this
|
||||
// command does nothing: CAT cannot interrupt other transmissions.
|
||||
if (txState != TX_CAT) return;
|
||||
|
||||
switch(rigMode) {
|
||||
// CAT should not start or stop TX in CW mode... we really should
|
||||
// not even get this command. But maybe the rig control software is
|
||||
// doing it (but then, we should inhibit this in the Raduino).
|
||||
//case RIG_MODE_CW:
|
||||
//break;
|
||||
|
||||
case RIG_MODE_SSB:
|
||||
// In SSB mode, CAT-PTT will always (de-)activate the Line-In TX
|
||||
// audio source.
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
audioReceive();
|
||||
txState = TX_OFF;
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
// In Digital (USB) mode, CAT-PTT will always (de-)activate the
|
||||
// USB-In TX audio source.
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
audioReceive();
|
||||
txState = TX_OFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// checkMicPTT()
|
||||
//======================================================================
|
||||
|
||||
void checkMicPTT()
|
||||
{
|
||||
micPTT.update();
|
||||
|
||||
// If we're transmitting, then we're just going to check if Mic-PTT
|
||||
// was released--the Mic-PTT can always be used to terminate a
|
||||
// transmission from another source.
|
||||
if ((txState != TX_OFF) && micPTT.rose()) {
|
||||
USBDEBUG("mic PTT released");
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
// In CW mode, we get a sidetone from the uBITX, so we don't mute
|
||||
// the receive audio.
|
||||
if (rigMode != RIG_MODE_CW) audioReceive();
|
||||
txState = TX_OFF;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((txState == TX_OFF) && micPTT.fell()) {
|
||||
USBDEBUG("mic PTT depressed");
|
||||
switch(rigMode) {
|
||||
case RIG_MODE_CW:
|
||||
txState = TX_MIC;
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
|
||||
case RIG_MODE_SSB:
|
||||
txState = TX_MIC;
|
||||
audioSelectTxInput(TX_MIC_IN);
|
||||
audioTransmit();
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
// Mic PTT actuation during Digital does nothing.
|
||||
break;
|
||||
|
||||
case RIG_MODE_TEST:
|
||||
txState = TX_MIC;
|
||||
audioSelectTxInput(TX_TEST_IN);
|
||||
audioTransmit();
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// checkLinePTT()
|
||||
//======================================================================
|
||||
|
||||
void checkLinePTT()
|
||||
{
|
||||
linePTT.update();
|
||||
|
||||
// If we're transmitting, then we're just going to check if Line-PTT
|
||||
// was released--the Line-PTT can always be used to terminate a
|
||||
// transmission from another source.
|
||||
if ((txState != TX_OFF) && linePTT.rose()) {
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
// In CW mode, we get a sidetone from the uBITX, so we don't mute
|
||||
// the receive audio.
|
||||
if (rigMode != RIG_MODE_CW) audioReceive();
|
||||
txState = TX_OFF;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((txState == TX_OFF) && linePTT.fell()) {
|
||||
switch(rigMode) {
|
||||
case RIG_MODE_CW:
|
||||
txState = TX_LINE;
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
|
||||
case RIG_MODE_SSB:
|
||||
txState = TX_LINE;
|
||||
audioSelectTxInput(TX_LINE_IN);
|
||||
audioTransmit();
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
// Line PTT actuation during Digital does nothing.
|
||||
break;
|
||||
|
||||
case RIG_MODE_TEST:
|
||||
txState = TX_LINE;
|
||||
audioSelectTxInput(TX_TEST_IN);
|
||||
audioTransmit();
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
void setRigMode(RigMode m)
|
||||
{
|
||||
rigMode = m;
|
||||
|
||||
switch(rigMode) {
|
||||
case RIG_MODE_SSB:
|
||||
case RIG_MODE_TEST:
|
||||
// SSB sets the TX audio input to line-in. Note that this will be
|
||||
// automatically overridden by mic-in, if the mic PTT is pressed.
|
||||
audioSelectTxInput(TX_LINE_IN);
|
||||
// audioSSBFilter();
|
||||
// dspMenu = &ssbMenu;
|
||||
break;
|
||||
|
||||
case RIG_MODE_DIGI:
|
||||
// Digi sets the TX audio input to USB-in. Keying in this case must
|
||||
// be via CAT control. Digital modes can also be used through the
|
||||
// line-in, but the rig mode should be set to SSB in that case, and
|
||||
// the rig could be keyed either via the line-in PTT, or via CAT.
|
||||
// Digimodes could also be used through the mic-in, but in that case,
|
||||
// the mic PTT line would need to be keyed by the computer rather
|
||||
// than using CAT for PTT control.
|
||||
audioSelectTxInput(TX_USB_IN);
|
||||
// audioDigiFilter();
|
||||
// dspMenu = &digiMenu;
|
||||
break;
|
||||
|
||||
case RIG_MODE_CW:
|
||||
// CW just gets the radio off of Mic-In; but it won't use Line-In.
|
||||
audioSelectTxInput(TX_LINE_IN);
|
||||
// audioCWFilter();
|
||||
// dspMenu = &cwMenu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
//elapsedMillis frame10hz = 0;
|
||||
|
||||
void setup() {
|
||||
// put your setup code here, to run once:
|
||||
initCAT(38400, SERIAL_8N1);
|
||||
USBDEBUG("setup started");
|
||||
|
||||
AudioMemory(16);
|
||||
AudioMemory(20); // NOTE: Need to fine tune this. Have had errors due to this being too low.
|
||||
|
||||
micPTT.attach(MIC_PTT_PIN, INPUT_PULLUP);
|
||||
micPTT.interval(25);
|
||||
linePTT.attach(LINE_PTT_PIN, INPUT_PULLUP);
|
||||
linePTT.interval(25);
|
||||
initKeyLine();
|
||||
rigAudio.init();
|
||||
|
||||
pinMode(PTT_KEY_OUT_PIN, OUTPUT);
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
frameCounter = 0;
|
||||
frameMillis = 0;
|
||||
|
||||
audioInit();
|
||||
USBDEBUG("setup completed");
|
||||
// audioInit();
|
||||
/*
|
||||
#if defined(FACTORY_CALIBRATION)
|
||||
setRigMode(RIG_MODE_TEST);
|
||||
#else
|
||||
setRigMode(RIG_MODE_SSB);
|
||||
#endif
|
||||
|
||||
//frame10Hz = 0;
|
||||
*/
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
void loop() {
|
||||
// elapsedMillis elapsed = 0;
|
||||
RigMode oldRigMode = rigMode;
|
||||
//RxFilter oldRxFilter = rxFilter;
|
||||
void loop()
|
||||
{
|
||||
static char frame_status[100];
|
||||
static bool paddle_loop = false;
|
||||
|
||||
switch(rigMode) {
|
||||
case RIG_MODE_CW:
|
||||
RigMode oldRigMode;
|
||||
|
||||
frameCounter++;
|
||||
|
||||
if (rig.isCWMode()) {
|
||||
if (keyer.do_paddles()) {
|
||||
if (keyer.is_down()) {
|
||||
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
||||
} else {
|
||||
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
||||
|
||||
// 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();
|
||||
}
|
||||
// No break... if the paddle is not active, I want this to fall
|
||||
// through to checkMicPTT etc... but return early if the paddle is
|
||||
// active, to maximize responsiveness. Probably could just use
|
||||
// 'if' statements here instead of the 'switch'.
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
checkMicPTT();
|
||||
checkLinePTT();
|
||||
serviceCAT();
|
||||
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 ((rigMode != oldRigMode)) { // || (rxFilter != oldRxFilter)) {
|
||||
switch(rigMode) {
|
||||
case RIG_MODE_SSB:
|
||||
sendIOPSSBStatus(iopConfig.ssb);
|
||||
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_DIGI:
|
||||
sendIOPDigiStatus(iopConfig.digi);
|
||||
case RIG_MODE_USB:
|
||||
USBDEBUG("sending USB mode status");
|
||||
sendIOPSSBStatus(rigConfig.usb);
|
||||
break;
|
||||
|
||||
case RIG_MODE_CW:
|
||||
sendIOPCWStatus(iopConfig.cw);
|
||||
case RIG_MODE_DGL:
|
||||
USBDEBUG("sending DGL mode status");
|
||||
sendIOPDGTStatus(rigConfig.dgl);
|
||||
break;
|
||||
|
||||
case RIG_MODE_TEST:
|
||||
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;
|
||||
}
|
||||
|
||||
audioUpdate();
|
||||
//dspMenu->update();
|
||||
|
||||
/*
|
||||
#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
|
||||
if (frameMillis > 1000) {
|
||||
#if defined(DEBUG)
|
||||
sprintf(frame_status, "update: %d ms, %d frames\n", frameMillis, frameCounter);
|
||||
USBDEBUG(frame_status);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
//audioUpdate(); // was used to update the speech compressor
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user