unit TritonPanelUnit;
// ----------------------------------------
// Tecella Triton patch clamp control panel
// ----------------------------------------
// (c) J. Dempster, University of Strathclyde, 2008
// 9.07.08
// 4.09.08 Revised to work with tecellaamp.dll and tested.

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ValidatedEdit, TritonUnit, global, math ;

type
  TTritonPanelFrm = class(TForm)
    ControlsGrp: TGroupBox;
    GroupBox2: TGroupBox;
    edCFast: TValidatedEdit;
    Label2: TLabel;
    sbCfast: TScrollBar;
    Label3: TLabel;
    sbCSlowA: TScrollBar;
    edCSlowA: TValidatedEdit;
    Label4: TLabel;
    sbCslowB: TScrollBar;
    edCSlowB: TValidatedEdit;
    Label5: TLabel;
    sbCSlowC: TScrollBar;
    edCslowC: TValidatedEdit;
    Label6: TLabel;
    sbCslowD: TScrollBar;
    edCslowD: TValidatedEdit;
    Label7: TLabel;
    sbRseries: TScrollBar;
    edRseries: TValidatedEdit;
    Label8: TLabel;
    sbJunctionPot: TScrollBar;
    edJunctionPot: TValidatedEdit;
    Label9: TLabel;
    sbRleak: TScrollBar;
    edRleak: TValidatedEdit;
    GroupBox3: TGroupBox;
    Label1: TLabel;
    cbChannel: TComboBox;
    GroupBox4: TGroupBox;
    Label10: TLabel;
    cbGain: TComboBox;
    cbSource: TComboBox;
    lbSource: TLabel;
    ckCslowA: TCheckBox;
    ckCslowB: TCheckBox;
    ckCslowC: TCheckBox;
    ckCslowD: TCheckBox;
    ckRseries: TCheckBox;
    ckJunctionPot: TCheckBox;
    ckRleak: TCheckBox;
    GroupBox5: TGroupBox;
    Label11: TLabel;
    sbFilter: TScrollBar;
    edFilter: TValidatedEdit;
    bAutoCompensate: TButton;
    bUpdateAllChannels: TButton;
    bClearCompensation: TButton;
    ckCompensationClearAllChannels: TCheckBox;
    bAutoJunctionNull: TButton;
    procedure FormShow(Sender: TObject);
    procedure sbCfastChange(Sender: TObject);
    procedure sbCSlowAChange(Sender: TObject);
    procedure sbCslowBChange(Sender: TObject);
    procedure sbCSlowCChange(Sender: TObject);
    procedure sbCslowDChange(Sender: TObject);
    procedure sbRseriesChange(Sender: TObject);
    procedure sbJunctionPotChange(Sender: TObject);
    procedure sbRleakChange(Sender: TObject);
    procedure cbGainChange(Sender: TObject);
    procedure cbSourceChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure sbFilterChange(Sender: TObject);
    procedure cbChannelChange(Sender: TObject);
    procedure ckCslowAClick(Sender: TObject);
    procedure ckCslowBClick(Sender: TObject);
    procedure ckCslowCClick(Sender: TObject);
    procedure ckCslowDClick(Sender: TObject);
    procedure ckRseriesClick(Sender: TObject);
    procedure ckJunctionPotClick(Sender: TObject);
    procedure ckRleakClick(Sender: TObject);
    procedure bAutoCompensateClick(Sender: TObject);
    procedure bUpdateAllChannelsClick(Sender: TObject);
    procedure bClearCompensationClick(Sender: TObject);
    procedure bAutoJunctionNullClick(Sender: TObject);
  private
    { Private declarations }
    DisableTritonUpdates : Boolean ; // Do not update Triton if TRUE

    procedure TritonGetValueAndEnabled(
              TritonRegister : Integer ;
              iChan : Integer ;
              var EditControl : TValidatedEdit ;
              var SliderControl : TScrollBar ;
              var EnableBox : TCheckBox ) ;

    procedure TritonGetValue(
              TritonRegister : Integer ;
              iChan : Integer ;
              var EditControl : TValidatedEdit ;
              var SliderControl : TScrollBar  ) ;

    procedure TritonSetPercent(
              TritonRegister : Integer ;
              var EditControl : TValidatedEdit ;
              var SliderControl : TScrollBar ) ;
    procedure TritonGetPercent(
              TritonRegister : Integer ;
              var EditControl : TValidatedEdit ;
              var SliderControl : TScrollBar ) ;
    procedure TritonSetEnable(
              TritonEnableRegister : Integer ;
              var EnableBox : TCheckBox ) ;

    procedure SetSlider(
              ScrollBar : TScrollBar ;
              Reg : Integer ) ;

    procedure UpdatePanelControls ;
  public
    { Public declarations }
  end;

