unit Ced1902;
{ ================================================
  WCP for Windows (c) J. Dempster, 1997
  CED 1902 Programmable Amplifier control module
  ================================================}

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, StdCtrls, Buttons, global, shared, Spin, maths ;

type
  TCED1902Frm = class(TForm)
    CED1902Group: TGroupBox;
    Label9: TLabel;
    Label10: TLabel;
    ckCED1902NotchFilter: TCheckBox;
    cbCED1902LPFilter: TComboBox;
    cbCED1902HPFilter: TComboBox;
    InputGrp: TGroupBox;
    Label7: TLabel;
    cbCED1902Input: TComboBox;
    Label8: TLabel;
    cbCED1902Gain: TComboBox;
    ckCED1902InUse: TCheckBox;
    ckCED1902ACCoupled: TCheckBox;
    cbCED1902ComPort: TComboBox;
    Label11: TLabel;
    bClose: TButton;
    lbDCOffset: TLabel;
    EdDCOffset: TEdit;
    procedure ckCED1902InUseClick(Sender: TObject);
    procedure cbCED1902GainChange(Sender: TObject);
    procedure cbCED1902InputChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure cbCED1902LPFilterChange(Sender: TObject);
    procedure cbCED1902HPFilterChange(Sender: TObject);
    procedure ckCED1902NotchFilterClick(Sender: TObject);
    procedure ckCED1902ACCoupledClick(Sender: TObject);
    procedure cbCED1902ComPortChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure bCloseClick(Sender: TObject);
    procedure EdDCOffsetKeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  CED1902Frm: TCED1902Frm;

function VMaxDCOffset( CED1902Input : LongInt ) : single ;

implementation

{$R *.DFM}

uses mdiform ;
const
     IP_GROUNDED = 1 ;
     IP_TRANSDUCER_SE = 2 ;
     IP_TRANSDUCER_DIFF = 3 ;
     IP_TRANSDUCER_INV = 4 ;
     IP_ELECTRODES_GROUNDED = 5 ;
     IP_ELECTRODES = 6 ;

procedure TCED1902Frm.FormCreate(Sender: TObject);
{ -------------------------------------
  Initialisations when form is created
  ------------------------------------}
var
   VScale : single ;
begin

     Main.mnCED1902.Enabled := false ;

     cbCED1902Input.clear ;
     cbCED1902Input.items.add('Grounded' );
     cbCED1902Input.items.add('Transducer (S.E.)');
     cbCED1902Input.items.add('Transducer (Diff+)') ;
     cbCED1902Input.items.add('Transducer (Diff-)');
     cbCED1902Input.items.add('Grounded ' );
     cbCED1902Input.items.add('Electrodes ' );
     cbCED1902Input.Itemindex := Settings.CED1902.Input - 1 ;

     cbCED1902Gain.clear ;
     if Settings.CED1902.Input < IP_ELECTRODES_GROUNDED then begin
        cbCED1902Gain.items.add(' X 1 ') ;
        cbCED1902Gain.items.add(' X 3 ') ;
        cbCED1902Gain.items.add(' X 10 ') ;
        cbCED1902Gain.items.add(' X 30 ') ;
        end ;

     cbCED1902Gain.items.add(' X 100 ') ;
     cbCED1902Gain.items.add(' X 300 ') ;
     cbCED1902Gain.items.add(' X 1000 ') ;
     cbCED1902Gain.items.add(' X 3000 ') ;
     cbCED1902Gain.items.add(' X 10000 ') ;
     cbCED1902Gain.items.add(' X 30000 ') ;
     cbCED1902Gain.items.add(' X 100000 ') ;
     cbCED1902Gain.itemindex := Settings.CED1902.Gain -1;

     { Low pass filter options list }
     cbCED1902LPFilter.clear ;
     cbCED1902LPFilter.items.add(' None ' ) ;
     cbCED1902LPFilter.items.add(' 1000 Hz ' ) ;
     cbCED1902LPFilter.items.add('  500 Hz ' ) ;
     cbCED1902LPFilter.items.add('  100 Hz ' ) ;
     cbCED1902LPFilter.itemindex := Settings.CED1902.LPFilter ;

     { High pass filter options list }
     cbCED1902HPFilter.clear ;
     cbCED1902HPFilter.items.add(' None ') ;
     cbCED1902HPFilter.items.add('  50 Hz ') ;
     cbCED1902HPFilter.items.add(' 100 Hz ') ;
     cbCED1902HPFilter.items.add(' 200 Hz ') ;
     cbCED1902HPFilter.itemindex := Settings.CED1902.HPFilter ;

     { 50Hz Notch filter }
     if Settings.CED1902.NotchFilter = 1 then ckCED1902NotchFilter.checked := True
                                         else ckCED1902NotchFilter.checked := False ;
     {AC/DC Coupling }
     if Settings.CED1902.ACCoupled = 1 then ckCED1902ACCoupled.checked := True
                                       else ckCED1902ACCoupled.checked := False ;
     {DC Offset}
     lbDCOffset.caption := format( 'DC Offset (+/-%.4g mV)',[VoltsTomV *
                                   VMaxDCOffset(Settings.CED1902.Input)] ) ;
     VScale := VoltsTomV * VMaxDCOffset( Settings.CED1902.Input ) / 32767. ;
     edDCOffset.text := format(' %f mV', [Settings.CED1902.DCOffset*VScale]) ;

     { CED 1902 in use }
     if Settings.CED1902.InUse  then begin
        ckCED1902InUse.checked := True ;
        end
     else ckCED1902InUse.checked := False ;

     { CED 1902 Communications port list }
     cbCED1902ComPort.clear ;
     cbCED1902ComPort.items.add( ' COM1 ' ) ;
     cbCED1902ComPort.items.add( ' COM2 ' ) ;
     cbCED1902ComPort.ItemIndex := Settings.CED1902.ComPort - 1 ;

     { CED 1902 settings are disabled if not in use }
     cbCED1902Gain.enabled := ckCED1902InUse.checked ;
     cbCED1902Input.enabled := ckCED1902InUse.checked ;
     cbCED1902LPFilter.enabled := ckCED1902InUse.checked ;
     cbCED1902HPFilter.enabled := ckCED1902InUse.checked ;
     ckCED1902ACCoupled.enabled := ckCED1902InUse.checked ;
     ckCED1902NotchFilter.enabled := ckCED1902InUse.checked ;
     cbCED1902ComPort.enabled := ckCED1902InUse.checked ;

     end;


