Browse Source

Ran indent on code to fix inconsistent style.

git-svn-id: https://bucket.mit.edu/svn/nilm/acquisition/ethstream@7298 ddd99763-3ecb-0310-9145-efcb8ce7c51f
tags/ethstream-1.1
zacharyc 15 years ago
parent
commit
7f79ec8ff3
17 changed files with 2276 additions and 1928 deletions
  1. +73
    -46
      compat-win32.c
  2. +2
    -2
      compat.h
  3. +9
    -9
      debug.c
  4. +2
    -2
      debug.h
  5. +532
    -448
      ethstream.c
  6. +66
    -62
      ljconfig.c
  7. +42
    -41
      ljtest.c
  8. +478
    -389
      nerdjack.c
  9. +19
    -14
      nerdjack.h
  10. +199
    -176
      netutil.c
  11. +15
    -14
      netutil.h
  12. +88
    -75
      opt.c
  13. +10
    -9
      opt.h
  14. +622
    -526
      ue9.c
  15. +73
    -70
      ue9.h
  16. +45
    -44
      ue9error.c
  17. +1
    -1
      ue9error.h

+ 73
- 46
compat-win32.c View File

@@ -3,55 +3,83 @@
#include "compat.h" #include "compat.h"
#include <windows.h> #include <windows.h>


unsigned int sleep(unsigned int seconds)
unsigned int
sleep (unsigned int seconds)
{ {
Sleep(seconds * 1000);
return 0;
Sleep (seconds * 1000);
return 0;
} }


static struct {
int num;
char *msg;
} win32_error[] = {
/* Errors that we might vaguely expect to see */
{ WSAEINTR, "Winsock: Interrupted system call" },
{ WSAEBADF, "Winsock: Bad file number" },
{ WSAEFAULT, "Winsock: Bad address" },
{ WSAEINVAL, "Winsock: Invalid argument" },
{ WSAEMFILE, "Winsock: Too many open files" },
{ WSAEWOULDBLOCK, "Winsock: Operation would block" },
{ WSAEINPROGRESS, "Winsock: Operation now in progress" },
{ WSAEALREADY, "Winsock: Operation already in progress" },
{ WSAENOTSOCK, "Winsock: Socket operation on nonsocket" },
{ WSAEADDRINUSE, "Winsock: Address already in use" },
{ WSAEADDRNOTAVAIL, "Winsock: Cannot assign requested address" },
{ WSAENETDOWN, "Winsock: Network is down" },
{ WSAENETUNREACH, "Winsock: Network is unreachable" },
{ WSAENETRESET, "Winsock: Network dropped connection on reset" },
{ WSAECONNABORTED, "Winsock: Software caused connection abort" },
{ WSAECONNRESET, "Winsock: Connection reset by peer" },
{ WSAETIMEDOUT, "Winsock: Connection timed out" },
{ WSAECONNREFUSED, "Winsock: Connection refused" },
{ WSAEHOSTDOWN, "Winsock: Host is down" },
{ WSAEHOSTUNREACH, "Winsock: No route to host" },
{ WSAVERNOTSUPPORTED, "Winsock: Unsupported Winsock version" },
{ ETIMEDOUT, "Connection timed out" },
{ ENOTCONN, "Not connected" },
{ -1, NULL },
};
char *compat_strerror(int errnum)
static struct
{ {
int i;
static char buf[128];
for (i = 0; win32_error[i].num != -1; i++)
if (errnum == win32_error[i].num)
return win32_error[i].msg;
if (errnum >= 10000) {
sprintf(buf, "Winsock: unknown error %d\n", errnum);
return buf;
}
return strerror(errnum);
int num;
char *msg;
} win32_error[] =
{
/* Errors that we might vaguely expect to see */
{
WSAEINTR, "Winsock: Interrupted system call"},
{
WSAEBADF, "Winsock: Bad file number"},
{
WSAEFAULT, "Winsock: Bad address"},
{
WSAEINVAL, "Winsock: Invalid argument"},
{
WSAEMFILE, "Winsock: Too many open files"},
{
WSAEWOULDBLOCK, "Winsock: Operation would block"},
{
WSAEINPROGRESS, "Winsock: Operation now in progress"},
{
WSAEALREADY, "Winsock: Operation already in progress"},
{
WSAENOTSOCK, "Winsock: Socket operation on nonsocket"},
{
WSAEADDRINUSE, "Winsock: Address already in use"},
{
WSAEADDRNOTAVAIL, "Winsock: Cannot assign requested address"},
{
WSAENETDOWN, "Winsock: Network is down"},
{
WSAENETUNREACH, "Winsock: Network is unreachable"},
{
WSAENETRESET, "Winsock: Network dropped connection on reset"},
{
WSAECONNABORTED, "Winsock: Software caused connection abort"},
{
WSAECONNRESET, "Winsock: Connection reset by peer"},
{
WSAETIMEDOUT, "Winsock: Connection timed out"},
{
WSAECONNREFUSED, "Winsock: Connection refused"},
{
WSAEHOSTDOWN, "Winsock: Host is down"},
{
WSAEHOSTUNREACH, "Winsock: No route to host"},
{
WSAVERNOTSUPPORTED, "Winsock: Unsupported Winsock version"},
{
ETIMEDOUT, "Connection timed out"},
{
ENOTCONN, "Not connected"},
{
-1, NULL},};
char *
compat_strerror (int errnum)
{
int i;
static char buf[128];

for (i = 0; win32_error[i].num != -1; i++)
if (errnum == win32_error[i].num)
return win32_error[i].msg;
if (errnum >= 10000)
{
sprintf (buf, "Winsock: unknown error %d\n", errnum);
return buf;
}
return strerror (errnum);
} }


#ifdef __WIN32__ #ifdef __WIN32__
@@ -80,4 +108,3 @@ char *compat_strerror(int errnum)
} }
*/ */
#endif #endif


+ 2
- 2
compat.h View File

@@ -2,8 +2,8 @@
#define COMPAT_H #define COMPAT_H


#ifdef __WIN32__ #ifdef __WIN32__
unsigned int sleep(unsigned int seconds);
char *compat_strerror(int errnum);
unsigned int sleep (unsigned int seconds);
char *compat_strerror (int errnum);
//const char *inet_ntop(int af, void *src, const char *dst, socklen_t cnt); //const char *inet_ntop(int af, void *src, const char *dst, socklen_t cnt);
#define INET_ADDRSTRLEN 16 #define INET_ADDRSTRLEN 16
#define ETIMEDOUT 110 #define ETIMEDOUT 110


+ 9
- 9
debug.c View File

@@ -4,15 +4,15 @@


int verb_count = 0; int verb_count = 0;


int func_fprintf(const char *func, FILE *stream, const char *format, ...)
int
func_fprintf (const char *func, FILE * stream, const char *format, ...)
{ {
va_list ap;
int ret;
va_list ap;
int ret;


fprintf(stream, "%s: ", func);
va_start(ap, format);
ret = vfprintf(stream, format, ap);
va_end(ap);
return ret;
fprintf (stream, "%s: ", func);
va_start (ap, format);
ret = vfprintf (stream, format, ap);
va_end (ap);
return ret;
} }


+ 2
- 2
debug.h View File

@@ -14,8 +14,8 @@ extern int verb_count;


#include <stdio.h> #include <stdio.h>


int func_fprintf(const char *func, FILE *stream, const char *format,
...) __attribute__ ((format (printf, 3, 4)));
int func_fprintf (const char *func, FILE * stream, const char *format,
...) __attribute__ ((format (printf, 3, 4)));


#define debug(x...) ({ \ #define debug(x...) ({ \
if(verb_count >= 2) \ if(verb_count >= 2) \


+ 532
- 448
ethstream.c
File diff suppressed because it is too large
View File


+ 66
- 62
ljconfig.c View File

@@ -25,74 +25,78 @@
#define UE9_COMMAND_PORT 52360 #define UE9_COMMAND_PORT 52360


struct options opt[] = { struct options opt[] = {
{ 'a', "address", "string", "host/address of UE9 (192.168.1.209)" },
{ 'h', "help", NULL, "this help" },
{ 'v', "verbose", NULL, "be verbose" },
{ 'V', "version", NULL, "show version number and exit" },
{ 0, NULL, NULL, NULL }
{'a', "address", "string", "host/address of UE9 (192.168.1.209)"},
{'h', "help", NULL, "this help"},
{'v', "verbose", NULL, "be verbose"},
{'V', "version", NULL, "show version number and exit"},
{0, NULL, NULL, NULL}
}; };


int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{ {
int optind;
char *optarg;
char c;
FILE *help = stderr;
char *address = strdup(DEFAULT_HOST);
int fd;
int ret;
int optind;
char *optarg;
char c;
FILE *help = stderr;
char *address = strdup (DEFAULT_HOST);
int fd;
int ret;


/* Parse arguments */
opt_init(&optind);
while ((c = opt_parse(argc, argv, &optind, &optarg, opt)) != 0) {
switch (c) {
case 'a':
free(address);
address = strdup(optarg);
break;
case 'v':
verb_count++;
break;
case 'V':
printf("ljconfig " VERSION "\n");
printf("Written by Jim Paris <jim@jtan.com>\n");
printf("This program comes with no warranty and is "
"provided under the GPLv2.\n");
return 0;
break;
case 'h':
help = stdout;
default:
printhelp:
fprintf(help, "Usage: %s [options]\n", *argv);
opt_help(opt, help);
fprintf(help, "Displays/changes Labjack UE9 config.\n");
return (help == stdout) ? 0 : 1;
}
/* Parse arguments */
opt_init (&optind);
while ((c = opt_parse (argc, argv, &optind, &optarg, opt)) != 0)
{
switch (c)
{
case 'a':
free (address);
address = strdup (optarg);
break;
case 'v':
verb_count++;
break;
case 'V':
printf ("ljconfig " VERSION "\n");
printf ("Written by Jim Paris <jim@jtan.com>\n");
printf ("This program comes with no warranty and is "
"provided under the GPLv2.\n");
return 0;
break;
case 'h':
help = stdout;
default:
printhelp:
fprintf (help, "Usage: %s [options]\n", *argv);
opt_help (opt, help);
fprintf (help, "Displays/changes Labjack UE9 config.\n");
return (help == stdout) ? 0 : 1;
} }
}


if(optind<argc) {
info("Error: too many arguments (%s)\n\n", argv[optind]);
goto printhelp;
}
ret = 1;
if (optind < argc)
{
info ("Error: too many arguments (%s)\n\n", argv[optind]);
goto printhelp;
}


/* Open */
fd = ue9_open(address, UE9_COMMAND_PORT);
if (fd < 0) {
info("Connect failed: %s:%d\n", address, UE9_COMMAND_PORT);
goto out0;
}
ret = 1;


goto out1;
ret = 0;
out1:
/* Close */
ue9_close(fd);
out0:
return ret;
}
/* Open */
fd = ue9_open (address, UE9_COMMAND_PORT);
if (fd < 0)
{
info ("Connect failed: %s:%d\n", address, UE9_COMMAND_PORT);
goto out0;
}


goto out1;


ret = 0;
out1:
/* Close */
ue9_close (fd);
out0:
return ret;
}

