Merge branch 'tinySA' into tinySA-v0.2

tinySA-v0.2
erikkaashoek 6 years ago
commit 955973e57b

@ -21,12 +21,21 @@
<option id="cdt.managedbuild.option.gnu.cross.path.1646817820" name="Path" superClass="cdt.managedbuild.option.gnu.cross.path"/>
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.targetPlatform.gnu.cross.1575467853" isAbstract="false" osList="all" superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
<builder id="cdt.managedbuild.builder.gnu.cross.1313864987" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.builder.gnu.cross"/>
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1854849685" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler"/>
<tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1854849685" name="Cross GCC Compiler" superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1732092714" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1084702363" name="Cross G++ Compiler" superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler"/>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.275503439" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.c.linker.275503439" name="Cross GCC Linker" superClass="cdt.managedbuild.tool.gnu.cross.c.linker">
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1265043045" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.677623493" name="Cross G++ Linker" superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker"/>
<tool id="cdt.managedbuild.tool.gnu.cross.archiver.442904128" name="Cross GCC Archiver" superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.484878785" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler"/>
<tool id="cdt.managedbuild.tool.gnu.cross.assembler.484878785" name="Cross GCC Assembler" superClass="cdt.managedbuild.tool.gnu.cross.assembler">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1703156224" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
@ -41,4 +50,6 @@
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

@ -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) | \

