Add native Sigrok writer (#1297)
This commit is contained in:
parent
ee43b82aac
commit
44d2af5e27
9 changed files with 269 additions and 124 deletions
|
@ -1,61 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] ; then
|
||||
echo input file missing
|
||||
echo "Usage: $0 input.cu8 output.sr [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -r "$1" ] ; then
|
||||
echo input not found
|
||||
echo "Usage: $0 input.cu8 output.sr [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
file=$1
|
||||
|
||||
if [ -z "$2" ] ; then
|
||||
echo output file missing
|
||||
echo "Usage: $0 input.cu8 output.sr [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
if [ -e "$2" ] ; then
|
||||
echo output already exists
|
||||
echo "Usage: $0 input.cu8 output.sr [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
out=$2
|
||||
|
||||
if [ -z "$3" ] ; then
|
||||
rate=250
|
||||
else
|
||||
rate=$3
|
||||
fi
|
||||
|
||||
if [ ! -z "$4" ] ; then
|
||||
echo too many arguments
|
||||
echo "Usage: $0 input.cu8 output.sr [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create channels
|
||||
rtl_433 -s ${rate}k -r "$file" -w F32:I:analog-1-4-1 -w F32:Q:analog-1-5-1 -w F32:AM:analog-1-6-1 -w F32:FM:analog-1-7-1 -w U8:LOGIC:logic-1-1 >/dev/null 2>&1
|
||||
# create version tag
|
||||
echo -n "2" >version
|
||||
# create meta data
|
||||
cat >metadata <<EOF
|
||||
[device 1]
|
||||
capturefile=logic-1
|
||||
total probes=3
|
||||
samplerate=$rate kHz
|
||||
total analog=4
|
||||
probe1=FRAME
|
||||
probe2=ASK
|
||||
probe3=FSK
|
||||
analog4=I
|
||||
analog5=Q
|
||||
analog6=AM
|
||||
analog7=FM
|
||||
unitsize=1
|
||||
EOF
|
||||
|
||||
zip "$out" version metadata analog-1-4-1 analog-1-5-1 analog-1-6-1 analog-1-7-1 logic-1-1
|
||||
rm version metadata analog-1-4-1 analog-1-5-1 analog-1-6-1 analog-1-7-1 logic-1-1
|
||||
echo 'Please use "rtl_433 [-s <samplerate>] -w <output>.sr -r <input>.cu8"'
|
||||
|
|
|
@ -1,67 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ] ; then
|
||||
echo input file missing
|
||||
echo "Usage: $0 input.cu8 [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -r "$1" ] ; then
|
||||
echo input not found
|
||||
echo "Usage: $0 input.cu8 [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
file=$1
|
||||
|
||||
filename=$(basename "$file")
|
||||
tempdir=$(mktemp -d)
|
||||
out="$tempdir/$filename.sr"
|
||||
trap "rm -f -- '$out'; rmdir -- '$tempdir'" EXIT
|
||||
|
||||
if [ -z "$2" ] ; then
|
||||
rate=250
|
||||
else
|
||||
rate=$2
|
||||
fi
|
||||
|
||||
if [ ! -z "$3" ] ; then
|
||||
echo too many arguments
|
||||
echo "Usage: $0 input.cu8 [sample rate in kHz]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create channels
|
||||
rtl_433 -s ${rate}k -r "$file" -w F32:I:analog-1-4-1 -w F32:Q:analog-1-5-1 -w F32:AM:analog-1-6-1 -w F32:FM:analog-1-7-1 -w U8:LOGIC:logic-1-1 >/dev/null 2>&1
|
||||
# create version tag
|
||||
echo -n "2" >version
|
||||
# create meta data
|
||||
cat >metadata <<EOF
|
||||
[device 1]
|
||||
capturefile=logic-1
|
||||
total probes=3
|
||||
samplerate=$rate kHz
|
||||
total analog=4
|
||||
probe1=FRAME
|
||||
probe2=ASK
|
||||
probe3=FSK
|
||||
analog4=I
|
||||
analog5=Q
|
||||
analog6=AM
|
||||
analog7=FM
|
||||
unitsize=1
|
||||
EOF
|
||||
|
||||
zip "$out" version metadata analog-1-4-1 analog-1-5-1 analog-1-6-1 analog-1-7-1 logic-1-1
|
||||
rm version metadata analog-1-4-1 analog-1-5-1 analog-1-6-1 analog-1-7-1 logic-1-1
|
||||
|
||||
case "$OSTYPE" in
|
||||
darwin*)
|
||||
open -b org.sigrok.PulseView --fresh --new --wait-apps --args -i "$out"
|
||||
;;
|
||||
*)
|
||||
pulseview -i "$out"
|
||||
;;
|
||||
esac
|
||||
|
||||
rm -f -- "$out"
|
||||
rmdir -- "$tempdir"
|
||||
trap - EXIT
|
||||
echo 'Please use "rtl_433 [-s <samplerate>] -W <output>.sr -r <input>.cu8"'
|
||||
|
|
|
@ -86,6 +86,10 @@ void add_null_output(struct r_cfg *cfg, char *param);
|
|||
|
||||
void start_outputs(struct r_cfg *cfg, char const **well_known);
|
||||
|
||||
void add_sr_dumper(struct r_cfg *cfg, char const *spec, int overwrite);
|
||||
|
||||
void close_dumpers(struct r_cfg *cfg);
|
||||
|
||||
void add_dumper(struct r_cfg *cfg, char const *spec, int overwrite);
|
||||
|
||||
void add_infile(struct r_cfg *cfg, char *in_file);
|
||||
|
|
|
@ -94,6 +94,8 @@ typedef struct r_cfg {
|
|||
char *output_tag;
|
||||
list_t output_handler;
|
||||
struct dm_state *demod;
|
||||
char const *sr_filename;
|
||||
int sr_execopen;
|
||||
int old_model_keys;
|
||||
/* stats*/
|
||||
unsigned frames_count; ///< stats counter for interval
|
||||
|
|
31
include/write_sigrok.h
Normal file
31
include/write_sigrok.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/** @file
|
||||
Sigrok Pulseview format writer.
|
||||
|
||||
Copyright (C) 2020 by Christian Zuckschwerdt <zany@triq.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_WRITE_SIGROK_
|
||||
#define INCLUDE_WRITE_SIGROK_
|
||||
|
||||
/** Write a Sigrok file from data dump files.
|
||||
|
||||
@param filename file to write
|
||||
@param samplerate sample rate for the channels
|
||||
@param probes number of binary channels, needs "logic-1-1" file
|
||||
@param analogs number of analog channels, needs "analog-1-N-1" with N starting at probes+1
|
||||
@param labels channel labels, probes+analog strings or NULL for generic labels
|
||||
*/
|
||||
void write_sigrok(char const *filename, unsigned samplerate, unsigned probes, unsigned analogs, char const *labels[]);
|
||||
|
||||
/** Open a file in a forked Pulseview.
|
||||
|
||||
@param filename file to open in Pulseview
|
||||
*/
|
||||
void open_pulseview(char const *filename);
|
||||
|
||||
#endif /* INCLUDE_WRITE_SIGROK_ */
|
|
@ -29,6 +29,7 @@ add_library(r_433 STATIC
|
|||
sdr.c
|
||||
term_ctl.c
|
||||
util.c
|
||||
write_sigrok.c
|
||||
devices/acurite.c
|
||||
devices/akhan_100F14.c
|
||||
devices/alecto.c
|
||||
|
|
38
src/r_api.c
38
src/r_api.c
|
@ -28,6 +28,7 @@
|
|||
#include "optparse.h"
|
||||
#include "output_mqtt.h"
|
||||
#include "output_influx.h"
|
||||
#include "write_sigrok.h"
|
||||
#include "compat_time.h"
|
||||
#include "fatal.h"
|
||||
|
||||
|
@ -878,8 +879,45 @@ void add_null_output(r_cfg_t *cfg, char *param)
|
|||
list_push(&cfg->output_handler, NULL);
|
||||
}
|
||||
|
||||
void add_sr_dumper(r_cfg_t *cfg, char const *spec, int overwrite)
|
||||
{
|
||||
// create channels
|
||||
add_dumper(cfg, "U8:LOGIC:logic-1-1", overwrite);
|
||||
add_dumper(cfg, "F32:I:analog-1-4-1", overwrite);
|
||||
add_dumper(cfg, "F32:Q:analog-1-5-1", overwrite);
|
||||
add_dumper(cfg, "F32:AM:analog-1-6-1", overwrite);
|
||||
add_dumper(cfg, "F32:FM:analog-1-7-1", overwrite);
|
||||
cfg->sr_filename = spec;
|
||||
cfg->sr_execopen = overwrite;
|
||||
}
|
||||
|
||||
void close_dumpers(struct r_cfg *cfg)
|
||||
{
|
||||
char const *labels[] = {
|
||||
"FRAME", // probe1
|
||||
"ASK", // probe2
|
||||
"FSK", // probe3
|
||||
"I", // analog4
|
||||
"Q", // analog5
|
||||
"AM", // analog6
|
||||
"FM", // analog7
|
||||
};
|
||||
if (cfg->sr_filename) {
|
||||
write_sigrok(cfg->sr_filename, cfg->samp_rate, 3, 4, labels);
|
||||
}
|
||||
if (cfg->sr_execopen) {
|
||||
open_pulseview(cfg->sr_filename);
|
||||
}
|
||||
}
|
||||
|
||||
void add_dumper(r_cfg_t *cfg, char const *spec, int overwrite)
|
||||
{
|
||||
size_t spec_len = strlen(spec);
|
||||
if (spec_len >= 3 && !strcmp(&spec[spec_len - 3], ".sr")) {
|
||||
add_sr_dumper(cfg, spec, overwrite);
|
||||
return;
|
||||
}
|
||||
|
||||
file_info_t *dumper = calloc(1, sizeof(*dumper));
|
||||
if (!dumper)
|
||||
FATAL_CALLOC("add_dumper()");
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "term_ctl.h"
|
||||
#include "compat_paths.h"
|
||||
#include "fatal.h"
|
||||
#include "write_sigrok.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
|
@ -1465,12 +1466,18 @@ int main(int argc, char **argv) {
|
|||
fclose(in_file = stdin);
|
||||
}
|
||||
|
||||
close_dumpers(cfg);
|
||||
free(test_mode_buf);
|
||||
free(test_mode_float_buf);
|
||||
r_free_cfg(cfg);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (cfg->sr_filename) {
|
||||
fprintf(stderr, "SR writing not recommended for live input\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Normal case, no test data, no in files
|
||||
r = sdr_open(&cfg->dev, &demod->sample_size, cfg->dev_query, cfg->verbosity);
|
||||
if (r < 0) {
|
||||
|
|
184
src/write_sigrok.c
Normal file
184
src/write_sigrok.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/** @file
|
||||
Sigrok Pulseview format writer.
|
||||
|
||||
Copyright (C) 2020 by Christian Zuckschwerdt <zany@triq.net>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "write_sigrok.h"
|
||||
|
||||
void write_sigrok(char const *filename, unsigned samplerate, unsigned probes, unsigned analogs, char const *labels[])
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Writing Sigrok not implemented for win32\n");
|
||||
#else
|
||||
// e.g. uses channels
|
||||
// U8:LOGIC:logic-1-1
|
||||
// F32:I:analog-1-4-1
|
||||
// F32:Q:analog-1-5-1
|
||||
// F32:AM:analog-1-6-1
|
||||
// F32:FM:analog-1-7-1
|
||||
|
||||
// probe1=FRAME
|
||||
// probe2=ASK
|
||||
// probe3=FSK
|
||||
// analog4=I
|
||||
// analog5=Q
|
||||
// analog6=AM
|
||||
// analog7=FM
|
||||
|
||||
// create version tag
|
||||
FILE *fp = fopen("version", "w");
|
||||
if (!fp) {
|
||||
perror("creating Sigrok \"version\" file");
|
||||
return;
|
||||
}
|
||||
fprintf(fp, "2");
|
||||
fclose(fp);
|
||||
|
||||
// create meta data
|
||||
fp = fopen("metadata", "w");
|
||||
if (!fp) {
|
||||
perror("creating Sigrok \"metadata\" file");
|
||||
return;
|
||||
}
|
||||
fprintf(fp,
|
||||
"[device 1]\n"
|
||||
"samplerate=%u kHz\n"
|
||||
"capturefile=logic-1\n"
|
||||
"unitsize=1\n"
|
||||
"total probes=%u\n"
|
||||
"total analog=%u\n",
|
||||
samplerate / 1000, probes, analogs);
|
||||
if (labels) {
|
||||
char const **label = labels;
|
||||
for (unsigned i = 1; i <= probes; ++i)
|
||||
fprintf(fp, "probe%u=%s\n", i, *label++);
|
||||
for (unsigned i = probes + 1; i <= probes + analogs; ++i)
|
||||
fprintf(fp, "analog%u=%s\n", i, *label++);
|
||||
}
|
||||
else {
|
||||
for (unsigned i = 1; i <= probes; ++i)
|
||||
fprintf(fp, "probe%u=L%u\n", i, i);
|
||||
for (unsigned i = probes + 1; i <= probes + analogs; ++i)
|
||||
fprintf(fp, "analog%u=A%u\n", i, i);
|
||||
}
|
||||
|
||||
// EOF
|
||||
fclose(fp);
|
||||
|
||||
char *argv[30] = {0};
|
||||
int arg = 0;
|
||||
argv[arg++] = "zip";
|
||||
argv[arg++] = (char *)filename; // "out.sr"
|
||||
argv[arg++] = "version";
|
||||
argv[arg++] = "metadata";
|
||||
|
||||
if (probes) {
|
||||
argv[arg++] = "logic-1-1";
|
||||
}
|
||||
|
||||
char **argv_analog = &argv[arg];
|
||||
for (unsigned i = probes + 1; i <= probes + analogs; ++i) {
|
||||
asprintf(&argv[arg++], "analog-1-%u-1", i);
|
||||
}
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("forking zip");
|
||||
return;
|
||||
}
|
||||
else if (pid == 0) {
|
||||
// child process because return value zero
|
||||
execvp(argv[0], argv);
|
||||
// execvp() returns only on error
|
||||
for (int i = 0; i < arg; ++i)
|
||||
fprintf(stderr, "%s ", argv[i]);
|
||||
fprintf(stderr, "\n");
|
||||
perror("execvp");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
// parent process because return value non-zero
|
||||
wait(NULL);
|
||||
printf("Done!\n");
|
||||
}
|
||||
|
||||
// rm version metadata logic-1-1 analog-1-4-1 analog-1-5-1 analog-1-6-1 analog-1-7-1
|
||||
if (unlink("version")) {
|
||||
perror("unlinking Sigrok \"version\" file");
|
||||
}
|
||||
if (unlink("metadata")) {
|
||||
perror("unlinking Sigrok \"metadata\" file");
|
||||
}
|
||||
|
||||
if (probes) {
|
||||
if (unlink("logic-1-1")) {
|
||||
perror("unlinking Sigrok \"logic-1-1\" file");
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < analogs; ++i) {
|
||||
if (unlink(argv_analog[i])) {
|
||||
perror("unlinking Sigrok \"analog-1-N-1\" file");
|
||||
}
|
||||
free(argv_analog[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void open_pulseview(char const *filename)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "Opening Pulseview not implemented for win32\n");
|
||||
#else
|
||||
char *argv[9] = {0};
|
||||
int arg = 0;
|
||||
char *abspath = realpath(filename, NULL);
|
||||
#ifdef __APPLE__
|
||||
argv[arg++] = "open";
|
||||
argv[arg++] = "-b";
|
||||
argv[arg++] = "org.sigrok.PulseView";
|
||||
argv[arg++] = "--fresh";
|
||||
argv[arg++] = "--new";
|
||||
argv[arg++] = "--args";
|
||||
argv[arg++] = "-i";
|
||||
argv[arg++] = (char *)abspath;
|
||||
#else
|
||||
argv[arg++] = "pulseview";
|
||||
argv[arg++] = "-i";
|
||||
argv[arg++] = abspath;
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "Opening Pulseview...\n");
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("forking pulseview");
|
||||
return;
|
||||
}
|
||||
else if (pid == 0) {
|
||||
// child process because return value zero
|
||||
execvp(argv[0], argv);
|
||||
// execvp() returns only on error
|
||||
for (int i = 0; i < arg; ++i)
|
||||
fprintf(stderr, "%s ", argv[i]);
|
||||
fprintf(stderr, "\n");
|
||||
perror("execvp");
|
||||
exit(1);
|
||||
}
|
||||
else {
|
||||
// parent process because return value non-zero
|
||||
wait(NULL);
|
||||
}
|
||||
free(abspath);
|
||||
#endif
|
||||
}
|
Loading…
Add table
Reference in a new issue