chiark / gitweb /
commented-out idents
[trains.git] / parport / train-pic-prog-select.c
1 /**/
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <fcntl.h>
11
12 #include <sys/ioctl.h>
13 #include <linux/ppdev.h>
14
15 #include "lib.h"
16
17 #define COLUMNS 7
18 #define ROWS 8
19
20 static const void badusage(const char *what) {
21   fprintf(stderr,"bad usage: %s\n"
22           "usage: train-pic-prog-select -i0|-i1"
23           " [-p/dev/parport] picno|range...\n"
24           "ranges are picno-picno (inclusive)\n"
25           "-i0 means PPWDATA bit is 0 for selected pics; -i1 means 1\n"
26           " (default: value of TRAIN_PPWDATA_SEL_BIT env. var)\n"
27           "-pstdin means use fd 0; -pstdin-noclaim uses fd 0 and"
28           " doesn't PPCLAIM\n",
29           what);
30   exit(126);
31 }
32
33 typedef unsigned char yesno;
34
35 const char *parport= "/dev/parport0";
36
37 static int yesfor1bit= -1; /* same as bit needed for `yes' :-) */
38
39 static union {
40   yesno rect[COLUMNS][ROWS];
41   yesno lin[COLUMNS*ROWS];
42 } yesses;
43
44 static void wpause(int ioctlnum, unsigned char value) {
45   printf(" %s%02x",
46          ioctlnum == PPWCONTROL ? "C" :
47          ioctlnum == PPWDATA ? "" : 0,
48          value);
49   doioctl(ioctlnum, &value, value);
50   usleep(5000);
51 }
52
53 int main(int argc, const char *const *argv) {
54   long first, last;
55   int row, col, v, nselected;
56   char *ep;
57   const char *arg;
58   
59   if (!*argv++) badusage("need argv[0]");
60   while ((arg= *argv) && arg[0]=='-') {
61     argv++;
62     if (arg[1]=='p') {
63       parport= arg+2;
64     } else if (arg[1]=='i') {
65       yesfor1bit= atoi(arg+2);
66     } else {
67       badusage("unknown option");
68     }
69   }
70   if (!(yesfor1bit==0 || yesfor1bit==1)) badusage("need proper -i value");
71
72   if (!*argv) badusage("need to specify pics");
73
74   while ((arg= *argv++)) {
75     first= last= strtol(arg,&ep,10);
76     if (ep==arg) badusage("syntactically incorrect pic number");
77     if (*ep == '-') {
78       last= strtol((arg=ep+1),&ep,10);
79       if (ep==arg) badusage("syntactically incorrect range");
80     }
81     if (*ep) badusage("syntactically incorrect picno or range");
82     if (first<0 || last>COLUMNS*ROWS-1 || first>last)
83       badusage("picno or range out of permissible range");
84     for (; first<=last; first++) {
85       if (yesses.lin[first]) badusage("one pic specified more than once");
86       yesses.lin[first]= 1;
87     }
88   }
89   if (!strcmp(parport,"stdin") || !strcmp(parport,"stdin-noclaim")) {
90     fd= 0;
91   } else {
92     fd= open(parport, O_RDWR);
93     if (fd<0) { perror(parport); exit(-1); }
94   }
95
96   setvbuf(stdout,0,_IONBF,0);
97   
98   for (nselected=0, row=0; row<ROWS; row++)
99     for (col=0; col<COLUMNS; col++)
100       if (yesses.rect[col][row])
101         nselected++;
102
103   if (!strcmp(parport,"stdin-noclaim")) {
104     printf("Not claiming.\n");
105   } else {
106     printf("Claiming %s...\n", parport);
107     doioctl(PPCLAIM,0,0);
108   }
109
110   printf("Selecting %d/%d; bytes:", nselected, ROWS*COLUMNS);
111   wpause(PPWCONTROL, 0x02 /* !ENGAGE_VPP, !PC, !PDW */);
112
113   for (row=0; row<ROWS; row++) {
114     v= 0;
115     for (col=0; col<COLUMNS; col++)
116       v |= yesses.rect[col][row]==yesfor1bit ? 0 : (1<<col);
117     wpause(PPWDATA, v | 0x80);
118     wpause(PPWDATA, v); /* SEL_CLK  ~|_  shifts */
119   }
120   wpause(PPWDATA, yesfor1bit ? 0xff : 0x80); /* SEL_CLK  _|~  deploys */
121   putchar('\n');
122   return 0;
123 }