Newer
Older
/* A simple console for accessing the SPEC virtual UART (i.e. for communicating with the WR Core shell
from a Linux terminal. */
Tomasz Wlostowski
committed
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <getopt.h>
#include <errno.h>
#include "speclib.h"
Tomasz Wlostowski
committed
static void *card;
Tomasz Wlostowski
committed
static int transfer_byte(int from, int is_control) {
Tomasz Wlostowski
committed
char c;
int ret;
do {
ret = read(from, &c, 1);
} while (ret < 0 && errno == EINTR);
if(ret == 1) {
if(is_control) {
if(c == '\x01') { // C-a
return -1;
Tomasz Wlostowski
committed
}
spec_vuart_tx(card, &c, 1);
Tomasz Wlostowski
committed
} else {
fprintf(stderr, "nothing to read. Port disconnected?\n");
Tomasz Wlostowski
committed
return -2;
}
return 0;
}
void term_main(int keep_term)
{
struct termios oldkey, newkey;
//above is place for old and new port settings for keyboard teletype
Tomasz Wlostowski
committed
int need_exit = 0;
fprintf(stderr, "[press C-a to exit]\n");
if(!keep_term) {
tcgetattr(STDIN_FILENO,&oldkey);
newkey.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newkey.c_iflag = IGNPAR;
newkey.c_oflag = 0;
newkey.c_lflag = 0;
newkey.c_cc[VMIN]=1;
newkey.c_cc[VTIME]=0;
tcflush(STDIN_FILENO, TCIFLUSH);
tcsetattr(STDIN_FILENO,TCSANOW,&newkey);
}
while(!need_exit) {
fd_set fds;
int ret;
char rx;
Tomasz Wlostowski
committed
struct timeval tv = {0, 10000};
Tomasz Wlostowski
committed
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
ret = select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
if(ret == -1) {
perror("select");
} else if (ret > 0) {
if(FD_ISSET(STDIN_FILENO, &fds)) {
need_exit = transfer_byte(STDIN_FILENO, 1);
Tomasz Wlostowski
committed
}
}
while((spec_vuart_rx(card, &rx, 1)) == 1)
fprintf(stderr,"%c", rx);
Tomasz Wlostowski
committed
}
if(!keep_term)
tcsetattr(STDIN_FILENO,TCSANOW,&oldkey);
}
int main(int argc, char **argv)
{
int bus = -1, dev_fn = -1, c;
Tomasz Wlostowski
committed
int keep_term = 0;
while ((c = getopt (argc, argv, "b:d:u:k")) != -1)
{
switch(c)
{
case 'b':
sscanf(optarg, "%i", &bus);
break;
case 'd':
sscanf(optarg, "%i", &dev_fn);
break;
case 'u':
sscanf(optarg, "%i", &vuart_base);
break;
case 'k':
keep_term = 1;
break;
default:
fprintf(stderr,
"Use: \"%s [-b bus] [-d devfn] "
"[-u VUART base] [-k]\"\n", argv[0]);
Tomasz Wlostowski
committed
fprintf(stderr,
"By default, the first available SPEC "
"is used and the VUART is assumed at 0x%x.\n"
"-k option keeps the prev terminal config\n",
vuart_base);
Tomasz Wlostowski
committed
exit(1);
}
}
card = spec_open(bus, dev_fn);
if(!card)
Tomasz Wlostowski
committed
{
fprintf(stderr, "Can't detect a SPEC card under the given "
Grzegorz Daniluk
committed
"adress.\nMake sure a SPEC card is present in your PC, "
"the driver is loaded and you run the program as root.\n");
Tomasz Wlostowski
committed
}
spec_vuart_init(card, vuart_base);
Tomasz Wlostowski
committed
term_main(keep_term);
spec_close(card);