function VMaxDCOffset( CED1902Input : LongInt ) : single ;
var
   V : single ;
begin
     case CED1902Input of
          IP_ELECTRODES, IP_ELECTRODES_GROUNDED : V := 0.01 ;
          IP_TRANSDUCER_SE : V := 5. ;
     else
          V := 0.0005 ;
          end ;
     Result := V ;
     end ;


procedure TCED1902Frm.ckCED1902InUseClick(Sender: TObject);
{ -----------------------
  Enable/disable CED 1902
  -----------------------}
begin

     if ckCED1902InUse.checked then begin
        Settings.CED1902.InUse := True ;
        SetCED1902( Settings.CED1902 ) ;
        end
     else Settings.CED1902.InUse := False ;

     { CED 1902 settings are disabled if not in use }
     cbCED1902Gain.enabled := ckCED1902InUse.checked ;
     cbCED1902Input.enabled := ckCED1902InUse.checked ;
     cbCED1902LPFilter.enabled := ckCED1902InUse.checked ;
     cbCED1902HPFilter.enabled := ckCED1902InUse.checked ;
     ckCED1902ACCoupled.enabled := ckCED1902InUse.checked ;
     ckCED1902NotchFilter.enabled := ckCED1902InUse.checked ;
     cbCED1902ComPort.enabled := ckCED1902InUse.checked ;

     end;


procedure TCED1902Frm.cbCED1902GainChange(Sender: TObject);
{ ------------------------------
  Update CED 1902 gain settings
  -----------------------------}
begin
     { Update Ch.0 amplifier gain }
     Settings.CED1902.Gain := cbCED1902Gain.ItemIndex + 1;
     Settings.CED1902.GainValue := ExtractFloat( cbCED1902Gain.items[cbCED1902Gain.ItemIndex],
                          Settings.CED1902.GainValue ) ;
     if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
     end;


procedure TCED1902Frm.cbCED1902InputChange(Sender: TObject);
{ ---------------------
  Update CED 1902 input
  ---------------------}
var
   VScale : single ;
