Merge branch 'ttrftech-master'

This commit is contained in:
qrp73 2019-09-28 08:57:06 +03:00
commit e37ef6eabc
5 changed files with 184 additions and 119 deletions

View file

@ -229,7 +229,7 @@ flash: build/ch.bin
dfu-util -d 0483:df11 -a 0 -s 0x08000000:leave -D build/ch.bin
dfu:
printf "reset dfu\r" >/dev/cu.usbmodem401
-@printf "reset dfu\r" >/dev/cu.usbmodem401
TAGS: Makefile
@etags *.[ch] NANOVNA_STM32_F072/*.[ch] $(shell find ChibiOS/os/hal/ports/STM32/STM32F0xx ChibiOS/os -name \*.\[ch\] -print)

196
main.c
View file

@ -39,7 +39,10 @@ static void apply_error_term_at(int i);
static void cal_interpolate(int s);
void apply_edelay_at(int i);
void sweep(void);
void set_frequencies(uint32_t start, uint32_t stop, int16_t points);
void update_frequencies(void);
bool sweep(bool break_on_operation);
static MUTEX_DECL(mutex);
@ -49,11 +52,10 @@ static MUTEX_DECL(mutex);
int32_t frequency_offset = 5000;
int32_t frequency = 10000000;
int8_t drive_strength = DRIVE_STRENGTH_AUTO;
int8_t frequency_updated = FALSE;
int8_t sweep_enabled = TRUE;
int8_t sweep_once = FALSE;
int8_t cal_auto_interpolate = TRUE;
uint16_t redraw_request = 0; // contains REDRAW_XXX flags
int8_t stop_the_world = FALSE;
int16_t vbat = 0;
@ -64,32 +66,38 @@ static THD_FUNCTION(Thread1, arg)
chRegSetThreadName("sweep");
while (1) {
if (stop_the_world) {
__WFI();
continue;
bool completed = false;
if (sweep_enabled || sweep_once) {
chMtxLock(&mutex);
completed = sweep(true);
sweep_once = FALSE;
chMtxUnlock(&mutex);
} else {
__WFI();
}
if (sweep_enabled) {
chMtxLock(&mutex);
sweep();
chMtxUnlock(&mutex);
} else {
__WFI();
ui_process();
}
if (vbat != -1) {
if (vbat != -1) {
adc_stop(ADC1);
vbat = adc_vbat_read(ADC1);
touch_start_watchdog();
draw_battery_status();
}
/* calculate trace coordinates and plot only if scan completed */
if (completed) {
plot_into_index(measured);
redraw_request |= REDRAW_CELLS;
}
/* plot trace and other indications as raster */
draw_all(completed); // flush markmap only if scan completed to prevent remaining traces
chMtxUnlock(&mutex);
}
/* calculate trace coordinates */
plot_into_index(measured);
/* plot trace as raster */
draw_all();
}
}
@ -220,6 +228,12 @@ static void cmd_resume(BaseSequentialStream *chp, int argc, char *argv[])
(void)chp;
(void)argc;
(void)argv;
// restore frequencies array and cal
update_frequencies();
if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY))
cal_interpolate(lastsaveid);
resume_sweep();
}
@ -462,13 +476,15 @@ static void cmd_data(BaseSequentialStream *chp, int argc, char *argv[])
if (sel == 0 || sel == 1) {
chMtxLock(&mutex);
for (i = 0; i < sweep_points; i++) {
chprintf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]);
if (frequencies[i] != 0)
chprintf(chp, "%f %f\r\n", measured[sel][i][0], measured[sel][i][1]);
}
chMtxUnlock(&mutex);
} else if (sel >= 2 && sel < 7) {
chMtxLock(&mutex);
for (i = 0; i < sweep_points; i++) {
chprintf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]);
if (frequencies[i] != 0)
chprintf(chp, "%f %f\r\n", cal_data[sel-2][i][0], cal_data[sel-2][i][1]);
}
chMtxUnlock(&mutex);
} else {
@ -506,10 +522,7 @@ static void cmd_capture(BaseSequentialStream *chp, int argc, char *argv[])
(void)argc;
(void)argv;
// pause sweep
stop_the_world = TRUE;
chThdSleepMilliseconds(1000);
chMtxLock(&mutex);
// use uint16_t spi_buffer[1024] (defined in ili9341) for read buffer
uint16_t *buf = &spi_buffer[0];
@ -532,7 +545,7 @@ static void cmd_capture(BaseSequentialStream *chp, int argc, char *argv[])
}
//*/
stop_the_world = FALSE;
chMtxUnlock(&mutex);
}
#if 0
@ -633,48 +646,13 @@ ensure_edit_config(void)
cal_status = 0;
}
#if 0
static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[])
{
float gamma[2];
int i;
int32_t freq, step;
int delay;
(void)argc;
(void)argv;
pause_sweep();
chMtxLock(&mutex);
freq = frequency0;
step = (frequency1 - frequency0) / (sweep_points-1);
set_frequency(freq);
delay = 4;
for (i = 0; i < sweep_points; i++) {
freq = freq + step;
wait_dsp(delay);
delay = set_frequency(freq);
palClearPad(GPIOC, GPIOC_LED);
calculate_gamma(gamma);
palSetPad(GPIOC, GPIOC_LED);
chprintf(chp, "%d %d\r\n", gamma[0], gamma[1]);
}
chMtxUnlock(&mutex);
}
#endif
// main loop for measurement
void sweep(void)
bool sweep(bool break_on_operation)
{
int i;
int delay;
rewind:
frequency_updated = FALSE;
//delay = 3;
for (i = 0; i < sweep_points; i++) {
delay = set_frequency(frequencies[i]);
int delay = set_frequency(frequencies[i]);
tlv320aic3204_select_in3(); // CH0:REFLECT
wait_dsp(delay);
@ -699,15 +677,51 @@ void sweep(void)
if (electrical_delay != 0)
apply_edelay_at(i);
ui_process();
if (redraw_request)
break; // return to redraw screen asap.
if (frequency_updated)
goto rewind;
// back to toplevel to handle ui operation
if (operation_requested && break_on_operation)
return false;
}
transform_domain();
return true;
}
static void cmd_scan(BaseSequentialStream *chp, int argc, char *argv[])
{
int32_t start, stop;
int16_t points = sweep_points;
if (argc != 2 && argc != 3) {
chprintf(chp, "usage: sweep {start(Hz)} {stop(Hz)} [points]\r\n");
return;
}
start = atoi(argv[0]);
stop = atoi(argv[1]);
if (start == 0 || stop == 0 || start > stop) {
chprintf(chp, "frequency range is invalid\r\n");
return;
}
if (argc == 3) {
points = atoi(argv[2]);
if (points <= 0 || points > sweep_points) {
chprintf(chp, "sweep points exceeds range\r\n");
return;
}
}
pause_sweep();
chMtxLock(&mutex);
set_frequencies(start, stop, points);
if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY))
cal_interpolate(lastsaveid);
sweep_once = TRUE;
chMtxUnlock(&mutex);
// wait finishing sweep
while (sweep_once)
chThdSleepMilliseconds(10);
}
static void
@ -742,32 +756,37 @@ update_marker_index(void)
}
void
update_frequencies(void)
set_frequencies(uint32_t start, uint32_t stop, int16_t points)
{
int i;
int32_t span;
int32_t start;
uint32_t span = (stop - start) / 1000; /* prevents overflow because of maximum of int32_t(2.147e+9) */
for (i = 0; i < points; i++)
frequencies[i] = start + span * i / (points - 1) * 1000;
for (; i < sweep_points; i++)
frequencies[i] = 0;
}
void
update_frequencies(void)
{
uint32_t start, stop;
if (frequency1 > 0) {
start = frequency0;
span = (frequency1 - frequency0)/100;
stop = frequency1;
} else {
int center = frequency0;
span = -frequency1;
int32_t center = frequency0;
int32_t span = -frequency1;
start = center - span/2;
span /= 100;
stop = center + span/2;
}
for (i = 0; i < sweep_points; i++)
frequencies[i] = start + span * i / (sweep_points - 1) * 100;
set_frequencies(start, stop, sweep_points);
update_marker_index();
frequency_updated = TRUE;
// set grid layout
update_grid();
}
void
freq_mode_startstop(void)
{
@ -801,7 +820,6 @@ void
set_sweep_frequency(int type, float frequency)
{
int32_t freq = frequency;
bool cal_applied = cal_status & CALSTAT_APPLY;
switch (type) {
case ST_START:
freq_mode_startstop();
@ -881,7 +899,7 @@ set_sweep_frequency(int type, float frequency)
break;
}
if (cal_auto_interpolate && cal_applied)
if (cal_auto_interpolate && (cal_status & CALSTAT_APPLY))
cal_interpolate(lastsaveid);
}
@ -915,8 +933,7 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[])
chprintf(chp, "%d %d %d\r\n", frequency0, frequency1, sweep_points);
return;
} else if (argc > 3) {
chprintf(chp, "usage: sweep {start(Hz)} [stop] [points]\r\n");
return;
goto usage;
}
if (argc >= 2) {
if (strcmp(argv[0], "start") == 0) {
@ -944,12 +961,18 @@ static void cmd_sweep(BaseSequentialStream *chp, int argc, char *argv[])
if (argc >= 1) {
int32_t value = atoi(argv[0]);
if (value == 0)
goto usage;
set_sweep_frequency(ST_START, value);
}
if (argc >= 2) {
int32_t value = atoi(argv[1]);
set_sweep_frequency(ST_STOP, value);
}
return;
usage:
chprintf(chp, "usage: sweep {start(Hz)} [stop(Hz)]\r\n");
chprintf(chp, "\tsweep {start|stop|center|span|cw} {freq(Hz)}\r\n");
}
@ -1718,7 +1741,8 @@ static void cmd_frequencies(BaseSequentialStream *chp, int argc, char *argv[])
(void)argc;
(void)argv;
for (i = 0; i < sweep_points; i++) {
chprintf(chp, "%d\r\n", frequencies[i]);
if (frequencies[i] != 0)
chprintf(chp, "%d\r\n", frequencies[i]);
}
}
@ -1888,7 +1912,7 @@ static const ShellCommand commands[] =
{ "power", cmd_power },
{ "sample", cmd_sample },
//{ "gamma", cmd_gamma },
//{ "scan", cmd_scan },
{ "scan", cmd_scan },
{ "sweep", cmd_sweep },
{ "test", cmd_test },
{ "touchcal", cmd_touchcal },

