/* Description: Driving a MAX186 chip from the printer port from Linux Date: Thu Jul 17 19:33:46 NZST 2008 Author: Clark Mills Chip description: Maxim MAX186 12 bit Analogue to Digital Converter */ #include #include #include #define BASEPORT 0x378 /* lp1 */ // Writes to the "data" port are through this global byte to not clobber bits int data; void resetPort(); int r_DOUT( void ); int r_SSTRB( void ); void w_DIN_hi( void ); void w_DIN_lo( void ); void w_SCLK_hi( void ); void w_SCLK_lo( void ); void writeCtlPort( int data ); unsigned int readValue(); main() { // Check that we have permissions to access the port... if (ioperm(BASEPORT, 3, 1)) { // Nope, die. perror("ioperm"); exit(1); } // Set ports to known state resetPort(); // ADC conversion: Start, CH0, Unipolar, Single ended, Internal clock writeCtlPort( 0x8E ); // Wait for conversion while (r_SSTRB() == 0) ; // Print the result printf( "Result=%u\n", readValue() ); } // Read the resultant 12 bit value unsigned int readValue() { unsigned int result = 0; int j; // Clock out 16 bits for (j=0; j<16; j++) { w_SCLK_hi(); w_SCLK_lo(); result = result << 1; result |= r_DOUT(); } // Discard 4 bits as only 12 bits valid result = result >> 4; return result; } // Write a byte to the control port void writeCtlPort( int data ) { int j; // For 8 bits... for (j=0; j<8; j++) { // Set data line... if (data & 128) w_DIN_hi(); else w_DIN_lo(); // Clock the data out w_SCLK_hi(); w_SCLK_lo(); // Shift up next bit data = data << 1; } // Clear the data bit (for neatness) w_DIN_lo(); } // Read DOUT line int r_DOUT( void ) { return ((inb(BASEPORT+1) >> 4) & 1); } // Set the DIN bit high (write through "data" byte to preserve other bits) void w_DIN_hi( void ) { data |= 0x01; outb(data, BASEPORT+0); } // Set the DIN bit low (write through "data" byte to preserve other bits) void w_DIN_lo( void ) { data &= 0xFE; outb(data, BASEPORT+0); } // Set SCLK high (write through "data" byte to preserve other bits) void w_SCLK_hi( void ) { data |= 0x02; outb(data, BASEPORT+0); } // Set SCLK low (write through "data" byte to preserve other bits) void w_SCLK_lo( void ) { data &= 0xFD; outb(data, BASEPORT+0); } // Read SSTRB line int r_SSTRB( void ) { return (~(inb(BASEPORT+1) >> 7) & 1); } // Set ports and data port mirror byte to known state void resetPort() { data = 0; // (write through "data" byte to preserve other bits) outb(data, BASEPORT+0); outb(0, BASEPORT+1); outb(0, BASEPORT+2); } /* EOF*/