+ 42
- 41
ljtest.c View File

@@ -16,52 +16,53 @@
#include "ue9.h" #include "ue9.h"
#include "compat.h" #include "compat.h"


int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{ {
int fd_cmd;
struct ue9Calibration calib;
int fd_cmd;
struct ue9Calibration calib;


verb_count = 2;
verb_count = 2;


fd_cmd = ue9_open("192.168.1.209", 52360);
if (fd_cmd < 0) {
fprintf(stderr, "ue9_open: %s\n",
compat_strerror(errno));
return 1;
}
fd_cmd = ue9_open ("192.168.1.209", 52360);
if (fd_cmd < 0)
{
fprintf (stderr, "ue9_open: %s\n", compat_strerror (errno));
return 1;
}


if (ue9_get_calibration(fd_cmd, &calib) < 0) {
fprintf(stderr, "ue9_get_calibration: %s\n",
compat_strerror(errno));
return 1;
}
if (ue9_get_calibration (fd_cmd, &calib) < 0)
{
fprintf (stderr, "ue9_get_calibration: %s\n", compat_strerror (errno));
return 1;
}


printf("double unipolarSlope[0] = %lf\n", calib.unipolarSlope[0]);
printf("double unipolarSlope[1] = %lf\n", calib.unipolarSlope[1]);
printf("double unipolarSlope[2] = %lf\n", calib.unipolarSlope[2]);
printf("double unipolarSlope[3] = %lf\n", calib.unipolarSlope[3]);
printf("double unipolarOffset[0] = %lf\n", calib.unipolarOffset[0]);
printf("double unipolarOffset[1] = %lf\n", calib.unipolarOffset[1]);
printf("double unipolarOffset[2] = %lf\n", calib.unipolarOffset[2]);
printf("double unipolarOffset[3] = %lf\n", calib.unipolarOffset[3]);
printf("double bipolarSlope = %lf\n", calib.bipolarSlope);
printf("double bipolarOffset = %lf\n", calib.bipolarOffset);
printf("double DACSlope[0] = %lf\n", calib.DACSlope[0]);
printf("double DACSlope[1] = %lf\n", calib.DACSlope[1]);
printf("double DACOffset[0] = %lf\n", calib.DACOffset[0]);
printf("double DACOffset[1] = %lf\n", calib.DACOffset[1]);
printf("double tempSlope = %lf\n", calib.tempSlope);
printf("double tempSlopeLow = %lf\n", calib.tempSlopeLow);
printf("double calTemp = %lf\n", calib.calTemp);
printf("double Vref = %lf\n", calib.Vref);
printf("double VrefDiv2 = %lf\n", calib.VrefDiv2);
printf("double VsSlope = %lf\n", calib.VsSlope);
printf("double hiResUnipolarSlope = %lf\n", calib.hiResUnipolarSlope);
printf("double hiResUnipolarOffset = %lf\n", calib.hiResUnipolarOffset);
printf("double hiResBipolarSlope = %lf\n", calib.hiResBipolarSlope);
printf("double hiResBipolarOffset = %lf\n", calib.hiResBipolarOffset);
printf ("double unipolarSlope[0] = %lf\n", calib.unipolarSlope[0]);
printf ("double unipolarSlope[1] = %lf\n", calib.unipolarSlope[1]);
printf ("double unipolarSlope[2] = %lf\n", calib.unipolarSlope[2]);
printf ("double unipolarSlope[3] = %lf\n", calib.unipolarSlope[3]);
printf ("double unipolarOffset[0] = %lf\n", calib.unipolarOffset[0]);
printf ("double unipolarOffset[1] = %lf\n", calib.unipolarOffset[1]);
printf ("double unipolarOffset[2] = %lf\n", calib.unipolarOffset[2]);
printf ("double unipolarOffset[3] = %lf\n", calib.unipolarOffset[3]);
printf ("double bipolarSlope = %lf\n", calib.bipolarSlope);
printf ("double bipolarOffset = %lf\n", calib.bipolarOffset);
printf ("double DACSlope[0] = %lf\n", calib.DACSlope[0]);
printf ("double DACSlope[1] = %lf\n", calib.DACSlope[1]);
printf ("double DACOffset[0] = %lf\n", calib.DACOffset[0]);
printf ("double DACOffset[1] = %lf\n", calib.DACOffset[1]);
printf ("double tempSlope = %lf\n", calib.tempSlope);
printf ("double tempSlopeLow = %lf\n", calib.tempSlopeLow);
printf ("double calTemp = %lf\n", calib.calTemp);
printf ("double Vref = %lf\n", calib.Vref);
printf ("double VrefDiv2 = %lf\n", calib.VrefDiv2);
printf ("double VsSlope = %lf\n", calib.VsSlope);
printf ("double hiResUnipolarSlope = %lf\n", calib.hiResUnipolarSlope);
printf ("double hiResUnipolarOffset = %lf\n", calib.hiResUnipolarOffset);
printf ("double hiResBipolarSlope = %lf\n", calib.hiResBipolarSlope);
printf ("double hiResBipolarOffset = %lf\n", calib.hiResBipolarOffset);


ue9_close(fd_cmd);
ue9_close (fd_cmd);


return 0;
return 0;
} }

+ 478
- 389
nerdjack.c View File

@@ -25,464 +25,553 @@
#include "netutil.h" #include "netutil.h"
#include "ethstream.h" #include "ethstream.h"


#define NERDJACK_TIMEOUT 5 /* Timeout for connect/send/recv, in seconds */
#define NERDJACK_TIMEOUT 5 /* Timeout for connect/send/recv, in seconds */


//Struct holding information about how channels should be reordered for output //Struct holding information about how channels should be reordered for output
typedef struct {
int numCopies;
int * destlist;
typedef struct
{
int numCopies;
int *destlist;
} deststruct; } deststruct;


typedef struct __attribute__((__packed__)) {
unsigned char headerone;
unsigned char headertwo;
unsigned short packetNumber;
unsigned long lwipmemoryused;
unsigned short adcused;
unsigned short packetsready;
signed short data[NERDJACK_NUM_SAMPLES];
typedef struct __attribute__ ((__packed__))
{
unsigned char headerone;
unsigned char headertwo;
unsigned short packetNumber;
unsigned long lwipmemoryused;
unsigned short adcused;
unsigned short packetsready;
signed short data[NERDJACK_NUM_SAMPLES];
} dataPacket; } dataPacket;


/* Choose the best ScanConfig and ScanInterval parameters for the /* Choose the best ScanConfig and ScanInterval parameters for the
desired scanrate. Returns -1 if no valid config found */ desired scanrate. Returns -1 if no valid config found */
int nerdjack_choose_scan(double desired_rate, double *actual_rate, unsigned long *period)
int
nerdjack_choose_scan (double desired_rate, double *actual_rate,
unsigned long *period)
{ {
//The ffffe is because of a silicon bug. The last bit is unusable in all
//devices so far. It is worked around on the chip, but giving it exactly
//0xfffff would cause the workaround code to roll over.
*period = floor((double) NERDJACK_CLOCK_RATE / desired_rate);
if(*period > 0x0ffffe) {
info("Cannot sample that slowly\n");
*actual_rate = (double)NERDJACK_CLOCK_RATE / (double) 0x0ffffe;
*period = 0x0ffffe;
//info("Sampling at slowest rate:%f\n",*actual_rate);
return -1;
//The ffffe is because of a silicon bug. The last bit is unusable in all
//devices so far. It is worked around on the chip, but giving it exactly
//0xfffff would cause the workaround code to roll over.
*period = floor ((double) NERDJACK_CLOCK_RATE / desired_rate);
if (*period > 0x0ffffe)
{
info ("Cannot sample that slowly\n");
*actual_rate = (double) NERDJACK_CLOCK_RATE / (double) 0x0ffffe;
*period = 0x0ffffe;
//info("Sampling at slowest rate:%f\n",*actual_rate);

return -1;
} }
//Period holds the period register for the NerdJack, so it needs to be right
*actual_rate = (double) NERDJACK_CLOCK_RATE / (double) *period;
if(*actual_rate != desired_rate) {
//info("Sampling at nearest rate:%f\n",*actual_rate);
return -1;
}
return 0;
//Period holds the period register for the NerdJack, so it needs to be right
*actual_rate = (double) NERDJACK_CLOCK_RATE / (double) *period;
if (*actual_rate != desired_rate)
{
//info("Sampling at nearest rate:%f\n",*actual_rate);
return -1;
}
return 0;
} }


