Skip to content

Commit b0dcd0b

Browse files
committed
FFI: Add functions for clamp, headstage and TP control
Added the following functions: FFI_GetClampState returns a wave with the current clamp control values FFI_SetClampMode FFI_SetHoldingPotential - allowed only in VC mode FFI_SetBiasCurrent - allowed only in IC mode FFI_SetAutoBias - allowed only in IC mode FFI_SetHeadstageActive - allowed only when no DAQ is running FFI_SetTestPulseEnable - allowed only when no DAQ is running FFI_TriggerAutoClampControl - wraps Pipette, Capacitance and Bridge Balance auto setting in a single call
1 parent 6268cbd commit b0dcd0b

File tree

1 file changed

+247
-0
lines changed

1 file changed

+247
-0
lines changed

Packages/MIES/MIES_ForeignFunctionInterface.ipf

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
/// @file MIES_ForeignFunctionInterface.ipf
1010
/// @brief __FFI__ ACQ4/ZeroMQ accessible functions
1111

12+
/// @name Auto Clamp Ctrls enum for FFI_TriggerAutoClampControl
13+
/// @anchor FFI_AutoClampCtrls
14+
///@{
15+
static Constant AUTO_PIPETTE = 1
16+
static Constant AUTO_CAPACITANCE = 2
17+
static Constant AUTO_BRIDGEBALANCE = 3
18+
///@}
19+
1220
/// @brief Function to return Peak Resistance, Steady State Resistance to ACQ4 (Neurophysiology Acquisition and Analysis System.
1321
/// See http://acq4.org/ for more details)
1422
///
@@ -323,3 +331,242 @@ Function FFI_TestPulseMDSingleResult(string device, variable action)
323331

