/// <summary> /// Constructor /// </summary> /// <param name="portName">Serial port name</param> public PN532CommunicationHSU(string portName) { this.length = 0; this.isFirstStartCode = false; this.isWaitingAck = false; this.frame = new ArrayList(); this.inputBuffer = new ArrayList(); this.queueFrame = new Queue(); this.state = HsuParserState.Preamble; this.received = new AutoResetEvent(false); // create and open serial port this.port = new SerialPort(portName, HSU_BAUD_RATE, HSU_PARITY, HSU_DATA_BITS, HSU_STOP_BITS); this.port.DataReceived += port_DataReceived; this.port.Open(); }
/// <summary> /// Constructor /// </summary> private Pn532CommunicationHsu(SerialDevice reader) { if (reader == null) { throw new ArgumentNullException("serial card reader is not set"); } _length = 0; _isFirstStartCode = false; _isWaitingAck = false; _frame = new ArrayList(); _inputBuffer = new ArrayList(); _queueFrame = new Queue(); _state = HsuParserState.Preamble; _received = new AutoResetEvent(false); _rfidReader = reader; }
void ExtractFrame() { lock (this.inputBuffer) { foreach (byte byteRx in this.inputBuffer) { switch (this.state) { case HsuParserState.Preamble: // preamble arrived, frame started if (byteRx == PN532.PN532_PREAMBLE) { this.length = 0; this.isFirstStartCode = false; this.frame.Clear(); this.frame.Add(byteRx); this.state = HsuParserState.StartCode; } break; case HsuParserState.StartCode: // first start code byte not received yet if (!this.isFirstStartCode) { if (byteRx == PN532.PN532_STARTCODE_1) { this.frame.Add(byteRx); this.isFirstStartCode = true; } } // first start code byte already received else { if (byteRx == PN532.PN532_STARTCODE_2) { this.frame.Add(byteRx); this.state = HsuParserState.Length; } } break; case HsuParserState.Length: // not waiting ack, the byte is LEN if (!this.isWaitingAck) { // save data length (TFI + PD0...PDn) for counting received data this.length = byteRx; this.frame.Add(byteRx); this.state = HsuParserState.LengthChecksum; } // waiting ack, the byte is first of ack/nack code else { this.frame.Add(byteRx); this.state = HsuParserState.AckCode; } break; case HsuParserState.LengthChecksum: // arrived LCS this.frame.Add(byteRx); this.state = HsuParserState.FrameIdentifierAndData; break; case HsuParserState.FrameIdentifierAndData: this.frame.Add(byteRx); // count received data bytes (TFI + PD0...PDn) this.length--; // all data bytes received if (this.length == 0) this.state = HsuParserState.DataChecksum; break; case HsuParserState.DataChecksum: // arrived DCS this.frame.Add(byteRx); this.state = HsuParserState.Postamble; break; case HsuParserState.Postamble: // postamble received, frame end if (byteRx == PN532.PN532_POSTAMBLE) { this.frame.Add(byteRx); this.state = HsuParserState.Preamble; // enqueue received frame byte[] frameReceived = new byte[this.frame.Count]; this.frame.CopyTo(frameReceived, 0); this.queueFrame.Enqueue(frameReceived); this.received.Set(); } break; case HsuParserState.AckCode: // second byte of ack/nack code this.frame.Add(byteRx); this.state = HsuParserState.Postamble; this.isWaitingAck = false; break; default: break; } } // clear internal buffer this.inputBuffer.Clear(); } }
//void port_DataReceived(object sender, SerialDataReceivedEventArgs e) //{ // lock (inputBuffer) // { // // read bytes from serial port and load them in the internal buffer // byte[] buffer = new byte[port.BytesToRead]; // port.Read(buffer, 0, buffer.Length); // for (int i = 0; i < buffer.Length; i++) // inputBuffer.Add(buffer[i]); // } // // frame parsing // ExtractFrame(); //} void ExtractFrame() { lock (_inputBuffer) { foreach (byte byteRx in _inputBuffer) { switch (_state) { case HsuParserState.Preamble: // preamble arrived, frame started if (byteRx == PN532.PN532_PREAMBLE) { _length = 0; _isFirstStartCode = false; _frame.Clear(); _frame.Add(byteRx); _state = HsuParserState.StartCode; } break; case HsuParserState.StartCode: // first start code byte not received yet if (!_isFirstStartCode) { if (byteRx == PN532.PN532_STARTCODE_1) { _frame.Add(byteRx); _isFirstStartCode = true; } } // first start code byte already received else { if (byteRx == PN532.PN532_STARTCODE_2) { _frame.Add(byteRx); _state = HsuParserState.Length; } } break; case HsuParserState.Length: // not waiting ack, the byte is LEN if (!_isWaitingAck) { // save data length (TFI + PD0...PDn) for counting received data _length = byteRx; _frame.Add(byteRx); _state = HsuParserState.LengthChecksum; } // waiting ack, the byte is first of ack/nack code else { _frame.Add(byteRx); _state = HsuParserState.AckCode; } break; case HsuParserState.LengthChecksum: // arrived LCS _frame.Add(byteRx); _state = HsuParserState.FrameIdentifierAndData; break; case HsuParserState.FrameIdentifierAndData: _frame.Add(byteRx); // count received data bytes (TFI + PD0...PDn) _length--; // all data bytes received if (_length == 0) { _state = HsuParserState.DataChecksum; } break; case HsuParserState.DataChecksum: // arrived DCS _frame.Add(byteRx); _state = HsuParserState.Postamble; break; case HsuParserState.Postamble: // postamble received, frame end if (byteRx == PN532.PN532_POSTAMBLE) { _frame.Add(byteRx); _state = HsuParserState.Preamble; // enqueue received frame byte[] frameReceived = new byte[_frame.Count]; _frame.CopyTo(frameReceived, 0); _queueFrame.Enqueue(frameReceived); _received.Set(); } break; case HsuParserState.AckCode: // second byte of ack/nack code _frame.Add(byteRx); _state = HsuParserState.Postamble; _isWaitingAck = false; break; default: break; } } // clear internal buffer _inputBuffer.Clear(); } }