int nerdjack_detect(char * ipAddress) {
int32_t sock, receivesock;
struct sockaddr_in sa, receiveaddr, sFromAddr;
int bytes_sent, buffer_length;
char buffer[200];
char incomingData[10];
unsigned int lFromLen;

sprintf(buffer, "TEST");
buffer_length = strlen(buffer) + 1;
net_init();

sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
receivesock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
/* Set nonblocking */
if (soblock(sock, 0) < 0) {
verb("can't set nonblocking\n");
int
nerdjack_detect (char *ipAddress)
{
int32_t sock, receivesock;
struct sockaddr_in sa, receiveaddr, sFromAddr;
int bytes_sent, buffer_length;
char buffer[200];
char incomingData[10];
unsigned int lFromLen;

sprintf (buffer, "TEST");
buffer_length = strlen (buffer) + 1;

net_init ();

sock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
receivesock = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);

/* Set nonblocking */
if (soblock (sock, 0) < 0)
{
verb ("can't set nonblocking\n");
return -1; return -1;
}
/* Set nonblocking */
if (soblock(receivesock, 0) < 0) {
verb("can't set nonblocking\n");
}

/* Set nonblocking */
if (soblock (receivesock, 0) < 0)
{
verb ("can't set nonblocking\n");
return -1; return -1;
}
}




int opt = 1;
setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(void *) &opt,sizeof(int));
if((-1 == sock) || (-1 == receivesock)) /* if socket failed to initialize, exit */
{
verb("Error Creating Socket\n");
int opt = 1;
setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (void *) &opt, sizeof (int));
if ((-1 == sock) || (-1 == receivesock)) /* if socket failed to initialize, exit */
{
verb ("Error Creating Socket\n");
return -1; return -1;
}

//Setup family for both sockets
sa.sin_family = PF_INET;
receiveaddr.sin_family = PF_INET;
//Setup ports to send on DATA and receive on RECEIVE
receiveaddr.sin_port = htons(NERDJACK_UDP_RECEIVE_PORT);
sa.sin_port = htons(NERDJACK_DATA_PORT);
//Receive from any IP address, Will send to broadcast
receiveaddr.sin_addr.s_addr = INADDR_ANY;
sa.sin_addr.s_addr = INADDR_BROADCAST;

bind(receivesock,(struct sockaddr*) &receiveaddr, sizeof(struct sockaddr_in));

bytes_sent = sendto(sock, buffer, buffer_length, 0,(struct sockaddr*) &sa, sizeof(struct sockaddr_in) );
if(bytes_sent < 0) {
info("Error sending packet: %s\n", strerror(errno) );
return -1;
}
}

//Setup family for both sockets
sa.sin_family = PF_INET;
receiveaddr.sin_family = PF_INET;

//Setup ports to send on DATA and receive on RECEIVE
receiveaddr.sin_port = htons (NERDJACK_UDP_RECEIVE_PORT);
sa.sin_port = htons (NERDJACK_DATA_PORT);

//Receive from any IP address, Will send to broadcast
receiveaddr.sin_addr.s_addr = INADDR_ANY;
sa.sin_addr.s_addr = INADDR_BROADCAST;


lFromLen = sizeof(sFromAddr);
if(0 > recvfrom_timeout(receivesock, incomingData, sizeof(incomingData),0,(struct sockaddr *) &sFromAddr, &lFromLen,
& (struct timeval) { .tv_sec = NERDJACK_TIMEOUT })) {
return -1;
bind (receivesock, (struct sockaddr *) &receiveaddr,
sizeof (struct sockaddr_in));

bytes_sent =
sendto (sock, buffer, buffer_length, 0, (struct sockaddr *) &sa,
sizeof (struct sockaddr_in));
if (bytes_sent < 0)
{
info ("Error sending packet: %s\n", strerror (errno));
return -1;
} }
ipAddress = malloc(INET_ADDRSTRLEN);
//It isn't ipv6 friendly, but inet_ntop isn't on Windows...
strcpy(ipAddress, inet_ntoa(sFromAddr.sin_addr));

close(sock); /* close the socket */
close(receivesock);
return 0;

lFromLen = sizeof (sFromAddr);

if (0 >
recvfrom_timeout (receivesock, incomingData, sizeof (incomingData), 0,
(struct sockaddr *) &sFromAddr, &lFromLen,
&(struct timeval)
{
.tv_sec = NERDJACK_TIMEOUT}))
{

return -1;
}

ipAddress = malloc (INET_ADDRSTRLEN);

//It isn't ipv6 friendly, but inet_ntop isn't on Windows...
strcpy (ipAddress, inet_ntoa (sFromAddr.sin_addr));

close (sock); /* close the socket */
close (receivesock);
return 0;
} }


int nerd_send_command(const char * address, void * command, int length)
int
nerd_send_command (const char *address, void *command, int length)
{ {
int ret,fd_command;
char buf[3];
fd_command = nerd_open(address, NERDJACK_COMMAND_PORT);
if (fd_command < 0) {
info("Connect failed: %s:%d\n", address, NERDJACK_COMMAND_PORT);
return -2;
int ret, fd_command;
char buf[3];
fd_command = nerd_open (address, NERDJACK_COMMAND_PORT);
if (fd_command < 0)
{
info ("Connect failed: %s:%d\n", address, NERDJACK_COMMAND_PORT);
return -2;
} }


/* Send request */
ret = send_all_timeout(fd_command, command, length, 0,
& (struct timeval) { .tv_sec = NERDJACK_TIMEOUT });
if (ret < 0 || ret != length) {
verb("short send %d\n", (int)ret);
return -1;
}
/* Send request */
ret = send_all_timeout (fd_command, command, length, 0, &(struct timeval)
{
.tv_sec = NERDJACK_TIMEOUT});
if (ret < 0 || ret != length)
{
verb ("short send %d\n", (int) ret);
return -1;
}


ret = recv_all_timeout(fd_command,buf,3,0,
& (struct timeval) { .tv_sec = NERDJACK_TIMEOUT });
ret = recv_all_timeout (fd_command, buf, 3, 0, &(struct timeval)
{
.tv_sec = NERDJACK_TIMEOUT});


nerd_close_conn(fd_command);
nerd_close_conn (fd_command);


if (ret < 0 || ret != 3) {
verb("Error receiving OK for command\n");
return -1;
}
if (ret < 0 || ret != 3)
{
verb ("Error receiving OK for command\n");
return -1;
}


if (0 != strcmp("OK",buf)){
verb("Did not receive OK. Received %s\n",buf);
return -3;
if (0 != strcmp ("OK", buf))
{
verb ("Did not receive OK. Received %s\n", buf);
return -3;
} }


return 0;
return 0;
} }


//Initialize the channel structure to distill how data should be displayed //Initialize the channel structure to distill how data should be displayed
static void nerd_init_channels(deststruct * destination, int numChannels, int numChannelsSampled, int *channel_list) {

int channelprocessing = 0;
int currentalign = 0; //Index into sampled channels
int i;
int tempdestlist[NERDJACK_CHANNELS];
//Clear out destination stuff
for(i=0; i < numChannelsSampled;i++) {
destination[i].numCopies = 0;
static void
nerd_init_channels (deststruct * destination, int numChannels,
int numChannelsSampled, int *channel_list)
{

int channelprocessing = 0;
int currentalign = 0; //Index into sampled channels
int i;
int tempdestlist[NERDJACK_CHANNELS];

//Clear out destination stuff
for (i = 0; i < numChannelsSampled; i++)
{
destination[i].numCopies = 0;
} }

for(channelprocessing = 0; channelprocessing < numChannelsSampled; channelprocessing++) {
//Find out how many copies of each channel so we malloc the right things
currentalign = 0;
for(i = 0; i < numChannels; i++) {
if(channelprocessing == channel_list[i]) {
tempdestlist[currentalign] = i;
currentalign++;
}
}
//If this channel is wanted, set it up.
if(currentalign > 0) {
destination[channelprocessing].numCopies = currentalign;
destination[channelprocessing].destlist = malloc( destination[channelprocessing].numCopies * sizeof(int) );
memcpy(destination[channelprocessing].destlist, tempdestlist, destination[channelprocessing].numCopies * sizeof(int) );
}


for (channelprocessing = 0; channelprocessing < numChannelsSampled;
channelprocessing++)
{
//Find out how many copies of each channel so we malloc the right things
currentalign = 0;
for (i = 0; i < numChannels; i++)
{
if (channelprocessing == channel_list[i])
{
tempdestlist[currentalign] = i;
currentalign++;
}
}



//If this channel is wanted, set it up.
if (currentalign > 0)
{
destination[channelprocessing].numCopies = currentalign;
destination[channelprocessing].destlist =
malloc (destination[channelprocessing].numCopies * sizeof (int));
memcpy (destination[channelprocessing].destlist, tempdestlist,
destination[channelprocessing].numCopies * sizeof (int));
}

} }
return;
return;
} }


