/*********************************************************************
SimpleCom. Basic interactive CL serial communication.
© Copyright 2013, BitFlow, Inc. All rights reserved.
2012 BitFlow/Tim original entry
$Author: steve $
$Date: 2015/06/23 17:11:03 $
$Id: SimpleCom.c,v 1.3 2015/06/23 17:11:03 steve Exp $
*********************************************************************/
/*==================================================================*/
/*
** For access to command line display.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
** For checking keypress
*/
#include <sys/time.h>
#include <sys/types.h>
/*
** For access to Bitflow camera interface
*/
#include "BFciLib.h"
#include "BF_Karbon_field.h"
/*====================================================================*/
static tCIp sCIp = NULL; /* device open token */
static int sExitAns; /* program exit code */
/*--------------------------------------------------------------------*/
#define SHOW(x) { (void)printf x ; (void)fflush(stdout); }
#define ERR(x) { SHOW(("ERR: ")); SHOW(x); }
static char *sArgv0 = NULL; /* name of executable */
static void ShowHelp(void)
{
SHOW(("%s \n\n", sArgv0));
SHOW(("Simple interactive CL serial comm.\n"));
SHOW(("Opens VFGx and initializes if needed.\n\n"));
SHOW(("Default settings are 9600 baud, 1 stop bit, no parity.\n"));
SHOW(("\t-h Show this message and exit.\n"));
SHOW(("\t-x VFG number to open.\n"));
SHOW(("\t-s D P S B Serial settings. Data bits, parity. stopbits, baud.\n"));
}
/*=====================================================================*/
static int CheckForKeyboardInput(char *buff)
/*
** Return 0 if no input available from stdin, 1 else
**
** Note: console needs a newline in order to post input.
*/
{
fd_set exceptfds, readfds, writefds;
struct timeval tv;
int ans;
FD_ZERO(&exceptfds);
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(fileno(stdin), &readfds);
(void)memset(&tv, '\0', sizeof(struct timeval));
ans = select(1, &readfds, &writefds, &exceptfds, &tv);
if ((ans == 1) && FD_ISSET(fileno(stdin), &readfds))
{
//get the line
(void)fgets(buff, 1024, stdin);
return (1);
}
return (0);
}
/*---------------------------------------------------------------------*/
void WriteMsg(char *msg)
{
tCIRC circ;
int len = strlen(msg);
char CR = '\r';
//need to replace LF with CR
msg[len - 1] = CR;
len = strlen(msg);
circ = CiCLwriteBytes(sCIp, len, (tCIU8 *) msg);
if (circ != kCIEnoErr)
{
ERR(("CiCLwriteByes gave '%s'\n", CiErrStr(circ)));
sExitAns = 1;
return;
}
}
void ReadMsg(char *buff, int buffsize)
{
tCIRC circ;
tCIU32 size = 0;
circ = CiCLreadBytes(sCIp, buffsize - 1, &size, (tCIU8 *) buff);
buff[size] = '\0';
if (circ != kCIEnoErr)
{
ERR(("CiCLreadByes gave '%s'\n", CiErrStr(circ)));
sExitAns = 1;
return;
}
}
int OpenAndInit(int bd, int flag)
{
tCIU32 circ;
tCIU32 init_state;
circ = CiVFGopen(bd, flag, &(sCIp));
if (circ != kCIEnoErr)
{
ERR(("CiVFGopen gave '%s'\n", CiErrStr(circ)));
}
//Check if the board needs fw and initialze.
//Serial com will not work if fw is not loaded.
circ = CiVFGqueryState(sCIp, &init_state);
if (circ != kCIEnoErr)
{
ERR(("CiVFGqueryState gave '%s'\n", CiErrStr(circ)));
return circ;
}
if (init_state == kCIBQ_needsFirmware)
{
SHOW(("Initializing...\n"))
circ = CiVFGinitialize(sCIp, kBFDEFAULTCFGFILE);
if (circ != kCIEnoErr)
{
ERR(("CiVFGinitialize gave '%s'\n", CiErrStr(circ)));
return circ;
}
}
return circ;
}
int Close(void)
{
tCIU32 circ;
circ = CiCLterm(sCIp);
if (circ != kCIEnoErr)
{
ERR(("CiCLterm gave '%s'\n", CiErrStr(circ)));
return circ;
}
circ = CiVFGclose(sCIp);
if (circ != kCIEnoErr)
{
ERR(("CiVFGclose gave '%s'\n", CiErrStr(circ)));
return circ;
}
SHOW(("Closed board. Goodbye.\n"));
return 0;
}
int main(int argc, char **argv)
{
int x = 0, y = 1, z = 0; //default to VFG 0(x=0) with flag = 1.
int baud9600 = 1, dataBits = 8, parity = 0, stopBits = 1; //baud rate equal to 9600*baud9600.
char *str;
tCIRC circ;
tCIU32 avail;
tCIU8 buff[1024];
tCIU8 msg[1024];
tCIU8 exitcode[2];
sArgv0 = *argv;
//Parse arguments
argv += 1;
argc -= 1; /*Skip the program name */
while (argc-- > 0)
{
str = *argv++;
if (str[0] != '-')
{
ERR(("Do not know '%s' arg\n", str));
ShowHelp();
exit(1);
}
switch (str[1])
{
case 'h':
ShowHelp();
exit(0);
case 'x':
x = atoi(*argv);
argv += 1;
argc -= 1;
break;
case 's':
dataBits = atoi(*argv);
argv += 1;
argc -= 1;
parity = atoi(*argv);
argv += 1;
argc -= 1;
stopBits = atoi(*argv);
argv += 1;
argc -= 1;
baud9600 = atoi(*argv);
argv += 1;
argc -= 1;
break;
default:
ERR(("Invalid input argument '%s'\n", str));
ShowHelp();
break;
}
}
SHOW(("Opening board...\n"));
//Check if the board is initialized and init if needed.
circ = OpenAndInit(x, y);
//Initialize serial interface
circ = CiCLinit(sCIp, dataBits, parity, stopBits, baud9600);
if (circ != kCIEnoErr)
{
ERR(("CiCLinit gave '%s'\n", CiErrStr(circ)));
}
//for comparison
strncpy((char *)exitcode, "x\r", 2);
SHOW(("Ready for Serial write and read\n"));
SHOW(("Press x to exit\n"));
while (!circ)
{
z = CheckForKeyboardInput((char *)msg);
if (z)
{
//SHOW(("%s \n", msg));
if (!(strncmp((char *)msg, (char *)exitcode, 1)))
{
break;
}
WriteMsg((char *)msg);
}
else
{
circ = CiCLgetBytesAvail(sCIp, &avail);
if (avail != 0)
{
ReadMsg((char *)buff, sizeof(buff));
SHOW(("%s", buff));
}
}
}
sExitAns = Close();
return sExitAns;
}
/*==================================================================*/
/*
$Log: SimpleCom.c,v $
Revision 1.3 2015/06/23 17:11:03 steve
Ready for ndif and cxp2
Revision 1.2 2015-01-15 17:24:40 steve
Cyton available
Revision 1.1 2013-03-03 18:58:11 steve
Ready w/CXP
*/