UniCB cleanup, simulation improved, locking.
This commit is contained in:
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Route: 128-bit word representing the current state of all valves and pumps
|
||||
/// </summary>
|
||||
public UInt128 Route { get { return benchModelRoute; } }
|
||||
|
||||
|
||||
/// UI actions are blocked when true
|
||||
public bool IsUIBlocked { get; set; }
|
||||
|
||||
/// Message queue
|
||||
Queue<Action> actionQueue;
|
||||
|
||||
/// Received data
|
||||
///
|
||||
public GeneralData Data;
|
||||
DivTransitionData divTransitionData;
|
||||
ScopeAnalyzerData scopeAnalyzerData;
|
||||
@@ -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<Action> 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
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -373,15 +364,20 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
/// </summary>
|
||||
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
|
||||
/// <returns>Bits of changed valves are set in the return value</returns>
|
||||
public UInt128 SetValves(UInt128 valvesToOpen, UInt128 valvesToClose, IList<BuiltIn.ValveEx.Valve> 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;
|
||||
|
||||
Reference in New Issue
Block a user