int nerd_data_stream(int data_fd, int numChannels, int *channel_list, int precision, int convert, int lines, int showmem, unsigned short * currentcount, unsigned int period)
int
nerd_data_stream (int data_fd, int numChannels, int *channel_list,
int precision, int convert, int lines, int showmem,
unsigned short *currentcount, unsigned int period)
{ {
//Variables that should persist across retries
static dataPacket buf;
static int linesleft = 0;
static int linesdumped = 0;

int index = 0;
int charsprocessed = 0;
int alignment = 0;
signed short datapoint = 0;
unsigned short dataline[NERDJACK_CHANNELS];
long double voltline[NERDJACK_CHANNELS];
int i;

unsigned long memused = 0;
unsigned short packetsready = 0;
unsigned short adcused = 0;
unsigned short tempshort = 0;
int charsread = 0;

int numgroups = 0;
long double volts;

unsigned int expectedtimeout = (period * NERDJACK_NUM_SAMPLES / NERDJACK_CLOCK_RATE) + 2;
//Check to see if we're trying to resume
//Don't blow away linesleft in that case
if(lines != 0 && linesleft == 0) {
linesleft = lines;
//Variables that should persist across retries
static dataPacket buf;
static int linesleft = 0;
static int linesdumped = 0;

int index = 0;
int charsprocessed = 0;
int alignment = 0;
signed short datapoint = 0;
unsigned short dataline[NERDJACK_CHANNELS];
long double voltline[NERDJACK_CHANNELS];
int i;


unsigned long memused = 0;
unsigned short packetsready = 0;
unsigned short adcused = 0;
unsigned short tempshort = 0;
int charsread = 0;

int numgroups = 0;
long double volts;

unsigned int expectedtimeout =
(period * NERDJACK_NUM_SAMPLES / NERDJACK_CLOCK_RATE) + 2;

//Check to see if we're trying to resume
//Don't blow away linesleft in that case
if (lines != 0 && linesleft == 0)
{
linesleft = lines;
} }
int numChannelsSampled = channel_list[0] + 1;
//The number sampled will be the highest channel requested plus 1 (i.e. channel 0 requested means 1 sampled)
for(i = 0; i < numChannels; i++) {
if (channel_list[i] + 1 > numChannelsSampled)
numChannelsSampled = channel_list[i] + 1;


int numChannelsSampled = channel_list[0] + 1;

//The number sampled will be the highest channel requested plus 1 (i.e. channel 0 requested means 1 sampled)
for (i = 0; i < numChannels; i++)
{
if (channel_list[i] + 1 > numChannelsSampled)
numChannelsSampled = channel_list[i] + 1;
} }
deststruct destination[numChannelsSampled];


nerd_init_channels(destination,numChannels,numChannelsSampled, channel_list);
//Now destination structure array is set as well as numDuplicates.
deststruct destination[numChannelsSampled];


//int numChannelsSampled = numChannels - numDuplicates;
int numGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled;
nerd_init_channels (destination, numChannels, numChannelsSampled,
channel_list);




//Loop forever to grab data
while((charsread = recv_all_timeout(data_fd,&buf,NERDJACK_PACKET_SIZE,0,
& (struct timeval) { .tv_sec = expectedtimeout }))){
//Now destination structure array is set as well as numDuplicates.


//We want a complete packet, so take the chars so far and keep waiting
if(charsread != NERDJACK_PACKET_SIZE) {
//There was a problem getting data. Probably a closed
//connection.
info("Packet timed out or was too short\n");
return -2;
}
//int numChannelsSampled = numChannels - numDuplicates;
int numGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled;


//First check the header info
if(buf.headerone != 0xF0 || buf.headertwo != 0xAA) {
info("No Header info\n");
return -1;
}


//Check counter info to make sure not out of order
tempshort = ntohs(buf.packetNumber);
//tempshort = (buf[2] << 8) | buf[3];
if(tempshort != *currentcount ){
info("Count wrong. Expected %hd but got %hd\n", *currentcount, tempshort);
return -1;
//Loop forever to grab data
while ((charsread =
recv_all_timeout (data_fd, &buf, NERDJACK_PACKET_SIZE, 0,
&(struct timeval)
{
.tv_sec = expectedtimeout})))
{

//We want a complete packet, so take the chars so far and keep waiting
if (charsread != NERDJACK_PACKET_SIZE)
{
//There was a problem getting data. Probably a closed
//connection.
info ("Packet timed out or was too short\n");
return -2;
}

//First check the header info
if (buf.headerone != 0xF0 || buf.headertwo != 0xAA)
{
info ("No Header info\n");
return -1;
}

//Check counter info to make sure not out of order
tempshort = ntohs (buf.packetNumber);
//tempshort = (buf[2] << 8) | buf[3];
if (tempshort != *currentcount)
{
info ("Count wrong. Expected %hd but got %hd\n", *currentcount,
tempshort);
return -1;
}

//Increment number of packets received
*currentcount = *currentcount + 1;

//Process the rest of the header and update the index value to be pointing after it
charsprocessed = 12;
memused = ntohl (buf.lwipmemoryused);
adcused = ntohs (buf.adcused);
packetsready = ntohs (buf.packetsready);
alignment = 0;
numgroups = 0;

if (showmem)
{
printf ("%lX %hd %hd\n", memused, adcused, packetsready);
continue;
}

index = 0;
//While there is still more data in the packet, process it
//use the destination structure to load the line before printing
while (charsread > charsprocessed)
{
datapoint = ntohs (buf.data[index]);
if (destination[alignment].numCopies != 0)
{
switch (convert)
{
case CONVERT_VOLTS:
if (alignment <= 5)
{
volts =
(long double) (datapoint / 32767.0) *
((precision & 0x01) ? 5.0 : 10.0);
}
else
{
volts =
(long double) (datapoint / 32767.0) *
((precision & 0x02) ? 5.0 : 10.0);
}
for (i = 0; i < destination[alignment].numCopies; i++)
{
voltline[destination[alignment].destlist[i]] = volts;
}
break;
default:
case CONVERT_HEX:
case CONVERT_DEC:
for (i = 0; i < destination[alignment].numCopies; i++)
{
dataline[destination[alignment].destlist[i]] =
(unsigned short) (datapoint - INT16_MIN);
}
break;
} }
//Increment number of packets received
*currentcount = *currentcount + 1;
//Process the rest of the header and update the index value to be pointing after it
charsprocessed = 12;
memused = ntohl(buf.lwipmemoryused);
adcused = ntohs(buf.adcused);
packetsready = ntohs(buf.packetsready);
alignment = 0;
numgroups = 0;

if(showmem) {
printf("%lX %hd %hd\n",memused, adcused, packetsready);
continue;
}
index = 0;
//While there is still more data in the packet, process it
//use the destination structure to load the line before printing
while(charsread > charsprocessed) {
datapoint = ntohs(buf.data[index]);
if(destination[alignment].numCopies != 0) {
switch(convert) {
case CONVERT_VOLTS:
if(alignment <= 5) {
volts = (long double) ( datapoint / 32767.0 ) * ((precision & 0x01) ? 5.0 : 10.0);
} else {
volts = (long double) (datapoint / 32767.0 ) * ((precision & 0x02) ? 5.0 : 10.0);
}
for(i = 0; i < destination[alignment].numCopies; i++) {
voltline[destination[alignment].destlist[i]] = volts;
}
break;
default:
case CONVERT_HEX:
case CONVERT_DEC:
for(i = 0; i < destination[alignment].numCopies; i++) {
dataline[destination[alignment].destlist[i]] =
(unsigned short) (datapoint - INT16_MIN);
}
break;

}

//Each point is two bytes, so increment index and total bytes read
charsprocessed++;
charsprocessed++;
index++;
alignment++;

//Since channel data is packed, we need to know when to insert a newline
if (alignment == numChannelsSampled)
{
if (linesdumped != 0)
{
switch (convert)
{
case CONVERT_VOLTS:
for (i = 0; i < numChannels; i++)
{
if (printf ("%Lf ", voltline[i]) < 0)
goto bad;
}
break;
case CONVERT_HEX:
for (i = 0; i < numChannels; i++)
{
if (printf ("%04hX", dataline[i]) < 0)
goto bad;
} }
}
//Each point is two bytes, so increment index and total bytes read
charsprocessed++;
charsprocessed++;
index++;
alignment++;
//Since channel data is packed, we need to know when to insert a newline
if(alignment == numChannelsSampled){
if(linesdumped != 0){
switch(convert) {
case CONVERT_VOLTS:
for(i = 0; i < numChannels; i++) {
if (printf("%Lf ",voltline[i]) < 0)
goto bad;
}
break;
case CONVERT_HEX:
for(i = 0; i < numChannels; i++) {
if (printf("%04hX",dataline[i]) < 0)
goto bad;
}
break;
default:
case CONVERT_DEC:
for(i = 0; i < numChannels; i++) {
if (printf("%hu ",dataline[i]) < 0)
goto bad;
}
break;
}
if(printf("\n") < 0)
goto bad;
} else {
linesdumped = linesdumped + 1;
if(lines != 0) {
linesleft++;
}
}
alignment = 0;
numgroups++;
if(lines != 0) {
linesleft--;
if(linesleft == 0) {
return 0;
}
}
//If numgroups so far is equal to the numGroups in a packet, this packet is done
if(numgroups == numGroups) {
break;
}
break;
default:
case CONVERT_DEC:
for (i = 0; i < numChannels; i++)
{
if (printf ("%hu ", dataline[i]) < 0)
goto bad;
} }
break;
}
if (printf ("\n") < 0)
goto bad;
}
else
{
linesdumped = linesdumped + 1;
if (lines != 0)
{
linesleft++;
}
}
alignment = 0;
numgroups++;
if (lines != 0)
{
linesleft--;
if (linesleft == 0)
{
return 0;
}
} }
index = 0;
charsprocessed = 0;
//If numgroups so far is equal to the numGroups in a packet, this packet is done
if (numgroups == numGroups)
{
break;
}
}
} }
index = 0;
charsprocessed = 0;
}


return 0;
return 0;


bad: bad:
info("Output error (disk full?)\n");
return -1;
info ("Output error (disk full?)\n");
return -1;


} }


int nerd_open(const char *address,int port) {
struct hostent *he;
net_init();
int32_t i32SocketFD = socket(PF_INET, SOCK_STREAM, 0);
int
nerd_open (const char *address, int port)
{


if(-1 == i32SocketFD)
struct hostent *he;

net_init ();

int32_t i32SocketFD = socket (PF_INET, SOCK_STREAM, 0);

if (-1 == i32SocketFD)
{ {
verb("cannot create socket");
verb ("cannot create socket");
return -1;
}

/* Set nonblocking */
if (soblock (i32SocketFD, 0) < 0)
{
verb ("can't set nonblocking\n");
return -1; return -1;
} }
/* Set nonblocking */
if (soblock(i32SocketFD, 0) < 0) {
verb("can't set nonblocking\n");
return -1;
}


struct sockaddr_in stSockAddr;
memset(&stSockAddr, 0, sizeof(stSockAddr));
struct sockaddr_in stSockAddr;
memset (&stSockAddr, 0, sizeof (stSockAddr));


stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons(port);
he = gethostbyname(address);
if (he == NULL) {
verb("gethostbyname(\"%s\") failed\n", address);
return -1;
}
stSockAddr.sin_addr = *((struct in_addr *) he->h_addr);

debug("Resolved %s -> %s\n", address, inet_ntoa(stSockAddr.sin_addr));
/* Connect */
if (connect_timeout(i32SocketFD, (struct sockaddr *) &stSockAddr, sizeof(stSockAddr),
& (struct timeval) { .tv_sec = NERDJACK_TIMEOUT }) < 0) {
verb("connection to %s:%d failed: %s\n",
inet_ntoa(stSockAddr.sin_addr), port, compat_strerror(errno));
return -1;
}
return i32SocketFD;
stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons (port);

he = gethostbyname (address);
if (he == NULL)
{
verb ("gethostbyname(\"%s\") failed\n", address);
return -1;
}
stSockAddr.sin_addr = *((struct in_addr *) he->h_addr);

debug ("Resolved %s -> %s\n", address, inet_ntoa (stSockAddr.sin_addr));

/* Connect */
if (connect_timeout
(i32SocketFD, (struct sockaddr *) &stSockAddr, sizeof (stSockAddr),
&(struct timeval)
{
.tv_sec = NERDJACK_TIMEOUT}) < 0)
{
verb ("connection to %s:%d failed: %s\n",
inet_ntoa (stSockAddr.sin_addr), port, compat_strerror (errno));
return -1;
}

return i32SocketFD;
} }


