Merge branch 'master' into tinySA-V4-SI4463

Removed_REF_marker
erikkaashoek 5 years ago
commit 424051821f

@ -56,8 +56,8 @@
#define GPIOA_XP 6 #define GPIOA_XP 6
#define GPIOA_YP 7 #define GPIOA_YP 7
#define GPIOA_MCO 8 #define GPIOA_MCO 8
#define GPIOA_TX 9 #define GPIOA_USART1_TX 9
#define GPIOA_USB_DISC 10 #define GPIOA_USART1_RX 10
#define GPIOA_USB_DM 11 #define GPIOA_USB_DM 11
#define GPIOA_USB_DP 12 #define GPIOA_USB_DP 12
#define GPIOA_JTMS 13 #define GPIOA_JTMS 13
@ -117,6 +117,8 @@
* GPIOA setup: * GPIOA setup:
* *
* PA8 - MCO (alternate 0). * PA8 - MCO (alternate 0).
* PA9 - USART1_TX (alternate 1).
* PA10 - USART1_RX (alternate 1).
* PA11 - USB_DM (alternate 14). * PA11 - USB_DM (alternate 14).
* PA12 - USB_DP (alternate 14). * PA12 - USB_DP (alternate 14).
* PA13 - SWDIO (alternate 0). * PA13 - SWDIO (alternate 0).
@ -131,8 +133,8 @@
PIN_MODE_ANALOG(GPIOA_XP) | \ PIN_MODE_ANALOG(GPIOA_XP) | \
PIN_MODE_ANALOG(GPIOA_YP) | \ PIN_MODE_ANALOG(GPIOA_YP) | \
PIN_MODE_ALTERNATE(GPIOA_MCO) | \ PIN_MODE_ALTERNATE(GPIOA_MCO) | \
PIN_MODE_ANALOG(9U) | \ PIN_MODE_ALTERNATE(GPIOA_USART1_TX) | \
PIN_MODE_ANALOG(GPIOA_USB_DISC) | \ PIN_MODE_ALTERNATE(GPIOA_USART1_RX) | \
PIN_MODE_INPUT(GPIOA_USB_DM) | \ PIN_MODE_INPUT(GPIOA_USB_DM) | \
PIN_MODE_INPUT(GPIOA_USB_DP) | \ PIN_MODE_INPUT(GPIOA_USB_DP) | \
PIN_MODE_ALTERNATE(GPIOA_JTMS) | \ PIN_MODE_ALTERNATE(GPIOA_JTMS) | \
@ -147,8 +149,8 @@
PIN_OTYPE_PUSHPULL(6U) | \ PIN_OTYPE_PUSHPULL(6U) | \
PIN_OTYPE_PUSHPULL(7U) | \ PIN_OTYPE_PUSHPULL(7U) | \
PIN_OTYPE_PUSHPULL(GPIOA_MCO) | \ PIN_OTYPE_PUSHPULL(GPIOA_MCO) | \
PIN_OTYPE_PUSHPULL(9U) | \ PIN_OTYPE_PUSHPULL(GPIOA_USART1_TX) | \
PIN_OTYPE_PUSHPULL(GPIOA_USB_DISC) | \ PIN_OTYPE_PUSHPULL(GPIOA_USART1_RX) | \
PIN_OTYPE_PUSHPULL(GPIOA_USB_DM) | \ PIN_OTYPE_PUSHPULL(GPIOA_USB_DM) | \
PIN_OTYPE_PUSHPULL(GPIOA_USB_DP) | \ PIN_OTYPE_PUSHPULL(GPIOA_USB_DP) | \
PIN_OTYPE_PUSHPULL(GPIOA_JTMS) | \ PIN_OTYPE_PUSHPULL(GPIOA_JTMS) | \
@ -163,8 +165,8 @@
PIN_OSPEED_2M(6) | \ PIN_OSPEED_2M(6) | \
PIN_OSPEED_2M(7) | \ PIN_OSPEED_2M(7) | \
PIN_OSPEED_100M(GPIOA_MCO) | \ PIN_OSPEED_100M(GPIOA_MCO) | \
PIN_OSPEED_2M(9) | \ PIN_OSPEED_100M(GPIOA_USART1_TX) | \
PIN_OSPEED_2M(10) | \ PIN_OSPEED_100M(GPIOA_USART1_RX) | \
PIN_OSPEED_100M(GPIOA_USB_DM) | \ PIN_OSPEED_100M(GPIOA_USB_DM) | \
PIN_OSPEED_100M(GPIOA_USB_DP) | \ PIN_OSPEED_100M(GPIOA_USB_DP) | \
PIN_OSPEED_100M(GPIOA_JTMS) | \ PIN_OSPEED_100M(GPIOA_JTMS) | \
@ -179,8 +181,8 @@
PIN_PUPDR_FLOATING(6) | \ PIN_PUPDR_FLOATING(6) | \
PIN_PUPDR_FLOATING(7) | \ PIN_PUPDR_FLOATING(7) | \
PIN_PUPDR_PULLUP(GPIOA_MCO) | \ PIN_PUPDR_PULLUP(GPIOA_MCO) | \
PIN_PUPDR_FLOATING(9) | \ PIN_PUPDR_FLOATING(GPIOA_USART1_TX) | \
PIN_PUPDR_FLOATING(GPIOA_USB_DISC) | \ PIN_PUPDR_FLOATING(GPIOA_USART1_RX) | \
PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \ PIN_PUPDR_FLOATING(GPIOA_USB_DM) | \
PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \ PIN_PUPDR_FLOATING(GPIOA_USB_DP) | \
PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \ PIN_PUPDR_PULLDOWN(GPIOA_JTMS) | \
@ -195,8 +197,8 @@
PIN_ODR_HIGH(6) | \ PIN_ODR_HIGH(6) | \
PIN_ODR_HIGH(7) | \ PIN_ODR_HIGH(7) | \
PIN_ODR_HIGH(GPIOA_MCO) | \ PIN_ODR_HIGH(GPIOA_MCO) | \
PIN_ODR_HIGH(9) | \ PIN_ODR_LOW(GPIOA_USART1_TX) | \
PIN_ODR_HIGH(GPIOA_USB_DISC) | \ PIN_ODR_LOW(GPIOA_USART1_RX) | \
PIN_ODR_HIGH(GPIOA_USB_DM) | \ PIN_ODR_HIGH(GPIOA_USB_DM) | \
PIN_ODR_HIGH(GPIOA_USB_DP) | \ PIN_ODR_HIGH(GPIOA_USB_DP) | \
PIN_ODR_HIGH(GPIOA_JTMS) | \ PIN_ODR_HIGH(GPIOA_JTMS) | \
@ -211,8 +213,8 @@
PIN_AFIO_AF(6, 0) | \ PIN_AFIO_AF(6, 0) | \
PIN_AFIO_AF(7, 0)) PIN_AFIO_AF(7, 0))
#define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_MCO, 0) | \ #define VAL_GPIOA_AFRH (PIN_AFIO_AF(GPIOA_MCO, 0) | \
PIN_AFIO_AF(9, 0) | \ PIN_AFIO_AF(GPIOA_USART1_TX, 1) | \
PIN_AFIO_AF(GPIOA_USB_DISC, 0) | \ PIN_AFIO_AF(GPIOA_USART1_RX, 1) | \
PIN_AFIO_AF(GPIOA_USB_DM, 0) | \ PIN_AFIO_AF(GPIOA_USB_DM, 0) | \
PIN_AFIO_AF(GPIOA_USB_DP, 0) | \ PIN_AFIO_AF(GPIOA_USB_DP, 0) | \
PIN_AFIO_AF(GPIOA_JTMS, 0) | \ PIN_AFIO_AF(GPIOA_JTMS, 0) | \

@ -188,7 +188,7 @@ caldata_recall(uint16_t id)
memcpy(dst, src, sizeof(setting_t)); memcpy(dst, src, sizeof(setting_t));
// Restore stored trace // Restore stored trace
memcpy(stored_t, &src[1], sizeof(stored_t)); memcpy(stored_t, &src[1], sizeof(stored_t));
update_min_max_freq();
update_frequencies(); update_frequencies();
set_scale(setting.scale); set_scale(setting.scale);
set_reflevel(setting.reflevel); set_reflevel(setting.reflevel);

@ -136,7 +136,7 @@
* @brief Enables the SERIAL subsystem. * @brief Enables the SERIAL subsystem.
*/ */
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) #if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
#define HAL_USE_SERIAL FALSE #define HAL_USE_SERIAL TRUE
#endif #endif
/** /**
@ -302,7 +302,7 @@
* buffers. * buffers.
*/ */
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) #if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 16 #define SERIAL_BUFFERS_SIZE 64
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
@ -325,7 +325,7 @@
* @note The default is 2 buffers. * @note The default is 2 buffers.
*/ */
#if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__) #if !defined(SERIAL_USB_BUFFERS_NUMBER) || defined(__DOXYGEN__)
#define SERIAL_USB_BUFFERS_NUMBER 1 #define SERIAL_USB_BUFFERS_NUMBER 2
#endif #endif
/*===========================================================================*/ /*===========================================================================*/

273
main.c

