source: projects/punch-card/driver/nixdorf-0377.01/reader.c @ 34

Last change on this file since 34 was 34, checked in by sven, 11 years ago

Start of Punch card project: Nixdorf 42 0377.01
device driver

-- sven @ nils

File size: 4.7 KB
Line 
1/**
2 * Linux parallel port userspace driver (ppdev) for the
3 *  Nixdorf 0043/44 punch card reader with
4 *  buffer 0377.01 (8 bit encoding)
5 *
6 * Copyright (c) March 2009 Sven Koeppel
7 *
8 * This program is free software; you can redistribute
9 * it and/or modify it under the terms of the GNU General
10 * Public License as published by the Free Software
11 * Foundation; either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * This program is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY; without even the
16 * implied warranty of MERCHANTABILITY or FITNESS FOR A
17 * PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 *
20 * You should have received a copy of the GNU General
21 * Public License along with this program; if not, see
22 * <http://www.gnu.org/licenses/>.
23 *
24 **/
25 
26#include <stdio.h>
27#include <unistd.h>
28#include <stdlib.h>
29#include <errno.h>
30#include <time.h>
31#include <fcntl.h>
32
33#include <sys/ioctl.h>
34#include <linux/ppdev.h>
35#include <linux/parport.h>
36
37#include <sys/time.h>
38#include <sys/select.h>
39
40#define PARPORT_DEVICE "/dev/parport0"
41
42int parport_fd;
43
44typedef enum {
45        MAGNET_ON,
46        MAGNET_OFF
47} magnet_status_t;
48
49void set_magnet(magnet_status_t target_status) {
50        unsigned char mask = (target_status==MAGNET_OFF ? PARPORT_CONTROL_AUTOFD : 0x0);
51        if(ioctl(parport_fd, PPWCONTROL, &mask)) {
52                perror("Setting magnet status (control lines)");
53                exit(0);
54        }
55}
56
57int mtime(long long since) {
58        /* gibt Millisekunden zurueck seit since. since sind dabei die
59           Millisekunden seit der Unix-Epoche. Ein initiales since kann
60           per mtime(0) gefunden werden. */
61        struct timeval time;
62        gettimeofday(&time, NULL);
63              // Sec*10^3
64        return (time.tv_sec * 1000 + (long long)(time.tv_usec / 1000)) - since;
65}
66
67void print_bit(char* label, int pos, unsigned char byte) {
68        int value = ((byte >> pos) & 0x01)==0 ? 0 : 1;
69        if(label == NULL)
70                printf("%i=%i ", pos, value);
71        else
72                printf("%s=%i ", label, value);
73}
74
75void simple_reading_program() {
76        // this will never touch the magnet...
77        long long abs_time = mtime(0);
78        for(;;) {
79                fflush(NULL);
80                unsigned char data;
81                unsigned char status;
82                fd_set rfds;
83                FD_ZERO (&rfds);
84                FD_SET (parport_fd, &rfds);
85                //printf("Waiting for interrupt...\n");
86                if (!select (parport_fd + 1, &rfds, NULL, NULL, NULL)) {
87                        /* Caught a signal? */
88                        printf("Caught a signal...");
89                        continue;
90                }
91                       
92                // we've got that interrupt
93                // fetch current register values
94                if(ioctl(parport_fd, PPRDATA, &data)) {
95                        perror("Interrupt data readout");
96                        exit(1);
97                }
98                if(ioctl(parport_fd, PPRSTATUS, &status)) {
99                        perror("Status data readout");
100                        exit(1);
101                }
102               
103                // display status:
104                printf("%i: ",(int)mtime(abs_time));
105                if(status & PARPORT_STATUS_SELECT) {
106                                       
107                printf("DATA: ");
108                int pos;
109                for(pos=0; pos<8; print_bit(NULL, pos++, data));
110                printf("| STATUS: ");
111                print_bit("ERROR", 3, status);
112                print_bit("SEL", 4, status);
113                print_bit("PE", 5, status);
114                print_bit("ACK", 6, status);
115                print_bit("BUSY", 7, status);
116                printf("\n");
117               
118                } else {
119                        printf("no card.\n");
120                }
121               
122                // clear the interrupt
123                unsigned char irqc;
124                ioctl(parport_fd, PPCLRIRQ, &irqc);
125                if(irqc > 1)
126                        printf("MISSED %d INTTERUPT%s!!!!!\n", irqc-1, irqc == 2 ? "S" : "");
127        }
128} // function
129
130void magnet_testing_program() {
131        printf("Looping.\n");
132
133        int x = 10;
134        //for(x=0; x<10; x++) {
135        while(x > 0) {
136                printf("m = Magnet, o = Magnet off, q = Quit\n> ");
137                fflush(NULL);
138                switch(getchar()) {
139                        case '\n': break;
140                        case 'm':
141                                printf("Magnet is ON!\n");
142                                set_magnet(MAGNET_ON); break;
143                        case 'q':
144                                printf("Quitting\n");
145                                x = -42;
146                                break;
147                        case 'o':
148                        default:
149                                printf("Magnet is OFF!\n");
150                                set_magnet(MAGNET_OFF);
151                }
152        }
153}
154
155int main(int arvc, char** argv) {
156        printf("opening device %s...\n", PARPORT_DEVICE);
157        parport_fd = open(PARPORT_DEVICE, O_RDWR);
158        if(parport_fd == -1) {
159                perror("opening device failed");
160                return 1;
161        }
162       
163        printf("claiming port...\n");
164        if(ioctl(parport_fd, PPCLAIM)) {
165                perror("claiming port (PPCLAIM)");
166                return 1;
167        }
168       
169        printf("setting compatibility mode...\n");
170        int mode = IEEE1284_MODE_COMPAT; //BYTE; //COMPAT;
171        if(ioctl(parport_fd, PPNEGOT, &mode)) {
172                perror("Setting compatibilty mode (PPNEGOT)");
173                return 1;
174        }
175       
176        printf("Disabling data line drivers...\n");
177        mode = 1;
178        if(ioctl(parport_fd, PPDATADIR, &mode)) {
179                perror("Setting PPDATADIR");
180                return 1;
181        }
182       
183        printf("Ready to start.\n");
184        printf("Setting up control mask\n");
185       
186        set_magnet(MAGNET_OFF);
187        //magnet_testing_program();
188       
189        // now fetch interrupts and give out data at these times.
190        // never use the magnet.
191        simple_reading_program();
192       
193
194        printf("Finished. Turning magnet off and quitting.\n");
195        set_magnet(MAGNET_OFF);
196        return 0;
197} // main
198
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License