var
  TritonPanelFrm: TTritonPanelFrm;

implementation

uses MDIForm, Sealtest;

{$R *.dfm}

procedure TTritonPanelFrm.FormShow(Sender: TObject);
// --------------------------------------
// Initialisations when form is displayed
// --------------------------------------
var
    ch : Integer ;
    Freq : Single ;
begin

     ClientWidth := ControlsGrp.Left + ControlsGrp.Width + 5 ;
     ClientHeight := ControlsGrp.Top + ControlsGrp.Height + 5 ;
     DisableTritonUpdates := False ;

     // Channels
     cbChannel.Clear ;
     for ch := 1 to 8 do  cbChannel.Items.Add(format('Ch.%d',[ch])) ;
     cbChannel.ItemIndex := 0 ;

     // Input source
     Main.SESLabIO.TritonGetSourceList( cbSource.Items ) ;

     // Set slider ranges
     SetSlider( sbCFast, TECELLA_REG_CFAST ) ;
     SetSlider( sbCSLowA, TECELLA_REG_CSLOW_A ) ;
     SetSlider( sbCSLowB, TECELLA_REG_CSLOW_B ) ;
     SetSlider( sbCSLowC, TECELLA_REG_CSLOW_C ) ;
     SetSlider( sbCSLowD, TECELLA_REG_CSLOW_D ) ;
     SetSlider( sbJunctionPot, TECELLA_REG_CHANOFF ) ;
     SetSlider( sbRLeak, TECELLA_REG_LEAK ) ;


     // Input Gain
     cbGain.Clear ;
     cbGain.Items.Add( 'A Low' ) ;
     cbGain.Items.Add( 'B ' ) ;
     cbGain.Items.Add( 'C ' ) ;
     cbGain.Items.Add( 'D High' ) ;

     // Update settings in Triton
     for ch := 0 to High(Settings.Triton.Source) do begin

         // Source
         Settings.Triton.Source[ch] :=  Min(Max(Settings.Triton.Source[ch],0),cbSource.Items.Count-1) ;
         Main.SESLABIO.TritonSource[ch] := Settings.Triton.Source[ch] ;
         if ch = cbChannel.ItemIndex then cbSource.ItemIndex := Settings.Triton.Source[ch] ;

         // Gain
         Settings.Triton.Gain[ch] :=  Min(Max(Settings.Triton.Gain[ch],0),cbGain.Items.Count-1) ;
         Main.SESLABIO.TritonGain[ch] := Settings.Triton.Gain[ch] ;
         if ch = cbChannel.ItemIndex then cbGain.ItemIndex := Settings.Triton.Gain[ch] ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CFAST,ch,Settings.Triton.CFAST[ch]) ;

         Main.SESLABIO.SetTritonBesselFilter( ch, Round(Settings.Triton.BESSEL[ch]), Freq ) ;
         if ch = cbChannel.ItemIndex then edFilter.Value := Freq ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_A,ch,Settings.Triton.CSLOW_A[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_A,ch,Settings.Triton.CSLOW_AEnabled[ch]) ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_B,ch,Settings.Triton.CSLOW_B[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_B,ch,Settings.Triton.CSLOW_BEnabled[ch]) ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_C,ch,Settings.Triton.CSLOW_C[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_C,ch,Settings.Triton.CSLOW_CEnabled[ch]) ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_D,ch,Settings.Triton.CSLOW_D[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_D,ch,Settings.Triton.CSLOW_DEnabled[ch]) ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_RSERIES,ch,Settings.Triton.RSERIES[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_RSERIES,ch,Settings.Triton.RSERIESEnabled[ch]) ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CHANOFF,ch,Settings.Triton.CHANOFF[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CHANOFF,ch,Settings.Triton.CHANOFFEnabled[ch]) ;

         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_LEAK,ch,Settings.Triton.LEAK[ch]) ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_LEAK,ch,Settings.Triton.LEAKEnabled[ch]) ;

         end ;

     // Update panel controls for selected channel
     UpdatePanelControls ;

     DisableTritonUpdates := False ;

     end ;


