-
Notifications
You must be signed in to change notification settings - Fork 8
/
nanotiny_command.c
141 lines (108 loc) · 4 KB
/
nanotiny_command.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// SPDX-License-Identifier: GPL-3.0-or-later
// A simple gateway to the NanoVNA shell commands for use in automatisation scripts.
// usage: nanovna_command <COMMAND> <ARG1> <ARG2> ...
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
const char *nano_port = "/dev/ttyACM0";
static int nano_fd = 0;
static int nano_open() {
nano_fd = open( nano_port, O_RDWR | O_NOCTTY | O_SYNC );
if ( nano_fd < 0 ) {
fprintf( stderr, "Error opening %s: %s\n", nano_port, strerror( errno ) );
exit( -1 );
}
return nano_fd;
}
static int nano_close() { return close( nano_fd ); }
static int nano_set_interface_attribs( int speed ) {
struct termios tty;
if ( tcgetattr( nano_fd, &tty ) < 0 ) {
fprintf( stderr, "Error from tcgetattr: %s\n", strerror( errno ) );
return -1;
}
cfsetospeed( &tty, (speed_t)speed );
cfsetispeed( &tty, (speed_t)speed );
tty.c_cflag |= ( CLOCAL | CREAD ); /* ignore modem controls */
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag &= ~PARENB; /* no parity bit */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
/* setup for non-canonical mode */
tty.c_iflag &= ~( IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON );
tty.c_lflag &= ~( ECHO | ECHONL | ICANON | ISIG | IEXTEN );
tty.c_oflag &= ~OPOST;
/* fetch bytes as they become available */
tty.c_cc[ VMIN ] = 1;
tty.c_cc[ VTIME ] = 1;
if ( tcsetattr( nano_fd, TCSANOW, &tty ) != 0 ) {
fprintf( stderr, "Error from tcsetattr: %s\n", strerror( errno ) );
return -1;
}
return 0;
}
// read from input and echo the char until pattern was received, do not echo the pattern
static int nano_wait_for( const char *pattern, int echo ) {
int matched = 0;
int len = strlen( pattern );
uint8_t c;
while ( matched < len ) { // still no match
if ( 1 != read( nano_fd, &c, 1 ) ) // read error
return -1;
if ( c == pattern[ matched ] ) { // possible match, do not echo
++matched;
} else { // nope
if ( echo ) {
if ( matched ) { // if there was a partial match then echo the suppressed chars
for ( int iii = 0; iii < matched; ++iii )
putchar( pattern[ iii ] );
}
putchar( c ); // echo all non matching char
}
matched = 0;
}
}
return 0;
}
static int nano_send_string( const char *string ) {
int len = strlen( string );
int written = write( nano_fd, string, len );
if ( written != len ) {
fprintf( stderr, "Error from write: %d, %d\n", written, errno );
return -1;
}
tcdrain( nano_fd ); /* delay for output */
return 0;
}
static void nano_send_command( const char *cmd ) {
nano_send_string( cmd ); // send the command
nano_send_string( "\r" ); // .. terminated with CR
nano_wait_for( cmd, 0 ); // wait for cmd but do not echo
nano_wait_for( "\r\n", 0 ); // .. terminated by CR LF (no echo)
}
int main( int argc, char **argv ) {
char cmdline[ 260 ] = "";
if ( 0 == --argc ) // return if no argument
return 1;
strncat( cmdline, *( ++argv ), 256 ); // get 1st part
while ( --argc ) { // add other parts separated by one space
int len = strlen( cmdline );
if ( len < 250 ) {
strcat( cmdline, " " ); // separator
++len;
strncat( cmdline, *( ++argv ), 256 - len ); // no longer than 256
}
}
nano_open(); // connect to NanoVNA
nano_set_interface_attribs( B115200 ); // baudrate 115200, 8 bits, no parity, 1 stop bit
nano_send_command( cmdline ); // send the complete line
nano_wait_for( "ch> ", 1 ); // .. got it
nano_close();
return 0;
}