smbsensors.~inc
来自「pipe类 pipe类 pipe类 pipe类 pipe类」· ~INC 代码 · 共 371 行
~INC
371 行
const
LM75_ID = $300;
ASB100_ID = $301;
ATXP1_ID = $302;
LM90_ID = $303;
LM99_ID = $304;
LM86_ID = $305;
ADM1032_ID = $306;
ADT7461_ID = $307;
MAX6657_ID = $308;
function Swap16(Val: Word): Word;
var
tmp1, tmp2: Byte;
begin
tmp1:=Val and $ff;
tmp2:=(Val shr 8) and $ff;
result:=tmp2 or (tmp1 shl 8);
end;
//==============================================================================
// Chip probe methods
//==============================================================================
function LM75Probe(HostNum: Word; addr: Byte): Boolean;
var
conf, tmpb: Byte;
cur, hyst, os: Word;
tmpw1, tmpw2: Word;
i: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_word_data(addr, 0, cur);
SMB.i2c_smbus_read_byte_data(addr, 1, conf);
SMB.i2c_smbus_read_word_data(addr, 2, hyst);
tmpw1:=0;
for i:=4 to 7 do
begin
SMB.i2c_smbus_read_word_data(addr, i, tmpw1);
if tmpw1<>hyst then exit;
end;
SMB.i2c_smbus_read_word_data(addr, 3, os);
tmpw1:=0;
for i:=4 to 7 do
begin
SMB.i2c_smbus_read_word_data(addr, i, tmpw1);
if tmpw1<>os then exit;
end;
//Unused bits
if (conf and $e0) <> 0 then exit;
//Addresses cycling
i:=8;
while (i < $ff) do
begin
SMB.i2c_smbus_read_byte_data(addr, i + 1, tmpb);
SMB.i2c_smbus_read_word_data(addr, i + 2, tmpw1);
SMB.i2c_smbus_read_word_data(addr, i + 3, tmpw2);
if (tmpb <> conf) or (tmpw1 <> hyst) or (tmpw2 <> os) then exit;
i:=i+8;
end;
result:=true;
end;
function ASB100Probe(HostNum: Word; addr: Byte): Boolean;
var
tmp: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
tmp:=0;
//if register $58 holds $31 then we have an asus (either ASB100 or AS99127F)
SMB.i2c_smbus_read_byte_data(addr, $58, tmp);
if tmp = $31 then
begin
//if (IOByte($4F,$0,IORead)=$94) or (IOByte($4F,$0,IORead)=$06) then ASB100
tmp:=0;
SMB.i2c_smbus_read_byte_data(addr, $4F, tmp);
if tmp in [$06, $94] then result:=true;
end;
end;
function ATXP1Probe(HostNum: Word; addr: Byte): Boolean;
var
tmp1, tmp2, tmp3, tmp4, i: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
//Reading some useless bits from Attansic
for i:=$30 to $3d do
SMB.i2c_smbus_read_byte_data(addr, i, tmp1);
//Detect ATXP1, checking if vendor ID registers are all zero
if (SMB.i2c_smbus_read_byte_data(addr, $3e, tmp1) <> 0) or
(SMB.i2c_smbus_read_byte_data(addr, $3f, tmp2) <> 0) or
(SMB.i2c_smbus_read_byte_data(addr, $fe, tmp3) <> 0) or
(SMB.i2c_smbus_read_byte_data(addr, $ff, tmp4) <> 0) then exit;
if (tmp1 <> 0) or (tmp2 <> 0) or (tmp3 <> 0) or (tmp4 <> 0) then exit;
//No vendor ID, now checking if registers 0x10,0x11 (non-existent)
//showing the same as register 0x00
tmp1:=0; tmp2:=0; tmp3:=0;
SMB.i2c_smbus_read_byte_data(addr, $3e, tmp1);
SMB.i2c_smbus_read_byte_data(addr, $10, tmp2);
SMB.i2c_smbus_read_byte_data(addr, $11, tmp3);
if not((tmp1 = tmp2) and (tmp1 = tmp3)) then exit;
result:=true;
end;
function LM90Probe(HostNum: Word; addr: Byte): Boolean;
var
man_id, chip_id, reg_config1, reg_config2, reg_convrate: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_byte_data(addr, $FE, man_id);
SMB.i2c_smbus_read_byte_data(addr, $FF, chip_id);
SMB.i2c_smbus_read_byte_data(addr, $03, reg_config1);
SMB.i2c_smbus_read_byte_data(addr, $BF, reg_config2);
SMB.i2c_smbus_read_byte_data(addr, $04, reg_convrate);
if (man_id = $01) then //National Semiconductor
if ((reg_config1 and $2A) = $00) and ((reg_config2 and $F8) = $00) and (reg_convrate <= $09) then
if ((chip_id and $F0) = $20) then result:=true; //LM90
end;
function LM99Probe(HostNum: Word; addr: Byte): Boolean;
var
man_id, chip_id, reg_config1, reg_config2, reg_convrate: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_byte_data(addr, $FE, man_id);
SMB.i2c_smbus_read_byte_data(addr, $FF, chip_id);
SMB.i2c_smbus_read_byte_data(addr, $03, reg_config1);
SMB.i2c_smbus_read_byte_data(addr, $BF, reg_config2);
SMB.i2c_smbus_read_byte_data(addr, $04, reg_convrate);
if (man_id = $01) then //National Semiconductor
if ((reg_config1 and $2A) = $00) and ((reg_config2 and $F8) = $00) and (reg_convrate <= $09) then
if ((chip_id and $F0) = $30) then result:=true;
end;
function LM86Probe(HostNum: Word; addr: Byte): Boolean;
var
man_id, chip_id, reg_config1, reg_config2, reg_convrate: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_byte_data(addr, $FE, man_id);
SMB.i2c_smbus_read_byte_data(addr, $FF, chip_id);
SMB.i2c_smbus_read_byte_data(addr, $03, reg_config1);
SMB.i2c_smbus_read_byte_data(addr, $BF, reg_config2);
SMB.i2c_smbus_read_byte_data(addr, $04, reg_convrate);
if (man_id = $01) then //National Semiconductor
if ((reg_config1 and $2A) = $00) and ((reg_config2 and $F8) = $00) and (reg_convrate <= $09) then
if ((chip_id and $F0) = $10) then result:=true;
end;
function ADM1032Probe(HostNum: Word; addr: Byte): Boolean;
var
man_id, chip_id, reg_config1, reg_convrate: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_byte_data(addr, $FE, man_id);
SMB.i2c_smbus_read_byte_data(addr, $FF, chip_id);
SMB.i2c_smbus_read_byte_data(addr, $03, reg_config1);
SMB.i2c_smbus_read_byte_data(addr, $04, reg_convrate);
if (man_id = $41) then //Analog Devices
if (addr = $4C) and ((chip_id and $F0) = $40) and
((reg_config1 and $3F) = $00) and (reg_convrate <= $0A) then result:=true;
end;
function ADT7461Probe(HostNum: Word; addr: Byte): Boolean;
var
man_id, chip_id, reg_config1, reg_config2, reg_convrate: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_byte_data(addr, $FE, man_id);
SMB.i2c_smbus_read_byte_data(addr, $FF, chip_id);
SMB.i2c_smbus_read_byte_data(addr, $03, reg_config1);
SMB.i2c_smbus_read_byte_data(addr, $BF, reg_config2);
SMB.i2c_smbus_read_byte_data(addr, $04, reg_convrate);
if (man_id = $41) then //Analog Devices
if (chip_id = $51) and
((reg_config1 and $1F) = $00) and (reg_convrate <= $0A) then result:=true;
end;
function MAX6657Probe(HostNum: Word; addr: Byte): Boolean;
var
man_id, chip_id, reg_config1, reg_convrate: Byte;
begin
result:=false;
SMB.CurrentHost:=HostNum;
SMB.i2c_smbus_read_byte_data(addr, $FE, man_id);
SMB.i2c_smbus_read_byte_data(addr, $FF, chip_id);
SMB.i2c_smbus_read_byte_data(addr, $03, reg_config1);
SMB.i2c_smbus_read_byte_data(addr, $04, reg_convrate);
//The Maxim variants do NOT have a chip_id register.
//Reading from that address will return the last read //value, which in our case is those of the man_id //register. Likewise, the config1 register seems to //lack a low nibble, so the value will be those of the //previous read, so in our case those of the man_id //register. if (man_id = $4D) then //Maxim
if (chip_id = man_id) and ((reg_config1 and $1F) = (man_id and $0F)) and (reg_convrate <= $09) then result:=true;end;
//==============================================================================
// Chip voltage methods
//==============================================================================
function ASB100GetVoltage(Index: byte; const Chip: tChip; var value: single; preset: byte): boolean;
var tmb: byte;
begin
value := 0;
result := false;
if (Index < 0) or (Index > Chip.ChipProp.VoltagesCount - 1) then exit;
with Chip do
SMB.CurrentHost:=smbHostNum;
if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $20 + Index, tmb) <> 0 then exit;
case Index of
0..2: value:=tmb*0.016;
3: value:=tmb*0.016*1.68;
4: value:=tmb*0.016*3.8;
5: value:=(tmb*(-0.016))*3.97;
6: value:=(tmb*(-0.016))*1.666;
end;
result := true;
end;
//==============================================================================
// Chip temperature methods
//==============================================================================
function LM75GetTemperature(Index: byte; const Chip: tChip; var value: single): boolean;
var
tmp: Word;
begin
result := false;
value := 0;
if (index < 0) or (index > Chip.ChipProp.TemperaturesCount - 1) then exit;
with Chip, oHWIO do
begin
SMB.CurrentHost:=smbHostNum;
SMB.i2c_smbus_read_word_data(smbDevice, 0, tmp);
tmp:=Swap16(tmp);
value:=round((tmp/1280)*5);
end;
result := true;
end;
function ASB100GetTemperature(Index: byte; const Chip: tChip; var value: single): boolean;
var tmb: byte;
begin
result := false;
value := 0;
if (index < 0) or (index > Chip.ChipProp.TemperaturesCount - 1) then exit;
with Chip do
SMB.CurrentHost:=smbHostNum;
case Index of
0:
begin
if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $27, tmb) <> 0 then exit;
if ((tmb and $80) shr 7) = 1 then
value := -((tmb xor $FF) + 1)
else
value := tmb;
end;
1:
begin
if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $17, tmb) <>0 then exit;
if ((tmb and $80) shr 7) = 1 then
value := -((tmb xor $FF) + 1)
else
value := tmb;
end;
end;
result := true;
end;
function LM90GetTemperature(Index: byte; const Chip: tChip; var value: single): boolean;
var
tmp, tmp1: Byte;
oldh, newh: Byte;
begin
result := false;
value := 0;
if (index < 0) or (index > Chip.ChipProp.TemperaturesCount - 1) then exit;
with Chip, oHWIO do
begin
case Index of
0: if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $00, tmp) <>0 then exit;
1: begin
{if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $01, oldh) <>0 then exit;
if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $10, tmp) <>0 then exit;
if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $01, newh) <>0 then exit;
if (newh <> oldh) then }
if SMB.i2c_smbus_read_byte_data(Chip.smbDevice, $01, tmp) <>0 then exit;
//tmp:=tmp or (newh shl 8);
end;
end;
value:=tmp;
end;
result := true;
end;
//==============================================================================
// Chip voltage methods
//==============================================================================
function ATXP1GetVoltage(Index: byte; const Chip: tChip; var value: single; preset: byte): boolean;
var
tmp: Byte;
begin
result := false;
if (index < 0) or (index > Chip.ChipProp.VoltagesCount - 1) then exit;
SMB.i2c_smbus_read_byte_data(Chip.smbDevice, Index, tmp);
tmp:=tmp and $1f;
case Index of
0: begin
if preset = 0 then value:=(1850-tmp*25)/1000
else tmp:=0;
end;
1: begin
if preset = 0 then value:=(1850-tmp*25)/1000
else tmp:=0;
end;
end;
result:=true;
end;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?