procedure TTritonPanelFrm.SetSlider(
          ScrollBar : TScrollBar ;
          Reg : Integer ) ;
// ------------------
// Set slider control
// ------------------
var
    VMin,VMax,VStep : Single ;
    CanBeDisabled : Boolean ;
begin

    Main.SESLabIO.TritonGetRegProperties (Reg, VMin,Vmax,VStep,CanBeDisabled) ;
    ScrollBar.Max := Round((VMax - VMin)/VStep) ;
    ScrollBar.Min := 0 ;
    ScrollBar.LargeChange := 10 ;

    end ;



procedure TTritonPanelFrm.UpdatePanelControls ;
// ------------------------------------------
// Update panel controls for selected channel
// ------------------------------------------
var
    Value : Single ;
begin

     DisableTritonUpdates := True ;

     cbSource.ItemIndex := Settings.Triton.Source[cbChannel.ItemIndex] ;
     cbGain.ItemIndex := Settings.Triton.Gain[cbChannel.ItemIndex] ;

     TritonGetValue( TECELLA_REG_CFAST,cbChannel.ItemIndex,edCFast,sbCFast) ;
     TritonGetValueAndEnabled(TECELLA_REG_CSLOW_A,cbChannel.ItemIndex,edCSlowA,sbCSlowA,ckCSlowA) ;
     TritonGetValueAndEnabled(TECELLA_REG_CSLOW_B,cbChannel.ItemIndex,edCSlowB,sbCSlowB,ckCSlowB) ;
     TritonGetValueAndEnabled(TECELLA_REG_CSLOW_C,cbChannel.ItemIndex,edCSlowC,sbCSlowC,ckCSlowC) ;
     TritonGetValueAndEnabled(TECELLA_REG_CSLOW_D,cbChannel.ItemIndex,edCSlowD,sbCSlowD,ckCSlowD) ;
     TritonGetValueAndEnabled(TECELLA_REG_RSERIES,cbChannel.ItemIndex,edRSERIES,sbRSERIES,ckRSERIES) ;
     TritonGetValueAndEnabled(TECELLA_REG_LEAK,cbChannel.ItemIndex,edRLEAK,sbRLEAK,ckRLEAK) ;
     TritonGetValueAndEnabled(TECELLA_REG_CHANOFF,cbChannel.ItemIndex,edJunctionPot,sbJunctionPot,ckJunctionPot) ;

     sbFilter.Position := Round(Settings.Triton.BESSEL[cbChannel.ItemIndex]) ;
     Main.SESLabIO.SetTritonBesselFilter( cbChannel.ItemIndex, sbFilter.Position, Value ) ;
     edFilter.Value := Value ;

     DisableTritonUpdates := False ;

     end ;


procedure TTritonPanelFrm.TritonGetValueAndEnabled(
          TritonRegister : Integer ;
          iChan : Integer ;
          var EditControl : TValidatedEdit ;
          var SliderControl : TScrollBar ;
          var EnableBox : TCheckBox ) ;
