unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ComCtrls; type TForm1 = class(TForm) Label10: TLabel; FlagLabel: TLabel; chnl0PaintBox: TPaintBox; Label18: TLabel; chnl0Max: TLabel; chnl0Rpm: TLabel; chnl1PaintBox: TPaintBox; chnl2PaintBox: TPaintBox; chnl3PaintBox: TPaintBox; chnl4PaintBox: TPaintBox; chnl5PaintBox: TPaintBox; chnl6PaintBox: TPaintBox; chnl7PaintBox: TPaintBox; Label4: TLabel; chnl1Max: TLabel; chnl1Rpm: TLabel; Label8: TLabel; chnl2Max: TLabel; chnl2Rpm: TLabel; Label44: TLabel; chnl3Max: TLabel; chnl3Rpm: TLabel; Label47: TLabel; chnl4Max: TLabel; chnl4Rpm: TLabel; Label50: TLabel; chnl5Max: TLabel; chnl5Rpm: TLabel; Label53: TLabel; chnl6Max: TLabel; chnl6Rpm: TLabel; Label56: TLabel; chnl7Max: TLabel; chnl7Rpm: TLabel; Label6: TLabel; Label7: TLabel; Label12: TLabel; Label41: TLabel; Label46: TLabel; GoButton: TButton; WriteChEdit: TEdit; InitButton: TButton; FlagButton: TButton; chnl0RpmBar: TProgressBar; GroupBox0: TGroupBox; Label14: TLabel; Label15: TLabel; chnl0MaxRpmLbl: TLabel; Label13: TLabel; Label19: TLabel; chnl0Track: TTrackBar; chn0ResEdit: TEdit; chnl0MultBox: TComboBox; ChEdit0: TEdit; setBtn0: TButton; RestBtn0: TButton; GroupBox1: TGroupBox; Label16: TLabel; Label17: TLabel; Label20: TLabel; chnl1MaxRpmLbl: TLabel; Label21: TLabel; chnl1Track: TTrackBar; chn1ResEdit: TEdit; chnl1MultBox: TComboBox; ChEdit1: TEdit; RestBtn1: TButton; setBtn1: TButton; GroupBox2: TGroupBox; Label22: TLabel; Label23: TLabel; Label24: TLabel; chnl2MaxRpmLbl: TLabel; Label26: TLabel; chnl2Track: TTrackBar; chn2ResEdit: TEdit; chnl2MultBox: TComboBox; ChEdit2: TEdit; setBtn2: TButton; RestBtn2: TButton; GroupBox3: TGroupBox; Label27: TLabel; Label28: TLabel; Label29: TLabel; chnl3MaxRpmLbl: TLabel; Label31: TLabel; chnl3Track: TTrackBar; chn3ResEdit: TEdit; chnl3MultBox: TComboBox; ChEdit3: TEdit; setBtn3: TButton; RestBtn3: TButton; GroupBox4: TGroupBox; Label25: TLabel; Label30: TLabel; Label32: TLabel; chnl4MaxRpmLbl: TLabel; Label34: TLabel; chnl4Track: TTrackBar; chn4ResEdit: TEdit; chnl4MultBox: TComboBox; ChEdit4: TEdit; setBtn4: TButton; RestBtn4: TButton; GroupBox5: TGroupBox; Label35: TLabel; Label36: TLabel; Label37: TLabel; chnl5MaxRpmLbl: TLabel; Label39: TLabel; chnl5Track: TTrackBar; chn5ResEdit: TEdit; chnl5MultBox: TComboBox; ChEdit5: TEdit; setBtn5: TButton; RestBtn5: TButton; GroupBox6: TGroupBox; Label33: TLabel; Label38: TLabel; Label40: TLabel; chnl6MaxRpmLbl: TLabel; Label42: TLabel; chnl6Track: TTrackBar; chn6ResEdit: TEdit; chnl6MultBox: TComboBox; ChEdit6: TEdit; setBtn6: TButton; RestBtn6: TButton; GroupBox7: TGroupBox; Label1: TLabel; Label2: TLabel; Label3: TLabel; chnl7MaxRpmLbl: TLabel; Label5: TLabel; chnl7Track: TTrackBar; chn7ResEdit: TEdit; chnl7MultBox: TComboBox; ChEdit7: TEdit; setBtn7: TButton; RestBtn7: TButton; chnl1RpmBar: TProgressBar; chnl2RpmBar: TProgressBar; chnl3RpmBar: TProgressBar; chnl4RpmBar: TProgressBar; chnl5RpmBar: TProgressBar; chnl6RpmBar: TProgressBar; chnl7RpmBar: TProgressBar; TheTime: TTimer; resetTimer: TTimer; BlurbMemo: TMemo; CardName: TLabel; Label45: TLabel; procedure FormCreate(Sender: TObject); procedure GoButtonClick(Sender: TObject ); procedure StopButtonClick(Sender: TObject); procedure TheTimeTimer(Sender: TObject); procedure InitButtonClick(Sender: TObject); procedure FlagButtonClick(Sender: TObject); procedure chnlTrackChange(Sender: TObject); procedure PaintBoxPaint(Sender: TObject); procedure chnlMultBoxChange(Sender: TObject); function setChannelMult(channel, mult: Integer): Integer; procedure RestBtnClick(Sender: TObject); procedure resetTimerTimer(Sender: TObject); procedure setBtnClick(Sender: TObject); procedure ChEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Addr: DWord; ChEdit: array [0..7] of TEdit; LoadEdit: array [0..7] of TEdit; resolution: array [0..7] of TEdit; rpmLabel: array[0..7] of TLabel; maxRpmGroupLabel: array [0..7] of TLabel; maxRpmBarLabel: array [0..7] of TLabel; rpmBar: array [0..7] of TProgressBar; paintBox: array [0..7] of TPaintBox; trackBar: array [0..7] of TTrackBar; multBox: array[0..7] of TComboBox; gBoxes: array [0..7] of TGroupBox; setBtn: array [0..7] of TButton; channelControlBytes: array [0..7] of Integer; channelResolutions: array [0..7] of Integer; channelMults: array[0..7] of Integer; channelReads: array[0..7] of Integer; channelReadsPrev: array[0..7] of Integer; RunFlag: Boolean; NumCards, CardNum: Integer; Offset: WORD; const PI = 3.141593; implementation uses AIOWDM; // DLL for PCI and PCIe products {$R *.DFM} //--------------------------------------------------------------------------- procedure Init_7766(); var count: Integer; begin // See spec for control register options // Init all for acquisition: for count:= 0 to 7 do begin //RelOutPort(CardNum, 0 , $A001); // init PCI board mode see spec RelOutPort(CardNum, 0 + (count * 8), $2831); // init PCI board mode see spec RelOutPortB(CardNum, 7 + (count * 8), $01); // swap inA and inB reverse direction value: (optional) (CPLD) RelOutPortB(CardNum, 6 + (count * 8), $09); // reset all flags and counters end; end; procedure Reset_7766(chan: integer); begin // Reset the counters for one channel: RelOutPortB(0, 0 + 6+ (chan * 8), $09); // reset all flags and counters end; function Read_7766_OL(chan: integer): integer; var data, base, offset: Integer; begin // See spec for control register options // The Channel data starts at address 0x02 // See the LS7766 spec RelOutPortB(CardNum, 0 + 6 + (chan * 8), $04); //Load ODR from CNTR // Read up to 8 channels 32 bits per channel: base := $02; offset := chan * 8; data := RelInPortL(CardNum, 0 + base + offset); Result := data; end; function Get_7766_Flags(Chan: DWORD): BYTE; begin Result := RelInPortB(CardNum, 6 + (Chan * 8) ); end; procedure SetQuadCountMode_7766(chan, index: integer); var ModeCtrlReg, mask, B1B0: Word; begin // See spec for options // MCR0 B1B0 == 00 v 01 v 10 v 11 // Use exiting MCR0 value and reinit with new count mode bits: // Set for one channel by index 0-4: // Note: ctrReg is our global default set at startup and used in init func as well ModeCtrlReg := $2831; // assume this is the default value mask := $2831; // assume this is the default value B1B0 := $0001; // default x1 quadrature // 00 is Non quadrature mode which is A and B data are count and direction // So this mode wont be appropriate for some encoders case index of //0: B1B0 := $00; 1: B1B0 := $01; 2: B1B0 := $02; 3: B1B0 := $03; else B1B0 := $00; end; //MCR0 and MCR1 mask := ModeCtrlReg and ( $FFFF shl 2 ); // clear 2 bottom bits ModeCtrlReg := (mask or B1B0); // set new value RelOutPort(CardNum, 0 + 0 + (chan * 8), ModeCtrlReg); // rewrite control register with new B1B0 bits RelOutPortB(CardNum, 0 + 7 + (chan * 8), $01); // swap inA and inB reverse direction value: (optional) (CPLD) RelOutPortB(CardNum, 0 + 6 + (chan * 8), $09); // reset all flags and counters // Reset the counters for one channel: //RelOutPortB(0, 0 + 6+ (chan * 8), $09); // reset all flags and counters end; //--------------------------------------------------------------------------- procedure TForm1.FormCreate(Sender: TObject); var count: Integer; // Get card info: //i: Integer; found: Boolean; DeviceID, Base: LongWord; NameSize: LongWord; Name: String; begin found := False; RunFlag := True; BlurbMemo.Lines.Text := 'This sample outputs a walking bit on Port A of the selected group. It then reads back the value from Port A. ' + 'This should be identical to the output value due to on-chip readback. ' + 'It also displays the Input from Port B. If a wrap plug is installed, Port B should read the same value. ' + 'Otherwise, ground individual bits on Port B to see them show zeroes on the display.' ; if (InPortB($61) = $AA55) then begin Application.MessageBox(' AIOWDM.SYS not detected.'#13#10' Please copy AIOWDM.SYS into [Windows]/system32/drivers and re-run this sample.'#13#10'Ensure that a board is installed properly.', 'Warning', IDOK); end; NumCards := GetNumCards(); CardNum := 0; // first/only card Offset := 0; // first/only card offset if NumCards = 0 then begin BlurbMemo.Text := 'No cards found. The cards may not be installed, or they may be installed using a driver other than AIOWDM.sys.'; end; NameSize := 256; SetString(Name, nil, NameSize); QueryCardInfo(CardNum, @DeviceID, @Base, @NameSize, PChar(Name)); SetLength(Name, NameSize - 1); case (DeviceID) of $2230: begin CardName.Caption := 'PCI-QUAD-8 Card'; Found := True; end; end;//case if not found then begin CardName.Caption := 'No Card Found.'; BlurbMemo.Lines.Clear; BlurbMemo.Lines.Append('No PCI Card Found.'); BlurbMemo.Lines.Append('The sample program might not have been updated for your specific device ID.'); RunFlag := False; end; //Set up GUI componenets: ChEdit[0] := ChEdit0; ChEdit[1] := ChEdit1; ChEdit[2] := ChEdit2; ChEdit[3] := ChEdit3; ChEdit[4] := ChEdit4; ChEdit[5] := ChEdit5; ChEdit[6] := ChEdit6; ChEdit[7] := ChEdit7; rpmLabel[0] := chnl0Rpm; rpmLabel[1] := chnl1Rpm; rpmLabel[2] := chnl2Rpm; rpmLabel[3] := chnl3Rpm; rpmLabel[4] := chnl4Rpm; rpmLabel[5] := chnl5Rpm; rpmLabel[6] := chnl6Rpm; rpmLabel[7] := chnl7Rpm; rpmBar[0] := chnl0RpmBar; rpmBar[1] := chnl1RpmBar; rpmBar[2] := chnl2RpmBar; rpmBar[3] := chnl3RpmBar; rpmBar[4] := chnl4RpmBar; rpmBar[5] := chnl5RpmBar; rpmBar[6] := chnl6RpmBar; rpmBar[7] := chnl7RpmBar; channelControlBytes[0] := 1; channelControlBytes[1] := 3; channelControlBytes[2] := 5; channelControlBytes[3] := 7; channelControlBytes[4] := 9; channelControlBytes[5] := 11; channelControlBytes[6] := 13; channelControlBytes[7] := 15; paintBox[0] := chnl0PaintBox; paintBox[1] := chnl1PaintBox; paintBox[2] := chnl2PaintBox; paintBox[3] := chnl3PaintBox; paintBox[4] := chnl4PaintBox; paintBox[5] := chnl5PaintBox; paintBox[6] := chnl6PaintBox; paintBox[7] := chnl7PaintBox; resolution[0] := chn0ResEdit; resolution[1] := chn1ResEdit; resolution[2] := chn2ResEdit; resolution[3] := chn3ResEdit; resolution[4] := chn4ResEdit; resolution[5] := chn5ResEdit; resolution[6] := chn6ResEdit; resolution[7] := chn7ResEdit; trackBar[0] := chnl0Track; trackBar[1] := chnl1Track; trackBar[2] := chnl2Track; trackBar[3] := chnl3Track; trackBar[4] := chnl4Track; trackBar[5] := chnl5Track; trackBar[6] := chnl6Track; trackBar[7] := chnl7Track; maxRpmGroupLabel[0] := chnl0MaxRpmLbl; maxRpmGroupLabel[1] := chnl1MaxRpmLbl; maxRpmGroupLabel[2] := chnl2MaxRpmLbl; maxRpmGroupLabel[3] := chnl3MaxRpmLbl; maxRpmGroupLabel[4] := chnl4MaxRpmLbl; maxRpmGroupLabel[5] := chnl5MaxRpmLbl; maxRpmGroupLabel[6] := chnl6MaxRpmLbl; maxRpmGroupLabel[7] := chnl7MaxRpmLbl; maxRpmBarLabel[0] := chnl0Max; maxRpmBarLabel[1] := chnl1Max; maxRpmBarLabel[2] := chnl2Max; maxRpmBarLabel[3] := chnl3Max; maxRpmBarLabel[4] := chnl4Max; maxRpmBarLabel[5] := chnl5Max; maxRpmBarLabel[6] := chnl6Max; maxRpmBarLabel[7] := chnl7Max; multBox[0] := chnl0MultBox; multBox[1] := chnl1MultBox; multBox[2] := chnl2MultBox; multBox[3] := chnl3MultBox; multBox[4] := chnl4MultBox; multBox[5] := chnl5MultBox; multBox[6] := chnl6MultBox; multBox[7] := chnl7MultBox; gBoxes[0] := GroupBox0; gBoxes[1] := GroupBox1; gBoxes[2] := GroupBox2; gBoxes[3] := GroupBox3; gBoxes[4] := GroupBox4; gBoxes[5] := GroupBox5; gBoxes[6] := GroupBox6; gBoxes[7] := GroupBox7; setBtn[0] := setBtn0; setBtn[1] := setBtn1; setBtn[2] := setBtn2; setBtn[3] := setBtn3; setBtn[4] := setBtn4; setBtn[5] := setBtn5; setBtn[6] := setBtn6; setBtn[7] := setBtn7; channelControlBytes[0] := 1; channelControlBytes[1] := 3; channelControlBytes[2] := 5; channelControlBytes[3] := 7; channelControlBytes[4] := 9; channelControlBytes[5] := 11; channelControlBytes[6] := 13; channelControlBytes[7] := 15; GoButton.Enabled := False; FlagButton.Enabled := False; for count := 0 to 7 do begin channelResolutions[count] := 300; channelMults[count] := 1; maxRpmGroupLabel[count].Caption := IntToStr(trackBar[count].Position); maxRpmBarLabel[count].Caption := maxRpmGroupLabel[count].Caption; gBoxes[count].Enabled := False; end; end; //--------------------------------------------------------------------------- procedure TForm1.GoButtonClick(Sender: TObject ); begin TheTime.Enabled := True; GoButton.OnClick := StopButtonClick; GoButton.Caption := 'Stop'; end; //--------------------------------------------------------------------------- procedure TForm1.StopButtonClick(Sender: TObject); begin TheTime.Enabled := False; GoButton.OnClick := GoButtonClick; GoButton.Caption := 'Go'; end; //--------------------------------------------------------------------------- procedure TForm1.TheTimeTimer(Sender: TObject); var rpm: double; I: Integer; begin for I := 0 to 7 do begin // Iterate through 8 channels: //channelReads[I] := Read_7766_OL(Offset + (I * 8) ); channelReads[I] := Read_7766_OL( I ); rpm := (channelReadsPrev[I] - channelReads[I]); rpm := rpm / (channelResolutions[I] * channelMults[I]); rpm := rpm * 60 /(TheTime.Interval * 0.001); rpm := abs(rpm); rpmLabel[I].Caption := FloatToStr(rpm); ChEdit[I].Text := IntToStr(channelReads[I]); if channelReadsPrev[I] <> channelReads[I] then paintBox[I].Invalidate() ; channelReadsPrev[I] := channelReads[I]; if (rpm > rpmBar[I].Max) then rpmBar[I].Position := rpmBar[I].Max else rpmBar[I].Position := round(rpm) ; end; end; //--------------------------------------------------------------------------- procedure TForm1.InitButtonClick(Sender: TObject); var count: Integer; begin //initialize all the counters to a resolution of 300 //with a mulitplier of 1 Init_7766(); // init all 8 for count := 0 to 7 do begin channelReads[count] := 0; channelReadsPrev[count] := 0; gBoxes[count].Enabled := True; end; InitButton.Enabled := False; GoButton.Enabled := True; FlagButton.Enabled := True; end; //--------------------------------------------------------------------------- procedure TForm1.FlagButtonClick(Sender: TObject); var Chan: DWORD; begin Chan := StrToInt('$' + WriteChEdit.Text); FlagLabel.Caption := IntToHex( Get_7766_Flags(Chan), 2); end; //--------------------------------------------------------------------------- procedure TForm1.PaintBoxPaint(Sender: TObject); var angle: double; pBox: TPaintBox; currentChannel: Integer; begin pBox := Sender as TPaintBox; currentChannel := pBox.Tag; if (rpmBar[currentChannel].Position = rpmBar[currentChannel].Max) then pBox.Canvas.Brush.Color := clRed else pBox.Canvas.Brush.Color := clWhite ; pBox.Canvas.Pen.Color := clBlack; pBox.Canvas.Ellipse(10, 10, 100, 100); pBox.Canvas.MoveTo(55, 55); pBox.Canvas.LineTo(55, 100); pBox.Canvas.MoveTo(55, 55); angle := channelReads[currentChannel]; angle := angle * 2 * PI; angle := angle / (channelResolutions[currentChannel] * channelMults[currentChannel]) - 0.5 * PI ; pBox.Canvas.Pen.Color := clBlue; pBox.Canvas.LineTo(round(55.0 - 45.0 * cos(angle)), round(55.0 - 45.0 * sin(angle))); end; //--------------------------------------------------------------------------- procedure TForm1.chnlTrackChange(Sender: TObject); var pBar: TTrackBar; begin pBar := Sender as TTrackBar; maxRpmBarLabel[pBar.Tag].Caption := IntToStr(trackBar[pBar.Tag].Position); maxRpmGroupLabel[pBar.Tag].Caption := maxRpmBarLabel[pBar.Tag].Caption; rpmBar[pBar.Tag].Max := trackBar[pBar.Tag].Position; end; //--------------------------------------------------------------------------- procedure TForm1.chnlMultBoxChange(Sender: TObject); var pBox: TComboBox; begin pBox := Sender as TComboBox; pBox.Text := IntToStr(setChannelMult(pBox.Tag, StrToInt(pBox.Text))); paintBox[pBox.Tag].Invalidate; end; //--------------------------------------------------------------------------- function TForm1.setChannelMult(channel, mult: Integer): Integer; begin // Quadature Count Mode Settings: case mult of // 0 is for Non quadrature mode 1: begin channelMults[channel] := 1; SetQuadCountMode_7766( channel, 1 ); // pass index 0,1,2,3 setChannelMult := 1; end; 2: begin channelMults[channel] := 2; SetQuadCountMode_7766( channel, 2 ); setChannelMult := 2; end; 4: begin channelMults[channel] := 4; SetQuadCountMode_7766( channel, 3 ); setChannelMult := 4; end; else setChannelMult := channelMults[channel]; end; end; procedure TForm1.RestBtnClick(Sender: TObject); var pBtn: TButton; begin pBtn := Sender as TButton; reset_7766(pBtn.Tag); // reset counter resetTimer.Tag := pBtn.Tag; resetTimer.Enabled := True; end; //--------------------------------------------------------------------------- procedure TForm1.resetTimerTimer(Sender: TObject); begin resetTimer.Enabled := False; rpmBar[resetTimer.Tag].Position := rpmBar[resetTimer.Tag].Min; paintBox[resetTimer.Tag].Invalidate(); end; //--------------------------------------------------------------------------- procedure TForm1.setBtnClick(Sender: TObject); var pBtn: TButton; begin pBtn := Sender as TButton; channelResolutions[pBtn.Tag] := StrToIntDef(resolution[pBtn.Tag].Text, 1000); paintBox[pBtn.Tag].Invalidate(); end; //--------------------------------------------------------------------------- procedure TForm1.ChEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var result: Integer; pEdit: TEdit; begin result := GetAsyncKeyState(VK_RETURN); if (result and $8000) <> 0 then begin pEdit := Sender as TEdit; setBtn[pEdit.Tag].Click(); end; end; end.