Programming the 12/16 Bit AtoD Card Updated: 3/29/99 This document describes how to program my 12/16 bit Analog To Digital Converter Card. Input/Output Port Address: The table below shows the port address for the different registers on the card. Table 1 ----------------------------------------------------------------------------- Port Address Read Write ----------------------------------------------------------------------------- Base + 0 Input Port Output Port Base + 1 N/A N/A Base + 2 N/A N/A Base + 3 N/A N/A Base + 4 A/D High Byte A/D Conversion Start Base + 5 A/D Low Byte N/A Base + 6 N/A N/A Base + 7 N/A N/A Base + 8 Counter 0 Counter 0 Base + 9 Counter 1 Counter 1 Base + 10 Counter 2 (not used) Counter 2 (Not Used) Base + 11 N/A Counter Control Base + 12 Interrupt Acknowledge N/A Base + 13 N/A N/A Base + 14 N/A N/A Base + 15 N/A N/A ----------------------------------------------------------------------------- Notes: Default Base Address is 220 Hex or 544 Decimal. N/A = Address not used. The section that follows describes each of the I/O registers. INPUT PORT - READ AT BASE + 0 This 8 bit input port has the following information. Bit # Description ------------------------------------------------------------------------------ 0 General Purpose Input 0 - Pin 32 on the 37 Pin I/O Connector Note: This port is used by SDR for GPS 1PPS input or external WWWV/WWVB input 1 General Purpose Input 1 - Pin 14 on the 37 Pin I/O Connector 2 General Purpose Input 2 - Pin 33 on the 37 Pin I/O Connector 3 General Purpose Input 3 - Pin 15 on the 37 Pin I/O Connector 4 Jumper JP2 marked "IN=16BIT" 5 WWV Tone Decoder Input 6 Timer Interrupt Latch Status 7 A/D Conversion Ready Input - From Pin 24 of the AtoD chip ------------------------------------------------------------------------------ Input Port Detail Description: Bits 0 to 3: Standard TTL input lines with a 3.3K pull-up resistor going to +5 VDC on each input. Bit 4: Goes to the jumper marked JP2, used by the software to determine if a 12 or 16 bit A/D chip is present. Can also be used for other purposes. If the jumper is in you will read a low on this bit. If the jumper is removed you will see a high on this bit. This bit has a 3.3k pull-up resistor. Bit 5: This bit is connected to the output of a NE567 tone decoder chip used with the WWV time option. This bit will go low when the tone decoder sees a 1000Hz tone. It is up to the software to look for a 800 millisecond pulse that WWV sends at the top of the minute. Bit 6: This bit can be used to poll the interrupt timer latch status. Normally this bit is high. When the counter/timer sets the interrupt latch this bit will go low until you send a interrupt acknowledge by reading data to Base + 12. See the block diagram below for more information on this input. Bit 7: This bit is used to see when the A/D chip has finished performing a conversion. When you start a A/D conversion by write data (any data will work) to Base + 4 this bit will go low. After the conversion is done (25 us max) this bit will go high again. OUTPUT PORT - WRITE TO BASE + 0 This 8 bit output port has the following information. Bit # Description ------------------------------------------------------------------------------ 0 8 channel Analog Multiplexer Control Address 0 1 8 channel Analog Multiplexer Control Address 1 2 8 channel Analog Multiplexer Control Address 2 3 General Purpose Output on Pin 18 of the 37 Pin I/O connector 4 General Purpose Output 0 on Pin 34 of the 37 Pin I/O connector 5 General Purpose Output 1 on Pin 16 of the 37 Pin I/O connector 6 General Purpose Output 2 on Pin 35 of the 37 Pin I/O connector 7 General Purpose Output 3 on Pin 17 of the 37 Pin I/O connector ------------------------------------------------------------------------------ Output Port Detail Description: Bits 0, 1, 2: Used to control the analog input multiplexer. A bit pattern of 000 will select channel 0, 001 will select channel 1, ... 111 will select channel 7. Bit 3: General purpose TTL output. SDR uses this bit as a 1 second timing reference. Bits 4,5,6,7: General purpose TTL outputs. Note: You can not read the contents of the output port register. You should keep a memory accumulator and modify any bits in memory then output it to the port. A/D CONVERTER START - WRITE TO BASE + 4 To start a A/D conversion write any data to Base + 4. A/D DATA - READ AT BASE + 4 (HIGH DATA BYTE) + 5 (LOW DATA BYTE) When the A/D conversion is complete you can read the data from the chip at Base address + 4 and + 5. The data at Base + 4 contains the high order data bits (bits 8 to 15) and Base + 5 contains the low order data bits (bits 0 to 7). With a 16 bit A/D chip all bits are used. With a 12 bit A/D chip the low order bits 0 to 3 are not used. You should rotate or divide the data 4 bits to produce a 12 bit word. See the ASM sample code below. ... mov dx, 548 ; decimal base address (default of 544 Dec) + 4 in al, dx ; get the high order byte mov ah, al ; save it in register AH inc dx ; point to low data or 549 dec. in al, dx ; get the low order byte mov cl, 0xff ; check to see if 12 or 16 bit A/D chip test cl, atod16 ; test flag, atod16 flag set at startup by ; reading bit 4 of the input port jnz Is16Bit ; if 16 bit chip jump to Is16Bit mov cx, 4 ; 12 bit chip, set up to rotate right data by 4 bits shr ax, cl ; rotate (shift to keep sign) right the data by 4 bits sub ax, 2048 ; makes the data in AX have the following based on the ; input; +5V input = +2047, 0 input = 0 and ; -5V input = -2048 jmp Done ; skip 16 bit chip code Is16Bit: sub ax, 32768 ; 16 bit chip, all we need to do is normalize the data so ; that a +5V input = +32767, 0 input = 0, and ; -5V input = -32768 Done: .... ; register AX now has the normalized 12 or 16 bit word. COUNTER/TIMER CHANNEL 0 - READ / WRITE TO BASE + 8 Used to write the prescale 16 bit counter channel 0 value into the Intel 8253/8254 programable counter/timer chip. The input to counter 0 is a 4.0 Mhz reference. The output of this counter goes to the input of counter/timer channel 1. Normally this counter is set to run in the square-wave output mode. To program a value into this channel you first write a control byte to Base + 11 and then write the low and then the high order counter value to this address. COUNTER/TIMER CHANNEL 1 - READ / WRITE TO BASE + 9 Used to write the 16 bit counter channel 1 value into the Intel 8253/8254 programable counter/timer chip. The input of counter 1 is counter/timer channel 0. The output of this counter goes to the interrupt controller latch (see the block diagram). Normally this counter is set to run in the square-wave output mode. To program a value into this channel you first write a control byte to Base + 11 and then write the low and then the high order counter value to this address. COUNTER/TIMER CHANNEL 2 - READ / WRITE TO BASE + 10 This counter/time channel is not used. COUNTER/TIMER CONTROL - WRITE TO BASE + 11 This port address is used to control the 8253/8254 timer/counter chip. For a complete discription of the chip please read the data sheet for this part. This chip has three (only two are used) 16 bit counters. To use this chip as a interrupt source (you can also use it by polling bit 6 of the input port) you would write commands and counter values to the chip. Each counter/timer channel is programmed by first writing a control byte to Base + 11 and then writing the low 8 bits of the counter value and then the high order 8 bits to the Base + 8 or + 9. Note: You can only write to this address. The following "C" code sets the two timers to interrupt the system every millisecond or 1000Hz. // note commands and data are in hexidecmal InitCounter() { // set counter 0 to divide the 4.0 Mhz input by 20 decimal out(Base+11, 0x36); // control for counter 0, sets counter to square-wave out(Base+8, 0x14); // load counter 0 with 20 decimal, low order data out(Base+8, 0); // load high order data // counter channel 0 now set to divide the 4.0 Mhz input by 20. This produces // a 200,000 Hz input to counter channel 1. Now set counter 1 to divide the // data by 200 producing a 1,000 Hz output to the interrupt latch. out(Base+11, 0x76); // control for channel 1, sets counter to square-wave out(Base+9, 0xc8); // load counter 1 with 200 decimal, low order data out(Base+9, 0); // load high order data } For other interrupt rates you can use the following formula: Interrupt Rate = 4 Mhz / (counter0 * counter1) INTERRUPT ACKNOWLEDGE - READ TO BASE + 12 This address is used to reset the Interrupt Timer Latch. To reset the latch you read data from to this address. The latch is set by the output of the second channel of 8253/8254 counter/timer chip. The output of this latch is used to generate a interrupt to the system. The output of this latch also goes to pin 6 of the input port at Base + 0. This input bit can be used to poll the timer instead of using an interrupt.