// --------------------------------------------------
// Get current value of selected register from Triton
// --------------------------------------------------
var
    Value,PercentValue : Single ;
    Enabled : Boolean ;
begin

     Main.SESLABIO.TritonGetReg( TritonRegister, cbChannel.ItemIndex, Value, PercentValue, Enabled ) ;
     SliderControl.Position :=  Round(PercentValue*0.01*SliderControl.Max) ;
     EditControl.Value := Value ;
     EnableBox.Checked := Enabled ;

     end ;


procedure TTritonPanelFrm.TritonGetValue(
          TritonRegister : Integer ;
          iChan : Integer ;
          var EditControl : TValidatedEdit ;
          var SliderControl : TScrollBar  ) ;
// --------------------------------------------------
// Get current value of selected register from Triton
// --------------------------------------------------
var
    Value,PercentValue : Single ;
    Enabled : Boolean ;
begin

     Main.SESLABIO.TritonGetReg( TritonRegister, cbChannel.ItemIndex, Value, PercentValue, Enabled ) ;
     EditControl.Value := Value ;
     SliderControl.Position :=  Round(PercentValue*0.01*SliderControl.Max) ;

     end ;



procedure TTritonPanelFrm.TritonSetEnable(
          TritonEnableRegister : Integer ;
          var EnableBox : TCheckBox ) ;
// --------------------------------------------------
// Set enable state of selected register from Triton
// --------------------------------------------------
begin

     // Set enabled state
     if not DisableTritonUpdates then begin
         Main.SESLABIO.TritonSetRegEnabled(
                                      TritonEnableRegister,
                                      cbChannel.ItemIndex,
                                      EnableBox.Checked ) ;
         end ;

      EnableBox.Checked := Main.SESLABIO.TritonGetRegEnabled(
                                      TritonEnableRegister,
                                      cbChannel.ItemIndex ) ;
     end ;


procedure TTritonPanelFrm.TritonSetPercent(
          TritonRegister : Integer ;
          var EditControl : TValidatedEdit ;
          var SliderControl : TScrollBar  ) ;
// --------------------------------------------------
// Set current value of selected register from Triton
// --------------------------------------------------
var
    Value,PercentValue : Single ;
    Enabled : Boolean ;
begin

     PercentValue := (SliderControl.Position/SliderControl.Max)*100.0 ;

     // Set register
     if not DisableTritonUpdates then begin
        Main.SESLABIO.TritonSetRegPercent( TritonRegister,
                                           cbChannel.ItemIndex,
                                           PercentValue ) ;
        end ;

     // Get actual value set back
     Main.SESLABIO.TritonGetReg( TritonRegister, cbChannel.ItemIndex, Value, PercentValue, Enabled ) ;

     EditControl.Value := Value ;

     end ;


procedure TTritonPanelFrm.TritonGetPercent(
          TritonRegister : Integer ;
          var EditControl : TValidatedEdit ;
          var SliderControl : TScrollBar  ) ;
// --------------------------------------------------
// Get current value of selected register from Triton
// --------------------------------------------------
var
    Value,PercentValue : Single ;
    Enabled : Boolean ;
begin

     PercentValue := SliderControl.Position ;

     // Get actual value set back
     Main.SESLABIO.TritonGetReg( TritonRegister, cbChannel.ItemIndex, Value, PercentValue, Enabled ) ;

     EditControl.Value := Value ;

     end ;



procedure TTritonPanelFrm.sbCfastChange(Sender: TObject);
begin
    TritonSetPercent( TECELLA_REG_CFAST, edCFast, sbCFast ) ;
    Settings.Triton.CFAST[cbChannel.ItemIndex] := (sbCFast.Position*100.0)/sbCFast.Max ;
    end;


procedure TTritonPanelFrm.sbCSlowAChange(Sender: TObject);
begin
     TritonSetPercent( TECELLA_REG_CSLOW_A, edCSlowA, sbCSlowA ) ;
     Settings.Triton.CSLOW_A[cbChannel.ItemIndex] := (sbCSLOWA.Position*100.0)/sbCSLOWA.Max ;
     end;


