Minimized code in main ino

cleanup
Marshal Horn 2020-07-01 10:44:42 -07:00
rodzic 0f42a423b2
commit d007e5c1e7
3 zmienionych plików z 164 dodań i 164 usunięć

Wyświetl plik

@ -54,6 +54,10 @@
#include "radio/fm.h"
#include "radio/cat.h"
#include "radio/rx.h"
#include "radio/common2.h"
#include "radio/calibration.h"
#include "ui.h"
//FUSES = { .low = 0xFF, .high = 0xD6, .extended = 0xFD }; // Fuse settings should be these at programming.
@ -65,170 +69,6 @@ ISR(TIMER2_COMPA_vect) // Timer2 COMPA interrupt
#endif
}
void dummy()
{
}
enum dsp_cap_t { ANALOG, DSP, SDR };
uint8_t dsp_cap = 0;
uint8_t ssb_cap = 0;
uint16_t analogSampleMic()
{
uint16_t adc;
noInterrupts();
if(dsp_cap == SDR) digitalWrite(RX, LOW); // disable RF input, only for SDR mod
//si5351.SendRegister(SI_CLK_OE, 0b11111111); // CLK2_EN=0, CLK1_EN,CLK0_EN=0
ADMUX = admux[2]; // set MUX for next conversion
ADCSRA |= (1 << ADSC); // start next ADC conversion
for(;!(ADCSRA & (1 << ADIF));); // wait until ADC conversion is completed
if(dsp_cap == SDR) digitalWrite(RX, HIGH); // enable RF input, only for SDR mod
//si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
adc = ADC;
interrupts();
return adc;
}
volatile bool change = true;
volatile int32_t freq = 7074000;
int8_t smode = 1;
float dbm_max;
float smeter(float ref = 5) //= 10*log(8000/2400)=5 ref to 2.4kHz BW. plus some other calibration factor
{
if(smode == 0){ // none, no s-meter
return 0;
}
float rms = _absavg256 / 256.0; //sqrt(256.0);
//if(dsp_cap == SDR) rms = (float)rms * 1.1 * (float)(1 << att2) / (1024.0 * (float)R * 4.0 * 100.0 * 40.0); // 2 rx gain stages: rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * audio gain]
if(dsp_cap == SDR) rms = (float)rms * 1.1 * (float)(1 << att2) / (1024.0 * (float)R * 4.0 * 820.0 * 3.0/*??*/); // 1 rx gain stage: rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * audio gain]
else rms = (float)rms * 5.0 * (float)(1 << att2) / (1024.0 * (float)R * 2.0 * 100.0 * 120.0 / 1.750);
float dbm = (10.0 * log10((rms * rms) / 50.0) + 30.0) - ref; //from rmsV to dBm at 50R
dbm_max = max(dbm_max, dbm);
static uint8_t cnt;
cnt++;
if((cnt % 8) == 0){
if(smode == 1){ // dBm meter
lcd.noCursor(); lcd.setCursor(9, 0); lcd.print((int16_t)dbm_max); lcd.print(F("dBm "));
}
if(smode == 2){ // S-meter
uint8_t s = (dbm_max < -63) ? ((dbm_max - -127) / 6) : (uint8_t)(dbm_max - -63 + 10) % 10; // dBm to S
lcd.noCursor(); lcd.setCursor(14, 0); if(s < 10){ lcd.print('S'); } lcd.print(s);
}
dbm_max = -174.0 + 34.0;
}
if(smode == 3){ // S-bar
int8_t s = (dbm < -63) ? ((dbm - -127) / 6) : (uint8_t)(dbm - -63 + 10) % 10; // dBm to S
lcd.noCursor(); lcd.setCursor(12, 0);
char tmp[5];
for(uint8_t i = 0; i != 4; i++){ tmp[i] = max(2, min(5, s + 1)); s = s - 3; } tmp[4] = 0;
lcd.print(tmp);
}
return dbm;
}
void start_rx()
{
_init = 1;
rx_state = 0;
func_ptr = sdr_rx; //enable RX DSP/SDR
adc_start(2, true, F_ADC_CONV); admux[2] = ADMUX;
if(dsp_cap == SDR){
adc_start(0, !(att == 1)/*true*/, F_ADC_CONV); admux[0] = ADMUX;
adc_start(1, !(att == 1)/*true*/, F_ADC_CONV); admux[1] = ADMUX;
} else { // ANALOG, DSP
adc_start(0, false, F_ADC_CONV); admux[0] = ADMUX; admux[1] = ADMUX;
}
timer1_start(F_SAMP_PWM);
timer2_start(F_SAMP_RX);
TCCR1A &= ~(1 << COM1B1); digitalWrite(KEY_OUT, LOW); // disable KEY_OUT PWM
}
void switch_rxtx(uint8_t tx_enable){
tx = tx_enable;
TIMSK2 &= ~(1 << OCIE2A); // disable timer compare interrupt
//delay(1);
noInterrupts();
if(tx_enable){
switch(mode){
case USB:
case LSB: func_ptr = dsp_tx; break;
case CW: func_ptr = dsp_tx_cw; break;
case AM: func_ptr = dsp_tx_am; break;
case FM: func_ptr = dsp_tx_fm; break;
}
} else func_ptr = sdr_rx;
if((!dsp_cap) && (!tx_enable) && vox) func_ptr = dummy; //hack: for SSB mode, disable dsp_rx during vox mode enabled as it slows down the vox loop too much!
interrupts();
if(tx_enable) ADMUX = admux[2];
else _init = 1;
rx_state = 0;
if(tx_enable){
digitalWrite(RX, LOW); // TX (disable RX)
#ifdef NTX
digitalWrite(NTX, LOW); // TX (enable TX)
#endif
lcd.setCursor(15, 1); lcd.print("T");
si5351.SendRegister(SI_CLK_OE, 0b11111011); // CLK2_EN=1, CLK1_EN,CLK0_EN=0
//if(!mox) TCCR1A &= ~(1 << COM1A1); // disable SIDETONE, prevent interference during TX
OCR1AL = 0; // make sure SIDETONE is set to 0%
TCCR1A |= (1 << COM1B1); // enable KEY_OUT PWM
} else {
//TCCR1A |= (1 << COM1A1); // enable SIDETONE
TCCR1A &= ~(1 << COM1B1); digitalWrite(KEY_OUT, LOW); // disable KEY_OUT PWM, prevents interference during RX
OCR1BL = 0; // make sure PWM (KEY_OUT) is set to 0%
digitalWrite(RX, !(att == 2)); // RX (enable RX when attenuator not on)
#ifdef NTX
digitalWrite(NTX, HIGH); // RX (disable TX)
#endif
si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
lcd.setCursor(15, 1); lcd.print((vox) ? "V" : "R");
}
OCR2A = (((float)F_CPU / (float)64) / (float)((tx_enable) ? F_SAMP_TX : F_SAMP_RX) + 0.5) - 1;
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt TIMER2_COMPA_vect
}
#ifdef QCX
#define CAL_IQ 1
#ifdef CAL_IQ
int16_t cal_iq_dummy = 0;
// RX I/Q calibration procedure: terminate with 50 ohm, enable CW filter, adjust R27, R24, R17 subsequently to its minimum side-band rejection value in dB
void calibrate_iq()
{
smode = 1;
lcd.setCursor(0, 0); lcd.print(blanks); lcd.print(blanks);
digitalWrite(SIG_OUT, true); // loopback on
si5351.freq(freq, 0, 90); // RX in USB
si5351.SendRegister(SI_CLK_OE, 0b11111000); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
float dbc;
si5351.freq_calc_fast(+700); si5351.SendPLLBRegisterBulk(); delay(100);
dbc = smeter();
si5351.freq_calc_fast(-700); si5351.SendPLLBRegisterBulk(); delay(100);
lcd.setCursor(0, 1); lcd.print("I-Q bal. 700Hz"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); smeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
si5351.freq_calc_fast(+600); si5351.SendPLLBRegisterBulk(); delay(100);
dbc = smeter();
si5351.freq_calc_fast(-600); si5351.SendPLLBRegisterBulk(); delay(100);
lcd.setCursor(0, 1); lcd.print("Phase Lo 600Hz"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); smeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
si5351.freq_calc_fast(+800); si5351.SendPLLBRegisterBulk(); delay(100);
dbc = smeter();
si5351.freq_calc_fast(-800); si5351.SendPLLBRegisterBulk(); delay(100);
lcd.setCursor(0, 1); lcd.print("Phase Hi 800Hz"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); smeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
lcd.setCursor(9, 0); lcd.print(blanks); // cleanup dbmeter
digitalWrite(SIG_OUT, false); // loopback off
si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
change = true; //restore original frequency setting
}
#endif
#endif //QCX
#include "ui.h" // Need to seperate this out
void setup()
{
digitalWrite(KEY_OUT, LOW); // for safety: to prevent exploding PA MOSFETs, in case there was something still biasing them.

Wyświetl plik

@ -0,0 +1,36 @@
#ifdef QCX
#define CAL_IQ 1
#ifdef CAL_IQ
int16_t cal_iq_dummy = 0;
// RX I/Q calibration procedure: terminate with 50 ohm, enable CW filter, adjust R27, R24, R17 subsequently to its minimum side-band rejection value in dB
void calibrate_iq()
{
smode = 1;
lcd.setCursor(0, 0); lcd.print(blanks); lcd.print(blanks);
digitalWrite(SIG_OUT, true); // loopback on
si5351.freq(freq, 0, 90); // RX in USB
si5351.SendRegister(SI_CLK_OE, 0b11111000); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
float dbc;
si5351.freq_calc_fast(+700); si5351.SendPLLBRegisterBulk(); delay(100);
dbc = smeter();
si5351.freq_calc_fast(-700); si5351.SendPLLBRegisterBulk(); delay(100);
lcd.setCursor(0, 1); lcd.print("I-Q bal. 700Hz"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); smeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
si5351.freq_calc_fast(+600); si5351.SendPLLBRegisterBulk(); delay(100);
dbc = smeter();
si5351.freq_calc_fast(-600); si5351.SendPLLBRegisterBulk(); delay(100);
lcd.setCursor(0, 1); lcd.print("Phase Lo 600Hz"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); smeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
si5351.freq_calc_fast(+800); si5351.SendPLLBRegisterBulk(); delay(100);
dbc = smeter();
si5351.freq_calc_fast(-800); si5351.SendPLLBRegisterBulk(); delay(100);
lcd.setCursor(0, 1); lcd.print("Phase Hi 800Hz"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); smeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
lcd.setCursor(9, 0); lcd.print(blanks); // cleanup dbmeter
digitalWrite(SIG_OUT, false); // loopback off
si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
change = true; //restore original frequency setting
}
#endif
#endif //QCX

Wyświetl plik

@ -0,0 +1,124 @@
enum dsp_cap_t { ANALOG, DSP, SDR };
uint8_t dsp_cap = 0;
uint8_t ssb_cap = 0;
void dummy()
{
}
void start_rx()
{
_init = 1;
rx_state = 0;
func_ptr = sdr_rx; //enable RX DSP/SDR
adc_start(2, true, F_ADC_CONV); admux[2] = ADMUX;
if(dsp_cap == SDR){
adc_start(0, !(att == 1)/*true*/, F_ADC_CONV); admux[0] = ADMUX;
adc_start(1, !(att == 1)/*true*/, F_ADC_CONV); admux[1] = ADMUX;
} else { // ANALOG, DSP
adc_start(0, false, F_ADC_CONV); admux[0] = ADMUX; admux[1] = ADMUX;
}
timer1_start(F_SAMP_PWM);
timer2_start(F_SAMP_RX);
TCCR1A &= ~(1 << COM1B1); digitalWrite(KEY_OUT, LOW); // disable KEY_OUT PWM
}
uint16_t analogSampleMic()
{
uint16_t adc;
noInterrupts();
if(dsp_cap == SDR) digitalWrite(RX, LOW); // disable RF input, only for SDR mod
//si5351.SendRegister(SI_CLK_OE, 0b11111111); // CLK2_EN=0, CLK1_EN,CLK0_EN=0
ADMUX = admux[2]; // set MUX for next conversion
ADCSRA |= (1 << ADSC); // start next ADC conversion
for(;!(ADCSRA & (1 << ADIF));); // wait until ADC conversion is completed
if(dsp_cap == SDR) digitalWrite(RX, HIGH); // enable RF input, only for SDR mod
//si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
adc = ADC;
interrupts();
return adc;
}
void switch_rxtx(uint8_t tx_enable){
tx = tx_enable;
TIMSK2 &= ~(1 << OCIE2A); // disable timer compare interrupt
//delay(1);
noInterrupts();
if(tx_enable){
switch(mode){
case USB:
case LSB: func_ptr = dsp_tx; break;
case CW: func_ptr = dsp_tx_cw; break;
case AM: func_ptr = dsp_tx_am; break;
case FM: func_ptr = dsp_tx_fm; break;
}
} else func_ptr = sdr_rx;
if((!dsp_cap) && (!tx_enable) && vox) func_ptr = dummy; //hack: for SSB mode, disable dsp_rx during vox mode enabled as it slows down the vox loop too much!
interrupts();
if(tx_enable) ADMUX = admux[2];
else _init = 1;
rx_state = 0;
if(tx_enable){
digitalWrite(RX, LOW); // TX (disable RX)
#ifdef NTX
digitalWrite(NTX, LOW); // TX (enable TX)
#endif
lcd.setCursor(15, 1); lcd.print("T");
si5351.SendRegister(SI_CLK_OE, 0b11111011); // CLK2_EN=1, CLK1_EN,CLK0_EN=0
//if(!mox) TCCR1A &= ~(1 << COM1A1); // disable SIDETONE, prevent interference during TX
OCR1AL = 0; // make sure SIDETONE is set to 0%
TCCR1A |= (1 << COM1B1); // enable KEY_OUT PWM
} else {
//TCCR1A |= (1 << COM1A1); // enable SIDETONE
TCCR1A &= ~(1 << COM1B1); digitalWrite(KEY_OUT, LOW); // disable KEY_OUT PWM, prevents interference during RX
OCR1BL = 0; // make sure PWM (KEY_OUT) is set to 0%
digitalWrite(RX, !(att == 2)); // RX (enable RX when attenuator not on)
#ifdef NTX
digitalWrite(NTX, HIGH); // RX (disable TX)
#endif
si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
lcd.setCursor(15, 1); lcd.print((vox) ? "V" : "R");
}
OCR2A = (((float)F_CPU / (float)64) / (float)((tx_enable) ? F_SAMP_TX : F_SAMP_RX) + 0.5) - 1;
TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt TIMER2_COMPA_vect
}
volatile bool change = true;
volatile int32_t freq = 7074000;
int8_t smode = 1;
float dbm_max;
float smeter(float ref = 5) //= 10*log(8000/2400)=5 ref to 2.4kHz BW. plus some other calibration factor
{
if(smode == 0){ // none, no s-meter
return 0;
}
float rms = _absavg256 / 256.0; //sqrt(256.0);
//if(dsp_cap == SDR) rms = (float)rms * 1.1 * (float)(1 << att2) / (1024.0 * (float)R * 4.0 * 100.0 * 40.0); // 2 rx gain stages: rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * audio gain]
if(dsp_cap == SDR) rms = (float)rms * 1.1 * (float)(1 << att2) / (1024.0 * (float)R * 4.0 * 820.0 * 3.0/*??*/); // 1 rx gain stage: rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * audio gain]
else rms = (float)rms * 5.0 * (float)(1 << att2) / (1024.0 * (float)R * 2.0 * 100.0 * 120.0 / 1.750);
float dbm = (10.0 * log10((rms * rms) / 50.0) + 30.0) - ref; //from rmsV to dBm at 50R
dbm_max = max(dbm_max, dbm);
static uint8_t cnt;
cnt++;
if((cnt % 8) == 0){
if(smode == 1){ // dBm meter
lcd.noCursor(); lcd.setCursor(9, 0); lcd.print((int16_t)dbm_max); lcd.print(F("dBm "));
}
if(smode == 2){ // S-meter
uint8_t s = (dbm_max < -63) ? ((dbm_max - -127) / 6) : (uint8_t)(dbm_max - -63 + 10) % 10; // dBm to S
lcd.noCursor(); lcd.setCursor(14, 0); if(s < 10){ lcd.print('S'); } lcd.print(s);
}
dbm_max = -174.0 + 34.0;
}
if(smode == 3){ // S-bar
int8_t s = (dbm < -63) ? ((dbm - -127) / 6) : (uint8_t)(dbm - -63 + 10) % 10; // dBm to S
lcd.noCursor(); lcd.setCursor(12, 0);
char tmp[5];
for(uint8_t i = 0; i != 4; i++){ tmp[i] = max(2, min(5, s + 1)); s = s - 3; } tmp[4] = 0;
lcd.print(tmp);
}
return dbm;
}