part 0 44 bytes
his is a multi-part message in MIME format.
part 1 1195 bytes content-type:text/plain; charset=us-ascii; format=flowed (decoded 7bit)
Here is a VERY (!!) simple sollution, it compiles with gcc 3.2.2 and
glibc 2.3.1 .
Read at the bottom of the C source file how to use it.
Hope this helps
Francisco
Andrew Seddon wrote:
{Quote hidden}>Can anybody recommend some terminal software with the following
>functionality.
>
>1.) Ability to view and send raw HEX, preferably binary too.
>2.) Hopefully some direct control over RTS, CTS (i.e see what the
>current state's are and change manually)
>3.) Free/Shareware
>4.) The ability to pre-compile hex packets to be sent out on
>command.
>
>I've tried Docklight which seems ideal, except for the fact that it
>doesn't allow you to use hardware flow control?? I`ve also tried a few
>other programs all of which can receive in HEX but not TX.
>
>Any help much appreciated.
>
>Cheers.
>
>
>--
>
http://www.piclist.com hint: The PICList is archived three different
>ways. See
http://www.piclist.com/#archives for details.
>
>
>.
>
>
>
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.
part 2 640 bytes content-type:text/plain;
(decoded 7bit)
# makefile by Francisco Ares <spam_OUTfraresTakeThisOuT
netscape.net>
BASENAME = miniterm
OPTIMIZER = -O3
HOSTCC = gcc
#CFLAGS = -g -Wall -pedantic -Wstrict-prototypes $(OPTIMIZER) -fomit-frame-pointer
GTK_CFLAGS = $(shell /usr/bin/pkg-config --cflags --libs gtk+-2.0)
CFLAGS = -g -Wall -pedantic
OBJS = ${BASENAME}.o
all : ${BASENAME}.o
${HOSTCC} ${CFLAGS} -o ${BASENAME} ${BASENAME}.o
clean:
rm -f *.o *.a ${BASENAME}
install :
cp ${BASENAME} ~/bin/
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.
part 3 16029 bytes content-type:text/x-csrc;
(decoded 7bit)
/*
* AUTHOR: Sven Goldt (.....goldtKILLspam
@spam@math.tu-berlin.de)
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*
This is like all programs in the Linux Programmer's Guide meant
as a simple practical demonstration.
It can be used as a base for a real terminal program.
*/
/*
* updated by Francisco J. A. Ares (frares
KILLspamnetscape.net)
* for newer include files for glibc 2.3.1
*/
/*
* altered to work with RS232 controllable device by
* Francisco J. A. Ares (.....fraresKILLspam
.....netscape.net)
*/
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BAUDRATE B9600
#define ENDMINITERM 4 /* ctrl-d to quit miniterm */
#define CRETURN 0x0d
#define NLINE 0x0a
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
int hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
/* default serial device */
char SerialDevice[20] = "/dev/ttyS1";
/* default behavior for CRC sending */
char SendCRC = FALSE;
/* default numer of characters to be sent */
int CharsToSend = 0;
/* default number of chars to receive until EOL */
int CharsToGet = 0;
void child_handler(int s)
{
STOP=TRUE;
}
void CommandLineInterpreter(int argc, char *argv[])
{
int i;
if ( ( argv[1] == "--help" ) || ( argv[1] == "-h" ) )
{
perror("miniterm [-d <serial device>] [-c] [-ns <count to send>] [-nr <count to receive>]");
exit (-1);
}
else
{
for (i=1;i<argc;i++)
{
if (strcmp (argv[i], "-d") == 0)
strcpy (SerialDevice,argv[i+1]);
if (strcmp (argv[i], "-c") == 0)
SendCRC = TRUE;
if (strcmp (argv[i], "-ns") == 0)
CharsToSend = (int) strtol(argv[i+1], 0, 10);
if (strcmp (argv[i], "-nr") == 0)
CharsToGet = (int) strtol(argv[i+1], 0, 10 );
}
}
}
int main(int argc, char *argv[])
{
int fd, c1, c2, ac;
struct termios oldtio, newtio, oldstdtio, newstdtio;
struct sigaction sa;
int outbuf[16]; /* buffer only 16 bytes long */
CommandLineInterpreter(argc, argv);
ac = 0;
/* Open serial device for reading and writing and not as controlling tty
because we don't want to get killed if linenoise sends CTRL-C. */
fd = open(SerialDevice, O_RDWR | O_NOCTTY);
if (fd <0)
{
perror(SerialDevice);
exit(-1);
}
tcgetattr(fd,&oldtio); /* save current modem settings */
/* Set bps rate and hardware flow control and 8n1 (8bit,no parity,1 stopbit).
Also don't hangup automatically and ignore modem status.
Finally enable receiving characters. */
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
/* Ignore bytes with parity errors and make terminal raw and dumb. */
newtio.c_iflag = IGNPAR;
/* Raw output. */
newtio.c_oflag = 0;
/* Don't echo characters because if you connect to a host it or your
modem will echo characters for you. Don't generate signals. */
newtio.c_lflag = 0;
/* blocking read until 1 char arrives */
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
/* now clean the modem line and activate the settings for modem */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/* next stop echo and buffering for stdin */
tcgetattr(0,&oldstdtio);
tcgetattr(0,&newstdtio); /* get working stdtio */
newstdtio.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0,TCSANOW,&newstdtio);
/* command line parameters checklist - "printf" and "puts" use stdout */
printf ( "\nUsing %s\n", SerialDevice);
if (SendCRC)
puts ( "Sending CRC"); /* "puts" already sends a newline */
else
puts ( "NOT sending CRC");
if (CharsToSend>0)
printf ( "Sending %d chars\n", CharsToSend);
else
puts ( "Sending chars until <ENTER>");
if (CharsToGet>0)
printf ( "Receiving %d chars\n\n", CharsToGet);
else
puts ( "Receiving chars until <ENTER>\n"); /* "puts" already sends a newline, and I want another one */
/* terminal settings done, now handle in/ouput */
switch (fork())
{
case 0: /* child */
/* user input */
c1=getchar();
while ( c1 != ENDMINITERM )
{
if ( c1 != ENDMINITERM )
{
if ( CharsToSend > 0)
{
/* hex digits, fixed number of bytes to be sent */
for ( ac = 0; ac < (SendCRC?CharsToSend-1:CharsToSend); ac++ )
{
/* get hex digits */
write(1,&c1,1); /* stdout */
c2 = getchar();
write(1,&c2,1);
/* converts two nibble chars to one only byte */
c1= ( ( c1 < 0x3a ?
c1 & 0x0f :
( c1 & 0x5f ) + 9 - 0x40 )
<< 4 ) |
( c2 < 0x3a ?
c2 & 0x0f :
( c2 & 0x5f ) + 9 - 0x40 ) ;
/* put new byte in buffer */
outbuf[ac] = c1;
/* separating hex digits on stdout (screen, basically) */
c2 = ' ';
write(1,&c2,1);
/* done with all bytes? */
if (ac != (SendCRC?CharsToSend-2:CharsToSend-1) )
c1 = getchar();
}
/* send bytes and calculate check summ */
ac = 0;
for ( c2 = 0 ; c2 < (SendCRC?CharsToSend-1:CharsToSend) ; c2++ )
{
c1 = outbuf[c2];
ac += c1;
write(fd,&c1,1);
}
}
else
{
/* typed chars are the bytes to be sent */
c2 = 0;
/* done with all bytes? */
while (c1 != NLINE)
{
/* put new byte in buffer */
outbuf[c2] = c1;
write(1,&c1,1); /* stdout */
c2++;
c1 = getchar();
}
/* text delimiters to external device (maybe some more command line parameters here) */
outbuf[c2] = CRETURN;
c2++;
outbuf[c2] = NLINE;
c2++;
outbuf[c2] = 0;
/* send bytes and calculate check summ */
ac = 0;
c2 = 0;
c1 = outbuf[c2];
while (c1 != NLINE)
{
c1 = outbuf[c2];
ac += c1;
write(fd,&c1,1);
c2++;
}
}
/* common part for both ways of typing bytes/chars */
if (SendCRC)
{
/* separating digits on stdout (screen, basically) */
c2 = ' '; /* extra space to checksum byte */
write(1,&c2,1);
write(fd,&ac,1); /* serial device */
/* converts one byte to two hex nibbles */
c2 = hex[ ( ac & 0xf0 ) >> 4 ]; write(1,&c2,1);
c2 = hex[ ac & 0x0f ]; write(1,&c2,1);
}
/* separating (at least trying to) input / output */
c2 = ' ';
write(1,&c2,1);
c2 = '-';
write(1,&c2,1);
c2 = ' ';
write(1,&c2,1);
/* delay - have to find something better */
for ( c1 = 0; c1 <= 0x1fff; c1++)
for ( c2 = 0; c2 <= 0x1fff; c2++)
;
/* new line on display anyhow, no matter if I get one through the serial */
c2 = NLINE;
write(1,&c2,1);
c1=getchar();
}
}
/* gracefully quit, child part */
tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */
tcsetattr(0,TCSANOW,&oldstdtio); /* restore old tty setings */
close(fd);
exit(0); /* will send a SIGCHLD to the parent */
break;
case -1:
perror("fork");
tcsetattr(fd,TCSANOW,&oldtio);
close(fd);
exit(-1);
default: /* parent */
/* stdin not needed */
close(0);
/* handle dying child */
sa.sa_handler = child_handler;
sa.sa_flags = 0;
sigaction(SIGCHLD,&sa,NULL);
/* serial device input handler */
while (STOP==FALSE)
{
read(fd,&c1,1); /* serial device */
if (STOP==FALSE)
{
if (CharsToGet != 0)
{
/* hex digits, fixed number of bytes to be received */
/* converts one byte to two hex nibbles */
c2 = hex[ ( c1 & 0xf0 ) >> 4 ];
write(1,&c2,1);
c2 = hex[ c1 & 0x0f ];
write(1,&c2,1);
c2 = ' ';
write(1,&c2,1);
/* done with all bytes? */
if ( ++ac == CharsToGet)
{
c2 = NLINE;
write(1,&c2,1); /* stdout */
ac = 0;
}
}
else
{
/* bytes received are just echoed to stdout */
if ( ( c1 == NLINE ) || ( c1 == CRETURN) )
c1 = ' ';
write(1,&c1,1); /* stdout */
}
}
}
/* gracefully quit, parent part */
c2 = NLINE;
write(1,&c2,1); /* stdout */
close(1);
/* wait for child to die or it will become a zombie */
wait(NULL);
break;
}
return (0);
}
/*
* Mitsubishi camera example:
* - program command line: miniterm -d /dev/ttyS1
* - manual iris adjust RS232 command: "IRM-30" ... "IRM+30" followed by CR + LF (using <ENTER> as end of input)
* - expected answer: "RE" + CR + LF + "SE0007" + CR + LF
* - screenshot:
* IRM17 - RE
* SE0007
*
* IRM18 - RE
* SE0007
*
* IRM31 - ERR1
*
* IRM30 - RE
* SE0007
*
*
* Another camera example:
* - program command line: miniterm -d /dev/ttyS1 -ns 6 -nr 9 -c
* - manual iris adjust RS232 command: c5 aa 7c <iris level> 00 <cam. ID> <CRC>
* - expected answer: c5 aa 7c <iris level> 7c XX XX XX <CRC> ( XX means don't care )
* - screenshot:
* c5 aa 7c df 00 CA - C5 AA 7C DF 7C 07 04 56 A7
*
* c5 aa 7c ff 00 EA - C5 AA 7C FF 7C 07 04 56 C7
*
*
* note that when the checksum is in use, it is one of the number
* of bytes to be sent specified on the command line parameter.
*
* crtl-D exits from the program at the beginning of a new command.
*/