Initial commit.
This commit is contained in:
commit
8d88437702
20
digibox/cat_serial.h
Normal file
20
digibox/cat_serial.h
Normal file
@ -0,0 +1,20 @@
|
||||
//======================================================================
|
||||
// cat_serial.h
|
||||
//======================================================================
|
||||
|
||||
#ifndef __cat_serial_h__
|
||||
#define __cat_serial_h__
|
||||
|
||||
namespace cat_serial
|
||||
{
|
||||
|
||||
void init(cat_serial_cfg& c);
|
||||
void update(int msec);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
368
digibox/dsp_audio.cpp
Normal file
368
digibox/dsp_audio.cpp
Normal file
@ -0,0 +1,368 @@
|
||||
//======================================================================
|
||||
// dsp_audio.cpp
|
||||
//======================================================================
|
||||
|
||||
#include <dynamicFilters.h>
|
||||
#include <effect_compressor_fb.h>
|
||||
#include "dsp_audio.h"
|
||||
|
||||
#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
|
||||
|
||||
#define RX_BPF_ONLY 0
|
||||
#define RX_NOTCH_ON 1
|
||||
|
||||
#include <Audio.h>
|
||||
#include <Wire.h>
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
#include <SerialFlash.h>
|
||||
|
||||
namespace dsp_audio
|
||||
{
|
||||
// GUItool: begin automatically generated code
|
||||
AudioInputI2S line_in; //xy=148.9999771118164,131
|
||||
AudioInputUSB usb_in; //xy=148.9999771118164,303
|
||||
AudioSynthWaveformSine sidetone; //xy=150.9999771118164,214
|
||||
AudioSynthWaveformSine sine2; //xy=337.9999771118164,482
|
||||
AudioSynthWaveformSine sine1; //xy=338.9999771118164,428
|
||||
AudioAnalyzeFFT256 rx_fft; //xy=370.0127944946289,103.02459716796875
|
||||
AudioAnalyzeRMS rx_rms; //xy=376.9999771118164,20
|
||||
AudioAnalyzePeak rx_peak; //xy=376.9999771118164,65
|
||||
AudioEffectFade tx_comp; //xy=400.99999237060547,260.99999809265137
|
||||
AudioAnalyzeRMS tx_comp_rms; //xy=402.9999771118164,224
|
||||
AudioMixer4 rx_in_mix; //xy=458.9999771118164,163
|
||||
AudioFilterFIR rx_fir_filter; //xy=628.0000839233398,135.00000476837158
|
||||
AudioMixer4 tx_mix; //xy=666.9999771118164,321
|
||||
AudioFilterBiquad rx_biquad_filter; //xy=765.7827301025391,183.02459716796875
|
||||
AudioAnalyzeRMS tx_rms; //xy=855.9999771118164,449
|
||||
AudioAnalyzePeak tx_peak; //xy=857.9999771118164,393
|
||||
AudioAmplifier tx_line_out_cal; //xy=906.9999771118164,255
|
||||
AudioAmplifier tx_usb_out_cal; //xy=907.9999771118164,312
|
||||
AudioMixer4 rx_out_mix; //xy=933.78271484375,119.02459144592285
|
||||
AudioAmplifier rx_usb_out_cal; //xy=1155,180.99999904632568
|
||||
AudioAmplifier rx_line_out_cal; //xy=1156.9999771118164,109.00000381469727
|
||||
AudioAmplifier rx_spkr_out_cal; //xy=1167.0000076293945,50
|
||||
AudioOutputAnalog spkr_out; //xy=1307.000015258789,53
|
||||
AudioOutputUSB usb_out; //xy=1332.999984741211,291.0000114440918
|
||||
AudioOutputI2S line_out; //xy=1374.9999618530273,207.0000057220459
|
||||
AudioConnection patchCord1(line_in, 0, rx_rms, 0);
|
||||
AudioConnection patchCord2(line_in, 0, rx_peak, 0);
|
||||
AudioConnection patchCord3(line_in, 0, rx_in_mix, 0);
|
||||
AudioConnection patchCord4(line_in, 0, rx_fft, 0);
|
||||
AudioConnection patchCord5(line_in, 1, tx_comp, 0);
|
||||
AudioConnection patchCord6(line_in, 1, tx_comp_rms, 0);
|
||||
AudioConnection patchCord7(usb_in, 0, rx_in_mix, 1);
|
||||
AudioConnection patchCord8(usb_in, 1, tx_mix, 1);
|
||||
AudioConnection patchCord9(sidetone, 0, rx_in_mix, 2);
|
||||
AudioConnection patchCord10(sine2, 0, tx_mix, 3);
|
||||
AudioConnection patchCord11(sine1, 0, tx_mix, 2);
|
||||
AudioConnection patchCord12(tx_comp, 0, tx_mix, 0);
|
||||
AudioConnection patchCord13(rx_in_mix, rx_fir_filter);
|
||||
AudioConnection patchCord14(rx_fir_filter, rx_biquad_filter);
|
||||
AudioConnection patchCord15(rx_fir_filter, 0, rx_out_mix, 0);
|
||||
AudioConnection patchCord16(tx_mix, tx_line_out_cal);
|
||||
AudioConnection patchCord17(tx_mix, tx_usb_out_cal);
|
||||
AudioConnection patchCord18(tx_mix, tx_peak);
|
||||
AudioConnection patchCord19(tx_mix, tx_rms);
|
||||
AudioConnection patchCord20(rx_biquad_filter, 0, rx_out_mix, 1);
|
||||
AudioConnection patchCord21(tx_line_out_cal, 0, line_out, 1);
|
||||
AudioConnection patchCord22(tx_usb_out_cal, 0, usb_out, 1);
|
||||
AudioConnection patchCord23(rx_out_mix, spkr_out_cal);
|
||||
AudioConnection patchCord24(rx_out_mix, rx_line_out_cal);
|
||||
AudioConnection patchCord25(rx_out_mix, rx_usb_out_cal);
|
||||
AudioConnection patchCord26(rx_usb_out_cal, 0, usb_out, 0);
|
||||
AudioConnection patchCord27(rx_line_out_cal, 0, line_out, 0);
|
||||
AudioConnection patchCord28(spkr_out_cal, spkr_out);
|
||||
AudioControlSGTL5000 audioCtrl; //xy=648,517
|
||||
// GUItool: end automatically generated code
|
||||
|
||||
class configurator
|
||||
{
|
||||
public:
|
||||
configurator(dsp_audio_cfg& c): data(c) {}
|
||||
dsp_audio_cfg& data;
|
||||
} *cfg = nullptr;
|
||||
};
|
||||
|
||||
void dsp_audio::init(dsp_audio_cfg& c) {
|
||||
USBDEBUG("audio initialization started");
|
||||
|
||||
if (cfg != nullptr) {
|
||||
delete cfg;
|
||||
}
|
||||
cfg = new configurator(c);
|
||||
|
||||
audio_ctrl.enable();
|
||||
audio_ctrl.adcHighPassFilterEnable(); // default
|
||||
audio_ctrl.dacVolume(1.0); // default
|
||||
audio_ctrl.dacVolumeRampDisable(); // not default; just trying to cull out culprits for my high freq hiss
|
||||
audio_ctrl.audioProcessorDisable();
|
||||
audio_ctrl.autoVolumeDisable();
|
||||
audio_ctrl.surroundSoundDisable();
|
||||
audio_ctrl.enhanceBassDisable();
|
||||
audio_ctrl.eqSelect(FLAT_FREQUENCY); // eventually, use this to smooth out the normal uBITX passband
|
||||
|
||||
audio_ctrl.muteHeadphone(); // not using the headphone output
|
||||
audio_ctrl.volume(0.0); // not using the headphone output
|
||||
audio_ctrl.inputSelect(AUDIO_INPUT_LINEIN); // required for RX audio
|
||||
audio_ctrl.unmuteLineout(); // required for RX audio
|
||||
|
||||
audio_ctrl.lineInLevel(cfg.data.rx_rig_in_level, cfg.data.tx_line_in_level); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audio_ctrl.lineOutLevel(cfg.data.rx_line_out_level, cfg.data.tx_rig_out_level); // NOTE: need to see if this persists through input changes (see mic gain...)
|
||||
audio_ctrl.micGain(cfg.data.tx_mic_in_gain); // superfluous, as I have to do this anytime I switch to mic for some reason
|
||||
|
||||
// configure line input
|
||||
audio_ctrl.lineInLevel(cfg.data.rx_rig_in_level, cfg.data.tx_line_in_level);
|
||||
|
||||
// configure line output
|
||||
tx_rig_out_cal.gain(cfg.data.tx_rig_out_cal);
|
||||
audio_ctrl.lineOutLevel(cfg.data.rx_line_out_level, cfg.data.tx_rig_out_level);
|
||||
|
||||
// configure "receive" of USB audio input (debug only)
|
||||
if (cfg.data.rx_usb_in_enable) {
|
||||
rx_in_mix.gain(RX_USB_IN, cfg.data.rx_usb_in_vol * cfg.data.rx_usb_in_cal);
|
||||
} else {
|
||||
rx_in_mix.gain(RX_USB_IN, 0.0);
|
||||
}
|
||||
|
||||
// configure USB audio output of transmit audio (useful for debug)
|
||||
if (cfg.data.tx_usb_out_enable) {
|
||||
tx_usb_out_cal.gain(cfg.data.tx_usb_out_cal);
|
||||
} else {
|
||||
tx_usb_out_cal.gain(0.0);
|
||||
}
|
||||
|
||||
// setup the two-tone generator
|
||||
sine1.frequency(700);
|
||||
sine2.frequency(1900);
|
||||
sine1.amplitude(0);
|
||||
sine2.amplitude(0);
|
||||
|
||||
// no separate filter amp; just need to appropriately set the rx_out_mix values
|
||||
rx_out_mix.gain(RX_BPF_ONLY, 1.0);
|
||||
rx_out_mix.gain(RX_NOTCH_ON, 0.0);
|
||||
|
||||
// for now, just pass through the compressor
|
||||
tx_comp.disable();
|
||||
|
||||
// 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++) {
|
||||
rx_in_mix.gain(i, 0.0);
|
||||
tx_mix.gain(i, 0.0);
|
||||
}
|
||||
|
||||
audio_equalizer();
|
||||
|
||||
USBDEBUG("audio initialization completed");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_rx() {
|
||||
rx_in_mix.gain(RX_RIG_IN, 0.0);
|
||||
USBDEBUG("RX audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_rx() {
|
||||
audio_ctrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
rx_in_mix.gain(RX_RIG_IN, cfg.data.rx_rig_in_vol * cfg.data.rx_rig_in_cal);
|
||||
USBDEBUG("RX audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_all_tx() {
|
||||
mute_mic_in();
|
||||
mute_line_in();
|
||||
mute_usb_in();
|
||||
mute_twotone_in();
|
||||
USBDEBUG("all TX audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_mic_in() {
|
||||
tx_mix.gain(TX_LINE_IN, 0.0);
|
||||
USBDEBUG("Mic In audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_mic_in() {
|
||||
audio_ctrl.inputSelect(AUDIO_INPUT_MIC);
|
||||
audio_ctrl.micGain(cfg.data.tx_mic_in_gain);
|
||||
tx_mix.gain(TX_LINE_IN, cfg.data.tx_mic_in_vol * cfg.data.tx_mic_in_cal);
|
||||
USBDEBUG("Mic In audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_line_in() {
|
||||
tx_mix.gain(TX_LINE_IN, 0.0);
|
||||
USBDEBUG("Line In audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_line_in() {
|
||||
audio_ctrl.inputSelect(AUDIO_INPUT_LINEIN);
|
||||
tx_mix.gain(TX_LINE_IN, cfg.data.tx_line_in_vol * cfg.data.tx_line_in_cal);
|
||||
USBDEBUG("Line In audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_usb_in() {
|
||||
tx_mix.gain(TX_USB_IN, 0.0);
|
||||
USBDEBUG("USB In audio muted");
|
||||
}
|
||||
void dsp_audio::unmuteUSBIn() {
|
||||
tx_mix.gain(TX_USB_IN, cfg.data.tx_usb_in_vol * cfg.data.tx_usb_in_cal);
|
||||
USBDEBUG("USB In audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_twotone_in() {
|
||||
tx_mix.gain(TX_TEST_IN, 0.0);
|
||||
tx_mix.gain(TX_TEST_IN + 1, 0.0);
|
||||
sine1.amplitude(0.0);
|
||||
sine2.amplitude(0.0);
|
||||
USBDEBUG("Two Tone audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_twotone_in() {
|
||||
sine1.amplitude(0.5);
|
||||
sine2.amplitude(0.5);
|
||||
tx_mix.gain(TX_TEST_IN, cfg.data.tx_sine1_vol);
|
||||
tx_mix.gain(TX_TEST_IN + 1, cfg.data.tx_sine2_vol);
|
||||
USBDEBUG("Two Tone audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_spkr_out() {
|
||||
rx_spkr_out_cal.gain(0.0);
|
||||
USBDEBUG("Speaker Out audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_spkr_out() {
|
||||
rx_spkr_out_cal.gain(cfg.data.rx_spkr_out_cal);
|
||||
USBDEBUG("Speaker Out audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_line_out() {
|
||||
rx_line_out_cal.gain(0.0);
|
||||
USBDEBUG("Line Out audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_line_out() {
|
||||
rx_line_out_cal.gain(cfg.data.rx_line_out_cal);
|
||||
USBDEBUG("Line Out audio unmuted");
|
||||
}
|
||||
|
||||
void dsp_audio::mute_usb_out() {
|
||||
rx_usb_out_cal.gain(0.0);
|
||||
USBDEBUG("USB Out audio muted");
|
||||
}
|
||||
|
||||
void dsp_audio::unmute_usb_out() {
|
||||
rx_usb_out_cal.gain(cfg.data.rx_usb_out_cal);
|
||||
USBDEBUG("USB Out audio unmuted");
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// bp_filter
|
||||
//
|
||||
// Band Pass Filter methods.
|
||||
//======================================================================
|
||||
|
||||
bp_filter::bp_filter(): filter(filterRX), amp(filterAmp) {}
|
||||
|
||||
bp_filter::bp_filter(AudioFilterFIR& f, AudioAmplifier& a): filter(f), amp(a) {}
|
||||
|
||||
void bp_filter::init(const bpf_config& cfg) {
|
||||
set_band(cfg.lo_freq, cfg.hi_freq);
|
||||
set_gain(cfg.gain);
|
||||
}
|
||||
|
||||
void bp_filter::set_band(double f1, double f2) {
|
||||
freq_lo = f1;
|
||||
freq_hi = f2;
|
||||
}
|
||||
|
||||
void bp_filter::set_freq_lo(double f) { freq_lo = f; }
|
||||
|
||||
void bp_filter::set_freq_hi(double f) { freq_hi = f; }
|
||||
|
||||
void bp_filter::set_center_and_width(double c, double w) {
|
||||
freq_lo = c - (0.5 * w);
|
||||
freq_hi = c + (0.5 * w);
|
||||
}
|
||||
|
||||
void bp_filter::set_center(double c) {
|
||||
double w = freq_hi - freq_lo;
|
||||
set_center_and_width(c, w);
|
||||
}
|
||||
|
||||
void bp_filter::set_width(double w) {
|
||||
double c = (freq_lo + freq_hi) * 0.5;
|
||||
set_center_and_width(c, w);
|
||||
}
|
||||
|
||||
void bp_filter::set_gain(double g) { recovery = g; }
|
||||
|
||||
void bp_filter::enable() {
|
||||
audioFilter(coefficients, NUM_COEFFICIENTS, ID_BANDPASS, W_HAMMING, freq_lo, freq_hi);
|
||||
filter.begin(coefficients, NUM_COEFFICIENTS);
|
||||
amp.gain(recovery);
|
||||
}
|
||||
|
||||
void bp_filter::disable() {
|
||||
filter.begin(FIR_PASSTHRU, NUM_COEFFICIENTS);
|
||||
amp.gain(1.0);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
speech_comp::speech_comp(comp_config* cfg) :
|
||||
config_(cfg), comp_(compTX), amp_(compAmp), rms_(compRMS) {}
|
||||
|
||||
void speech_comp::enable()
|
||||
{
|
||||
config_->enabled = true;
|
||||
comp_.begin(1, config_->threshold, config_->ratio); // Need to make configurable
|
||||
amp_.gain(config_->gain);
|
||||
}
|
||||
|
||||
void speech_comp::disable()
|
||||
{
|
||||
config_->enabled = false;
|
||||
comp_.disable();
|
||||
amp_.gain(1.0);
|
||||
}
|
||||
|
||||
// Speech compressor code based on post by 'hyperdyne': https://forum.pjrc.com/threads/36245-Changing-Pitch-of-Voice
|
||||
|
||||
void speech_comp::update()
|
||||
{
|
||||
float rms_cur;
|
||||
if (config_->enabled && rms_.available()) {
|
||||
rms_cur = rms_.read();
|
||||
env_ = rms_cur + (alpha_ * (env_ - rms_cur));
|
||||
comp_.update_pwr(env_);
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
void dsp_audio::audio_equalizer()
|
||||
{
|
||||
static int eqFilter1[5];
|
||||
|
||||
audioCtrl.audioPreProcessorEnable();
|
||||
audioCtrl.eqSelect(PARAMETRIC_EQUALIZER);
|
||||
// calcBiquad(FilterType,FrequencyC,dBgain,Q,QuantizationUnit,SampleRate,int*);
|
||||
calcBiquad(FILTER_PARAEQ, 2700, 6, 0.707, 524288, 44100, eqFilter1);
|
||||
// calcBiquad(FILTER_HIPASS, 100, 0, 0.707, 524288, 44100, hpFilter);
|
||||
audioCtrl.eqFilter(0, eqFilter1);
|
||||
// audioCtrl.eqFilter(1, hpFilter);
|
||||
// audioCtrl.eqFilter(2, lpFilter);
|
||||
// audioCtrl.eqFilter(3, hpFilter);
|
||||
// audioCtrl.eqFilter(4, lpFilter);
|
||||
// audioCtrl.eqFilter(5, hpFilter);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
120
digibox/dsp_audio.h
Normal file
120
digibox/dsp_audio.h
Normal file
@ -0,0 +1,120 @@
|
||||
//======================================================================
|
||||
// dsp_audio.h
|
||||
//======================================================================
|
||||
|
||||
#ifndef __dsp_audio_h__
|
||||
#define __dsp_audio_h__
|
||||
|
||||
#include <Audio.h>
|
||||
#include <dynamicFilters.h>
|
||||
#include <effect_compressor_fb.h>
|
||||
#include "config.h"
|
||||
|
||||
namespace dsp_audio
|
||||
{
|
||||
|
||||
void init(dsp_audio_cfg& c);
|
||||
void update(int msec);
|
||||
|
||||
void mute_rx();
|
||||
void unmute_rx();
|
||||
|
||||
void mute_all_tx();
|
||||
|
||||
void mute_mic_in();
|
||||
void unmute_mic_in();
|
||||
|
||||
void mute_line_in();
|
||||
void unmute_line_in();
|
||||
|
||||
void mute_usb_in();
|
||||
void unmute_usb_in();
|
||||
|
||||
void mute_twotone_in();
|
||||
void unmute_twotone_in();
|
||||
|
||||
void mute_spkr_out();
|
||||
void unmute_spkr_out();
|
||||
|
||||
void mute_line_out();
|
||||
void unmute_line_out();
|
||||
|
||||
void mute_usb_out();
|
||||
void unmute_usb_out();
|
||||
|
||||
//======================================================================
|
||||
|
||||
class bp_filter {
|
||||
|
||||
public:
|
||||
bp_filter();
|
||||
bp_filter(AudioFilterFIR& f, AudioAmplifier& a);
|
||||
void init(const bpf_config& cfg);
|
||||
void set_band(double f1, double f2);
|
||||
void set_freq_lo(double f);
|
||||
void set_freq_hi(double f);
|
||||
void set_center_and_width(double c, double w);
|
||||
void set_center(double c);
|
||||
void set_width(double w);
|
||||
void set_gain(double g);
|
||||
void enable();
|
||||
void disable();
|
||||
|
||||
private:
|
||||
|
||||
double freq_lo;
|
||||
double freq_hi;
|
||||
short int window;
|
||||
short int coeff;
|
||||
float recovery; // recovery amplifier value
|
||||
|
||||
AudioFilterFIR& filter; // = &filterRX;
|
||||
AudioAmplifier& amp;
|
||||
short coefficients[NUM_COEFFICIENTS];
|
||||
bool setup_complete;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
class notch_filter
|
||||
{
|
||||
public:
|
||||
notch_filter(notch_config& cfg);
|
||||
void enable();
|
||||
void disable();
|
||||
inline bool is_enabled() const { return config_.enabled; }
|
||||
|
||||
private:
|
||||
|
||||
notch_config& config_;
|
||||
double freq_;
|
||||
double q_;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
class speech_comp
|
||||
{
|
||||
public:
|
||||
speech_comp(comp_config& cfg);
|
||||
void update();
|
||||
void enable();
|
||||
void disable();
|
||||
inline bool is_enabled() const { return config_.enabled; }
|
||||
|
||||
private:
|
||||
comp_config& config_;
|
||||
AudioEffectCompressor& comp_;
|
||||
AudioAmplifier& amp_;
|
||||
AudioAnalyzeRMS& rms_;
|
||||
float env_ = 1.0;
|
||||
float alpha_ = 0.8;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
75
digibox/ubitx-dsp.h
Normal file
75
digibox/ubitx-dsp.h
Normal file
@ -0,0 +1,75 @@
|
||||
//======================================================================
|
||||
// ubitx_iop.h
|
||||
//======================================================================
|
||||
|
||||
#ifndef __ubitx_iop_h__
|
||||
#define __ubitx_iop_h__
|
||||
|
||||
#include "config.h"
|
||||
#include "audio.h"
|
||||
#include "cat.h"
|
||||
#include "eeprom.h"
|
||||
#include "keyer.h"
|
||||
|
||||
#define PTT_KEY_OUT_PIN 2
|
||||
#define ENCODER_A_PIN 5
|
||||
#define ENCODER_B_PIN 4
|
||||
#define ENCODER_SW_PIN 3
|
||||
|
||||
// comment this out to disable debugging code
|
||||
#define DEBUG
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define USBDEBUG(x) USBSERIAL.print("IOP: "); USBSERIAL.println(x);
|
||||
#else
|
||||
#define USBDEBUG(x)
|
||||
#endif
|
||||
|
||||
//enum RigMode {
|
||||
// MODE_SSB = 0,
|
||||
// MODE_DIGI = 1,
|
||||
// MODE_CW = 2,
|
||||
//};
|
||||
|
||||
enum TxState {
|
||||
TX_OFF = 0,
|
||||
TX_MIC,
|
||||
TX_LINE,
|
||||
TX_CAT,
|
||||
TX_KEYER,
|
||||
};
|
||||
|
||||
//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
|
||||
|
||||
//======================================================================
|
||||
// EOF
|
||||
//======================================================================
|
235
digibox/ubitx-dsp.ino
Normal file
235
digibox/ubitx-dsp.ino
Normal file
@ -0,0 +1,235 @@
|
||||
//======================================================================
|
||||
// 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
|
||||
//======================================================================
|
Loading…
Reference in New Issue
Block a user