Added menu-button description. Added co-existence support for serial interface mod. Added RX spur rejection leaking via KEY_OUT PWM. Removed SIDETONE PWM leakage into TX.

pull/8/head
guido 2019-12-11 21:43:49 +01:00
rodzic 3c57e3b5b9
commit 4bf92bbdf6
3 zmienionych plików z 58 dodań i 1562 usunięć

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,10 +1,10 @@
// QCX-SSB.ino - https://github.com/threeme3/QCX-SSB
//
// Copyright 2019 Guido PE1NNZ <pe1nnz@amsat.org>
// Copyright 2019, 2020 Guido PE1NNZ <pe1nnz@amsat.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define VERSION "1.01r"
#define VERSION "1.01s"
/* BACKLOG:
code definitions and re-use for comb, integrator, dc decoupling, arctan
@ -79,7 +79,7 @@ public: // LCD1602 display in 4-bit mode, RS is pull-up and kept low when idle
PORTD = LCD_PREP_NIBBLE(b); // Send data and enable high
delayMicroseconds(4);
LCD_EN_LO();
delayMicroseconds(37); // Execution time
delayMicroseconds(60); // Execution time (was: 37)
}
void cmd(uint8_t b){ nib(b >> 4); nib(b & 0xf); }// Write command: send nibbles while RS low
size_t write(uint8_t b){ // Write data: send nibbles while RS high
@ -94,6 +94,7 @@ public: // LCD1602 display in 4-bit mode, RS is pull-up and kept low when idle
LCD_EN_LO();
LCD_RS_LO();
delayMicroseconds(41); // Execution time
PORTD |= 0x02; // To support serial-interface keep LCD_D5 high, so that DVM is not pulled-down via D
return 1;
}
void setCursor(uint8_t x, uint8_t y){ cmd(0x80 | (x + y * 0x40)); }
@ -108,7 +109,7 @@ volatile int8_t encoder_val = 0;
volatile int8_t encoder_step = 0;
static uint8_t last_state;
ISR(PCINT2_vect){ // Interrupt on rotary encoder turn
noInterrupts();
//noInterrupts();
switch(last_state = (last_state << 4) | (digitalRead(ROT_B) << 1) | digitalRead(ROT_A)){ //transition (see: https://www.allaboutcircuits.com/projects/how-to-use-a-rotary-encoder-in-a-mcu-based-project/ )
//#define ENCODER_ENHANCED_RESOLUTION 1
#ifdef ENCODER_ENHANCED_RESOLUTION // Option: enhance encoder from 24 to 96 steps/revolution, see: appendix 1, https://www.sdr-kits.net/documents/PA0KLT_Manual.pdf
@ -119,7 +120,7 @@ ISR(PCINT2_vect){ // Interrupt on rotary encoder turn
case 0x32: case 0x20: case 0x01: case 0x13: if(encoder_step > 0) encoder_step = 0; encoder_step--; if(encoder_step < -3){ encoder_step = 0; encoder_val--; } break;
#endif
}
interrupts();
//interrupts();
}
void encoder_setup()
{
@ -267,8 +268,8 @@ public:
#define SI_CLK_SRC_MS 0b00001100
#define SI_CLK_IDRV_8MA 0b00000011
#define SI_CLK_INV 0b00010000
#define SI_PLL_FREQ 400000000 //900000000, with 400MHz PLL freq, usable range is 3.2..100MHz
volatile uint32_t fxtal = 27004300; //myqcx1:27003847 myqcx2:27004900 Actual crystal frequency of 27MHz XTAL2 for CL = 10pF (default), calibrate your QCX 27MHz crystal frequency here
#define SI_PLL_FREQ (16*fxtal) //900000000, with 432MHz(=16*27M) PLL freq, usable range is 3.46..100MHz
volatile uint8_t prev_divider;
volatile int32_t raw_freq;
@ -546,6 +547,7 @@ inline int16_t ssb(int16_t in)
int16_t phase = arctan3(q, i);
int16_t dp = phase - prev_phase; // phase difference and restriction
//dp = (amp) ? dp : 0; // dp = 0 when amp = 0
prev_phase = phase;
if(dp < 0) dp = dp + _UA; // make negative phase shifts positive: prevents negative frequencies and will reduce spurs on other sideband
@ -681,7 +683,7 @@ volatile bool cw_event = false;
//#define F_SAMP_RX 28409
#define F_ADC_CONV (192307/1)
volatile int8_t volume = 0;
volatile int8_t volume = 8;
volatile bool agc = true;
volatile uint8_t nr = 0;
volatile uint8_t att = 0;
@ -1440,7 +1442,8 @@ void start_rx()
adc_start(0, false, F_ADC_CONV); admux[0] = ADMUX; admux[1] = ADMUX;
}
timer1_start(78125);
timer2_start(F_SAMP_RX);
timer2_start(F_SAMP_RX);
TCCR1A &= ~(1 << COM1B1); digitalWrite(KEY_OUT, LOW); // disable KEY_OUT PWM
}
void switch_rxtx(uint8_t tx_enable){
@ -1454,10 +1457,15 @@ void switch_rxtx(uint8_t tx_enable){
else _init = 1;
numSamples = 0;
if(tx_enable){
digitalWrite(RX, LOW); // TX
lcd.setCursor(15, 1); lcd.print("T");
si5351.SendRegister(SI_CLK_OE, 0b11111011); // CLK2_EN=1, CLK1_EN,CLK0_EN=0
digitalWrite(RX, LOW); // TX
//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)
si5351.SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
@ -1851,7 +1859,6 @@ void setup()
delay(1500); wdt_reset();
}
#endif
volume = (dsp_cap) ? ((dsp_cap == SDR) ? 8 : 10) : 0; // default volume: keep volume disabled for analog rig
// Load parameters from EEPROM, reset to factory defaults when stored values are from a different version
paramAction(LOAD, VERS);
@ -1869,6 +1876,8 @@ void setup()
change = true;
prev_bandval = bandval;
if(!dsp_cap) volume = 0; // mute volume for unmodified QCX receiver
for(uint16_t i = 0; i != 256; i++) // refresh LUT based on pwm_min, pwm_max
lut[i] = (float)i / ((float)255 / ((float)pwm_max - (float)pwm_min)) + pwm_min;
@ -2125,11 +2134,13 @@ void loop()
//si5351.SendRegister(SI_CLK_OE, 0b11111000); // CLK2_EN=1, CLK1_EN,CLK0_EN=1
//digitalWrite(SIG_OUT, HIGH); // inject CLK2 on antenna input via 120K
}
noInterrupts();
if(mode == LSB)
si5351.freq(freq, 90, 0); // RX in LSB
else
si5351.freq(freq, 0, 90); // RX in USB
interrupts();
}
if((schedule_time) && (millis() > schedule_time)){ // save freq when time has reached schedule

Wyświetl plik

@ -62,7 +62,7 @@ Change the following component values (and type of component in some cases), and
1. To implement the SDR receiver: R11,12,17,24,27,29,59,IC10 (remove); IC7-9,R13,R18-20,R25,R28-40,R60,C9,C11,C13-24,C52-53,D5,Q7 (omit on new builds); C10 (.1uF); R16,23 (120k); wire IC10(pin7) to IC6(pin7); wire R27(pin2) to IC6(pin1); wire IC2(pin15) to IC10(pin1); disconnect R50-5V and R52-5V and both wire to R57-DVM(pin3); disconnect R21-IC6(pin7) and R22-IC6(pin7) and both wire to R7-IC5(pin1).
2. To implement the SSB transmitter: D4,R21,R56 (10k); R58 (.22uF); C32 (10uF); C31 (remove); wire IC2-pin21 to R57-DVM(pin3); wire IC2(pin20) to DVM(pin2); wire IC2(pin18) to junction D4-C42-R58;
3. To implement multiband support: C1,C5,C8,T1,R64 (remove); at T1 landing pattern (see [QCX Assembly instruction] page 53) install R (1K) over 6-8; R (1K) over 3-4; C (10nF) over 4-8; C30 (30pF); L4 (1uH/16t); replace C25-28,L1-L3 with different LPFs as you wish.
4. Upload the hex firmware-file to existing or new ATMEGA328/328P chip (click on top green download button for zip). The [standard QCX firmware upload procedure] can be followed (for details <sup>[note 1](#note1)</sup>). You can safely switch between this/original QCX firmware without any issues.
4. Upload the hex firmware-file to existing or new ATMEGA328/328P chip (here is [latest released hex file] and click on "Assets" below the description). The [standard QCX firmware upload procedure] can be followed (for details <sup>[note 1](#note1)</sup>). You can safely switch between this/original QCX firmware without any issues.
5. Connect an electret microphone pins (+) to tip and (-) to sleeve of paddle-jack; PTT-switch pins to ring and sleeve (see [X1M-mic]).
@ -93,6 +93,39 @@ Currently, the following functions have been assigned to the buttons:
| RIGHT push + turn | |
| KEY | Push-to-talk (SSB) / Straight-key (CW) |
Currently, the following functions have been assigned to buttons and menu-items:
| Menu Item | Function | Button |
| ------------------- | -------------------------------------------- | ----------- |
| | Push-to-talk (SSB) / Straight-key (CW) | **KEY**
| | Quick menu | **LEFT push + turn** |
| | Menu-item | **LEFT single-press** |
| | Tune frequency | **CENTER turn** |
| 1.1 Volume | Audio level (0..16) & power-off/on | **CENTER push + turn** |
| 1.2 Mode | Modulation (LSB, USB, CW, AM, FM) | **RIGHT single-press** |
| 1.3 Filter BW | Audio passband (Full, 300..4000, 300..2500, 300..1700, 200, 100 Hz) | **RIGHT double-press** |
| 1.4 Band | Band-switch to pre-defined FT8 freqs for 80m, 60m, 40m, 30m, 20m, 17m, 15m, 12m, 10m, 6m, 4m | **CENTER double-press** |
| 1.5 Tuning Rate | Tuning frequency step size 10M, 1M, 0.5M, 100k, 10k, 1k, 0.5k, 100, 10, 1 | **CENTER long/single-press** |
| 1.6 AGC | Automatic Gain Control (ON, OFF) | |
| 1.7 NR | Noise-reduction level (0-8), basically smooth signal and cut-off high-frequencies | |
| 1.8 ATT | Analog Attenuator (0, -13, -20, -33, -40, -53, -60, -73 dB) | |
| 1.9 ATT2 | Digital Attenuator in CIC-stage (0-16) in steps of 6dB | |
| 1.10 S-meter | Type of S-Meter (OFF, dBm, S, S-bar) | |
| 2.1 CW Decoder | Enable/disable CW Decoder (ON, OFF) | |
| 3.1 VOX | Voice Operated Xmit (ON, OFF) | **RIGHT long-press** | |
| 3.2 VOX Level | Audio threshold of VOX (0-255) | |
| 3.3 MOX | Monitor on Xmit (audio unmuted during transmit) | |
| 3.4 TX Drive | Transmit audio gain (0-8) in steps of 6dB, 8=constant amplitude for SSB | |
| 9.1 Ref freq | Actual si5351 crystal frequency, used for frequency-calibration | |
| 9.2 PA Bias min | KEY_OUT PWM level (0-255) for representing 0% RF output | |
| 9.3 PA Bias max | KEY_OUT PWM level (0-255) for representing 100% RF output | |
| 9.4 Param A | for debugging, testing and experimental purpose | |
| 9.5 Param B | for debugging, testing and experimental purpose | |
| 9.6 Param C | for debugging, testing and experimental purpose | |
Operating Instructions:
Tuning can be done by turning the rotary encoder. Its step size can be decreased or increased by a short or long press. A change of band can be done with a double press. The mode of operation is altered with a short press on the right button; this can be combined with changing S4 to change between wide-band (SSB) and small-band operation operation.
@ -164,6 +197,8 @@ The following performance measurements were made with QCX-SSB R1.01, a modified
[QCX-SSB Sketch]: QCX-SSB.ino
[latest released hex file]: https://github.com/threeme3/QCX-SSB/releases
[original QCX-SSB modification]: https://github.com/threeme3/QCX-SSB/tree/26c4e97a034d367e1325c5587a56a7c2a43c69f3
[standard QCX firmware upload procedure]: https://www.qrp-labs.com/qcx/qcxfirmware.html