unit Sample4u; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TSample4Form = class(TForm) Label2: TLabel; BoardBox: TGroupBox; Label1: TLabel; Label4: TLabel; StartTestButton: TButton; DACBox: TComboBox; CardBox: TComboBox; CurveBox: TGroupBox; SineButton: TButton; TriangleButton: TButton; SawButton: TButton; StatusBox: TGroupBox; CalcuLabel: TLabel; GenerLabel: TLabel; StopTestButton: TButton; ExitButton: TButton; procedure ExitButtonClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure StopTestButtonClick(Sender: TObject); procedure SineButtonClick(Sender: TObject); procedure TriangleButtonClick(Sender: TObject); procedure SawButtonClick(Sender: TObject); procedure StartTestButtonClick(Sender: TObject); private { Private declarations } public { Public declarations } GoFlag : Boolean; CardNum : Integer; procedure ISR(); procedure HandleError(ErrorMsg : longint); end; TCardData = record CardNum : longint; Base : longword; end; const counts : integer = 1000; var Sample4Form: TSample4Form; DacNum, Index, BaseAddress : integer; progstruct : array [0..20000] of word; CardData : array [0..9] of TCardData; implementation {$R *.DFM} uses IRQThreadUnit, AIOWDM, ACCES32; var Thrd : IRQThread; procedure TSample4Form.ISR(); //interrupt handler begin if (GoFlag) then begin inc(Index); OutPort(BaseAddress+(DacNum*2), progstruct[Index]); Index := Index mod counts; end; // end if end; // end ISR procedure InitIRQ(); begin Thrd := IRQThread.Create(True); Thrd.Resume; end; // end InitIRQ procedure CtrMode(addr : Word; cntr : byte; mode : byte); var ctrl : integer; begin ctrl := (cntr SHL 6) or $30 or (mode SHL 1); OutPortB(addr+3,ctrl); end; // end CtrMode procedure CtrLoad(addr : Word; c : Word; val : Word); begin OutPortB(addr+c,(val and $00FF)); OutPortB(addr+c,((val SHR 8) and $00ff)); end; // end CtrLoad procedure Stop(); begin Sample4Form.GoFlag := False; InPortB(BaseAddress+6); //disable CTR to promptDAC InPortB(BaseAddress+4); //disable IRQ end; // end Stop procedure Start(); begin Sample4Form.GoFlag := True; InPortB(BaseAddress+5); //enable CTR to promptDAC InPortB(BaseAddress+3); //enable IRQ end; // end Start procedure TSample4Form.ExitButtonClick(Sender: TObject); begin if (CardNum >= 0 ) then begin Stop(); AbortRequest(CardNum); end; Close(); end; procedure TSample4Form.FormCreate(Sender: TObject); var DeviceID, NameSize, Base : longword; Name : String; i, CardIndex : integer; begin if (InPortB($61) = $AA55) then begin Application.MessageBox('ACCESNT.SYS not detected. Please copy ACCESNT.SYS into [NT]/system32/drivers and re-run this sample.', 'Warning', IDOK); end; DACBox.ItemIndex := 0; Index := 0; CardIndex := 0; GoFlag := False; DeviceID := 0; Base := 0; Name := ''; CardNum := -1; for i := 0 to GetNumCards() - 1 do begin NameSize := 255; SetString(Name, nil, NameSize); QueryCardInfo(i, @DeviceID, @Base, @NameSize, pChar(Name)); SetLength(Name, NameSize-1); if (DeviceID = $6cb0) or (DeviceID = $6ca8) then begin CardBox.Items.Add(Name + ' [' + IntToHex(Base, 4) + ']'); CardData[CardIndex].CardNum := i; CardData[CardIndex].Base := Base; inc(CardIndex); end; // end if end; // end for CardBox.ItemIndex := 0; end; // end FormCreate procedure TSample4Form.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin { Abort all pending IRQ requests. If we don't do this before exiting, later when an IRQ comes in or somebody else calls AbortRequest the pending IRQ request will attempt to unlock a thread that no longer exists, which is bad. } if (CardNum >= 0) then begin Stop(); AbortRequest(CardNum); end; end; // end FormCloseQuery procedure TSample4Form.FormClose(Sender: TObject; var Action: TCloseAction); begin { Abort all pending IRQ requests. If we don't do this before exiting, later when an IRQ comes in or somebody else calls AbortRequest the pending IRQ request will attempt to unlock a thread that no longer exists, which is bad. } if (CardNum >= 0) then begin Stop(); AbortRequest(CardNum); end; end; // end FormClose procedure TSample4Form.StopTestButtonClick(Sender: TObject); begin Stop(); Thrd.Terminate(); AbortRequest(CardNum); BoardBox.Visible := True; CurveBox.Visible := False; StatusBox.Visible := False; end; // end Button1Click procedure TSample4Form.SineButtonClick(Sender: TObject); var i : Word; rads, sine : Real; begin Stop(); CalcuLabel.Caption := 'Calculating sine wave points.....'; rads := 2.0 * Pi / (counts - 1); // rad per count for i := 0 to counts do begin sine := (sin(rads * i) + 1.0) * 2047; progstruct[i] := trunc(sine); end; // end for GenerLabel.Caption := 'Generating sine wave, press any key to stop....'; Start(); end; // end SineButtonClick procedure TSample4Form.TriangleButtonClick(Sender: TObject); var i : Word; slope,temp : Real; begin Stop(); CalcuLabel.Caption := 'Calculating triangle wave points.....'; slope := 4095.0 / counts * 2.0; // wave form slope for i := 0 to counts div 2 do begin temp := slope * i; progstruct[i] := trunc(temp); temp := 4095 - temp; progstruct[i + counts div 2] := trunc(temp); end; // end for GenerLabel.Caption := 'Generating triangle wave, press any key to stop....'; Start(); end; // end TriangleButtonClick procedure TSample4Form.SawButtonClick(Sender: TObject); var i : Word; slope,temp : Real; begin Stop(); CalcuLabel.Caption := 'Calculating saw tooth wave points.....'; slope := 4095.0 / counts; // saw tooth slope for i := 0 to counts do begin temp := slope * i; progstruct[i] := trunc(temp); progstruct[i] := progstruct[i] mod 4095; end; // end for GenerLabel.Caption := 'Generating saw tooth wave, press any key to stop....'; Start(); end; // end SawButtonClick procedure TSample4Form.StartTestButtonClick(Sender: TObject); var channel : integer; begin if not(DACBox.Text = '') and not(CardBox.Text = '') then begin CardNum := CardData[CardBox.ItemIndex].CardNum; BaseAddress := CardData[CardBox.ItemIndex].Base; DacNum := StrToInt('$'+DACBox.Text); BoardBox.Visible := False; CurveBox.Visible := True; StatusBox.Visible := True; CtrMode(BaseAddress + $24,1,2); //counter 1 mode 2 CtrMode(BaseAddress + $24,2,2); //counter 2 mode 2 CtrLoad(BaseAddress + $24,1,$5); //load 10 to counter 1 CtrLoad(BaseAddress + $24,2,$30); //load 1000 to counter 2 for channel := 0 to 15 do OutPort(BaseAddress + (channel * 2), $800); InPortB(BaseAddress + 10); InPortB(BaseAddress + 15); InitIRQ(); fillchar(progstruct,sizeof(progstruct),0); //clear buffer CalcuLabel.Caption := ''; GenerLabel.Caption := ''; end; // end if end; // end InputButtonClick procedure TSample4Form.HandleError(ErrorMsg : LongInt); begin if GoFlag then if ErrorMsg = ERROR_INVALID_FUNCTION then Application.MessageBox('Error: this card already has a pending IRQ request.', 'IRQ request aborted.', MB_OK) else Application.MessageBox('Some error occurred in the driver.', 'IRQ request aborted.', MB_OK); end; // end HandleError end.