procedure TTritonPanelFrm.sbCslowBChange(Sender: TObject);
begin
     TritonSetPercent( TECELLA_REG_CSLOW_B, edCSlowB, sbCSlowB ) ;
     Settings.Triton.CSLOW_B[cbChannel.ItemIndex] := (sbCSLOWB.Position*100.0)/sbCSLOWB.Max ;
     end;


procedure TTritonPanelFrm.sbCSlowCChange(Sender: TObject);
begin
     TritonSetPercent( TECELLA_REG_CSLOW_C, edCSlowC, sbCSlowC ) ;
     Settings.Triton.CSLOW_C[cbChannel.ItemIndex] := (sbCSLOWC.Position*100.0)/sbCSLOWC.Max ;
     end;


procedure TTritonPanelFrm.sbCslowDChange(Sender: TObject);
begin
     TritonSetPercent( TECELLA_REG_CSLOW_D, edCSlowD, sbCSlowD ) ;
     Settings.Triton.CSLOW_D[cbChannel.ItemIndex] := (sbCSLOWD.Position*100.0)/sbCSLOWD.Max ;
     end;

procedure TTritonPanelFrm.sbRseriesChange(Sender: TObject);
begin
     TritonSetPercent( TECELLA_REG_RSERIES, edRseries, sbRseries ) ;
     Settings.Triton.RSERIES[cbChannel.ItemIndex] := (sbRSeries.Position*100.0)/sbRSeries.Max ;
     end;

procedure TTritonPanelFrm.sbJunctionPotChange(Sender: TObject);
begin
     TritonSetPercent( TECELLA_REG_CHANOFF, edJunctionPot, sbJunctionPot ) ;
     Settings.Triton.CHANOFF[cbChannel.ItemIndex] := (sbJunctionPot.Position*100.0)/sbJunctionPot.Max ;
     end;

procedure TTritonPanelFrm.sbRleakChange(Sender: TObject);
begin
    TritonSetPercent( TECELLA_REG_LEAK, edRleak, sbRleak ) ;
    Settings.Triton.LEAK[cbChannel.ItemIndex] := (sbRLeak.Position*100.0)/sbRLeak.Max ;
    end;

procedure TTritonPanelFrm.cbGainChange(Sender: TObject);
// -----------------------------------------
// Gain resistir for selected channel changed
// -----------------------------------------
begin
     Main.SESLABIO.TritonGain[cbChannel.ItemIndex] := cbGain.ItemIndex ;
     Settings.Triton.Gain[cbChannel.ItemIndex] := cbGain.ItemIndex ;
     end;


procedure TTritonPanelFrm.cbSourceChange(Sender: TObject);
// -----------------------------------------
// Input source for selected channel changed
// -----------------------------------------
begin
     Main.SESLABIO.TritonSource[cbChannel.ItemIndex] := cbSource.ItemIndex ;
     Settings.Triton.Source[cbChannel.ItemIndex] := cbSource.ItemIndex ;
     end;


procedure TTritonPanelFrm.FormClose(Sender: TObject;
  var Action: TCloseAction);
// ----------------------
// Tidy up and close form
// ----------------------
begin
     Action := caFree ;
     end;


procedure TTritonPanelFrm.sbFilterChange(Sender: TObject);
// ----------------------------------------------
// Update Bessel filter cut-off frequency setting
// ----------------------------------------------

var
    Freq : Single ;
    ch : Integer ;
begin

    // BUG workaround! For some reason, a register must be set to the selected channel before
    // the call to SetTritonBesselFilter to ensure that the correct Triton channel bessel filter is updated
    Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CFAST,cbChannel.ItemIndex,Settings.Triton.CFAST[cbChannel.ItemIndex]) ;

    // Set bessel filter
    Settings.Triton.Bessel[cbChannel.ItemIndex] := sbFilter.Position ;
    Main.SESLabIO.SetTritonBesselFilter( cbChannel.ItemIndex,
                                         sbFilter.Position,
                                         Freq ) ;

    edFilter.Value := Freq ;

    end;


