diff --git a/TBF/Rig/ControlBoard/Uni/UniCB.cs b/TBF/Rig/ControlBoard/Uni/UniCB.cs
index dabff3598..e6325cef8 100644
--- a/TBF/Rig/ControlBoard/Uni/UniCB.cs
+++ b/TBF/Rig/ControlBoard/Uni/UniCB.cs
@@ -83,57 +83,14 @@ namespace TBF.Rig.ControlBoard.Uni
const int BUFFER_SIZE = 4000; /// Size of input buffers
byte[] buffer; /// Buffer for data received in one attempt in RunDeviceBefore()
byte[] rcvdData; /// Buffer for all recevied but nut processed data. May contain data from several read attempts
- int[] cumulativeSums;
+ int[] cumulativeSums; /// Cumulative sums to verify checksums easily
int rcvdBytesCount; /// Count of valid bytes in rcvdData buffer
int lastReceivedTime; /// StateMachine.Time time stamp of the last received valid frame
+ bool outputsInitialized; /// Flag indicating that outputs were sent at least once
///
- /// Route / digital outputs / states of electromagnetic valves
- ///
- readonly UInt128 routeMask; /// Set in the constructor, bits of outputs that can be controlled by Action.ChangeRoute are set.
- /// Regulation valve control outputs and diverters cannot be controlled by Action.ChangeRoute
- /// Depends on the control board configuration
-
- ulong valvesToInvert; /// From configurations of valve and pump components. Inversion is applied when creating
- /// Action.ChangeRoute an dafter obtaining RRoute from the control board
-
- /// State of digital outputs obtained from the control board
- public UInt128 RRoute
- {
- get
- {
- if ((StateMachine.Time - lastReceivedTime) < 5)
- {
- return (UInt128)(Data.Vystupy ^ valvesToInvert);
- }
- else
- {
- return ((UInt128)1) << cbCfg.BitNr; /// No connection to control board
- }
- }
- }
-
- UInt128 displayedRoute; /// A route displayed on the screen (inversions are not applied)
- UInt128 bitsChangedByUI; /// Ones in this word indicate which valves/pumpes were changed in UI by mouse clicks
- UInt128 displayedRoutePlusUI; /// A route displayed on the screen plus the modifications from UI (inversions are not applied)
- UInt128 outputLatch; /// A copy of route sent to physical outputs
- UInt128 benchModelRoute;
- bool outputsInitialized;
- int lastStateMachineTime = 0;
-
- ///
- /// Route: 128-bit word representing the current state of all valves and pumps
- ///
- public UInt128 Route { get { return benchModelRoute; } }
-
-
- /// UI actions are blocked when true
- public bool IsUIBlocked { get; set; }
-
- /// Message queue
- Queue actionQueue;
-
/// Received data
+ ///
public GeneralData Data;
DivTransitionData divTransitionData;
ScopeAnalyzerData scopeAnalyzerData;
@@ -143,7 +100,7 @@ namespace TBF.Rig.ControlBoard.Uni
/// Current flow meter ID
public int FlowmeterId { get { return Convert.ToInt32(Data.State & (ulong)StatusP.FlowmtrNrMask); } }
-
+
public UInt64 DigitalInputs { get { return Data.Vstupy; } } /// Digital inputs
public Int16 AnalogInput(int channel)
@@ -152,10 +109,36 @@ namespace TBF.Rig.ControlBoard.Uni
{
return Data.AnalogInput[channel];
}
- return 0;
+ else return 0;
}
- /// Values valid during a test
+ ///
+ /// Digital outputs / Route / States of electromagnetic valves
+ ///
+ readonly UInt128 routeMask; /// Set in the constructor, bits of outputs that can be controlled by Action.ChangeRoute are set.
+ /// Regulation valve control outputs and diverters cannot be controlled by Action.ChangeRoute
+ /// Depends on the control board configuration
+ ulong valvesToInvert; /// From configurations of valve and pump components. Inversion is applied when creating
+ /// a message to be sent by serial port
+ UInt128 displayedRoute; /// A route displayed on the screen (inversions are not applied)
+ UInt128 bitsChangedByUI; /// Ones in this word indicate which valves/pumpes were changed in UI by mouse clicks
+ UInt128 displayedRoutePlusUI; /// A route displayed on the screen plus the modifications from UI (inversions are not applied)
+ UInt128 outputLatch; /// A copy of data sent to physical digital outputs (inversions are not applied)
+ ///
+ /// 128-bit word representing the current state of all valves and pumps (inversions are not applied)
+ ///
+ UInt128 route;
+ public UInt128 Route { get { return route; } }
+
+ ///
+ /// Queue of higher level commands for the control board
+ ///
+ Queue actionQueue;
+
+ /// UI actions are blocked when true
+ public bool IsUIBlocked { get; set; }
+
+ /// Measured values valid during a test
public double RefFrequency { get { return Data.ReferenceFreq[0]; } }
public double RefFrequency1 { get { return Data.ReferenceFreq[1]; } }
public double RefFrequency2 { get { return Data.ReferenceFreq[2]; } }
@@ -252,19 +235,14 @@ namespace TBF.Rig.ControlBoard.Uni
/// Handler handling mouse clicks on the schematc drawinng - valve or pump state changes
TBF.UiBridge.Bridge.RouteChangeHandler += delegate(object sndr, TBF.UiBridge.RouteChangeArgs args)
- {
- UInt128 oneBitMask = ((UInt128)1) << args.BitNr;
- bitsChangedByUI |= oneBitMask;
- displayedRoutePlusUI = displayedRoutePlusUI ^ oneBitMask;
- //if ((displayedRoutePlusUI & oneBitMask) == 0)
- //{
- // displayedRoutePlusUI |= oneBitMask;
- //}
- //else
- //{
- // displayedRoutePlusUI &= (~oneBitMask);
- //}
- };
+ {
+ UInt128 oneBitMask = ((UInt128)1) << args.BitNr;
+ lock (this)
+ {
+ bitsChangedByUI |= oneBitMask;
+ displayedRoutePlusUI = displayedRoutePlusUI ^ oneBitMask;
+ }
+ };
log.FatalFormat("{0} - Device successfully initialized", Name);
}
@@ -274,6 +252,9 @@ namespace TBF.Rig.ControlBoard.Uni
///
public void RunDeviceBefore()
{
+ ///
+ /// Read data from the control board
+ ///
if (cbCfg.DebugLevel == DebugMode.Normal && serialPort != null && serialPort.IsOpen)
{
/// Read new received bytes and append them to a buffer
@@ -357,15 +338,25 @@ namespace TBF.Rig.ControlBoard.Uni
rcvdBytesCount -= lastValidOffset;
}
- benchModelRoute = RRoute;
///
- if (!IsUIBlocked && bitsChangedByUI != 0)
+ /// Combine data from the current route, from digital outputs and from UI
+ ///
+ lock (this)
{
- benchModelRoute = (benchModelRoute & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
- bitsChangedByUI = 0;
+ route = (UInt128)(Data.Vystupy ^ valvesToInvert);
+ ///
+ if (!IsUIBlocked && bitsChangedByUI != 0)
+ {
+ route = (route & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
+ bitsChangedByUI = 0;
+ }
+ if ((StateMachine.Time - lastReceivedTime) >= 5)
+ {
+ /// No connection to control board ... set indicator bit
+ route += ((UInt128)1) << cbCfg.BitNr;
+ }
}
-
- log.DebugFormat("Route synced with RRoute and UI changes, new route = {0}", Utils.RouteToStr(benchModelRoute));
+ log.DebugFormat("Route synced with RRoute and UI changes, new route = {0}", Utils.RouteToStr(route));
}
///
@@ -373,15 +364,20 @@ namespace TBF.Rig.ControlBoard.Uni
///
public void RunDeviceAfter()
{
- /// Synchronize benchModelRoute with RRoute
- if (!IsUIBlocked && bitsChangedByUI != 0)
+ ///
+ /// Combine data from the current route and from UI
+ ///
+ lock (this)
{
- benchModelRoute = (benchModelRoute & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
+ if (!IsUIBlocked && bitsChangedByUI != 0)
+ {
+ route = (route & ~bitsChangedByUI) | (displayedRoutePlusUI & bitsChangedByUI);
+ bitsChangedByUI = 0;
+ }
+ displayedRoute = route;
+ displayedRoutePlusUI = route;
bitsChangedByUI = 0;
}
- displayedRoute = Route;
- displayedRoutePlusUI = Route;
- bitsChangedByUI = 0;
ProcessData.UpdateMeasuredValuesAndSetpoints();
Bridge.OnStateMachineTick(this, new StateMachineTickEventArgs(displayedRoute, ProcessData.MsrmntAvailableFlags, ProcessData.MeasuredValues,
ProcessData.AltStrings, ProcessData.Setpoints));
@@ -405,7 +401,7 @@ namespace TBF.Rig.ControlBoard.Uni
}
}
- if (!outputsInitialized || (outputLatch & routeMask) != (benchModelRoute & routeMask)) /// || (StateMachine.Time - lastStateMachineTime) >= 15)
+ if (!outputsInitialized || (outputLatch & routeMask) != (route & routeMask)) /// || (StateMachine.Time - lastStateMachineTime) >= 15)
{
var actionsToModify = actionQueue.Where(x => (x.ActionId == ActionID.ChangeRoute));
bool oneModified = false;
@@ -418,14 +414,14 @@ namespace TBF.Rig.ControlBoard.Uni
}
oneModified = true;
- a.Route = (ulong)benchModelRoute;
- log.InfoFormat("ChangeRoute(route={0:X}) ... an action in the queue modified", benchModelRoute);
+ a.Route = (ulong)route;
+ log.InfoFormat("ChangeRoute(route={0:X}) ... an action in the queue modified", route);
}
if (!oneModified)
{
- actionQueue.Enqueue(Action.ChangeRoute(false, (ulong)benchModelRoute));
- log.InfoFormat("ChangeRoute(route={0:X}) ... a new action enqueued", (ulong)benchModelRoute);
+ actionQueue.Enqueue(Action.ChangeRoute(false, (ulong)route));
+ log.InfoFormat("ChangeRoute(route={0:X}) ... a new action enqueued", (ulong)route);
}
foreach (var a in actionQueue) log.DebugFormat(" {0}", a);
@@ -440,10 +436,16 @@ namespace TBF.Rig.ControlBoard.Uni
{
outputsInitialized = true;
outputLatch = combinedAction.Route;
- lastStateMachineTime = StateMachine.Time;
+ if (cbCfg.DebugLevel != DebugMode.Normal)
+ {
+ Data.Vystupy = combinedAction.Route ^ valvesToInvert;
+ }
}
- if (cbCfg.DebugLevel == DebugMode.Normal) serialPort.Write(outData, 0, outData.Length);
+ if (cbCfg.DebugLevel == DebugMode.Normal)
+ {
+ serialPort.Write(outData, 0, outData.Length);
+ }
string s = Telegram.LogTelegram("Sent: ", outData);
Debug.WriteLine(s);
@@ -506,11 +508,11 @@ namespace TBF.Rig.ControlBoard.Uni
/// Bits of changed valves are set in the return value
public UInt128 SetValves(UInt128 valvesToOpen, UInt128 valvesToClose, IList logicalFnValves)
{
- UInt128 oldRoute = benchModelRoute;
- benchModelRoute = (benchModelRoute | valvesToOpen) & (~valvesToClose);
- foreach (var logFnV in logicalFnValves) logFnV.UpdateRoute(ref benchModelRoute);
- log.DebugFormat("SetValves(x,x), new route = {0}", Utils.RouteToStr(benchModelRoute));
- UInt128 retVal = oldRoute ^ benchModelRoute;
+ UInt128 oldRoute = route;
+ route = (route | valvesToOpen) & (~valvesToClose);
+ foreach (var logFnV in logicalFnValves) logFnV.UpdateRoute(ref route);
+ log.DebugFormat("SetValves(x,x), new route = {0}", Utils.RouteToStr(route));
+ UInt128 retVal = oldRoute ^ route;
log.DebugFormat("{0}.SetValves({1}, {2}) returns {3}", Name, valvesToOpen.ToString("X"), valvesToClose.ToString("X"), retVal.ToString("X"));
return retVal;