begin
     { Regenerate Gain combo box if Input has changed
       because Electrodes input has an extra X100 gain
       on all settings }

     cbCED1902Gain.clear ;
     if cbCED1902Input.ItemIndex < 5 then begin
        cbCED1902Gain.items.add(' X 1 ') ;
        cbCED1902Gain.items.add(' X 3 ') ;
        cbCED1902Gain.items.add(' X 10 ') ;
        cbCED1902Gain.items.add(' X 30 ') ;
        end ;
     cbCED1902Gain.items.add(' X 100 ') ;
     cbCED1902Gain.items.add(' X 300 ') ;
     cbCED1902Gain.items.add(' X 1000 ') ;
     cbCED1902Gain.items.add(' X 3000 ') ;
     cbCED1902Gain.items.add(' X 10000 ') ;
     cbCED1902Gain.items.add(' X 30000 ') ;
     cbCED1902Gain.items.add(' X 100000 ') ;

     { Make sure that the selected gain remains within the new range of values }
     cbCED1902Gain.ItemIndex := MinInt([Settings.CED1902.Gain-1,cbCED1902Gain.items.count-1]) ;
     Settings.CED1902.GainValue := ExtractFloat( cbCED1902Gain.items[cbCED1902Gain.ItemIndex],
                                   Settings.CED1902.GainValue ) ;

     { Update Ch.0 amplifier gain }
     Settings.CED1902.Input := cbCED1902Input.itemIndex + 1;

     { Update DC Offset (range changes with inputs }
     lbDCOffset.caption := format( 'DC Offset (+/-%.4g mV)',[VoltsTomV *
                                   VMaxDCOffset(Settings.CED1902.Input)] ) ;
     VScale := VoltsTomV * VMaxDCOffset( Settings.CED1902.Input ) / 32767. ;
     edDCOffset.text := format(' %f mV', [Settings.CED1902.DCOffset*VScale]) ;

     if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
     end;


procedure TCED1902Frm.cbCED1902LPFilterChange(Sender: TObject);
{ -------------------------------
  Update CED 1902 low pass filter
  -------------------------------}
begin
     Settings.CED1902.LPFilter := cbCED1902LPFilter.ItemIndex ;
     if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
     end;


procedure TCED1902Frm.cbCED1902HPFilterChange(Sender: TObject);
{ --------------------------------
  Update CED 1902 high pass filter
  --------------------------------}
begin
     Settings.CED1902.HPFilter := cbCED1902HPFilter.ItemIndex ;
     if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
     end;


procedure TCED1902Frm.ckCED1902NotchFilterClick(Sender: TObject);
{ --------------------------------------
  Update CED 1902 50Hz notch pass filter
  --------------------------------------}
begin
     if ckCED1902NotchFilter.checked then Settings.CED1902.NotchFilter := 1
                                     else Settings.CED1902.NotchFilter := 0 ;
     if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
     end;


procedure TCED1902Frm.ckCED1902ACCoupledClick(Sender: TObject);
{ -------------------------------
  Update CED 1902 AC/DC coupling
  -------------------------------}
begin
     if ckCED1902ACCoupled.checked   then Settings.CED1902.ACCoupled := 1
                                     else Settings.CED1902.ACCoupled := 0 ;
     if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
     end;


procedure TCED1902Frm.cbCED1902ComPortChange(Sender: TObject);
{ -----------------------------------
  Update CED 1902 communications port
  -----------------------------------}
begin
     Settings.CED1902.ComPort := cbCED1902ComPort.itemIndex + 1 ;
     Settings.CED1902.InUse := False ;
     end;


procedure TCED1902Frm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     Main.mnCED1902.Enabled := true ;
     Action := caFree ;
     end;


procedure TCED1902Frm.bCloseClick(Sender: TObject);
begin
     close ;
     end;


procedure TCED1902Frm.EdDCOffsetKeyPress(Sender: TObject; var Key: Char);
{ -------------------------
  Update CED 1902 DC Offset
  -------------------------}
var
   V,VScale,VMax : Single ;
begin
     VMax := VoltsTomV * VMaxDCOffset( Settings.CED1902.Input ) ;
     if key = chr(13) then begin
        VScale :=  VMax / 32767. ;
        V := Settings.CED1902.DCOffset*VScale ;
        V := ExtractFloat( edDCOffset.text, V ) ;
        if V >  VMax then V :=  VMax ;
        if V < -VMax then V := -VMax ;
        Settings.CED1902.DCOffset := Trunc( V/VScale ) ;
        if Settings.CED1902.InUse then SETCED1902( Settings.CED1902 ) ;
        edDCOffset.text := format(' %f mV', [Settings.CED1902.DCOffset*VScale]) ;
        end ;
     end;

end.