//Generate an appropriate sample initiation command //Generate an appropriate sample initiation command
int nerd_generate_command(getPacket * command, int * channel_list, int channel_count, int precision,
unsigned long period) {
short channelbit = 0;
int i;
for( i = 0; i < channel_count; i++) {
channelbit = channelbit | (0x1 << channel_list[i]);
int
nerd_generate_command (getPacket * command, int *channel_list,
int channel_count, int precision, unsigned long period)
{

short channelbit = 0;
int i;

for (i = 0; i < channel_count; i++)
{
channelbit = channelbit | (0x1 << channel_list[i]);
} }
//command->word = "GETD";
command->word[0] = 'G';
command->word[1] = 'E';
command->word[2] = 'T';
command->word[3] = 'D';
command->channelbit = htons(channelbit);
command->precision = precision;
command->period = htonl(period);
command->prescaler = 0;
//sprintf(command,"GETD%3.3X%d%5.5d", channelbit,precision,period);
return 0;
//command->word = "GETD";
command->word[0] = 'G';
command->word[1] = 'E';
command->word[2] = 'T';
command->word[3] = 'D';
command->channelbit = htons (channelbit);
command->precision = precision;
command->period = htonl (period);
command->prescaler = 0;
//sprintf(command,"GETD%3.3X%d%5.5d", channelbit,precision,period);
return 0;
} }


int nerd_close_conn(int data_fd)
int
nerd_close_conn (int data_fd)
{ {
shutdown(data_fd, 2);
close(data_fd);
return 0;
shutdown (data_fd, 2);
close (data_fd);
return 0;
} }

+ 19
- 14
nerdjack.h View File

@@ -24,33 +24,38 @@
#define NERDJACK_PACKET_SIZE 1460 #define NERDJACK_PACKET_SIZE 1460
#define NERDJACK_NUM_SAMPLES 724 #define NERDJACK_NUM_SAMPLES 724


typedef struct __attribute__((__packed__)) {
char word[4];
unsigned short channelbit;
unsigned char precision;
unsigned long period;
unsigned char prescaler;
typedef struct __attribute__ ((__packed__))
{
char word[4];
unsigned short channelbit;
unsigned char precision;
unsigned long period;
unsigned char prescaler;
} getPacket; } getPacket;


/* Open/close TCP/IP connection to the NerdJack */ /* Open/close TCP/IP connection to the NerdJack */
int nerd_open(const char *address,int port);
int nerd_close_conn(int data_fd);
int nerd_open (const char *address, int port);
int nerd_close_conn (int data_fd);


/* Generate the command word for the NerdJack */ /* Generate the command word for the NerdJack */
int nerd_generate_command(getPacket * command, int * channel_list, int channel_count, int precision,
unsigned long period);
int nerd_generate_command (getPacket * command, int *channel_list,
int channel_count, int precision,
unsigned long period);


/* Send given command to NerdJack */ /* Send given command to NerdJack */
int nerd_send_command(const char * address, void * command, int length);
int nerd_send_command (const char *address, void *command, int length);


/* Stream data out of the NerdJack */ /* Stream data out of the NerdJack */
int nerd_data_stream(int data_fd, int numChannels, int * channel_list, int precision, int convert, int lines, int showmem, unsigned short * currentcount, unsigned int period);
int nerd_data_stream (int data_fd, int numChannels, int *channel_list,
int precision, int convert, int lines, int showmem,
unsigned short *currentcount, unsigned int period);


/* Detect the IP Address of the NerdJack and return in ipAddress */ /* Detect the IP Address of the NerdJack and return in ipAddress */
int nerdjack_detect(char * ipAddress);
int nerdjack_detect (char *ipAddress);


/* Choose the best ScanConfig and ScanInterval parameters for the /* Choose the best ScanConfig and ScanInterval parameters for the
desired scanrate. Returns -1 if no valid config found */ desired scanrate. Returns -1 if no valid config found */
int nerdjack_choose_scan(double desired_rate, double *actual_rate, unsigned long *period);
int nerdjack_choose_scan (double desired_rate, double *actual_rate,
unsigned long *period);


#endif #endif

+ 199
- 176
netutil.c View File

@@ -5,239 +5,262 @@
#include <stdio.h> #include <stdio.h>


/* Initialize networking */ /* Initialize networking */
void net_init(void)
void
net_init (void)
{ {
#ifdef __WIN32__ #ifdef __WIN32__
WSADATA blah;
WSAStartup(0x0101, &blah);
WSADATA blah;
WSAStartup (0x0101, &blah);
#endif #endif
} }


/* Set socket blocking/nonblocking */ /* Set socket blocking/nonblocking */
int soblock(int socket, int blocking)
int
soblock (int socket, int blocking)
{ {
#ifdef __WIN32__ #ifdef __WIN32__
unsigned long arg = blocking ? 0 : 1;
if (ioctlsocket(socket, FIONBIO, &arg) != 0)
return -1;
return 0;
unsigned long arg = blocking ? 0 : 1;
if (ioctlsocket (socket, FIONBIO, &arg) != 0)
return -1;
return 0;
#else #else
int sockopt;

/* Get flags */
sockopt = fcntl(socket, F_GETFL);
if (sockopt == -1) {
return -1;
}

/* Modify */
if (blocking)
sockopt &= ~O_NONBLOCK;
else
sockopt |= O_NONBLOCK;

/* Set flags */
if (fcntl(socket, F_SETFL, sockopt) != 0)
return -1;
return 0;
int sockopt;

/* Get flags */
sockopt = fcntl (socket, F_GETFL);
if (sockopt == -1)
{
return -1;
}

/* Modify */
if (blocking)
sockopt &= ~O_NONBLOCK;
else
sockopt |= O_NONBLOCK;

/* Set flags */
if (fcntl (socket, F_SETFL, sockopt) != 0)
return -1;

return 0;
#endif #endif
} }




/* Like connect(2), but with a timeout. Socket must be non-blocking. */ /* Like connect(2), but with a timeout. Socket must be non-blocking. */
int connect_timeout(int s, const struct sockaddr *serv_addr, socklen_t addrlen,
struct timeval *timeout)
int
connect_timeout (int s, const struct sockaddr *serv_addr, socklen_t addrlen,
struct timeval *timeout)
{ {
int ret;
fd_set writefds;
fd_set exceptfds;
int optval;
socklen_t optlen;

/* Start connect */
ret = connect(s, serv_addr, addrlen);

if (ret == 0) {
/* Success */
return 0;
}

/* Check for immediate failure */
int ret;
fd_set writefds;
fd_set exceptfds;
int optval;
socklen_t optlen;

/* Start connect */
ret = connect (s, serv_addr, addrlen);

if (ret == 0)
{
/* Success */
return 0;
}

/* Check for immediate failure */
#ifdef __WIN32__ #ifdef __WIN32__
errno = WSAGetLastError();
if (ret < 0 && errno != WSAEWOULDBLOCK && errno != WSAEINVAL)
return -1;
errno = WSAGetLastError ();
if (ret < 0 && errno != WSAEWOULDBLOCK && errno != WSAEINVAL)
return -1;
#else #else
if (ret < 0 && errno != EINPROGRESS && errno != EALREADY)
return -1;
if (ret < 0 && errno != EINPROGRESS && errno != EALREADY)
return -1;
#endif #endif


/* In progress, wait for result. */
FD_ZERO(&writefds);
FD_SET(s, &writefds);
FD_ZERO(&exceptfds);
FD_SET(s, &exceptfds);
ret = select(s + 1, NULL, &writefds, &exceptfds, timeout);
if (ret < 0) {
/* Error */
return -1;
}
if (ret == 0) {
/* Timed out */
errno = ETIMEDOUT;
return -1;
}

/* Check the socket state */
optlen = sizeof(optval);
if (getsockopt(s, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen) != 0)
return -1;

if (optval != 0) {
/* Connection failed. */
errno = optval;
return -1;
}

/* On Windows, SO_ERROR sometimes shows no error but the connection
still failed. Sigh. */
if (FD_ISSET(s, &exceptfds) || !FD_ISSET(s, &writefds)) {
errno = EIO;
return -1;
}

/* Success */
return 0;
/* In progress, wait for result. */
FD_ZERO (&writefds);
FD_SET (s, &writefds);
FD_ZERO (&exceptfds);
FD_SET (s, &exceptfds);
ret = select (s + 1, NULL, &writefds, &exceptfds, timeout);
if (ret < 0)
{
/* Error */
return -1;
}
if (ret == 0)
{
/* Timed out */
errno = ETIMEDOUT;
return -1;
}

/* Check the socket state */
optlen = sizeof (optval);
if (getsockopt (s, SOL_SOCKET, SO_ERROR, (void *) &optval, &optlen) != 0)
return -1;

if (optval != 0)
{
/* Connection failed. */
errno = optval;
return -1;
}

/* On Windows, SO_ERROR sometimes shows no error but the connection
still failed. Sigh. */
if (FD_ISSET (s, &exceptfds) || !FD_ISSET (s, &writefds))
{
errno = EIO;
return -1;
}

/* Success */
return 0;
} }


