Skip to content

Commit 891b22b

Browse files
authored
Merge pull request LinuxCNC#3722 from grandixximo/master
Halscope always 16 channels, and add user configurable samples
2 parents 9d9c401 + 402a96d commit 891b22b

File tree

8 files changed

+722
-167
lines changed

8 files changed

+722
-167
lines changed

src/hal/utils/scope.c

Lines changed: 123 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,33 @@ static void exit_on_signal(int signum) {
9999
exit_from_hal();
100100
exit(1);
101101
}
102+
103+
/* Read just the SAMPLES value from config file before loading scope_rt */
104+
static int read_samples_from_config(const char *filename)
105+
{
106+
FILE *fp;
107+
char buf[100];
108+
int samples = 0;
109+
110+
fp = fopen(filename, "r");
111+
if (fp == NULL) {
112+
return 0; /* file doesn't exist, use default */
113+
}
114+
while (fgets(buf, sizeof(buf), fp) != NULL) {
115+
/* Support both "SAMPLES nnn" and "# SAMPLES nnn" for backward compatibility */
116+
/* Older halscope versions will ignore "# SAMPLES" as a comment */
117+
if (strncasecmp(buf, "SAMPLES ", 8) == 0) {
118+
samples = atoi(buf + 8);
119+
break;
120+
} else if (strncasecmp(buf, "# SAMPLES ", 10) == 0) {
121+
samples = atoi(buf + 10);
122+
break;
123+
}
124+
}
125+
fclose(fp);
126+
return samples;
127+
}
128+
102129
/***********************************************************************
103130
* MAIN() FUNCTION *
104131
************************************************************************/
@@ -141,9 +168,30 @@ int main(int argc, gchar * argv[])
141168
break;
142169
}
143170
}
144-
if(argc > optind) num_samples = atoi(argv[argc-1]);
171+
/* first try to read samples from config file */
172+
num_samples = read_samples_from_config(ifilename);
173+
/* command line num_samples overrides config file, but only if it's a valid number */
174+
if(argc > optind) {
175+
int cmdline_samples = atoi(argv[optind]);
176+
if(cmdline_samples > 0) {
177+
num_samples = cmdline_samples;
178+
}
179+
}
180+
/* apply defaults and bounds */
145181
if(num_samples <= 0)
146182
num_samples = SCOPE_NUM_SAMPLES_DEFAULT;
183+
if(num_samples < SCOPE_NUM_SAMPLES_MIN) {
184+
rtapi_print_msg(RTAPI_MSG_WARN,
185+
"SCOPE: num_samples %d too small, using %d\n",
186+
num_samples, SCOPE_NUM_SAMPLES_MIN);
187+
num_samples = SCOPE_NUM_SAMPLES_MIN;
188+
}
189+
if(num_samples > SCOPE_NUM_SAMPLES_MAX) {
190+
rtapi_print_msg(RTAPI_MSG_WARN,
191+
"SCOPE: num_samples %d too large, using %d\n",
192+
num_samples, SCOPE_NUM_SAMPLES_MAX);
193+
num_samples = SCOPE_NUM_SAMPLES_MAX;
194+
}
147195

148196
/* connect to the HAL */
149197
comp_id = hal_init("halscope");
@@ -161,6 +209,10 @@ int main(int argc, gchar * argv[])
161209
hal_exit(comp_id);
162210
exit(1);
163211
}
212+
} else {
213+
/* scope_rt already loaded - we'll check if sample count matches later */
214+
rtapi_print_msg(RTAPI_MSG_DBG,
215+
"SCOPE: scope_rt already loaded, requested %d samples\n", num_samples);
164216
}
165217
/* set up a shared memory region for the scope data */
166218
shm_id = rtapi_shmem_new(SCOPE_SHM_KEY, comp_id, sizeof(scope_shm_control_t));
@@ -191,6 +243,16 @@ int main(int argc, gchar * argv[])
191243
ctrl_usr = &ctrl_struct;
192244
init_usr_control_struct(shm_base);
193245

