mirror of
https://github.com/ttrftech/NanoVNA.git
synced 2025-12-06 03:31:59 +01:00
Compare commits
12 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d02db797a7 | ||
|
|
4d64ef6e48 | ||
|
|
bc1b57c3f0 | ||
|
|
64de4d5d87 | ||
|
|
e57292ea01 | ||
|
|
fb57511f9a | ||
|
|
56b0d3ad8a | ||
|
|
ba7d358d35 | ||
|
|
d7c7d8faeb | ||
|
|
fe7a1ac4de | ||
|
|
5a10105b1a | ||
|
|
1656342eeb |
8
Makefile
8
Makefile
|
|
@ -81,6 +81,10 @@ endif
|
||||||
# Project, sources and paths
|
# Project, sources and paths
|
||||||
#
|
#
|
||||||
|
|
||||||
|
# Dvice node to flash
|
||||||
|
DEVICE = /dev/cu.usbmodem401
|
||||||
|
#DEVICE = /dev/ttyACM0
|
||||||
|
|
||||||
# Define project name here
|
# Define project name here
|
||||||
PROJECT = ch
|
PROJECT = ch
|
||||||
|
|
||||||
|
|
@ -225,6 +229,4 @@ flash: build/ch.bin
|
||||||
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
|
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
|
||||||
|
|
||||||
dfu:
|
dfu:
|
||||||
-@printf "reset dfu\r" >/dev/cu.usbmodem401
|
-printf "reset dfu\r" >$(DEVICE) && sleep 1
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ There are seveal numbers of great companion PC tools from third-party.
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
* [NanoVNA User Guide](https://cho45.github.io/NanoVNA-manual/) [(google translate)](https://translate.google.com/translate?sl=ja&tl=en&u=https%3A%2F%2Fcho45.github.io%2FNanoVNA-manual%2F) by cho45
|
* [NanoVNA User Guide(ja)](https://cho45.github.io/NanoVNA-manual/) by cho45. [(en:google translate)](https://translate.google.com/translate?sl=ja&tl=en&u=https%3A%2F%2Fcho45.github.io%2FNanoVNA-manual%2F)
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
|
|
||||||
|
|
@ -105,6 +105,7 @@ Hardware design material is disclosed to prevent bad quality clone. Please let m
|
||||||
## Authorized Distributor
|
## Authorized Distributor
|
||||||
|
|
||||||
* [Nooelec](https://www.nooelec.com/store/nanovna-bundle.html)
|
* [Nooelec](https://www.nooelec.com/store/nanovna-bundle.html)
|
||||||
|
* Switch Science(ja) [NanoVNA-H](https://www.switch-science.com/catalog/6405/) [NanoVNA-H4](https://www.switch-science.com/catalog/6406/)
|
||||||
|
|
||||||
## Credit
|
## Credit
|
||||||
|
|
||||||
|
|
|
||||||
16
dsp.c
16
dsp.c
|
|
@ -41,10 +41,10 @@ const int16_t sincos_tbl[48][2] = {
|
||||||
{-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 }
|
{-24636, -21605 }, {-32698, -2143 }, {-27246, 18205 }, {-10533, 31029 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t acc_samp_s;
|
float acc_samp_s;
|
||||||
int32_t acc_samp_c;
|
float acc_samp_c;
|
||||||
int32_t acc_ref_s;
|
float acc_ref_s;
|
||||||
int32_t acc_ref_c;
|
float acc_ref_c;
|
||||||
|
|
||||||
void
|
void
|
||||||
dsp_process(int16_t *capture, size_t length)
|
dsp_process(int16_t *capture, size_t length)
|
||||||
|
|
@ -79,10 +79,10 @@ dsp_process(int16_t *capture, size_t length)
|
||||||
ref_c = __SMLATT(sr, sc, ref_c);
|
ref_c = __SMLATT(sr, sc, ref_c);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
acc_samp_s = samp_s;
|
acc_samp_s += samp_s;
|
||||||
acc_samp_c = samp_c;
|
acc_samp_c += samp_c;
|
||||||
acc_ref_s = ref_s;
|
acc_ref_s += ref_s;
|
||||||
acc_ref_c = ref_c;
|
acc_ref_c += ref_c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
139
main.c
139
main.c
|
|
@ -198,40 +198,54 @@ transform_domain(void)
|
||||||
// and calculate ifft for time domain
|
// and calculate ifft for time domain
|
||||||
float* tmp = (float*)spi_buffer;
|
float* tmp = (float*)spi_buffer;
|
||||||
|
|
||||||
|
// correct IFFT window and zero-padding loss
|
||||||
|
// assuming a 2*POINT_COUNT window
|
||||||
|
float wincorr = 1.0f;
|
||||||
|
float beta = 0.0;
|
||||||
|
switch (domain_mode & TD_WINDOW) {
|
||||||
|
case TD_WINDOW_MINIMUM:
|
||||||
|
beta = 0.0; // this is rectangular
|
||||||
|
// loss by zero-padding 202 to 256 points
|
||||||
|
wincorr = (float)FFT_SIZE / (float)(2*POINTS_COUNT);
|
||||||
|
break;
|
||||||
|
case TD_WINDOW_NORMAL:
|
||||||
|
beta = 6.0;
|
||||||
|
// additional window loss: 1/mean(kaiser(202,6)) = 2.01
|
||||||
|
wincorr = (float)FFT_SIZE / (float)(2*POINTS_COUNT) * 2.01f;
|
||||||
|
break;
|
||||||
|
case TD_WINDOW_MAXIMUM:
|
||||||
|
beta = 13;
|
||||||
|
// additional window loss: 1/mean(kaiser(202,13)) = 2.92
|
||||||
|
wincorr = (float)FFT_SIZE / (float)(2*POINTS_COUNT) * 2.92f;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t window_size = POINTS_COUNT, offset = 0;
|
uint8_t window_size = POINTS_COUNT, offset = 0;
|
||||||
uint8_t is_lowpass = FALSE;
|
uint8_t is_lowpass = FALSE;
|
||||||
switch (domain_mode & TD_FUNC) {
|
switch (domain_mode & TD_FUNC) {
|
||||||
case TD_FUNC_BANDPASS:
|
case TD_FUNC_BANDPASS:
|
||||||
offset = 0;
|
offset = 0;
|
||||||
window_size = POINTS_COUNT;
|
window_size = POINTS_COUNT;
|
||||||
|
// window size is half the size as assumed above => twice the IFFT loss
|
||||||
|
wincorr *= 2.0f;
|
||||||
break;
|
break;
|
||||||
case TD_FUNC_LOWPASS_IMPULSE:
|
|
||||||
case TD_FUNC_LOWPASS_STEP:
|
case TD_FUNC_LOWPASS_STEP:
|
||||||
|
// no IFFT losses need to be considered to calculate the step response
|
||||||
|
wincorr = 1.0f;
|
||||||
|
// fall-through
|
||||||
|
case TD_FUNC_LOWPASS_IMPULSE:
|
||||||
is_lowpass = TRUE;
|
is_lowpass = TRUE;
|
||||||
offset = POINTS_COUNT;
|
offset = POINTS_COUNT;
|
||||||
window_size = POINTS_COUNT * 2;
|
window_size = POINTS_COUNT * 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float beta = 0.0;
|
|
||||||
switch (domain_mode & TD_WINDOW) {
|
|
||||||
case TD_WINDOW_MINIMUM:
|
|
||||||
beta = 0.0; // this is rectangular
|
|
||||||
break;
|
|
||||||
case TD_WINDOW_NORMAL:
|
|
||||||
beta = 6.0;
|
|
||||||
break;
|
|
||||||
case TD_WINDOW_MAXIMUM:
|
|
||||||
beta = 13;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int ch = 0; ch < 2; ch++) {
|
for (int ch = 0; ch < 2; ch++) {
|
||||||
memcpy(tmp, measured[ch], sizeof(measured[0]));
|
memcpy(tmp, measured[ch], sizeof(measured[0]));
|
||||||
for (int i = 0; i < POINTS_COUNT; i++) {
|
for (int i = 0; i < POINTS_COUNT; i++) {
|
||||||
float w = kaiser_window(i + offset, window_size, beta);
|
float w = kaiser_window(i + offset, window_size, beta);
|
||||||
tmp[i * 2 + 0] *= w;
|
tmp[i * 2 + 0] *= w * wincorr;
|
||||||
tmp[i * 2 + 1] *= w;
|
tmp[i * 2 + 1] *= w * wincorr;
|
||||||
}
|
}
|
||||||
for (int i = POINTS_COUNT; i < FFT_SIZE; i++) {
|
for (int i = POINTS_COUNT; i < FFT_SIZE; i++) {
|
||||||
tmp[i * 2 + 0] = 0.0;
|
tmp[i * 2 + 0] = 0.0;
|
||||||
|
|
@ -584,10 +598,34 @@ int16_t dump_buffer[AUDIO_BUFFER_LEN];
|
||||||
int16_t dump_selection = 0;
|
int16_t dump_selection = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
volatile int16_t wait_count = 0;
|
volatile uint8_t wait_count = 0;
|
||||||
|
volatile uint8_t accumerate_count = 0;
|
||||||
|
|
||||||
|
const int8_t bandwidth_accumerate_count[] = {
|
||||||
|
1, // 1kHz
|
||||||
|
3, // 300Hz
|
||||||
|
10, // 100Hz
|
||||||
|
33, // 30Hz
|
||||||
|
100 // 10Hz
|
||||||
|
};
|
||||||
|
|
||||||
float measured[2][POINTS_COUNT][2];
|
float measured[2][POINTS_COUNT][2];
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dsp_start(int count)
|
||||||
|
{
|
||||||
|
wait_count = count;
|
||||||
|
accumerate_count = bandwidth_accumerate_count[bandwidth];
|
||||||
|
reset_dsp_accumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
dsp_wait(void)
|
||||||
|
{
|
||||||
|
while (accumerate_count > 0)
|
||||||
|
__WFI();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLED_DUMP
|
#ifdef ENABLED_DUMP
|
||||||
static void
|
static void
|
||||||
duplicate_buffer_to_dump(int16_t *p)
|
duplicate_buffer_to_dump(int16_t *p)
|
||||||
|
|
@ -610,13 +648,16 @@ void i2s_end_callback(I2SDriver *i2sp, size_t offset, size_t n)
|
||||||
(void)i2sp;
|
(void)i2sp;
|
||||||
(void)n;
|
(void)n;
|
||||||
|
|
||||||
if (wait_count > 0) {
|
if (wait_count > 1) {
|
||||||
if (wait_count == 1)
|
|
||||||
dsp_process(p, n);
|
|
||||||
#ifdef ENABLED_DUMP
|
|
||||||
duplicate_buffer_to_dump(p);
|
|
||||||
#endif
|
|
||||||
--wait_count;
|
--wait_count;
|
||||||
|
} else if (wait_count > 0) {
|
||||||
|
if (accumerate_count > 0) {
|
||||||
|
dsp_process(p, n);
|
||||||
|
accumerate_count--;
|
||||||
|
}
|
||||||
|
#ifdef ENABLED_DUMP
|
||||||
|
duplicate_buffer_to_dump(p);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PORT_SUPPORTS_RT
|
#if PORT_SUPPORTS_RT
|
||||||
|
|
@ -668,7 +709,8 @@ VNA_SHELL_FUNCTION(cmd_dump)
|
||||||
if (argc == 1)
|
if (argc == 1)
|
||||||
dump_selection = my_atoi(argv[0]);
|
dump_selection = my_atoi(argv[0]);
|
||||||
|
|
||||||
wait_dsp(3);
|
dsp_start(3);
|
||||||
|
dsp_wait();
|
||||||
|
|
||||||
len = AUDIO_BUFFER_LEN;
|
len = AUDIO_BUFFER_LEN;
|
||||||
if (dump_selection == 1 || dump_selection == 2)
|
if (dump_selection == 1 || dump_selection == 2)
|
||||||
|
|
@ -752,7 +794,6 @@ config_t config = {
|
||||||
.trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR, DEFAULT_TRACE_4_COLOR },
|
.trace_color = { DEFAULT_TRACE_1_COLOR, DEFAULT_TRACE_2_COLOR, DEFAULT_TRACE_3_COLOR, DEFAULT_TRACE_4_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 = { 338, 522, 153, 192 }, // 2.8 inch LCD panel
|
.touch_cal = { 338, 522, 153, 192 }, // 2.8 inch LCD panel
|
||||||
.freq_mode = FREQ_MODE_START_STOP,
|
|
||||||
.harmonic_freq_threshold = 300000000,
|
.harmonic_freq_threshold = 300000000,
|
||||||
.vbat_offset = 500
|
.vbat_offset = 500
|
||||||
};
|
};
|
||||||
|
|
@ -792,6 +833,8 @@ void load_default_properties(void)
|
||||||
current_props._active_marker = 0;
|
current_props._active_marker = 0;
|
||||||
current_props._domain_mode = 0;
|
current_props._domain_mode = 0;
|
||||||
current_props._marker_smith_format = MS_RLC;
|
current_props._marker_smith_format = MS_RLC;
|
||||||
|
current_props._freq_mode = FREQ_MODE_START_STOP;
|
||||||
|
|
||||||
//Checksum add on caldata_save
|
//Checksum add on caldata_save
|
||||||
//current_props.checksum = 0;
|
//current_props.checksum = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -808,9 +851,6 @@ ensure_edit_config(void)
|
||||||
cal_status = 0;
|
cal_status = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DSP_START(delay) wait_count = delay;
|
|
||||||
#define DSP_WAIT_READY while (wait_count) __WFI();
|
|
||||||
|
|
||||||
#define DELAY_CHANNEL_CHANGE 2
|
#define DELAY_CHANNEL_CHANGE 2
|
||||||
|
|
||||||
// main loop for measurement
|
// main loop for measurement
|
||||||
|
|
@ -824,20 +864,20 @@ bool sweep(bool break_on_operation)
|
||||||
if (frequencies[i] == 0) break;
|
if (frequencies[i] == 0) break;
|
||||||
delay = set_frequency(frequencies[i]); // 700
|
delay = set_frequency(frequencies[i]); // 700
|
||||||
tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure
|
tlv320aic3204_select(0); // 60 CH0:REFLECT, reset and begin measure
|
||||||
DSP_START(delay + ((i == 0) ? 1 : 0)); // 1900
|
dsp_start(delay + ((i == 0) ? 1 : 0)); // 1900
|
||||||
//================================================
|
//================================================
|
||||||
// Place some code thats need execute while delay
|
// Place some code thats need execute while delay
|
||||||
//================================================
|
//================================================
|
||||||
DSP_WAIT_READY;
|
dsp_wait();
|
||||||
// calculate reflection coefficient
|
// calculate reflection coefficient
|
||||||
(*sample_func)(measured[0][i]); // 60
|
(*sample_func)(measured[0][i]); // 60
|
||||||
|
|
||||||
tlv320aic3204_select(1); // 60 CH1:TRANSMISSION, reset and begin measure
|
tlv320aic3204_select(1); // 60 CH1:TRANSMISSION, reset and begin measure
|
||||||
DSP_START(DELAY_CHANNEL_CHANGE); // 1700
|
dsp_start(DELAY_CHANNEL_CHANGE); // 1700
|
||||||
//================================================
|
//================================================
|
||||||
// Place some code thats need execute while delay
|
// Place some code thats need execute while delay
|
||||||
//================================================
|
//================================================
|
||||||
DSP_WAIT_READY;
|
dsp_wait();
|
||||||
// calculate transmission coefficient
|
// calculate transmission coefficient
|
||||||
(*sample_func)(measured[1][i]); // 60
|
(*sample_func)(measured[1][i]); // 60
|
||||||
// ======== 170 ===========
|
// ======== 170 ===========
|
||||||
|
|
@ -979,7 +1019,7 @@ set_sweep_frequency(int type, uint32_t freq)
|
||||||
ensure_edit_config();
|
ensure_edit_config();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ST_START:
|
case ST_START:
|
||||||
config.freq_mode &= ~FREQ_MODE_CENTER_SPAN;
|
freq_mode &= ~FREQ_MODE_CENTER_SPAN;
|
||||||
if (frequency0 != freq) {
|
if (frequency0 != freq) {
|
||||||
frequency0 = freq;
|
frequency0 = freq;
|
||||||
// if start > stop then make start = stop
|
// if start > stop then make start = stop
|
||||||
|
|
@ -987,7 +1027,7 @@ set_sweep_frequency(int type, uint32_t freq)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_STOP:
|
case ST_STOP:
|
||||||
config.freq_mode &= ~FREQ_MODE_CENTER_SPAN;
|
freq_mode &= ~FREQ_MODE_CENTER_SPAN;
|
||||||
if (frequency1 != freq) {
|
if (frequency1 != freq) {
|
||||||
frequency1 = freq;
|
frequency1 = freq;
|
||||||
// if start > stop then make start = stop
|
// if start > stop then make start = stop
|
||||||
|
|
@ -995,7 +1035,7 @@ set_sweep_frequency(int type, uint32_t freq)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_CENTER:
|
case ST_CENTER:
|
||||||
config.freq_mode |= FREQ_MODE_CENTER_SPAN;
|
freq_mode |= FREQ_MODE_CENTER_SPAN;
|
||||||
uint32_t center = frequency0 / 2 + frequency1 / 2;
|
uint32_t center = frequency0 / 2 + frequency1 / 2;
|
||||||
if (center != freq) {
|
if (center != freq) {
|
||||||
uint32_t span = frequency1 - frequency0;
|
uint32_t span = frequency1 - frequency0;
|
||||||
|
|
@ -1010,7 +1050,7 @@ set_sweep_frequency(int type, uint32_t freq)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_SPAN:
|
case ST_SPAN:
|
||||||
config.freq_mode |= FREQ_MODE_CENTER_SPAN;
|
freq_mode |= FREQ_MODE_CENTER_SPAN;
|
||||||
if (frequency1 - frequency0 != freq) {
|
if (frequency1 - frequency0 != freq) {
|
||||||
uint32_t center = frequency0 / 2 + frequency1 / 2;
|
uint32_t center = frequency0 / 2 + frequency1 / 2;
|
||||||
if (center < START_MIN + freq / 2) {
|
if (center < START_MIN + freq / 2) {
|
||||||
|
|
@ -1024,7 +1064,7 @@ set_sweep_frequency(int type, uint32_t freq)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ST_CW:
|
case ST_CW:
|
||||||
config.freq_mode |= FREQ_MODE_CENTER_SPAN;
|
freq_mode |= FREQ_MODE_CENTER_SPAN;
|
||||||
if (frequency0 != freq || frequency1 != freq) {
|
if (frequency0 != freq || frequency1 != freq) {
|
||||||
frequency0 = freq;
|
frequency0 = freq;
|
||||||
frequency1 = freq;
|
frequency1 = freq;
|
||||||
|
|
@ -1524,7 +1564,8 @@ static const struct {
|
||||||
{ "REAL", NGRIDY/2, 0.25 },
|
{ "REAL", NGRIDY/2, 0.25 },
|
||||||
{ "IMAG", NGRIDY/2, 0.25 },
|
{ "IMAG", NGRIDY/2, 0.25 },
|
||||||
{ "R", NGRIDY/2, 100.0 },
|
{ "R", NGRIDY/2, 100.0 },
|
||||||
{ "X", NGRIDY/2, 100.0 }
|
{ "X", NGRIDY/2, 100.0 },
|
||||||
|
{ "Q", 0, 10.0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char * const trc_channel_name[] = {
|
static const char * const trc_channel_name[] = {
|
||||||
|
|
@ -1628,8 +1669,8 @@ VNA_SHELL_FUNCTION(cmd_trace)
|
||||||
#if MAX_TRACE_TYPE != 12
|
#if MAX_TRACE_TYPE != 12
|
||||||
#error "Trace type enum possibly changed, check cmd_trace function"
|
#error "Trace type enum possibly changed, check cmd_trace function"
|
||||||
#endif
|
#endif
|
||||||
// enum TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF
|
// enum TRC_LOGMAG, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_Q, TRC_OFF
|
||||||
static const char cmd_type_list[] = "logmag|phase|delay|smith|polar|linear|swr|real|imag|r|x|off";
|
static const char cmd_type_list[] = "logmag|phase|delay|smith|polar|linear|swr|real|imag|r|x|q|off";
|
||||||
int type = get_str_index(argv[1], cmd_type_list);
|
int type = get_str_index(argv[1], cmd_type_list);
|
||||||
if (type >= 0) {
|
if (type >= 0) {
|
||||||
set_trace_type(t, type);
|
set_trace_type(t, type);
|
||||||
|
|
@ -1921,6 +1962,23 @@ VNA_SHELL_FUNCTION(cmd_port)
|
||||||
tlv320aic3204_select(port);
|
tlv320aic3204_select(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VNA_SHELL_FUNCTION(cmd_bandwidth)
|
||||||
|
{
|
||||||
|
if (argc != 1)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
static const char bw_choice[] = "1000|300|100|30|10";
|
||||||
|
int i = get_str_index(argv[0], bw_choice);
|
||||||
|
if (i < 0)
|
||||||
|
goto usage;
|
||||||
|
|
||||||
|
bandwidth = i;
|
||||||
|
return;
|
||||||
|
|
||||||
|
usage:
|
||||||
|
shell_printf("usage: bandwidth {%s}\r\n", bw_choice);
|
||||||
|
}
|
||||||
|
|
||||||
VNA_SHELL_FUNCTION(cmd_stat)
|
VNA_SHELL_FUNCTION(cmd_stat)
|
||||||
{
|
{
|
||||||
int16_t *p = &rx_buffer[0];
|
int16_t *p = &rx_buffer[0];
|
||||||
|
|
@ -2109,6 +2167,7 @@ static const VNAShellCommand commands[] =
|
||||||
{"dump" , cmd_dump , 0},
|
{"dump" , cmd_dump , 0},
|
||||||
#endif
|
#endif
|
||||||
{"frequencies" , cmd_frequencies , 0},
|
{"frequencies" , cmd_frequencies , 0},
|
||||||
|
{"bandwidth" , cmd_bandwidth , 0},
|
||||||
{"port" , cmd_port , 0},
|
{"port" , cmd_port , 0},
|
||||||
{"stat" , cmd_stat , 0},
|
{"stat" , cmd_stat , 0},
|
||||||
{"gain" , cmd_gain , 0},
|
{"gain" , cmd_gain , 0},
|
||||||
|
|
|
||||||
15
nanovna.h
15
nanovna.h
|
|
@ -194,10 +194,10 @@ extern const uint16_t numfont16x22[];
|
||||||
|
|
||||||
#define MAX_TRACE_TYPE 12
|
#define MAX_TRACE_TYPE 12
|
||||||
enum trace_type {
|
enum trace_type {
|
||||||
TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_OFF
|
TRC_LOGMAG=0, TRC_PHASE, TRC_DELAY, TRC_SMITH, TRC_POLAR, TRC_LINEAR, TRC_SWR, TRC_REAL, TRC_IMAG, TRC_R, TRC_X, TRC_Q, TRC_OFF
|
||||||
};
|
};
|
||||||
// Mask for define rectangular plot
|
// Mask for define rectangular plot
|
||||||
#define RECTANGULAR_GRID_MASK ((1<<TRC_LOGMAG)|(1<<TRC_PHASE)|(1<<TRC_DELAY)|(1<<TRC_LINEAR)|(1<<TRC_SWR)|(1<<TRC_REAL)|(1<<TRC_IMAG)|(1<<TRC_R)|(1<<TRC_X))
|
#define RECTANGULAR_GRID_MASK ((1<<TRC_LOGMAG)|(1<<TRC_PHASE)|(1<<TRC_DELAY)|(1<<TRC_LINEAR)|(1<<TRC_SWR)|(1<<TRC_REAL)|(1<<TRC_IMAG)|(1<<TRC_R)|(1<<TRC_X)|(1<<TRC_Q))
|
||||||
|
|
||||||
// LOGMAG: SCALE, REFPOS, REFVAL
|
// LOGMAG: SCALE, REFPOS, REFVAL
|
||||||
// PHASE: SCALE, REFPOS, REFVAL
|
// PHASE: SCALE, REFPOS, REFVAL
|
||||||
|
|
@ -230,7 +230,6 @@ 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;
|
|
||||||
uint32_t harmonic_freq_threshold;
|
uint32_t harmonic_freq_threshold;
|
||||||
uint16_t vbat_offset;
|
uint16_t vbat_offset;
|
||||||
uint8_t _reserved[22];
|
uint8_t _reserved[22];
|
||||||
|
|
@ -379,7 +378,9 @@ typedef struct properties {
|
||||||
int8_t _active_marker;
|
int8_t _active_marker;
|
||||||
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */
|
uint8_t _domain_mode; /* 0bxxxxxffm : where ff: TD_FUNC m: DOMAIN_MODE */
|
||||||
uint8_t _marker_smith_format;
|
uint8_t _marker_smith_format;
|
||||||
uint8_t _reserved[50];
|
uint8_t _bandwidth;
|
||||||
|
int8_t _freq_mode;
|
||||||
|
uint8_t _reserved[49];
|
||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
} properties_t;
|
} properties_t;
|
||||||
|
|
||||||
|
|
@ -405,9 +406,11 @@ extern properties_t current_props;
|
||||||
#define domain_mode current_props._domain_mode
|
#define domain_mode current_props._domain_mode
|
||||||
#define velocity_factor current_props._velocity_factor
|
#define velocity_factor current_props._velocity_factor
|
||||||
#define marker_smith_format current_props._marker_smith_format
|
#define marker_smith_format current_props._marker_smith_format
|
||||||
|
#define bandwidth current_props._bandwidth
|
||||||
|
#define freq_mode current_props._freq_mode
|
||||||
|
|
||||||
#define FREQ_IS_STARTSTOP() (!(config.freq_mode&FREQ_MODE_CENTER_SPAN))
|
#define FREQ_IS_STARTSTOP() (!(freq_mode & FREQ_MODE_CENTER_SPAN))
|
||||||
#define FREQ_IS_CENTERSPAN() (config.freq_mode&FREQ_MODE_CENTER_SPAN)
|
#define FREQ_IS_CENTERSPAN() (freq_mode & FREQ_MODE_CENTER_SPAN)
|
||||||
#define FREQ_IS_CW() (frequency0 == frequency1)
|
#define FREQ_IS_CW() (frequency0 == frequency1)
|
||||||
|
|
||||||
int caldata_save(int id);
|
int caldata_save(int id);
|
||||||
|
|
|
||||||
21
plot.c
21
plot.c
|
|
@ -491,6 +491,14 @@ reactance(const float *v)
|
||||||
return zi;
|
return zi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
qualityfactor(const float *v)
|
||||||
|
{
|
||||||
|
float i = 2*v[1];
|
||||||
|
float r = (1+v[0])*(1-v[0]) - v[1]*v[1];
|
||||||
|
return fabs(i / r);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cartesian_scale(float re, float im, int *xp, int *yp, float scale)
|
cartesian_scale(float re, float im, int *xp, int *yp, float scale)
|
||||||
{
|
{
|
||||||
|
|
@ -567,6 +575,9 @@ trace_into_index(int t, int i, float array[POINTS_COUNT][2])
|
||||||
case TRC_X:
|
case TRC_X:
|
||||||
v-= reactance(coeff) * scale;
|
v-= reactance(coeff) * scale;
|
||||||
break;
|
break;
|
||||||
|
case TRC_Q:
|
||||||
|
v-= qualityfactor(coeff) * scale;
|
||||||
|
break;
|
||||||
case TRC_SMITH:
|
case TRC_SMITH:
|
||||||
//case TRC_ADMIT:
|
//case TRC_ADMIT:
|
||||||
case TRC_POLAR:
|
case TRC_POLAR:
|
||||||
|
|
@ -610,7 +621,7 @@ format_smith_value(char *buf, int len, const float coeff[2], uint32_t frequency)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MS_RX:
|
case MS_RX:
|
||||||
plot_printf(buf, len, "%F"S_OHM"%+Fj", zr, zi);
|
plot_printf(buf, len, "%F%+Fj"S_OHM, zr, zi);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MS_RLC:
|
case MS_RLC:
|
||||||
|
|
@ -669,6 +680,10 @@ trace_get_value_string(int t, char *buf, int len, float array[POINTS_COUNT][2],
|
||||||
format = "%.2F"S_OHM;
|
format = "%.2F"S_OHM;
|
||||||
v = gamma2reactance(coeff);
|
v = gamma2reactance(coeff);
|
||||||
break;
|
break;
|
||||||
|
case TRC_Q:
|
||||||
|
format = "%.1f";
|
||||||
|
v = qualityfactor(coeff);
|
||||||
|
break;
|
||||||
case TRC_SMITH:
|
case TRC_SMITH:
|
||||||
format_smith_value(buf, len, coeff, frequencies[i]);
|
format_smith_value(buf, len, coeff, frequencies[i]);
|
||||||
return;
|
return;
|
||||||
|
|
@ -729,6 +744,10 @@ trace_get_value_string_delta(int t, char *buf, int len, float array[POINTS_COUNT
|
||||||
format = "%.2F"S_OHM;
|
format = "%.2F"S_OHM;
|
||||||
v = gamma2reactance(coeff);
|
v = gamma2reactance(coeff);
|
||||||
break;
|
break;
|
||||||
|
case TRC_Q:
|
||||||
|
format = "%.1f";
|
||||||
|
v = qualityfactor(coeff);
|
||||||
|
break;
|
||||||
//case TRC_ADMIT:
|
//case TRC_ADMIT:
|
||||||
case TRC_POLAR:
|
case TRC_POLAR:
|
||||||
plot_printf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]);
|
plot_printf(buf, len, "%.2f%+.2fj", coeff[0], coeff[1]);
|
||||||
|
|
|
||||||
37
ui.c
37
ui.c
|
|
@ -631,6 +631,13 @@ menu_transform_filter_cb(int item, uint8_t data)
|
||||||
ui_mode_normal();
|
ui_mode_normal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
menu_bandwidth_cb(int item)
|
||||||
|
{
|
||||||
|
bandwidth = item;
|
||||||
|
draw_menu();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
choose_active_marker(void)
|
choose_active_marker(void)
|
||||||
{
|
{
|
||||||
|
|
@ -761,9 +768,11 @@ menu_marker_search_cb(int item, uint8_t data)
|
||||||
break;
|
break;
|
||||||
case 2: /* search Left */
|
case 2: /* search Left */
|
||||||
i = marker_search_left(markers[active_marker].index);
|
i = marker_search_left(markers[active_marker].index);
|
||||||
|
uistat.marker_tracking = false;
|
||||||
break;
|
break;
|
||||||
case 3: /* search right */
|
case 3: /* search right */
|
||||||
i = marker_search_right(markers[active_marker].index);
|
i = marker_search_right(markers[active_marker].index);
|
||||||
|
uistat.marker_tracking = false;
|
||||||
break;
|
break;
|
||||||
case 4: /* tracking */
|
case 4: /* tracking */
|
||||||
uistat.marker_tracking = !uistat.marker_tracking;
|
uistat.marker_tracking = !uistat.marker_tracking;
|
||||||
|
|
@ -877,6 +886,7 @@ const menuitem_t menu_format2[] = {
|
||||||
{ MT_CALLBACK, TRC_IMAG, "IMAG", menu_format_cb },
|
{ MT_CALLBACK, TRC_IMAG, "IMAG", menu_format_cb },
|
||||||
{ MT_CALLBACK, TRC_R, "RESISTANCE", menu_format_cb },
|
{ MT_CALLBACK, TRC_R, "RESISTANCE", menu_format_cb },
|
||||||
{ MT_CALLBACK, TRC_X, "REACTANCE", menu_format_cb },
|
{ MT_CALLBACK, TRC_X, "REACTANCE", menu_format_cb },
|
||||||
|
{ MT_CALLBACK, TRC_Q, "Q FACTOR", menu_format_cb },
|
||||||
{ 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
|
||||||
};
|
};
|
||||||
|
|
@ -928,12 +938,23 @@ const menuitem_t menu_transform[] = {
|
||||||
{ MT_NONE, 0, NULL, NULL } // sentinel
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const menuitem_t menu_bandwidth[] = {
|
||||||
|
{ MT_CALLBACK, 0, "1 kHz", menu_bandwidth_cb },
|
||||||
|
{ MT_CALLBACK, 0, "300 Hz", menu_bandwidth_cb },
|
||||||
|
{ MT_CALLBACK, 0, "100 Hz", menu_bandwidth_cb },
|
||||||
|
{ MT_CALLBACK, 0, "30 Hz", menu_bandwidth_cb },
|
||||||
|
{ MT_CALLBACK, 0, "10 Hz", menu_bandwidth_cb },
|
||||||
|
{ MT_CANCEL, 0, S_LARROW" BACK", NULL },
|
||||||
|
{ MT_NONE, 0, NULL, NULL } // sentinel
|
||||||
|
};
|
||||||
|
|
||||||
const menuitem_t menu_display[] = {
|
const menuitem_t menu_display[] = {
|
||||||
{ MT_SUBMENU, 0, "TRACE", menu_trace },
|
{ MT_SUBMENU, 0, "TRACE", menu_trace },
|
||||||
{ MT_SUBMENU, 0, "FORMAT", menu_format },
|
{ MT_SUBMENU, 0, "FORMAT", menu_format },
|
||||||
{ MT_SUBMENU, 0, "SCALE", menu_scale },
|
{ MT_SUBMENU, 0, "SCALE", menu_scale },
|
||||||
{ MT_SUBMENU, 0, "CHANNEL", menu_channel },
|
{ MT_SUBMENU, 0, "CHANNEL", menu_channel },
|
||||||
{ MT_SUBMENU, 0, "TRANSFORM", menu_transform },
|
{ MT_SUBMENU, 0, "TRANSFORM", menu_transform },
|
||||||
|
{ MT_SUBMENU, 0, "BANDWIDTH", menu_bandwidth },
|
||||||
{ 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
|
||||||
};
|
};
|
||||||
|
|
@ -985,7 +1006,7 @@ const menuitem_t menu_marker_smith[] = {
|
||||||
{ MT_CALLBACK, MS_LIN, "LIN", menu_marker_smith_cb },
|
{ MT_CALLBACK, MS_LIN, "LIN", menu_marker_smith_cb },
|
||||||
{ MT_CALLBACK, MS_LOG, "LOG", menu_marker_smith_cb },
|
{ MT_CALLBACK, MS_LOG, "LOG", menu_marker_smith_cb },
|
||||||
{ MT_CALLBACK, MS_REIM,"Re+Im", menu_marker_smith_cb },
|
{ MT_CALLBACK, MS_REIM,"Re+Im", menu_marker_smith_cb },
|
||||||
{ MT_CALLBACK, MS_RX, "R+Xj", menu_marker_smith_cb },
|
{ MT_CALLBACK, MS_RX, "R+jX", menu_marker_smith_cb },
|
||||||
{ MT_CALLBACK, MS_RLC, "R+L/C", menu_marker_smith_cb },
|
{ MT_CALLBACK, MS_RLC, "R+L/C", menu_marker_smith_cb },
|
||||||
{ 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
|
||||||
|
|
@ -1120,6 +1141,7 @@ menu_invoke(int item)
|
||||||
|
|
||||||
#define MENU_BUTTON_WIDTH 60
|
#define MENU_BUTTON_WIDTH 60
|
||||||
#define MENU_BUTTON_HEIGHT 30
|
#define MENU_BUTTON_HEIGHT 30
|
||||||
|
#define MENU_BUTTON_MAX 8
|
||||||
#define NUM_INPUT_HEIGHT 30
|
#define NUM_INPUT_HEIGHT 30
|
||||||
|
|
||||||
#define KP_WIDTH 48
|
#define KP_WIDTH 48
|
||||||
|
|
@ -1365,6 +1387,11 @@ menu_item_modify_attribute(const menuitem_t *menu, int item,
|
||||||
*bg = DEFAULT_MENU_TEXT_COLOR;
|
*bg = DEFAULT_MENU_TEXT_COLOR;
|
||||||
*fg = config.menu_normal_color;
|
*fg = config.menu_normal_color;
|
||||||
}
|
}
|
||||||
|
} else if (menu == menu_bandwidth) {
|
||||||
|
if (item == bandwidth) {
|
||||||
|
*bg = 0x0000;
|
||||||
|
*fg = 0xffff;
|
||||||
|
}
|
||||||
} else if (menu == menu_transform) {
|
} else if (menu == menu_transform) {
|
||||||
if ((item == 0 && (domain_mode & DOMAIN_MODE) == DOMAIN_TIME)
|
if ((item == 0 && (domain_mode & DOMAIN_MODE) == DOMAIN_TIME)
|
||||||
|| (item == 1 && (domain_mode & TD_FUNC) == TD_FUNC_LOWPASS_IMPULSE)
|
|| (item == 1 && (domain_mode & TD_FUNC) == TD_FUNC_LOWPASS_IMPULSE)
|
||||||
|
|
@ -1389,7 +1416,7 @@ static void
|
||||||
draw_menu_buttons(const menuitem_t *menu)
|
draw_menu_buttons(const menuitem_t *menu)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (i = 0; i < 7; i++) {
|
for (i = 0; i < MENU_BUTTON_MAX; i++) {
|
||||||
const char *l1, *l2;
|
const char *l1, *l2;
|
||||||
if (menu[i].type == MT_NONE)
|
if (menu[i].type == MT_NONE)
|
||||||
break;
|
break;
|
||||||
|
|
@ -1435,7 +1462,7 @@ menu_apply_touch(void)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
touch_position(&touch_x, &touch_y);
|
touch_position(&touch_x, &touch_y);
|
||||||
for (i = 0; i < 7; i++) {
|
for (i = 0; i < MENU_BUTTON_MAX; i++) {
|
||||||
if (menu[i].type == MT_NONE)
|
if (menu[i].type == MT_NONE)
|
||||||
break;
|
break;
|
||||||
if (menu[i].type == MT_BLANK)
|
if (menu[i].type == MT_BLANK)
|
||||||
|
|
@ -1460,7 +1487,7 @@ draw_menu(void)
|
||||||
static void
|
static void
|
||||||
erase_menu_buttons(void)
|
erase_menu_buttons(void)
|
||||||
{
|
{
|
||||||
ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT*7, DEFAULT_BG_COLOR);
|
ili9341_fill(320-MENU_BUTTON_WIDTH, 0, MENU_BUTTON_WIDTH, MENU_BUTTON_HEIGHT * MENU_BUTTON_MAX, DEFAULT_BG_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -1478,8 +1505,8 @@ leave_ui_mode()
|
||||||
} else if (ui_mode == UI_NUMERIC) {
|
} else if (ui_mode == UI_NUMERIC) {
|
||||||
request_to_draw_cells_behind_numeric_input();
|
request_to_draw_cells_behind_numeric_input();
|
||||||
erase_numeric_input();
|
erase_numeric_input();
|
||||||
draw_frequencies();
|
|
||||||
}
|
}
|
||||||
|
draw_frequencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue