kopia lustrzana https://github.com/kamocat/uSDX
125 wiersze
4.7 KiB
C
125 wiersze
4.7 KiB
C
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;
|
|
}
|