{ Контроллер канала питания источника ионов (АК2) 5.105.177 Включение блоков и открытие клапанов } unit MI1201AGM_ISSB_Emulator; interface USES SysUtils, TimeInterval_Emulator, MI1201AGM_Hardware_Emulator, MI1201AGM_Controller_Emulator; const cDataSignature='ISSB emulator data. '^M^L; cRegistrySubPath='ISSB'; cValidPorts=[$90..$97]; cValidReadPorts=[$90]; cValidWritePorts=[$91..$97]; type tDataSignature=array[1..Length(cDataSignature)] of char; tBeamState=0..1; tMCounter=0..4; tMDirection=-1..1; tMotorData=record Pos:word; MaxPos:word; OptPos:word; Direction:tMDirection; Counter:tMCounter; end; tMotors=array[tMotor] of tMotorData; // Данные, сохраняющиеся между измерениями tData=record Signature:tDataSignature; Motors:tMotors; end; // Данные, НЕсохраняющиеся между измерениями tTmpData=record end; tISSB=class(tController) private prData:tData; prTmpData:tTmpData; protected // обязательные процедуры function SubPath:string; override; procedure prOutByte(b:Byte; port:word); override; function prInByte(port:word):Byte; override; function CheckData(Data:pointer):boolean; override; function DataSize:integer; override; function SetData(aData:pointer):boolean; override; function GetData(aData:pointer):boolean; override; // прочие процедуры public // обязательные процедуры constructor Create(Hardware:tMi1201HardwareEmulator); destructor Destroy; override; procedure ReInit; override; procedure SetDefaultData; override; function ValidPort(APort:word):boolean; function ValidReadPort(APort:word):boolean; function ValidWritePort(APort:word):boolean; // прочие процедуры function FlagsGet:byte; procedure BeamSet(b:tBeamState); procedure MotorSet(m:tMotor; b:byte); function MotorSignalScaleGet(m:tMotor):tMotorSignalScale; end; implementation type tWord=record case byte of 0:(w:word); 1:(Lo,Hi:byte); end; function tISSB.SetData(aData:pointer):boolean; begin Result:=Inherited SetData(aData); if Result then begin Inc(Cardinal(aData),Inherited DataSize); Result:=CheckData(aData); if Result then begin Move(aData^,prData,DataSize); end; end; end; function tISSB.GetData(aData:pointer):boolean; begin Result:=Inherited GetData(aData); if Result then begin Inc(Cardinal(aData),Inherited DataSize); Result:=CheckData(aData); if Result then begin Move(prData,aData^,SizeOf(prData)); end; end; end; function tISSB.DataSize:integer; begin Result:=Inherited DataSize + SizeOf(prData); end; function tISSB.SubPath:string; begin Result:=cRegistrySubPath; end; function tISSB.CheckData(Data:pointer):boolean; begin Result:=Inherited CheckData(Data) and TRUE; end; constructor tISSB.Create(Hardware:tMi1201HardwareEmulator); begin Inherited; end; destructor tISSB.Destroy; begin Inherited; end; procedure tISSB.ReInit; begin end; procedure tISSB.SetDefaultData; var m:tMotor; begin prData.Signature:=cDataSignature; Hardware.HardwareSignalSet(esCatodOK); Hardware.HardwareSignalSet(esBeam_Off); for m:=Low(m) to High(m) do begin prData.Motors[m].Pos:=0; prData.Motors[m].Direction:=0; prData.Motors[m].MaxPos:=100; prData.Motors[m].Counter:=0; end; prData.Motors[mEmisI].MaxPos:=500; prData.Motors[mIonizU].MaxPos:=500; for m:=Low(m) to High(m) do begin prData.Motors[m].OptPos:=((0+prData.Motors[m].MaxPos) div 2) + 3*Ord(m); end; for m:=Low(m) to High(m) do begin Hardware.IonSourceScaleSet(m,MotorSignalScaleGet(m)); end; end; function tISSB.FlagsGet:byte; begin FlagsGet:=byte(Hardware.HardwareSignals); end; procedure tISSB.BeamSet(b:tBeamState); begin case b of 0: Hardware.HardwareSignalClear(esBeam_Off); 1: Hardware.HardwareSignalSet(esBeam_Off); else RunError(201); end; end; procedure tISSB.MotorSet(m:tMotor; b:byte); begin b:=b and 3; with prData.Motors[m] do begin case Direction of 0:begin case b of 0:Direction:=1; 3:Direction:=-1; else {$IfNDef Seg16} raise ERangeError.CreateFmt ( 'Неверный вывод[%x (%d.)] для шагового двигателя [%d.]. Должно быть [0 или 3].', [b,b,Ord(m)]); {$ELSE} RunError(201); {$EndIf} end; end; -1,1:begin if b<>(Counter+Direction) then {$IfNDef Seg16} raise ERangeError.CreateFmt ( 'Неверный вывод[%x (%d.)] для шагового двигателя [%d.]. Должно быть [%x (%d.)].', [b,b,Ord(m),Counter+Direction,Counter+Direction]); {$ELSE} RunError(201); {$EndIf} case Direction of -1:if b=3 then begin If Pos0 then Dec(Pos); Direction:=0; end; end; end; else {$IfNDef Seg16} raise ERangeError.CreateFmt ( 'Неверный вывод[%x (%d.)] для шагового двигателя [%d.]. Не инициализирован эмулятор.', [b,b,Ord(m)]); {$ELSE} RunError(201); {$EndIf} end; Counter:=b; end; Hardware.IonSourceScaleSet(m,MotorSignalScaleGet(m)); end; function tISSB.MotorSignalScaleGet(m:tMotor):tMotorSignalScale; const cSqrt2PI=2.5066282746310005024; var s:word; begin with prData.Motors[m] do begin s:=(MaxPos-Pos) div 4; MotorSignalScaleGet:=Round( High(tMotorSignalScale)*exp(0.5*Sqr((Pos-OptPos)/s))/(cSqrt2PI*s) ); end; end; procedure tISSB.prOutByte(b:byte; port:word); begin port:=port and $FF; case Port of {Порты АК2 - Контроллер канала питания источника ионов } $91: begin {Луч} BeamSet(b and 1); end; $92: begin {Коррекция Z} MotorSet(mCorrZ,b); end; $93: begin {Коррекция Y} MotorSet(mCorrY,b); end; $94: begin {Фокусирующее напряжение} MotorSet(mFocusU,b); end; $95: begin {Вытягивающее напряжение} MotorSet(mExtrU,b); end; $96: begin {Ток эмиссии} MotorSet(mEmisI,b); end; $97: begin {Ионизирующее напряжение} MotorSet(mIonizU,b); end; else if port in cValidReadPorts then begin WriteToInvalidPort:=TRUE; if ExceptionOnInvalidPort then raise EInvalidPort.CreateEx(ClassName,Port); end else begin InvalidPort:=TRUE; if ExceptionOnInvalidPort then raise EInvalidPort.CreateEx(ClassName,Port); end; end; end; function tISSB.prInByte(port:word):byte; begin port:=port and $FF; Result:=$FF; case Port of {Порты АК2 - Контроллер канала питания источника ионов } $90: begin {Флаги} Result:=FlagsGet; end; else if port in cValidWritePorts then begin ReadFromInvalidPort:=TRUE; if ExceptionOnInvalidPort then raise EInvalidPort.CreateEx(ClassName,Port); end else begin InvalidPort:=TRUE; if ExceptionOnInvalidPort then raise EInvalidPort.CreateEx(ClassName,Port); end; end; end; function tISSB.ValidPort(APort:word):boolean; begin Result:= ((APort and $FF00)=cBasePort) and ((APort and $FF) in cValidPorts); end; function tISSB.ValidReadPort(APort:word):boolean; begin Result:= ((APort and $FF00)=cBasePort) and ((APort and $FF) in cValidReadPorts); end; function tISSB.ValidWritePort(APort:word):boolean; begin Result:= ((APort and $FF00)=cBasePort) and((APort and $FF) in cValidWritePorts); end; end. { Контроллер канала питания источника ионов (АК2) 5.105.177 г========T================T=====================================¬ ¦ Адрес ¦ ПОРТ ¦ ¦ ¦ порта +-------T--------+ Назначение ¦ ¦ ¦чтение ¦запись ¦ ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $97 ¦ - ¦ + ¦ Порт управления шаговым двигателем ¦ ¦ ¦ ¦ ¦ " Напряжение ионизации " ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $96 ¦ - ¦ + ¦ Порт управления шаговым двигателем ¦ ¦ ¦ ¦ ¦ " Ток эмиссии " ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $95 ¦ - ¦ + ¦ Порт управления шаговым двигателем ¦ ¦ ¦ ¦ ¦ " Напряжение вытягивающее " ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $94 ¦ - ¦ + ¦Порт управления шаговым двигателем ¦ ¦ ¦ ¦ ¦ " Напряжение фокусирующее " ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $93 ¦ - ¦ + ¦ Порт управления шаговым двигателем ¦ ¦ ¦ ¦ ¦ " Коррекция Х " ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $92 ¦ - ¦ + ¦ Порт управления шаговым двигателем ¦ ¦ ¦ ¦ ¦ " Коррекция Z " ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $91 ¦ - ¦ + ¦ Включение луча стабилизатора напря- ¦ ¦ ¦ ¦ ¦ жения : ¦ ¦ ¦ ¦ ¦ 0-й бит = 0 - включить ¦ ¦ ¦ ¦ ¦ 0-й бит = 1 - выключить ¦ ¦--------+-------+--------+-------------------------------------¦ ¦ $90 ¦ + ¦ - ¦ Чтение аварийных сигналов: ¦ ¦ ¦ ¦ ¦"катод не сгорел"---- 0000 0001 ($1)¦ ¦ ¦ ¦ ¦"БПГИ включен"---- 0000 0010 ($2)¦ ¦ ¦ ¦ ¦"10 kV включен "---- 0000 0100 ($4)¦ ¦ ¦ ¦ ¦"Перегрузка" -------- 0000 1000 ($8)¦ ¦ ¦ ¦ ¦"Луч не включен"----- 0001 0000 ($10)¦ L========¦=======¦========¦=====================================- }