Today boss asked me to implement a serial com port simulator. I used MSCommLib COM library in C# to develop this simulator.
The serial protocol I am working on is a bit strange:
The message synchronization is achieved via a technique utilizing the parity bit of serially of transmitted data. The parity bit sent with each byte no longer denotes the byte’s parity, but the parity bit is used instead to indicate the start of new messages. In this mode, the parity bit is often referred to as the “wake-up bit”. The parity bit is now used in the following manner: when the parity bit is set, this denotes the start (i.e. the first byte) of a new message. , the parity bit (or wake-up bit), is only ever set on the first byte (i.e. the address byte) of a message. The remainder of the message has parity forced to zero.
Therefore, this protocol needs dynamically update the parity bit settings during the message sending. There are many articles about generic serial com programming. However, it’s hard to find the parity bit toggling. After few hours exploring, I found a way to achieve this.
Like other serial protocol, we have to initialize com port
public void InitComPort(int portNumber)
{
// Set the com port to be 1
m_ComPort.CommPort = (short)portNumber;
// This port is already open, close it to reset it.
if (m_ComPort.PortOpen)
m_ComPort.PortOpen = false;
// Trigger the OnComm event whenever data is received
m_ComPort.RThreshold = 1;
//e, Even. m, Mark. m, (Default) None. o, Odd. s, Space
// Set the port to 19200 baud, even parity bit, 8 data bits, 1 stop bit (all standard)
m_ComPort.Settings = "19200,e,8,1";
// Force the DTR line high, used sometimes to hang up modems
m_ComPort.DTREnable = true;
// No handshaking is used
m_ComPort.Handshaking = MSCommLib.HandshakeConstants.comNone;
// Use this line instead for byte array input, best for most communications
m_ComPort.InputMode = MSCommLib.InputModeConstants.comInputModeBinary;
// Read the entire waiting data when com.Input is used
m_ComPort.InputLen = 0;
// Don't discard nulls, 0x00 is a useful byte
m_ComPort.NullDiscard = false;
// Attach the event handler
m_ComPort.OnComm += new MSCommLib.DMSCommEvents_OnCommEventHandler(OnComm);
m_ComPort.ParityReplace = "0";
// Open the com port
m_ComPort.PortOpen = true;
}
Here is the way to toggle the parity bit during sending message
private void SendThread()
{
while(m_ComPort.PortOpen)
{
m_ComPort.PortOpen = false;
// Change port setting, toggle the parity bit to 1
m_ComPort.Settings = "19200,m,8,1";
m_ComPort.PortOpen = true;
m_ComPort.Output = addr;
// wait 10 ms to toggle parity bit
Thread.Sleep(10);
m_ComPort.PortOpen = false;
// Change port setting, toggle the parity bit to 0
m_ComPort.Settings = "19200,s,8,1";
m_ComPort.PortOpen = true;
m_ComPort.Output = packet;
}
}