324332
return ret
325333
End
334+
335+
/// @brief Returns the clamp state of a headstage of a locked device
336+
///
337+
/// The clamp state wave is DP numeric wave and has 11 elements with the following information
338+
/// - non-applicable values for the current clamp mode are NaN
339+
/// - if the requested head stage is not active then clamp mode returned NaN
340+
///
341+
/// \rst
342+
/// +-------+------------------------+----------------------------+----------+----------+------------+
343+
/// | Index | Label | Value description | Units VC | Units IC | Units I=0 |
344+
/// +=======+========================+============================+==========+==========+============+
345+
/// | 0 | Mode | Clamp Mode | | | |
346+
/// | | | 0 : VC | | | |
347+
/// | | | 1 : IC | | | |
348+
/// | | | 2 : I=0 | | | |
349+
/// | | | NaN : headstage not active | | | |
350+
/// +-------+------------------------+----------------------------+----------+----------+------------+
351+
/// | 1 | HoldingPotential | | mV | pA | pA |
352+
/// +-------+------------------------+----------------------------+----------+----------+------------+
353+
/// | 2 | HoldingPotentialEnable | 1 : On 0: Off | On/Off | On/Off | On/Off |
354+
/// +-------+------------------------+----------------------------+----------+----------+------------+
355+
/// | 3 | BiasCurrent | | mV | pA | pA |
356+
/// +-------+------------------------+----------------------------+----------+----------+------------+
357+
/// | 4 | BiasCurrentEnable | 1 : On 0: Off | On/Off | On/Off | On/Off |
358+
/// +-------+------------------------+----------------------------+----------+----------+------------+
359+
/// | 5 | AutoBiasVcom | | mV | mV | mV |
360+
/// +-------+------------------------+----------------------------+----------+----------+------------+
361+
/// | 6 | AutoBiasVcomVariance | | mV | mV | mV |
362+
/// +-------+------------------------+----------------------------+----------+----------+------------+
363+
/// | 7 | AutoBiasIbiasmax | | pA | pA | pA |
364+
/// +-------+------------------------+----------------------------+----------+----------+------------+
365+
/// | 8 | AutoBiasEnable | 1 : On 0: Off | On/Off | On/Off | On/Off |
366+
/// +-------+------------------------+----------------------------+----------+----------+------------+
367+
/// | 9 | PipetteOffsetVC | | mV | mV | mV |
368+
/// +-------+------------------------+----------------------------+----------+----------+------------+
369+
/// | 10 | PipetteOffsetIC | | mV | mV | mV |
370+
/// +-------+------------------------+----------------------------+----------+----------+------------+
371+
/// \endrst
372+
///
373+
/// @param[in] device Device title, e.g. "Dev1"
374+
/// @param[in] headstage headstage number
375+
/// @returns wave with clamp state
376+
Function/WAVE FFI_GetClampState(string device, variable headstage)
377+
378+
variable clampMode
379+
string stateList = "Mode;HoldingPotential;HoldingPotentialEnable;BiasCurrent;BiasCurrentEnable;AutoBiasVcom;AutoBiasVcomVariance;AutoBiasIbiasmax;AutoBiasEnable;PipetteOffsetVC;PipetteOffsetIC;"
380+
381+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
382+
383+
Make/FREE/D/N=(ItemsInList(stateList)) clampState
384+
385+
SetDimensionLabels(clampState, stateList, ROWS)
386+
FastOp clampState = (NaN)
387+
388+
if(!DAG_GetHeadstageState(device, headstage))
389+
return clampState
390+
endif
391+
392+
clampMode = DAG_GetHeadstageMode(device, headstage)
393+
clampState[%Mode] = clampMode
394+
395+
WAVE/T stateNames = ListToTextWave(stateList, ";")
396+
clampState[1,] = DAG_GetNumericalValue(device, AI_MapFunctionConstantToControl(AI_MapNameToFunctionConstant(stateNames[p]), clampMode))
397+
398+
Duplicate/FREE/T stateNames, units
399+
units[1,] = AI_GetUnitForFunctionConstant(AI_MapNameToFunctionConstant(stateNames[p]), clampMode)
400+
401+
return clampState
402+
End
403+
404+
/// @brief Triggers an auto clamp control
405+
///
406+
/// @param[in] device Device title, e.g. "Dev1"
407+
/// @param[in] headstage headstage number
408+
/// @param[in] autoCtrl auto control number @ref FFI_AutoClampCtrls
409+
Function FFI_TriggerAutoClampControl(string device, variable headstage, variable autoCtrl)
410+
411+
variable clampMode
412+
413+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
414+
415+
clampMode = DAG_GetHeadstageMode(device, headstage)
416+
417+
if(autoCtrl == AUTO_PIPETTE)
418+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_AUTOPIPETTEOFFSET_FUNC, 1, GUIWrite = 0)
419+
elseif(autoCtrl == AUTO_CAPACITANCE)
420+
AI_WriteToAmplifier(device, headstage, V_CLAMP_MODE, MCC_AUTOWHOLECELLCOMP_FUNC, 1, GUIWrite = 0)
421+
elseif(autoCtrl == AUTO_BRIDGEBALANCE)
422+
AI_WriteToAmplifier(device, headstage, I_CLAMP_MODE, MCC_AUTOBRIDGEBALANCE_FUNC, 1, GUIWrite = 0)
423+
else
424+
FATAL_ERROR("Unknown auto clamp control")
425+
endif
426+
End
427+
428+
/// @brief Sets clamp mode
429+
///
430+
/// @param[in] device Device title, e.g. "Dev1"
431+
/// @param[in] headstage headstage number
432+
/// @param[in] clampMode clamp mode @ref AmplifierClampModes
433+
Function FFI_SetClampMode(string device, variable headstage, variable clampMode)
434+
435+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
436+
ASSERT(AI_IsValidClampMode(clampMode), "Invalid clamp mode: " + num2istr(clampMode))
437+
438+
DAP_SetClampMode(device, headstage, clampMode)
439+
End
440+
441+
/// @brief Sets Holding Potential
442+
///
443+
/// @param[in] device Device title, e.g. "Dev1"
444+
/// @param[in] headstage headstage number
445+
/// @param[in] potential holding potential in mV when current clamp mode of headstage is VC, bias current in pA when current clamp mode of headstage is IC
446+
Function FFI_SetHoldingPotential(string device, variable headstage, variable potential)
447+
448+
variable clampMode
449+
450+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
451+
452+
clampMode = DAG_GetHeadstageMode(device, headstage)
453+
ASSERT(clampMode == V_CLAMP_MODE, "Attempt to set holding potential but current clamp mode is not VC !")
454+
ASSERT(!IsNaN(potential), "potential argument is NaN")
455+
456+
FFI_SetHolding(device, headstage, clampMode, potential)
457+
End
458+
459+
/// @brief Sets Bias Current
460+
///
461+
/// @param[in] device Device title, e.g. "Dev1"
462+
/// @param[in] headstage headstage number
463+
/// @param[in] biasCurrent bias current in pA
464+
Function FFI_SetBiasCurrent(string device, variable headstage, variable biasCurrent)
465+
466+
variable clampMode
467+
468+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
469+
470+
clampMode = DAG_GetHeadstageMode(device, headstage)
471+
ASSERT(clampMode == I_CLAMP_MODE, "Attempt to set holding potential but current clamp mode is not IC !")
472+
ASSERT(!IsNaN(biasCurrent), "bias current argument is NaN")
473+
474+
FFI_SetHolding(device, headstage, clampMode, biasCurrent)
475+
End
476+
477+
static Function FFI_SetHolding(string device, variable headstage, variable clampMode, variable value)
478+
479+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_HOLDING_FUNC, value, GUIWrite = 0)
480+
End
481+
482+
static Function FFI_CheckValidDeviceAndHeadstage(string device, variable headstage)
483+
484+
ASSERT(!DAP_DeviceIsUnlocked(device), "Target device is not locked:" + device)
485+
ASSERT(IsValidHeadstage(headstage), "Invalid headStage index: " + num2str(headstage))
486+
End
487+
488+
/// @brief Sets Auto Bias
489+
///
490+
/// @param[in] device Device title, e.g. "Dev1"
491+
/// @param[in] headstage headstage number
492+
/// @param[in] potential Vm in mV in the range -99 mV to 99 mV
493+
/// @param[in] enable when set to 1 then auto bias gets enabled, 0 disabled
494+
Function FFI_SetAutoBias(string device, variable headstage, variable potential, variable enable)
495+
496+
variable clampMode
497+
498+
enable = !!enable
499+
500+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
501+
502+
clampMode = DAG_GetHeadstageMode(device, headstage)
503+
ASSERT(clampMode == I_CLAMP_MODE, "Attempt to set auto bias but current clamp mode is not IC !")
504+
ASSERT(!IsNaN(potential) && potential > -100 && potential < 100, "Potential out of range")
505+
506+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_NO_AUTOBIAS_V_FUNC, potential, GUIWrite = 0)
507+
AI_WriteToAmplifier(device, headstage, clampMode, MCC_NO_AUTOBIAS_ENABLE_FUNC, enable, GUIWrite = 0)
508+
End
509+
510+
/// @brief Enables/Disables a headstage
511+
///
512+
/// The headstage state can not be changed while a data acquisition is running
513+
///
514+
/// @param[in] device Device title, e.g. "Dev1"
515+
/// @param[in] headstage headstage number
516+
/// @param[in] enable when set to 1 the headstage gets enabled, 0 disabled
517+
/// @returns 0 when successful
518+
Function FFI_SetHeadstageActive(string device, variable headstage, variable enable)
519+
520+
string ctrlName
521+
522+
enable = !!enable
523+
524+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
525+
526+
ctrlName = "Check_DataAcqHS_" + num2str(headstage, "%02d")
527+
PGC_SetAndActivateControl(device, ctrlName, val = enable)
528+
529+
return 0
530+
End
531+
532+
/// @brief Enables/Disables a TestPulse
533+
///
534+
/// TestPulse can only be enabled when there is no data acquisition running
535+
///
536+
/// @param[in] device Device title, e.g. "Dev1"
537+
/// @param[in] headstage headstage number
538+
/// @param[in] enable when set to 1 the headstage gets enabled, 0 disabled
539+
/// @returns 0 when successful
540+
Function FFI_SetTestPulseEnable(string device, variable headstage, variable enable)
541+
542+
string ctrlName
543+
variable tpIsRunning
544+
545+
enable = !!enable
546+
547+
FFI_CheckValidDeviceAndHeadstage(device, headstage)
548+
549+
NVAR dataAcqRunMode = $GetDataAcqRunMode(device)
550+
if(dataAcqRunMode != DAQ_NOT_RUNNING)
551+
return 1
552+
endif
553+
554+
tpIsRunning = TP_CheckIfTestpulseIsRunning(device)
555+
if(!enable)
556+
if(tpIsRunning)
557+
TP_StopTestPulse(device)
558+
endif
559+
560+
return 0
561+
endif
562+
563+
if(!tpIsRunning)
564+
if(DAG_GetNumericalValue(device, "check_Settings_MD"))
565+
TPM_StartTestPulseMultiDevice(device)
566+
else
567+
TPS_StartTestPulseSingleDevice(device)
568+
endif
569+
endif
570+
571+
return 0
572+
End

0 commit comments

Comments
 (0)