View file

@ -236,7 +236,7 @@ void redraw_marker(int marker, int update_info);
void trace_get_info(int t, char *buf, int len);
void plot_into_index(float measured[2][101][2]);
void force_set_markmap(void);
void draw_all(void);
void draw_all(bool flush);
void draw_cal_status(void);

20
plot.c
View file

@ -1248,7 +1248,7 @@ draw_cell(int m, int n)
}
void
draw_all_cells(void)
draw_all_cells(bool flush_markmap)
{
int m, n;
for (m = 0; m < (area_width+CELLWIDTH-1) / CELLWIDTH; m++)
@ -1257,17 +1257,19 @@ draw_all_cells(void)
draw_cell(m, n);
}
// keep current map for update
swap_markmap();
// clear map for next plotting
clear_markmap();
if (flush_markmap) {
// keep current map for update
swap_markmap();
// clear map for next plotting
clear_markmap();
}
}
void
draw_all(void)
draw_all(bool flush)
{
draw_all_cells();
if (redraw_request & REDRAW_CELLS)
draw_all_cells(flush);
if (redraw_request & REDRAW_FREQUENCY)
draw_frequencies();
if (redraw_request & REDRAW_CAL_STATUS)
@ -1285,7 +1287,7 @@ redraw_marker(int marker, int update_info)
if (update_info)
markmap[current_mappage][0] = 0xffff;
draw_all_cells();
draw_all_cells(TRUE);
}
void

