Merge branch 'p1-fixes'

copilot/add-multi-platform-rf-scan-exports
erikkaashoek 2 weeks ago
commit c8e392fc57

@ -1,3 +1,12 @@
V1.4284 2026-11-02 For all tinySA models
- Every tinySA has its own USB serial number (from the MCU unique ID, on the tinySA Ultra the same as its DFU serial number), so Windows can tell several tinySAs apart. Windows assigns a new COM port once
- The battery stays visible when the sweep is paused with the "pause" console command
- "ext_gain" without a value shows the current external gain
- A preset loaded from SD now also uses its RBW (Ultra only)
- Band names are stored in .bnd files and loaded from them (Ultra only)
- Self test: when there is no signal, "Cable connected?" is shown in the test list instead of a hint that was overwritten
- Version screen: copyright 2026, aligned thread table (Ultra only)
V1.4273 2026-11-02 For all tinySA Ultra models
- The tinySA Ultra has its own USB IDs: VID 0x1781 PID 0x0A44 (was 0x0483 0x5740, the ST virtual COM port). Windows assigns a new COM port once, programs that look for the tinySA by its USB IDs need an update (tinySA-App accepts both)

@ -96,7 +96,7 @@ uint16_t redraw_request = 0; // contains REDRAW_XXX flags
// Version text, displayed in Config->Version menu, also send by info command
const char * const info_about[]={
BOARD_NAME,
"2019-2024 Copyright @Erik Kaashoek",
"2019-2026 Copyright @Erik Kaashoek",
"2016-2020 Copyright @edy555",
"SW licensed under GPL. See: https://github.com/erikkaashoek/tinySA",
"Version: " VERSION,

@ -398,7 +398,7 @@ VNA_SHELL_FUNCTION(cmd_sweeptime)
VNA_SHELL_FUNCTION(cmd_ext_gain)
{
if (argc != 1 || argv[0][0] == '?') {
usage_printf("ext_gain -100.0..+100.0\r\n");
usage_printf("ext_gain -100.0..+100.0\r\n%.1f\r\n", setting.external_gain);
return;
}
float o = my_atof(argv[0]);

@ -6476,6 +6476,7 @@ static const char *const test_text [4] =
static const char *(test_fail_cause [TEST_COUNT]);
static int test_status[TEST_COUNT];
static int show_test_info = FALSE;
static const char *test_hint; // last line of the test list while waiting for a touch
static volatile int test_wait = false;
static float test_value;
@ -6584,7 +6585,7 @@ void cell_draw_test_info(int x0, int y0)
cell_printf(xpos, ypos, FONT_s"Self test status:");
} else if (test_case[i].kind == TC_END) {
if (test_wait)
cell_printf(xpos, ypos, FONT_s"Touch screen to continue");
cell_printf(xpos, ypos, FONT_s"%s", test_hint);
continue;
} else {
cell_printf(xpos, ypos, FONT_s"Test %d: %s%s", i+1, test_fail_cause[i], test_text[test_status[i]] );
@ -7153,6 +7154,7 @@ void selftest(int test)
test_fail_cause[i] = "";
}
show_test_info = TRUE;
test_hint = "Touch screen to continue";
test_step=0;
test_step = setting.test_argument;
if (test_step != 0) {
@ -7170,9 +7172,7 @@ void selftest(int test)
if (test_step == 2) {
if (peakLevel < -60) {
test_step = TEST_END;
ili9341_set_foreground(LCD_BRIGHT_COLOR_RED);
ili9341_drawstring_7x13("Signal level too low", 30, 140);
ili9341_drawstring_7x13("Did you connect high and low ports with cable?", 0, 210);
test_hint = "Cable connected? Touch screen to continue"; // drawn in the list, a direct draw was overwritten
goto resume2;
}

12
ui.c

@ -707,10 +707,12 @@ extern const char *states[];
#else
uint32_t stklimit = 0U;
#endif
lcd_printf(x, y+=bFONT_STR_HEIGHT, "%08x|%08x|%08x|%08x|%4u|%4u|%9s|%12s",
// The font is proportional (a space is narrower than a digit), padding with spaces does not align:
// zero padded numbers, the name after them, the state at a fixed position
lcd_printf(x, y+=bFONT_STR_HEIGHT, "%08x|%08x|%08x|%08x|%u|%03u|%s",
stklimit, (uint32_t)tp->ctx.sp, max_stack_use, (uint32_t)tp,
(uint32_t)tp->refs - 1, (uint32_t)tp->prio, states[tp->state],
tp->name == NULL ? "" : tp->name);
(uint32_t)tp->refs - 1, (uint32_t)tp->prio, tp->name == NULL ? "" : tp->name);
lcd_printf(x + 330, y, "%s", states[tp->state]);
tp = chRegNextThread(tp);
} while (tp != NULL);
#endif
@ -6495,6 +6497,7 @@ redraw_cal_status:
#endif
return;
}
redraw_request |= REDRAW_BATTERY; // the fill erased it, while paused no completed sweep redraws it
// if (current_menu_is_form() && !in_selftest)
// return;
@ -8448,8 +8451,7 @@ static void sa_save_file(uint8_t format) {
char *buf = (char *)spi_buffer;
buf += plot_printf(buf, 100, "%U, ", setting.bands[i].start);
buf += plot_printf(buf, 100, "%U, ", setting.bands[i].end);
buf += plot_printf(buf, 100, "%f ", setting.bands[i].level);
buf += plot_printf(buf, 100, "\r\n");
buf += plot_printf(buf, 100, "%f, \"%s\"\r\n", setting.bands[i].level, setting.bands[i].name); // name: older firmware ignores it
res = f_write(fs_file, (char *)spi_buffer, buf - (char *)spi_buffer, &size);
}
}

