1
0
Files
2022-09-29 17:59:04 +03:00

338 lines
8.3 KiB
C

/*
testdeck.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <unistd.h>
#include <bstring.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/mman.h>
#include <sys/statfs.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/prctl.h>
#include <assert.h>
#include <signal.h>
#include <sys/param.h>
#include <fcntl.h>
#include <ulocks.h>
#include <errno.h>
#include <stropts.h>
#include <dmedia/dmedia.h>
#include "../inc/tserialio.h"
TSstatus tsSetDebug(TSconfig config, int debug);
#include "util.h"
void giveup(void)
{
printf("GIVING UP\n");
sleep(2); /* to keep serial port alive for tracing on scope */
exit(2);
}
/* simple sony RS-422 protocol parsing ----------------------------------- */
void send1(TSport wp,
unsigned char cmd1, unsigned char cmd2,
unsigned char data1)
{
unsigned char c;
stamp_t stamp=0;
tsWrite(wp, &cmd1, &stamp, 1);
tsWrite(wp, &cmd2, &stamp, 1);
tsWrite(wp, &data1, &stamp, 1);
c = (unsigned char)(cmd1+cmd2+data1); /* checksum */
tsWrite(wp, &c, &stamp, 1);
}
#define packem(hi, lo) (((unsigned char)(hi) << 4) | ((unsigned char)(lo)))
void sendtc(TSport wp,
unsigned char cmd1, unsigned char cmd2,
int h, int m, int s, int f)
{
unsigned char hh = packem(h/10, h%10);
unsigned char mm = packem(m/10, m%10);
unsigned char ss = packem(s/10, s%10);
unsigned char ff = packem(f/10, f%10);
unsigned char c;
stamp_t stamp=0;
tsWrite(wp, &cmd1, &stamp, 1);
tsWrite(wp, &cmd2, &stamp, 1);
tsWrite(wp, &ff, &stamp, 1);
tsWrite(wp, &ss, &stamp, 1);
tsWrite(wp, &mm, &stamp, 1);
tsWrite(wp, &hh, &stamp, 1);
c = (unsigned char)(cmd1+cmd2+ff+ss+mm+hh); /* checksum */
tsWrite(wp, &c, &stamp, 1);
}
int readit_verbose = 1;
unsigned char readit(TSport rp, stamp_t *stamp,
stamp_t timeout, int *timedout)
{
unsigned char c;
int nfilled = tsGetFilledBytes(rp);
if (nfilled == 0)
{
if (timeout == 0)
{
*timedout = 1;
*stamp = -1;
return 0xff;
}
/* wait for timeout */
{
int nfds;
fd_set readset;
struct timeval tv; /* 1/2 sec means deck is dead */
tv.tv_sec = timeout / 1000000000LL;
tv.tv_usec = (timeout - 1000000000LL*tv.tv_sec) / 1000;
FD_ZERO(&readset);
FD_SET(tsGetFD(rp), &readset);
tsSetFillPointBytes(rp, 1);
if ((nfds=select(getdtablehi(), &readset, NULL, NULL, &tv)) < 0)
perror_exit("read select");
if (nfds == 0) /* timed out */
{
*timedout = 1;
*stamp = -1;
return 0xff;
}
}
}
assert(tsGetFilledBytes(rp) > 0);
tsRead(rp, &c, stamp, 1);
*timedout = 0;
if (readit_verbose)
printf("got 0x%02x at %lld\n", c, *stamp);
return c;
}
void print_tc(unsigned char tc[4])
{
printf("%02xh:%02xm:%02xs:%02xf%s",
tc[3], tc[2], tc[1]&0x7f, tc[0], (tc[1]&0x80)?"*":"");
}
void print_ub(unsigned char ub[4])
{
printf("ub%02x:%02x:%02x:%02x", ub[3], ub[2], ub[1], ub[0]);
}
#define CHECK_BAIL() { if (timedout) return 0; }
int readresp(TSport rp, stamp_t timeout)
{
unsigned char cmd1, cmd2;
unsigned short cmd;
unsigned char data[16];
unsigned char csum, ocsum;
int ndata, i;
stamp_t stamp;
int timedout;
cmd1 = readit(rp, &stamp, timeout, &timedout); CHECK_BAIL();
cmd2 = readit(rp, &stamp, timeout, &timedout); CHECK_BAIL();
cmd = (cmd1<<8) | cmd2;
ndata = (cmd1 & 0x0f);
csum = cmd1 + cmd2;
for(i=0; i < ndata; i++)
{
data[i] = readit(rp, &stamp, timeout, &timedout); CHECK_BAIL();
csum += data[i];
}
ocsum = readit(rp, &stamp, timeout, &timedout); CHECK_BAIL();
if (csum != ocsum)
{
printf("warning: checksum bad\n");
giveup();
}
switch (cmd)
{
case 0x1001:
printf("ACK\n");
break;
case 0x1112:
printf("NACK %02x\n", data[0]);
exit(2);
break;
case 0x7400: printf("TIMER-1 tc: "); print_tc(data);
printf("\n"); break;
case 0x7404: printf("LTC tc: "); print_tc(data);
printf("\n"); break;
case 0x7804: printf("LTC tc: "); print_tc(data);
printf(" LTC ub: "); print_ub(data+4);
printf("\n"); break;
case 0x7405: printf("LTC ub: "); print_ub(data);
printf("\n"); break;
case 0x7406: printf("VITC tc: "); print_tc(data);
printf("\n"); break;
case 0x7806: printf("VITC tc: "); print_tc(data);
printf(" VITC ub: "); print_ub(data+4);
printf("\n"); break;
case 0x7407: printf("VITC ub: "); print_ub(data);
printf("\n"); break;
case 0x700d: printf("no time to report, sorry.");
printf("\n"); break;
case 0x7414: printf("LTC (interp) tc: "); print_tc(data);
printf("\n"); break;
case 0x7814: printf("LTC (interp) tc: "); print_tc(data);
printf(" LTC (interp) ub: "); print_ub(data+4);
printf("\n"); break;
case 0x7416: printf("VITC (hold) tc: "); print_tc(data);
printf(" VITC (hold) ub: "); print_ub(data+4);
printf("\n"); break;
case 0x7816: printf("VITC (hold) tc: "); print_tc(data);
printf("\n"); break;
default:
printf("Command %04x: ", cmd);
for(i=0; i < ndata; i++)
printf("%02x ", data[i]);
printf("\n");
break;
}
return 1;
}
int main(int argc, char **argv)
{
TSport rp, wp;
char devname[20];
int c, rc;
int portnum = 2;
stamp_t timeout = 10000000; /* 10 ms */
while ((c = getopt(argc, argv, "p:d:r:")) != EOF)
{
switch(c)
{
case 'p':
portnum = atoi(optarg);
break;
case 'd': /* in millisecons */
timeout = 1.E6 * atof(optarg);
break;
case 'r':
readit_verbose = atoi(optarg);
break;
}
}
printf("opening serial port %d\n", portnum);
sprintf(devname,"/dev/ttyts%d", portnum);
#define QSIZE 100
{
TSconfig config = tsNewConfig();
tsSetPortName(config, devname);
tsSetQueueSize(config, QSIZE);
tsSetCflag(config, CS8|PARENB|PARODD);
tsSetOspeed(config, 38400);
tsSetDebug(config, TS_INTR_DEBUG|TS_LIB_DEBUG);
tsSetDebug(config, 0 /* TS_INTR_DEBUG|TS_TX_DEBUG|TS_LIB_DEBUG */ );
tsSetDirection(config, TS_DIRECTION_RECEIVE);
if (TS_SUCCESS != (rc=tsOpenPort(config, &rp)))
error_exit("rx open bailed with %d", rc);
tsSetDirection(config, TS_DIRECTION_TRANSMIT);
if (TS_SUCCESS != (rc=tsOpenPort(config, &wp)))
error_exit("tx open bailed with %d", rc);
tsFreeConfig(config);
}
#if 0
sendtc(wp, 0x24, 0x31, 1, 2, 14, 0);
readresp(rp, 1000000000);
printf("cueued up; press a key...\n");
getchar();
#else
printf("rippin now\n");
#endif
while (1)
{
stamp_t then, now;
dmGetUST((unsigned long long *)&then);
/* send current time sense command */
printf("sending\n");
send1(wp,
0x61, 0x0c, /* current time sense */
0x03);
/* read response */
if (!readresp(rp, timeout))
{
#if 0
printf("response timed out. NO DRAIN!!\n");
#elif 0
printf("response timed out. fast drain\n"
"-------------------------------\n");
while (tsGetFilledBytes(rp) > 0)
{
unsigned char c;
stamp_t stamp;
tsRead(rp, &c, &stamp, 1);
printf("draining: 0x%02x at %lld\n", c, stamp);
}
#else
printf("response timed out. draining rx up to 1 sec\n"
"--------------------------------------------\n");
while (1)
{
int timedout;
stamp_t stamp;
unsigned char c;
c = readit(rp, &stamp, 1000000000, &timedout);
printf("draining: 0x%02x\n", c);
if (timedout) break;
}
#endif
}
/* sleep for rest of desired period */
dmGetUST((unsigned long long *)&now);
if (now < then+timeout)
sginap( CLK_TCK * ((then+timeout-now)/1.E9) );
}
return 0;
}