/* Like send(2), but with a timeout. Socket must be non-blocking. /* Like send(2), but with a timeout. Socket must be non-blocking.
The timeout only applies if no data at all is sent -- this function The timeout only applies if no data at all is sent -- this function
may still send less than requested. */ may still send less than requested. */
ssize_t send_timeout(int s, const void *buf, size_t len, int flags,
struct timeval *timeout)
ssize_t
send_timeout (int s, const void *buf, size_t len, int flags,
struct timeval * timeout)
{ {
fd_set writefds;
int ret;
FD_ZERO(&writefds);
FD_SET(s, &writefds);
ret = select(s + 1, NULL, &writefds, NULL, timeout);
if (ret == 0) {
/* Timed out */
errno = ETIMEDOUT;
return -1;
}
if (ret != 1) {
/* Error */
return -1;
}

return send(s, buf, len, flags);
fd_set writefds;
int ret;

FD_ZERO (&writefds);
FD_SET (s, &writefds);
ret = select (s + 1, NULL, &writefds, NULL, timeout);
if (ret == 0)
{
/* Timed out */
errno = ETIMEDOUT;
return -1;
}
if (ret != 1)
{
/* Error */
return -1;
}

return send (s, buf, len, flags);
} }


/* Like recv(2), but with a timeout. Socket must be non-blocking. /* Like recv(2), but with a timeout. Socket must be non-blocking.
The timeout only applies if no data at all is received -- this The timeout only applies if no data at all is received -- this
function may still return less than requested. */ function may still return less than requested. */
ssize_t recv_timeout(int s, void *buf, size_t len, int flags,
struct timeval *timeout)
ssize_t
recv_timeout (int s, void *buf, size_t len, int flags,
struct timeval * timeout)
{ {
fd_set readfds;
int ret;
FD_ZERO(&readfds);
FD_SET(s, &readfds);
ret = select(s + 1, &readfds, NULL, NULL, timeout);
if (ret == 0) {
/* Timed out */
errno = ETIMEDOUT;
return -1;
}
if (ret != 1) {
/* Error */
return -1;
}

return recv(s, buf, len, flags);
fd_set readfds;
int ret;

FD_ZERO (&readfds);
FD_SET (s, &readfds);
ret = select (s + 1, &readfds, NULL, NULL, timeout);
if (ret == 0)
{
/* Timed out */
errno = ETIMEDOUT;
return -1;
}
if (ret != 1)
{
/* Error */
return -1;
}

return recv (s, buf, len, flags);
} }


/* Like recvfrom(2), but with a timeout. Socket must be non-blocking. /* Like recvfrom(2), but with a timeout. Socket must be non-blocking.
The timeout only applies if no data at all is received -- this The timeout only applies if no data at all is received -- this
function may still return less than requested. */ function may still return less than requested. */
ssize_t recvfrom_timeout(int s, void *buf, size_t len, int flags, struct sockaddr *address, socklen_t *address_len,
struct timeval *timeout)
ssize_t
recvfrom_timeout (int s, void *buf, size_t len, int flags,
struct sockaddr * address, socklen_t * address_len,
struct timeval * timeout)
{ {
fd_set readfds;
int ret;
FD_ZERO(&readfds);
FD_SET(s, &readfds);
ret = select(s + 1, &readfds, NULL, NULL, timeout);
if (ret == 0) {
/* Timed out */
errno = ETIMEDOUT;
return -1;
}
if (ret != 1) {
/* Error */
return -1;
}

return recvfrom(s, buf, len, flags, address, address_len);
fd_set readfds;
int ret;

FD_ZERO (&readfds);
FD_SET (s, &readfds);
ret = select (s + 1, &readfds, NULL, NULL, timeout);
if (ret == 0)
{
/* Timed out */
errno = ETIMEDOUT;
return -1;
}
if (ret != 1)
{
/* Error */
return -1;
}

return recvfrom (s, buf, len, flags, address, address_len);
} }


/* Like send_timeout, but retries (with the same timeout) in case of /* Like send_timeout, but retries (with the same timeout) in case of
partial transfers. This is a stronger attempt to send all partial transfers. This is a stronger attempt to send all
requested data. */ requested data. */
ssize_t send_all_timeout(int s, const void *buf, size_t len, int flags,
struct timeval *timeout)
ssize_t
send_all_timeout (int s, const void *buf, size_t len, int flags,
struct timeval * timeout)
{ {
struct timeval tv;
size_t left = len;
ssize_t ret;
struct timeval tv;
size_t left = len;
ssize_t ret;


while (left > 0) {
tv.tv_sec = timeout->tv_sec;
tv.tv_usec = timeout->tv_usec;
ret = send_timeout(s, buf, left, flags, &tv);
while (left > 0)
{
tv.tv_sec = timeout->tv_sec;
tv.tv_usec = timeout->tv_usec;
ret = send_timeout (s, buf, left, flags, &tv);


if (ret < 0)
return ret;
if (ret < 0)
return ret;


if (ret == 0)
break;
if (ret == 0)
break;


left -= ret;
buf += ret;
}
left -= ret;
buf += ret;
}


return len - left;
return len - left;
} }


/* Like recv_timeout, but retries (with the same timeout) in case of /* Like recv_timeout, but retries (with the same timeout) in case of
partial transfers. This is a stronger attempt to recv all partial transfers. This is a stronger attempt to recv all
requested data. */ requested data. */
ssize_t recv_all_timeout(int s, void *buf, size_t len, int flags,
struct timeval *timeout)
ssize_t
recv_all_timeout (int s, void *buf, size_t len, int flags,
struct timeval * timeout)
{ {
struct timeval tv;
size_t left = len;
ssize_t ret;
struct timeval tv;
size_t left = len;
ssize_t ret;


while (left > 0) {
tv.tv_sec = timeout->tv_sec;
tv.tv_usec = timeout->tv_usec;
ret = recv_timeout(s, buf, left, flags, &tv);
while (left > 0)
{
tv.tv_sec = timeout->tv_sec;
tv.tv_usec = timeout->tv_usec;
ret = recv_timeout (s, buf, left, flags, &tv);


if (ret < 0)
return ret;
if (ret < 0)
return ret;


if (ret == 0)
break;
if (ret == 0)
break;


left -= ret;
buf += ret;
}
left -= ret;
buf += ret;
}


return len - left;
return len - left;
} }

+ 15
- 14
netutil.h View File

@@ -19,27 +19,28 @@
#endif #endif


/* Initialize networking */ /* Initialize networking */
void net_init(void);
void net_init (void);


/* Set socket blocking/nonblocking */ /* Set socket blocking/nonblocking */
int soblock(int socket, int blocking);
int soblock (int socket, int blocking);