procedure TTritonPanelFrm.cbChannelChange(Sender: TObject);
// -------------------------------
// Selected Triton channel changed
// -------------------------------
begin
     UpdatePanelControls ;
     end;


procedure TTritonPanelFrm.ckCslowAClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_CSLOW_A, ckCslowA ) ;
    Settings.Triton.CSLOW_AEnabled[cbChannel.ItemIndex] := ckCslowA.Checked ;
    end;


procedure TTritonPanelFrm.ckCslowBClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_CSLOW_B, ckCslowB ) ;
    Settings.Triton.CSLOW_BEnabled[cbChannel.ItemIndex] := ckCslowB.Checked ;
    end;


procedure TTritonPanelFrm.ckCslowCClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_CSLOW_C, ckCslowC ) ;
    Settings.Triton.CSLOW_CEnabled[cbChannel.ItemIndex] := ckCslowC.Checked ;
    end;


procedure TTritonPanelFrm.ckCslowDClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_CSLOW_D, ckCslowD ) ;
    Settings.Triton.CSLOW_DEnabled[cbChannel.ItemIndex] := ckCslowD.Checked ;
    end;


procedure TTritonPanelFrm.ckRseriesClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_RSERIES, ckRSERIES ) ;
    Settings.Triton.RSERIESEnabled[cbChannel.ItemIndex] := ckRSERIES.Checked ;
    end;


procedure TTritonPanelFrm.ckJunctionPotClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_CHANOFF, ckJunctionPot ) ;
    Settings.Triton.CHANOFFEnabled[cbChannel.ItemIndex] := ckJunctionPot.Checked ;
    end;


procedure TTritonPanelFrm.ckRleakClick(Sender: TObject);
begin
    TritonSetEnable( TECELLA_REG_LEAK, ckRleak ) ;
    Settings.Triton.LEAKEnabled[cbChannel.ItemIndex] := ckRleak.Checked ;
    end;


procedure TTritonPanelFrm.bAutoCompensateClick(Sender: TObject);
// --------------------------------------------------------------
// Apply automatic capacity/leak compensation to selected channel
// --------------------------------------------------------------
var
    ch : Integer ;
    Enabled : Boolean ;
    Value : Single ;
begin

     // Stop seal test
     if Main.FormExists( 'SealTestFrm' ) then SealTestFrm.StopADCAndDAC ;

     bAutoCompensate.Enabled := False ;

     Screen.Cursor := crHourGlass ;

     // Apply compensation
     Main.SESLabIO.TritonAutoCompensation( ckCSlowA.Checked,
                                           ckCSlowB.Checked,
                                           ckCSlowC.Checked,
                                           ckCSlowD.Checked,
                                           ckRLeak.Checked ) ;

     // Update settings
     for ch := 0 to High(Settings.Triton.Source) do begin
        Main.SESLABIO.TritonGetReg(TECELLA_REG_CFAST,ch,Value,Settings.Triton.CFAST[ch],Enabled) ;

        Main.SESLABIO.TritonGetreg(TECELLA_REG_CSLOW_A,ch,Value,Settings.Triton.CSLOW_A[ch],
                                       Settings.Triton.CSLOW_AEnabled[ch]) ;
        Main.SESLABIO.TritonGetreg(TECELLA_REG_CSLOW_B,ch,Value,Settings.Triton.CSLOW_B[ch],
                                       Settings.Triton.CSLOW_BEnabled[ch]) ;
        Main.SESLABIO.TritonGetreg(TECELLA_REG_CSLOW_C,ch,Value,Settings.Triton.CSLOW_C[ch],
                                       Settings.Triton.CSLOW_CEnabled[ch]) ;
        Main.SESLABIO.TritonGetreg(TECELLA_REG_CSLOW_D,ch,Value,Settings.Triton.CSLOW_D[ch],
                                       Settings.Triton.CSLOW_DEnabled[ch]) ;

        Main.SESLABIO.TritonGetreg(TECELLA_REG_RSERIES,ch,Value,Settings.Triton.RSERIES[ch],
                                        Settings.Triton.RSERIESEnabled[ch]  ) ;
        Main.SESLABIO.TritonGetreg(TECELLA_REG_CHANOFF,ch,Value,Settings.Triton.CHANOFF[ch],
                                       Settings.Triton.CHANOFFEnabled[ch]   ) ;
        Main.SESLABIO.TritonGetreg(TECELLA_REG_LEAK,ch,Value,Settings.Triton.LEAK[ch],
                                       Settings.Triton.LEAKEnabled[ch]) ;
        end ;

     UpdatePanelControls ;

     Screen.Cursor := crDefault ;

     // Restart seal test
     if Main.FormExists( 'SealTestFrm' ) then SealTestFrm.Show ;

     bAutoCompensate.Enabled := True ;

     end;

