/* based on dumprom.c -- program a 27c010, 1mbit, 128kbyte eprom */ #include #include #include #include #include #include #include #include #include #include int pport=-1; /* * Controlling the parallel interface */ void check_if_bidirectional() { unsigned int modes; if(ioctl(pport,PPGETMODES,&modes)) { perror("ioctl"); exit(1); } if(!(modes&PARPORT_MODE_TRISTATE)) { fprintf(stderr,"Port is not bidirectional!\n"); exit(1); } } void init_os() { pport=open("/dev/parport0",O_RDWR); if(pport==-1) { perror("open parallel port"); exit(1); } if(ioctl(pport,PPEXCL)) { perror("ioctl"); exit(1); } if(ioctl(pport,PPCLAIM)) { perror("ioctl"); exit(1); } check_if_bidirectional(); } /* set the data lines to be outputs */ void direction_output() { int i=0; if(ioctl(pport,PPDATADIR,&i)) { perror("ioctl"); exit(1); } } /* set the data lines to be inputs */ void direction_input() { int i=1; if(ioctl(pport,PPDATADIR,&i)) { perror("ioctl"); exit(1); } } /* write to the pport data lines */ void data_out(unsigned char c) { if(ioctl(pport,PPWDATA,&c)) { perror("ioctl"); exit(1); } } /* read from the pport data lines */ unsigned char data_in() { char c; if(ioctl(pport,PPRDATA,&c)) { perror("ioctl"); exit(1); } return c; } void frob_control(unsigned char mask, unsigned char val) { static struct ppdev_frob_struct foo; foo.mask=mask; foo.val=val; if(ioctl(pport,PPFCONTROL,&foo)) { perror("ioctl"); exit(1); } } /* set the eprom's output enable line inactive (logic high) */ void disable_oe() { frob_control(PARPORT_CONTROL_SELECT,0); } /* set the eprom's output enable line active (logic low) */ void enable_oe() { frob_control(PARPORT_CONTROL_SELECT,PARPORT_CONTROL_SELECT); } /* set the shift-register strobe low */ void strobe_low() { frob_control(PARPORT_CONTROL_STROBE,PARPORT_CONTROL_STROBE); } /* set the shift-register strobe high; clock in the bits */ void strobe_high() { frob_control(PARPORT_CONTROL_STROBE,0); } void autofeed_high() { frob_control(PARPORT_CONTROL_AUTOFD,0); } void autofeed_low() { frob_control(PARPORT_CONTROL_AUTOFD,PARPORT_CONTROL_AUTOFD); } inline void init_high() { frob_control(PARPORT_CONTROL_INIT,PARPORT_CONTROL_INIT); } inline void init_low() { frob_control(PARPORT_CONTROL_INIT,0); } /* * Delays */ void shiftreg_delay() { struct timespec foo; struct sched_param high, normal; high.sched_priority=99; normal.sched_priority=0; foo.tv_sec=0; foo.tv_nsec=666; sched_setscheduler(0,SCHED_FIFO,&high); nanosleep(foo,NULL); sched_setscheduler(0,SCHED_OTHER,&normal); /* actually we barely need to delay at all from a setup/hold point of view. however, we have to keep the clocking to the register less than 1.5MHz */ } void read_delay() { /*shiftreg_delay();*/ } /* * Controlling the epromseed hardware */ /* if the abit'th bit in addr is set, return a value with the dbit'th bit set */ int dbit(int dbit, int abit, int addr) { dbit=1<=25) { fprintf(stderr,"\nDevice failed while writing address %x. wanted %x got %x\n",addr,data[addr],readback); exit(1); } } } fprintf(stderr,"\n"); } unsigned char read_byte(int addr) { set_address(addr); return get_data(); } void verify_device(unsigned char *data, int bytes) { int addr; unsigned char readback; for(addr=0;addr