@ -248,74 +248,28 @@ static const uint8_t vcom_string2[] = {
};
#endif
#ifdef TINYSA4
/*
* Serial Number string. VERSION = 'tinySA4_v1.3-nnn-gxxxxxxx'
* 01234567890123456789012
* skip last two 'xx' char due to 'tinySA4_v1.3-n-gxxxxxxx'
* Serial Number string: 12 hex digits made from the MCU unique ID the way the STM32F303 DFU
* bootloader makes its serial number (UID0 + UID2, then the upper half of UID2), so every tinySA
* has its own. It was the kernel version "400" on all of them: Windows could not tell two units
* apart and gave one unit's COM port to the other. Filled at every USB reset, before it is requested.
*/
static const uint8_t vcom_string3[] =
static uint8_t vcom_string3[2 + 2 * 12]; // the upper bytes of the UTF-16 characters stay 0
static void fill_serial_string(void)
{
#if 1
USB_DESC_BYTE(8), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
'0' + CH_KERNEL_MAJOR, 0,
'0' + CH_KERNEL_MINOR, 0,
'0' + CH_KERNEL_PATCH, 0
#else
USB_DESC_BYTE(32), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
VERSION[8], 0, /* 'v' */
VERSION[9], 0, /* '1' */
VERSION[10], 0, /* '.' */
VERSION[11], 0, /* '3' */
VERSION[12], 0, /* '-' */
VERSION[13], 0, /* 'n' */
VERSION[14], 0, /* 'n' */
VERSION[15], 0, /* 'n' */
VERSION[16], 0, /* '-' */
VERSION[17], 0, /* 'g' */
VERSION[18], 0, /* 'x' */
VERSION[19], 0, /* 'x' */
VERSION[20], 0, /* 'x' */
VERSION[21], 0, /* 'x' */
VERSION[22], 0, /* 'x' */
#endif
};
#else
/*
* Serial Number string. VERSION = 'tinySA_v1.3-nnn-gxxxxxxx'
* 0123456789012345678901
* skip last two 'xx' char due to 'tinySA_v1.3-n-gxxxxxxx'
*/
static const uint8_t vcom_string3[] = {
#if 1
USB_DESC_BYTE(8), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
'0' + CH_KERNEL_MAJOR, 0,
'0' + CH_KERNEL_MINOR, 0,
'0' + CH_KERNEL_PATCH, 0
#else
USB_DESC_BYTE(32), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
VERSION[7], 0, /* 'v' */
VERSION[8], 0, /* '1' */
VERSION[9], 0, /* '.' */
VERSION[10], 0, /* '3' */
VERSION[11], 0, /* '-' */
VERSION[12], 0, /* 'n' */
VERSION[13], 0, /* 'n' */
VERSION[14], 0, /* 'n' */
VERSION[15], 0, /* '-' */
VERSION[16], 0, /* 'g' */
VERSION[17], 0, /* 'x' */
VERSION[18], 0, /* 'x' */
VERSION[19], 0, /* 'x' */
VERSION[20], 0, /* 'x' */
VERSION[21], 0, /* 'x' */
#endif
};
#endif
const uint32_t *uid = (const uint32_t *)UID_BASE;
uint32_t v = uid[0] + uid[2];
vcom_string3[0] = sizeof vcom_string3;
vcom_string3[1] = USB_DESCRIPTOR_STRING;
for (int i = 2; i < (int)sizeof vcom_string3; i += 2) {
if (i == 2 + 2 * 8) // 8 digits done: then the upper half of UID2
v = uid[2];
uint8_t c = v >> 28;
v <<= 4;
vcom_string3[i] = c + (c < 10 ? '0' : 'A' - 10);
}
}
/*
* Strings wrappers array.
@ -406,6 +360,7 @@ static void usb_event(USBDriver *usbp, usbevent_t event) {
switch (event) {
case USB_EVENT_RESET:
fill_serial_string();
#ifdef __USE_USB_MSC__
{
/* usb_lld_reset() has just allocated the EP0 buffers.*/

@ -177,11 +177,13 @@ finish2:
line[j] = 0; j = 0;
char *args[16];
int nargs = parse_line(line, args, 16); // Parse line to 16 args
if (nargs < 2 || args[0][0] == '#' || args[0][0] == '!') continue; // No data or comment or settings
if (nargs < 3 || args[0][0] == '#' || args[0][0] == '!') continue; // No data or comment or settings
if (count >= BANDS_MAX) {error = "Format err"; goto finish3;}
setting.bands[count].start = my_atoui(args[0]);// Get frequency
setting.bands[count].end = my_atoui(args[1]);// Get frequency
setting.bands[count].level = my_atof(args[2]); // Get frequency
if (nargs > 3) // Name, files of older firmware have none
plot_printf(setting.bands[count].name, BAND_NAME_SIZE, "%s", args[3]);
setting.bands[count].enabled = true; // Get frequency
count++;
}
@ -334,6 +336,7 @@ static char cmd_buffer[256+128];
set_scale(setting.scale);
set_reflevel(setting.reflevel);
set_level_meter_or_waterfall();
update_rbw(); // as caldata_recall(), else the RBW of the loaded preset is not used
// Remember where this preset came from so storing it back can default to it
plot_printf(sd_preset_path, sizeof(sd_preset_path), "%s", fno.fname);
}

Loading…
Cancel
Save

Powered by TurnKey Linux.