/* Like send(2), recv(2), connect(2), but with timeouts. /* Like send(2), recv(2), connect(2), but with timeouts.
Socket must be O_NONBLOCK. */ Socket must be O_NONBLOCK. */
int connect_timeout(int s, const struct sockaddr *serv_addr, socklen_t addrlen,
struct timeval *timeout);
ssize_t send_timeout(int s, const void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t recv_timeout(int s, void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t recvfrom_timeout(int s, void *buf, size_t len, int flags, struct sockaddr *address, socklen_t *address_len,
struct timeval *timeout);
int connect_timeout (int s, const struct sockaddr *serv_addr,
socklen_t addrlen, struct timeval *timeout);
ssize_t send_timeout (int s, const void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t recv_timeout (int s, void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t recvfrom_timeout (int s, void *buf, size_t len, int flags,
struct sockaddr *address, socklen_t * address_len,
struct timeval *timeout);


/* Like send_timeout and recv_timeout, but they retry (with the same timeout) /* Like send_timeout and recv_timeout, but they retry (with the same timeout)
in case of partial transfers, in order to try to transfer all data. */ in case of partial transfers, in order to try to transfer all data. */
ssize_t send_all_timeout(int s, const void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t recv_all_timeout(int s, void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t send_all_timeout (int s, const void *buf, size_t len, int flags,
struct timeval *timeout);
ssize_t recv_all_timeout (int s, void *buf, size_t len, int flags,
struct timeval *timeout);


#endif #endif

+ 88
- 75
opt.c View File

@@ -11,85 +11,98 @@
#include <string.h> #include <string.h>
#include "opt.h" #include "opt.h"


void opt_init(int *optind) {
*optind=0;
void
opt_init (int *optind)
{
*optind = 0;
} }


char opt_parse(int argc, char **argv, int *optind, char **optarg,
struct options *opt) {
char c;
int i;
(*optind)++;
if(*optind>=argc)
return 0;
if(argv[*optind][0]=='-' &&
argv[*optind][1]!='-' &&
argv[*optind][1]!=0) {
/* Short option (or a bunch of 'em) */
/* Save this and shift others over */
c=argv[*optind][1];
for(i=2;argv[*optind][i]!=0;i++)
argv[*optind][i-1]=argv[*optind][i];
argv[*optind][i-1]=0;
if(argv[*optind][1]!=0)
(*optind)--;
/* Now find it */
for(i=0;opt[i].shortopt!=0;i++)
if(opt[i].shortopt==c)
break;
if(opt[i].shortopt==0) {
fprintf(stderr,"Error: unknown option '-%c'\n",c);
return '?';
}
if(opt[i].arg==NULL)
return c;
(*optind)++;
if(*optind>=argc || (argv[*optind][0]=='-' &&
argv[*optind][1]!=0)) {
fprintf(stderr,"Error: option '-%c' requires an "
"argument\n",c);
return '?';
}
(*optarg)=argv[*optind];
return c;
} else if(argv[*optind][0]=='-' &&
argv[*optind][1]=='-' &&
argv[*optind][2]!=0) {
/* Long option */
for(i=0;(c=opt[i].shortopt)!=0;i++)
if(strcmp(opt[i].longopt,argv[*optind]+2)==0)
break;
if(opt[i].shortopt==0) {
fprintf(stderr,"Error: unknown option '%s'\n",
argv[*optind]);
return '?';
}
if(opt[i].arg==NULL)
return c;
(*optind)++;
if(*optind>=argc || (argv[*optind][0]=='-' &&
argv[*optind][1]!=0)) {
fprintf(stderr,"Error: option '%s' requires an "
"argument\n",argv[*optind-1]);
return '?';
}
(*optarg)=argv[*optind];
return c;
} else {
/* End of options */
return 0;
char
opt_parse (int argc, char **argv, int *optind, char **optarg,
struct options *opt)
{
char c;
int i;
(*optind)++;
if (*optind >= argc)
return 0;

if (argv[*optind][0] == '-' &&
argv[*optind][1] != '-' && argv[*optind][1] != 0)
{
/* Short option (or a bunch of 'em) */
/* Save this and shift others over */
c = argv[*optind][1];
for (i = 2; argv[*optind][i] != 0; i++)
argv[*optind][i - 1] = argv[*optind][i];
argv[*optind][i - 1] = 0;
if (argv[*optind][1] != 0)
(*optind)--;
/* Now find it */
for (i = 0; opt[i].shortopt != 0; i++)
if (opt[i].shortopt == c)
break;
if (opt[i].shortopt == 0)
{
fprintf (stderr, "Error: unknown option '-%c'\n", c);
return '?';
}
if (opt[i].arg == NULL)
return c;
(*optind)++;
if (*optind >= argc || (argv[*optind][0] == '-' &&
argv[*optind][1] != 0))
{
fprintf (stderr, "Error: option '-%c' requires an "
"argument\n", c);
return '?';
}
(*optarg) = argv[*optind];
return c;
}
else if (argv[*optind][0] == '-' &&
argv[*optind][1] == '-' && argv[*optind][2] != 0)
{
/* Long option */
for (i = 0; (c = opt[i].shortopt) != 0; i++)
if (strcmp (opt[i].longopt, argv[*optind] + 2) == 0)
break;
if (opt[i].shortopt == 0)
{
fprintf (stderr, "Error: unknown option '%s'\n", argv[*optind]);
return '?';
} }
if (opt[i].arg == NULL)
return c;
(*optind)++;
if (*optind >= argc || (argv[*optind][0] == '-' &&
argv[*optind][1] != 0))
{
fprintf (stderr, "Error: option '%s' requires an "
"argument\n", argv[*optind - 1]);
return '?';
}
(*optarg) = argv[*optind];
return c;
}
else
{
/* End of options */
return 0;
}
} }


void opt_help(struct options *opt, FILE *out) {
int i;
int printed;
void
opt_help (struct options *opt, FILE * out)
{
int i;
int printed;


for(i=0;opt[i].shortopt!=0;i++) {
fprintf(out," -%c, --%s%n",opt[i].shortopt,
opt[i].longopt,&printed);
fprintf(out," %-*s%s\n",30-printed,
opt[i].arg?opt[i].arg:"",opt[i].help);
}
for (i = 0; opt[i].shortopt != 0; i++)
{
fprintf (out, " -%c, --%s%n", opt[i].shortopt,
opt[i].longopt, &printed);
fprintf (out, " %-*s%s\n", 30 - printed,
opt[i].arg ? opt[i].arg : "", opt[i].help);
}
} }

+ 10
- 9
opt.h View File

@@ -11,18 +11,19 @@


#include <stdlib.h> #include <stdlib.h>


struct options {
char shortopt;
char *longopt;
char *arg;
char *help;
struct options
{
char shortopt;
char *longopt;
char *arg;
char *help;
}; };


void opt_init(int *optind);
void opt_init (int *optind);


char opt_parse(int argc, char **argv, int *optind, char **optarg,
struct options *opt);
char opt_parse (int argc, char **argv, int *optind, char **optarg,
struct options *opt);


void opt_help(struct options *opt, FILE *out);
void opt_help (struct options *opt, FILE * out);


#endif #endif

+ 622
- 526
ue9.c
File diff suppressed because it is too large
View File


+ 73
- 70
ue9.h View File

@@ -16,56 +16,59 @@
#include "netutil.h" #include "netutil.h"


/* Calibration data */ /* Calibration data */
struct ue9Calibration {
double unipolarSlope[4];
double unipolarOffset[4];
double bipolarSlope;
double bipolarOffset;
double DACSlope[2];
double DACOffset[2];
double tempSlope;
double tempSlopeLow;
double calTemp;
double Vref;
double VrefDiv2;
double VsSlope;
double hiResUnipolarSlope;
double hiResUnipolarOffset;
double hiResBipolarSlope;
double hiResBipolarOffset;
struct ue9Calibration
{
double unipolarSlope[4];
double unipolarOffset[4];
double bipolarSlope;
double bipolarOffset;
double DACSlope[2];
double DACOffset[2];
double tempSlope;
double tempSlopeLow;
double calTemp;
double Vref;
double VrefDiv2;
double VsSlope;
double hiResUnipolarSlope;
double hiResUnipolarOffset;
double hiResBipolarSlope;
double hiResBipolarOffset;
}; };


/* Comm config */ /* Comm config */
struct ue9CommConfig {
uint8_t local_id;
uint8_t power_level;
in_addr_t address;
in_addr_t gateway;
in_addr_t subnet;
in_port_t portA;
in_port_t portB;
uint8_t dhcp_enabled;
uint8_t product_id;
uint8_t mac_address[6];
double hw_version;
double comm_fw_version;
struct ue9CommConfig
{
uint8_t local_id;
uint8_t power_level;
in_addr_t address;
in_addr_t gateway;
in_addr_t subnet;
in_port_t portA;
in_port_t portB;
uint8_t dhcp_enabled;
uint8_t product_id;
uint8_t mac_address[6];
double hw_version;
double comm_fw_version;
}; };


/* Control config */ /* Control config */
struct ue9ControlConfig {
uint8_t power_level;
uint8_t reset_source;
double control_fw_version;
double control_bl_version;
uint8_t hires;
uint8_t fio_dir;
uint8_t fio_state;
uint8_t eio_dir;
uint8_t eio_state;
uint8_t cio_dirstate;;
uint8_t mio_dirstate;
uint16_t dac0;
uint16_t dac1;
struct ue9ControlConfig
{
uint8_t power_level;
uint8_t reset_source;
double control_fw_version;
double control_bl_version;
uint8_t hires;
uint8_t fio_dir;
uint8_t fio_state;
uint8_t eio_dir;
uint8_t eio_state;
uint8_t cio_dirstate;;
uint8_t mio_dirstate;
uint16_t dac0;
uint16_t dac1;
}; };


#define UE9_UNIPOLAR_GAIN1 0x00 #define UE9_UNIPOLAR_GAIN1 0x00
@@ -77,65 +80,65 @@ struct ue9ControlConfig {
#define UE9_CHANNELS 14 #define UE9_CHANNELS 14


/* Fill checksums in data buffers */ /* Fill checksums in data buffers */
void ue9_checksum_normal(uint8_t *buffer, size_t len);
void ue9_checksum_extended(uint8_t *buffer, size_t len);
void ue9_checksum_normal (uint8_t * buffer, size_t len);
void ue9_checksum_extended (uint8_t * buffer, size_t len);


/* Verify checksums in data buffers. Returns 0 on error. */ /* Verify checksums in data buffers. Returns 0 on error. */
int ue9_verify_normal(uint8_t *buffer, size_t len);
int ue9_verify_extended(uint8_t *buffer, size_t len);
int ue9_verify_normal (uint8_t * buffer, size_t len);
int ue9_verify_extended (uint8_t * buffer, size_t len);


/* Open/close TCP/IP connection to the UE9 */ /* Open/close TCP/IP connection to the UE9 */
int ue9_open(const char *host, int port);
void ue9_close(int fd);
int ue9_open (const char *host, int port);
void ue9_close (int fd);


/* Read a memory block from the device. Returns -1 on error. */ /* Read a memory block from the device. Returns -1 on error. */
int ue9_memory_read(int fd, int blocknum, uint8_t *buffer, int len);
int ue9_memory_read (int fd, int blocknum, uint8_t * buffer, int len);


/* Convert 64-bit fixed point to double type */ /* Convert 64-bit fixed point to double type */
double ue9_fp64_to_double(uint8_t *data);
double ue9_fp64_to_double (uint8_t * data);


/* Retrieve calibration data or configuration from the device */ /* Retrieve calibration data or configuration from the device */
int ue9_get_calibration(int fd, struct ue9Calibration *calib);
int ue9_get_comm_config(int fd, struct ue9CommConfig *config);
int ue9_get_control_config(int fd, struct ue9ControlConfig *config);
int ue9_get_calibration (int fd, struct ue9Calibration *calib);
int ue9_get_comm_config (int fd, struct ue9CommConfig *config);
int ue9_get_control_config (int fd, struct ue9ControlConfig *config);


/* Data conversion. If calib is NULL, use uncalibrated conversions. */ /* Data conversion. If calib is NULL, use uncalibrated conversions. */
double ue9_binary_to_analog(struct ue9Calibration *calib,
uint8_t gain, uint8_t resolution, uint16_t data);
double ue9_binary_to_analog (struct ue9Calibration *calib,
uint8_t gain, uint8_t resolution, uint16_t data);


/* Compute scanrate based on the provided values. */ /* Compute scanrate based on the provided values. */
double ue9_compute_rate(uint8_t scanconfig, uint16_t scaninterval);
double ue9_compute_rate (uint8_t scanconfig, uint16_t scaninterval);


/* Choose the best ScanConfig and ScanInterval parameters for the /* Choose the best ScanConfig and ScanInterval parameters for the
desired scanrate. Returns 0 if nothing can be chosen. */ desired scanrate. Returns 0 if nothing can be chosen. */
int ue9_choose_scan(double desired_rate, double *actual_rate,
uint8_t *scanconfig, uint16_t *scaninterval);
int ue9_choose_scan (double desired_rate, double *actual_rate,
uint8_t * scanconfig, uint16_t * scaninterval);


/* Flush data buffers */ /* Flush data buffers */
void ue9_buffer_flush(int fd);
void ue9_buffer_flush (int fd);


/* Stop stream. Returns < 0 on failure. */ /* Stop stream. Returns < 0 on failure. */
int ue9_stream_stop(int fd);
int ue9_stream_stop (int fd);


/* Start stream. Returns < 0 on failure. */ /* Start stream. Returns < 0 on failure. */
int ue9_stream_start(int fd);
int ue9_stream_start (int fd);


/* Execute a command on the UE9. Returns -1 on error. Fills the /* Execute a command on the UE9. Returns -1 on error. Fills the
checksums on the outgoing packets, and verifies them on the checksums on the outgoing packets, and verifies them on the
incoming packets. Data in "out" is transmitted, data in "in" is incoming packets. Data in "out" is transmitted, data in "in" is
received. */ received. */
int ue9_command(int fd, uint8_t *out, uint8_t *in, int inlen);
int ue9_command (int fd, uint8_t * out, uint8_t * in, int inlen);


/* "Simple" stream configuration, assumes the channels are all /* "Simple" stream configuration, assumes the channels are all
configured with the same gain. */ configured with the same gain. */
int ue9_streamconfig_simple(int fd, int *channel_list, int channel_count,
uint8_t scanconfig, uint16_t scaninterval,
uint8_t gain);
int ue9_streamconfig_simple (int fd, int *channel_list, int channel_count,
uint8_t scanconfig, uint16_t scaninterval,
uint8_t gain);


/* Stream data and pass it to the data callback. If callback returns /* Stream data and pass it to the data callback. If callback returns
negative, stops reading and returns 0. Returns < 0 on error. */ negative, stops reading and returns 0. Returns < 0 on error. */
typedef int (*ue9_stream_cb_t)(int channels, uint16_t *data, void *context);
int ue9_stream_data(int fd, int channels,
ue9_stream_cb_t callback, void *context);
typedef int (*ue9_stream_cb_t) (int channels, uint16_t * data, void *context);
int ue9_stream_data (int fd, int channels,
ue9_stream_cb_t callback, void *context);


#endif #endif

+ 45
- 44
ue9error.c View File

@@ -1,51 +1,52 @@
#include "ue9error.h" #include "ue9error.h"


const char *ue9_error_text[] = { const char *ue9_error_text[] = {
[0] = "(no error)",
[SCRATCH_WRT_FAIL] = "SCRATCH_WRT_FAIL",
[SCRATCH_ERASE_FAIL] = "SCRATCH_ERASE_FAIL",
[DATA_BUFFER_OVERFLOW] = "DATA_BUFFER_OVERFLOW",
[ADC0_BUFFER_OVERFLOW] = "ADC0_BUFFER_OVERFLOW",
[FUNCTION_INVALID] = "FUNCTION_INVALID",
[SWDT_TIME_INVALID] = "SWDT_TIME_INVALID",
[FLASH_WRITE_FAIL] = "FLASH_WRITE_FAIL",
[FLASH_ERASE_FAIL] = "FLASH_ERASE_FAIL",
[FLASH_JMP_FAIL] = "FLASH_JMP_FAIL",
[FLASH_PSP_TIMEOUT] = "FLASH_PSP_TIMEOUT",
[FLASH_ABORT_RECEIVED] = "FLASH_ABORT_RECEIVED",
[FLASH_PAGE_MISMATCH] = "FLASH_PAGE_MISMATCH",
[FLASH_BLOCK_MISMATCH] = "FLASH_BLOCK_MISMATCH",
[FLASH_PAGE_NOT_IN_CODE_AREA] = "FLASH_PAGE_NOT_IN_CODE_AREA",
[MEM_ILLEGAL_ADDRESS] = "MEM_ILLEGAL_ADDRESS",
[FLASH_LOCKED] = "FLASH_LOCKED",
[INVALID_BLOCK] = "INVALID_BLOCK",
[FLASH_ILLEGAL_PAGE] = "FLASH_ILLEGAL_PAGE",
[STREAM_IS_ACTIVE] = "STREAM_IS_ACTIVE",
[STREAM_TABLE_INVALID] = "STREAM_TABLE_INVALID",
[STREAM_CONFIG_INVALID] = "STREAM_CONFIG_INVALID",
[STREAM_BAD_TRIGGER_SOURCE] = "STREAM_BAD_TRIGGER_SOURCE",
[STREAM_NOT_RUNNING] = "STREAM_NOT_RUNNING",
[STREAM_INVALID_TRIGGER] = "STREAM_INVALID_TRIGGER",
[STREAM_CONTROL_BUFFER_OVERFLOW] = "STREAM_CONTROL_BUFFER_OVERFLOW",
[STREAM_SCAN_OVERLAP] = "STREAM_SCAN_OVERLAP",
[STREAM_SAMPLE_NUM_INVALID] = "STREAM_SAMPLE_NUM_INVALID",
[STREAM_BIPOLAR_GAIN_INVALID] = "STREAM_BIPOLAR_GAIN_INVALID",
[STREAM_SCAN_RATE_INVALID] = "STREAM_SCAN_RATE_INVALID",
[TIMER_INVALID_MODE] = "TIMER_INVALID_MODE",
[TIMER_QUADRATURE_AB_ERROR] = "TIMER_QUADRATURE_AB_ERROR",
[TIMER_QUAD_PULSE_SEQUENCE] = "TIMER_QUAD_PULSE_SEQUENCE",
[TIMER_BAD_CLOCK_SOURCE] = "TIMER_BAD_CLOCK_SOURCE",
[TIMER_STREAM_ACTIVE] = "TIMER_STREAM_ACTIVE",
[TIMER_PWMSTOP_MODULE_ERROR] = "TIMER_PWMSTOP_MODULE_ERROR",
[EXT_OSC_NOT_STABLE] = "EXT_OSC_NOT_STABLE",
[INVALID_POWER_SETTING] = "INVALID_POWER_SETTING",
[PLL_NOT_LOCKED] = "PLL_NOT_LOCKED"
[0] = "(no error)",
[SCRATCH_WRT_FAIL] = "SCRATCH_WRT_FAIL",
[SCRATCH_ERASE_FAIL] = "SCRATCH_ERASE_FAIL",
[DATA_BUFFER_OVERFLOW] = "DATA_BUFFER_OVERFLOW",
[ADC0_BUFFER_OVERFLOW] = "ADC0_BUFFER_OVERFLOW",
[FUNCTION_INVALID] = "FUNCTION_INVALID",
[SWDT_TIME_INVALID] = "SWDT_TIME_INVALID",
[FLASH_WRITE_FAIL] = "FLASH_WRITE_FAIL",
[FLASH_ERASE_FAIL] = "FLASH_ERASE_FAIL",
[FLASH_JMP_FAIL] = "FLASH_JMP_FAIL",
[FLASH_PSP_TIMEOUT] = "FLASH_PSP_TIMEOUT",
[FLASH_ABORT_RECEIVED] = "FLASH_ABORT_RECEIVED",
[FLASH_PAGE_MISMATCH] = "FLASH_PAGE_MISMATCH",
[FLASH_BLOCK_MISMATCH] = "FLASH_BLOCK_MISMATCH",
[FLASH_PAGE_NOT_IN_CODE_AREA] = "FLASH_PAGE_NOT_IN_CODE_AREA",
[MEM_ILLEGAL_ADDRESS] = "MEM_ILLEGAL_ADDRESS",
[FLASH_LOCKED] = "FLASH_LOCKED",
[INVALID_BLOCK] = "INVALID_BLOCK",
[FLASH_ILLEGAL_PAGE] = "FLASH_ILLEGAL_PAGE",
[STREAM_IS_ACTIVE] = "STREAM_IS_ACTIVE",
[STREAM_TABLE_INVALID] = "STREAM_TABLE_INVALID",
[STREAM_CONFIG_INVALID] = "STREAM_CONFIG_INVALID",
[STREAM_BAD_TRIGGER_SOURCE] = "STREAM_BAD_TRIGGER_SOURCE",
[STREAM_NOT_RUNNING] = "STREAM_NOT_RUNNING",
[STREAM_INVALID_TRIGGER] = "STREAM_INVALID_TRIGGER",
[STREAM_CONTROL_BUFFER_OVERFLOW] = "STREAM_CONTROL_BUFFER_OVERFLOW",
[STREAM_SCAN_OVERLAP] = "STREAM_SCAN_OVERLAP",
[STREAM_SAMPLE_NUM_INVALID] = "STREAM_SAMPLE_NUM_INVALID",
[STREAM_BIPOLAR_GAIN_INVALID] = "STREAM_BIPOLAR_GAIN_INVALID",
[STREAM_SCAN_RATE_INVALID] = "STREAM_SCAN_RATE_INVALID",
[TIMER_INVALID_MODE] = "TIMER_INVALID_MODE",
[TIMER_QUADRATURE_AB_ERROR] = "TIMER_QUADRATURE_AB_ERROR",
[TIMER_QUAD_PULSE_SEQUENCE] = "TIMER_QUAD_PULSE_SEQUENCE",
[TIMER_BAD_CLOCK_SOURCE] = "TIMER_BAD_CLOCK_SOURCE",
[TIMER_STREAM_ACTIVE] = "TIMER_STREAM_ACTIVE",
[TIMER_PWMSTOP_MODULE_ERROR] = "TIMER_PWMSTOP_MODULE_ERROR",
[EXT_OSC_NOT_STABLE] = "EXT_OSC_NOT_STABLE",
[INVALID_POWER_SETTING] = "INVALID_POWER_SETTING",
[PLL_NOT_LOCKED] = "PLL_NOT_LOCKED"
}; };


const char *ue9_error(int errorcode)
const char *
ue9_error (int errorcode)
{ {
if (errorcode > ARRAY_SIZE(ue9_error_text))
return "(invalid errorcode)";
else
return ue9_error_text[errorcode];
if (errorcode > ARRAY_SIZE (ue9_error_text))
return "(invalid errorcode)";
else
return ue9_error_text[errorcode];
} }

+ 1
- 1
ue9error.h View File

@@ -44,6 +44,6 @@


extern const char *ue9_error_text[]; extern const char *ue9_error_text[];


const char *ue9_error(int errorcode);
const char *ue9_error (int errorcode);


#endif #endif

Loading…
Cancel
Save