/*Dongle.c Illustrative driver for the parallel port based security Dongle. Dongle hardware uses Atmel's AVR RISC processor AT90S2343 in internal oscillator mode. 3 processor pin I/O handshake interface */ /* Parallel Port AT90S2343 ------------- --------- D0 (data out) -----> PB0 (data in/out) D1 (Strobe out) -----> PB1 (strobe in) D2 (proc reset) -----> reset S7 (data in) <----- PB0 S6 (Ack in) <----- PB2 (Ack out) */ /*The inactive state of the strobe and the ack signal is '0' The PC is the master and the processor is slave. PC starts data transfer by asseting strobe '1' (after ensuring that ack is '0'). The data transfer could be from the PC to processor or vice-versa and depends upon context. After reset the PC sends 2 bytes to processor and then expects 1 byte from the processor as result*/ /*For PC ---> processor data transfer: PC checks that the ack signal is '0' and then places data on the D0 line (most significant bit first) and asserts strobe '1'. Processor, monitoring the strobe line, reads the data bit and takes the ack line high. In response, the PC having noted the ack signal transitioning to '1', de-asserts strobe by taking it to '0'. The processor first ensures that the strobe line has been de-asserted to '0' and then processes the acquired data bit and when ready for more, de-asserts the ack line to '0'. */ /*For processor ----> PC data transfer: When the PC wants to read data (and processor wants to send data), the PC checks that he ack line is '0' and then asserts strobe to '1'. The processor places the data (m.s. bit first) and then raises ack signal to '1'. and waits for the strobe to go low. when strobe goes to '0', it also takes the ack bit to '0' and waits for the strobe to go high again*/ /*Copyright: Dhananjay V. Gadre 29th July 1999 */ #include #include /*For resetting the Processor*/ /*Reset is active low and is on par port pin D2*/ #define RST 0xFB #define NORST 0x04 /*For generating strobe*/ /*Strobe is on pin D1 of the par port*/ #define STB 0x02 #define NOSTB 0xFD /*holds addresses of the data(status) and status(input) ports of the parallel port*/ int dport, sport; /*data that needs to be shifted out of the pin D0 of the par port*/ unsigned char DATA; main() { /*start of main*/ int select, offset; unsigned char rx_data; /*Aquire the data port address of LPT1*/ dport=peek(0x40, 8); /*If the address is zero, means that particular parallel adapter*/ /*is not present. No point in continuing. Abort the code here*/ if (dport ==0) { printf("Sorry, On this machine LPT does not exist\n"); exit(0); } /*status port address*/ sport=dport+1; printf("\n\n\n\nResetting the Processor\n\n"); reset_proc(); /*till a key is pressed, do the loop*/ while(!kbhit()) { /*put your own data here*/ DATA=100; printf("\n\nPreset = %x", DATA); send_data(); /*put your own data here*/ DATA=5; send_data(); printf("\nLoop Value = %x", DATA); /*Now wait for the result to come*/ printf("\nReceiving Data..."); get_data(); /*end of while loop*/ } /*end of main*/ } /*generates a low pulse on signal D2, (pin 4) of the parallel port*/ /*then takes it high after 100 ms*/ reset_proc() { unsigned char data; data=inportb(dport); /*assert reset (take it low)*/ data = data & RST; /*strobe is also de-asserted*/ data = data & NOSTB; outportb(dport, data); delay(100); /*de-asseert reset (take it high)*/ data = data | NORST; outportb(dport, data); delay(200); return; } send_data() { unsigned char temp, data_out, count, temp1; temp=255; data_out=DATA; for(count=0; count<8; count++) { /*wait for ACK to go low*/ temp=255; while(tem != 0) { temp=inportb(sport); temp = temp & 0x40; } /*device now ready to accept data*/ /*output data*/ temp = data_out >> (8 - count -1); temp1= inportb(dport) & 0xfe; temp = temp & 0x01; temp= temp | temp1; outportb(dport, temp); /*assert Strobe*/ temp=inportb(dport); temp = temp | STB; outportb(dport, temp); temp=0; /*wait for ACK to go high*/ while(temp != 0x40) { temp=inportb(sport); temp = temp & 0x40; } /*data has been accepted. so de-assert Strobe*/ temp=inportb(dport); temp = temp & NOSTB; outportb(dport, temp); /*end of for loop*/ } /*return*/ } /*receive a byte from the processor*/ get_data() { unsigned char temp, data_in, count; data_in=0; /* make D0 '1' so that the status pin S7 can read data from the processor*/ temp=inportb(dport); temp = temp | 1; outportb(dport, temp); temp = 255; data_in=0; for(count=0; count<8; count++) { /*wait for ACK to go low*/ while(temp != 0) { temp=inportb(sport); temp = temp & 0x40; } /*device now ready to send data*/ /*assert Strobe*/ temp=inportb(dport); temp = temp | STB; outportb(dport, temp); temp=0; /*wait for ACK to go high*/ while(temp != 0x40) { temp=inportb(sport); temp = temp & 0x40; } /*now read data*/ temp=( inportb(sport) ^ 0x80) & 0x80; temp = temp >> 7; data_in = (data_in << 1) | temp; /*now de-assert Strobe*/ temp=inportb(dport) & NOSTB; outportb(dport, temp); /*end of for loop*/ } printf("Result=%x", data_in); /*return*/ }