/// <summary> /// Transmits the current packet to the bus /// </summary> private void TransmitPacket(EosPacket sendPacket) { byte[] buffer = new byte[64]; lock (sendPacket) { sendPacket.Source = 0; buffer[0] = 0xbb; buffer[1] = 0x88; buffer[2] = sendPacket.Destination; buffer[3] = sendPacket.Source; buffer[4] = sendPacket.Command; buffer[5] = (byte)(sendPacket.Data.Count); sendPacket.Data.CopyTo(buffer, 6); buffer[6 + sendPacket.Data.Count] = sendPacket.Checksum; _masterState = BusMasterState.TRANSMITTING; SendData(buffer, 0, sendPacket.Data.Count + 7); if (sendPacket.Command > 127) { _resposneAddress = sendPacket.Destination; } else { _resposneAddress = 0xff; } _busTimer.Interval = TRANSMIT_CHECK_INTERVAL; _busTimer.Start(); sendPacket.IsSent = true; } }
/// <summary> /// Process a response timeout /// </summary> private void ProcessResponseTimeout() { switch (State) { case EosBusState.POLLING: //Console.WriteLine("Polling timeout"); _devices[_pollId].PollingErrors++; break; case EosBusState.WAITING_RESPONSE: OnResponseReceived((EosPacket)null); _masterState = BusMasterState.IDLE; break; } }
public override void Reset() { if (_masterState != BusMasterState.IDLE) { _masterState = BusMasterState.CLEARINGRESET; return; } ; SendPacket(new EosPacket(0xff, EosBusCommands.RESET)); // Reset our error statistics _stats.Timeouts = 0; _stats.Collisions = 0; _stats.Overruns = 0; _stats.PacketErrors = 0; }
private void Parser_ParseError(object sender, EosParserErrorEventArgs e) { lock (this) { if (_masterState == BusMasterState.CLEARINGSCAN) { _masterState = BusMasterState.IDLE; Rescan(); } else if (_masterState == BusMasterState.CLEARINGRESET) { _masterState = BusMasterState.IDLE; Reset(); } else if (_masterState == BusMasterState.WAITINGRESPONSE) { _masterState = BusMasterState.IDLE; _busTimer.Stop(); switch (State) { case EosBusState.SCANNING: NextScan(); break; case EosBusState.POLLING: //Console.WriteLine("Polling Parse Error"); _devices[_pollId].PollingErrors++; break; case EosBusState.WAITING_RESPONSE: OnResponseReceived((EosPacket)null); break; } } else { // Received errored packet when we are not waiting on one. _stats.Collisions++; } } }
public EosBusMaster(string port, int baudRate) : base(port, baudRate, 64) { _stats = new EosBusStatistics(); _masterState = BusMasterState.IDLE; State = EosBusState.IDLE; _parser = new EosParser(150); _parser.PacketReady += new EosPacketEventHandler(Parser_PacketReady); _parser.ParseError += new EosParserErrorEventHandler(Parser_ParseError); _busTimer = new Timer(100); _busTimer.AutoReset = false; _busTimer.Elapsed += TimerEvent; _scanned = false; _devices = new List <EosDevice>(); _externalDevices = new EosDeviceCollection(_devices); _sendPackets = new ConcurrentQueue <EosPacket>(); }
public override void Rescan() { if (_masterState != BusMasterState.IDLE) { _masterState = BusMasterState.CLEARINGSCAN; return; } ; // Stop current activity _busTimer.Stop(); _parser.Reset(); // Setup for a bus scan _pollId = 1; State = EosBusState.SCANNING; _devices.Clear(); // Start the scan. NextScan(); }
private void Parser_PacketReady(object sender, EosPacketEventArgs e) { lock (this) { //Console.WriteLine("Packet Received (masterState {0}, responseAddress {1})", _masterState, _resposneAddress); OnPacketReceived(e.Packet); // Check to see if we got the response before we checked for done transmitting if (_masterState == BusMasterState.TRANSMITTING && _resposneAddress != 0xff && !IsWriting) { _masterState = BusMasterState.WAITINGRESPONSE; switch (State) { case EosBusState.TRANSMITTING: State = EosBusState.WAITING_RESPONSE; break; case EosBusState.POLLING: case EosBusState.IDLE: State = _polling ? EosBusState.POLLING : EosBusState.IDLE; break; } } if (_masterState == BusMasterState.WAITINGRESPONSE && e.Packet.Source == _resposneAddress) { _busTimer.Stop(); _masterState = BusMasterState.IDLE; switch (State) { case EosBusState.POLLING: //Console.WriteLine("Polling Received"); if (e.Packet.Data.Count > 0) { EosDevice device = Devices.GetByAddress(e.Packet.Source); device.UpdateState(e.Packet); OnDeviceUpdated(device); } _busTimer.Interval = POLL_INTERVAL; _busTimer.Start(); break; case EosBusState.SCANNING: // Scan found a valid response _devices.Add(new EosDevice(this, e.Packet.Source, e.Packet.Data)); NextScan(); break; case EosBusState.WAITING_RESPONSE: //Console.WriteLine("Response sent"); OnResponseReceived(e.Packet); if (_polling) { State = EosBusState.POLLING; _busTimer.Interval = POLL_INTERVAL; _busTimer.Start(); } else { State = EosBusState.IDLE; } break; } } else if (_masterState == BusMasterState.CLEARINGSCAN) { _masterState = BusMasterState.IDLE; Rescan(); } else if (_masterState == BusMasterState.CLEARINGRESET) { _masterState = BusMasterState.IDLE; Reset(); } else { // Received errored packet when we are not waiting on one. _stats.Collisions++; } } }
/// <summary> /// Timer event which is fired when a timeout occurs or a polling /// wait interval is over. /// </summary> private void TimerEvent(object sender, ElapsedEventArgs e) { lock (this) { switch (_masterState) { case BusMasterState.CLEARINGSCAN: _masterState = BusMasterState.IDLE; Rescan(); break; case BusMasterState.CLEARINGRESET: _masterState = BusMasterState.IDLE; Reset(); break; case BusMasterState.IDLE: DoIdle(); break; case BusMasterState.TRANSMITTING: if (!IsWriting) { if (_resposneAddress != 0xff) { switch (State) { case EosBusState.TRANSMITTING: State = EosBusState.WAITING_RESPONSE; break; case EosBusState.POLLING: case EosBusState.IDLE: State = _polling ? EosBusState.POLLING : EosBusState.IDLE; break; } _masterState = BusMasterState.WAITINGRESPONSE; _busTimer.Interval = RESPONSE_TIMEOUT; _busTimer.Start(); } else { switch (State) { case EosBusState.TRANSMITTING: case EosBusState.POLLING: case EosBusState.IDLE: State = _polling ? EosBusState.POLLING : EosBusState.IDLE; break; } _masterState = BusMasterState.IDLE; DoIdle(); } } break; case BusMasterState.WAITINGRESPONSE: ProcessResponseTimeout(); if (State == EosBusState.WAITING_RESPONSE) { State = _polling ? EosBusState.POLLING : EosBusState.IDLE; } _masterState = BusMasterState.IDLE; DoIdle(); break; } } }