Created
June 16, 2010 09:55
-
-
Save johnhowe/440408 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/***************************************************************************** | |
* File: k-2805.c | |
* Author: Clark Mills (clark@kiwi.gen.nz) | |
* Date: Sun Aug 7 09:56:59 NZST 2005 | |
* Description: Routines to allow playing with the Dick Smith Electronics | |
* Discovery series K-2805 Parallel Port Interface | |
* License: GPL | |
* Keywords: Linux 2805 PCB printed circuit board kitset | |
*****************************************************************************/ | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <sys/io.h> | |
#include <stdlib.h> | |
/* defs */ | |
#define BASEPORT 0x378 /* lp1 */ | |
/* prototypes */ | |
void push_byte(int byte); | |
void dac1_load( int byte ); | |
void dac1_load( int byte ); | |
void bits_load( int byte ); | |
int adc_eoc(); | |
int adc_data(); | |
/* globals */ | |
int port[3]; // Mirror of port values | |
/* functions */ | |
int main() | |
{ | |
int data; | |
int j; | |
port_init(); // Reset registers | |
card_power_on(); // Power up the card | |
// Output ~2.48v which is tied to adc input 0 for testing | |
dac1_load( 127 ); // Half of supply voltage | |
dac1_output_enable(); // DAC is always enabled | |
adc_cs_enable(); // Chip is always selected | |
adc_addr_low(); // Address is always 0000 | |
usleep( 1000 ); | |
while (1) | |
{ | |
data = 0; // Collect our byte here | |
for (j=0; j<8; j++) | |
{ | |
clock_bit_high(); | |
usleep( 1000 ); | |
data <<= 1; // Shift our byte | |
data |= adc_data(); // Get a bit | |
usleep( 1000 ); | |
clock_bit_low(); | |
usleep( 1000 ); | |
} | |
printf( "%3d\r", data ); // Display our byte | |
fflush( stdout ); | |
while (!adc_eoc()) // Wait for end-of-conversion flag | |
usleep( 1000 ); | |
} | |
card_shutdown(); // We never get here | |
exit(0); | |
} | |
/***************************************************************************** | |
* Low level routines. * | |
*****************************************************************************/ | |
port_init() | |
{ | |
if (ioperm(BASEPORT, 3, 1)) { perror("ioperm"); exit(1); } | |
// Reset port and variables to a sane known state | |
port[0] = port[1] = port[2] = 0; | |
outb(port[0], BASEPORT+0); | |
outb(port[1], BASEPORT+1); | |
outb(port[2], BASEPORT+2); | |
} | |
card_power_on() | |
{ | |
port[0] |= 0x80; | |
outb(port[0], BASEPORT+0); | |
} | |
card_power_off() | |
{ | |
port[0] &= 0x7F; | |
outb(port[0], BASEPORT+0); | |
} | |
card_shutdown() | |
{ | |
card_power_off(); | |
if (ioperm(BASEPORT, 3, 0)) { perror("ioperm"); exit(1); } | |
} | |
/* Data bit routines */ | |
data_bit_high() | |
{ | |
port[0] |= 0x01; | |
outb(port[0], BASEPORT+0); | |
} | |
data_bit_low() | |
{ | |
port[0] &= 0xFE; | |
outb(port[0], BASEPORT+0); | |
} | |
/* Clock routines */ | |
clock_bit_high() | |
{ | |
port[0] |= 0x02; | |
outb(port[0], BASEPORT+0); | |
} | |
clock_bit_low() | |
{ | |
port[0] &= 0xFD; | |
outb(port[0], BASEPORT+0); | |
} | |
/* Shift in 1 byte */ | |
void push_byte(int byte) | |
{ | |
int j; | |
for (j=0; j<8; j++) | |
{ | |
if (byte & 0x80) // MSB first | |
data_bit_high(); | |
else | |
data_bit_low(); | |
clock_bit_high(); | |
clock_bit_low(); | |
byte <<= 1; | |
} | |
} | |
/***************************************************************************** | |
* Routines that handle the digital to analogue converter 1 * | |
* Output can be read at: SK1 * | |
* Loads IC1, 74HC595 * | |
*****************************************************************************/ | |
dac1_output_enable() // Inverse of expected bit state | |
{ | |
port[2] |= 0x01; | |
outb(port[2], BASEPORT+2); | |
} | |
dac1_output_disable() // Inverse of expected bit state | |
{ | |
port[2] &= 0xFE; | |
outb(port[2], BASEPORT+2); | |
} | |
dac1_store_high() | |
{ | |
port[0] |= 0x04; | |
outb(port[0], BASEPORT+0); | |
} | |
dac1_store_low() | |
{ | |
port[0] &= 0xFB; | |
outb(port[0], BASEPORT+0); | |
} | |
dac1_store() | |
{ | |
dac1_store_high(); | |
dac1_store_low(); | |
} | |
void dac1_load( int byte ) | |
{ | |
push_byte(byte); | |
dac1_store(); | |
} | |
/***************************************************************************** | |
* Routines that handle the digital to analogue converter 2 * | |
* Output can be read at: SK2 * | |
* Loads IC2, 74HC595 * | |
*****************************************************************************/ | |
dac2_output_enable() // Inverse of expected bit state | |
{ | |
port[2] |= 0x02; | |
outb(port[2], BASEPORT+2); | |
} | |
dac2_output_disable() // Inverse of expected bit state | |
{ | |
port[2] &= 0xFD; | |
outb(port[2], BASEPORT+2); | |
} | |
dac2_store_high() | |
{ | |
port[0] |= 0x08; | |
outb(port[0], BASEPORT+0); | |
} | |
dac2_store_low() | |
{ | |
port[0] &= 0xF7; | |
outb(port[0], BASEPORT+0); | |
} | |
dac2_store() | |
{ | |
dac2_store_high(); | |
dac2_store_low(); | |
} | |
void dac2_load( int byte ) | |
{ | |
push_byte(byte); | |
push_byte(0); | |
dac2_store(); | |
} | |
/***************************************************************************** | |
* Routines that handle the open collector outputs * | |
* Output can be read at: SK4 * | |
* Loads IC3, 74HC595 * | |
*****************************************************************************/ | |
bits_output_enable() // Inverse of expected bit state | |
{ | |
port[2] |= 0x08; | |
outb(port[2], BASEPORT+2); | |
} | |
bits_output_disable() // Inverse of expected bit state | |
{ | |
port[2] &= 0xF7; | |
outb(port[2], BASEPORT+2); | |
} | |
bits_store_high() | |
{ | |
port[0] |= 0x10; | |
outb(port[0], BASEPORT+0); | |
} | |
bits_store_low() | |
{ | |
port[0] &= 0xEF; | |
outb(port[0], BASEPORT+0); | |
} | |
bits_store() | |
{ | |
bits_store_high(); | |
bits_store_low(); | |
} | |
void bits_load( int byte ) | |
{ | |
push_byte(byte); | |
push_byte(0); | |
push_byte(0); | |
bits_store(); | |
} | |
/***************************************************************************** | |
* Routines that handle the analogue to digital converter and mux * | |
* Physical input is read from: SK5 * | |
* Loads IC4, TLC542 * | |
*****************************************************************************/ | |
adc_cs_enable() | |
{ | |
port[0] &= 0xDF; | |
outb(port[0], BASEPORT+0); | |
} | |
adc_cs_disable() | |
{ | |
port[0] |= 0x20; | |
outb(port[0], BASEPORT+0); | |
} | |
adc_addr_high() | |
{ | |
port[0] |= 0x40; | |
outb(port[0], BASEPORT+0); | |
} | |
adc_addr_low() | |
{ | |
port[0] &= 0xBF; | |
outb(port[0], BASEPORT+0); | |
} | |
int adc_eoc() | |
{ | |
int data; | |
data = inb( BASEPORT+1 ); | |
data &= 0x40; | |
data >>= 6; | |
return ( data ); | |
} | |
int adc_data() | |
{ | |
int data; | |
data = inb( BASEPORT+1 ); | |
data &= 0x10; | |
data >>= 4; | |
return ( data ); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment