usdx-kamocat/QCX-SSB.ino

1313 wiersze
48 KiB
Arduino
Czysty Zwykły widok Historia

2019-01-28 17:44:15 +00:00
// Arduino Sketch of the QCX-SSB: SSB with your QCX transceiver (modification)
//
2019-04-12 15:31:09 +00:00
// https://github.com/threeme3/QCX-SSB
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
#define VERSION "1.01f"
2019-01-28 17:44:15 +00:00
// QCX pin defintion
#define LCD_D4 0
#define LCD_D5 1
#define LCD_D6 2
#define LCD_D7 3
#define LCD_EN 4
#define ROT_A 6
#define ROT_B 7
#define RX 8
#define SIDETONE 9
2019-01-28 17:44:15 +00:00
#define KEY_OUT 10
#define SIG_OUT 11
#define DAH 12
#define DIT 13
#define AUDIO1 14 //A0
#define AUDIO2 15 //A1
#define DVM 16 //A2
#define BUTTONS 17 //A3
#define LCD_RS 18
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
#define SDA 18 //shared with LCD_RS
2019-01-28 17:44:15 +00:00
#define SCL 19
#include <LiquidCrystal.h>
class QCXLiquidCrystal : public LiquidCrystal {
public: // QCXLiquidCrystal extends LiquidCrystal library for pull-up driven LCD_RS, as done on QCX. LCD_RS needs to be set to LOW in advance of calling any operation.
QCXLiquidCrystal(uint8_t rs, uint8_t en, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7) : LiquidCrystal(rs, en, d4, d5, d6, d7){ };
virtual size_t write(uint8_t value){ // overwrites LiquidCrystal::write() and re-implements LCD data writes
pinMode(LCD_RS, INPUT); // pull-up LCD_RS
write4bits(value >> 4);
write4bits(value);
pinMode(LCD_RS, OUTPUT); // pull-down LCD_RS
return 1;
};
void write4bits(uint8_t value){
digitalWrite(LCD_D4, (value >> 0) & 0x01);
digitalWrite(LCD_D5, (value >> 1) & 0x01);
digitalWrite(LCD_D6, (value >> 2) & 0x01);
digitalWrite(LCD_D7, (value >> 3) & 0x01);
digitalWrite(LCD_EN, LOW); // pulseEnable
delayMicroseconds(1);
digitalWrite(LCD_EN, HIGH);
delayMicroseconds(1); // enable pulse must be >450ns
digitalWrite(LCD_EN, LOW);
delayMicroseconds(100); // commands need > 37us to settle
};
};
QCXLiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7);
2019-01-28 17:44:15 +00:00
#include <inttypes.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#undef F_CPU
#define F_CPU 20008440 //20000000 // Actual crystal frequency of XTAL1
2019-01-28 17:44:15 +00:00
#define I2C_DELAY 4 // Determines I2C Speed (2=939kb/s (too fast!!); 3=822kb/s; 4=731kb/s; 5=658kb/s; 6=598kb/s). Increase this value when you get I2C tx errors (E05); decrease this value when you get a CPU overload (E01). An increment eats ~3.5% CPU load; minimum value is 3 on my QCX, resulting in 84.5% CPU load
2019-01-28 17:44:15 +00:00
#define I2C_DDR DDRC // Pins for the I2C bit banging
#define I2C_PIN PINC
#define I2C_PORT PORTC
#define I2C_SDA (1 << 4) // PC4
#define I2C_SCL (1 << 5) // PC5
#define DELAY(n) for(uint8_t i = 0; i != n; i++) asm("nop");
2019-01-28 17:44:15 +00:00
#define I2C_SDA_GET() I2C_PIN & I2C_SDA
#define I2C_SCL_GET() I2C_PIN & I2C_SCL
2019-01-28 17:44:15 +00:00
#define I2C_SDA_HI() I2C_DDR &= ~I2C_SDA;
2019-04-12 15:31:09 +00:00
#define I2C_SDA_LO() I2C_DDR |= I2C_SDA;
#define I2C_SCL_HI() I2C_DDR &= ~I2C_SCL; DELAY(I2C_DELAY);
#define I2C_SCL_LO() I2C_DDR |= I2C_SCL; DELAY(I2C_DELAY);
2019-01-28 17:44:15 +00:00
inline void i2c_start()
{
i2c_resume(); //prepare for I2C
I2C_SCL_LO();
I2C_SDA_HI();
2019-01-28 17:44:15 +00:00
}
inline void i2c_stop()
{
I2C_SCL_HI();
I2C_SDA_HI();
I2C_DDR &= ~(I2C_SDA | I2C_SCL); // prepare for a start: pull-up both SDA, SCL
2019-01-28 17:44:15 +00:00
i2c_suspend();
}
#define i2c_SendBit(data, mask) \
if(data & mask){ \
I2C_SDA_HI(); \
} else { \
I2C_SDA_LO(); \
} \
I2C_SCL_HI(); \
2019-01-28 17:44:15 +00:00
I2C_SCL_LO();
inline void i2c_SendByte(uint8_t data)
{
2019-04-12 15:31:09 +00:00
i2c_SendBit(data, 1 << 7);
i2c_SendBit(data, 1 << 6);
i2c_SendBit(data, 1 << 5);
i2c_SendBit(data, 1 << 4);
i2c_SendBit(data, 1 << 3);
i2c_SendBit(data, 1 << 2);
i2c_SendBit(data, 1 << 1);
i2c_SendBit(data, 1 << 0);
I2C_SDA_HI(); // recv ACK
DELAY(I2C_DELAY);
I2C_SCL_HI();
I2C_SCL_LO();
}
inline uint8_t i2c_RecvBit(uint8_t mask)
{
I2C_SCL_HI();
uint16_t i = 60000;
for(;(!I2C_SCL_GET()) && i; i--); // wait util slave release SCL to HIGH (meaning data valid), or timeout at 3ms
if(!i){ lcd.setCursor(0, 1); lcd.print("E07 I2C timeout"); }
uint8_t data = I2C_SDA_GET();
I2C_SCL_LO();
return (data) ? mask : 0;
}
inline uint8_t i2c_RecvByte(uint8_t last)
{
uint8_t data = 0;
data |= i2c_RecvBit(1 << 7);
data |= i2c_RecvBit(1 << 6);
data |= i2c_RecvBit(1 << 5);
data |= i2c_RecvBit(1 << 4);
data |= i2c_RecvBit(1 << 3);
data |= i2c_RecvBit(1 << 2);
data |= i2c_RecvBit(1 << 1);
data |= i2c_RecvBit(1 << 0);
if(last){
I2C_SDA_HI(); // NACK
} else {
I2C_SDA_LO(); // ACK
}
DELAY(I2C_DELAY);
2019-01-28 17:44:15 +00:00
I2C_SCL_HI();
I2C_SDA_HI(); // restore SDA for read
2019-01-28 17:44:15 +00:00
I2C_SCL_LO();
return data;
2019-01-28 17:44:15 +00:00
}
void i2c_init()
{
I2C_PORT &= ~( I2C_SDA | I2C_SCL );
I2C_SCL_HI();
I2C_SDA_HI();
i2c_suspend();
}
void i2c_deinit()
2019-04-12 15:31:09 +00:00
{
2019-01-28 17:44:15 +00:00
I2C_PORT &= ~( I2C_SDA | I2C_SCL );
I2C_DDR &= ~( I2C_SDA | I2C_SCL );
}
inline void i2c_resume()
{
#ifdef LCD_RS_PORTIO
I2C_PORT &= ~I2C_SDA; // pin sharing SDA/LCD_RS mitigation
#endif
2019-01-28 17:44:15 +00:00
}
inline void i2c_suspend()
{
I2C_SDA_LO(); // pin sharing SDA/LCD_RS: pull-down LCD_RS; QCXLiquidCrystal require this for any operation
2019-01-28 17:44:15 +00:00
}
#define SI_I2C_ADDR 96 // SI5351A I2C address
#define SI_CLK_OE 3 // Register definitions
#define SI_CLK0_CONTROL 16
#define SI_CLK1_CONTROL 17
#define SI_CLK2_CONTROL 18
#define SI_SYNTH_PLL_A 26
#define SI_SYNTH_PLL_B 34
#define SI_SYNTH_MS_0 42
#define SI_SYNTH_MS_1 50
#define SI_SYNTH_MS_2 58
#define SI_CLK0_PHOFF 165
#define SI_CLK1_PHOFF 166
#define SI_CLK2_PHOFF 167
#define SI_PLL_RESET 177
#define SI_MS_INT 0b01000000 // Clock control
#define SI_CLK_SRC_PLL_A 0b00000000
#define SI_CLK_SRC_PLL_B 0b00100000
#define SI_CLK_SRC_MS 0b00001100
#define SI_CLK_IDRV_8MA 0b00000011
#define SI_CLK_INV 0b00010000
2019-01-28 17:44:15 +00:00
#define SI_XTAL_FREQ 27003847 //27003847 27004452 Measured crystal frequency of XTAL2 for CL = 10pF (default), calibrate your QCX 27MHz crystal frequency here
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
#define log2(n) (log(n) / log(2))
2019-01-28 17:44:15 +00:00
volatile uint8_t si5351_prev_divider;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
volatile int32_t si5351_raw_freq;
2019-01-28 17:44:15 +00:00
volatile uint8_t si5351_divider; // note: because of int8 only freq > 3.6MHz can be covered for R_DIV=1
volatile uint8_t si5351_mult;
volatile uint8_t si5351_pll_data[8];
static int32_t si5351_prev_pll_freq = 0;
uint8_t si5351_RecvRegister(uint8_t reg)
{
// Data write to set the register address
i2c_start();
i2c_SendByte(SI_I2C_ADDR << 1);
i2c_SendByte(reg);
i2c_stop();
// Data read to retrieve the data from the set address
i2c_start();
i2c_SendByte((SI_I2C_ADDR << 1) | 1);
uint8_t data = i2c_RecvByte(true);
i2c_stop();
return data;
}
2019-01-28 17:44:15 +00:00
void si5351_SendRegister(uint8_t reg, uint8_t data)
{
i2c_start();
i2c_SendByte(SI_I2C_ADDR << 1);
i2c_SendByte(reg);
i2c_SendByte(data);
i2c_stop();
}
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
inline void si5351_SendPLLBRegisterBulk() // fast freq change of PLLB, takes about [ 2 + 7*(8+1) + 2 ] / 840000 = 80 uS
2019-01-28 17:44:15 +00:00
{
i2c_start();
i2c_SendByte(SI_I2C_ADDR << 1);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
i2c_SendByte(SI_SYNTH_PLL_B + 3); // Skip the first three pll_data bytes (first two always 0xFF and third not often changing
2019-01-28 17:44:15 +00:00
i2c_SendByte(si5351_pll_data[3]);
i2c_SendByte(si5351_pll_data[4]);
i2c_SendByte(si5351_pll_data[5]);
i2c_SendByte(si5351_pll_data[6]);
i2c_SendByte(si5351_pll_data[7]);
i2c_stop();
}
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
// Set up MultiSynth for register reg=MSNA, MNSB, MS0-5 with fractional divider, num and denom and R divider (for MSn, not for MSNA, MSNB)
// divider is 15..90 for MSNA, MSNB, divider is 8..900 (and in addition 4,6 for integer mode) for MS[0-5]
// num is 0..1,048,575 (0xFFFFF)
// denom is 0..1,048,575 (0xFFFFF)
// num = 0, denom = 1 forces an integer value for the divider
// r_div = 1..128 (1,2,4,8,16,32,64,128)
void si5351_SetupMultisynth(uint8_t reg, uint8_t divider, uint32_t num, uint32_t denom, uint8_t r_div)
{
uint32_t P1; // Synth config register P1
uint32_t P2; // Synth config register P2
uint32_t P3; // Synth config register P3
P1 = (uint32_t)(128 * ((float)num / (float)denom));
P1 = (uint32_t)(128 * (uint32_t)(divider) + P1 - 512);
P2 = (uint32_t)(128 * ((float)num / (float)denom));
P2 = (uint32_t)(128 * num - denom * P2);
P3 = denom;
si5351_SendRegister(reg + 0, (P3 & 0x0000FF00) >> 8);
si5351_SendRegister(reg + 1, (P3 & 0x000000FF));
si5351_SendRegister(reg + 2, (P1 & 0x00030000) >> 16 | ((int)log2(r_div) << 4) );
si5351_SendRegister(reg + 3, (P1 & 0x0000FF00) >> 8);
si5351_SendRegister(reg + 4, (P1 & 0x000000FF));
si5351_SendRegister(reg + 5, ((P3 & 0x000F0000) >> 12) | ((P2 & 0x000F0000) >> 16));
si5351_SendRegister(reg + 6, (P2 & 0x0000FF00) >> 8);
si5351_SendRegister(reg + 7, (P2 & 0x000000FF));
}
// this function relies on cached (global) variables: si5351_divider, si5351_mult, si5351_raw_freq, si5351_pll_data
2019-01-28 17:44:15 +00:00
inline void si5351_freq_calc_fast(int16_t freq_offset)
{ // freq_offset is relative to freq set in si5351_freq(freq)
// uint32_t num128 = ((si5351_divider * (si5351_raw_freq + offset)) % SI_XTAL_FREQ) * (float)(0xFFFFF * 128) / SI_XTAL_FREQ;
2019-04-12 15:31:09 +00:00
// Above definition (for SI_XTAL_FREQ=27.00491M) can be optimized by pre-calculating factor (0xFFFFF*128)/SI_XTAL_FREQ (=4.97) as integer constant (5) and
2019-01-28 17:44:15 +00:00
// substracting the rest error factor (0.03). Note that the latter is shifted left (0.03<<6)=2, while the other term is shifted right (>>6)
register int32_t z = ((si5351_divider * (si5351_raw_freq + freq_offset)) % SI_XTAL_FREQ);
register int32_t z2 = -(z >> 5);
int32_t num128 = (z * 5) + z2;
// Set up specified PLL with si5351_mult, num and denom: si5351_mult is 15..90, num128 is 0..128*1,048,575 (128*0xFFFFF), denom is 0..1,048,575 (0xFFFFF)
uint32_t P1 = 128 * si5351_mult + (num128 / 0xFFFFF) - 512;
uint32_t P2 = num128 % 0xFFFFF;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
//si5351_pll_data[0] = 0xFF;
//si5351_pll_data[1] = 0xFF;
//si5351_pll_data[2] = (P1 >> 14) & 0x0C;
2019-01-28 17:44:15 +00:00
si5351_pll_data[3] = P1 >> 8;
si5351_pll_data[4] = P1;
si5351_pll_data[5] = 0xF0 | (P2 >> 16);
si5351_pll_data[6] = P2 >> 8;
si5351_pll_data[7] = P2;
}
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
uint16_t si5351_div(uint32_t num, uint32_t denom, uint32_t* b, uint32_t* c)
{ // returns a + b / c = num / denom, where a is the integer part and b and c is the optional fractional part 20 bits each (range 0..1048575)
uint16_t a = num / denom;
if(b && c){
uint64_t l = num % denom;
2019-04-12 15:31:09 +00:00
l <<= 20; l--; // l *= 1048575;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
l /= denom; // normalize
*b = l;
*c = 0xFFFFF; // for simplicity set c to the maximum 1048575
}
return a;
}
volatile int32_t pll_freq; // temporary
2019-01-28 17:44:15 +00:00
void si5351_freq(uint32_t freq, uint8_t i, uint8_t q)
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
{ // Fout = Fvco / (R * [MSx_a + MSx_b/MSx_c]), Fvco = Fxtal * [MSPLLx_a + MSPLLx_b/MSPLLx_c]; MSx as integer reduce spur
uint8_t r_div = (freq > 4000000) ? 1 : (freq > 400000) ? 32 : 128; // helps si5351_divider to be in range
freq *= r_div; // take r_div into account, now freq is in the range 1MHz to 150MHz
si5351_raw_freq = freq; // cache frequency generated by PLL and MS stages (excluding R divider stage); used by si5351_freq_calc_fast()
si5351_divider = 900000000 / freq; // Calculate the division ratio. 900,000,000 is the maximum internal PLL freq (official range 600..900MHz but can be pushed to 300MHz..~1200Mhz)
2019-04-12 15:31:09 +00:00
if(si5351_divider % 2) si5351_divider--; // si5351_divider in range 8.. 900 (including 4,6 for integer mode), even numbers preferred. Note that uint8 datatype is used, so 254 is upper limit
if( (si5351_divider * (freq - 5000) / SI_XTAL_FREQ) != (si5351_divider * (freq + 5000) / SI_XTAL_FREQ) ) si5351_divider -= 2; // Test if si5351_multiplier remains same for freq deviation +/- 5kHz, if not use different si5351_divider to make same
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
/*int32_t*/ pll_freq = si5351_divider * freq; // Calculate the pll_freq: the si5351_divider * desired output freq
uint32_t num, denom;
si5351_mult = si5351_div(pll_freq, SI_XTAL_FREQ, &num, &denom); // Determine the mult to get to the required pll_freq (in the range 15..90)
2019-04-12 15:31:09 +00:00
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
// Set up specified PLL with mult, num and denom: mult is 15..90, num is 0..1,048,575 (0xFFFFF), denom is 0..1,048,575 (0xFFFFF)
// Set up PLL A and PLL B with the calculated multiplication ratio
si5351_SetupMultisynth(SI_SYNTH_PLL_A, si5351_mult, num, denom, 1);
si5351_SetupMultisynth(SI_SYNTH_PLL_B, si5351_mult, num, denom, 1);
//if(denom == 1) si5351_SendRegister(22, SI_MSx_INT); // FBA_INT: MSNA operates in integer mode
//if(denom == 1) si5351_SendRegister(23, SI_MSx_INT); // FBB_INT: MSNB operates in integer mode
// Set up MultiSynth 0,1,2 with the calculated divider, from 4, 6..1800.
// The final R division stage can divide by a power of two, from 1..128
// if you want to output frequencies below 1MHz, you have to use the final R division stage
si5351_SetupMultisynth(SI_SYNTH_MS_0, si5351_divider, 0, 1, r_div);
si5351_SetupMultisynth(SI_SYNTH_MS_1, si5351_divider, 0, 1, r_div);
si5351_SetupMultisynth(SI_SYNTH_MS_2, si5351_divider, 0, 1, r_div);
//if(si5351_prev_divider != si5351_divider){ lcd.setCursor(0, 0); lcd.print(si5351_divider); lcd.print(blanks); }
2019-04-12 15:31:09 +00:00
// Set I/Q phase
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SendRegister(SI_CLK0_PHOFF, i * si5351_divider / 90); // one LSB equivalent to a time delay of Tvco/4 range 0..127
si5351_SendRegister(SI_CLK1_PHOFF, q * si5351_divider / 90); // one LSB equivalent to a time delay of Tvco/4 range 0..127
// Switch on the CLK0, CLK1 output to be PLL A and set si5351_multiSynth0, si5351_multiSynth1 input (0x0F = SI_CLK_SRC_MS | SI_CLK_IDRV_8MA)
si5351_SendRegister(SI_CLK0_CONTROL, 0x0F | SI_MS_INT | SI_CLK_SRC_PLL_A);
si5351_SendRegister(SI_CLK1_CONTROL, 0x0F | SI_MS_INT | SI_CLK_SRC_PLL_A);
2019-04-12 15:31:09 +00:00
// Switch on the CLK2 output to be PLL B and set si5351_multiSynth2 input
si5351_SendRegister(SI_CLK2_CONTROL, 0x0F | SI_MS_INT | SI_CLK_SRC_PLL_B);
si5351_SendRegister(SI_CLK_OE, 0b11111100); // Enable CLK1|CLK0
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
// Reset the PLL. This causes a glitch in the output. For small changes to
// the parameters, you don't need to reset the PLL, and there is no glitch
2019-04-12 15:31:09 +00:00
if((abs(pll_freq - si5351_prev_pll_freq) > 16000000L) || si5351_divider != si5351_prev_divider){
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_prev_pll_freq = pll_freq;
si5351_prev_divider = si5351_divider;
si5351_SendRegister(SI_PLL_RESET, 0xA0);
}
}
void si5351_alt_clk2(uint32_t freq)
{
uint32_t num, denom;
uint16_t mult = si5351_div(pll_freq, freq, &num, &denom);
2019-04-12 15:31:09 +00:00
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SetupMultisynth(SI_SYNTH_MS_2, mult, num, denom, 1);
2019-04-12 15:31:09 +00:00
// Switch on the CLK2 output to be PLL A and set si5351_multiSynth2 input
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SendRegister(SI_CLK2_CONTROL, 0x0F | SI_CLK_SRC_PLL_A);
2019-04-12 15:31:09 +00:00
si5351_SendRegister(SI_CLK_OE, 0b11111000); // Enable CLK2|CLK1|CLK0
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
//si5351_SendRegister(SI_CLK0_PHOFF, 0 * si5351_divider / 90); // one LSB equivalent to a time delay of Tvco/4 range 0..127
//si5351_SendRegister(SI_CLK1_PHOFF, 90 * si5351_divider / 90); // one LSB equivalent to a time delay of Tvco/4 range 0..127
//si5351_SendRegister(SI_CLK2_PHOFF, 45 * si5351_divider / 90); // one LSB equivalent to a time delay of Tvco/4 range 0..127
//si5351_SendRegister(SI_PLL_RESET, 0xA0);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
}
enum mode_t { LSB, USB, CW };
volatile uint8_t mode = USB;
2019-01-28 17:44:15 +00:00
volatile bool change = true;
volatile int32_t freq = 7074000;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
volatile uint8_t tx = 0;
2019-01-28 17:44:15 +00:00
volatile bool vox_enable = false;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
inline void vox(bool trigger)
{
if(trigger){
if(!tx){
2019-04-12 15:31:09 +00:00
lcd.setCursor(15, 1); lcd.print("T");
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SendRegister(SI_CLK_OE, 0b11111011); // CLK2_EN=1, CLK1_EN,CLK0_EN=0
digitalWrite(RX, LOW); // TX
}
tx = 255; // hangtime = 255 / 4402 = 58ms (the time that TX at least stays on when not triggered again)
} else {
if(tx){
tx--;
if(!tx){
digitalWrite(RX, HIGH); // RX
si5351_SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
2019-04-12 15:31:09 +00:00
lcd.setCursor(15, 1); lcd.print("V");
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
}
2019-01-28 17:44:15 +00:00
}
}
}
volatile uint8_t drive = 4;
//#define F_SAMP 4402
#define F_SAMP 4810 //4810 // ADC sample-rate; is best a multiple of _UA and fits exactly in OCR0A = ((F_CPU / 64) / F_SAMP) - 1 , should not exceed CPU utilization
#define _UA (F_SAMP) //360 // unit angle; integer representation of one full circle turn or 2pi radials or 360 degrees, should be a integer divider of F_SAMP and maximized to have higest precision
//#define MAX_DP (_UA/1) //(_UA/2) // the occupied SSB bandwidth can be further reduced by restricting the maximum phase change (set MAX_DP to _UA/2).
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
inline int16_t arctan3(int16_t q, int16_t i) // error ~ 0.8 degree
{ // source: [1] http://www-labs.iro.umontreal.ca/~mignotte/IFT2425/Documents/EfficientApproximationArctgFunction.pdf
2019-04-12 15:31:09 +00:00
#define _atan2(z) (_UA/8 - _UA/22 * z + _UA/22) * z //derived from (5) [1]
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
//#define _atan2(z) (_UA/8 - _UA/24 * z + _UA/24) * z //derived from (7) [1]
int16_t r;
if(abs(q) > abs(i))
2019-04-12 15:31:09 +00:00
r = _UA / 4 - _atan2(abs(i) / abs(q)); // arctan(z) = 90-arctan(1/z)
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
else
2019-04-12 15:31:09 +00:00
r = (i == 0) ? 0 : _atan2(abs(q) / abs(i)); // arctan(z)
r = (i < 0) ? _UA / 2 - r : r; // arctan(-z) = -arctan(z)
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
return (q < 0) ? -r : r; // arctan(-z) = -arctan(z)
}
2019-01-28 17:44:15 +00:00
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
uint8_t lut[256];
volatile uint8_t amp;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
inline int16_t ssb(int16_t in)
2019-01-28 17:44:15 +00:00
{
static int16_t dc;
2019-04-12 15:31:09 +00:00
int16_t i, q;
uint8_t j;
static int16_t v[16];
for(j = 0; j != 15; j++) v[j] = v[j + 1];
2019-01-28 17:44:15 +00:00
//dc += (in - dc) / 2;
v[15] = in - dc; // DC decoupling
dc = in; // this is actually creating a low-pass filter
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
2019-04-12 15:31:09 +00:00
i = v[7];
q = ((v[0] - v[14]) * 2 + (v[2] - v[12]) * 8 + (v[4] - v[10]) * 21 + (v[6] - v[8]) * 15) / 128 + (v[6] - v[8]) / 2; // Hilbert transform, 40dB side-band rejection in 400..1900Hz (@4kSPS) when used in image-rejection scenario; (Hilbert transform require 5 additional bits)
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
2019-04-12 15:31:09 +00:00
uint16_t _amp = abs(i) > abs(q) ? abs(i) + abs(q) / 4 : abs(q) + abs(i) / 4; // approximation of: amp = sqrt(i*i + q*q); error 0.95dB
2019-01-28 17:44:15 +00:00
#define VOX_THRESHOLD (1 << 2) // 2*6dB above ADC noise level
2019-04-12 15:31:09 +00:00
if(vox_enable) vox((_amp > VOX_THRESHOLD));
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
2019-04-12 15:31:09 +00:00
_amp = _amp << drive;
_amp = ((_amp > 255) || (drive == 8)) ? 255 : _amp; // clip or when drive=8 use max output
amp = (tx) ? lut[_amp] : 0;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
2019-04-12 15:31:09 +00:00
static int16_t prev_phase;
int16_t phase = arctan3(q, i);
int16_t dp = phase - prev_phase; // phase difference and restriction
prev_phase = phase;
2019-01-28 17:44:15 +00:00
if(dp < 0) dp = dp + _UA; // make negative phase shifts positive: prevents negative frequencies and will reduce spurs on other sideband
#ifdef MAX_DP
2019-04-12 15:31:09 +00:00
if(dp > MAX_DP){ // dp should be less than half unit-angle in order to keep frequencies below F_SAMP/2
prev_phase = phase - (dp - MAX_DP); // substract restdp
dp = MAX_DP;
}
#endif
if(mode == USB)
2019-04-12 15:31:09 +00:00
return dp * ( F_SAMP / _UA); // calculate frequency-difference based on phase-difference
else
return dp * (-F_SAMP / _UA);
2019-01-28 17:44:15 +00:00
}
volatile uint16_t numSamples = 0;
#define MIC_ATTEN 0 // 0*6dB attenuation (note that the LSB bits are quite noisy)
2019-01-28 17:44:15 +00:00
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
// This is the ADC ISR, issued with sample-rate via timer1 compb interrupt.
// It performs in real-time the ADC sampling, calculation of SSB phase-differences, calculation of SI5351 frequency registers and send the registers to SI5351 over I2C.
void dsp_tx()
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
{ // jitter dependent things first
uint8_t low = ADCL; // ADC sample 10-bits analog input, first ADCL, then ADCH
uint8_t high = ADCH;
OCR1BL = amp; // submit amplitude to PWM register (actually this is done in advance (about 140us) of phase-change, so that phase-delays in key-shaping circuit filter can settle)
si5351_SendPLLBRegisterBulk(); // submit frequency registers to SI5351 over 731kbit/s I2C (transfer takes 64/731 = 88us, then PLL-loopfilter probably needs 50us to stabalize)
//OCR1BL = amp; // submit amplitude to PWM register (takes about 1/32125 = 31us+/-31us to propagate) -> amplitude-phase-alignment error is about 30-50us
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
int16_t adc = ((high << 8) | low) - 512;
2019-01-28 17:44:15 +00:00
int16_t df = ssb(adc >> MIC_ATTEN); // convert analog input into phase-shifts (carrier out by periodic frequency shifts)
si5351_freq_calc_fast(df); // calculate SI5351 registers based on frequency shift and carrier frequency
2019-01-28 17:44:15 +00:00
numSamples++;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
}
2019-01-28 17:44:15 +00:00
int16_t dsp(int16_t in)
{
static int16_t dc;
int16_t i, q;
uint8_t j;
static int16_t v[16];
for(j = 0; j != 15; j++) v[j] = v[j + 1];
dc += (in - dc) / 2;
v[15] = in - dc; // DC decoupling
i = v[7];
q = ((v[0] - v[14]) * 2 + (v[2] - v[12]) * 8 + (v[4] - v[10]) * 21 + (v[6] - v[8]) * 15) / 128 + (v[6] - v[8]) / 2; // Hilbert transform, 40dB side-band rejection in 400..1900Hz (@4kSPS) when used in image-rejection scenario; (Hilbert transform require 5 additional bits)
return abs(i) > abs(q) ? abs(i) + abs(q) / 4 : abs(q) + abs(i) / 4; // approximation of: amp = sqrt(i*i + q*q); error 0.95dB
}
static int32_t signal;
static int16_t avg = 0;
static int16_t maxpk=0;
static int16_t k0=0;
static int16_t k1=0;
static uint8_t sym;
static int16_t ta=0;
static char m2c[] = "##ETIANMSURWDKGOHVF#L#PJBXCYZQ##54S3###2##+###J16=/###H#7#G#8#90############?_####\"##.####@###'##-########;!#)#####,####:####";
char cw(int16_t in)
{
char ch = 0;
int i;
signal += dsp(in);
#define OSR 64 // (8*FS/1000)
if((numSamples % OSR) == 0){ // process every 8 ms
if(!signal) return ch;
signal = signal / OSR; //normalize
maxpk = signal > maxpk ? signal : maxpk;
#define RT 4
if(signal>(maxpk/2) ){ // threshold: 3dB below max signal
k1++; // key on
k0=0;
} else {
k0++; // key off
if(k0>0 && k1>0){ //symbol space
if(k1>(ta/100)) ta=RT*ta/100+(100-RT)*k1; // go slower
if(k1>(ta/600) && k1<(ta/300)) ta=(100-RT)*ta/100+RT*k1*3; // go faster
if(k1>(ta/600)) sym=(sym<<1)|(k1>(ta/200)); // dit (0) or dash (1)
k1=0;
}
if(k0>=(ta/200) && sym>1){ //letter space
if(sym<128) ch=m2c[sym];
sym=1;
}
if(k0>=(ta/67)){ //word space (67=1.5/100)
ch = ' ';
k0=-1000*(ta/100); //delay word spaces
}
}
avg = avg*99/100 + signal*1/100;
maxpk = maxpk*99/100 + signal*1/100;
signal = 0;
}
return ch;
}
int16_t filt_cwn(int16_t in)
{
static int16_t v[4];
int16_t f0 = (in*16+105*v[0]+-57*v[1])/64;
int16_t f1 = (38*f0+-76*v[0]+38*v[1])/128;
v[1]=v[0];
v[0]=f0;
int16_t f2 = (f1*16+100*v[2]+-56*v[3])/64;
int16_t f3 = (32*v[1]+64*v[2]+32*v[3])/128;
v[3]=v[2];
v[2]=f2;
return f3;
}
static char out[] = " ";
volatile bool cw_event = false;
// This is the ADC ISR, issued with sample-rate via timer1 compb interrupt.
void dsp_rx()
{ // jitter dependent things first
uint8_t low = ADCL; // ADC sample 10-bits analog input, first ADCL, then ADCH
uint8_t high = ADCH;
int16_t adc = ((high << 8) | low) - 512;
static int16_t dc;
dc += (adc - dc) / 2;
int16_t ac = adc - dc; // DC decoupling
if(mode == CW) ac = filt_cwn(ac);
OCR1AL = ac + 128;
//#define CW_DECODER 1
#ifdef CW_DECODER
char ch = cw(adc >> 0);
if(ch){
for(int i=0; i!=15;i++) out[i]=out[i+1];
out[15] = ch;
cw_event = true;
}
#endif
numSamples++;
}
typedef void (*func_t)(void);
static volatile func_t func_ptr = dsp_tx;
ISR(ADC_vect) // ADC conversion interrupt
{
func_ptr();
}
ISR(TIMER0_COMPB_vect) // Timer0 interrupt
2019-01-28 17:44:15 +00:00
{
ADCSRA |= (1 << ADSC); // start ADC conversion (triggers ADC interrupt)
}
uint8_t old_TCCR0A;
uint8_t old_TCCR0B;
uint8_t old_TCNT0;
uint8_t old_TIMSK0;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
void adc_start(uint8_t adcpin, uint8_t ref1v1)
2019-01-28 17:44:15 +00:00
{
// Setup ADC
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
DIDR0 |= (1 << adcpin); // disable digital input
2019-01-28 17:44:15 +00:00
ADCSRA = 0; // clear ADCSRA register
ADCSRB = 0; // clear ADCSRB register
ADMUX = 0; // clear ADMUX register
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
ADMUX |= (adcpin & 0x0f); // set analog input pin
ADMUX |= ((ref1v1) ? (1 << REFS1) : 0) | (1 << REFS0); // set AREF=1.1V (Internal ref); otherwise AREF=AVCC=(5V)
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
//ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 128 prescaler for 9.6kHz*1.25
//ADCSRA |= (1 << ADPS2) | (1 << ADPS1); // 64 prescaler for 19.2kHz*1.25
//ADCSRA |= (1 << ADPS2) | (1 << ADPS0); // 32 prescaler for 38.5 KHz*1.25 (this seems to contain more precision and gain compared to 153.8kHz*1.25
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
//ADCSRA |= (1 << ADPS2); // 16 prescaler for 76.9 KHz*1.25
ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // ADPS=011: 8 prescaler for 153.8 KHz*1.25; sampling rate is [ADC clock] / [prescaler] / [conversion clock cycles] for Arduino Uno ADC clock is 20 MHz and a conversion takes 13 clock cycles: ADPS=011: 8 prescaler for 153.8 KHz, ADPS=100: 16 prescaler for 76.9 KHz; ADPS=101: 32 prescaler for 38.5 KHz; ADPS=110: 64 prescaler for 19.2kHz; // ADPS=111: 128 prescaler for 9.6kHz
2019-01-28 17:44:15 +00:00
ADCSRA |= (1 << ADIE); // enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); // enable ADC
//ADCSRA |= (1 << ADSC); // start ADC measurements
2019-01-28 17:44:15 +00:00
// backup Timer 0, is used by delay(), micros(), etc.
old_TCCR0A = TCCR0A;
old_TCCR0B = TCCR0B;
old_TCNT0 = TCNT0;
old_TIMSK0 = TIMSK0;
// Timer 0: interrupt mode
TCCR0A = 0;
TCCR0B = 0;
TCNT0 = 0;
TCCR0A |= (1 << WGM01); // turn on CTC mode
TCCR0B |= (1 << CS01) | (1 << CS00); // Set CS01 and CS00 bits for 64 prescaler
TIMSK0 |= (1 << OCIE0B); // enable timer compare interrupt TIMER0_COMPB_vect
uint8_t ocr = (((float)F_CPU / (float)64) / (float)F_SAMP + 0.5) - 1; // ((F_CPU / 64) / F_SAMP) - 1;
OCR0A = ocr; // Set the value that you want to count to : OCRn = [clock_speed / (Prescaler_value * Fs)] - 1 : sampling frequency
2019-01-28 17:44:15 +00:00
// Timer 1: PWM mode
TCCR1A = 0;
TCCR1B = 0;
TCCR1A |= (1 << COM1B1); // Clear OC1B on Compare Match when upcounting. Set OC1B on Compare Match when downcounting.
2019-01-28 17:44:15 +00:00
TCCR1B |= ((1 << CS10) | (1 << WGM13)); // WGM13: Mode 8 - PWM, Phase and Frequency Correct; CS10: clkI/O/1 (No prescaling)
ICR1H = 0x00; // TOP. This sets the PWM frequency: PWM_FREQ=312.500kHz ICR=0x1freq bit_depth=5; PWM_FREQ=156.250kHz ICR=0x3freq bit_depth=6; PWM_FREQ=78.125kHz ICR=0x7freq bit_depth=7; PWM_FREQ=39.250kHz ICR=0xFF bit_depth=8
ICR1L = 0xFF; // Fpwm = F_CPU / (2 * Prescaler * TOP) : PWM_FREQ = 39.25kHz, bit-depth=8
OCR1BH = 0;
2019-04-12 15:31:09 +00:00
OCR1BL = 0; // PWM duty-cycle (span set by ICR).
amp = 0;
2019-01-28 17:44:15 +00:00
}
#define F_SAMP_RX 8000
void adc_start_rx(uint8_t adcpin, uint8_t ref1v1)
{
// Setup ADC
DIDR0 |= (1 << adcpin); // disable digital input
ADCSRA = 0; // clear ADCSRA register
ADCSRB = 0; // clear ADCSRB register
ADMUX = 0; // clear ADMUX register
ADMUX |= (adcpin & 0x0f); // set analog input pin
ADMUX |= ((ref1v1) ? (1 << REFS1) : 0) | (1 << REFS0); // set AREF=1.1V (Internal ref); otherwise AREF=AVCC=(5V)
//ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 128 prescaler for 9.6kHz*1.25
//ADCSRA |= (1 << ADPS2) | (1 << ADPS1); // 64 prescaler for 19.2kHz*1.25
//ADCSRA |= (1 << ADPS2) | (1 << ADPS0); // 32 prescaler for 38.5 KHz*1.25
//ADCSRA |= (1 << ADPS2); // 16 prescaler for 76.9 KHz*1.25
ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // ADPS=011: 8 prescaler for 153.8 KHz; sampling rate is [ADC clock] / [prescaler] / [conversion clock cycles] for Arduino Uno ADC clock is 20 MHz and a conversion takes 13 clock cycles: ADPS=011: 8 prescaler for 153.8 KHz, ADPS=100: 16 prescaler for 76.9 KHz; ADPS=101: 32 prescaler for 38.5 KHz; ADPS=110: 64 prescaler for 19.2kHz; // ADPS=111: 128 prescaler for 9.6kHz
ADCSRA |= (1 << ADIE); // enable interrupts when measurement complete
ADCSRA |= (1 << ADEN); // enable ADC
//ADCSRA |= (1 << ADSC); // start ADC measurements
// backup Timer 0, is used by delay(), micros(), etc.
old_TCCR0A = TCCR0A;
old_TCCR0B = TCCR0B;
old_TCNT0 = TCNT0;
old_TIMSK0 = TIMSK0;
// Timer 0: interrupt mode
TCCR0A = 0;
TCCR0B = 0;
TCNT0 = 0;
TCCR0A |= (1 << WGM01); // turn on CTC mode
TCCR0B |= (1 << CS01) | (1 << CS00); // Set CS01 and CS00 bits for 64 prescaler
TIMSK0 |= (1 << OCIE0B); // enable timer compare interrupt TIMER0_COMPB_vect
uint8_t ocr = (((float)F_CPU / (float)64) / (float)F_SAMP_RX + 0.5) - 1; // ((F_CPU / 64) / F_SAMP) - 1;
OCR0A = ocr; // Set the value that you want to count to : OCRn = [clock_speed / (Prescaler_value * Fs)] - 1 : sampling frequency
// Timer 1: PWM mode
TCCR1A = 0;
TCCR1B = 0;
TCCR1A |= (1 << COM1A1); // Clear OC1A on Compare Match when upcounting. Set OC1A on Compare Match when downcounting.
TCCR1B |= ((1 << CS10) | (1 << WGM13)); // WGM13: Mode 8 - PWM, Phase and Frequency Correct; CS10: clkI/O/1 (No prescaling)
ICR1H = 0x00; // TOP. This sets the PWM frequency: PWM_FREQ=312.500kHz ICR=0x1freq bit_depth=5; PWM_FREQ=156.250kHz ICR=0x3freq bit_depth=6; PWM_FREQ=78.125kHz ICR=0x7freq bit_depth=7; PWM_FREQ=39.250kHz ICR=0xFF bit_depth=8
ICR1L = 0xFF; // Fpwm = F_CPU / (2 * Prescaler * TOP) : PWM_FREQ = 39.25kHz, bit-depth=8
OCR1AH = 0;
OCR1AL = 0; // PWM duty-cycle (span set by ICR).
}
2019-01-28 17:44:15 +00:00
void adc_stop()
2019-04-12 15:31:09 +00:00
{
2019-01-28 17:44:15 +00:00
// restore Timer 0, is shared with delay(), micros(), etc.
TCCR0A = old_TCCR0A;
TCCR0B = old_TCCR0B;
TCNT0 = old_TCNT0;
TIMSK0 = old_TIMSK0;
2019-04-12 15:31:09 +00:00
2019-01-28 17:44:15 +00:00
// Stop Timer 0 interrupt
//TIMSK0 &= ~(1 << OCIE0B); // disable timer compare interrupt TIMER0_COMPB_vect
//TCCR0A |= (1 << WGM00); // for some reason WGM00 must be 1 in normal operation
OCR1AL = 0x00;
OCR1BL = 0x00;
2019-04-12 15:31:09 +00:00
//ADCSRA &= ~(1 << ADATE); // disable auto trigger
2019-01-28 17:44:15 +00:00
ADCSRA &= ~(1 << ADIE); // disable interrupts when measurement complete
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // 128 prescaler for 9.6kHz
ADMUX = 0; // clear ADMUX register
ADMUX |= (1 << REFS0); // restore reference voltage AREF (5V)
}
static uint8_t bandval = 2; //4
#define N_BANDS 7 //13
uint32_t band[] = { 3573000, 5357000, 7074000, 10136000, 14074000, 18100000, 21074000 }; //{ 472000, 1840000, 3573000, 5357000, 7074000, 10136000, 14074000, 18100000, 21074000, 24915000, 28074000, 50313000, 70101000 };
enum step_t { STEP_10M, STEP_1M, STEP_500k, STEP_100k, STEP_10k, STEP_1k, STEP_500, STEP_100, STEP_10, STEP_1 };
volatile int8_t stepsize = STEP_1k;
2019-01-28 17:44:15 +00:00
void encoder_vect(int8_t sign)
{
int32_t stepval;
switch(stepsize){
case STEP_10M: stepval = 10000000; break;
case STEP_1M: stepval = 1000000; break;
case STEP_500k: stepval = 500000; break;
case STEP_100k: stepval = 100000; break;
case STEP_10k: stepval = 10000; break;
case STEP_1k: stepval = 1000; break;
case STEP_500: stepval = 500; break;
case STEP_100: stepval = 100; break;
case STEP_10: stepval = 10; break;
case STEP_1: stepval = 1; break;
}
2019-04-12 15:31:09 +00:00
if(stepval < STEP_100) freq %= 1000; // when tuned and stepsize > 100Hz then forget fine-tuning details
2019-01-28 17:44:15 +00:00
freq += sign * stepval;
freq = max(1, min(99999999, freq));
2019-01-28 17:44:15 +00:00
change = true;
}
void stepsize_showcursor()
{
2019-04-12 15:31:09 +00:00
lcd.setCursor(stepsize, 1); // display stepsize with cursor
lcd.cursor();
2019-01-28 17:44:15 +00:00
}
void stepsize_change(int8_t val)
{
stepsize += val;
if(stepsize < STEP_1M) stepsize = STEP_10;
if(stepsize > STEP_10) stepsize = STEP_1M;
if(stepsize == STEP_10k || stepsize == STEP_500k) stepsize += val;
2019-01-28 17:44:15 +00:00
stepsize_showcursor();
}
2019-04-12 15:31:09 +00:00
ISR(PCINT2_vect){ // Interrupt on rotary encoder turn
2019-01-28 17:44:15 +00:00
noInterrupts();
static uint8_t last_state;
2019-01-28 17:44:15 +00:00
uint8_t curr_state = (digitalRead(ROT_B) << 1) | digitalRead(ROT_A);
switch((last_state << 2) | curr_state){ //transition
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
#ifdef ENCODER_ENHANCED_RESOLUTION // Option: enhance encoder from 24 to 96 steps/revolution, see: https://www.sdr-kits.net/documents/PA0KLT_Manual.pdf
2019-01-28 17:44:15 +00:00
case 0b1101: case 0b0100: case 0b0010: case 0b1011: encoder_vect(1); break;
case 0b1110: case 0b1000: case 0b0001: case 0b0111: encoder_vect(-1); break;
#else
case 0b1101: encoder_vect(1); break;
case 0b1110: encoder_vect(-1); break;
#endif
}
last_state = curr_state;
interrupts();
}
void encoder_setup()
{
pinMode(ROT_A, INPUT_PULLUP);
pinMode(ROT_B, INPUT_PULLUP);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT22) | (1 << PCINT23);
interrupts();
}
void qcx_setup()
{
// initialize
digitalWrite(SIG_OUT, LOW);
digitalWrite(RX, HIGH);
digitalWrite(KEY_OUT, LOW);
digitalWrite(SIDETONE, LOW);
2019-01-28 17:44:15 +00:00
// pins
pinMode(SIDETONE, OUTPUT);
2019-01-28 17:44:15 +00:00
pinMode(SIG_OUT, OUTPUT);
pinMode(RX, OUTPUT);
pinMode(KEY_OUT, OUTPUT);
pinMode(BUTTONS, INPUT); // L/R/rotary button
pinMode(DIT, INPUT_PULLUP);
pinMode(DAH, INPUT);
pinMode(AUDIO1, INPUT);
pinMode(AUDIO2, INPUT);
}
char blanks[] = " ";
byte font_run[] = {
0b01000,
0b00100,
0b01010,
0b00101,
0b01010,
0b00100,
0b01000,
0b00000
};
void customDelay(uint32_t _micros) //_micros=100000 is 132052us delay
{
uint32_t i; for(i = 0; i != _micros * 3; i++) wdt_reset();
}
uint32_t sample_amp(uint8_t pin, uint16_t osr)
2019-01-28 17:44:15 +00:00
{
2019-04-12 15:31:09 +00:00
uint16_t avg = 1024 / 2;
2019-01-28 17:44:15 +00:00
uint32_t rms = 0;
uint16_t i;
2019-04-12 15:31:09 +00:00
for(i = 0; i != 16; i++){
2019-01-28 17:44:15 +00:00
uint16_t adc = analogRead(pin);
avg = (avg + adc) / 2;
}
for(i = 0; i != osr; i++){ // 128 overampling is 42dB gain => with 10-bit ADC resulting in a total of 102dB DR
2019-01-28 17:44:15 +00:00
uint16_t adc = analogRead(pin);
avg = (avg + adc) / 2; // average
rms += ((adc > avg) ? 1 : -1) * (adc - avg); // rectify based
wdt_reset();
2019-01-28 17:44:15 +00:00
}
return rms;
}
float smeter(float ref = 0.0)
{
float rms = ((float)sample_amp(AUDIO1, 128)) * 5.0 / (1024.0 * 128.0 * 100.0 * 120.0 / 1.750); // rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * audio gain]
float dbm = (10.0 * log10((rms * rms) / 50.0) + 30.0) - ref; //from rmsV to dBm at 50R
static float dbm_max;
dbm_max = max(dbm_max, dbm);
static uint8_t cnt;
cnt++;
if((cnt % 8) == 0){
//#define DBM_METER 1
#ifdef DBM_METER
lcd.setCursor(9, 0); lcd.print((int16_t)dbm_max); lcd.print((ref == 0.0) ? "dBm " : "dB ");
#else
uint8_t s = (dbm_max < -63) ? ((dbm_max - -127) / 6) : (uint8_t)(dbm_max - -63 + 10) % 10; // dBm to S
lcd.setCursor(14, 0); if(s < 10){ lcd.print("S"); } lcd.print(s);
#endif
dbm_max = -174.0 + 34.0;
}
return dbm;
}
float dbmeter(float ref = 0.0)
{
float rms = ((float)sample_amp(AUDIO1, 128)) * 5.0 / (1024.0 * 128.0 * 100.0); // rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * audio gain]
float dbm = (10.0 * log10((rms * rms) / 50.0) + 30.0) - ref; //from rmsV to dBm at 50R
lcd.setCursor(9, 0); lcd.print(dbm); lcd.print("dB ");
delay(300);
return dbm;
}
void test_tx_amp()
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
{
lcd.setCursor(9, 0); lcd.print(blanks);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
TCCR1A = 0; // Timer 1: PWM mode
TCCR1B = 0;
TCCR1A |= (1 << COM1B1); // Clear OC1A/OC1B on Compare Match when upcounting. Set OC1A/OC1B on Compare Match when downcounting.
TCCR1B |= ((1 << CS10) | (1 << WGM13)); // WGM13: Mode 8 - PWM, Phase and Frequency Correct; CS10: clkI/O/1 (No prescaling)
ICR1H = 0x00; // TOP. This sets the PWM frequency: PWM_FREQ=312.500kHz ICR=0x1freq bit_depth=5; PWM_FREQ=156.250kHz ICR=0x3freq bit_depth=6; PWM_FREQ=78.125kHz ICR=0x7freq bit_depth=7; PWM_FREQ=39.250kHz ICR=0xFF bit_depth=8
ICR1L = 0xFF; // Fpwm = F_CPU / (2 * Prescaler * TOP) : PWM_FREQ = 39.25kHz, bit-depth=8
OCR1BH = 0x00;
2019-04-12 15:31:09 +00:00
OCR1BL = 0x00; // PWM duty-cycle (span set by ICR).
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_prev_pll_freq = 0; // enforce PLL reset
si5351_freq(freq, 0, 90); // RX in USB
si5351_alt_clk2(freq);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SendRegister(SI_CLK_OE, 0b11111011); // CLK2_EN=1, CLK1_EN,CLK0_EN=0
digitalWrite(RX, LOW); // TX
uint16_t i;
for(i = 0; i != 256; i++)
{
OCR1BL = lut[i];
2019-04-12 15:31:09 +00:00
si5351_alt_clk2(freq + i * 10);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
wdt_reset();
lcd.setCursor(0, 1); lcd.print("SWEEP("); lcd.print(i); lcd.print(")="); lcd.print(lut[i]); lcd.print(blanks);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
delay(200);
}
OCR1BL = 0;
2019-04-12 15:31:09 +00:00
delay(500);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
digitalWrite(RX, HIGH); // RX
si5351_SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
change = true; //restore original frequency setting
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
}
void calibrate_predistortion()
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
{
lcd.setCursor(9, 0); lcd.print(blanks);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
TCCR1A = 0; // Timer 1: PWM mode
TCCR1B = 0;
TCCR1A |= (1 << COM1B1); // Clear OC1A/OC1B on Compare Match when upcounting. Set OC1A/OC1B on Compare Match when downcounting.
TCCR1B |= ((1 << CS10) | (1 << WGM13)); // WGM13: Mode 8 - PWM, Phase and Frequency Correct; CS10: clkI/O/1 (No prescaling)
ICR1H = 0x00; // TOP. This sets the PWM frequency: PWM_FREQ=312.500kHz ICR=0x1freq bit_depth=5; PWM_FREQ=156.250kHz ICR=0x3freq bit_depth=6; PWM_FREQ=78.125kHz ICR=0x7freq bit_depth=7; PWM_FREQ=39.250kHz ICR=0xFF bit_depth=8
ICR1L = 0xFF; // Fpwm = F_CPU / (2 * Prescaler * TOP) : PWM_FREQ = 39.25kHz, bit-depth=8
OCR1BH = 0x00;
2019-04-12 15:31:09 +00:00
OCR1BL = 0x00; // PWM duty-cycle (span set by ICR).
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_prev_pll_freq = 0; //enforce PLL reset
si5351_freq(freq, 0, 90); // RX in USB
si5351_alt_clk2(freq + 1000); // si5351_freq_clk2(freq + 1000);
si5351_SendRegister(SI_CLK_OE, 0b11111000); // CLK2_EN=1, CLK1_EN,CLK0_EN=1
digitalWrite(RX, LOW); // TX
OCR1BL = 0xFF; // Max power to determine scale
delay(200);
float scale = sample_amp(AUDIO2, 128);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
wdt_reset();
uint8_t amp[256];
2019-04-12 15:31:09 +00:00
int16_t i, j;
for(i = 127; i >= 0; i--) // determine amp for pwm value i
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
{
OCR1BL = i;
wdt_reset();
delay(100);
amp[i] = min(255, (float)sample_amp(AUDIO2, 128) * 255.0 / scale);
lcd.setCursor(0, 1); lcd.print("CALIB("); lcd.print(i); lcd.print(")="); lcd.print(amp[i]); lcd.print(blanks);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
}
OCR1BL = 0xFF; // Max power to determine scale
delay(200);
for(j = 0; j != 256; j++){
for(i = 0; i != 255 && amp[i] < j; i++) ; //lookup pwm i for amp[i] >= j
if(j == 255) i = 255; // do not use PWM for peak RF
lut[j] = i;
}
OCR1BL = 0x00;
digitalWrite(RX, HIGH); // RX
si5351_SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
change = true; //restore original frequency setting
2019-01-28 17:44:15 +00:00
}
// 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()
{
lcd.setCursor(9, 0); lcd.print(blanks);
digitalWrite(SIG_OUT, true); // loopback on
si5351_prev_pll_freq = 0; //enforce PLL reset
si5351_freq(freq, 0, 90); // RX in USB
float dbc;
si5351_alt_clk2(freq + 700);
dbc = dbmeter();
si5351_alt_clk2(freq - 700);
lcd.setCursor(0, 1); lcd.print("I-Q bal. (700 Hz)"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); dbmeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
si5351_alt_clk2(freq + 600);
dbc = dbmeter();
si5351_alt_clk2(freq - 600);
lcd.setCursor(0, 1); lcd.print("Phase Lo (600 Hz)"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); dbmeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
si5351_alt_clk2(freq + 800);
dbc = dbmeter();
si5351_alt_clk2(freq - 800);
lcd.setCursor(0, 1); lcd.print("Phase Hi (800 Hz)"); lcd.print(blanks);
for(; !digitalRead(BUTTONS);){ wdt_reset(); dbmeter(dbc); } for(; digitalRead(BUTTONS);) wdt_reset();
/*
for(uint32_t offset = 0; offset < 3000; offset += 100){
si5351_alt_clk2(freq + offset);
dbc = dbmeter();
si5351_alt_clk2(freq - offset);
lcd.setCursor(0, 1); lcd.print(offset); lcd.print(" Hz"); lcd.print(blanks);
wdt_reset(); dbmeter(dbc); delay(500); 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
2019-01-28 17:44:15 +00:00
}
void powermeter()
2019-01-28 17:44:15 +00:00
{
lcd.setCursor(9, 0); lcd.print(blanks);
si5351_prev_pll_freq = 0; //enforce PLL reset
si5351_freq(freq, 0, 90); // RX in USB
si5351_alt_clk2(freq + 1000); // si5351_freq_clk2(freq + 1000);
si5351_SendRegister(SI_CLK_OE, 0b11111000); // CLK2_EN=1, CLK1_EN,CLK0_EN=1
digitalWrite(KEY_OUT, HIGH); //OCR1BL = 0xFF;
digitalWrite(RX, LOW); // TX
delay(100);
float rms = ((float)sample_amp(AUDIO2, 128)) * 5.0 / (1024.0 * 128.0 * 100.0 * 50.0 / 100000.0); // rmsV = ADC value * AREF / [ADC DR * processing gain * receiver gain * rx/tx switch attenuation]
2019-04-12 15:31:09 +00:00
float dbm = 10.0 * log10((rms * rms) / 50.0) + 30.0; //from rmsV to dBm at 50R
lcd.setCursor(9, 0); lcd.print(" +"); lcd.print((int16_t)dbm); lcd.print("dBm ");
digitalWrite(KEY_OUT, LOW); //OCR1BL = 0x00;
digitalWrite(RX, HIGH); // RX
si5351_SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
change = true; //restore original frequency setting
delay(1000);
2019-01-28 17:44:15 +00:00
}
void toggle_rxdsp()
{
if(func_ptr != dsp_rx){
func_ptr = dsp_rx; //enable RX DSP
adc_start_rx(0, false);
} else {
adc_stop(); //disable RX DSP
func_ptr = dsp_tx;
}
change = true;
}
/*
volatile boolean WDTalarm = false;
ISR(WDT_vect)
{
wdt_disable(); // disable watchdog so the system does not restart
WDTalarm = true; // flag the event
}
float getTemp()
{
WDTalarm = false;
// Set the Watchdog timer from: https://www.gammon.com.au/power
byte interval = 0b000110; // 1s=0b000110, 2s=0b000111, 4s=0b100000, 8s=0b10000
//64ms= 0b000010, 128ms = 0b000011, 256ms= 0b000100, 512ms= 0b000101
noInterrupts ();
MCUSR = 0;
WDTCSR |= 0b00011000; // set WDCE, WDE
WDTCSR = 0b01000000 | interval; // set WDIE & delay interval
wdt_reset(); // pat the dog
interrupts ();
unsigned long startTime = micros();
while(!WDTalarm) { //sleep while waiting for the WDT
set_sleep_mode (SLEEP_MODE_IDLE);
noInterrupts (); sleep_enable(); interrupts (); sleep_cpu ();
sleep_disable(); //processor starts here when any interrupt occurs
}
unsigned long WDTmicrosTime = micros() - startTime; // this is your measurement!
return (float)WDTmicrosTime * 0.0026 - 3668.1; //calibrate here
}
*/
2019-01-28 17:44:15 +00:00
void setup()
{
// Benchmark ADC_vect() ISR (this needs to be done in beginning of setup() otherwise when VERSION containts 5 chars, mis-alignment impact performance by a few percent)
uint32_t t0, t1;
t0 = micros();
TIMER0_COMPB_vect();
ADC_vect();
t1 = micros();
float load = (t1 - t0) * F_SAMP * 100.0 / 1000000.0;
2019-01-28 17:44:15 +00:00
wdt_enable(WDTO_2S); // Enable watchdog, resolves QCX startup issue
lcd.begin(16, 2);
lcd.createChar(1, font_run);
2019-04-12 15:31:09 +00:00
lcd.setCursor(0, 0); lcd.print("QCX-SSB R"); lcd.print(VERSION); lcd.print(blanks);
delay(200);
//lcd.setCursor(0, 1); lcd.print("temp="); lcd.print(getTemp()); lcd.print("C");
//for(;!digitalRead(BUTTONS);) wdt_reset();
2019-01-28 17:44:15 +00:00
i2c_init();
encoder_setup();
qcx_setup();
2019-01-28 17:44:15 +00:00
//PCICR |= (1 << PCIE0);
//PCMSK0 |= (1 << PCINT5) | (1 << PCINT4) | (1 << PCINT3);
//interrupts();
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
// initialize LUT
//#define C31_IS_INSTALLED 1 // Uncomment this line when C31 is installed (shaping circuit will be driven with analog signal instead of being switched digitally with PWM signal)
2019-04-12 15:31:09 +00:00
#ifdef C31_IS_INSTALLED // In case of analog driven shaping circuit:
#define PWM_MIN 29 // The PWM value where the voltage over L4 is approaching its minimum (~0.6V)
#define PWM_MAX 96 // The PWM value where the voltage over L4 is approaching its maximum (~11V)
2019-04-12 15:31:09 +00:00
#else // In case of digital driven shaping circuit:
#define PWM_MIN 0 // The PWM value where the voltage over L4 is its minimum (0V)
#define PWM_MAX 255 // The PWM value where the voltage over L4 is its maximum (12V)
2019-04-12 15:31:09 +00:00
#endif
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
uint16_t i;
2019-04-12 15:31:09 +00:00
for(i = 0; i != 256; i++)
lut[i] = (float)i / ((float)255 / ((float)PWM_MAX - (float)PWM_MIN)) + PWM_MIN;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
// Measure CPU loads
if(!(load < 100.0)){
lcd.setCursor(0, 1); lcd.print("E01 CPU overload");
delay(1500);
wdt_reset();
}
// Measure VDD (+5V); should be ~5V
digitalWrite(RX, LOW); // mute RX
digitalWrite(KEY_OUT, LOW);
si5351_SendRegister(SI_CLK_OE, 0b11111111); // Mute QSD: CLK2_EN=CLK1_EN,CLK0_EN=0
float vdd = 2.0 * (float)analogRead(AUDIO2) * 5.0 / 1024.0;
digitalWrite(RX, HIGH);
if(!(vdd > 4.5 && vdd < 5.2)){
lcd.setCursor(0, 1); lcd.print("E02 +5V not OK");
delay(1500);
wdt_reset();
}
// Measure VEE (+3.3V); should be ~3.3V
float vee = (float)analogRead(SCL) * 5.0 / 1024.0;
if(!(vee > 3.2 && vee < 3.8)){
lcd.setCursor(0, 1); lcd.print("E03 +3.3V not OK");
delay(1500);
wdt_reset();
}
// Measure AVCC via AREF and using internal 1.1V reference fed to ADC; should be ~5V
analogRead(6); // setup almost proper ADC readout
bitSet(ADMUX, 3); // Switch to channel 14 (Vbg=1.1V)
delay(1); // delay improves accuracy
bitSet(ADCSRA, ADSC);
for(; bit_is_set(ADCSRA, ADSC););
float avcc = 1.1 * 1023.0 / ADC;
if(!(avcc > 4.6 && avcc < 5.1)){
lcd.setCursor(0, 1); lcd.print("E04 AVCC not OK");
delay(1500);
wdt_reset();
}
// Measure DVM bias; should be ~VAREF/2
float dvm = (float)analogRead(DVM) * 5.0 / 1024.0;
if(!(dvm > 1.8 && dvm < 3.2)){
lcd.setCursor(0, 1); lcd.print("E05 DVM bias err");
delay(1500);
wdt_reset();
}
// Measure I2C Bus speed for Bulk Transfers
t0 = micros();
for(i = 0; i != 1000; i++) si5351_SendPLLBRegisterBulk();
t1 = micros();
uint32_t i2c_speed = (1000000 * 8 * 7) / (t1 - t0); // speed in kbit/s
// Measure I2C Bit-Error Rate (BER); should be error free for a thousand random bulk PLLB writes
uint16_t i2c_error = 0; // number of I2C byte transfer errors
for(i = 0; i != 1000; i++){
for(int j = 3; j != 8; j++) si5351_pll_data[j] = rand();
si5351_SendPLLBRegisterBulk();
for(int j = 3; j != 8; j++) if(si5351_RecvRegister(SI_SYNTH_PLL_B + j) != si5351_pll_data[j]) i2c_error++;
}
if(i2c_error){
lcd.setCursor(0, 1); lcd.print("E06 I2C tx error");
delay(1500);
wdt_reset();
}
lcd.setCursor(0, 1); lcd.print("CPU_tx="); lcd.print(load); lcd.print("%"); lcd.print(blanks);
delay(800);
2019-04-12 15:31:09 +00:00
lcd.setCursor(7, 0); lcd.print("\001"); lcd.print(blanks); // Ready: display initialization complete normally
2019-01-28 17:44:15 +00:00
}
void loop()
{
delay(100);
2019-04-12 15:31:09 +00:00
if(func_ptr != dsp_rx) smeter();
if(mode == CW && cw_event){
cw_event = false;
lcd.setCursor(0, 1); lcd.print(out);
}
2019-01-28 17:44:15 +00:00
if(!digitalRead(DIT)){
2019-04-12 15:31:09 +00:00
lcd.setCursor(15, 1); lcd.print("T");
lcd.setCursor(9, 0); lcd.print(blanks);
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SendRegister(SI_CLK_OE, 0b11111011); // CLK2_EN=1, CLK1_EN,CLK0_EN=0
adc_start(2, true);
customDelay(1000); //allow setup time
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
digitalWrite(RX, LOW); // TX
tx = 1;
for(; !digitalRead(DIT);){ //until released
2019-01-28 17:44:15 +00:00
wdt_reset();
}
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
digitalWrite(RX, HIGH); // RX
customDelay(1000); //allow setup time
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
tx = 0;
2019-01-28 17:44:15 +00:00
adc_stop();
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_SendRegister(SI_CLK_OE, 0b11111100); // CLK2_EN=0, CLK1_EN,CLK0_EN=1
2019-04-12 15:31:09 +00:00
lcd.setCursor(15, 1); lcd.print("R");
2019-01-28 17:44:15 +00:00
}
2019-04-12 15:31:09 +00:00
if(digitalRead(BUTTONS)){ // Left-/Right-/Rotary-button
uint16_t val;
if(func_ptr != dsp_rx) //hack to prevent corrupting RX DSP ADC settings
val = analogRead(BUTTONS);
else { toggle_rxdsp(); return; }
2019-01-28 17:44:15 +00:00
bool longpress = false;
bool doubleclick = false;
int32_t t0 = millis();
for(; digitalRead(BUTTONS) && !longpress;){ // until released or long-press
2019-01-28 17:44:15 +00:00
longpress = ((millis() - t0) > 300);
wdt_reset();
}
delay(10); //debounce
2019-04-12 15:31:09 +00:00
for(; !longpress && ((millis() - t0) < 500) && !doubleclick;){ //until 2nd press or timeout
2019-01-28 17:44:15 +00:00
doubleclick = digitalRead(BUTTONS);
wdt_reset();
}
for(; digitalRead(BUTTONS);) wdt_reset(); // until released
if(val < 862){ // LEFT-button ADC=780
2019-01-28 17:44:15 +00:00
if(doubleclick){
calibrate_predistortion();
return;
}
if(longpress){
test_tx_amp();
//powermeter();
2019-01-28 17:44:15 +00:00
return;
} //single-click
//calibrate_iq();
toggle_rxdsp();
} else if(val < 1023){ // RIGHT-button ADC=943
if(doubleclick){
if(drive == 0) drive = 1;
else drive += 1;
if(drive > 8) drive = 0;
lcd.setCursor(0, 1); lcd.print("Drive "); lcd.print(drive); lcd.print(blanks);
return;
2019-01-28 17:44:15 +00:00
}
if(longpress){
2019-04-12 15:31:09 +00:00
lcd.setCursor(15, 1); lcd.print("V");
lcd.setCursor(9, 0); lcd.print(blanks);
2019-01-28 17:44:15 +00:00
vox_enable = true;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
adc_start(2, true);
2019-04-12 15:31:09 +00:00
for(; !digitalRead(BUTTONS);){ // while in VOX mode
wdt_reset(); // until 2nd press
}
2019-01-28 17:44:15 +00:00
adc_stop();
vox_enable = false;
2019-04-12 15:31:09 +00:00
lcd.setCursor(15, 1); lcd.print("R");
for(; digitalRead(BUTTONS);) wdt_reset(); // until released
2019-01-28 17:44:15 +00:00
delay(100);
return;
} //single-click
mode++;
if(mode > CW) mode = LSB;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
si5351_prev_pll_freq = 0; // enforce PLL reset
2019-04-12 15:31:09 +00:00
change = true;
} else { // ROTARY-button ADC=1023
2019-01-28 17:44:15 +00:00
if(doubleclick){
delay(100);
bandval++;
if(bandval >= N_BANDS) bandval = 0;
2019-04-12 15:31:09 +00:00
freq = band[bandval];
2019-01-28 17:44:15 +00:00
stepsize = STEP_1k;
2019-04-12 15:31:09 +00:00
change = true;
2019-01-28 17:44:15 +00:00
return;
}
if(longpress){
stepsize_change(-1);
return;
} //single-click
2019-01-28 17:44:15 +00:00
stepsize_change(+1);
2019-04-12 15:31:09 +00:00
}
2019-01-28 17:44:15 +00:00
}
if(change){
change = false;
Improved audio quality and IMD3 performance and experimental (amplitude) pre-distortion and calibration. Fixed an issue with spurious transmission for RX-TX-RX transitions. In detail: Reduced sample jitter by matching sampling rate to a multiple of OCR0A timer divider. Unit angle now configurable and scalable so that full precision (of integer range) can be used to calculate phase differences; the unit angle is configured to be an exact multiple of the samp$ Hilbert transformer fixed bug, simplified and improved in precision (improved from -15dB to -40dB in an image rejection setting). Arctan rounding errors reduced from approx. 5 degree to 0.8 degree. Moved from 8 bit to 16 bit precision for audio input and I/Q values. Microphone-input response now flat from 0-2200Hz (removed original high-pass filter with 20dB roll-off at 800Hz). Experimental code (currently commented-out) for measuring phase differences between programmatically synchronised SI5351 clocks. Fixed an issue where for every RX-TX transition a burst of random RF frequencies were emitted. Improved precision of smeter, and found that disabling smeter prevent spurs leaking in from LCD data transfer into RXi (smeter still enabled). Added a LUT-based pre-distortion algorithm that can be calibrated via an internal amplitude measurement. Fixed issue with the envelope generation through Q6 impacting the IMD-performance, dynamic range, efficiency and thermal-stability; this fix REQUIRES the removal of C31 and increase of C32 to$ Fixed an issue where VOX was unintentially triggering TX by ADC noise leaking through key-shaping circuit, and simplied VOX algorithm. Generaized PLL and MultiSynth algorithms and added experimental algorithm for setting a second frequency (via a different MS divider and where PLL is the same). Experimental code for measuring the phase of the transmitted signal (via PA and QSD), this could give insight in antenna impedance and PA phase-response as function of amplitude.
2019-04-02 16:34:03 +00:00
uint32_t n = freq / 1000000; // lcd.print(f) with commas
2019-01-28 17:44:15 +00:00
uint32_t n2 = freq % 1000000;
uint32_t scale = 1000000;
2019-04-12 15:31:09 +00:00
char buf[16];
sprintf(buf, "%2u", n); lcd.setCursor(0, 1); lcd.print(buf);
while(scale != 1){
scale /= 1000;
n = n2 / scale;
n2 = n2 % scale;
if(scale == 1) sprintf(buf, ",%02u", n / 10); else // leave last digit out
sprintf(buf, ",%03u", n);
lcd.print(buf);
2019-01-28 17:44:15 +00:00
}
lcd.print(" ");
if(mode == LSB) lcd.print("LSB");
if(mode == USB) lcd.print("USB");
if(mode == CW) lcd.print("CW ");
lcd.print(" ");
if(func_ptr != dsp_rx) lcd.setCursor(15, 1); lcd.print("R");
if(func_ptr == dsp_rx) lcd.setCursor(15, 1); lcd.print("D");
2019-04-12 15:31:09 +00:00
if(mode == LSB)
si5351_freq(freq, 90, 0); // RX in LSB
else
si5351_freq(freq, 0, 90); // RX in USB
2019-01-28 17:44:15 +00:00
}
wdt_reset();
stepsize_showcursor();
}