diff --git a/.cproject b/.cproject
index ec54bde..4714753 100644
--- a/.cproject
+++ b/.cproject
@@ -21,12 +21,21 @@
-
+
+
+
-
+
+
+
+
+
+
-
+
+
+
@@ -41,4 +50,6 @@
+
+
diff --git a/NANOVNA_STM32_F072/board.h b/NANOVNA_STM32_F072/board.h
index 7a8ac43..143a48e 100644
--- a/NANOVNA_STM32_F072/board.h
+++ b/NANOVNA_STM32_F072/board.h
@@ -56,6 +56,7 @@
#define GPIOA_XP 6
#define GPIOA_YP 7
#define GPIOA_MCO 8
+#define GPIOA_TX 9
#define GPIOA_USB_DISC 10
#define GPIOA_USB_DM 11
#define GPIOA_USB_DP 12
@@ -130,7 +131,7 @@
PIN_MODE_ANALOG(GPIOA_XP) | \
PIN_MODE_ANALOG(GPIOA_YP) | \
PIN_MODE_ALTERNATE(GPIOA_MCO) | \
- PIN_MODE_INPUT(9U) | \
+ PIN_MOD_ULTRA(9U) | \
PIN_MODE_OUTPUT(GPIOA_USB_DISC) | \
PIN_MODE_INPUT(GPIOA_USB_DM) | \
PIN_MODE_INPUT(GPIOA_USB_DP) | \
diff --git a/halconf.h b/halconf.h
index 1450b9f..af6c283 100644
--- a/halconf.h
+++ b/halconf.h
@@ -132,7 +132,7 @@
* @brief Enables the SERIAL subsystem.
*/
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
-#define HAL_USE_SERIAL FALSE
+#define HAL_USE_SERIAL TRUE
#endif
/**
diff --git a/ili9341.c b/ili9341.c
index 3b21d4e..bba3dd9 100644
--- a/ili9341.c
+++ b/ili9341.c
@@ -294,9 +294,11 @@ static const uint8_t ili9341_init_seq[] = {
// POWER_CONTROL_2
ILI9341_POWER_CONTROL_2, 1, 0x11,
// VCOM_CONTROL_1
- ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E,
+// ILI9341_VCOM_CONTROL_1, 2, 0x35, 0x3E,
+ ILI9341_VCOM_CONTROL_1, 2, 0x3e, 0x28,
// VCOM_CONTROL_2
ILI9341_VCOM_CONTROL_2, 1, 0xBE,
+// ILI9341_VCOM_CONTROL_2, 1, 0x86,
// MEMORY_ACCESS_CONTROL
//ILI9341_MEMORY_ACCESS_CONTROL, 1, 0x48, // portlait
ILI9341_MEMORY_ACCESS_CONTROL, 1, DISPLAY_ROTATION_0, // landscape
diff --git a/main.c b/main.c
index 100c856..7b1f13f 100644
--- a/main.c
+++ b/main.c
@@ -16,9 +16,14 @@
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
+//#define HAL_USE_SERIAL 1
+//#define STM32_SERIAL_USE_USART1 1
#include "ch.h"
#include "hal.h"
+
+//#include "hal_serial.h"
+
#include "usbcfg.h"
#ifdef __VNA__
#include "si5351.h"
@@ -32,10 +37,10 @@
#include
#include
-extern uint32_t minFreq;
-extern uint32_t maxFreq;
-uint32_t frequencyStart;
-uint32_t frequencyStop;
+extern float minFreq;
+extern float maxFreq;
+float frequencyStart;
+float frequencyStop;
int32_t frequencyExtra;
#define START_MIN minFreq
#define STOP_MAX maxFreq
@@ -2204,7 +2209,7 @@ int xtoi(char *t)
else if ('a' <= *t && *t <= 'f')
v = v*16 + *t - 'a' + 10;
else if ('A' <= *t && *t <= 'F')
- v = v*16 + *t - 'a' + 10;
+ v = v*16 + *t - 'A' + 10;
else
return v;
t++;
@@ -2212,7 +2217,7 @@ int xtoi(char *t)
return v;
}
-VNA_SHELL_FUNCTION(cmd_x)
+VNA_SHELL_FUNCTION(cmd_y)
{
int rvalue;
int lvalue = 0;
@@ -2231,9 +2236,36 @@ VNA_SHELL_FUNCTION(cmd_x)
}
}
+VNA_SHELL_FUNCTION(cmd_x)
+{
+ uint32_t reg;
+
+
+ if (argc != 1) {
+ shell_printf("usage: x value(0-FFFFFFFF)\r\n");
+ return;
+ }
+ reg = xtoi(argv[0]);
+
+ if ((reg & 7) == 5) {
+ if (reg & (1<<22))
+ VFO = 1;
+ else
+ VFO = 0;
+ reg &= ~0xc00000; // Force led to show lock
+ reg |= 0x400000;
+ }
+#ifdef __ULTRA_SA__
+ ADF4351_WriteRegister32(VFO, reg);
+#endif
+ shell_printf("x=%x\r\n", reg);
+}
+
+
VNA_SHELL_FUNCTION(cmd_i)
{
int rvalue;
+return; // Don't use!!!!
SI4432_Init();
shell_printf("SI4432 init done\r\n");
if (argc == 1) {
@@ -2246,9 +2278,10 @@ VNA_SHELL_FUNCTION(cmd_i)
VNA_SHELL_FUNCTION(cmd_o)
{
(void) argc;
- int32_t value = my_atoi(argv[0]);
- if (VFO == 0)
- frequency_IF = value;
+ return;
+ uint32_t value = my_atoi(argv[0]);
+// if (VFO == 0)
+// frequency_IF = value;
setFreq(VFO, value);
}
@@ -2303,13 +2336,25 @@ VNA_SHELL_FUNCTION(cmd_m)
{
(void)argc;
(void)argv;
+
+ SetMode(0);
+ setting_tracking = false; //Default test setup
+ setting_step_atten = false;
+ SetAttenuation(0);
+ SetReflevel(-10);
+ set_sweep_frequency(ST_START,frequencyStart - frequency_IF );
+ set_sweep_frequency(ST_STOP, frequencyStop - frequency_IF);
+ draw_cal_status();
+
pause_sweep();
int32_t f_step = (frequencyStop-frequencyStart)/ points;
- palClearPad(GPIOB, GPIOB_LED); // disable led and wait for voltage stabilization
+ palClearPad(GPIOC, GPIOC_LED); // disable led and wait for voltage stabilization
+ int old_step = setting_frequency_step;
setting_frequency_step = f_step;
update_rbw();
chThdSleepMilliseconds(10);
streamPut(shell_stream, '{');
+ dirty = true;
for (int i = 0; i 0) {
+ sdPut(&SD1,*buf++);
+ osalThreadSleepMicroseconds(1000);
+ }
+}
+
+static int serial_count = 0;
+int mySerialReadline(unsigned char *buf, int len)
+{
+ int i;
+ do {
+ i = sdReadTimeout(&SD1,&buf[serial_count], 20-serial_count,TIME_IMMEDIATE);
+ serial_count += i;
+ if (i > 0)
+ osalThreadSleepMicroseconds(1000);
+ } while (serial_count < len && i > 0);
+ if (buf[serial_count-1] == '\n') {
+ serial_count = 0;
+ return(i);
+ } else
+ return 0;
+}
+#endif
// Main thread stack size defined in makefile USE_PROCESS_STACKSIZE = 0x200
// Profile stack usage (enable threads command by def ENABLE_THREADS_COMMAND) show:
@@ -2625,7 +2727,42 @@ int main(void)
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
-/*
+#if 0
+ /*
+ * UART initialize
+ */
+ uartStart(&UARTD1, &uart_cfg_1);
+
+ uartStartSend(&UARTD1, 1, "H");
+ uartStartReceive(&UARTD1, 1, buf);
+#endif
+
+#if 0
+ palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(1)); // USART1 TX.
+ palSetPadMode(GPIOA,10, PAL_MODE_ALTERNATE(1)); // USART1 RX.
+
+ uint8_t buf[10];
+ sdStart(&SD1,&default_config);
+ osalThreadSleepMilliseconds(10);
+ mySerialWrite("Hallo!?\n");
+
+ osalThreadSleepMilliseconds(10);
+
+ mySerialReadline(buf, 10);
+
+ sdReadTimeout(&SD1,buf,10, 10);
+
+ sdWrite(&SD1,(const uint8_t *)"Test123",7);
+ osalThreadSleepMicroseconds(10);
+ sdReadTimeout(&SD1,buf,10,TIME_IMMEDIATE);
+ sdReadTimeout(&SD1,buf,10, 10);
+ int i = sdReadTimeout(&SD1,buf,10,TIME_IMMEDIATE);
+
+#endif
+#ifdef __ULTRA_SA__
+ ADF4351_Setup();
+#endif
+ /*
* SPI LCD Initialize
*/
ili9341_init();
diff --git a/mcuconf.h b/mcuconf.h
index 6d4550a..e04096c 100644
--- a/mcuconf.h
+++ b/mcuconf.h
@@ -201,7 +201,7 @@
/*
* UART driver system settings.
*/
-#define STM32_UART_USE_USART1 TRUE
+#define STM32_UART_USE_USART1 FALSE
#define STM32_UART_USE_USART2 FALSE
#define STM32_UART_USART1_IRQ_PRIORITY 3
#define STM32_UART_USART2_IRQ_PRIORITY 3
diff --git a/nanovna.h b/nanovna.h
index 0c3ee99..6fbc161 100644
--- a/nanovna.h
+++ b/nanovna.h
@@ -29,6 +29,10 @@
#define __ICONS__
#define __MEASURE__
#define __SELFTEST__
+#define __CALIBRATE__
+//#define __ULTRA__ // Add harmonics mode on low input.
+//#define __ULTRA_SA__ // Adds ADF4351 control for extra high 1st IF stage
+
/*
* main.c
@@ -123,12 +127,12 @@ int shell_printf(const char *fmt, ...);
void toggle_sweep(void);
void load_default_properties(void);
-extern float perform(bool b, int i, int32_t f, int e);
+extern float perform(bool b, int i, uint32_t f, int e);
enum {
AV_OFF, AV_MIN, AV_MAX_HOLD, AV_MAX_DECAY, AV_4, AV_16
};
enum {
- M_LOW, M_HIGH, M_GENLOW, M_GENHIGH,
+ M_LOW, M_HIGH, M_GENLOW, M_GENHIGH, M_ULTRA
};
enum {
@@ -136,7 +140,11 @@ enum {
};
#define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH )
+#ifdef __ULTRA__
+#define MODE_INPUT(x) ((x) == M_LOW || (x) == M_HIGH || (x) == M_ULTRA )
+#else
#define MODE_INPUT(x) ((x) == M_LOW || (x) == M_HIGH )
+#endif
#define MODE_HIGH(x) ((x) == M_HIGH || (x) == M_GENHIGH )
#define MODE_LOW(x) ((x) == M_LOW || (x) == M_GENLOW )
#define MODE_SELECT(x) (MODE_HIGH(x) ? 1 : 0)
@@ -323,7 +331,7 @@ float groupdelay_from_array(int i, float array[POINTS_COUNT][2]);
#endif
// marker
enum {
- M_NORMAL=0,M_REFERENCE=1, M_DELTA=2, M_NOISE=4, M_TRACKING=8 // Tracking must be last.
+ M_NORMAL=0,M_REFERENCE=1, M_DELTA=2, M_NOISE=4, M_TRACKING=8, M_DELETE=16 // Tracking must be last.
};
enum {
@@ -574,7 +582,7 @@ typedef struct uistat {
int8_t digit; /* 0~5 */
int8_t digit_mode;
int8_t current_trace; /* 0..3 */
- int32_t value; // for editing at numeric input area
+ float value; // for editing at numeric input area
// uint32_t previous_value;
uint8_t lever_mode;
uint8_t marker_delta;
diff --git a/plot.c b/plot.c
index 0f246fe..893fe6a 100644
--- a/plot.c
+++ b/plot.c
@@ -1534,7 +1534,28 @@ draw_all_cells(bool flush_markmap)
g = 255 - b - r
return r, g, b
*/
+
int r,g,b;
+#if 0
+ int ratio = (int)(1024 * (actual_t[i] - w_min) / (w_max - w_min));
+
+ r = ratio - 512;
+ if (r<0) r=0;
+ b = (1024 - ratio*4) - 512;
+ if (b<0) b=0;
+ g = 512-r-b;
+ if (r>255) r=255;
+ if (g>255) g=255;
+ if (b>255) b=255;
+
+#define gamma_correct(X,L) X = (L + X * (255 - L)/255 )
+ gamma_correct(r,160);
+ gamma_correct(g,160);
+ gamma_correct(b,160);
+
+#endif
+
+#if 1
float ratio = (int)(510.0 * (actual_t[i] - w_min) / (w_max - w_min));
// float ratio = (i*2); // Uncomment for testing the waterfall colors
b = 255 - ratio;
@@ -1549,6 +1570,7 @@ draw_all_cells(bool flush_markmap)
gamma_correct(r,128);
gamma_correct(g,128);
gamma_correct(b,128);
+#endif
#if 0
int k = (actual_t[i]+120)* 2 * 8;
k &= 255;
diff --git a/sa_core.c b/sa_core.c
index 202e33a..f6d7efb 100644
--- a/sa_core.c
+++ b/sa_core.c
@@ -23,6 +23,7 @@ int setting_tracking = false;
int setting_modulation = MO_NONE;
int setting_step_delay = 0;
int setting_frequency_step;
+int setting_harmonic;
int setting_decay;
int setting_noise;
float actual_rbw = 0;
@@ -32,10 +33,11 @@ int setting_tracking_output;
int setting_measurement;
int vbwSteps = 1;
-
-//int setting_spur = 0;
-uint32_t minFreq = 0;
-uint32_t maxFreq = 520000000;
+#ifdef __ULTRA__
+int setting_spur = 0;
+#endif
+float minFreq = 0;
+float maxFreq = 520000000;
int setting_refer = -1; // Off by default
const int reffer_freq[] = {30000000, 15000000, 10000000, 4000000, 3000000, 2000000, 1000000};
@@ -50,6 +52,7 @@ void reset_settings(int m)
setting_attenuate = 0;
setting_rbw = 0;
setting_average = 0;
+ setting_harmonic = 0;
setting_show_stored = 0;
setting_auto_attenuation = true;
setting_subtract_stored = 0;
@@ -69,15 +72,31 @@ void reset_settings(int m)
trace[TRACE_TEMP].enabled = false;
setting_measurement = M_OFF;
-// setting_spur = 0;
+#ifdef __ULTRA__
+ setting_spur = 0;
+#endif
switch(m) {
case M_LOW:
minFreq = 0;
maxFreq = 520000000;
- set_sweep_frequency(ST_START, (int32_t) 0);
- set_sweep_frequency(ST_STOP, (int32_t) 350000000);
+ set_sweep_frequency(ST_START, (uint32_t) 0);
+ set_sweep_frequency(ST_STOP, (uint32_t) 350000000);
setting_attenuate = 30;
break;
+#ifdef __ULTRA__
+ case M_ULTRA:
+ minFreq = 870000000;
+ if (setting_harmonic * 240000000 > 870000000)
+ minFreq = setting_harmonic * 240000000;
+ if (setting_harmonic == 0)
+ maxFreq = 4360000000;
+ else
+ maxFreq = 960000000 * setting_harmonic;
+ set_sweep_frequency(ST_START, (uint32_t) minFreq);
+ set_sweep_frequency(ST_STOP, (uint32_t) maxFreq);
+ setting_attenuate = 0;
+ break;
+#endif
case M_GENLOW:
setting_drive=8;
minFreq = 0;
@@ -86,8 +105,13 @@ void reset_settings(int m)
set_sweep_frequency(ST_SPAN, 0);
break;
case M_HIGH:
+#ifdef __ULTRA_SA__
+ minFreq = 00000000;
+ maxFreq = 2000000000;
+#else
minFreq = 240000000;
maxFreq = 960000000;
+#endif
set_sweep_frequency(ST_START, (int32_t) minFreq);
set_sweep_frequency(ST_STOP, (int32_t) maxFreq);
break;
@@ -290,6 +314,10 @@ void SetPowerLevel(int o)
config.high_level_offset = new_offset;
else if (setting_mode == M_LOW)
config.low_level_offset = new_offset;
+#ifdef __ULTRA__
+ else if (setting_mode == M_ULTRA)
+ config.low_level_offset = new_offset;
+#endif
}
else {
config.low_level_offset = 100;
@@ -338,14 +366,30 @@ int GetActualRBW(void)
{
return((int) actual_rbw);
}
-#if 0
+
+#ifdef __ULTRA__
void SetSpur(int v)
{
-// setting_spur = v;
+ setting_spur = v;
+ if (setting_spur && actual_rbw > 360)
+ SetRBW(300);
dirty = true;
}
#endif
+void set_harmonic(int h)
+{
+ setting_harmonic = h;
+ minFreq = 870000000;
+ if (setting_harmonic * 240000000 > 870000000)
+ minFreq = setting_harmonic * 240000000;
+ maxFreq = 4360000000;
+ if (setting_harmonic != 0 && 960000000.0 * setting_harmonic < 4360000000.0)
+ maxFreq = ((uint32_t)960000000) * (uint32_t)setting_harmonic;
+ set_sweep_frequency(ST_START, (uint32_t) minFreq);
+ set_sweep_frequency(ST_STOP, (uint32_t) maxFreq);
+}
+
void SetStepDelay(int d)
{
setting_step_delay = d;
@@ -422,6 +466,10 @@ void SetScale(int s) {
//}
void SetMode(int m)
{
+#ifdef __ULTRA__
+ if (m == 6)
+ m = M_ULTRA;
+#endif
if (setting_mode == m)
return;
reset_settings(m);
@@ -429,17 +477,6 @@ void SetMode(int m)
void apply_settings(void)
{
- if (setting_step_delay == 0){
- if (actual_rbw >142.0) actualStepDelay = 450;
- else if (actual_rbw > 75.0) actualStepDelay = 550;
- else if (actual_rbw > 56.0) actualStepDelay = 650;
- else if (actual_rbw > 37.0) actualStepDelay = 800;
- else if (actual_rbw > 18.0) actualStepDelay = 1100;
- else if (actual_rbw > 9.0) actualStepDelay = 2000;
- else if (actual_rbw > 5.0) actualStepDelay = 3500;
- else actualStepDelay = 6000;
- } else
- actualStepDelay = setting_step_delay;
PE4302_Write_Byte(setting_attenuate * 2);
#if 0
if (setting_modulation == MO_NFM ) {
@@ -456,6 +493,17 @@ void apply_settings(void)
SetRX(setting_mode);
SI4432_SetReference(setting_refer);
update_rbw();
+ if (setting_step_delay == 0){
+ if (actual_rbw >142.0) actualStepDelay = 450;
+ else if (actual_rbw > 75.0) actualStepDelay = 550;
+ else if (actual_rbw > 56.0) actualStepDelay = 650;
+ else if (actual_rbw > 37.0) actualStepDelay = 800;
+ else if (actual_rbw > 18.0) actualStepDelay = 1100;
+ else if (actual_rbw > 9.0) actualStepDelay = 2000;
+ else if (actual_rbw > 5.0) actualStepDelay = 3500;
+ else actualStepDelay = 6000;
+ } else
+ actualStepDelay = setting_step_delay;
}
//------------------------------------------
@@ -475,17 +523,19 @@ void setupSA(void)
PE4302_Write_Byte(0);
}
-static unsigned long old_freq[2] = { 0, 0 };
+static unsigned long old_freq[4] = { 0, 0, 0, 0 };
void setFreq(int V, unsigned long freq)
{
- SI4432_Sel = V;
if (old_freq[V] != freq) {
- if (V == 0) {
- V = -V;
- V = -V;
+ if (V <= 1) {
+ SI4432_Sel = V;
+ SI4432_Set_Frequency(freq);
+#ifdef __ULTRA_SA__
+ } else {
+ ADF4351_set_frequency(V-2,freq,3);
+#endif
}
- SI4432_Set_Frequency(freq);
old_freq[V] = freq;
}
}
@@ -511,9 +561,16 @@ void SetRX(int m)
{
switch(m) {
case M_LOW: // Mixed into 0
+#ifdef __ULTRA__
+case M_ULTRA:
+#endif
SI4432_Sel = 0;
SI4432_Receive();
- SetSwitchReceive();
+ if (setting_step_atten) {
+ SetSwitchTransmit();
+ } else {
+ SetSwitchReceive();
+ }
SetAGCLNA();
SI4432_Sel = 1;
@@ -817,9 +874,8 @@ static int modulation_counter = 0;
char age[POINTS_COUNT];
-float perform(bool break_on_operation, int i, int32_t f, int tracking)
+float perform(bool break_on_operation, int i, uint32_t f, int tracking)
{
- // long local_IF = (MODE_LOW(setting_mode)?frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw :0):0);
long local_IF;
if (MODE_HIGH(setting_mode))
local_IF = 0;
@@ -861,8 +917,14 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
float RSSI = -150.0;
int t = 0;
do {
- int lf = (uint32_t)(f + (int)((t * 500 - vbwSteps * 250) * actual_rbw));
- if (lf < 0) lf = 0;
+ int offs = (int)((t * 500 - vbwSteps * 250) * actual_rbw);
+// if (-offs > (uint32_t)f) // Ensure lf >0 0
+// offs = -(uint32_t)(f + offs);
+ uint32_t lf = (uint32_t)(f + offs);
+#ifdef __ULTRA__
+ float spur_RSSI = 0;
+again:
+#endif
if (setting_mode == M_LOW && tracking) {
setFreq (0, frequency_IF + lf - reffer_freq[setting_refer]); // Offset so fundamental of reffer is visible
local_IF = frequency_IF ;
@@ -870,11 +932,17 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
if (setting_mode == M_LOW && !in_selftest && avoid_spur(f)) {
local_IF = spur_alternate_IF;
} else {
- local_IF = frequency_IF ;
+// local_IF = frequency_IF ;
}
if (setting_mode == M_GENLOW && setting_modulation == MO_EXTERNAL)
local_IF += lf;
setFreq (0, local_IF);
+#ifdef __ULTRA__
+ } else if (setting_mode == M_ULTRA) {
+ local_IF = frequency_IF + (int)(actual_rbw < 350.0 ? setting_spur*300000 : 0 );
+ setFreq (0, local_IF);
+ // local_IF = frequency_IF + (int)(actual_rbw < 300.0?setting_spur * 1000 * actual_rbw:0);
+#endif
} else
local_IF= 0;
#if 0
@@ -883,15 +951,56 @@ float perform(bool break_on_operation, int i, int32_t f, int tracking)
break;
}
#endif
- setFreq (1, local_IF + lf);
+#ifdef __ULTRA__
+ if (setting_mode == M_ULTRA) {
+// if (lf > 3406000000 )
+// setFreq (1, local_IF/5 + lf/5);
+// else
+ if (lf > 2446000000 )
+ setFreq (1, local_IF/5 + lf/5);
+ else
+// if (lf > 1486000000)
+ setFreq (1, local_IF/3 + lf/3);
+// else
+// setFreq (1, local_IF/2 + lf/2);
+ } else
+#endif
+ {
+#ifdef __ULTRA_SA__
+//#define IF_1 2550000000
+#define IF_2 2025000000
+
+ setFreq (3, IF_2 - 433800000);
+ setFreq (2, IF_2 + lf);
+ setFreq (1, 433800000);
+#else
+ setFreq (1, local_IF+lf);
+#endif
+ }
if (MODE_OUTPUT(setting_mode)) // No substepping in output mode
return(0);
float signal_path_loss;
- if (setting_mode == M_LOW)
- signal_path_loss = -9.5; // Loss in dB
+#ifdef __ULTRA__
+ if (setting_mode == M_ULTRA)
+ signal_path_loss = -15; // Loss in dB, -9.5 for v0.1, -12.5 for v0.2
else
+#endif
+ if (setting_mode == M_LOW)
+ signal_path_loss = -9.5; // Loss in dB, -9.5 for v0.1, -12.5 for v0.2
+ else
signal_path_loss = 7; // Loss in dB (+ is gain)
float subRSSI = SI4432_RSSI(lf, MODE_SELECT(setting_mode))+settingLevelOffset()+ setting_attenuate - signal_path_loss;
+#ifdef __ULTRA__
+ if (setting_spur == 1) { // First pass
+ spur_RSSI = subRSSI;
+ setting_spur = -1;
+ goto again; // Skip all other processing
+ } else if (setting_spur == -1) { // Second pass
+ subRSSI = ( subRSSI < spur_RSSI ? subRSSI : spur_RSSI); // Minimum of two passes
+ setting_spur = 1;
+ }
+#endif
+
if (RSSI < subRSSI)
RSSI = subRSSI;
t++;
@@ -914,7 +1023,6 @@ static bool sweep(bool break_on_operation)
temppeakLevel = -150;
float temp_min_level = 100;
// spur_old_stepdelay = 0;
- //again:
for (int i = 0; i < sweep_points; i++) {
RSSI = perform(break_on_operation, i, frequencies[i], setting_tracking);
@@ -926,12 +1034,7 @@ static bool sweep(bool break_on_operation)
}
if (MODE_INPUT(setting_mode)) {
- // if (setting_spur == 1) { // First pass
- // temp_t[i] = RSSI;
- // continue; // Skip all other processing
- // }
- // if (setting_spur == -1) // Second pass
- // RSSI = ( RSSI < temp_t[i] ? RSSI : temp_t[i]); // Minimum of two passes
+
temp_t[i] = RSSI;
if (setting_subtract_stored) {
RSSI = RSSI - stored_t[i] ;
@@ -1019,12 +1122,6 @@ static bool sweep(bool break_on_operation)
temp_min_level = actual_t[i];
}
- // if (setting_spur == 1) {
- // setting_spur = -1;
- // goto again;
- // } else if (setting_spur == -1)
- // setting_spur = 1;
-
if (scandirty) {
scandirty = false;
draw_cal_status();
@@ -1331,7 +1428,7 @@ void draw_cal_status(void)
buf[5]=0;
ili9341_drawstring(buf, x, y);
}
-#if 0
+#ifdef __ULTRA__
if (setting_spur) {
ili9341_set_foreground(BRIGHT_COLOR_BLUE);
y += YSTEP*2;
@@ -1379,7 +1476,11 @@ void draw_cal_status(void)
ili9341_drawstring("Scan:", x, y);
y += YSTEP;
- int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10 /* * (setting_spur ? 2 : 1) */; // in mS
+ int32_t t = (int)((2* vbwSteps * sweep_points * ( actualStepDelay / 100) )) /10
+#ifdef __ULTRA__
+ * (setting_spur ? 2 : 1)
+#endif
+ ; // in mS
if (t>1000)
plot_printf(buf, BLEN, "%dS",(t+500)/1000);
else
@@ -1424,17 +1525,16 @@ void draw_cal_status(void)
}
// -------------------- Self testing -------------------------------------------------
-#ifdef __SELFTEST__
enum {
TC_SIGNAL, TC_BELOW, TC_ABOVE, TC_FLAT, TC_MEASURE, TC_SET, TC_END,
};
enum {
- TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_30MHZ, TPH_30MHZ
+ TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_10MHZ_SWITCH, TP_30MHZ, TPH_30MHZ
};
-#define TEST_COUNT 16
+#define TEST_COUNT 17
static const struct {
int kind;
@@ -1455,12 +1555,13 @@ static const struct {
{TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -13, 55, -60 }, // 7 BPF loss and stop band
{TC_FLAT, TP_10MHZEXTRA, 10, 4, -18, 20, -60}, // 8 BPF pass band flatness
{TC_BELOW, TP_30MHZ, 430, 60, -65, 0, -75}, // 9 LPF cutoff
+ {TC_SIGNAL, TP_10MHZ_SWITCH,20, 7, -58, 30, -90 }, // 10 Switch isolation
{TC_END, 0, 0, 0, 0, 0, 0},
- {TC_MEASURE, TP_30MHZ, 30, 7, -22.5, 30, -70 }, // 11 Measure power level and noise
- {TC_MEASURE, TP_30MHZ, 270, 4, -45, 30, -75 }, // 12 Measure powerlevel and noise
- {TC_MEASURE, TPH_30MHZ, 270, 4, -45, 30, -75 }, // 13 Calibrate power high mode
+ {TC_MEASURE, TP_30MHZ, 30, 7, -22.5, 30, -70 }, // 12 Measure power level and noise
+ {TC_MEASURE, TP_30MHZ, 270, 4, -45, 30, -75 }, // 13 Measure powerlevel and noise
+ {TC_MEASURE, TPH_30MHZ, 270, 4, -45, 30, -65 }, // 14 Calibrate power high mode
{TC_END, 0, 0, 0, 0, 0, 0},
- {TC_MEASURE, TP_30MHZ, 30, 1, -20, 30, -70 }, // 15 Measure RBW step time
+ {TC_MEASURE, TP_30MHZ, 30, 1, -20, 30, -70 }, // 16 Measure RBW step time
{TC_END, 0, 0, 0, 0, 0, 0},
};
@@ -1539,20 +1640,29 @@ void cell_draw_test_info(int x0, int y0)
#define fabs(X) ((X)<0?-(X):(X))
-int validate_peak_within(int i, float margin)
+int validate_signal_within(int i, float margin)
{
- if (fabs(peakLevel-test_case[i].pass) > margin)
- return false;
- return(test_case[i].center * 1000000 - 100000 < peakFreq && peakFreq < test_case[i].center * 1000000 + 100000 );
+ test_fail_cause[i] = "Signal level ";
+ if (fabs(peakLevel-test_case[i].pass) > 2*margin) {
+ return TS_FAIL;
+ }
+ if (fabs(peakLevel-test_case[i].pass) > margin) {
+ return TS_CRITICAL;
+ }
+ test_fail_cause[i] = "Frequency ";
+ if (peakFreq < test_case[i].center * 1000000 - 100000 || test_case[i].center * 1000000 + 100000 < peakFreq )
+ return TS_FAIL;
+ test_fail_cause[i] = "";
+ return TS_PASS;
}
int validate_peak_below(int i, float margin) {
return(test_case[i].pass - peakLevel > margin);
}
-int validate_below(void) {
+int validate_below(int tc, int from, int to) {
int status = TS_PASS;
- for (int j = 0; j < POINTS_COUNT; j++) {
+ for (int j = from; j < to; j++) {
if (actual_t[j] > stored_t[j] - 5)
status = TS_CRITICAL;
else if (actual_t[j] > stored_t[j]) {
@@ -1560,11 +1670,14 @@ int validate_below(void) {
break;
}
}
+ if (status != TS_PASS)
+ test_fail_cause[tc] = "Above ";
return(status);
}
int validate_flatness(int i) {
volatile int j;
+ test_fail_cause[i] = "Passband ";
for (j = peakIndex; j < POINTS_COUNT; j++) {
if (actual_t[j] < peakLevel - 3) // Search right -3dB
break;
@@ -1577,10 +1690,11 @@ int validate_flatness(int i) {
}
if (peakIndex - j < test_case[i].width)
return(TS_FAIL);
+ test_fail_cause[i] = "";
return(TS_PASS);
}
-int validate_above(void) {
+int validate_above(int tc) {
int status = TS_PASS;
for (int j = 0; j < POINTS_COUNT; j++) {
if (actual_t[j] < stored_t[j] + 5)
@@ -1590,6 +1704,8 @@ int validate_above(void) {
break;
}
}
+ if (status != TS_PASS)
+ test_fail_cause[tc] = "Below ";
return(status);
}
@@ -1607,32 +1723,12 @@ int test_validate(int i)
SetPowerLevel(test_case[i].pass);
goto common;
case TC_MEASURE:
- case TC_SIGNAL: // Validate signal
- common:
- if (validate_peak_within(i, 5.0)) // Validate Peak
- current_test_status = TS_PASS;
- else if (validate_peak_within(i, 10.0))
- current_test_status = TS_CRITICAL;
- else
- current_test_status = TS_FAIL;
- if (current_test_status != TS_PASS)
- test_fail_cause[i] = "Peak ";
+ case TC_SIGNAL: // Validate signal
+ common: current_test_status = validate_signal_within(i, 5.0);
if (current_test_status == TS_PASS) { // Validate noise floor
- for (int j = 0; j < POINTS_COUNT/2 - test_case[i].width; j++) {
- if (actual_t[j] > test_case[i].stop - 5)
- current_test_status = TS_CRITICAL;
- else if (actual_t[j] > test_case[i].stop) {
- current_test_status = TS_FAIL;
- break;
- }
- }
- for (int j = POINTS_COUNT/2 + test_case[i].width; j < POINTS_COUNT; j++) {
- if (actual_t[j] > test_case[i].stop - 5)
- current_test_status = TS_CRITICAL;
- else if (actual_t[j] > test_case[i].stop) {
- current_test_status = TS_FAIL;
- break;
- }
+ current_test_status = validate_below(i, 0, POINTS_COUNT/2 - test_case[i].width);
+ if (current_test_status == TS_PASS) {
+ current_test_status = validate_below(i, POINTS_COUNT/2 + test_case[i].width, POINTS_COUNT);
}
if (current_test_status != TS_PASS)
test_fail_cause[i] = "Stopband ";
@@ -1641,28 +1737,15 @@ int test_validate(int i)
test_value = peakLevel;
else
test_value = 0; // Not valid
- break;
+ break;
case TC_ABOVE: // Validate signal above curve
- for (int j = 0; j < POINTS_COUNT; j++) {
- if (actual_t[j] < test_case[i].pass + 5)
- current_test_status = TS_CRITICAL;
- else if (actual_t[j] < test_case[i].pass) {
- current_test_status = TS_FAIL;
- break;
- }
- }
- if (current_test_status != TS_PASS)
- test_fail_cause[i] = "Above ";
+ current_test_status = validate_above(i);
break;
case TC_BELOW: // Validate signal below curve
- current_test_status = validate_below();
- if (current_test_status != TS_PASS)
- test_fail_cause[i] = "Above ";
- break;
+ current_test_status = validate_below(i, 0, POINTS_COUNT);
+ break;
case TC_FLAT: // Validate passband flatness
current_test_status = validate_flatness(i);
- if (current_test_status != TS_PASS)
- test_fail_cause[i] = "Passband ";
break;
}
@@ -1682,6 +1765,8 @@ int test_validate(int i)
void test_prepare(int i)
{
setting_tracking = false; //Default test setup
+ setting_step_atten = false;
+ SetAttenuation(0);
switch(test_case[i].setup) { // Prepare test conditions
case TPH_SILENT: // No input signal
SetMode(M_HIGH);
@@ -1693,9 +1778,15 @@ common_silent:
for (int j = 0; j < POINTS_COUNT; j++)
stored_t[j] = test_case[i].pass;
break;
+ case TP_10MHZ_SWITCH:
+ SetMode(M_LOW);
+ set_refer_output(2);
+ setting_step_atten = true;
+ goto common;
case TP_10MHZEXTRA: // Swept receiver
SetMode(M_LOW);
setting_tracking = true; //Sweep BPF
+ frequency_IF = 434000000; // Center on SAW filters
set_refer_output(2);
goto common;
case TP_10MHZ: // 10MHz input
@@ -1719,11 +1810,12 @@ common_silent:
set_refer_output(0);
goto common;
}
+ setting_auto_attenuation = false;
+ setting_attenuate = 0;
trace[TRACE_STORED].enabled = true;
SetReflevel(test_case[i].pass+10);
set_sweep_frequency(ST_CENTER, (int32_t)(test_case[i].center * 1000000));
set_sweep_frequency(ST_SPAN, (int32_t)(test_case[i].span * 1000000));
- SetAttenuation(0);
draw_cal_status();
}
@@ -1745,11 +1837,10 @@ int add_spur(int f)
}
return 1;
}
-#endif
+
void self_test(void)
{
-#ifdef __SELFTEST__
#if 0
in_selftest = true;
@@ -1800,7 +1891,7 @@ void self_test(void)
int local_test_status;
in_selftest = true;
reset_settings(M_LOW);
- int i = 14; // calibrate low mode power on 30 MHz;
+ int i = 15; // calibrate low mode power on 30 MHz;
test_prepare(i);
for (int j= 0; j < 32; j++ ) {
test_prepare(i);
@@ -1815,7 +1906,7 @@ void self_test(void)
int local_test_status;
in_selftest = true;
reset_settings(M_LOW);
- int i = 14; // calibrate low mode power on 30 MHz;
+ int i = 15; // calibrate low mode power on 30 MHz;
test_prepare(i);
setting_step_delay = 6000;
for (int j= 0; j < 57; j++ ) {
@@ -1845,7 +1936,7 @@ void self_test(void)
}
return;
#else
-
+ int old_IF = frequency_IF;
in_selftest = true;
menu_autosettings_cb(0);
for (int i=0; i < TEST_COUNT; i++) { // All test cases waiting
@@ -1857,6 +1948,7 @@ void self_test(void)
show_test_info = TRUE;
int i=0;
while (test_case[i].kind != TC_END) {
+ frequency_IF = old_IF;
test_prepare(i);
test_acquire(i); // Acquire test
test_status[i] = test_validate(i); // Validate test
@@ -1877,8 +1969,6 @@ void self_test(void)
reset_settings(M_LOW);
in_selftest = false;
#endif
-
-#endif
}
void reset_calibration(void)
@@ -1897,7 +1987,7 @@ void calibrate(void)
in_selftest = true;
SetPowerLevel(100);
reset_settings(M_LOW);
- int i = 10; // calibrate low mode power on 30 MHz;
+ int i = 11; // calibrate low mode power on 30 MHz;
for (int j= 0; j < CALIBRATE_RBWS; j++ ) {
SetRBW(power_rbw[j]);
test_prepare(i);
@@ -1913,7 +2003,7 @@ void calibrate(void)
chThdSleepMilliseconds(1000);
}
}
- i = 11; // Measure 270MHz in low mode
+ i = 12; // Measure 270MHz in low mode
SetRBW(100);
test_prepare(i);
test_acquire(i); // Acquire test
@@ -1923,7 +2013,7 @@ void calibrate(void)
config.high_level_offset = 0; /// Preliminary setting
- i = 12; // Calibrate 270MHz in high mode
+ i = 13; // Calibrate 270MHz in high mode
for (int j = 0; j < CALIBRATE_RBWS; j++) {
SetRBW(power_rbw[j]);
test_prepare(i);
@@ -1947,7 +2037,7 @@ quit:
in_selftest = false;
sweep_mode = SWEEP_ENABLE;
set_refer_output(0);
- reset_settings(M_LOW);
+ SetMode(M_LOW);
#endif
}
diff --git a/si4432.c b/si4432.c
index 0a8a1eb..462d1d2 100644
--- a/si4432.c
+++ b/si4432.c
@@ -19,7 +19,7 @@
#include "ch.h"
#include "hal.h"
#include "nanovna.h"
-
+#include
#include "si4432.h"
#define CS_SI0_HIGH palSetPad(GPIOC, GPIO_RX_SEL)
@@ -508,4 +508,365 @@ float Simulated_SI4432_RSSI(uint32_t i, int s)
return(v);
}
+#endif
+//------------------------------- ADF4351 -------------------------------------
+
+#ifdef __ULTRA_SA__
+
+#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
+#define bitSet(value, bit) ((value) |= (1UL << (bit)))
+#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
+#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
+
+#define CS_ADF0_HIGH palSetPad(GPIOA, 9)
+#define CS_ADF1_HIGH palSetPad(GPIOA, 10)
+
+#define CS_ADF0_LOW palClearPad(GPIOA, 9)
+#define CS_ADF1_LOW palClearPad(GPIOA, 10)
+
+#define SPI3_CLK_HIGH palSetPad(GPIOA, 1)
+#define SPI3_CLK_LOW palClearPad(GPIOA, 1)
+
+#define SPI3_SDI_HIGH palSetPad(GPIOA, 2)
+#define SPI3_SDI_LOW palClearPad(GPIOA, 2)
+
+
+void ADF_shiftOut(uint8_t val)
+{
+ uint8_t i;
+ for (i = 0; i < 8; i++) {
+ if (val & (1 << (7 - i)))
+ SPI3_SDI_HIGH;
+ else
+ SPI3_SDI_LOW;
+// chThdSleepMicroseconds(10);
+ SPI3_CLK_HIGH;
+// chThdSleepMicroseconds(10);
+ SPI3_CLK_LOW;
+// chThdSleepMicroseconds(10);
+ }
+}
+
+//unsigned long registers[6] = {0x4580A8, 0x80080C9, 0x4E42, 0x4B3, 0xBC803C, 0x580005} ;
+//unsigned long registers[6] = {0x4C82C8, 0x80083E9, 0x6E42, 0x8004B3, 0x8C81FC, 0x580005} ;
+
+//uint32_t registers[6] = {0x320000, 0x8008011, 0x4E42, 0x4B3,0x8C803C , 0x580005} ; //25 MHz ref
+
+uint32_t registers[6] = {0xA00000, 0x8000011, 0x4E42, 0x4B3,0xDC003C , 0x580005} ; //10 MHz ref
+
+int debug = 0;
+int ADF4351_LE[2] = { 9, 10};
+int ADF4351_Mux = 7;
+
+
+//#define DEBUG(X) // Serial.print( X )
+//#define DEBUGLN(X) Serial.println( X )
+//#define DEBUGFLN(X,Y) Serial.println( X,Y )
+//#define DEBUGF(X,Y) Serial.print( X,Y )
+#define DEBUG(X)
+#define DEBUGLN(X)
+
+
+double RFout, //Output freq in MHz
+#if 0 //Black modules
+ PFDRFout[6] = {25.0,25.0,25.0,10.0,10.0,10.0}, //Reference freq in MHz
+ Chrystal[6] = {25.0,25.0,25.0,10.0,10.0,10.0},
+#else // Green modules
+ PFDRFout[6] = {10.0,10.0,10.0,10.0,10.0,10.0}, //Reference freq in MHz
+ Chrystal[6] = {10.0,10.0,10.0,10.0,10.0,10.0},
+#endif
+
+ OutputChannelSpacing = 0.010, // = 0.01
+ FRACF; // Temp
+
+unsigned int long RFint, // Output freq/10Hz
+ INTA, // Temp
+ RFcalc, //UI
+ MOD, //Temp
+ FRAC; //Temp
+
+byte OutputDivider; // Temp
+byte lock=2; //Not used
+
+// Lock = A4
+
+void ADF4351_Setup()
+{
+// palSetPadMode(GPIOA, 1, PAL_MODE_OUTPUT_PUSHPULL );
+// palSetPadMode(GPIOA, 2, PAL_MODE_OUTPUT_PUSHPULL );
+
+ SPI3_CLK_HIGH;
+ SPI3_SDI_HIGH;
+ CS_ADF0_HIGH;
+ CS_ADF1_HIGH;
+// bitSet (registers[2], 17); // R set to 8
+// bitClear (registers[2], 14); // R set to 8
+
+// while(1) {
+//
+ ADF4351_set_frequency(0,100000000,0);
+ ADF4351_set_frequency(1,150000000,0);
+// ADF4351_Set(0);
+// ADF4351_Set(1);
+// chThdSleepMilliseconds(1000);
+// }
+// bitSet (registers[2], 17); // R set to 8
+// bitClear (registers[2], 14); // R set to 8
+// for (int i=0; i<6; i++) pinMode(ADF4351_LE[i], OUTPUT); // Setup pins
+// for (int i=0; i<6; i++) digitalWrite(ADF4351_LE[i], HIGH);
+// pinMode(ADF4351_Mux, INPUT);
+// SPI.begin(); // Init SPI bus
+// SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
+ //SPI.setDataMode(SPI_MODE0); // CPHA = 0 Clock positive
+ //SPI.setBitOrder(MSBFIRST);
+}
+
+void ADF4351_WriteRegister32(int channel, const uint32_t value)
+{
+ palClearPad(GPIOA, ADF4351_LE[channel]);
+// chThdSleepMicroseconds(10);
+ for (int i = 3; i >= 0; i--) ADF_shiftOut((value >> (8 * i)) & 0xFF);
+// chThdSleepMicroseconds(10);
+ palSetPad(GPIOA, ADF4351_LE[channel]);
+// chThdSleepMicroseconds(10);
+ palClearPad(GPIOA, ADF4351_LE[channel]);
+// chThdSleepMicroseconds(10);
+}
+
+void ADF4351_disable_output()
+{
+ bitClear (registers[4], 5); // digital lock
+ ADF4351_Set(0);
+}
+
+void ADF4351_enable_output()
+{
+ bitSet (registers[4], 5); // digital lock
+ ADF4351_Set(0);
+}
+void ADF4351_Set(int channel)
+{ for (int i = 5; i >= 0; i--) {
+ ADF4351_WriteRegister32(channel, registers[i]);
+// if (debug) Serial.println(registers[i],HEX);
+}
+}
+
+void ADF4351_set_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz
+{
+ ADF4351_prep_frequency(channel,freq, drive);
+ ADF4351_Set(channel);
+}
+
+void ADF4351_spur_mode(int S)
+{
+ if (S & 1) {
+ bitSet (registers[2], 29); // R set to 8
+ } else {
+ bitClear (registers[2], 29); // R set to 8
+ }
+ if (S & 2)
+ bitSet (registers[2], 30); // R set to 8
+ else
+ bitClear (registers[2], 30); // R set to 8
+}
+
+void ADF4351_R_counter(int R)
+{
+ int dbl = false;
+ if (R < 0) {
+ dbl = true;
+ R = -R;
+ }
+ if (R<1)
+ return;
+ if (dbl) {
+ bitSet (registers[2], 25); // Reference doubler
+ } else {
+ bitClear (registers[2], 25); // Reference doubler
+ }
+ for (int channel=0; channel < 6; channel++) {
+ PFDRFout[channel] = Chrystal[channel] * (dbl?2:1) / R;
+ }
+ registers[2] &= ~ (((unsigned long)0x3FF) << 14);
+ registers[2] |= (((unsigned long)R) << 14);
+}
+
+void ADF4351_CP(int p)
+{
+ registers[2] &= ~ (((unsigned long)0xF) << 9);
+ registers[2] |= (((unsigned long)p) << 9);
+}
+
+void ADF4351_level(int p)
+{
+ registers[4] &= ~ (((unsigned long)0x3) << 3);
+ registers[4] |= (((unsigned long)p) << 3);
+}
+
+void ADF4351_channel_spacing(int spacing)
+{
+ OutputChannelSpacing = 0.001 * spacing;
+}
+
+static uint32_t gcd(uint32_t x, uint32_t y)
+{
+ uint32_t z;
+ while (y != 0) {
+ z = x % y;
+ x = y;
+ y = z;
+ }
+ return x;
+}
+
+void ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz
+{
+ (void)drive;
+// if (channel == 0)
+ RFout=freq/1000000.0; // To MHz
+// else
+ // RFout=freq/1000002.764; // To MHz
+
+ if (RFout >= 2200) {
+ OutputDivider = 1;
+ bitWrite (registers[4], 22, 0);
+ bitWrite (registers[4], 21, 0);
+ bitWrite (registers[4], 20, 0);
+ } else if (RFout >= 1100) {
+ OutputDivider = 2;
+ bitWrite (registers[4], 22, 0);
+ bitWrite (registers[4], 21, 0);
+ bitWrite (registers[4], 20, 1);
+ } else if (RFout >= 550) {
+ OutputDivider = 4;
+ bitWrite (registers[4], 22, 0);
+ bitWrite (registers[4], 21, 1);
+ bitWrite (registers[4], 20, 0);
+ } else if (RFout >= 275) {
+ OutputDivider = 8;
+ bitWrite (registers[4], 22, 0);
+ bitWrite (registers[4], 21, 1);
+ bitWrite (registers[4], 20, 1);
+ } else if (RFout >= 137.5) {
+ OutputDivider = 16;
+ bitWrite (registers[4], 22, 1);
+ bitWrite (registers[4], 21, 0);
+ bitWrite (registers[4], 20, 0);
+ } else if (RFout >= 68.75) {
+ OutputDivider = 32;
+ bitWrite (registers[4], 22, 1);
+ bitWrite (registers[4], 21, 0);
+ bitWrite (registers[4], 20, 1);
+ } else {
+ OutputDivider = 64;
+ bitWrite (registers[4], 22, 1);
+ bitWrite (registers[4], 21, 1);
+ bitWrite (registers[4], 20, 0);
+ }
+
+ INTA = (RFout * OutputDivider) / PFDRFout[channel];
+ MOD = (PFDRFout[channel] / OutputChannelSpacing) + 0.01;
+// MOD = 3125;
+ FRACF = (((RFout * OutputDivider) / PFDRFout[channel]) - INTA) * MOD;
+ FRAC = round(FRACF);
+
+ while (FRAC > 4095 || MOD > 4095) {
+ FRAC = FRAC >> 1;
+ MOD = MOD >> 1;
+ // Serial.println( "MOD/FRAC reduced");
+ }
+
+ int32_t k = gcd(FRAC, MOD);
+ if (k > 1) {
+ FRAC /= k;
+ MOD /= k;
+// Serial.print( "MOD/FRAC gcd reduced");
+ }
+// while (denom >= (1<<20)) {
+// num >>= 1;
+// denom >>= 1;
+// }
+
+
+// if (INTA <= 75) Serial.println( "INTA <= 75");
+// if (FRAC > 4095) Serial.println( "FRAC > 4095");
+// if (MOD > 4095) Serial.println( "MOD > 4095");
+
+
+// if (FRAC > 4095) Serial.println( "FRAC > 4095");
+// if (MOD > 4095) Serial.println( "MOD > 4095");
+// if (INTA > 4095) Serial.println( "INT > 4095");
+
+ if (debug) {
+ DEBUG(" ODIV=");
+ DEBUG(OutputDivider);
+ DEBUG(" INT=");
+ DEBUG(INTA);
+ DEBUG(" FRAC=");
+ DEBUG(FRAC);
+ DEBUG(" MOD=");
+ DEBUG(MOD);
+ DEBUG( " CalF=");
+// DEBUGFLN(PFDRFout[channel] *(INTA + ((double)FRAC)/MOD)/OutputDivider,6);
+
+// DEBUG(" FRACF=");
+// DEBUGF(FRACF,6);
+ }
+ registers[0] = 0;
+ registers[0] = INTA << 15; // OK
+ FRAC = FRAC << 3;
+ registers[0] = registers[0] + FRAC;
+ if (MOD == 1) MOD = 2;
+ registers[1] = 0;
+ registers[1] = MOD << 3;
+ registers[1] = registers[1] + 1 ; // restore address "001"
+ bitSet (registers[1], 27); // Prescaler at 8/9
+/*
+ drive = 1;
+ if (drive == 0) {
+ bitClear (registers[4], 3); // +5dBm + out
+ bitClear (registers[4], 4); // +5dBm
+ bitClear (registers[4], 6); // +5dBm - out
+ bitClear (registers[4], 7); // +5dBm
+ } else if (drive == 1) {
+ bitSet (registers[4], 6); // +5dBm
+ bitClear (registers[4], 7); // +5dBm - out
+ bitSet (registers[4], 3); // +5dBm
+ bitClear (registers[4], 4); // +5dBm + out
+ } else if (drive == 2) {
+ bitClear (registers[4], 6); // +5dBm - out
+ bitSet (registers[4], 7); // +5dBm
+ bitClear (registers[4], 3); // +5dBm + out
+ bitSet (registers[4], 4); // +5dBm
+ }
+ else {
+ bitSet (registers[4], 6); // +5dBm - out
+ bitSet (registers[4], 7); // +5dBm
+ bitSet (registers[4], 3); // +5dBm + out
+ bitSet (registers[4], 4); // +5dBm
+ }
+*/
+// bitSet (registers[4], 5); // enable + output
+// bitClear (registers[4], 8); // enable B output
+
+#if 0
+ if (FRAC == 0)
+ bitSet (registers[2], 8); // INT mode
+ else
+ bitClear (registers[2], 8); // INT mode
+ bitSet (registers[2], 13); // Double buffered
+
+ bitSet (registers[2], 28); // Digital lock == "110" sur b28 b27 b26
+ bitSet (registers[2], 27); // digital lock
+ bitClear (registers[2], 26); // digital lock
+
+ //bitSet (registers[4], 10); // Mute till lock
+// bitSet (registers[3], 23); // Fast lock
+ #endif
+// bitSet (registers[4], 10); // Mute till lock
+// ADF4351_Set(channel);
+}
+
+
+
#endif
diff --git a/si4432.h b/si4432.h
index 8b2774e..8473302 100644
--- a/si4432.h
+++ b/si4432.h
@@ -19,4 +19,26 @@ float SI4432_SET_RBW(float WISH);
void PE4302_Write_Byte(unsigned char DATA );
void PE4302_init(void);
+#ifdef __ULTRA_SA__
+extern int ADF4351_LE[];
+extern int debug;
+void ADF4351_Setup(void);
+
+
+void ADF4351_WriteRegister32(int channel, const uint32_t value);
+void ADF4351_set_frequency(int channel, uint32_t freq, int drive_strength);
+void ADF4351_prep_frequency(int channel, uint32_t freq, int drive_strength);
+//int ADF4351_set_frequency_with_offset(uint32_t freq, int offset, uint8_t drive_strength);
+void ADF4351_Set(int channel);
+void ADF4351_enable_output(void);
+void ADF4351_disable_output(void);
+void ADF4351_spur_mode(int S);
+void ADF4351_R_counter(int R);
+void ADF4351_channel_spacing(int spacing);
+void ADF4351_CP(int p);
+void ADF4351_level(int p);
+int ADF4351_locked(void);
+#endif
+
+
#endif //__SI4432_H__
diff --git a/ui.c b/ui.c
index e508c71..899d0d0 100644
--- a/ui.c
+++ b/ui.c
@@ -53,7 +53,11 @@ uistat_t uistat = {
#define BIT_DOWN1 1
#define READ_PORT() palReadPort(GPIOA)
+#ifdef __ULTRA_SA__
+#define BUTTON_MASK 0
+#else
#define BUTTON_MASK 0b1110
+#endif
static uint16_t last_button = 0b0000;
static uint32_t last_button_down_ticks;
@@ -128,7 +132,7 @@ static void choose_active_marker(void);
static void menu_move_back(void);
static void menu_push_submenu(const menuitem_t *submenu);
-static const menuitem_t menu_marker_type[];
+//static const menuitem_t menu_marker_type[];
static int btn_check(void)
{
@@ -1109,7 +1113,7 @@ const menuitem_t menu_top[] = {
#include "ui_sa.c"
-#define MENU_STACK_DEPTH_MAX 4
+#define MENU_STACK_DEPTH_MAX 5
const menuitem_t *menu_stack[MENU_STACK_DEPTH_MAX] = {
menu_mode, NULL, NULL, NULL
};
@@ -1784,7 +1788,7 @@ static void
draw_numeric_area(void)
{
char buf[10];
- plot_printf(buf, sizeof buf, "%9d", uistat.value);
+ plot_printf(buf, sizeof buf, "%9d", ((int32_t)uistat.value));
draw_numeric_input(buf);
}
@@ -2051,7 +2055,7 @@ keypad_click(int key)
/* numeric input done */
double value = my_atof(kp_buf) * scale;
#if 1
- uistat.value = (int)value;
+ uistat.value = value;
set_numeric_value();
#else
switch (keypad_mode) {
@@ -2497,8 +2501,13 @@ static void extcb1(EXTDriver *extp, expchannel_t channel)
static const EXTConfig extcfg = {
{
{EXT_CH_MODE_DISABLED, NULL},
+#ifdef __ULTRA_SA__
+ {EXT_CH_MODE_DISABLED, NULL},
+ {EXT_CH_MODE_DISABLED, NULL},
+#else
{EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1},
{EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1},
+#endif
{EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1},
{EXT_CH_MODE_DISABLED, NULL},
{EXT_CH_MODE_DISABLED, NULL},
@@ -2556,8 +2565,8 @@ ui_init()
/*
* Activates the EXT driver 1.
*/
- extStart(&EXTD1, &extcfg);
+ extStart(&EXTD1, &extcfg);
#if 1
gptStart(&GPTD3, &gpt3cfg);
gptPolledDelay(&GPTD3, 10); /* Small delay.*/
diff --git a/ui_sa.c b/ui_sa.c
index eaf102f..9aae4f5 100644
--- a/ui_sa.c
+++ b/ui_sa.c
@@ -1,6 +1,6 @@
void markmap_all_markers(void);
-static void menu_marker_type_cb(int item, uint8_t data);
-
+static void menu_marker_modify_cb(int item, uint8_t data);
+extern const menuitem_t menu_marker_modify[];
void set_sweep_frequency(int type, uint32_t frequency);
uint32_t get_sweep_frequency(int type);
void clearDisplay(void);
@@ -12,6 +12,8 @@ void set_refer_output(int);
int get_refer_output(void);
void SetAttenuation(int);
int GetAttenuation(void);
+void set_harmonic(int);
+extern int setting_harmonic;
int search_is_greater(void);
void set_auto_attenuation(void);
void set_auto_reflevel(void);
@@ -23,8 +25,10 @@ void SetDrive(int d);
void SetIF(int f);
void SetStepDelay(int t);
extern int setting_rbw;
-void SetSpur(int);
-int GetSpur(void);
+#ifdef __ULTRA__
+extern int setting_spur;
+void SetSpur(int v);
+#endif
void SetAverage(int);
int GetAverage(void);
extern int setting_average;
@@ -473,6 +477,7 @@ extern const menuitem_t menu_highoutputmode[];
extern const menuitem_t menu_modulation[];
extern const menuitem_t menu_top[];
extern const menuitem_t menu_tophigh[];
+extern const menuitem_t menu_topultra[];
static void menu_mode_cb(int item, uint8_t data)
{
@@ -492,6 +497,11 @@ static void menu_mode_cb(int item, uint8_t data)
case 4:
menu_push_submenu(menu_highoutputmode);
break;
+#ifdef __ULTRA__
+ case 7:
+ menu_push_submenu(menu_topultra);
+ break;
+#endif
}
// draw_cal_status();
}
@@ -614,13 +624,12 @@ static void menu_drive_cb(int item, uint8_t data)
-#if 0
-
+#ifdef __ULTRA__
static void menu_spur_cb(int item, uint8_t data)
{
(void)data;
(void)item;
- if (GetSpur())
+ if (setting_spur)
SetSpur(0);
else
SetSpur(1); // must be 0 or 1 !!!!
@@ -785,12 +794,31 @@ static void menu_average_cb(int item, uint8_t data)
draw_cal_status();
}
-static void menu_marker_type_cb(int item, uint8_t data)
+static void
+menu_marker_select_cb(int item, uint8_t data)
+{
+ (void)data;
+// int t;
+ if (item >= 0 && item < MARKERS_MAX) {
+ markers[item].enabled = true;
+ active_marker_select(item);
+ menu_push_submenu(menu_marker_modify);
+ redraw_marker(active_marker);
+ draw_menu();
+ }
+}
+
+static void menu_marker_modify_cb(int item, uint8_t data)
{
(void)item;
if (markers[active_marker].enabled == M_ENABLED)
{
- if (data == M_NORMAL) {
+ if (data == M_DELETE) {
+ markers[active_marker].enabled = false;
+ menu_move_back();
+// ui_mode_normal();
+// return;
+ } else if (data == M_NORMAL) {
markers[active_marker].mtype = M_NORMAL;
} else if (data == M_REFERENCE) {
for (int i = 0; i= 0 && markers[active_marker].enabled == M_ENABLED) {
+ } else if (menu == menu_marker_modify && active_marker >= 0 && markers[active_marker].enabled == M_ENABLED) {
if (data & markers[active_marker].mtype)
mark = true;
else if (item < 5 && data==markers[active_marker].mtype) // This catches the M_NORMAL case
@@ -1431,8 +1524,8 @@ static void menu_item_modify_attribute(
mark = true;
if (item == 4 && markers[active_marker].mtype & M_TRACKING)
mark = true;
- } else if (menu == menu_marker_sel) {
- if (item < MARKERS_MAX && markers[item].enabled)
+ } else if (menu == menu_marker_sel || menu == menu_marker_select) {
+ if (item < 4 && markers[item].enabled)
mark = true;
else if (item == 4 && uistat.marker_delta)
mark = true;
@@ -1487,19 +1580,19 @@ static void fetch_numeric_target(void)
break;
case KM_SCALE:
uistat.value = setting_scale;
- plot_printf(uistat.text, sizeof uistat.text, "%ddB/", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%ddB/", ((int32_t)uistat.value));
break;
case KM_REFPOS:
uistat.value = setting_reflevel;
- plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value));
break;
case KM_ATTENUATION:
uistat.value = GetAttenuation();
- plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value));
break;
case KM_ACTUALPOWER:
uistat.value = settingLevelOffset();
- plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value));
break;
case KM_IF:
uistat.value = frequency_IF;
@@ -1507,23 +1600,23 @@ static void fetch_numeric_target(void)
break;
case KM_SAMPLETIME:
uistat.value = setting_step_delay;
- plot_printf(uistat.text, sizeof uistat.text, "%3duS", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%3duS", ((int32_t)uistat.value));
break;
case KM_DRIVE:
uistat.value = setting_drive;
- plot_printf(uistat.text, sizeof uistat.text, "%3ddB", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%3ddB", ((int32_t)uistat.value));
break;
case KM_LOWOUTLEVEL:
uistat.value = GetAttenuation(); // compensation for dB offset during low output mode
- plot_printf(uistat.text, sizeof uistat.text, "%ddB", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%ddB", ((int32_t)uistat.value));
break;
case KM_DECAY:
uistat.value = setting_decay;
- plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%3d", ((int32_t)uistat.value));
break;
case KM_NOISE:
uistat.value = setting_noise;
- plot_printf(uistat.text, sizeof uistat.text, "%3d", uistat.value);
+ plot_printf(uistat.text, sizeof uistat.text, "%3d", ((int32_t)uistat.value));
break;
case KM_10MHZ:
uistat.value = setting_10mhz;