9c1a490963
that allows messages to go back from the IOP to Raduino. I don't know if actual CAT from the PC works currently, however.
344 lines
9.0 KiB
C++
344 lines
9.0 KiB
C++
//======================================================================
|
|
// ubitx_iop.ino
|
|
//======================================================================
|
|
|
|
#include <iopcomm.h>
|
|
#include "ubitx_iop.h"
|
|
|
|
#include <Bounce2.h>
|
|
#define BOUNCE_WITH_PROMPT_DETECTION
|
|
|
|
RigMode rigMode = RIG_MODE_SSB;
|
|
RxFilter rxFilter = RX_FILTER_NORMAL;
|
|
IOPConfig iopConfig;
|
|
|
|
#define MIC_PTT_PIN 21
|
|
#define LINE_PTT_PIN 20
|
|
#define PTT_KEY_OUT_PIN 2
|
|
|
|
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;
|
|
|
|
//======================================================================
|
|
// 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);
|
|
|
|
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);
|
|
|
|
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;
|
|
|
|
switch(rigMode) {
|
|
case RIG_MODE_CW:
|
|
if (keyer.do_paddles()) {
|
|
if (keyer.is_down()) {
|
|
digitalWrite(PTT_KEY_OUT_PIN, LOW);
|
|
} else {
|
|
digitalWrite(PTT_KEY_OUT_PIN, HIGH);
|
|
}
|
|
// 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();
|
|
}
|
|
|
|
// send current status @ 10 Hz
|
|
//if (frame10Hz > 100) {
|
|
if ((rigMode != oldRigMode) || (rxFilter != oldRxFilter)) {
|
|
switch(rigMode) {
|
|
case RIG_MODE_SSB:
|
|
sendIOPSSBStatus(iopConfig.ssb);
|
|
break;
|
|
|
|
case RIG_MODE_DIGI:
|
|
sendIOPDigiStatus(iopConfig.digi);
|
|
break;
|
|
|
|
case RIG_MODE_CW:
|
|
sendIOPCWStatus(iopConfig.cw);
|
|
break;
|
|
|
|
case RIG_MODE_TEST:
|
|
sendIOPTestStatus();
|
|
}
|
|
//frame10Hz = 0;
|
|
}
|
|
|
|
//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
|
|
}
|
|
*/
|
|
}
|
|
|
|
//======================================================================
|
|
// EOF
|
|
//======================================================================
|