procedure TTritonPanelFrm.bUpdateAllChannelsClick(Sender: TObject);
// --------------------------------------------------
// Make all channel settings same as selected channel
// --------------------------------------------------
var
    ch : Integer ;
    Freq : Single ;
begin

     // Update settings in Triton
     for ch := 0 to High(Settings.Triton.Source) do begin

         // Source
         Settings.Triton.Source[ch] :=  Min(Max(Settings.Triton.Source[cbChannel.ItemIndex],0),cbSource.Items.Count-1) ;
         Main.SESLABIO.TritonSource[ch] := Settings.Triton.Source[ch] ;
         if ch = cbChannel.ItemIndex then cbSource.ItemIndex := Settings.Triton.Source[ch] ;

         // Gain
         Settings.Triton.Gain[ch] :=  Min(Max(Settings.Triton.Gain[cbChannel.ItemIndex],0),cbGain.Items.Count-1) ;
         Main.SESLABIO.TritonGain[ch] := Settings.Triton.Gain[ch] ;
         if ch = cbChannel.ItemIndex then cbGain.ItemIndex := Settings.Triton.Gain[ch] ;

         Settings.Triton.CFAST[ch] := Settings.Triton.CFAST[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CFAST,ch,Settings.Triton.CFAST[ch]) ;

         Settings.Triton.BESSEL[ch] := Settings.Triton.BESSEL[cbChannel.ItemIndex] ;
         Main.SESLABIO.SetTritonBesselFilter( ch, Round(Settings.Triton.BESSEL[ch]), Freq ) ;

         Settings.Triton.CSLOW_A[ch] := Settings.Triton.CSLOW_A[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_A,ch,Settings.Triton.CSLOW_A[ch]) ;

         Settings.Triton.CSLOW_AEnabled[ch] := Settings.Triton.CSLOW_AEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_A,ch,Settings.Triton.CSLOW_AEnabled[ch]) ;

         Settings.Triton.CSLOW_B[ch] := Settings.Triton.CSLOW_B[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_B,ch,Settings.Triton.CSLOW_B[ch]) ;

         Settings.Triton.CSLOW_BEnabled[ch] := Settings.Triton.CSLOW_BEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_B,ch,Settings.Triton.CSLOW_BEnabled[ch]) ;

         Settings.Triton.CSLOW_C[ch] := Settings.Triton.CSLOW_C[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_C,ch,Settings.Triton.CSLOW_C[ch]) ;

         Settings.Triton.CSLOW_CEnabled[ch] := Settings.Triton.CSLOW_CEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_C,ch,Settings.Triton.CSLOW_CEnabled[ch]) ;

         Settings.Triton.CSLOW_D[ch] := Settings.Triton.CSLOW_D[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_D,ch,Settings.Triton.CSLOW_D[ch]) ;

         Settings.Triton.CSLOW_DEnabled[ch] := Settings.Triton.CSLOW_DEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CSLOW_D,ch,Settings.Triton.CSLOW_DEnabled[ch]) ;

         Settings.Triton.RSERIES[ch] := Settings.Triton.RSERIES[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_RSERIES,ch,Settings.Triton.RSERIES[ch]) ;
         Settings.Triton.RSERIESEnabled[ch] := Settings.Triton.RSERIESEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_RSERIES,ch,Settings.Triton.RSERIESEnabled[ch]) ;

         Settings.Triton.CHANOFF[ch] := Settings.Triton.CHANOFF[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CHANOFF,ch,Settings.Triton.CHANOFF[ch]) ;
         Settings.Triton.CHANOFFEnabled[ch] := Settings.Triton.CHANOFFEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_CHANOFF,ch,Settings.Triton.CHANOFFEnabled[ch]) ;

         Settings.Triton.LEAK[ch] := Settings.Triton.LEAK[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_LEAK,ch,Settings.Triton.LEAK[ch]) ;
         Settings.Triton.LEAKEnabled[ch] := Settings.Triton.LEAKEnabled[cbChannel.ItemIndex] ;
         Main.SESLABIO.TritonSetRegEnabled(TECELLA_REG_LEAK,ch,Settings.Triton.LEAKEnabled[ch]) ;

         end ;