View file

@ -3,8 +3,19 @@ import serial
import numpy as np
import pylab as pl
import scipy.signal as signal
import time
import struct
from serial.tools import list_ports
VID = 0x0483 #1155
PID = 0x5740 #22336
# Get nanovna device automatically
def getport() -> str:
device_list = list_ports.comports()
for device in device_list:
if device.vid == VID and device.pid == PID:
return device.device
raise OSError("device not found")
REF_LEVEL = (1<<9)
@ -31,7 +42,7 @@ class NanoVNA:
def frequencies(self):
return self._frequencies
def set_sweep(self, start = 1e6, stop = 900e6, points = None):
def set_frequencies(self, start = 1e6, stop = 900e6, points = None):
if points:
self.points = points
self._frequencies = np.linspace(start, stop, self.points)
@ -50,6 +61,12 @@ class NanoVNA:
self.serial.write(cmd.encode())
self.serial.readline() # discard empty line
def set_sweep(self, start, stop):
if start is not None:
self.send_command("sweep start %d\r" % start)
if stop is not None:
self.send_command("sweep stop %d\r" % stop)
def set_frequency(self, freq):
if freq is not None:
self.send_command("freq %d\r" % freq)
@ -128,19 +145,6 @@ class NanoVNA:
d = data.strip().split(' ')
return (int(d[0])+int(d[1])*1.j)/REF_LEVEL
def fetch_scan(self, port = None):
self.set_port(port)
self.send_command("scan\r")
data = self.fetch_data()
x = []
for line in data.split('\n'):
if line:
x.append([int(d) for d in line.strip().split(' ')])
x = np.array(x)
freqs = x[:,0]
gammas = x[:,1]+x[:,2]*1j
return gammas / REF_LEVEL, freqs
def reflect_coeff_from_rawwave(self, freq = None):
ref, samp = self.fetch_rawwave(freq)
if self.filter:
@ -162,7 +166,7 @@ class NanoVNA:
def pause(self):
self.send_command("pause\r")
def scan(self, port = None):
def scan_gamma0(self, port = None):
self.set_port(port)
return np.vectorize(self.gamma)(self.frequencies)
@ -189,6 +193,29 @@ class NanoVNA:
x.append(float(line))
self._frequencies = np.array(x)
def send_scan(self, start = 1e6, stop = 900e6, points = None):
if points:
self.send_command("scan %d %d %d\r"%(start, stop, points))
else:
self.send_command("scan %d %d\r"%(start, stop))
def scan(self):
segment_length = 101
array0 = []
array1 = []
freqs = self._frequencies
while len(freqs) > 0:
seg_start = freqs[0]
seg_stop = freqs[segment_length-1] if len(freqs) >= segment_length else freqs[-1]
length = segment_length if len(freqs) >= segment_length else len(freqs)
#print((seg_start, seg_stop, length))
self.send_scan(seg_start, seg_stop, length)
array0.extend(self.data(0))
array1.extend(self.data(1))
freqs = freqs[segment_length:]
self.resume()
return (array0, array1)
def capture(self):
from PIL import Image
self.send_command("capture\r")
@ -331,6 +358,15 @@ if __name__ == '__main__':
parser.add_option("-c", "--scan", dest="scan",
action="store_true", default=False,
help="scan by script", metavar="SCAN")
parser.add_option("-S", "--start", dest="start",
type="float", default=1e6,
help="start frequency", metavar="START")
parser.add_option("-E", "--stop", dest="stop",
type="float", default=900e6,
help="stop frequency", metavar="STOP")
parser.add_option("-N", "--points", dest="points",
type="int", default=101,
help="scan points", metavar="POINTS")
parser.add_option("-P", "--port", type="int", dest="port",
help="port", metavar="PORT")
parser.add_option("-d", "--dev", dest="device",
@ -341,7 +377,7 @@ if __name__ == '__main__':
help="gain (0-95)", metavar="GAIN")
parser.add_option("-O", "--offset", type="int", dest="offset",
help="offset frequency", metavar="OFFSET")
parser.add_option("-S", "--strength", type="int", dest="strength",
parser.add_option("--strength", type="int", dest="strength",
help="drive strength(0-3)", metavar="STRENGTH")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
@ -353,7 +389,7 @@ if __name__ == '__main__':
help="capture current display to FILE", metavar="FILE")
(opt, args) = parser.parse_args()
nv = NanoVNA(opt.device or '/dev/cu.usbmodem401')
nv = NanoVNA(opt.device or getport())
if opt.capture:
print("capturing...")
@ -379,14 +415,17 @@ if __name__ == '__main__':
print(np.average(samp[0::2] * samp[1::2]))
pl.show()
exit(0)
if opt.start or opt.stop or opt.points:
nv.set_frequencies(opt.start, opt.stop, opt.points)
plot = opt.phase or opt.plot or opt.vswr or opt.delay or opt.groupdelay or opt.smith or opt.unwrapphase or opt.polar or opt.tdr
if plot:
if opt.scan:
p = int(opt.port) if opt.port else 0
if opt.scan or opt.points > 101:
s = nv.scan()
s = s[p]
else:
p = 0
if opt.port:
p = int(opt.port)
if opt.start or opt.stop:
nv.set_sweep(opt.start, opt.stop)
s = nv.data(p)
if opt.smith:
nv.smith(s)