@ -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
/**

@ -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

165
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 <string.h>
#include <math.h>
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<points; i++) {
float val = perform(false, i, frequencyStart - frequency_IF + f_step * i, setting_tracking);
streamPut(shell_stream, 'x');
@ -2319,19 +2364,22 @@ VNA_SHELL_FUNCTION(cmd_m)
// enable led
}
streamPut(shell_stream, '}');
palSetPad(GPIOB, GPIOB_LED);
setting_frequency_step = old_step;
update_rbw();
resume_sweep();
palSetPad(GPIOC, GPIOC_LED);
}
VNA_SHELL_FUNCTION(cmd_p)
{
(void)argc;
return;
int p = my_atoi(argv[0]);
int a = my_atoi(argv[1]);
if (p==5)
SetAttenuation(-a);
if (p==6)
if (a != GetMode())
SetMode(a);
SetMode(a);
if (p==1)
if (get_refer_output() != a)
set_refer_output(a);
@ -2341,6 +2389,7 @@ VNA_SHELL_FUNCTION(cmd_w)
{
(void)argc;
int p = my_atoi(argv[0]);
return;
SetRBW(p);
}
//=============================================================================
@ -2591,6 +2640,59 @@ static DACConfig dac1cfg1 = {
};
#endif
#if 0
/*
* UART driver configuration structure.
*/
static UARTConfig uart_cfg_1 = {
NULL, //txend1,
NULL, //txend2,
NULL, //rxend,
NULL, //rxchar,
NULL, //rxerr,
800000,
0,
0, //USART_CR2_LINEN,
0
};
#endif
#if 0
static const SerialConfig default_config =
{
9600,
0,
USART_CR2_STOP2_BITS,
0
};
void myWrite(char *buf)
{
int len = strlen(buf);
while(len-- > 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();

@ -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

@ -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;

@ -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;

@ -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
}

@ -19,7 +19,7 @@
#include "ch.h"
#include "hal.h"
#include "nanovna.h"
#include <math.h>
#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

@ -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__

19
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.*/

@ -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<MARKER_COUNT; i++ ) {
@ -815,7 +843,7 @@ static void menu_marker_type_cb(int item, uint8_t data)
}
const int rbwsel[]={0,3,10,30,100,300};
const int rbwsel[]={0,3,10,30,100,300,600};
static void menu_rbw_cb(int item, uint8_t data)
{
@ -862,6 +890,15 @@ static void choose_active_marker(void)
active_marker = -1;
}
#ifdef __ULTRA__
static void menu_harmonic_cb(int item, uint8_t data)
{
(void)item;
set_harmonic(data);
draw_menu();
}
#endif
static void menu_settings2_cb(int item, uint8_t data)
{
(void)item;
@ -993,6 +1030,7 @@ static const menuitem_t menu_rbw[] = {
{ MT_CALLBACK, 3, " 30kHz", menu_rbw_cb},
{ MT_CALLBACK, 4, "100kHz", menu_rbw_cb},
{ MT_CALLBACK, 5, "300kHz", menu_rbw_cb},
{ MT_CALLBACK, 6, "600kHz", menu_rbw_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -1045,12 +1083,13 @@ static const menuitem_t menu_reflevel[] = {
static const menuitem_t menu_marker_type[] = {
{ MT_CALLBACK, M_REFERENCE, "REFERENCE", menu_marker_type_cb},
{ MT_CALLBACK, M_DELTA, "DELTA", menu_marker_type_cb},
{ MT_CALLBACK, M_NOISE, "NOISE", menu_marker_type_cb},
{ MT_CALLBACK, M_TRACKING, "TRACKING", menu_marker_type_cb},
{ MT_CALLBACK, M_NORMAL, "NORMAL", menu_marker_type_cb},
const menuitem_t menu_marker_modify[] = {
{ MT_CALLBACK, M_REFERENCE, "REFERENCE", menu_marker_modify_cb},
{ MT_CALLBACK, M_DELTA, "DELTA", menu_marker_modify_cb},
{ MT_CALLBACK, M_NOISE, "NOISE", menu_marker_modify_cb},
{ MT_CALLBACK, M_TRACKING, "TRACKING", menu_marker_modify_cb},
{ MT_CALLBACK, M_NORMAL, "NORMAL", menu_marker_modify_cb},
{ MT_CALLBACK, M_DELETE, "DELETE", menu_marker_modify_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -1079,6 +1118,14 @@ const menuitem_t menu_marker_sel[] = {
{ MT_NONE, 0, NULL, NULL } // sentinel
};
const menuitem_t menu_marker_select[] = {
{ MT_CALLBACK, 1, "MARKER 1", menu_marker_select_cb },
{ MT_CALLBACK, 2, "MARKER 2", menu_marker_select_cb },
{ MT_CALLBACK, 3, "MARKER 3", menu_marker_select_cb },
{ MT_CALLBACK, 4, "MARKER 4", menu_marker_select_cb },
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
#if 0
@ -1107,8 +1154,8 @@ const menuitem_t menu_marker_ops[] = {
static const menuitem_t menu_marker[] = {
{ MT_SUBMENU, 0, "\2SELECT\0MARKERS", menu_marker_sel},
{ MT_SUBMENU, 0, "\2CHANGE\0MARKER", menu_marker_type},
{ MT_SUBMENU, 0, "\2SELECT\0MARKER", menu_marker_sel},
{ MT_SUBMENU, 0, "\2MODIFY\0MARKERS", menu_marker_select},
{ MT_SUBMENU, 0, "\2MARKER\0OPS", menu_marker_ops},
{ MT_SUBMENU, 0, "\2SEARCH\0MARKER", menu_marker_search},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
@ -1121,6 +1168,17 @@ static const menuitem_t menu_dfu[] = {
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
#ifdef __ULTRA__
static const menuitem_t menu_harmonic[] =
{
{ MT_CALLBACK, 2, "2", menu_harmonic_cb},
{ MT_CALLBACK, 3, "3", menu_harmonic_cb},
{ MT_CALLBACK, 4, "4", menu_harmonic_cb},
{ MT_CALLBACK, 5, "5", menu_harmonic_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
#endif
static const menuitem_t menu_settings2[] =
{
{ MT_CALLBACK, 0, "AGC", menu_settings2_cb},
@ -1140,6 +1198,9 @@ static const menuitem_t menu_settings[] =
{ MT_KEYPAD, KM_IF, "\2IF\0FREQ", NULL},
{ MT_KEYPAD, KM_SAMPLETIME, "\2SAMPLE\0TIME", NULL},
{ MT_SUBMENU,0, "\2LO\0DRIVE", menu_drive},
#ifdef __ULTRA__
{ MT_SUBMENU,0, "HARMONIC", menu_harmonic},
#endif
{ MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
@ -1250,6 +1311,9 @@ static const menuitem_t menu_stimulus[] = {
{ MT_KEYPAD, KM_SPAN, "SPAN", NULL},
{ MT_KEYPAD, KM_CW, "\2ZERO\0SPAN", NULL},
{ MT_SUBMENU,0, "RBW", menu_rbw},
#ifdef __ULTRA__
{ MT_CALLBACK,0, "\2SPUR\0REMOVAL", menu_spur_cb},
#endif
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
@ -1264,10 +1328,29 @@ static const menuitem_t menu_mode[] = {
{ MT_FORM | MT_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "HIGH OUTPUT", menu_mode_cb},
{ MT_FORM | MT_SUBMENU | MT_ICON, I_CONNECT+I_GEN, "CAL OUTPUT: %s", menu_reffer},
{ MT_FORM | MT_SUBMENU | MT_ICON, I_EMPTY+I_CONFIG, "CONFIG", menu_config},
// { MT_CANCEL, 0, S_LARROW" BACK", NULL },
#ifdef __ULTRA__
{ MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "ULTRA HIGH INPUT",menu_mode_cb},
#endif
// { MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
};
#if 1
#ifdef __ULTRA__
const menuitem_t menu_topultra[] = {
{ MT_CALLBACK, 0, "RESET", menu_autosettings_cb},
{ MT_SUBMENU, 0, "FREQ", menu_stimulus},
{ MT_SUBMENU, 0, "LEVEL", menu_level},
{ MT_SUBMENU, 0, "DISPLAY", menu_display},
{ MT_SUBMENU, 0, "MARKER", menu_marker},
{ MT_SUBMENU, 0, "MEASURE", menu_measure},
{ MT_SUBMENU, 0, "SETTINGS", menu_settings},
{ MT_CANCEL, 0, S_LARROW" MODE",NULL},
{ MT_NONE, 0, NULL, NULL } // sentinel,
// MENUITEM_CLOSE,
};
#endif
const menuitem_t menu_top[] = {
{ MT_CALLBACK, 0, "RESET", menu_autosettings_cb},
{ MT_SUBMENU, 0, "FREQ", menu_stimulus},
@ -1367,6 +1450,11 @@ static void menu_item_modify_attribute(
if (item == 5 /* PAUSE */ && !(sweep_mode&SWEEP_ENABLE)) {
mark = true;
}
#ifdef __ULTRA__
if (item == 6 && setting_spur) {
mark = true;
}
#endif
} else if (menu == menu_average) {
if (item == GetAverage()){
mark = true;
@ -1384,7 +1472,7 @@ static void menu_item_modify_attribute(
mark = true;
}
} else if (MT_MASK(menu[item].type) != MT_CALLBACK && (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3)) {
} else if (MT_MASK(menu[item].type) == MT_CALLBACK && (menu == menu_drive || menu == menu_drive_wide || menu == menu_drive_wide2|| menu == menu_drive_wide3)) {
if (data == setting_drive){
mark = true;
}
@ -1409,6 +1497,11 @@ static void menu_item_modify_attribute(
if (item ==0 && setting_tracking_output){
mark = true;
}
#ifdef __ULTRA__
} else if (MT_MASK(menu[item].type) == MT_CALLBACK && menu == menu_harmonic) {
if (data == setting_harmonic)
mark = true;
#endif
} else if (menu == menu_settings2 || menu == menu_settingshigh2) {
if (item ==0 && setting_agc){
mark = true;
@ -1419,7 +1512,7 @@ static void menu_item_modify_attribute(
if (item == 2 && setting_tracking){ // should not happen in high mode
mark = true;
}
} else if (menu == menu_marker_type && active_marker >= 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;

Loading…
Cancel
Save

Powered by TurnKey Linux.