end;

procedure TTritonPanelFrm.bClearCompensationClick(Sender: TObject);
// ---------------------------
// Clear capacity compensation
// ---------------------------
var
    ch : Integer ;
begin

     for ch := 0 to High(Settings.Triton.Source) do
        if ckCompensationClearAllChannels.Checked or (ch = cbChannel.ItemIndex) then begin

        Settings.Triton.CFAST[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CFAST,ch,Settings.Triton.CFAST[ch]) ;

        Settings.Triton.CSLOW_A[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_A,ch,Settings.Triton.CSLOW_A[ch]) ;

        Settings.Triton.CSLOW_B[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_B,ch,Settings.Triton.CSLOW_B[ch]) ;

        Settings.Triton.CSLOW_C[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_C,ch,Settings.Triton.CSLOW_C[ch]) ;

        Settings.Triton.CSLOW_D[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CSLOW_D,ch,Settings.Triton.CSLOW_D[ch]) ;

        Settings.Triton.RSERIES[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_RSERIES,ch,Settings.Triton.RSERIES[ch]) ;

        Settings.Triton.CHANOFF[ch] := 50 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_CHANOFF,ch,Settings.Triton.CHANOFF[ch]) ;

        Settings.Triton.LEAK[ch] := 0 ;
        Main.SESLABIO.TritonSetRegPercent(TECELLA_REG_LEAK,ch,Settings.Triton.LEAK[ch]) ;

        end ;

     UpdatePanelControls ;

     end;

procedure TTritonPanelFrm.bAutoJunctionNullClick(Sender: TObject);
// --------------------------------------------------------------
// Apply automatic junction potential null
// --------------------------------------------------------------
var
    ch : Integer ;
    Enabled : Boolean ;
    Value : Single ;
begin

     // Stop seal test
     if Main.FormExists( 'SealTestFrm' ) then SealTestFrm.StopADCAndDAC ;

     bAutoJunctionNull.Enabled := False ;

     Screen.Cursor := crHourGlass ;

     // Apply compensation
     Main.SESLabIO.TritonJPAutoZero ;

     // Update settings
     for ch := 0 to High(Settings.Triton.Source) do begin
        Main.SESLABIO.TritonGetreg(TECELLA_REG_CHANOFF,ch,Value,Settings.Triton.CHANOFF[ch],
                                       Settings.Triton.CHANOFFEnabled[ch]   ) ;
        end ;

     UpdatePanelControls ;

     Screen.Cursor := crDefault ;

     // Restart seal test
     if Main.FormExists( 'SealTestFrm' ) then SealTestFrm.Show ;

     bAutoJunctionNull.Enabled := True ;

     end;


end.