@ -47,7 +47,7 @@ int32_t frequencyExtra;
// enable this need reduce spi_buffer size, by default shell run in main thread // enable this need reduce spi_buffer size, by default shell run in main thread
// #define VNA_SHELL_THREAD // #define VNA_SHELL_THREAD
static BaseSequentialStream *shell_stream = (BaseSequentialStream *)&SDU1; static BaseSequentialStream *shell_stream;
// Shell new line // Shell new line
#define VNA_SHELL_NEWLINE_STR "\r\n" #define VNA_SHELL_NEWLINE_STR "\r\n"
@ -80,6 +80,7 @@ static volatile vna_shellcmd_t shell_function = 0;
#define ENABLE_INFO_COMMAND #define ENABLE_INFO_COMMAND
// Enable color command, allow change config color for traces, grid, menu // Enable color command, allow change config color for traces, grid, menu
#define ENABLE_COLOR_COMMAND #define ENABLE_COLOR_COMMAND
#define ENABLE_USART_COMMAND
#ifdef __VNA__ #ifdef __VNA__
static void apply_error_term_at(int i); static void apply_error_term_at(int i);
static void apply_edelay_at(int i); static void apply_edelay_at(int i);
@ -182,6 +183,8 @@ static THD_FUNCTION(Thread1, arg)
int i = marker_search(); int i = marker_search();
if (i != -1 && active_marker != -1) { if (i != -1 && active_marker != -1) {
markers[active_marker].index = i; markers[active_marker].index = i;
markers[active_marker].frequency = frequencies[i];
redraw_request |= REDRAW_MARKER; redraw_request |= REDRAW_MARKER;
} }
} }
@ -327,6 +330,18 @@ int shell_printf(const char *fmt, ...)
return formatted_bytes; return formatted_bytes;
} }
#ifdef __USE_SERIAL_CONSOLE__
// Serial Shell commands output
int shell_serial_printf(const char *fmt, ...)
{
va_list ap;
int formatted_bytes;
va_start(ap, fmt);
formatted_bytes = chvprintf(&SD1, fmt, ap);
va_end(ap);
return formatted_bytes;
}
#endif
VNA_SHELL_FUNCTION(cmd_pause) VNA_SHELL_FUNCTION(cmd_pause)
{ {
(void)argc; (void)argc;
@ -471,7 +486,7 @@ calculate:
return value; return value;
} }
double float
my_atof(const char *p) my_atof(const char *p)
{ {
int neg = FALSE; int neg = FALSE;
@ -479,11 +494,11 @@ my_atof(const char *p)
neg = TRUE; neg = TRUE;
if (*p == '-' || *p == '+') if (*p == '-' || *p == '+')
p++; p++;
double x = my_atoi(p); float x = my_atoi(p);
while (_isdigit((int)*p)) while (_isdigit((int)*p))
p++; p++;
if (*p == '.') { if (*p == '.') {
double d = 1.0f; float d = 1.0f;
p++; p++;
while (_isdigit((int)*p)) { while (_isdigit((int)*p)) {
d /= 10; d /= 10;
@ -846,13 +861,14 @@ config_t config = {
.magic = CONFIG_MAGIC, .magic = CONFIG_MAGIC,
.dac_value = 1922, .dac_value = 1922,
.grid_color = DEFAULT_GRID_COLOR, .grid_color = DEFAULT_GRID_COLOR,
.ham_color = DEFAULT_HAM_COLOR,
.menu_normal_color = DEFAULT_MENU_COLOR, .menu_normal_color = DEFAULT_MENU_COLOR,
.menu_active_color = DEFAULT_MENU_ACTIVE_COLOR, .menu_active_color = DEFAULT_MENU_ACTIVE_COLOR,
.trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR}, .trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR},
// .touch_cal = { 693, 605, 124, 171 }, // 2.4 inch LCD panel // .touch_cal = { 693, 605, 124, 171 }, // 2.4 inch LCD panel
// .touch_cal = { 347, 495, 160, 205 }, // 2.8 inch LCD panel .touch_cal = { 347, 495, 160, 205 }, // 2.8 inch LCD panel
.touch_cal = { 272, 521, 114, 153 }, //4.0" LCD ._mode = _MODE_USB,
.freq_mode = FREQ_MODE_START_STOP, ._serial_speed = USART_SPEED_SETTING(SERIAL_DEFAULT_BITRATE),
#ifdef __VNA__ #ifdef __VNA__
.harmonic_freq_threshold = 300000000, .harmonic_freq_threshold = 300000000,
#endif #endif
@ -861,6 +877,9 @@ config_t config = {
.high_level_offset = 100, // Uncalibrated .high_level_offset = 100, // Uncalibrated
.correction_frequency = { 10000, 100000, 200000, 500000, 50000000, 140000000, 200000000, 300000000, 330000000, 350000000 }, .correction_frequency = { 10000, 100000, 200000, 500000, 50000000, 140000000, 200000000, 300000000, 330000000, 350000000 },
.correction_value = { +6.0, +2.8, +1.6, -0.4, 0.0, -0.4, +0.4, +3.0, +4.0, +8.1 }, .correction_value = { +6.0, +2.8, +1.6, -0.4, 0.0, -0.4, +0.4, +3.0, +4.0, +8.1 },
.cor_am = -14,
.cor_wfm = -17,
.cor_nfm = -17,
}; };
//properties_t current_props; //properties_t current_props;
@ -1023,9 +1042,9 @@ VNA_SHELL_FUNCTION(cmd_scan)
if (mask) { if (mask) {
for (i = 0; i < points; i++) { for (i = 0; i < points; i++) {
if (mask & 1) shell_printf("%u ", frequencies[i]); if (mask & 1) shell_printf("%u ", frequencies[i]);
if (mask & 2) shell_printf("%f ", value(measured[0][i])); if (mask & 2) shell_printf("%f %f ", value(measured[2][i]), 0.0);
if (mask & 4) shell_printf("%f ", value(measured[1][i])); if (mask & 4) shell_printf("%f %f ", value(measured[1][i]), 0.0);
if (mask & 8) shell_printf("%f ", value(measured[2][i])); if (mask & 8) shell_printf("%f %f ", value(measured[0][i]), 0.0);
shell_printf("\r\n"); shell_printf("\r\n");
} }
} }
@ -1053,6 +1072,7 @@ update_marker_index(void)
for (i = 0; i < sweep_points-1; i++) { for (i = 0; i < sweep_points-1; i++) {
if (frequencies[i] <= f && f < frequencies[i+1]) { if (frequencies[i] <= f && f < frequencies[i+1]) {
markers[m].index = f < (frequencies[i] / 2 + frequencies[i + 1] / 2) ? i : i + 1; markers[m].index = f < (frequencies[i] / 2 + frequencies[i + 1] / 2) ? i : i + 1;
markers[m].frequency = frequencies[markers[m].index ];
break; break;
} }
} }
@ -1060,6 +1080,23 @@ update_marker_index(void)
} }
} }
void set_marker_frequency(int m, uint32_t f)
{
if (m < 0 || !markers[m].enabled)
return;
int i = 1;
markers[m].mtype &= ~M_TRACKING;
uint32_t s = (frequencies[1] - frequencies[0])/2;
while (i< sweep_points - 1){
if (frequencies[i]-s <= f && f < frequencies[i]+s) {
markers[m].index = i;
markers[m].frequency = f;
return;
}
i++;
}
}
static void static void
set_frequencies(uint32_t start, uint32_t stop, uint16_t points) set_frequencies(uint32_t start, uint32_t stop, uint16_t points)
{ {
@ -1886,27 +1923,39 @@ VNA_SHELL_FUNCTION(cmd_marker)
if (t < 0 || t >= MARKERS_MAX) if (t < 0 || t >= MARKERS_MAX)
goto usage; goto usage;
if (argc == 1) { if (argc == 1) {
display_marker:
shell_printf("%d %d %d %.2f\r\n", t+1, markers[t].index, markers[t].frequency, value(actual_t[markers[t].index])); shell_printf("%d %d %d %.2f\r\n", t+1, markers[t].index, markers[t].frequency, value(actual_t[markers[t].index]));
active_marker = t; active_marker = t;
// select active marker // select active marker
markers[t].enabled = TRUE; markers[t].enabled = TRUE;
return; return;
} }
static const char cmd_marker_list[] = "on|off"; static const char cmd_marker_list[] = "on|off|peak";
switch (get_str_index(argv[1], cmd_marker_list)) { switch (get_str_index(argv[1], cmd_marker_list)) {
case 0: markers[t].enabled = TRUE; active_marker = t; return; case 0: markers[t].enabled = TRUE; active_marker = t; return;
case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = -1; return; case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = -1; return;
case 2: markers[t].enabled = TRUE; active_marker = t;
int i = marker_search_max();
if (i == -1) i = 0;
markers[active_marker].index = i;
markers[active_marker].frequency = frequencies[i];
goto display_marker;
default: default:
// select active marker and move to index // select active marker and move to index or frequency
markers[t].enabled = TRUE; markers[t].enabled = TRUE;
int index = my_atoi(argv[1]); uint32_t value = my_atoui(argv[1]);
markers[t].index = index; markers[t].mtype &= ~M_TRACKING;
markers[t].frequency = frequencies[index];
active_marker = t; active_marker = t;
if (value > sweep_points)
set_marker_frequency(active_marker, value);
else {
markers[t].index = value;
markers[t].frequency = frequencies[value];
}
return; return;
} }
usage: usage:
shell_printf("marker [n] [%s|{index}]\r\n", cmd_marker_list); shell_printf("marker [n] [%s|{freq}|{index}]\r\n", cmd_marker_list);
} }
VNA_SHELL_FUNCTION(cmd_touchcal) VNA_SHELL_FUNCTION(cmd_touchcal)
@ -2255,6 +2304,20 @@ VNA_SHELL_FUNCTION(cmd_threads)
} }
#endif #endif
#ifdef ENABLE_USART_COMMAND
VNA_SHELL_FUNCTION(cmd_usart)
{
uint32_t time = 2000; // 200ms wait answer by default
if (argc == 0 || argc > 2 || (config._mode & _MODE_SERIAL)) return;
if (argc == 2) time = my_atoui(argv[1])*10;
sdWriteTimeout(&SD1, (uint8_t *)argv[0], strlen(argv[0]), time);
sdWriteTimeout(&SD1, (uint8_t *)VNA_SHELL_NEWLINE_STR, sizeof(VNA_SHELL_NEWLINE_STR)-1, time);
uint32_t size;
uint8_t buffer[64];
while ((size = sdReadTimeout(&SD1, buffer, sizeof(buffer), time)))
streamWrite(&SDU1, buffer, size);
}
#endif
#include "sa_cmd.c" #include "sa_cmd.c"
//============================================================================= //=============================================================================
@ -2305,6 +2368,7 @@ static const VNAShellCommand commands[] =
{"touchtest" , cmd_touchtest , CMD_WAIT_MUTEX}, {"touchtest" , cmd_touchtest , CMD_WAIT_MUTEX},
{"pause" , cmd_pause , 0}, {"pause" , cmd_pause , 0},
{"resume" , cmd_resume , 0}, {"resume" , cmd_resume , 0},
{"caloutput" , cmd_caloutput , 0},
#ifdef __VNA__ #ifdef __VNA__
{"cal" , cmd_cal , CMD_WAIT_MUTEX}, {"cal" , cmd_cal , CMD_WAIT_MUTEX},
#endif #endif
@ -2313,6 +2377,9 @@ static const VNAShellCommand commands[] =
{"trace" , cmd_trace , CMD_WAIT_MUTEX}, {"trace" , cmd_trace , CMD_WAIT_MUTEX},
{"trigger" , cmd_trigger , 0}, {"trigger" , cmd_trigger , 0},
{"marker" , cmd_marker , 0}, {"marker" , cmd_marker , 0},
#ifdef ENABLE_USART_COMMAND
{"usart" , cmd_usart , CMD_WAIT_MUTEX},
#endif
#ifdef __VNA__ #ifdef __VNA__
{"edelay" , cmd_edelay , 0}, {"edelay" , cmd_edelay , 0},
#endif #endif
@ -2389,6 +2456,110 @@ VNA_SHELL_FUNCTION(cmd_help)
/* /*
* VNA shell functions * VNA shell functions
*/ */
// Check Serial connection requirements
#ifdef __USE_SERIAL_CONSOLE__
#if HAL_USE_SERIAL == FALSE
#error "For serial console need HAL_USE_SERIAL as TRUE in halconf.h"
#endif
// Before start process command from shell, need select input stream
#define PREPARE_STREAM shell_stream = (config._mode&_MODE_SERIAL) ? (BaseSequentialStream *)&SD1 : (BaseSequentialStream *)&SDU1;
// Update Serial connection speed and settings
void shell_update_speed(void){
// Update Serial speed settings
SerialConfig s_config = {USART_GET_SPEED(config._serial_speed), 0, USART_CR2_STOP1_BITS, 0 };
sdStop(&SD1);
sdStart(&SD1, &s_config); // USART config
}
// Check USB connection status
static bool usb_IsActive(void){
return usbGetDriverStateI(&USBD1) == USB_ACTIVE;
}
void shell_reset_console(void){
// Reset I/O queue over USB (for USB need also connect/disconnect)
if (usb_IsActive()){
if (config._mode & _MODE_SERIAL)
sduDisconnectI(&SDU1);
else
sduConfigureHookI(&SDU1);
}
// Reset I/O queue over Serial
oqResetI(&SD1.oqueue);
iqResetI(&SD1.iqueue);
}
// Check active connection for Shell
static bool shell_check_connect(void){
// Serial connection always active
if (config._mode & _MODE_SERIAL)
return true;
// USB connection can be USB_SUSPENDED
return usb_IsActive();
}
static void shell_init_connection(void){
/*
* Initializes and start serial-over-USB CDC driver SDU1, connected to USBD1
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
/*
* Set Serial speed settings for SD1
*/
shell_update_speed();
/*
* Activates the USB driver and then the USB bus pull-up on D+.
* Note, a delay is inserted in order to not have to disconnect the cable
* after a reset.
*/
usbDisconnectBus(&USBD1);
chThdSleepMilliseconds(100);
usbStart(&USBD1, &usbcfg);
usbConnectBus(&USBD1);
/*
* Set I/O stream (SDU1 or SD1) for shell
*/
PREPARE_STREAM;
}
#else
// Only USB console, shell_stream always on USB
#define PREPARE_STREAM
// Check connection as Active, if no suspend input
static bool shell_check_connect(void){
return SDU1.config->usbp->state == USB_ACTIVE;
}
// Init shell I/O connection over USB
static void shell_init_connection(void){
/*
* Initializes and start serial-over-USB CDC driver SDU1, connected to USBD1
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
/*
* Activates the USB driver and then the USB bus pull-up on D+.
* Note, a delay is inserted in order to not have to disconnect the cable
* after a reset.
*/
usbDisconnectBus(&USBD1);
chThdSleepMilliseconds(100);
usbStart(&USBD1, &usbcfg);
usbConnectBus(&USBD1);
/*
* Set I/O stream SDU1 for shell
*/
shell_stream = (BaseSequentialStream *)&SDU1;
}
#endif
// //
// Read command line from shell_stream // Read command line from shell_stream
@ -2398,6 +2569,8 @@ static int VNAShell_readLine(char *line, int max_size)
// Read line from input stream // Read line from input stream
uint8_t c; uint8_t c;
char *ptr = line; char *ptr = line;
// Prepare I/O for shell_stream
PREPARE_STREAM;
while (1) { while (1) {
// Return 0 only if stream not active // Return 0 only if stream not active
if (streamRead(shell_stream, &c, 1) == 0) if (streamRead(shell_stream, &c, 1) == 0)
@ -2608,23 +2781,6 @@ int main(void)
i2cStart(&I2CD1, &i2ccfg); i2cStart(&I2CD1, &i2ccfg);
si5351_init(); si5351_init();
// MCO on PA8
//palSetPadMode(GPIOA, 8, PAL_MODE_ALTERNATE(0));
/*
* Initializes a serial-over-USB CDC driver.
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serusbcfg);
/*
* Activates the USB driver and then the USB bus pull-up on D+.
* Note, a delay is inserted in order to not have to disconnect the cable
* after a reset.
*/
usbDisconnectBus(serusbcfg.usbp);
chThdSleepMilliseconds(100);
usbStart(serusbcfg.usbp, &usbcfg);
usbConnectBus(serusbcfg.usbp);
#ifdef __SI4432__ #ifdef __SI4432__
/* /*
* Powercycle the RF part to reset SI4432 * Powercycle the RF part to reset SI4432
@ -2664,44 +2820,6 @@ int main(void)
} }
#endif #endif
#if 0
/*
* UART initialize
*/
uartStart(&UARTD1, &uart_cfg_1);
again:
uartStartSend(&UARTD1, 1, "H");
uint8_t buf[10];
uartStartReceive(&UARTD1, 1, buf);
goto again;
#endif
#if 0
again:
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);
goto again;
#endif
#ifdef __ULTRA_SA__ #ifdef __ULTRA_SA__
ADF4351_Setup(); ADF4351_Setup();
#endif #endif
@ -2721,6 +2839,12 @@ goto again;
if (caldata_recall(0) == -1) { if (caldata_recall(0) == -1) {
load_default_properties(); load_default_properties();
} }
/*
* Init Shell console connection data (after load config for settings)
*/
shell_init_connection();
/* restore frequencies and calibration 0 slot properties from flash memory */ /* restore frequencies and calibration 0 slot properties from flash memory */
dac1cfg1.init = config.dac_value; dac1cfg1.init = config.dac_value;
@ -2755,7 +2879,7 @@ goto again;
// menu_mode_cb(setting.mode,0); // menu_mode_cb(setting.mode,0);
// } // }
redraw_frame(); redraw_frame();
#if 0 #if 1
set_mode(M_HIGH); set_mode(M_HIGH);
set_sweep_frequency(ST_STOP, (uint32_t) 30000000); set_sweep_frequency(ST_STOP, (uint32_t) 30000000);
sweep(false); sweep(false);
@ -2764,9 +2888,12 @@ goto again;
set_mode(M_LOW); set_mode(M_LOW);
set_sweep_frequency(ST_STOP, (uint32_t) 4000000); set_sweep_frequency(ST_STOP, (uint32_t) 4000000);
sweep(false); sweep(false);
set_sweep_frequency(ST_STOP, (uint32_t) 350000000);
#endif #endif
if (caldata_recall(0) == -1) {
load_default_properties();
}
set_refer_output(-1); set_refer_output(-1);
// ui_mode_menu(); // Show menu when autostarting mode // ui_mode_menu(); // Show menu when autostarting mode
ui_mode_normal(); ui_mode_normal();

@ -193,7 +193,7 @@
/* /*
* SERIAL driver system settings. * SERIAL driver system settings.
*/ */
#define STM32_SERIAL_USE_USART1 FALSE #define STM32_SERIAL_USE_USART1 TRUE
#define STM32_SERIAL_USE_USART2 FALSE #define STM32_SERIAL_USE_USART2 FALSE
#define STM32_SERIAL_USART1_PRIORITY 3 #define STM32_SERIAL_USART1_PRIORITY 3
#define STM32_SERIAL_USART2_PRIORITY 3 #define STM32_SERIAL_USART2_PRIORITY 3

@ -38,11 +38,12 @@
#define __CALIBRATE__ #define __CALIBRATE__
#define __FAST_SWEEP__ // Pre-fill SI4432 RSSI buffer to get fastest sweep in zero span mode #define __FAST_SWEEP__ // Pre-fill SI4432 RSSI buffer to get fastest sweep in zero span mode
#define __AUDIO__ #define __AUDIO__
#define __HAM_BAND__
//#define __ULTRA__ // Add harmonics mode on low input. //#define __ULTRA__ // Add harmonics mode on low input.
//#define __ULTRA_SA__ // Adds ADF4351 control for extra high 1st IF stage //#define __ULTRA_SA__ // Adds ADF4351 control for extra high 1st IF stage
#define __SPUR__ // Does spur reduction by shifting IF #define __SPUR__ // Does spur reduction by shifting IF
#define __USE_SERIAL_CONSOLE__ // Enable serial I/O connection (need enable HAL_USE_SERIAL as TRUE in halconf.h)
#define __SI4463__ #define __SI4463__
/* /*
* main.c * main.c
*/ */
@ -133,9 +134,10 @@ void update_frequencies(void);
void set_sweep_frequency(int type, uint32_t frequency); void set_sweep_frequency(int type, uint32_t frequency);
uint32_t get_sweep_frequency(int type); uint32_t get_sweep_frequency(int type);
void my_microsecond_delay(int t); void my_microsecond_delay(int t);
double my_atof(const char *p); float my_atof(const char *p);
int shell_printf(const char *fmt, ...); int shell_printf(const char *fmt, ...);
void set_marker_frequency(int m, uint32_t f);
void toggle_sweep(void); void toggle_sweep(void);
void toggle_mute(void); void toggle_mute(void);
void load_default_properties(void); void load_default_properties(void);
@ -148,7 +150,7 @@ enum {
}; };
enum { enum {
MO_NONE, MO_AM_1kHz, MO_AM_10Hz, MO_NFM, MO_WFM, MO_EXTERNAL, MO_NONE, MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL,
}; };
#define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH ) #define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH )
@ -175,6 +177,7 @@ extern const char *info_about[];
// ------------------------------- sa_core.c ---------------------------------- // ------------------------------- sa_core.c ----------------------------------
void reset_settings(int); void reset_settings(int);
void update_min_max_freq(void);
//void ui_process_touch(void); //void ui_process_touch(void);
void SetPowerGrid(int); void SetPowerGrid(int);
void SetRefLevel(float); void SetRefLevel(float);
@ -235,6 +238,7 @@ void toggle_tracking_output(void);
extern int32_t frequencyExtra; extern int32_t frequencyExtra;
void set_10mhz(uint32_t); void set_10mhz(uint32_t);
void set_modulation(int); void set_modulation(int);
void set_modulation_frequency(int);
//extern int setting.modulation; //extern int setting.modulation;
void set_measurement(int); void set_measurement(int);
// extern int settingSpeed; // extern int settingSpeed;
@ -288,10 +292,13 @@ extern void tlv320aic3204_select(int channel);
#ifdef __SCROLL__ #ifdef __SCROLL__
extern uint16_t _grid_y; extern uint16_t _grid_y;
#define GRIDY _grid_y #define GRIDY _grid_y
#define HEIGHT_SCROLL 250 extern uint16_t graph_bottom;
#define HEIGHT_NOSCROLL 310 #define BIG_WATERFALL 90
#define SMALL_WATERFALL 180
#define NO_WATERFALL CHART_BOTTOM
#define CHART_BOTTOM 310
#define SCROLL_GRIDY (HEIGHT_SCROLL / NGRIDY) #define SCROLL_GRIDY (HEIGHT_SCROLL / NGRIDY)
#define NOSCROLL_GRIDY (HEIGHT_NOSCROLL / NGRIDY) #define NOSCROLL_GRIDY (CHART_BOTTOM / NGRIDY)
#else #else
#define GRIDY (310 / NGRIDY) #define GRIDY (310 / NGRIDY)
#endif #endif
@ -436,6 +443,11 @@ typedef struct trace {
#define FREQ_MODE_CENTER_SPAN 0x1 #define FREQ_MODE_CENTER_SPAN 0x1
#define FREQ_MODE_DOTTED_GRID 0x2 #define FREQ_MODE_DOTTED_GRID 0x2
// Connection flag
#define _MODE_CONNECTION_MASK 0x04
#define _MODE_SERIAL 0x04
#define _MODE_USB 0x00
typedef struct config { typedef struct config {
int32_t magic; int32_t magic;
uint16_t dac_value; uint16_t dac_value;
@ -444,7 +456,8 @@ typedef struct config {
uint16_t menu_active_color; uint16_t menu_active_color;
uint16_t trace_color[TRACES_MAX]; uint16_t trace_color[TRACES_MAX];
int16_t touch_cal[4]; int16_t touch_cal[4];
int8_t freq_mode; int8_t _mode;
uint32_t _serial_speed;
#ifdef __VNA__ #ifdef __VNA__
uint32_t harmonic_freq_threshold; uint32_t harmonic_freq_threshold;
#endif #endif
@ -454,6 +467,13 @@ typedef struct config {
uint32_t correction_frequency[CORRECTION_POINTS]; uint32_t correction_frequency[CORRECTION_POINTS];
float correction_value[CORRECTION_POINTS]; float correction_value[CORRECTION_POINTS];
uint32_t deviceid; uint32_t deviceid;
uint16_t ham_color;
uint16_t gridlines;
uint16_t hambands;
int8_t cor_am;
int8_t cor_wfm;
int8_t cor_nfm;
int8_t dummy;
// uint8_t _reserved[22]; // uint8_t _reserved[22];
uint32_t checksum; uint32_t checksum;
} config_t; } config_t;
@ -471,6 +491,20 @@ float get_trace_refpos(int t);
const char *get_trace_typename(int t); const char *get_trace_typename(int t);
extern int in_selftest; extern int in_selftest;
//
// Shell config functions and macros
// Serial connect definitions not used if Serial mode disabled
// Minimum speed - USART_SPEED_MULTIPLIER
// Maximum speed - USART_SPEED_MULTIPLIER * 256
// Can be: 19200, 38400, 57600, 76800, 115200, 230400, 460800, 921600, 1843200, 3686400
#define USART_SPEED_MULTIPLIER 19200
#define USART_SPEED_SETTING(speed) ((speed)/USART_SPEED_MULTIPLIER - 1)
#define USART_GET_SPEED(idx) (((idx) + 1) * USART_SPEED_MULTIPLIER)
void shell_update_speed(void);
void shell_reset_console(void);
int shell_serial_printf(const char *fmt, ...);
#ifdef __VNA #ifdef __VNA
void set_electrical_delay(float picoseconds); void set_electrical_delay(float picoseconds);
float get_electrical_delay(void); float get_electrical_delay(void);
@ -559,6 +593,7 @@ extern volatile uint8_t redraw_request;
#define DARK_GREY RGB565(140,140,140) #define DARK_GREY RGB565(140,140,140)
#define LIGHT_GREY RGB565(220,220,220) #define LIGHT_GREY RGB565(220,220,220)
#define DEFAULT_GRID_COLOR RGB565(128,128,128) #define DEFAULT_GRID_COLOR RGB565(128,128,128)
#define DEFAULT_HAM_COLOR RGB565(80,80,80)
#define DEFAULT_GRID_VALUE_COLOR RGB565(196,196,196) #define DEFAULT_GRID_VALUE_COLOR RGB565(196,196,196)
#define DEFAULT_MENU_COLOR RGB565(255,255,255) #define DEFAULT_MENU_COLOR RGB565(255,255,255)
#define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0) #define DEFAULT_MENU_TEXT_COLOR RGB565( 0, 0, 0)
@ -683,6 +718,7 @@ typedef struct setting
int offset_delay; int offset_delay;
int fast_speedup; int fast_speedup;
float normalize_level; // Level to set normalize to, zero if not doing anything float normalize_level; // Level to set normalize to, zero if not doing anything
int modulation_frequency;
uint32_t checksum; uint32_t checksum;
}setting_t; }setting_t;
@ -714,7 +750,7 @@ extern uint32_t frequencies[POINTS_COUNT];
extern const float unit_scale_value[]; extern const float unit_scale_value[];
extern const char * const unit_scale_text[]; extern const char * const unit_scale_text[];
#if 1 #if 1 // Still sufficient flash
// Flash save area - flash7 : org = 0x0801B000, len = 20k in *.ld file // Flash save area - flash7 : org = 0x0801B000, len = 20k in *.ld file
// 2k - for config save // 2k - for config save
// 9 * 2k for setting_t + stored trace // 9 * 2k for setting_t + stored trace
@ -744,6 +780,7 @@ extern const char * const unit_scale_text[];
#define SAVE_PROP_CONFIG_3_ADDR 0x0801E000 #define SAVE_PROP_CONFIG_3_ADDR 0x0801E000
#define SAVE_PROP_CONFIG_4_ADDR 0x0801e800 #define SAVE_PROP_CONFIG_4_ADDR 0x0801e800
#endif #endif
#if 0 #if 0
typedef struct properties { typedef struct properties {
uint32_t magic; uint32_t magic;
@ -945,11 +982,13 @@ extern uint16_t actual_rbw_x10;
int get_waterfall(void); int get_waterfall(void);
void toggle_tracking(void); void toggle_tracking(void);
void toggle_hambands(void);
void reset_calibration(void); void reset_calibration(void);
void set_reflevel(float); void set_reflevel(float);
void set_offset(float); void set_offset(float);
void set_unit(int); void set_unit(int);
void set_switches(int); void set_switches(int);
void set_gridlines(int);
void set_trigger_level(float); void set_trigger_level(float);
void set_trigger(int); void set_trigger(int);
void update_rbw(void); void update_rbw(void);
@ -964,7 +1003,7 @@ uint32_t calc_min_sweep_time_us(void);
pureRSSI_t perform(bool b, int i, uint32_t f, int e); pureRSSI_t perform(bool b, int i, uint32_t f, int e);
enum { enum {
M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_STOP_BAND, M_PASS_BAND, M_LINEARITY M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_STOP_BAND, M_PASS_BAND, M_LINEARITY, M_AM, M_FM
}; };
enum { enum {

156
plot.c

@ -29,7 +29,8 @@
#ifdef __SCROLL__ #ifdef __SCROLL__
uint16_t _grid_y = NOSCROLL_GRIDY; uint16_t _grid_y = (CHART_BOTTOM / NGRIDY);
uint16_t graph_bottom = CHART_BOTTOM;
static int waterfall = false; static int waterfall = false;
#endif #endif
static void cell_draw_marker_info(int x0, int y0); static void cell_draw_marker_info(int x0, int y0);
@ -41,6 +42,7 @@ void cell_draw_test_info(int x0, int y0);
static int16_t grid_offset; static int16_t grid_offset;
static int16_t grid_width; static int16_t grid_width;
static int32_t grid_span;
int16_t area_width = AREA_WIDTH_NORMAL; int16_t area_width = AREA_WIDTH_NORMAL;
int16_t area_height; // initialized in main() = AREA_HEIGHT_NORMAL; int16_t area_height; // initialized in main() = AREA_HEIGHT_NORMAL;
@ -126,24 +128,29 @@ void update_grid(void)
fspan = setting.actual_sweep_time_us; // Time in uS fspan = setting.actual_sweep_time_us; // Time in uS
fstart = 0; fstart = 0;
} }
if (config.gridlines < 3)
config.gridlines = 6;
while (gdigit > 100) { while (gdigit > 100) {
grid = 5 * gdigit; grid = 5 * gdigit;
if (fspan / grid >= 4) if (fspan / grid >= config.gridlines)
break; break;
grid = 2 * gdigit; grid = 2 * gdigit;
if (fspan / grid >= 4) if (fspan / grid >= config.gridlines)
break; break;
grid = gdigit; grid = gdigit;
if (fspan / grid >= 4) if (fspan / grid >= config.gridlines)
break; break;
gdigit /= 10; gdigit /= 10;
} }
grid_span = grid;
grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100); grid_offset = (WIDTH) * ((fstart % grid) / 100) / (fspan / 100);
grid_width = (WIDTH) * (grid / 100) / (fspan / 1000); grid_width = (WIDTH) * (grid / 100) / (fspan / 1000);
force_set_markmap(); force_set_markmap();
if (get_waterfall())
ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom, 0);
redraw_request |= REDRAW_FREQUENCY; redraw_request |= REDRAW_FREQUENCY;
} }
@ -401,6 +408,51 @@ rectangular_grid(int x, int y)
} }
#endif #endif
#ifdef __HAM_BAND__
typedef const struct {
uint32_t start;
uint32_t stop;
} ham_bands_t;
const ham_bands_t ham_bands[] =
{
{135700, 137800},
{472000, 479000},
{1800000, 2000000},
{3500000, 3800000},
{5250000, 5450000},
{7000000, 7200000},
{10100000, 10150000},
{14000000, 14350000},
{18068000, 18168000},
{21000000, 21450000},
{24890000, 24990000},
{28000000, 29700000},
{50000000, 52000000},
{70000000, 70500000},
{144000000, 146000000}
};
int ham_band(int x) // Search which index in the frequency tabled matches with frequency f using actual_rbw
{
if (!config.hambands)
return false;
uint32_t f = frequencies[x];
int L = 0;
int R = (sizeof ham_bands)/sizeof(uint32_t) - 1;
while (L <= R) {
int m = (L + R) / 2;
if (ham_bands[m].stop < f)
L = m + 1;
else if (ham_bands[m].start > f)
R = m - 1;
else
return true; // index is m
}
return false;
}
#endif
static int static int
rectangular_grid_x(int x) rectangular_grid_x(int x)
{ {
@ -462,30 +514,31 @@ draw_on_strut(int v0, int d, int color)
#define SQRT_50 ((float)7.0710678118654) #define SQRT_50 ((float)7.0710678118654)
#define LOG_10_SQRT_50 ((float)0.84948500216800) #define LOG_10_SQRT_50 ((float)0.84948500216800)
#define POW_30_20 ((float) 0.215443469) #define POW_30_20 ((float) 0.215443469)
#define POW_SQRT 1.5234153789 #define POW_SQRT ((float)1.5234153789)
/* /*
* calculate log10(abs(gamma)) * calculate log10f(abs(gamma))
*/ */
float float
value(const float v) value(const float v)
{ {
switch(setting.unit) switch(setting.unit)
{ {
case U_DBMV: case U_DBMV:
// return v + 30.0 + 20.0*log10(sqrt(50)); // return v + 30.0 + 20.0*log10f(sqrt(50));
return v + 30.0 + 20.0*LOG_10_SQRT_50; //TODO convert constants to single float number as GCC compiler does runtime calculation return v + 30.0 + 20.0*LOG_10_SQRT_50; //TODO convert constants to single float number as GCC compiler does runtime calculation
break; break;
case U_DBUV: case U_DBUV:
// return v + 90.0 + 20.0*log10(sqrt(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation // return v + 90.0 + 20.0*log10f(sqrt(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation
return v + 90.0 + 20.0*LOG_10_SQRT_50; return v + 90.0 + 20.0*LOG_10_SQRT_50;
break; break;
case U_VOLT: case U_VOLT:
// return pow(10, (v-30.0)/20.0) * sqrt(50.0); // return pow(10, (v-30.0)/20.0) * sqrt((float)50.0);
return pow(10, (v-30.0)/20.0)*SQRT_50; return pow((float)10.0, (v-(float)30.0)/(float)20.0)*SQRT_50; // Do NOT change pow to powf as this will increase the size
// return pow(10, v/20.0) * POW_SQRT; //TODO there is an error in this calculation as the outcome is different from the not optimized version // return pow(10, v/20.0) * POW_SQRT; //TODO there is an error in this calculation as the outcome is different from the not optimized version
break; break;
case U_WATT: case U_WATT:
return pow(10, v/10.0)/1000.0; return pow((float)10.0, v/10.0)/1000.0; // Do NOT change pow to powf as this will increase the size
break; break;
} }
// case U_DBM: // case U_DBM:
@ -499,19 +552,19 @@ to_dBm(const float v)
switch(setting.unit) switch(setting.unit)
{ {
case U_DBMV: case U_DBMV:
// return v - 30.0 - 20.0*log10(sqrt(50)); // return v - 30.0 - 20.0*log10f(sqrt(50));
return v - 30.0 - 20.0*LOG_10_SQRT_50; return v - 30.0 - 20.0*LOG_10_SQRT_50;
break; break;
case U_DBUV: case U_DBUV:
// return v - 90.0 - 20.0*log10(sqrt(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation // return v - 90.0 - 20.0*log10f(sqrt(50.0)); //TODO convert constants to single float number as GCC compiler does runtime calculation
return v - 90.0 - 20.0*LOG_10_SQRT_50; return v - 90.0 - 20.0*LOG_10_SQRT_50;
break; break;
case U_VOLT: case U_VOLT:
// return log10( v / (sqrt(50.0))) * 20.0 + 30.0 ; // return log10f( v / (sqrt(50.0))) * 20.0 + 30.0 ;
return log10( v / (SQRT_50)) * 20.0 + 30.0 ; return log10f( v / (SQRT_50)) * 20.0 + 30.0 ;
break; break;
case U_WATT: case U_WATT:
return log10(v*1000.0)*10.0; return log10f(v*1000.0)*10.0;
break; break;
} }
// case U_DBM: // case U_DBM:
@ -842,7 +895,7 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT
extern const char *unit_string[]; extern const char *unit_string[];
static void trace_get_value_string( inline void trace_get_value_string( // Only used at one place
int t, char *buf, int len, int t, char *buf, int len,
int i, float coeff[POINTS_COUNT], int i, float coeff[POINTS_COUNT],
int ri, int mtype, int ri, int mtype,
@ -912,7 +965,7 @@ static void trace_get_value_string(
#endif #endif
v = value(coeff[i]); v = value(coeff[i]);
if (mtype & M_NOISE) if (mtype & M_NOISE)
v = v - 10*log10(actual_rbw_x10*100.0); v = v - 10*log10f(actual_rbw_x10*100.0);
if (v == -INFINITY) if (v == -INFINITY)
plot_printf(buf, len, "-INF"); plot_printf(buf, len, "-INF");
else { else {
@ -1510,6 +1563,11 @@ draw_cell(int m, int n)
// Draw rectangular plot (40 system ticks for all screen calls) // Draw rectangular plot (40 system ticks for all screen calls)
if (trace_type & RECTANGULAR_GRID_MASK) { if (trace_type & RECTANGULAR_GRID_MASK) {
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
#ifdef __HAM_BAND__
if (ham_band(x+x0)) {
for (y = 0; y < h; y++) cell_buffer[y * CELLWIDTH + x] = config.ham_color;
}
#endif
if (rectangular_grid_x(x + x0)) { if (rectangular_grid_x(x + x0)) {
for (y = 0; y < h; y++) cell_buffer[y * CELLWIDTH + x] = c; for (y = 0; y < h; y++) cell_buffer[y * CELLWIDTH + x] = c;
} }
@ -2140,11 +2198,11 @@ draw_frequencies(void)
plot_printf(buf2, sizeof(buf2), " TIME %.3Fs", (float)t/ONE_SECOND_TIME); plot_printf(buf2, sizeof(buf2), " TIME %.3Fs", (float)t/ONE_SECOND_TIME);
} else if (FREQ_IS_STARTSTOP()) { } else if (FREQ_IS_STARTSTOP()) {
plot_printf(buf1, sizeof(buf1), " START %qHz", get_sweep_frequency(ST_START)); plot_printf(buf1, sizeof(buf1), " START %.3qHz %5.1qHz/", get_sweep_frequency(ST_START), grid_span);
plot_printf(buf2, sizeof(buf2), " STOP %qHz", get_sweep_frequency(ST_STOP)); plot_printf(buf2, sizeof(buf2), " STOP %.3qHz", get_sweep_frequency(ST_STOP));
} else if (FREQ_IS_CENTERSPAN()) { } else if (FREQ_IS_CENTERSPAN()) {
plot_printf(buf1, sizeof(buf1), " CENTER %qHz", get_sweep_frequency(ST_CENTER)); plot_printf(buf1, sizeof(buf1), " CENTER %.3qHz %5.1qHz/", get_sweep_frequency(ST_CENTER), grid_span);
plot_printf(buf2, sizeof(buf2), " SPAN %qHz", get_sweep_frequency(ST_SPAN)); plot_printf(buf2, sizeof(buf2), " SPAN %.3qHz", get_sweep_frequency(ST_SPAN));
} }
#ifdef __VNA__ #ifdef __VNA__
} else { } else {
@ -2159,12 +2217,12 @@ draw_frequencies(void)
buf1[0] = S_SARROW[0]; buf1[0] = S_SARROW[0];
if (uistat.lever_mode == LM_SPAN) if (uistat.lever_mode == LM_SPAN)
buf2[0] = S_SARROW[0]; buf2[0] = S_SARROW[0];
int p2 = FREQUENCIES_XPOS2; // int p2 = FREQUENCIES_XPOS2;
if (FREQ_IS_CW()) { // if (FREQ_IS_CW()) {
p2 = LCD_WIDTH - FONT_MAX_WIDTH*strlen(buf2); int p2 = LCD_WIDTH - FONT_MAX_WIDTH*strlen(buf2);
} // }
ili9341_drawstring(buf1, FREQUENCIES_XPOS1, FREQUENCIES_YPOS);
ili9341_drawstring(buf2, p2, FREQUENCIES_YPOS); ili9341_drawstring(buf2, p2, FREQUENCIES_YPOS);
ili9341_drawstring(buf1, FREQUENCIES_XPOS1, FREQUENCIES_YPOS);
} }
#ifdef __VNA__ #ifdef __VNA__
void void
@ -2259,22 +2317,23 @@ static void update_waterfall(void){
int i; int i;
int w_width = area_width < POINTS_COUNT ? area_width : POINTS_COUNT; int w_width = area_width < POINTS_COUNT ? area_width : POINTS_COUNT;
// Waterfall only in 290 or 145 points // Waterfall only in 290 or 145 points
if (!(sweep_points == 290 || sweep_points == 145)) // if (!(sweep_points == 290 || sweep_points == 145))
return; // return;
for (i = HEIGHT_NOSCROLL-1; i >=HEIGHT_SCROLL+2; i--) { // Scroll down for (i = CHART_BOTTOM-1; i >=graph_bottom+1; i--) { // Scroll down
ili9341_read_memory(OFFSETX, i , w_width, 1, w_width*1, spi_buffer); ili9341_read_memory(OFFSETX, i , w_width, 1, w_width*1, spi_buffer);
ili9341_bulk(OFFSETX, i+1, w_width, 1); ili9341_bulk(OFFSETX, i+1, w_width, 1);
} }
index_t *index = trace_index[TRACE_ACTUAL]; index_t *index = trace_index[TRACE_ACTUAL];
for (i=0; i< w_width; i++) { // Add new topline int j = 0;
for (i=0; i< sweep_points; i++) { // Add new topline
uint16_t color; uint16_t color;
#ifdef _USE_WATERFALL_PALETTE #ifdef _USE_WATERFALL_PALETTE
uint16_t y = _PALETTE_ALIGN(CELL_Y(index[i])); // should be always in range 0 - HEIGHT_SCROLL uint16_t y = _PALETTE_ALIGN(CELL_Y(index[i])); // should be always in range 0 - graph_bottom
// y = (uint8_t)i; // for test // y = (uint8_t)i; // for test
color = waterfall_palette[y]; color = waterfall_palette[y];
#elif 0 #elif 0
uint16_t y = CELL_Y(index[i]); // should be always in range 0 - HEIGHT_SCROLL uint16_t y = CELL_Y(index[i]); // should be always in range 0 - graph_bottom
uint16_t ratio = (HEIGHT_SCROLL - y)*2; uint16_t ratio = (graph_bottom - y)*2;
// ratio = (i*2); // Uncomment for testing the waterfall colors // ratio = (i*2); // Uncomment for testing the waterfall colors
int16_t b = 255 - ratio; int16_t b = 255 - ratio;
if (b > 255) b = 255; if (b > 255) b = 255;
@ -2289,7 +2348,7 @@ static void update_waterfall(void){
gamma_correct(b); gamma_correct(b);
color = RGB565(r, g, b); color = RGB565(r, g, b);
#else #else
uint16_t y = CELL_Y(index[i]); // should be always in range 0 - HEIGHT_SCROLL uint16_t y = CELL_Y(index[i])* (graph_bottom == BIG_WATERFALL ? 2 : 1); // should be always in range 0 - graph_bottom *2 depends on height of scroll
// Calculate gradient palette for range 0 .. 192 // Calculate gradient palette for range 0 .. 192
// idx r g b // idx r g b
// 0 - 127 0 0 // 0 - 127 0 0
@ -2309,37 +2368,38 @@ static void update_waterfall(void){
else color = RGB565( 0, 124-((y-160)*4), 252-((y-160)*4)); else color = RGB565( 0, 124-((y-160)*4), 252-((y-160)*4));
#endif #endif
if (sweep_points == 290) while (j * sweep_points < (i+1) * 290) { // Scale waterfall to 290 points
spi_buffer[i] = color; spi_buffer[j++] = color;
else {
spi_buffer[2*i ] = color;
spi_buffer[2*i+1] = color;
} }
} }
ili9341_bulk(OFFSETX, HEIGHT_SCROLL+2, w_width, 1); ili9341_bulk(OFFSETX, graph_bottom+1, w_width, 1);
} }
int get_waterfall(void) int get_waterfall(void)
{ {
return(waterfall); return(waterfall);
} }
enum {W_OFF, W_SMALL, W_BIG};
void void
toggle_waterfall(void) toggle_waterfall(void)
{ {
if (!waterfall) { if (waterfall == W_OFF) {
_grid_y = SCROLL_GRIDY;
ili9341_fill(OFFSETX, HEIGHT_SCROLL, LCD_WIDTH - OFFSETX, HEIGHT_NOSCROLL - HEIGHT_SCROLL, 0);
waterfall = true;
w_min = (int)min_level; w_min = (int)min_level;
w_max = (int)peakLevel; w_max = (int)peakLevel;
if (w_max < w_min + 20) if (w_max < w_min + 20)
w_max = w_min + 20; w_max = w_min + 20;
graph_bottom = SMALL_WATERFALL;
waterfall = W_SMALL;
} else if (waterfall == W_SMALL) {
graph_bottom = BIG_WATERFALL;
waterfall = W_BIG;
} else { } else {
_grid_y = NOSCROLL_GRIDY; graph_bottom = NO_WATERFALL;
waterfall = false; waterfall = W_OFF;
} }
_grid_y = graph_bottom / NGRIDY;
ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom, 0);
request_to_redraw_grid(); request_to_redraw_grid();
} }
void void

@ -14,6 +14,8 @@
* the Free Software Foundation, Inc., 51 Franklin Street, * the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*/ */
#pragma GCC push_options
#pragma GCC optimize ("Os")
static int VFO = 0; static int VFO = 0;
@ -62,7 +64,7 @@ VNA_SHELL_FUNCTION(cmd_modulation )
shell_printf("usage: modulation %s\r\n", cmd_mod); shell_printf("usage: modulation %s\r\n", cmd_mod);
return; return;
} }
static const int cmd_mod_val[] = { MO_NONE, MO_AM_1kHz, MO_AM_10Hz, MO_NFM, MO_WFM, MO_EXTERNAL}; static const int cmd_mod_val[] = { MO_NONE, MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL};
int m = get_str_index(argv[1], cmd_mod); int m = get_str_index(argv[1], cmd_mod);
if (m<0) if (m<0)
goto usage; goto usage;
@ -633,4 +635,20 @@ VNA_SHELL_FUNCTION(cmd_scanraw)
redraw_request = 0; // disable screen update in this mode redraw_request = 0; // disable screen update in this mode
} }
VNA_SHELL_FUNCTION(cmd_caloutput)
{
static const char cmd[] = "off|30|15|10|4|3|2|1";
if (argc != 1) {
usage:
shell_printf("usage: caloutput %s\r\n", cmd);
return;
}
int m = get_str_index(argv[0], cmd);
if (m != -1)
set_refer_output(m - 1);
}
#pragma GCC pop_options

@ -16,9 +16,9 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*/ */
//#ifdef __SI4432__ #ifdef __SI4432__
#include "SI4432.h" // comment out for simulation #include "si4432.h" // comment out for simulation
//#endif #endif
#include "stdlib.h" #include "stdlib.h"
#pragma GCC push_options #pragma GCC push_options
@ -62,10 +62,44 @@ this is a very long string only used to fill memory so I know when the memory is
; ;
#endif #endif
void update_min_max_freq(void)
{
switch(setting.mode) {
case M_LOW:
minFreq = 0;
maxFreq = 350000000;
break;
#ifdef __ULTRA__
case M_ULTRA:
minFreq = 674000000;
maxFreq = 4300000000;
break;
#endif
case M_GENLOW:
minFreq = 0;
maxFreq = 350000000;
break;
case M_HIGH:
#ifdef __ULTRA_SA__
minFreq = 00000000;
maxFreq = 2000000000;
#else
minFreq = 24*setting_frequency_10mhz;
maxFreq = 96*setting_frequency_10mhz;
#endif
break;
case M_GENHIGH:
minFreq = 240000000;
maxFreq = 960000000;
break;
}
}
void reset_settings(int m) void reset_settings(int m)
{ {
// strcpy((char *)spi_buffer, dummy); // strcpy((char *)spi_buffer, dummy);
setting.mode = m; setting.mode = m;
update_min_max_freq();
sweep_mode |= SWEEP_ENABLE; sweep_mode |= SWEEP_ENABLE;
setting.unit_scale_index = 0; setting.unit_scale_index = 0;
setting.unit_scale = 1; setting.unit_scale = 1;
@ -86,6 +120,7 @@ void reset_settings(int m)
setting.lna = S_AUTO_OFF; setting.lna = S_AUTO_OFF;
setting.tracking = false; setting.tracking = false;
setting.modulation = MO_NONE; setting.modulation = MO_NONE;
setting.modulation_frequency = 1000;
setting.step_delay = 0; setting.step_delay = 0;
setting.offset_delay = 0; setting.offset_delay = 0;
setting.step_delay_mode = SD_NORMAL; setting.step_delay_mode = SD_NORMAL;
@ -127,18 +162,14 @@ void reset_settings(int m)
break; break;
#ifdef __ULTRA__ #ifdef __ULTRA__
case M_ULTRA: case M_ULTRA:
minFreq = 674000000; set_sweep_frequency(ST_START, minFreq);
maxFreq = 4300000000; set_sweep_frequency(ST_STOP, maxFreq);
set_sweep_frequency(ST_START, (uint32_t) minFreq);
set_sweep_frequency(ST_STOP, (uint32_t) maxFreq);
setting.attenuate = 0; setting.attenuate = 0;
setting.sweep_time_us = 0; setting.sweep_time_us = 0;
break; break;
#endif #endif
case M_GENLOW: case M_GENLOW:
setting.drive=8; setting.drive=8;
minFreq = 0;
maxFreq = 350000000;
set_sweep_frequency(ST_CENTER, 10000000); set_sweep_frequency(ST_CENTER, 10000000);
set_sweep_frequency(ST_SPAN, 0); set_sweep_frequency(ST_SPAN, 0);
setting.sweep_time_us = 10*ONE_SECOND_TIME; setting.sweep_time_us = 10*ONE_SECOND_TIME;
@ -157,8 +188,6 @@ void reset_settings(int m)
break; break;
case M_GENHIGH: case M_GENHIGH:
setting.drive=8; setting.drive=8;
minFreq = 240000000;
maxFreq = 960000000;
set_sweep_frequency(ST_CENTER, 300000000); set_sweep_frequency(ST_CENTER, 300000000);
set_sweep_frequency(ST_SPAN, 0); set_sweep_frequency(ST_SPAN, 0);
setting.sweep_time_us = 10*ONE_SECOND_TIME; setting.sweep_time_us = 10*ONE_SECOND_TIME;
@ -203,7 +232,10 @@ uint32_t calc_min_sweep_time_us(void) // Estimate minimum sweep time in
void set_refer_output(int v) void set_refer_output(int v)
{ {
setting.refer = v; setting.refer = v;
dirty = true; #ifdef __SI4432__
SI4432_SetReference(setting.refer);
#endif
// dirty = true;
} }
void set_decay(int d) void set_decay(int d)
@ -222,6 +254,16 @@ void set_noise(int d)
dirty = true; dirty = true;
} }
void set_gridlines(int d)
{
if (d < 3 || d > 20)
return;
config.gridlines = d;
config_save();
dirty = true;
update_grid();
}
void set_measurement(int m) void set_measurement(int m)
{ {
setting.measurement = m; setting.measurement = m;
@ -292,6 +334,12 @@ void toggle_mute(void)
dirty = true; dirty = true;
} }
void toggle_hambands(void)
{
config.hambands = !config.hambands;
dirty = true;
}
void toggle_below_IF(void) void toggle_below_IF(void)
{ {
if (S_IS_AUTO(setting.below_IF )) if (S_IS_AUTO(setting.below_IF ))
@ -309,6 +357,14 @@ void set_modulation(int m)
dirty = true; dirty = true;
} }
void set_modulation_frequency(int f)
{
if (100 <= f && f <= 6000) {
setting.modulation_frequency = f;
dirty = true;
}
}
void set_repeat(int r) void set_repeat(int r)
{ {
if (r > 0 && r <= 100) { if (r > 0 && r <= 100) {
@ -1373,6 +1429,7 @@ search_maximum(int m, int center, int span)
} }
} }
markers[m].index = max_index[0]; markers[m].index = max_index[0];
markers[m].frequency = frequencies[markers[m].index];
return found; return found;
} }
@ -1479,9 +1536,25 @@ int avoid_spur(int f) // find if this frequency should be avoi
static int modulation_counter = 0; static int modulation_counter = 0;
static const int am_modulation[5] = { 4,0,1,5,7 }; // 5 step AM modulation #define MODULATION_STEPS 8
static const int nfm_modulation[5] = { 0, 2, 1, -1, -2}; // 5 step narrow FM modulation static const int am_modulation[MODULATION_STEPS] = { 5, 1, 0, 1, 5, 9, 11, 9 }; // AM modulation
static const int wfm_modulation[5] = { 0, 190, 118, -118, -190 }; // 5 step wide FM modulation //
// Offset is 156.25Hz when below 600MHz and 312.5 when above.
//
#define LND 16 // Total NFM deviation is LND * 4 * 156.25 = 5kHz when below 600MHz or 600MHz - 434MHz
#define HND 8
#define LWD 96 // Total WFM deviation is LWD * 4 * 156.25 = 30kHz when below 600MHz
#define HWD 48
static const int fm_modulation[4][MODULATION_STEPS] = // Avoid sign changes in NFM
{
{ 2*LND,(int)( 3.5*LND ), 4*LND, (int)(3.5*LND), 2*LND, (int)(0.5*LND), 0, (int)(0.5*LND)},
{ 0*LWD,(int)( 1.5*LWD ), 2*LWD, (int)(1.5*LWD), 0*LWD, (int)(-1.5*LWD), (int)-2*LWD, (int)(-1.5*LWD)},
{ 2*HND,(int)( 3.5*HND ), 4*HND, (int)(3.5*HND), 2*HND, (int)(0.5*HND), 0, (int)(0.5*HND)},
{ 0*HWD,(int)( 1.5*HWD ), 2*HWD, (int)(1.5*HWD), 0*HWD, (int)(-1.5*HWD), (int)-2*HWD, (int)(-1.5*HWD)},
}; // narrow FM modulation avoid sign changes
static const int fm_modulation_offset[4] = { LND*625/2, 0, LND*625/2, 0};
deviceRSSI_t age[POINTS_COUNT]; // Array used for 1: calculating the age of any max and 2: buffer for fast sweep RSSI values; deviceRSSI_t age[POINTS_COUNT]; // Array used for 1: calculating the age of any max and 2: buffer for fast sweep RSSI values;
@ -1493,6 +1566,8 @@ static systime_t sweep_elapsed = 0; // Time since fi
pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking) // Measure the RSSI for one frequency, used from sweep and other measurement routines. Must do all HW setup pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking) // Measure the RSSI for one frequency, used from sweep and other measurement routines. Must do all HW setup
{ {
int modulation_delay = 0;
int modulation_index = 0;
if (i == 0 && dirty ) { // if first point in scan and dirty if (i == 0 && dirty ) { // if first point in scan and dirty
calculate_correction(); // pre-calculate correction factor dividers to avoid float division calculate_correction(); // pre-calculate correction factor dividers to avoid float division
apply_settings(); // Initialize HW apply_settings(); // Initialize HW
@ -1532,7 +1607,6 @@ pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking)
+ get_attenuation() + get_attenuation()
- setting.offset); - setting.offset);
} }
// if (MODE_OUTPUT(setting.mode) && setting.additional_step_delay_us < 500) // Minimum wait time to prevent LO from lockup during output frequency sweep // if (MODE_OUTPUT(setting.mode) && setting.additional_step_delay_us < 500) // Minimum wait time to prevent LO from lockup during output frequency sweep
// setting.additional_step_delay_us = 500; // setting.additional_step_delay_us = 500;
// Update grid and status after // Update grid and status after
@ -1595,39 +1669,59 @@ pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking)
else else
auto_set_AGC_LNA(true, 0); auto_set_AGC_LNA(true, 0);
} }
// Calculate the RSSI correction for later use
if (MODE_INPUT(setting.mode)){ // only cases where the value can change on 0 point of sweep
if (i == 0 || setting.frequency_step != 0)
correct_RSSI_freq = get_frequency_correction(f);
}
int *current_fm_modulation;
if (MODE_OUTPUT(setting.mode)) {
if (setting.modulation != MO_NONE && setting.modulation != MO_EXTERNAL && setting.modulation_frequency != 0) {
modulation_delay = (1000000/ MODULATION_STEPS ) / setting.modulation_frequency; // 5 steps so 1MHz/5
modulation_counter = 0;
if (setting.modulation == MO_AM) // -14 default
modulation_delay += config.cor_am;
else { // must be FM
if (setting.modulation == MO_WFM) { // -17 default
modulation_delay += config.cor_wfm;
modulation_index = 1;
} else { // must be NFM
modulation_delay += config.cor_nfm; // -17 default
// modulation_index = 0; // default value
}
if ((setting.mode == M_GENLOW && f > 480000000 - 433000000) ||
(setting.mode == M_GENHIGH && f > 480000000) )
modulation_index += 2;
current_fm_modulation = (int *)fm_modulation[modulation_index];
f -= fm_modulation_offset[modulation_index]; // Shift output frequency
}
}
}
modulation_again: modulation_again:
// ----------------------------------------------------- modulation for output modes --------------------------------------- // ----------------------------------------------------- modulation for output modes ---------------------------------------
if (MODE_OUTPUT(setting.mode)){ if (MODE_OUTPUT(setting.mode)){
if (setting.modulation == MO_AM_1kHz || setting.modulation == MO_AM_10Hz) { // AM modulation if (setting.modulation == MO_AM) { // AM modulation
int p = setting.attenuate * 2 + am_modulation[modulation_counter++]; int p = setting.attenuate * 2 + am_modulation[modulation_counter];
if (p>63) p = 63; if (p>63) p = 63;
else if (p< 0) p = 0; else if (p< 0) p = 0;
#ifdef __PE4302__ #ifdef __PE4302__
PE4302_Write_Byte(p); PE4302_Write_Byte(p);
#endif #endif
if (modulation_counter == 5) // 3dB modulation depth
modulation_counter = 0;
my_microsecond_delay(setting.modulation == MO_AM_10Hz ? 20000 : 180);
} }
else if (setting.modulation == MO_NFM || setting.modulation == MO_WFM ) { //FM modulation else if (setting.modulation == MO_NFM || setting.modulation == MO_WFM ) { //FM modulation
#ifdef __SI4432__ #ifdef __SI4432__
SI4432_Sel = SI4432_LO ; SI4432_Sel = SI4432_LO ;
int offset = setting.modulation == MO_NFM ? nfm_modulation[modulation_counter] : wfm_modulation[modulation_counter] ; int offset = current_fm_modulation[modulation_counter];
SI4432_Write_Byte(SI4432_FREQ_OFFSET1, (offset & 0xff )); // Use frequency hopping channel for FM modulation SI4432_Write_2_Byte(SI4432_FREQ_OFFSET1, (offset & 0xff ), ((offset >> 8) & 0x03 )); // Use frequency hopping channel for FM modulation
SI4432_Write_Byte(SI4432_FREQ_OFFSET2, ((offset >> 8) & 0x03 )); // Use frequency hopping channel for FM modulation // SI4432_Write_Byte(SI4432_FREQ_OFFSET2, ); // Use frequency hopping channel for FM modulation
#endif #endif
modulation_counter++;
if (modulation_counter == 5) // 3dB modulation depth
modulation_counter = 0;
my_microsecond_delay(200);
// chThdSleepMicroseconds(200);
} }
} modulation_counter++;
if (modulation_counter == MODULATION_STEPS) // 3dB modulation depth
// Calculate the RSSI correction for later use modulation_counter = 0;
if (MODE_INPUT(setting.mode)){ // only cases where the value can change on 0 point of sweep if (setting.modulation != MO_NONE && setting.modulation != MO_EXTERNAL) {
if (i == 0 || setting.frequency_step != 0) my_microsecond_delay(modulation_delay);
correct_RSSI_freq = get_frequency_correction(f); }
} }
// -------------------------------- Acquisition loop for one requested frequency covering spur avoidance and vbwsteps ------------------------ // -------------------------------- Acquisition loop for one requested frequency covering spur avoidance and vbwsteps ------------------------
@ -1794,9 +1888,10 @@ modulation_again:
if (MODE_OUTPUT(setting.mode)) { // No substepping and no RSSI in output mode if (MODE_OUTPUT(setting.mode)) { // No substepping and no RSSI in output mode
if (break_on_operation && operation_requested) // break subscanning if requested if (break_on_operation && operation_requested) // break subscanning if requested
return(0); // abort return(0); // abort
if (MODE_OUTPUT(setting.mode) && setting.modulation != MO_NONE && setting.modulation != MO_EXTERNAL) // if in output mode with modulation if (MODE_OUTPUT(setting.mode) && setting.modulation != MO_NONE && setting.modulation != MO_EXTERNAL) { // if in output mode with modulation
i = 1; // Everything set so skip LO setting
goto modulation_again; // Keep repeating sweep loop till user aborts by input goto modulation_again; // Keep repeating sweep loop till user aborts by input
}
return(0); return(0);
} }
// ---------------- Prepare RSSI ---------------------- // ---------------- Prepare RSSI ----------------------
@ -1959,7 +2054,7 @@ sweep_again: // stay in sweep loop when output mo
scandirty = false; scandirty = false;
if (break_on_operation && operation_requested) { // break loop if needed if (break_on_operation && operation_requested) { // break loop if needed
if (setting.actual_sweep_time_us > ONE_SECOND_TIME && MODE_INPUT(setting.mode)) { if (setting.actual_sweep_time_us > ONE_SECOND_TIME && MODE_INPUT(setting.mode)) {
ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, WIDTH, 1, 0); // Erase progress bar ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1, 0); // Erase progress bar
} }
return false; return false;
} }
@ -1999,8 +2094,8 @@ sweep_again: // stay in sweep loop when output mo
if (setting.actual_sweep_time_us > ONE_SECOND_TIME && (i & 0x07) == 0) { // if required if (setting.actual_sweep_time_us > ONE_SECOND_TIME && (i & 0x07) == 0) { // if required
int pos = i * (WIDTH+1) / sweep_points; int pos = i * (WIDTH+1) / sweep_points;
ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, pos, 1, BRIGHT_COLOR_GREEN); // update sweep progress bar ili9341_fill(OFFSETX, CHART_BOTTOM+1, pos, 1, BRIGHT_COLOR_GREEN); // update sweep progress bar
ili9341_fill(OFFSETX+pos, HEIGHT_NOSCROLL+1, WIDTH-pos, 1, 0); ili9341_fill(OFFSETX+pos, CHART_BOTTOM+1, WIDTH-pos, 1, 0);
} }
// ------------------------ do all RSSI calculations from CALC menu ------------------- // ------------------------ do all RSSI calculations from CALC menu -------------------
@ -2198,7 +2293,7 @@ sweep_again: // stay in sweep loop when output mo
setting.atten_step = false; // No step attenuate in low mode auto attenuate setting.atten_step = false; // No step attenuate in low mode auto attenuate
int changed = false; int changed = false;
int delta = 0; int delta = 0;
int actual_max_level = (int) (actual_t[max_index[0]] - get_attenuation()); int actual_max_level = (max_index[0] == 0 ? -100 :(int) (actual_t[max_index[0]] - get_attenuation()) ); // If no max found reduce attenuation
if (actual_max_level < AUTO_TARGET_LEVEL && setting.attenuate > 0) { if (actual_max_level < AUTO_TARGET_LEVEL && setting.attenuate > 0) {
delta = - (AUTO_TARGET_LEVEL - actual_max_level); delta = - (AUTO_TARGET_LEVEL - actual_max_level);
} else if (actual_max_level > AUTO_TARGET_LEVEL && setting.attenuate < 30) { } else if (actual_max_level > AUTO_TARGET_LEVEL && setting.attenuate < 30) {
@ -2354,27 +2449,51 @@ sweep_again: // stay in sweep loop when output mo
} }
uint32_t lf = frequencies[l]; uint32_t lf = frequencies[l];
uint32_t rf = frequencies[r]; uint32_t rf = frequencies[r];
markers[0].frequency = lf;
markers[1].frequency = rf;
markers[2].enabled = search_maximum(2, lf - (rf - lf), 12); markers[2].enabled = search_maximum(2, lf - (rf - lf), 12);
markers[3].enabled = search_maximum(3, rf + (rf - lf), 12); markers[3].enabled = search_maximum(3, rf + (rf - lf), 12);
} else if (setting.measurement == M_PHASE_NOISE && markers[0].index > 10) { // ------------Phase noise measurement } else if (setting.measurement == M_PHASE_NOISE && markers[0].index > 10) { // ------------Phase noise measurement
markers[1].index = markers[0].index + (setting.mode == M_LOW ? 290/4 : -290/4); // Position phase noise marker at requested offset markers[1].index = markers[0].index + (setting.mode == M_LOW ? 290/4 : -290/4); // Position phase noise marker at requested offset
markers[1].frequency = frequencies[markers[1].index];
} else if (setting.measurement == M_STOP_BAND && markers[0].index > 10) { // -------------Stop band measurement } else if (setting.measurement == M_STOP_BAND && markers[0].index > 10) { // -------------Stop band measurement
markers[1].index = marker_search_left_min(markers[0].index); markers[1].index = marker_search_left_min(markers[0].index);
if (markers[1].index < 0) markers[1].index = 0; if (markers[1].index < 0) markers[1].index = 0;
markers[1].frequency = frequencies[markers[1].index];
markers[2].index = marker_search_right_min(markers[0].index); markers[2].index = marker_search_right_min(markers[0].index);
if (markers[2].index < 0) markers[1].index = setting._sweep_points - 1; if (markers[2].index < 0) markers[1].index = setting._sweep_points - 1;
markers[2].frequency = frequencies[markers[2].index];
} else if (setting.measurement == M_PASS_BAND && markers[0].index > 10) { // ----------------Pass band measurement } else if (setting.measurement == M_PASS_BAND && markers[0].index > 10) { // ----------------Pass band measurement
int t = markers[0].index; int t = markers[0].index;
float v = actual_t[t]; float v = actual_t[t];
while (t > 0 && actual_t[t] > v - 3.0) // Find left -3dB point while (t > 0 && actual_t[t] > v - 6.0) // Find left -3dB point
t --; t --;
if (t > 0) if (t > 0) {
markers[1].index = t; markers[1].index = t;
markers[1].frequency = frequencies[t];
}
t = markers[0].index; t = markers[0].index;
while (t < setting._sweep_points - 1 && actual_t[t] > v - 3.0) // find right -3dB point while (t < setting._sweep_points - 1 && actual_t[t] > v - 6.0) // find right -3dB point
t ++; t ++;
if (t < setting._sweep_points - 1 ) if (t < setting._sweep_points - 1 ) {
markers[2].index = t; markers[2].index = t;
markers[2].frequency = frequencies[t];
}
} else if (setting.measurement == M_AM) { // ----------------AM measurement
if (S_IS_AUTO(setting.agc )) {
if (actual_t[max_index[0]] - get_attenuation() > -20 ) {
setting.agc = S_AUTO_OFF;
setting.lna = S_AUTO_OFF;
} else if (actual_t[max_index[0]] - get_attenuation() < -45 ) {
setting.agc = S_AUTO_ON;
setting.lna = S_AUTO_ON;
} else {
setting.agc = S_AUTO_OFF;
setting.lna = S_AUTO_ON;
}
set_AGC_LNA();
}
} }
#endif #endif
@ -2437,7 +2556,7 @@ sweep_again: // stay in sweep loop when output mo
// redraw_marker(peak_marker, FALSE); // redraw_marker(peak_marker, FALSE);
// STOP_PROFILE; // STOP_PROFILE;
ili9341_fill(OFFSETX, HEIGHT_NOSCROLL+1, WIDTH, 1, 0); ili9341_fill(OFFSETX, CHART_BOTTOM+1, WIDTH, 1, 0);
palSetPad(GPIOC, GPIOC_LED); palSetPad(GPIOC, GPIOC_LED);
return true; return true;
@ -2632,7 +2751,7 @@ void draw_cal_status(void)
rounding = true; rounding = true;
const char * const unit = unit_string[setting.unit]; const char * const unit = unit_string[setting.unit];
ili9341_fill(0, 0, OFFSETX, HEIGHT_NOSCROLL, 0x0000); ili9341_fill(0, 0, OFFSETX, CHART_BOTTOM, 0x0000);
if (MODE_OUTPUT(setting.mode)) { // No cal status during output if (MODE_OUTPUT(setting.mode)) { // No cal status during output
return; return;
} }
@ -2925,24 +3044,24 @@ void draw_cal_status(void)
ili9341_drawstring(buf, x, y); ili9341_drawstring(buf, x, y);
// ili9341_set_background(DEFAULT_BG_COLOR); // ili9341_set_background(DEFAULT_BG_COLOR);
if (!get_waterfall()) { // Do not draw bottom level if in waterfall mode
// Bottom level // Bottom level
y = area_height - 8 + OFFSETY; y = area_height - 8 + OFFSETY;
if (rounding) if (rounding)
plot_printf(buf, BLEN, "%4d", (int)(yMax - setting.scale * NGRIDY)); plot_printf(buf, BLEN, "%4d", (int)(yMax - setting.scale * NGRIDY));
else
plot_printf(buf, BLEN, "%+4.3F", ((yMax - setting.scale * NGRIDY)/setting.unit_scale));
// buf[5]=0;
if (level_is_calibrated())
if (setting.auto_reflevel)
color = DEFAULT_FG_COLOR;
else else
color = BRIGHT_COLOR_GREEN; plot_printf(buf, BLEN, "%+4.3F", ((yMax - setting.scale * NGRIDY)/setting.unit_scale));
else // buf[5]=0;
color = BRIGHT_COLOR_RED; if (level_is_calibrated())
ili9341_set_foreground(color); if (setting.auto_reflevel)
ili9341_drawstring(buf, x, y); color = DEFAULT_FG_COLOR;
else
color = BRIGHT_COLOR_GREEN;
else
color = BRIGHT_COLOR_RED;
ili9341_set_foreground(color);
ili9341_drawstring(buf, x, y);
}
} }
// -------------------- Self testing ------------------------------------------------- // -------------------- Self testing -------------------------------------------------
@ -2952,10 +3071,10 @@ enum {
}; };
enum { enum {
TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_10MHZ_SWITCH, TP_30MHZ, TPH_30MHZ TP_SILENT, TPH_SILENT, TP_10MHZ, TP_10MHZEXTRA, TP_10MHZ_SWITCH, TP_30MHZ, TPH_30MHZ, TPH_30MHZ_SWITCH
}; };
#define TEST_COUNT 17 #define TEST_COUNT 19
#define W2P(w) (sweep_points * w / 100) // convert width in % to actual sweep points #define W2P(w) (sweep_points * w / 100) // convert width in % to actual sweep points
@ -2973,6 +3092,7 @@ static const struct {
{TC_BELOW, TP_SILENT, 0.015, 0.01, -30, 0, 0}, // 2 Phase noise of zero Hz {TC_BELOW, TP_SILENT, 0.015, 0.01, -30, 0, 0}, // 2 Phase noise of zero Hz
{TC_SIGNAL, TP_10MHZ, 20, 7, -39, 10, -90 }, // 3 {TC_SIGNAL, TP_10MHZ, 20, 7, -39, 10, -90 }, // 3
{TC_SIGNAL, TP_10MHZ, 30, 7, -34, 10, -90 }, // 4 {TC_SIGNAL, TP_10MHZ, 30, 7, -34, 10, -90 }, // 4
#define TEST_SILENCE 4
{TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 5 Wide band noise floor low mode {TC_BELOW, TP_SILENT, 200, 100, -75, 0, 0}, // 5 Wide band noise floor low mode
{TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 6 Wide band noise floor high mode {TC_BELOW, TPH_SILENT, 600, 720, -75, 0, 0}, // 6 Wide band noise floor high mode
{TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 27, -80 }, // 7 BPF loss and stop band {TC_SIGNAL, TP_10MHZEXTRA, 10, 8, -20, 27, -80 }, // 7 BPF loss and stop band
@ -2980,14 +3100,20 @@ static const struct {
{TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -75}, // 9 LPF cutoff {TC_BELOW, TP_30MHZ, 430, 60, -75, 0, -75}, // 9 LPF cutoff
{TC_SIGNAL, TP_10MHZ_SWITCH,20, 7, -39, 10, -60 }, // 10 Switch isolation using high attenuation {TC_SIGNAL, TP_10MHZ_SWITCH,20, 7, -39, 10, -60 }, // 10 Switch isolation using high attenuation
{TC_END, 0, 0, 0, 0, 0, 0}, {TC_END, 0, 0, 0, 0, 0, 0},
#define TEST_POWER 11
{TC_MEASURE, TP_30MHZ, 30, 7, -25, 10, -55 }, // 12 Measure power level and noise {TC_MEASURE, TP_30MHZ, 30, 7, -25, 10, -55 }, // 12 Measure power level and noise
{TC_MEASURE, TP_30MHZ, 270, 4, -50, 10, -75 }, // 13 Measure powerlevel and noise {TC_MEASURE, TP_30MHZ, 270, 4, -50, 10, -75 }, // 13 Measure powerlevel and noise
{TC_MEASURE, TPH_30MHZ, 270, 4, -40, 10, -65 }, // 14 Calibrate power high mode {TC_MEASURE, TPH_30MHZ, 270, 4, -40, 10, -65 }, // 14 Calibrate power high mode
{TC_END, 0, 0, 0, 0, 0, 0}, {TC_END, 0, 0, 0, 0, 0, 0},
#define TEST_RBW 15
{TC_MEASURE, TP_30MHZ, 30, 1, -20, 10, -60 }, // 16 Measure RBW step time {TC_MEASURE, TP_30MHZ, 30, 1, -20, 10, -60 }, // 16 Measure RBW step time
{TC_END, 0, 0, 0, 0, 0, 0}, {TC_END, 0, 0, 0, 0, 0, 0},
{TC_MEASURE, TPH_30MHZ, 300, 4, -48, 10, -65 }, // 14 Calibrate power high mode
{TC_MEASURE, TPH_30MHZ_SWITCH,300, 4, -40, 10, -65 }, // 14 Calibrate power high mode
}; };
enum { enum {
TS_WAITING, TS_PASS, TS_FAIL, TS_CRITICAL TS_WAITING, TS_PASS, TS_FAIL, TS_CRITICAL
}; };
@ -3232,11 +3358,14 @@ common_silent:
set_mode(M_LOW); set_mode(M_LOW);
maxFreq = 520000000; // needed to measure the LPF rejection maxFreq = 520000000; // needed to measure the LPF rejection
set_refer_output(0); set_refer_output(0);
dirty = true;
// set_step_delay(1); // Do not set !!!!! // set_step_delay(1); // Do not set !!!!!
#ifdef __SPUR__ #ifdef __SPUR__
setting.spur_removal = 1; setting.spur_removal = 1;
#endif #endif
goto common; goto common;
case TPH_30MHZ_SWITCH:
case TPH_30MHZ: case TPH_30MHZ:
set_mode(M_HIGH); set_mode(M_HIGH);
set_refer_output(0); set_refer_output(0);
@ -3246,6 +3375,10 @@ common_silent:
case TP_10MHZ_SWITCH: case TP_10MHZ_SWITCH:
set_attenuation(32); // This forces the switch to transmit so isolation can be tested set_attenuation(32); // This forces the switch to transmit so isolation can be tested
break; break;
case TPH_30MHZ_SWITCH:
set_attenuation(0);
setting.atten_step = true; // test high switch isolation
break;
default: default:
set_attenuation(0.0); set_attenuation(0.0);
} }
@ -3329,7 +3462,7 @@ void self_test(int test)
float p2, p1, p; float p2, p1, p;
in_selftest = true; // Spur search in_selftest = true; // Spur search
reset_settings(M_LOW); reset_settings(M_LOW);
test_prepare(4); test_prepare(TEST_SILENCE);
setting.auto_IF = false; setting.auto_IF = false;
setting.frequency_IF=433000000; setting.frequency_IF=433000000;
setting.frequency_step = 30000; setting.frequency_step = 30000;
@ -3368,18 +3501,17 @@ void self_test(int test)
} else if (test == 2) { // Attenuator test } else if (test == 2) { // Attenuator test
in_selftest = true; in_selftest = true;
reset_settings(M_LOW); reset_settings(M_LOW);
int i = 15; // calibrate attenuator at 30 MHz;
float reference_peak_level = 0; float reference_peak_level = 0;
test_prepare(i); test_prepare(TEST_RBW);
for (int j= 0; j < 50; j++ ) { for (int j= 0; j < 50; j++ ) {
test_prepare(i); test_prepare(TEST_RBW);
set_RBW(300); set_RBW(300);
set_attenuation((float)j); set_attenuation((float)j);
float summed_peak_level = 0; float summed_peak_level = 0;
for (int k=0; k<10; k++) { for (int k=0; k<10; k++) {
test_acquire(i); // Acquire test test_acquire(TEST_RBW); // Acquire test
test_validate(i); // Validate test test_validate(TEST_RBW); // Validate test
summed_peak_level += peakLevel; summed_peak_level += peakLevel;
} }
peakLevel = summed_peak_level / 10; peakLevel = summed_peak_level / 10;
@ -3394,15 +3526,13 @@ void self_test(int test)
setting.auto_IF = false; setting.auto_IF = false;
setting.frequency_IF=433900000; setting.frequency_IF=433900000;
ui_mode_normal(); ui_mode_normal();
// int i = 13; // calibrate low mode power on 30 MHz; test_prepare(TEST_RBW);
int i = 15; // calibrate low mode power on 30 MHz;
test_prepare(i);
setting.step_delay = 8000; setting.step_delay = 8000;
for (int j= 0; j < SI4432_RBW_count; j++ ) { for (int j= 0; j < SI4432_RBW_count; j++ ) {
if (setting.test_argument != 0) if (setting.test_argument != 0)
j = setting.test_argument; j = setting.test_argument;
// do_again: // do_again:
test_prepare(i); test_prepare(TEST_RBW);
setting.spur_removal = 0; setting.spur_removal = 0;
#if 1 // Disable for offset baseline scanning #if 1 // Disable for offset baseline scanning
setting.step_delay_mode = SD_NORMAL; setting.step_delay_mode = SD_NORMAL;
@ -3428,8 +3558,8 @@ void self_test(int test)
else else
set_sweep_frequency(ST_SPAN, (uint32_t)(18000000)); set_sweep_frequency(ST_SPAN, (uint32_t)(18000000));
#endif #endif
test_acquire(i); // Acquire test test_acquire(TEST_RBW); // Acquire test
test_validate(i); // Validate test test_validate(TEST_RBW); // Validate test
// if (test_value == 0) { // if (test_value == 0) {
// setting.step_delay = setting.step_delay * 4 / 5; // setting.step_delay = setting.step_delay * 4 / 5;
// goto do_again; // goto do_again;
@ -3443,7 +3573,7 @@ void self_test(int test)
shell_printf("Start level = %f, ",peakLevel); shell_printf("Start level = %f, ",peakLevel);
#if 1 // Enable for step delay tuning #if 1 // Enable for step delay tuning
while (setting.step_delay > 10 && test_value != 0 && test_value > saved_peakLevel - 0.5) { while (setting.step_delay > 10 && test_value != 0 && test_value > saved_peakLevel - 0.5) {
test_prepare(i); test_prepare(TEST_RBW);
setting.spur_removal = 0; setting.spur_removal = 0;
setting.step_delay_mode = SD_NORMAL; setting.step_delay_mode = SD_NORMAL;
setting.step_delay = setting.step_delay * 4 / 5; setting.step_delay = setting.step_delay * 4 / 5;
@ -3453,8 +3583,8 @@ void self_test(int test)
set_sweep_frequency(ST_SPAN, (uint32_t)(18000000)); set_sweep_frequency(ST_SPAN, (uint32_t)(18000000));
// setting.repeat = 10; // setting.repeat = 10;
test_acquire(i); // Acquire test test_acquire(TEST_RBW); // Acquire test
test_validate(i); // Validate test test_validate(TEST_RBW); // Validate test
// shell_printf(" Step %f, %d",peakLevel, setting.step_delay); // shell_printf(" Step %f, %d",peakLevel, setting.step_delay);
} }
@ -3468,7 +3598,7 @@ void self_test(int test)
test_value = saved_peakLevel; test_value = saved_peakLevel;
if ((uint32_t)(setting.rbw_x10 * 1000) / (sweep_points) < 8000) { // fast mode possible if ((uint32_t)(setting.rbw_x10 * 1000) / (sweep_points) < 8000) { // fast mode possible
while (setting.offset_delay > 0 && test_value != 0 && test_value > saved_peakLevel - 1.5) { while (setting.offset_delay > 0 && test_value != 0 && test_value > saved_peakLevel - 1.5) {
test_prepare(i); test_prepare(TEST_RBW);
setting.step_delay_mode = SD_FAST; setting.step_delay_mode = SD_FAST;
setting.offset_delay /= 2; setting.offset_delay /= 2;
setting.spur_removal = 0; setting.spur_removal = 0;
@ -3477,8 +3607,8 @@ void self_test(int test)
else else
set_sweep_frequency(ST_SPAN, (uint32_t)(18000000)); // Limit to 18MHz set_sweep_frequency(ST_SPAN, (uint32_t)(18000000)); // Limit to 18MHz
// setting.repeat = 10; // setting.repeat = 10;
test_acquire(i); // Acquire test test_acquire(TEST_RBW); // Acquire test
test_validate(i); // Validate test test_validate(TEST_RBW); // Validate test
// shell_printf(" Step %f, %d",peakLevel, setting.step_delay); // shell_printf(" Step %f, %d",peakLevel, setting.step_delay);
} }
} }
@ -3551,16 +3681,15 @@ void calibrate(void)
in_selftest = true; in_selftest = true;
reset_calibration(); reset_calibration();
reset_settings(M_LOW); reset_settings(M_LOW);
int i = 11; // calibrate low mode power on 30 MHz;
for (int j= 0; j < CALIBRATE_RBWS; j++ ) { for (int j= 0; j < CALIBRATE_RBWS; j++ ) {
// set_RBW(power_rbw[j]); // set_RBW(power_rbw[j]);
// set_sweep_points(21); // set_sweep_points(21);
test_prepare(i); test_prepare(TEST_POWER);
setting.step_delay_mode = SD_PRECISE; setting.step_delay_mode = SD_PRECISE;
setting.agc = S_OFF; setting.agc = S_OFF;
setting.lna = S_OFF; setting.lna = S_OFF;
test_acquire(i); // Acquire test test_acquire(TEST_POWER); // Acquire test
local_test_status = test_validate(i); // Validate test local_test_status = test_validate(TEST_POWER); // Validate test
// chThdSleepMilliseconds(1000); // chThdSleepMilliseconds(1000);
if (local_test_status != TS_PASS) { if (local_test_status != TS_PASS) {
ili9341_set_foreground(BRIGHT_COLOR_RED); ili9341_set_foreground(BRIGHT_COLOR_RED);
@ -3573,22 +3702,20 @@ void calibrate(void)
} }
#if 0 // No high input calibration as CAL OUTPUT is unreliable #if 0 // No high input calibration as CAL OUTPUT is unreliable
i = 12; // Measure 270MHz in low mode
set_RBW(100); set_RBW(100);
test_prepare(i); test_prepare(TEST_POWER+1);
test_acquire(i); // Acquire test test_acquire(TEST_POWER+1); // Acquire test
float last_peak_level = peakLevel; float last_peak_level = peakLevel;
local_test_status = test_validate(i); // Validate test local_test_status = test_validate(TEST_POWER+1); // Validate test
chThdSleepMilliseconds(1000); chThdSleepMilliseconds(1000);
config.high_level_offset = 0; /// Preliminary setting config.high_level_offset = 0; /// Preliminary setting
i = 13; // Calibrate 270MHz in high mode
for (int j = 0; j < CALIBRATE_RBWS; j++) { for (int j = 0; j < CALIBRATE_RBWS; j++) {
set_RBW(power_rbw[j]); set_RBW(power_rbw[j]);
test_prepare(i); test_prepare(TEST_POWER+2);
test_acquire(i); // Acquire test test_acquire(TEST_POWER+2); // Acquire test
local_test_status = test_validate(i); // Validate test local_test_status = test_validate(TEST_POWER+2); // Validate test
// if (local_test_status != TS_PASS) { // Do not validate due to variations in SI4432 // if (local_test_status != TS_PASS) { // Do not validate due to variations in SI4432
// ili9341_set_foreground(BRIGHT_COLOR_RED); // ili9341_set_foreground(BRIGHT_COLOR_RED);
// ili9341_drawstring_7x13("Calibration failed", 30, 120); // ili9341_drawstring_7x13("Calibration failed", 30, 120);

@ -254,6 +254,22 @@ void SI4432_Write_Byte(uint8_t ADR, uint8_t DATA )
// SI4432_guard = 0; // SI4432_guard = 0;
} }
void SI4432_Write_2_Byte(uint8_t ADR, uint8_t DATA1, uint8_t DATA2)
{
// if (SI4432_guard)
// while(1) ;
// SI4432_guard = 1;
// SPI2_CLK_LOW;
palClearPad(GPIOC, SI_nSEL[SI4432_Sel]);
// chThdSleepMicroseconds(SELECT_DELAY);
ADR |= 0x80 ; // RW = 1
shiftOut( ADR );
shiftOut( DATA1 );
shiftOut( DATA2 );
palSetPad(GPIOC, SI_nSEL[SI4432_Sel]);
// SI4432_guard = 0;
}
void SI4432_Write_3_Byte(uint8_t ADR, uint8_t DATA1, uint8_t DATA2, uint8_t DATA3 ) void SI4432_Write_3_Byte(uint8_t ADR, uint8_t DATA1, uint8_t DATA2, uint8_t DATA3 )
{ {
set_SPI_mode(SPI_MODE_SI); set_SPI_mode(SPI_MODE_SI);

@ -120,6 +120,7 @@ extern int SI4432_frequency_changed;
extern int SI4432_offset_changed; extern int SI4432_offset_changed;
void SI4432_Write_Byte(uint8_t ADR, uint8_t DATA ); void SI4432_Write_Byte(uint8_t ADR, uint8_t DATA );
void SI4432_Write_2_Byte(uint8_t ADR, uint8_t DATA1, uint8_t DATA2);
uint8_t SI4432_Read_Byte( uint8_t ADR ); uint8_t SI4432_Read_Byte( uint8_t ADR );
void SI4432_Transmit(int d); void SI4432_Transmit(int d);

16
ui.c

@ -190,9 +190,12 @@ static int btn_wait_release(void)
uint16_t changed = last_button ^ cur_button; uint16_t changed = last_button ^ cur_button;
if (dt >= BUTTON_DOWN_LONG_TICKS && (cur_button & (1<<BIT_PUSH))) if (dt >= BUTTON_DOWN_LONG_TICKS && (cur_button & (1<<BIT_PUSH)))
return EVT_BUTTON_DOWN_LONG; return EVT_BUTTON_DOWN_LONG;
else if (changed & (1<<BIT_PUSH)) // release else if (changed & (1<<BIT_PUSH)) { // release
last_button = cur_button;
last_button_down_ticks = ticks;
return EVT_BUTTON_SINGLE_CLICK; return EVT_BUTTON_SINGLE_CLICK;
if (changed) { }
if (changed) {
// finished // finished
last_button = cur_button; last_button = cur_button;
last_button_down_ticks = ticks; last_button_down_ticks = ticks;
@ -1928,6 +1931,8 @@ leave_ui_mode()
// Erase bottom area (not redraw on area update) // Erase bottom area (not redraw on area update)
if (MENU_BUTTON_HEIGHT*MENU_BUTTON_MAX - area_height > 0) if (MENU_BUTTON_HEIGHT*MENU_BUTTON_MAX - area_height > 0)
ili9341_fill(LCD_WIDTH-MENU_BUTTON_WIDTH, area_height, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*MENU_BUTTON_MAX - area_height, DEFAULT_BG_COLOR); ili9341_fill(LCD_WIDTH-MENU_BUTTON_WIDTH, area_height, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*MENU_BUTTON_MAX - area_height, DEFAULT_BG_COLOR);
if (get_waterfall())
ili9341_fill(OFFSETX, graph_bottom, LCD_WIDTH - OFFSETX, CHART_BOTTOM - graph_bottom, 0);
redraw_request|=REDRAW_AREA | REDRAW_FREQUENCY | REDRAW_CAL_STATUS | REDRAW_BATTERY; redraw_request|=REDRAW_AREA | REDRAW_FREQUENCY | REDRAW_CAL_STATUS | REDRAW_BATTERY;
} }
@ -2081,6 +2086,7 @@ lever_move_marker(int status)
} }
markers[active_marker].frequency = frequencies[markers[active_marker].index]; markers[active_marker].frequency = frequencies[markers[active_marker].index];
redraw_marker(active_marker); redraw_marker(active_marker);
markers[active_marker].mtype &= ~M_TRACKING; // Disable tracking when dragging marker
step++; step++;
} }
status = btn_wait_release(); status = btn_wait_release();
@ -2226,7 +2232,7 @@ ui_process_menu(void)
const menuitem_t *menu = menu_stack[menu_current_level]; const menuitem_t *menu = menu_stack[menu_current_level];
int status = btn_check(); int status = btn_check();
if (status != 0) { if (status != 0) {
if (status & EVT_BUTTON_SINGLE_CLICK) { if (selection >=0 && status & EVT_BUTTON_SINGLE_CLICK) {
menu_invoke(selection); menu_invoke(selection);
} else { } else {
do { do {
@ -2242,7 +2248,7 @@ ui_process_menu(void)
} }
if (status & EVT_DOWN) { if (status & EVT_DOWN) {
// skip menu item if disabled // skip menu item if disabled
while (menuDisabled(menu[selection-1].type)) while (selection > 0 && menuDisabled(menu[selection-1].type))
selection--; selection--;
// close menu if item is 0, else step down // close menu if item is 0, else step down
if (selection > 0) if (selection > 0)
@ -2492,7 +2498,7 @@ touch_pickup_marker(void)
// select trace // select trace
uistat.current_trace = t; uistat.current_trace = t;
select_lever_mode(LM_MARKER); select_lever_mode(LM_MARKER);
markers[m].mtype &= ~M_TRACKING; // Disable tracking when dragging marker
// drag marker until release // drag marker until release
drag_marker(t, m); drag_marker(t, m);
return TRUE; return TRUE;

@ -16,6 +16,9 @@
* the Free Software Foundation, Inc., 51 Franklin Street, * the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*/ */
#pragma GCC push_options
#pragma GCC optimize ("Os")
#define FORM_ICON_WIDTH 16 #define FORM_ICON_WIDTH 16
#define FORM_ICON_HEIGHT 16 #define FORM_ICON_HEIGHT 16
@ -403,7 +406,8 @@ static const keypads_t keypads_time[] = {
enum { enum {
KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFLEVEL, KM_SCALE, KM_ATTENUATION, KM_START, KM_STOP, KM_CENTER, KM_SPAN, KM_CW, KM_REFLEVEL, KM_SCALE, KM_ATTENUATION,
KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE, KM_ACTUALPOWER, KM_IF, KM_SAMPLETIME, KM_DRIVE, KM_LOWOUTLEVEL, KM_DECAY, KM_NOISE,
KM_10MHZ, KM_REPEAT, KM_OFFSET, KM_TRIGGER, KM_LEVELSWEEP, KM_SWEEP_TIME, KM_OFFSET_DELAY, KM_FAST_SPEEDUP, KM_10MHZ, KM_REPEAT, KM_OFFSET, KM_TRIGGER, KM_LEVELSWEEP, KM_SWEEP_TIME, KM_OFFSET_DELAY,
KM_FAST_SPEEDUP, KM_GRIDLINES, KM_MARKER, KM_MODULATION,KM_COR_AM,KM_COR_WFM, KM_COR_NFM,
KM_NONE // always at enum end KM_NONE // always at enum end
}; };
@ -425,7 +429,7 @@ static const struct {
{keypads_positive , "DRIVE"}, // drive {keypads_positive , "DRIVE"}, // drive
{keypads_plusmin , "LEVEL"}, // KM_LOWOUTLEVEL {keypads_plusmin , "LEVEL"}, // KM_LOWOUTLEVEL
{keypads_positive , "SCANS"}, // KM_DECAY {keypads_positive , "SCANS"}, // KM_DECAY
{keypads_positive , "LEVEL"}, // KM_NOISE {keypads_positive , "NOISE\nLEVEL"}, // KM_NOISE
{keypads_freq , "FREQ"}, // KM_10MHz {keypads_freq , "FREQ"}, // KM_10MHz
{keypads_positive , "SAMPLE\nREPEAT"}, // KM_REPEA {keypads_positive , "SAMPLE\nREPEAT"}, // KM_REPEA
{keypads_plusmin , "OFFSET"}, // KM_OFFSET {keypads_plusmin , "OFFSET"}, // KM_OFFSET
@ -434,6 +438,12 @@ static const struct {
{keypads_time , "SWEEP\nSECONDS"}, // KM_SWEEP_TIME {keypads_time , "SWEEP\nSECONDS"}, // KM_SWEEP_TIME
{keypads_positive , "OFFSET\nDELAY"}, // KM_OFFSET_DELAY {keypads_positive , "OFFSET\nDELAY"}, // KM_OFFSET_DELAY
{keypads_positive , "FAST\nSPEEDUP"}, // KM_FAST_SPEEDUP {keypads_positive , "FAST\nSPEEDUP"}, // KM_FAST_SPEEDUP
{keypads_positive , "MINIMUM\nGRIDLINES"}, // KM_GRIDLINES
{keypads_freq , "MARKER\nFREQ"}, // KM_MARKER
{keypads_freq , "MODULATION\nFREQ"}, // KM_MODULATION
{keypads_plusmin , "COR\nAM"}, // KM_COR_AM
{keypads_plusmin , "COR\nWFM"}, // KM_COR_WFM
{keypads_plusmin , "COR\nNFM"}, // KM_COR_NFM
}; };
// ===[MENU CALLBACKS]========================================================= // ===[MENU CALLBACKS]=========================================================
@ -499,7 +509,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_load_preset_acb)
} }
if (caldata_recall(data) == -1) { if (caldata_recall(data) == -1) {
if (data == 0) if (data == 0)
reset_settings(setting.mode); // Restore all defaults reset_settings(setting.mode); // Restore factory defaults
else { else {
draw_menu(); draw_menu();
return; return;
@ -577,30 +587,34 @@ static UI_FUNCTION_ADV_CALLBACK(menu_scanning_speed_acb)
ui_mode_normal(); ui_mode_normal();
} }
#define CONFIG_MENUITEM_TOUCH_CAL 0
#define CONFIG_MENUITEM_TOUCH_TEST 1
#define CONFIG_MENUITEM_SELFTEST 2
#define CONFIG_MENUITEM_VERSION 3
static UI_FUNCTION_CALLBACK(menu_config_cb) static UI_FUNCTION_CALLBACK(menu_config_cb)
{ {
(void)data; (void)item;
switch (item) { switch (data) {
case 0: case CONFIG_MENUITEM_TOUCH_CAL:
touch_cal_exec(); touch_cal_exec();
redraw_frame(); redraw_frame();
request_to_redraw_grid(); request_to_redraw_grid();
draw_menu(); draw_menu();
break; break;
case 1: case CONFIG_MENUITEM_TOUCH_TEST:
touch_draw_test(); touch_draw_test();
redraw_frame(); redraw_frame();
request_to_redraw_grid(); request_to_redraw_grid();
draw_menu(); draw_menu();
break; break;
case 2: case CONFIG_MENUITEM_SELFTEST:
sweep_mode = 0; // Suspend sweep to save time sweep_mode = 0; // Suspend sweep to save time
menu_move_back_and_leave_ui(); menu_move_back_and_leave_ui();
setting.test = 0; setting.test = 0;
setting.test_argument = 0; setting.test_argument = 0;
sweep_mode = SWEEP_SELFTEST; sweep_mode = SWEEP_SELFTEST;
break; break;
case 4: case CONFIG_MENUITEM_VERSION:
show_version(); show_version();
redraw_frame(); redraw_frame();
request_to_redraw_grid(); request_to_redraw_grid();
@ -616,8 +630,8 @@ static UI_FUNCTION_CALLBACK(menu_dfu_cb)
} }
// const int menu_modulation_value[]={MO_NONE,MO_AM_1, MO_NFM, MO_WFM, MO_EXTERNAL}; // const int menu_modulation_value[]={MO_NONE,MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL};
const char *menu_modulation_text[]={"None", "AM 1kHz", "AM 10Hz", "Narrow FM", "Wide FM", "External"}; const char *menu_modulation_text[]={"None", "AM", "NFM", "WFM", "External"};
static UI_FUNCTION_ADV_CALLBACK(menu_modulation_acb) static UI_FUNCTION_ADV_CALLBACK(menu_modulation_acb)
{ {
@ -641,7 +655,12 @@ static UI_FUNCTION_ADV_CALLBACK(menu_smodulation_acb){
(void)item; (void)item;
(void)data; (void)data;
if(b){ if(b){
b->param_1.text = menu_modulation_text[setting.modulation]; if (setting.modulation == MO_NONE || setting.modulation == MO_EXTERNAL)
b->param_1.text = menu_modulation_text[setting.modulation];
else {
plot_printf(uistat.text, sizeof uistat.text, "%5.3fkHz %s", setting.modulation_frequency / 1000.0, menu_modulation_text[setting.modulation]);
b->param_1.text = uistat.text;
}
return; return;
} }
menu_push_submenu(menu_modulation); menu_push_submenu(menu_modulation);
@ -834,6 +853,35 @@ static UI_FUNCTION_ADV_CALLBACK(menu_measure_acb)
set_measurement(M_LINEARITY); set_measurement(M_LINEARITY);
ui_mode_normal(); ui_mode_normal();
break; break;
case M_AM: // OIP3
reset_settings(setting.mode);
for (int i = 0; i< 3; i++) {
markers[i].enabled = M_ENABLED;
markers[i].mtype = M_DELTA | M_TRACKING;
}
markers[0].mtype = M_REFERENCE | M_TRACKING;
kp_help_text = "Frequency of signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
set_sweep_frequency(ST_SPAN, 100000); // 100kHz
set_measurement(M_AM);
break;
case M_FM: // OIP3
reset_settings(setting.mode);
for (int i = 0; i< 3; i++) {
markers[i].enabled = M_ENABLED;
markers[i].mtype = M_DELTA | M_TRACKING;
}
markers[0].mtype = M_REFERENCE | M_TRACKING;
kp_help_text = "Frequency of signal";
ui_mode_keypad(KM_CENTER);
ui_process_keypad();
kp_help_text = "Frequency deviation";
ui_mode_keypad(KM_SPAN);
ui_process_keypad();
set_sweep_frequency(ST_SPAN, uistat.value*30);
set_measurement(M_FM);
break;
} }
#endif #endif
// selection = -1; // selection = -1;
@ -948,6 +996,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_marker_select_acb)
return; return;
} }
markers[data-1].enabled = true; markers[data-1].enabled = true;
markers[data-1].frequency = frequencies[markers[data-1].index];
active_marker_select(data-1); active_marker_select(data-1);
menu_push_submenu(menu_marker_modify); menu_push_submenu(menu_marker_modify);
redraw_marker(active_marker); redraw_marker(active_marker);
@ -1141,6 +1190,19 @@ static UI_FUNCTION_ADV_CALLBACK(menu_settings_bpf_acb){
draw_menu(); draw_menu();
} }
#ifdef __HAM_BAND__
static UI_FUNCTION_ADV_CALLBACK(menu_settings_ham_bands){
(void)item;
(void)data;
if(b){
b->icon = config.hambands ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK;
return;
}
toggle_hambands();
draw_menu();
}
#endif
static UI_FUNCTION_ADV_CALLBACK(menu_settings_below_if_acb){ static UI_FUNCTION_ADV_CALLBACK(menu_settings_below_if_acb){
(void)item; (void)item;
(void)data; (void)data;
@ -1205,6 +1267,33 @@ static UI_FUNCTION_ADV_CALLBACK(menu_points_acb){
draw_menu(); draw_menu();
} }
#ifdef __USE_SERIAL_CONSOLE__
static UI_FUNCTION_ADV_CALLBACK(menu_serial_speed_acb)
{
(void)item;
if (b){
b->icon = config._serial_speed == data ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP;
b->param_1.u = USART_GET_SPEED(data);
return;
}
config._serial_speed = data;
shell_update_speed();
draw_menu();
}
static UI_FUNCTION_ADV_CALLBACK(menu_connection_acb)
{
(void)item;
if (b){
b->icon = (config._mode&_MODE_CONNECTION_MASK) == data ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP;
return;
}
config._mode&=~_MODE_CONNECTION_MASK;
config._mode|=data;
shell_reset_console();
draw_menu();
}
#endif
// ===[MENU DEFINITION]========================================================= // ===[MENU DEFINITION]=========================================================
#if 0 #if 0
static const menuitem_t menu_store_preset_high[8] = static const menuitem_t menu_store_preset_high[8] =
@ -1301,11 +1390,11 @@ static const menuitem_t menu_drive_wide[] = {
static const menuitem_t menu_modulation[] = { static const menuitem_t menu_modulation[] = {
{ MT_FORM | MT_TITLE, 0, "MODULATION",NULL}, { MT_FORM | MT_TITLE, 0, "MODULATION",NULL},
{ MT_FORM | MT_ADV_CALLBACK, MO_NONE, "None", menu_modulation_acb}, { MT_FORM | MT_ADV_CALLBACK, MO_NONE, "None", menu_modulation_acb},
{ MT_FORM | MT_ADV_CALLBACK | MT_LOW, MO_AM_1kHz, "AM 1kHz", menu_modulation_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_LOW, MO_AM, "AM", menu_modulation_acb},
{ MT_FORM | MT_ADV_CALLBACK | MT_LOW, MO_AM_10Hz, "AM 10Hz", menu_modulation_acb},
{ MT_FORM | MT_ADV_CALLBACK, MO_NFM, "Narrow FM", menu_modulation_acb}, { MT_FORM | MT_ADV_CALLBACK, MO_NFM, "Narrow FM", menu_modulation_acb},
{ MT_FORM | MT_ADV_CALLBACK, MO_WFM, "Wide FM", menu_modulation_acb}, { MT_FORM | MT_ADV_CALLBACK, MO_WFM, "Wide FM", menu_modulation_acb},
{ MT_FORM | MT_ADV_CALLBACK | MT_LOW, MO_EXTERNAL, "External", menu_modulation_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_LOW, MO_EXTERNAL, "External", menu_modulation_acb},
{ MT_FORM | MT_KEYPAD, KM_MODULATION, "FREQ: %s", "100Hz..6kHz"},
{ MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL },
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
}; };
@ -1314,7 +1403,7 @@ static const menuitem_t menu_lowoutputmode[] = {
{ MT_FORM | MT_ADV_CALLBACK, 0, "LOW OUTPUT %s", menu_outputmode_acb}, { MT_FORM | MT_ADV_CALLBACK, 0, "LOW OUTPUT %s", menu_outputmode_acb},
{ MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", "10kHz..350MHz"}, { MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", "10kHz..350MHz"},
{ MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", "-76..-6"}, { MT_FORM | MT_KEYPAD, KM_LOWOUTLEVEL, "LEVEL: %s", "-76..-6"},
{ MT_FORM | MT_ADV_CALLBACK, 0, "MODULATION: %s", menu_smodulation_acb}, { MT_FORM | MT_ADV_CALLBACK, 0, "MOD: %s", menu_smodulation_acb},
{ MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", "0..350MHz"}, { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", "0..350MHz"},
{ MT_FORM | MT_KEYPAD | MT_LOW, KM_LEVELSWEEP,"LEVEL CHANGE: %s", "-70..70"}, { MT_FORM | MT_KEYPAD | MT_LOW, KM_LEVELSWEEP,"LEVEL CHANGE: %s", "-70..70"},
{ MT_FORM | MT_KEYPAD, KM_SWEEP_TIME, "SWEEP TIME: %s", "0..600 seconds"}, { MT_FORM | MT_KEYPAD, KM_SWEEP_TIME, "SWEEP TIME: %s", "0..600 seconds"},
@ -1326,7 +1415,7 @@ static const menuitem_t menu_highoutputmode[] = {
{ MT_FORM | MT_ADV_CALLBACK, 0, "HIGH OUTPUT %s", menu_outputmode_acb}, { MT_FORM | MT_ADV_CALLBACK, 0, "HIGH OUTPUT %s", menu_outputmode_acb},
{ MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", "240MHz..960MHz"}, { MT_FORM | MT_KEYPAD, KM_CENTER, "FREQ: %s", "240MHz..960MHz"},
{ MT_FORM | MT_ADV_CALLBACK, 0, "LEVEL: %+ddBm", menu_sdrive_acb}, { MT_FORM | MT_ADV_CALLBACK, 0, "LEVEL: %+ddBm", menu_sdrive_acb},
{ MT_FORM | MT_ADV_CALLBACK, 0, "MODULATION: %s", menu_smodulation_acb}, { MT_FORM | MT_ADV_CALLBACK, 0, "MOD: %s", menu_smodulation_acb},
{ MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL}, { MT_FORM | MT_KEYPAD, KM_SPAN, "SPAN: %s", NULL},
{ MT_FORM | MT_KEYPAD, KM_SWEEP_TIME,"SWEEP TIME: %s", "0..600 seconds"}, { MT_FORM | MT_KEYPAD, KM_SWEEP_TIME,"SWEEP TIME: %s", "0..600 seconds"},
{ MT_FORM | MT_CANCEL, 0, "MODE", NULL }, { MT_FORM | MT_CANCEL, 0, "MODE", NULL },
@ -1427,6 +1516,7 @@ const menuitem_t menu_marker_search[] = {
{ MT_CALLBACK, 1, "MIN\n" S_RARROW" RIGHT", menu_marker_search_cb }, { MT_CALLBACK, 1, "MIN\n" S_RARROW" RIGHT", menu_marker_search_cb },
{ MT_CALLBACK, 2, "MAX\n" S_LARROW" LEFT", menu_marker_search_cb }, { MT_CALLBACK, 2, "MAX\n" S_LARROW" LEFT", menu_marker_search_cb },
{ MT_CALLBACK, 3, "MAX\n" S_RARROW" RIGHT", menu_marker_search_cb }, { MT_CALLBACK, 3, "MAX\n" S_RARROW" RIGHT", menu_marker_search_cb },
{ MT_KEYPAD, KM_MARKER, "ENTER\nFREQUENCY", NULL},
{ MT_ADV_CALLBACK, 0, "TRACKING",menu_marker_tracking_acb }, { MT_ADV_CALLBACK, 0, "TRACKING",menu_marker_tracking_acb },
{ MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel { MT_NONE, 0, NULL, NULL } // sentinel
@ -1541,6 +1631,24 @@ static const menuitem_t menu_sweep_speed[] =
{ MT_NONE, 0, NULL, NULL } // sentinel { MT_NONE, 0, NULL, NULL } // sentinel
}; };
static const menuitem_t menu_settings3[] =
{
{ MT_KEYPAD, KM_10MHZ, "CORRECT\nFREQUENCY", "Enter actual l0MHz frequency"},
{ MT_KEYPAD, KM_GRIDLINES, "MINIMUM\nGRIDLINES", "Enter minimum horizontal grid divisions"},
// { MT_KEYPAD, KM_COR_AM, "COR\nAM", "Enter AM modulation correction"},
{ MT_KEYPAD, KM_COR_WFM, "COR\nWFM", "Enter WFM modulation correction"},
{ MT_KEYPAD, KM_COR_NFM, "COR\nNFM", "Enter NFM modulation correction"},
#ifdef __HAM_BAND__
{ MT_ADV_CALLBACK, 0, "HAM\nBANDS", menu_settings_ham_bands},
#endif
#ifdef __ULTRA__
{ MT_SUBMENU,0, "HARMONIC", menu_harmonic},
#endif
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_settings2[] = static const menuitem_t menu_settings2[] =
{ {
{ MT_ADV_CALLBACK, 0, "AGC", menu_settings_agc_acb}, { MT_ADV_CALLBACK, 0, "AGC", menu_settings_agc_acb},
@ -1549,10 +1657,10 @@ static const menuitem_t menu_settings2[] =
{ MT_ADV_CALLBACK | MT_LOW, 0, "BELOW IF", menu_settings_below_if_acb}, { MT_ADV_CALLBACK | MT_LOW, 0, "BELOW IF", menu_settings_below_if_acb},
{ MT_KEYPAD, KM_DECAY, "HOLD\nSWEEPS", "1..1000 sweeps"}, { MT_KEYPAD, KM_DECAY, "HOLD\nSWEEPS", "1..1000 sweeps"},
{ MT_KEYPAD, KM_NOISE, "NOISE\nLEVEL", "2..20 dB"}, { MT_KEYPAD, KM_NOISE, "NOISE\nLEVEL", "2..20 dB"},
{ MT_KEYPAD, KM_10MHZ, "CORRECT\nFREQUENCY", "Enter actual l0MHz frequency"},
#ifdef __ULTRA__ #ifdef __ULTRA__
{ MT_SUBMENU,0, "HARMONIC", menu_harmonic}, { MT_SUBMENU,0, "HARMONIC", menu_harmonic},
#endif #endif
{ MT_SUBMENU, 0, S_RARROW" MORE", menu_settings3},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel { MT_NONE, 0, NULL, NULL } // sentinel
}; };
@ -1570,14 +1678,22 @@ static const menuitem_t menu_settings[] =
{ MT_NONE, 0, NULL, NULL } // sentinel { MT_NONE, 0, NULL, NULL } // sentinel
}; };
static const menuitem_t menu_measure[] = { static const menuitem_t menu_measure2[] = {
{ MT_ADV_CALLBACK, M_OFF, "OFF", menu_measure_acb},
{ MT_ADV_CALLBACK, M_IMD, "HARMONIC", menu_measure_acb},
{ MT_ADV_CALLBACK, M_OIP3, "OIP3", menu_measure_acb},
{ MT_ADV_CALLBACK, M_PHASE_NOISE,"PHASE\nNOISE", menu_measure_acb},
// { MT_ADV_CALLBACK, M_STOP_BAND, "STOP\nBAND", menu_measure_acb},
// { MT_ADV_CALLBACK, M_PASS_BAND, "PASS\nBAND", menu_measure_acb},
// { MT_ADV_CALLBACK | MT_LOW, M_LINEARITY, "LINEAR", menu_measure_acb}, // { MT_ADV_CALLBACK | MT_LOW, M_LINEARITY, "LINEAR", menu_measure_acb},
{ MT_ADV_CALLBACK, M_AM, "AM", menu_measure_acb},
{ MT_ADV_CALLBACK, M_FM, "FM", menu_measure_acb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_measure[] = {
{ MT_ADV_CALLBACK, M_OFF, "OFF", menu_measure_acb},
{ MT_ADV_CALLBACK, M_IMD, "HARMONIC", menu_measure_acb},
{ MT_ADV_CALLBACK, M_OIP3, "OIP3", menu_measure_acb},
{ MT_ADV_CALLBACK, M_PHASE_NOISE,"PHASE\nNOISE", menu_measure_acb},
{ MT_ADV_CALLBACK, M_STOP_BAND, "SNR", menu_measure_acb},
{ MT_ADV_CALLBACK, M_PASS_BAND, "-6dB\nWIDTH", menu_measure_acb},
{ MT_SUBMENU, 0, S_RARROW" MORE", menu_measure2},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel { MT_NONE, 0, NULL, NULL } // sentinel
}; };
@ -1591,12 +1707,57 @@ static const menuitem_t menu_calibrate[] =
{ MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel
}; };
#ifdef __USE_SERIAL_CONSOLE__
//19200, 38400, 57600, 74800, 115200, 230400, 460800, 921600, 1843200, 3686400
#if 0
const menuitem_t menu_serial_speed2[] = {
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 460800), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 921600), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING(1843200), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING(3686400), "%u", menu_serial_speed_acb },
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
#endif
const menuitem_t menu_serial_speed[] = {
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 19200), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 38400), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 57600), "%u", menu_serial_speed_acb },
// { MT_ADV_CALLBACK, USART_SPEED_SETTING( 76800), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING(115200), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING(230400), "%u", menu_serial_speed_acb },
// { MT_SUBMENU, 0, S_RARROW" MORE", menu_serial_speed2 },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 460800), "%u", menu_serial_speed_acb },
{ MT_ADV_CALLBACK, USART_SPEED_SETTING( 921600), "%u", menu_serial_speed_acb },
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
const menuitem_t menu_connection[] = {
{ MT_ADV_CALLBACK, _MODE_USB, "USB", menu_connection_acb },
{ MT_ADV_CALLBACK, _MODE_SERIAL, "SERIAL", menu_connection_acb },
{ MT_SUBMENU, 0, "SERIAL\nSPEED", menu_serial_speed },
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
#endif
const menuitem_t menu_touch[] = {
{ MT_CALLBACK, CONFIG_MENUITEM_TOUCH_CAL, "TOUCH CAL", menu_config_cb},
{ MT_CALLBACK, CONFIG_MENUITEM_TOUCH_TEST, "TOUCH TEST", menu_config_cb},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
{ MT_NONE, 0, NULL, NULL } // sentinel
};
static const menuitem_t menu_config[] = { static const menuitem_t menu_config[] = {
{ MT_CALLBACK, 0, "TOUCH CAL", menu_config_cb}, { MT_SUBMENU, 0, "TOUCH", menu_touch},
{ MT_CALLBACK, 0, "TOUCH TEST", menu_config_cb}, { MT_CALLBACK, CONFIG_MENUITEM_SELFTEST, "SELF TEST", menu_config_cb},
{ MT_CALLBACK, 0, "SELF TEST", menu_config_cb}, { MT_SUBMENU, 0, "LEVEL CAL", menu_calibrate},
{ MT_SUBMENU, 0, "LEVEL CAL", menu_calibrate}, { MT_CALLBACK, CONFIG_MENUITEM_VERSION, "VERSION", menu_config_cb},
{ MT_CALLBACK, 0, "VERSION", menu_config_cb}, #ifdef __USE_SERIAL_CONSOLE__
{ MT_SUBMENU, 0, "CONNECTION", menu_connection},
#endif
{ MT_SUBMENU, 0, "EXPERT\nCONFIG", menu_settings}, { MT_SUBMENU, 0, "EXPERT\nCONFIG", menu_settings},
{ MT_SUBMENU, 0, S_RARROW" DFU", menu_dfu}, { MT_SUBMENU, 0, S_RARROW" DFU", menu_dfu},
{ MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_CANCEL, 0, S_LARROW" BACK", NULL },
@ -1686,6 +1847,8 @@ static const menuitem_t menu_mode[] = {
{ MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINUS, "%s to LOW out", menu_mode_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_LOW_OUTPUT+I_SINUS, "%s to LOW out", menu_mode_acb},
{ MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "%s to HIGH out", menu_mode_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_HIGH_OUTPUT+I_GEN, "%s to HIGH out", menu_mode_acb},
{ MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_CONNECT+I_GEN, "Cal. output: %s", menu_sreffer_acb}, { MT_FORM | MT_ADV_CALLBACK | MT_ICON, I_CONNECT+I_GEN, "Cal. output: %s", menu_sreffer_acb},
// { MT_SUBMENU, 0, "EXPERT\nCONFIG", menu_settings3},
#ifdef __ULTRA__ #ifdef __ULTRA__
{ MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "ULTRA HIGH INPUT",menu_mode_cb}, { MT_FORM | MT_CALLBACK | MT_ICON, I_LOW_INPUT+I_SA, "ULTRA HIGH INPUT",menu_mode_cb},
#endif #endif
@ -1858,7 +2021,18 @@ static void fetch_numeric_target(void)
uistat.value = setting.trigger_level; uistat.value = setting.trigger_level;
plot_printf(uistat.text, sizeof uistat.text, "%.1fdB", uistat.value); plot_printf(uistat.text, sizeof uistat.text, "%.1fdB", uistat.value);
break; break;
case KM_MARKER:
if (active_marker >=0) {
uistat.value = markers[active_marker].frequency;
plot_printf(uistat.text, sizeof uistat.text, "%3.3fMHz", uistat.value / 1000000.0);
}
break;
case KM_MODULATION:
if (active_marker >=0) {
uistat.value = setting.modulation_frequency;
plot_printf(uistat.text, sizeof uistat.text, "%7.0fHz", uistat.value);
}
break;
} }
{ {
@ -1956,6 +2130,28 @@ set_numeric_value(void)
completed = true; completed = true;
break; break;
case KM_GRIDLINES:
set_gridlines(uistat.value);
break;
case KM_MARKER:
set_marker_frequency(active_marker, (uint32_t)uistat.value);
break;
case KM_MODULATION:
set_modulation_frequency((int)uistat.value);
break;
case KM_COR_AM:
config.cor_am =(int)uistat.value;
config_save();
break;
case KM_COR_WFM:
config.cor_wfm =(int)uistat.value;
config_save();
break;
case KM_COR_NFM:
config.cor_nfm =(int)uistat.value;
config_save();
break;
} }
} }
@ -1966,3 +2162,4 @@ menu_move_top(void)
menu_move_back(); menu_move_back();
} }
#pragma GCC pop_options

Loading…
Cancel
Save

Powered by TurnKey Linux.