Index: /documentation/index.php
===================================================================
--- /documentation/index.php (revision 33)
+++ /documentation/index.php (revision 34)
@@ -141,5 +141,9 @@
),
'The Punch Card Project' => array(
- 'Start' => $doc.'/punch-card.htm'
+ 'Start' => $doc.'/punch-card.htm',
+ 'Device Drivers' => array(
+ 'Overview' => 'punch-card/drivers/README.htm',
+ 'Nixdorf 0377.01' => 'punch-card/drivers/nixdorf-0377.01/README.htm'
+ )
),
#'About' => $doc.'/about.htm'
Index: /punch-card/driver/README.htm
===================================================================
--- /punch-card/driver/README.htm (revision 34)
+++ /punch-card/driver/README.htm (revision 34)
@@ -0,0 +1,14 @@
+
+
+
+Punch card device drivers
+
+
+ This directory contains device drivers for various punch card
+ devices.
+
+
List of device drivers
+
+
Index: /punch-card/driver/nixdorf-0377.01/README.htm
===================================================================
--- /punch-card/driver/nixdorf-0377.01/README.htm (revision 34)
+++ /punch-card/driver/nixdorf-0377.01/README.htm (revision 34)
@@ -0,0 +1,26 @@
+
+
+
+Nixdorf 43/44 Punch card reader
+
+
+ This is a Linux ppdev userspace driver for a small card reader made by
+ Nixdorf, equipped with the buffer board 377.01. This board encodes the
+ 12 bit punch card code (H code) to 8 bit, by compressing row 1 to 7 to
+ only 3 bits.
+
+
+ The connection is established via a self made cable from a pseudo standard
+ Siemens plug to IEEE 1284 and to the power supply of the card reader.
+
+
+
+About
+
+ Project started in February 2009, coding the very first driver started at
+ Sunday, 22. March 2009.
+
+
+ Copyright 2009 Sven Koeppel, GNU Public License applies here like to the
+ complete project.
+
Index: /punch-card/driver/nixdorf-0377.01/reader.c
===================================================================
--- /punch-card/driver/nixdorf-0377.01/reader.c (revision 34)
+++ /punch-card/driver/nixdorf-0377.01/reader.c (revision 34)
@@ -0,0 +1,198 @@
+/**
+ * Linux parallel port userspace driver (ppdev) for the
+ * Nixdorf 0043/44 punch card reader with
+ * buffer 0377.01 (8 bit encoding)
+ *
+ * Copyright (c) March 2009 Sven Koeppel
+ *
+ * This program is free software; you can redistribute
+ * it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software
+ * Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will
+ * be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General
+ * Public License along with this program; if not, see
+ * .
+ *
+ **/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#define PARPORT_DEVICE "/dev/parport0"
+
+int parport_fd;
+
+typedef enum {
+ MAGNET_ON,
+ MAGNET_OFF
+} magnet_status_t;
+
+void set_magnet(magnet_status_t target_status) {
+ unsigned char mask = (target_status==MAGNET_OFF ? PARPORT_CONTROL_AUTOFD : 0x0);
+ if(ioctl(parport_fd, PPWCONTROL, &mask)) {
+ perror("Setting magnet status (control lines)");
+ exit(0);
+ }
+}
+
+int mtime(long long since) {
+ /* gibt Millisekunden zurueck seit since. since sind dabei die
+ Millisekunden seit der Unix-Epoche. Ein initiales since kann
+ per mtime(0) gefunden werden. */
+ struct timeval time;
+ gettimeofday(&time, NULL);
+ // Sec*10^3
+ return (time.tv_sec * 1000 + (long long)(time.tv_usec / 1000)) - since;
+}
+
+void print_bit(char* label, int pos, unsigned char byte) {
+ int value = ((byte >> pos) & 0x01)==0 ? 0 : 1;
+ if(label == NULL)
+ printf("%i=%i ", pos, value);
+ else
+ printf("%s=%i ", label, value);
+}
+
+void simple_reading_program() {
+ // this will never touch the magnet...
+ long long abs_time = mtime(0);
+ for(;;) {
+ fflush(NULL);
+ unsigned char data;
+ unsigned char status;
+ fd_set rfds;
+ FD_ZERO (&rfds);
+ FD_SET (parport_fd, &rfds);
+ //printf("Waiting for interrupt...\n");
+ if (!select (parport_fd + 1, &rfds, NULL, NULL, NULL)) {
+ /* Caught a signal? */
+ printf("Caught a signal...");
+ continue;
+ }
+
+ // we've got that interrupt
+ // fetch current register values
+ if(ioctl(parport_fd, PPRDATA, &data)) {
+ perror("Interrupt data readout");
+ exit(1);
+ }
+ if(ioctl(parport_fd, PPRSTATUS, &status)) {
+ perror("Status data readout");
+ exit(1);
+ }
+
+ // display status:
+ printf("%i: ",(int)mtime(abs_time));
+ if(status & PARPORT_STATUS_SELECT) {
+
+ printf("DATA: ");
+ int pos;
+ for(pos=0; pos<8; print_bit(NULL, pos++, data));
+ printf("| STATUS: ");
+ print_bit("ERROR", 3, status);
+ print_bit("SEL", 4, status);
+ print_bit("PE", 5, status);
+ print_bit("ACK", 6, status);
+ print_bit("BUSY", 7, status);
+ printf("\n");
+
+ } else {
+ printf("no card.\n");
+ }
+
+ // clear the interrupt
+ unsigned char irqc;
+ ioctl(parport_fd, PPCLRIRQ, &irqc);
+ if(irqc > 1)
+ printf("MISSED %d INTTERUPT%s!!!!!\n", irqc-1, irqc == 2 ? "S" : "");
+ }
+} // function
+
+void magnet_testing_program() {
+ printf("Looping.\n");
+
+ int x = 10;
+ //for(x=0; x<10; x++) {
+ while(x > 0) {
+ printf("m = Magnet, o = Magnet off, q = Quit\n> ");
+ fflush(NULL);
+ switch(getchar()) {
+ case '\n': break;
+ case 'm':
+ printf("Magnet is ON!\n");
+ set_magnet(MAGNET_ON); break;
+ case 'q':
+ printf("Quitting\n");
+ x = -42;
+ break;
+ case 'o':
+ default:
+ printf("Magnet is OFF!\n");
+ set_magnet(MAGNET_OFF);
+ }
+ }
+}
+
+int main(int arvc, char** argv) {
+ printf("opening device %s...\n", PARPORT_DEVICE);
+ parport_fd = open(PARPORT_DEVICE, O_RDWR);
+ if(parport_fd == -1) {
+ perror("opening device failed");
+ return 1;
+ }
+
+ printf("claiming port...\n");
+ if(ioctl(parport_fd, PPCLAIM)) {
+ perror("claiming port (PPCLAIM)");
+ return 1;
+ }
+
+ printf("setting compatibility mode...\n");
+ int mode = IEEE1284_MODE_COMPAT; //BYTE; //COMPAT;
+ if(ioctl(parport_fd, PPNEGOT, &mode)) {
+ perror("Setting compatibilty mode (PPNEGOT)");
+ return 1;
+ }
+
+ printf("Disabling data line drivers...\n");
+ mode = 1;
+ if(ioctl(parport_fd, PPDATADIR, &mode)) {
+ perror("Setting PPDATADIR");
+ return 1;
+ }
+
+ printf("Ready to start.\n");
+ printf("Setting up control mask\n");
+
+ set_magnet(MAGNET_OFF);
+ //magnet_testing_program();
+
+ // now fetch interrupts and give out data at these times.
+ // never use the magnet.
+ simple_reading_program();
+
+
+ printf("Finished. Turning magnet off and quitting.\n");
+ set_magnet(MAGNET_OFF);
+ return 0;
+} // main
+