246+
/* check if loaded scope_rt has different sample count than requested */
247+
if (ctrl_shm->buf_len != num_samples) {
248+
rtapi_print_msg(RTAPI_MSG_WARN,
249+
"SCOPE: scope_rt was loaded with %d samples, but config requested %d.\n"
250+
"To change sample count, unload scope_rt first or restart LinuxCNC.\n",
251+
ctrl_shm->buf_len, num_samples);
252+
}
253+
/* store requested samples for saving to config */
254+
ctrl_usr->horiz.requested_samples = num_samples;
255+
194256
/* init watchdog */
195257
ctrl_shm->watchdog = 10;
196258
/* set main window */
@@ -278,6 +340,33 @@ void start_capture(void)
278340
/* already running! */
279341
return;
280342
}
343+
344+
/* Check if data is from log file */
345+
if (ctrl_usr->data_from_log_file) {
346+
GtkWidget *dialog = gtk_message_dialog_new(
347+
GTK_WINDOW(ctrl_usr->main_win),
348+
GTK_DIALOG_MODAL,
349+
GTK_MESSAGE_WARNING,
350+
GTK_BUTTONS_OK_CANCEL,
351+
_("Overwrite loaded log file data?"));
352+
353+
gtk_message_dialog_format_secondary_text(
354+
GTK_MESSAGE_DIALOG(dialog),
355+
_("Starting acquisition will clear the data loaded from the CSV file. Continue?"));
356+
357+
int response = gtk_dialog_run(GTK_DIALOG(dialog));
358+
gtk_widget_destroy(dialog);
359+
360+
if (response != GTK_RESPONSE_OK) {
361+
/* User cancelled, switch back to STOP mode */
362+
set_run_mode(STOP);
363+
return;
364+
}
365+
366+
/* Clear the flag */
367+
ctrl_usr->data_from_log_file = 0;
368+
}
369+
281370
for (n = 0; n < 16; n++) {
282371
/* point to user space channel data */
283372
chan = &(ctrl_usr->chan[n]);
@@ -436,12 +525,41 @@ static void init_usr_control_struct(void *shmem)
436525
/* set all 16 channels to "no source assigned" */
437526
for (n = 0; n < 16; n++) {
438527
ctrl_usr->chan[n].data_source_type = -1;
528+
ctrl_usr->chan[n].is_phantom = 0;
439529
}
530+
ctrl_usr->data_from_log_file = 0;
440531
/* done */
441532
}
442533

443534
static void menuitem_response(gchar *string) {
444-
printf("%s\n", string);
535+
if (strcmp(string, "file/open datafile") == 0) {
536+
open_log_cb(GTK_WINDOW(ctrl_usr->main_win));
537+
} else {
538+
printf("%s\n", string);
539+
}
540+
}
541+
542+
void open_log_cb(GtkWindow *parent)
543+
{
544+
GtkWidget *filew;
545+
GtkFileChooser *chooser;
546+
547+
filew = gtk_file_chooser_dialog_new(_("Open Log File:"),
548+
parent,
549+
GTK_FILE_CHOOSER_ACTION_OPEN,
550+
_("_Cancel"), GTK_RESPONSE_CANCEL,
551+
_("_Open"), GTK_RESPONSE_ACCEPT,
552+
NULL);
553+
554+
chooser = GTK_FILE_CHOOSER(filew);
555+
set_file_filter(chooser, "Text CSV (.csv)", "*.csv");
556+
557+
if (gtk_dialog_run(GTK_DIALOG(filew)) == GTK_RESPONSE_ACCEPT) {
558+
char *filename = gtk_file_chooser_get_filename(chooser);
559+
read_log_file(filename);
560+
g_free(filename);
561+
}
562+
gtk_widget_destroy(filew);
445563
}
446564

447565
static void about(void) {
@@ -546,7 +664,7 @@ static void define_menubar(GtkWidget *vboxtop) {
546664
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), fileopendatafile);
547665
g_signal_connect_swapped(fileopendatafile, "activate",
548666
G_CALLBACK(menuitem_response), "file/open datafile");
549-
gtk_widget_set_sensitive(GTK_WIDGET(fileopendatafile), FALSE); // XXX
667+
gtk_widget_set_sensitive(GTK_WIDGET(fileopendatafile), TRUE);
550668
gtk_widget_show(fileopendatafile);
551669

552670
filesavedatafile = gtk_menu_item_new_with_mnemonic(_("S_ave Log File"));
@@ -626,9 +744,9 @@ static void define_scope_windows(void)
626744
{
627745
GtkWidget *vbox, *hbox, *vboxtop, *vboxbottom, *vboxleft, *vboxright, *hboxright;
628746

629-
/* create main window, set its minimum size and title */
747+
/* create main window, set its default size and title */
630748
ctrl_usr->main_win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
631-
gtk_widget_set_size_request(GTK_WIDGET(ctrl_usr->main_win), 650, 400);
749+
gtk_window_set_default_size(GTK_WINDOW(ctrl_usr->main_win), 1050, 550);
632750
gtk_window_set_title(GTK_WINDOW(ctrl_usr->main_win), _("HAL Oscilloscope"));
633751

634752
/* top level - big vbox, menu above, everything else below */

0 commit comments

Comments
 (0)