// <CONSTRUCTORS> /// <summary> /// Initializes port but does not open it /// </summary> public COM() { // serial port port = new SerialPort(); port.Parity = Global.Parity; port.StopBits = Global.StopBits; port.ReadTimeout = readTimeout; port.WriteTimeout = Global.WriteTimeout; port.BaudRate = Global.BaudRate; port.DataBits = Global.DataBits; port.NewLine = Global.NewLine; // asynchronous transaction processing comWorker.WorkerReportsProgress = false; comWorker.WorkerSupportsCancellation = true; comWorker.DoWork += ComWorker_DoWork; comWorker.RunWorkerAsync(); // finite state machine state = DeviceState.GetDefaultState(port); newState = state; }
// </PROPERTIES> // <EVENT HANDLERS> /// <summary> /// The main loop that processes enqueued transactions /// </summary> /// <param name="sender">Background worker</param> /// <param name="e">Event arguments</param> private void ComWorker_DoWork(object sender, DoWorkEventArgs e) { while (!((BackgroundWorker)sender).CancellationPending) { Thread.Sleep(Global.Delay); // reduce CPU load // process flags if (disconnect) { disconnect = false; state = state.Disconnect(); } if (connect) { connect = false; state = state.Connect(tempPortName); } if (reset) { reset = false; if (state is ResettableState) { state = new Identified(port); } } // continue with state-specific actions if (state is Disconnected) { ClearQueue(); Exception innerException = ((Disconnected)state).RemoveInnerException(); // raise events if (DeviceIdentified != null) { DeviceIdentified(null); } if ((innerException != null) && (PortClosed != null)) { PortClosed(innerException); } } else if (state is Connected) { ClearQueue(); string connectionInfo; state = ((Connected)state).Identify(Global.Identification, out connectionInfo); // raise events if ((state is Identified) && (DeviceIdentified != null)) { DeviceIdentified(connectionInfo); } } else if (state is Identified) { ClearQueue(); Flush(); state = ((Identified)state).Reset(); // raise events if (state is Ready) { if (DeviceReady != null) { DeviceReady(); } } } else if (state is Ready) { if (transactionsQueue.Count > 0) { lastTransaction = transactionsQueue.Dequeue(); string command = lastTransaction.Command.Command(); if (lastTransaction.ExpectsResponse == Response.ExpectsResponse) // query commands { string response; // Terminate all commands which expect response with a question mark (if not already present). With the exception of compensate commands which expect response but do not have question mark. if ((lastTransaction.Command.Command().Contains("?") == false) && (lastTransaction.Command != Commands.CompensateOpen) && (lastTransaction.Command != Commands.CompensateShort)) { command += "?"; } state = ((Ready)state).Query(command, out response); // query the device Transaction outputTransaction = new Transaction(lastTransaction.Command, lastTransaction.ExpectsResponse); // make a copy of the transaction to pass out outputTransaction.AddResponse(response); // add the received response // raise events if ((DataUpdated != null) && (state is Ready)) { DataUpdated(outputTransaction); } } else // send commands { if (lastTransaction.Parameter == null) // without parameter { state = ((Ready)state).Send(command); } else // with parameter { state = ((Ready)state).Send(command + " " + lastTransaction.Parameter); } } } else if (TransactionQueueEmpty != null) // raise event if transaction queue is empty { TransactionQueueEmpty(); } } } }