unit aio1616F; interface uses acces32; function sbitd (data:longword; bit:word):word; function DAC(DACnum:word; DACV:double):double; procedure EEPROM_Enable(); procedure EEPROM_Disable(); procedure EEPROM_Write(addr:word; data:word); function EEPROM_Read(addr:word):word; procedure CAL_ADC(M:word;B:word); procedure CAL_DAC(DACNum:word;M:word); procedure CALWrite(zAM:word;zAB:word;zDAM:word;zDBM:word); procedure doCAL(); procedure init(); var {unsigned int BASE=0x300; unsigned short jumpers; unsigned char adrange; unsigned char dacBrange; unsigned char dacArange;} BASE:word; jumpers : word; adrange : word; dacBrange : word; dacArange : word; implementation //sbitd takes data and bit, then returns 0x81 or 0x01 based on data[bit] function sbitd (data:longword; bit:word):word; begin //return (data & (1< 0 then count := round(DACV/5.0 * 4096) else count := round(DACV/10.0 * 4096) end else begin if dacBrange <> 0 then count := round(DACV/5.0 * 4096) else count := round(DACV/10.0 * 4096) end; //count &= 0xFFF; //12-bit DAC count := count and $FFF; //To the hardware, the DACs are 1-based OutPortB(BASE+9, $81);//DAC load mode = software OutPortB(BASE+9,sbitd(DACnum + 1,1) + 2);//DACnum bit 1 OutPortB(BASE+9,sbitd(DACnum + 1,0) + 2);//DACnum bit 0 OutPortB(BASE+9,$01);//unused bit OutPortB(BASE+9,sbitd(count,11));//data bit 11 OutPortB(BASE+9,sbitd(count,10));//data bit 10 OutPortB(BASE+9,sbitd(count,9));//data bit 9 OutPortB(BASE+9,sbitd(count,8));//data bit 8 OutPortB(BASE+9,sbitd(count,7));//data bit 7 OutPortB(BASE+9,sbitd(count,6));//data bit 6 OutPortB(BASE+9,sbitd(count,5));//data bit 5 OutPortB(BASE+9,sbitd(count,4));//data bit 4 OutPortB(BASE+9,sbitd(count,3));//data bit 3 OutPortB(BASE+9,sbitd(count,2));//data bit 2 OutPortB(BASE+9,sbitd(count,1));//data bit 1 OutPortB(BASE+9,sbitd(count,0));//data bit 0 OutPortB(BASE+9, 0);//end trans OutPortB(BASE+9, 2);//Load DACs //return double(count)/4096.0L*((DACnum?dacArange:dacBrange)?5.0L:10.0L);//actual V} if DACnum = 0 then begin if dacArange <> 0 then DAC := (count/4096.0) * 5.0 else DAC := (count/4096.0) * 10.0 end else begin if dacBrange <> 0 then DAC := (count/4096.0) * 5.0 else DAC := (count/4096.0) * 10.0 end; end; // Enable the EEEPROM for writing procedure EEPROM_Enable(); begin OutPortB(BASE+$0a,$81);//start bit OutPortB(BASE+$0a,$01);//Opcode bit 0 (00 = enable/disable) OutPortB(BASE+$0a,$01);//Opcode bit 1 "" OutPortB(BASE+$0a,$81);//a5 (must be 1 to enable) OutPortB(BASE+$0a,$81);//a4 (must be 1 to enable) OutPortB(BASE+$0a,$01);//a3 (don't care because enable/disable) OutPortB(BASE+$0a,$01);//a2 (don't care because enable/disable) OutPortB(BASE+$0a,$01);//a1 (don't care because enable/disable) OutPortB(BASE+$0a,$01);//a0 (don't care because enable/disable) OutPortB(BASE+$0a,$00);//end trans end; // Disable the EEPROM write procedure EEPROM_Disable(); begin OutPortB(BASE+$0a,$81);//start bit OutPortB(BASE+$0a,$01);//Opcode bit 0 (00 = enable/disable) OutPortB(BASE+$0a,$01);//Opcode bit 1 "" OutPortB(BASE+$0a,$01);//a5 (must be 0 to disable) OutPortB(BASE+$0a,$01);//a4 (must be 0 to disable) OutPortB(BASE+$0a,$01);//a3 (don't care because enable/disable) OutPortB(BASE+$0a,$01);//a2 (don't care because enable/disable) OutPortB(BASE+$0a,$01);//a1 (don't care because enable/disable) OutPortB(BASE+$0a,$01);//a0 (don't care because enable/disable) OutPortB(BASE+$0a,$00);//end trans end; // write the value in data to the EEPROM to the location specified by addr procedure EEPROM_Write(addr:word; data:word); begin OutPortB(BASE+$0a,$81);//Start Bit OutPortB(BASE+$0a,$01);//Opcode Bit 0 (01=write) OutPortB(BASE+$0a,$81);//Opcode Bit 1 "" OutPortB(BASE+$0a,sbitd(addr,5));//a5 (address to write to) OutPortB(BASE+$0a,sbitd(addr,4));//a4 OutPortB(BASE+$0a,sbitd(addr,3));//a3 OutPortB(BASE+$0a,sbitd(addr,2));//a2 OutPortB(BASE+$0a,sbitd(addr,1));//a1 OutPortB(BASE+$0a,sbitd(addr,0));//a0 OutPortB(BASE+$0a,sbitd(data,15));//d15 OutPortB(BASE+$0a,sbitd(data,14));//d14 OutPortB(BASE+$0a,sbitd(data,13));//d13 OutPortB(BASE+$0a,sbitd(data,12));//d12 OutPortB(BASE+$0a,sbitd(data,11));//d11 OutPortB(BASE+$0a,sbitd(data,10));//d10 OutPortB(BASE+$0a,sbitd(data,9));//d9 OutPortB(BASE+$0a,sbitd(data,8));//d8 OutPortB(BASE+$0a,sbitd(data,7));//d7 OutPortB(BASE+$0a,sbitd(data,6));//d6 OutPortB(BASE+$0a,sbitd(data,5));//d5 OutPortB(BASE+$0a,sbitd(data,4));//d4 OutPortB(BASE+$0a,sbitd(data,3));//d3 OutPortB(BASE+$0a,sbitd(data,2));//d2 OutPortB(BASE+$0a,sbitd(data,1));//d1 OutPortB(BASE+$0a,sbitd(data,0));//d0 OutPortB(BASE+$0a,$00);//end trans end; // read the value from the EEPROM at the location specified by addr and return it function EEPROM_Read(addr:word):word; var data:word; begin data:=0; OutPortB(BASE+$0a,$81);//Start Bit OutPortB(BASE+$0a,$81);//Opcode Bit 0 (10=Read) OutPortB(BASE+$0a,$01);//Opcode Bit 1 "" OutPortB(BASE+$0a,sbitd(addr,5));//a5 (address to write to) OutPortB(BASE+$0a,sbitd(addr,4));//a4 OutPortB(BASE+$0a,sbitd(addr,3));//a3 OutPortB(BASE+$0a,sbitd(addr,2));//a2 OutPortB(BASE+$0a,sbitd(addr,1));//a1 OutPortB(BASE+$0a,sbitd(addr,0));//a0 // delay(10); // InPortB(BASE+0x0a);//dummy bit data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d15 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d14 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d13 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d12 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d11 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d10 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d9 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d8 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d7 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d6 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d5 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d4 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d3 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d2 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d1 data :=(data shl 1) or ((InPortB(BASE+$0a) shr 7));//d0 OutPortB(BASE+$0a,$00);//end com EEPROM_Read := data; end; // write the gain (M) and the offset (B) to the pots. y=Mx + B procedure CAL_ADC(M:word;B:word); begin //write cal to A/D, offset first, then slope OutPortB(BASE+$0b,$01);//a1 pot 00 is offset OutPortB(BASE+$0b,$01);//a0 "" OutPortB(BASE+$0b,sbitd(B,7));//data bit 7 of offset OutPortB(BASE+$0b,sbitd(B,6));//data bit 6 of offset OutPortB(BASE+$0b,sbitd(B,5));//data bit 5 of offset OutPortB(BASE+$0b,sbitd(B,4));//data bit 4 of offset OutPortB(BASE+$0b,sbitd(B,3));//data bit 3 of offset OutPortB(BASE+$0b,sbitd(B,2));//data bit 2 of offset OutPortB(BASE+$0b,sbitd(B,1));//data bit 1 of offset OutPortB(BASE+$0b,sbitd(B,0));//data bit 0 of offset OutPortB(BASE+$0b,$00);//end trans //write slope now OutPortB(BASE+$0b,$01);//a1 pot 01 is slope of A/D OutPortB(BASE+$0b,$81);//a0 pot 01 is slope of A/D OutPortB(BASE+$0b,sbitd(M,7));//data bit 7 of slope OutPortB(BASE+$0b,sbitd(M,6));//data bit 6 of slope OutPortB(BASE+$0b,sbitd(M,5));//data bit 5 of slope OutPortB(BASE+$0b,sbitd(M,4));//data bit 4 of slope OutPortB(BASE+$0b,sbitd(M,3));//data bit 3 of slope OutPortB(BASE+$0b,sbitd(M,2));//data bit 2 of slope OutPortB(BASE+$0b,sbitd(M,1));//data bit 1 of slope OutPortB(BASE+$0b,sbitd(M,0));//data bit 0 of slope OutPortB(BASE+$0b,$00);//end trans end; // write the gain(M) for the specified DAC to the pots procedure CAL_DAC(DACNum:word;M:word); begin OutPortB(BASE+$0b,$81);//a1 pot 10 is slope of DAC0 OutPortB(BASE+$0b,sbitd(DACNum,0));//a0 pot 11 is slope of DAC1 OutPortB(BASE+$0b,sbitd(M,7));//data bit 7 of slope OutPortB(BASE+$0b,sbitd(M,6));//data bit 6 of slope OutPortB(BASE+$0b,sbitd(M,5));//data bit 5 of slope OutPortB(BASE+$0b,sbitd(M,4));//data bit 4 of slope OutPortB(BASE+$0b,sbitd(M,3));//data bit 3 of slope OutPortB(BASE+$0b,sbitd(M,2));//data bit 2 of slope OutPortB(BASE+$0b,sbitd(M,1));//data bit 1 of slope OutPortB(BASE+$0b,sbitd(M,0));//data bit 0 of slope OutPortB(BASE+$0b,$00);//end trans end; // writes the current calibration values to the EEPROM. procedure CALWrite(zAM:word;zAB:word;zDAM:word;zDBM:word); begin EEPROM_Enable(); EEPROM_Write((adrange+0),zAB); EEPROM_Write((adrange+8),zAM); EEPROM_Write((dacArange+$10),zDAM); EEPROM_Write((dacBrange+$12),zDBM); EEPROM_Disable(); end; // reads the calibration values from the EEPROM and write them to the pots // this should be done before taking any readings from the board. procedure doCAL(); var zDAM : word; zDBM : word; zAM : word; zAB : word; begin zAB := EEPROM_Read((adrange+0))and $ff; //byte 0-7 in EEPROM holds "B" for ADC zAM := EEPROM_Read((adrange+8))and $ff; //byte 8-f in EEPROM holds "M" for ADC zDAM := EEPROM_Read((dacArange+$10))and $ff; //byte x10,x11 in EEPROM holds "M" for DAC0 zDBM := EEPROM_Read((dacBrange+$12))and $ff; //byte x12,x13 in EEPROM holds "M" for DAC1 CAL_DAC(0,zDAM);//write the calibration value from EEPROM to CAL Pots CAL_DAC(1,zDBM);// "" CAL_ADC(zAM,zAB);// "" end; //reads the jumper config from the board and initializes the global variables procedure init(); begin jumpers := InPortB(BASE+$08);//jumper configuration readback adrange := jumpers and $07;//d2,d1,d0 are 5/10, uni/bip, 16/8 dacBrange := (jumpers shr 3) and $01;//d4,d3 are 5/10 for daca,b dacArange := (jumpers shr 4) and $01; // CAL(); end; end.