|
|
| Copyright © 2000 Paul Sheer - Click here for copying permissions Source by FTP | |
5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195 200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 305 310 315 320 325 330 335 340 345 350 355 360 365 370 375 380 385 390 |
/* little program to allow any program on the network to read the ADC *//* to use, just telnet to the port and enter: * x, y * * where x is the channel, and y is the number of samples over which * you would like an average. It returns the time in seconds * since the socket was opened. * * Entering * reset * resets the time to zero. * * Entering * close * * closes the socket. */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <sys/io.h> /* for glibc */#include <netinet/ip.h>#include <arpa/inet.h>#include <netdb.h>#include <signal.h>#include <sys/time.h>#include <errno.h>#include "sample.h"#include "port.h"void milli_sleep (long milliseconds){ struct timeval tv; tv.tv_sec = milliseconds / 1000; tv.tv_usec = (milliseconds % 1000) * 1000; select (0, 0, 0, 0, &tv);}void pc30_init (PC30 * p, int base_address){ struct timeval tv;#ifdef __alpha__ if (ioperm (0x0000, 0x10000, 1)) { printf ("sample: Cannot get I/O permissions.\n"); exit (1); }#else if (iopl (3)) { printf ("sample: Cannot get I/O permissions.\n"); exit (1); }#endif memset (p, 0, sizeof (PC30)); p->base_address = base_address; port_out (0x92, PC30_ADMDE (p)); port_out (0x34, PC30_TMRCTR (p)); port_out (0x74, PC30_TMRCTR (p)); port_out (0xB6, PC30_TMRCTR (p)); port_out (0x02, PC30_ADCCR (p)); port_out (0, PC30_DIOCNTRL (p)); port_out (0, PC30_GMEM (p, 0)); port_out (0, PC30_GMEM (p, 1)); port_out (0, PC30_GMEM (p, 2)); port_out (0, PC30_GMEM (p, 3)); tv.tv_sec = 0; tv.tv_usec = 100; select (0, 0, 0, 0, &tv); port_in (PC30_ADDATL (p)); port_in (PC30_ADDSR (p));}void pc30_clear (PC30 * p){ struct timeval tv;// port_out (PC30_ADMDE (p), 0x92); port_out (PC30_ADCCR (p), 0x02); port_in (PC30_ADDATL (p)); port_in (PC30_ADDSR (p));/* sleep 100 microseconds sec */ tv.tv_sec = 0; tv.tv_usec = 100; select (0, 0, 0, 0, &tv); port_in (PC30_ADDATL (p)); port_in (PC30_ADDSR (p));}void pc30_set_gain (PC30 * p, int channel, int gain){ int reg, shift, val; reg = channel & 0x3; shift = (channel >> 2) << 1; val = port_in (PC30_GMEM (p, reg)); val = (val & (0xFFFF ^ (3 << shift))) | ((gain & 3) << shift); port_out (val, PC30_GMEM (p, reg));}int pc30_getsample (PC30 * p, int channel){ int r;#if 0/* this just seems to be a waiste of milliseconds (we initialised already): */ pc30_clear (p); pc30_set_gain (p, channel, p->gain[channel]);#endif port_out (PC30_STBC | (channel << 4), PC30_ADCCR (p)); port_out (PC30_STBC | PC30_SSTB | (channel << 4), PC30_ADCCR (p)); port_out (PC30_STBC | (channel << 4), PC30_ADCCR (p)); while (!(port_in (PC30_ADDSR (p)) & PC30_ADDONE)); r = port_in (PC30_ADDATL (p)); r |= port_in (PC30_ADDSR (p)) << 8; return (r & 0x0FFF) - (0x0FFF / 2);}double pc30_getsample_ave (PC30 * p, int channel, int n){ double ave = 0.0; int i; for (i = 0; i < n; i++) ave += (double) pc30_getsample (p, channel); return (double) ave / (double) n;}#define MAX_SOCKETS 64#define MAX_SOCKET_RESULT 32#define NUM_CHANNELS 8#define LISTEN_PORT 1928struct client_adc { int socket; double time; char result[MAX_SOCKET_RESULT];} adc_socket[MAX_SOCKETS];static void fatal_error (char *fmt, ...){ va_list ap; va_start (ap, fmt); fprintf (stderr, "sampled: aborting: "); vfprintf (stderr, fmt, ap); fprintf (stderr, "\n"); if (errno) fprintf (stderr, "[%s]\n", sys_errlist[errno]); va_end (ap); exit (1);}void usage (void){ printf ("Usage:\n\tsample [-v] [-p <port>] [-h]\n\n"); printf ("-h help\n"); printf ("-v verbose (-v -v for greater verbosity)\n"); printf ("-d run as daemon\n"); printf ("-p set listen port\n\n"); printf ("See sample.c for more help.\n\n"); exit (0);}double gettime (void){ struct timeval tv; gettimeofday (&tv, 0); return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;}int main (int argc, char **argv){ int a; int verbose = 0; int sock, port = LISTEN_PORT; PC30 p; struct sockaddr_in server_address; struct hostent *hp; char hostname[255]; int yes = 1; errno = 0; for (a = 1; a < argc; a++) { if (!strcmp (argv[a], "-v")) { verbose++; continue; } if (!strcmp (argv[a], "-d")) { if (fork ()) exit (0); if (fork ()) exit (0); continue; } if (!strcmp (argv[a], "-h")) { usage (); continue; } if (!strcmp (argv[a], "-p")) { if (argv[++a]) port = atoi (argv[a]); else fatal_error ("error on command line: try\n\tsample -h"); continue; } fatal_error ("error on command line: try\n\tsample -h"); } pc30_init (&p, 0x700); if ((sock = socket (AF_INET, SOCK_STREAM, 0)) < 0) fatal_error ("socket() failed"); if (verbose) printf ("sock = %d\n", sock); /* Use this to debug: */ if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (char *) &yes, sizeof (yes)) < 0) fatal_error ("setsockopt() failed"); gethostname (hostname, 255); if (!(hp = gethostbyname (hostname))) fatal_error ("gethostbyname() failed"); memset ((char *) &server_address, 0, sizeof (server_address)); server_address.sin_family = hp->h_addrtype; server_address.sin_addr.s_addr = INADDR_ANY; server_address.sin_port = htons (port); if (verbose) printf ("listen port is %d\n", port); if (bind (sock, (struct sockaddr *) &server_address, sizeof (server_address)) < 0) fatal_error ("bind() failed"); listen (sock, 5); for (a = 0; a < MAX_SOCKETS; a++) { adc_socket[a].socket = 0; adc_socket[a].result[0] = '\0'; } signal (SIGPIPE, SIG_IGN); for (;;) { int i; fd_set writing, reading; int last_sock = 0; FD_ZERO (&writing); FD_ZERO (&reading); FD_SET (sock, &reading); if (sock > last_sock) last_sock = sock; for (i = 0; i < MAX_SOCKETS; i++) { if (adc_socket[i].socket) { FD_SET (adc_socket[i].socket, &reading); if (adc_socket[i].result[0]) FD_SET (adc_socket[i].socket, &writing); if (adc_socket[i].socket > last_sock) last_sock = adc_socket[i].socket; } } if (verbose > 1) printf ("select (%d,...)\n", last_sock + 1); if (select (last_sock + 1, &reading, &writing, 0, 0) == -1) fatal_error ("select() return -1"); if (FD_ISSET (sock, &reading)) { struct sockaddr_in client_address; unsigned int l = sizeof (client_address); if (verbose > 1) printf ("FD_ISSET (sock = %d, &reading)\n", sock); for (i = 0; i < MAX_SOCKETS && adc_socket[i].socket; i++); if (i == MAX_SOCKETS) fatal_error ("MAX_SOCKETS reached"); if (verbose > 1) printf ("accepting:\n"); adc_socket[i].socket = accept (sock, (struct sockaddr *) &client_address, &l); adc_socket[i].result[0] = '\0'; adc_socket[i].time = gettime (); if (verbose > 1) printf ("%d = accept (sock = %d,...)\n", adc_socket[i].socket, sock); } for (i = 0; i < MAX_SOCKETS; i++) { if (FD_ISSET (adc_socket[i].socket, &reading)) { int l; char buf[1024] = ""; if (verbose > 1) printf ("FD_ISSET (%d, &reading)\n", adc_socket[i].socket); l = read (adc_socket[i].socket, buf, 1024); if (verbose > 1) printf ("%d = read (%d, ...)\n", l, adc_socket[i].socket); if (l <= 0) { if (verbose) printf ("read error, closing socket %d\n", adc_socket[i].socket); close (adc_socket[i].socket); adc_socket[i].socket = 0; adc_socket[i].result[0] = '\0'; continue; } if (!strncmp (buf, "close", 5)) { if (verbose) printf ("recieved \"close\", closing socket %d\n", adc_socket[i].socket); close (adc_socket[i].socket); adc_socket[i].socket = 0; adc_socket[i].result[0] = '\0'; continue; } if (!strncmp (buf, "reset", 5)) { adc_socket[i].time = gettime (); continue; } if (verbose) printf ("got command: \"%.50s\", from socket %d\n", buf, adc_socket[i].socket); { char *q; int channel, samples = 0; channel = atoi (buf); q = (char *) strchr (buf, ','); if (q) while (strchr (", \t", *q)) q++; if (q) samples = atoi (q); if (!samples || channel < 0 || channel >= NUM_CHANNELS) { if (verbose) printf ("bad command: \"%.50s\", closing socket %d\n", buf, adc_socket[i].socket); close (adc_socket[i].socket); adc_socket[i].socket = 0; adc_socket[i].result[0] = '\0'; continue; } sprintf (adc_socket[i].result, "%.3f, %.3f\n", gettime () - adc_socket[i].time, pc30_getsample_ave (&p, channel, atoi (q))); } } } for (i = 0; i < MAX_SOCKETS; i++) { if (FD_ISSET (adc_socket[i].socket, &writing)) { int l; if (verbose > 1) printf ("FD_ISSET (%d, &writing)\n", adc_socket[i].socket); l = write (adc_socket[i].socket, adc_socket[i].result, strlen (adc_socket[i].result)); if (verbose > 1) printf ("%d = write (%d, ...)\n", l, adc_socket[i].socket); if (l != strlen (adc_socket[i].result)) { if (verbose) printf ("write error, closing socket %d\n", adc_socket[i].socket); close (adc_socket[i].socket); adc_socket[i].socket = 0; adc_socket[i].result[0] = '\0'; } adc_socket[i].result[0] = '\0'; } } } return 0;} |