private List <byte> ParseKmmFrame()
        {
            byte temp;

            // receive kmm opcode
            //Console.WriteLine("mr: kmm opcode");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);
            if (temp != KMM_OPCODE)
            {
                throw new Exception(string.Format("mr: unexpected opcode, expected: 0x{0:X2}, got: 0x{1:X2}", KMM_OPCODE, temp));
            }

            int length = 0;

            // receive length high byte
            //Console.WriteLine("mr: length high byte");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);

            length |= (temp & 0xFF) << 8;

            // receive length low byte
            //Console.WriteLine("mr: length low byte");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);

            length |= temp & 0xFF;

            //Console.WriteLine("length: {0}", length);

            List <byte> toCrc = new List <byte>();

            // receive control
            //Console.WriteLine("mr: control");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);
            toCrc.Add(temp);

            // receive dest rsi high byte
            //Console.WriteLine("mr: dest rsi high byte");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);
            toCrc.Add(temp);

            // receive dest rsi mid byte
            //Console.WriteLine("mr: dest rsi mid byte");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);
            toCrc.Add(temp);

            // receive dest rsi low byte
            //Console.WriteLine("mr: dest rsi low byte");
            temp = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);
            toCrc.Add(temp);

            int bodyLength = length - 6;

            List <byte> kmm = new List <byte>();

            for (int i = 0; i < bodyLength; i++)
            {
                //Console.WriteLine("mr: kmm byte {0} of {1}", i + 1, bodyLength);
                temp = Protocol.GetByte(TWI_TIMEOUT);
                //Console.WriteLine("mr -> kfd: 0x{0:X2}", temp);

                kmm.Add(temp);
            }

            toCrc.AddRange(kmm);

            byte[] crc = new byte[2];

            // receive crc high byte
            //Console.WriteLine("mr: crc high byte");
            crc[0] = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", crc[0]);

            // receive crc low byte
            //Console.WriteLine("mr: crc low byte");
            crc[1] = Protocol.GetByte(TWI_TIMEOUT);
            //Console.WriteLine("mr -> kfd: 0x{0:X2}", crc[1]);

            // calculate crc
            byte[] expectedCrc = CRC16.CalculateCrc(toCrc.ToArray());

            if (expectedCrc[0] != crc[0])
            {
                throw new Exception(string.Format("mr: crc high byte mismatch, expected: 0x{0:X2}, got: 0x{1:X2}", expectedCrc[0], crc[0]));
            }

            if (expectedCrc[1] != crc[1])
            {
                throw new Exception(string.Format("mr: crc low byte mismatch, expected: 0x{0:X2}, got: 0x{1:X2}", expectedCrc[1], crc[1]));
            }

            return(kmm);
        }
        private List <byte> ParseKmmFrame()
        {
            byte temp;

            int length = 0;

            // receive length high byte
            Log.Debug("mr: length high byte");
            temp = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: 0x{0:X2}", temp);

            length |= (temp & 0xFF) << 8;

            // receive length low byte
            Log.Debug("mr: length low byte");
            temp = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(temp));

            length |= temp & 0xFF;

            Log.Debug("length: {0}", length);

            List <byte> toCrc = new List <byte>();

            // receive control
            Log.Debug("mr: control");
            temp = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(temp));
            toCrc.Add(temp);

            // receive dest rsi high byte
            Log.Debug("mr: dest rsi high byte");
            temp = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(temp));
            toCrc.Add(temp);

            // receive dest rsi mid byte
            Log.Debug("mr: dest rsi mid byte");
            temp = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(temp));
            toCrc.Add(temp);

            // receive dest rsi low byte
            Log.Debug("mr: dest rsi low byte");
            temp = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(temp));
            toCrc.Add(temp);

            int bodyLength = length - 6;

            List <byte> kmm = new List <byte>();

            for (int i = 0; i < bodyLength; i++)
            {
                Log.Debug("mr: kmm byte {0} of {1}", i + 1, bodyLength);
                temp = Protocol.GetByte(TIMEOUT_STD);
                Log.Debug("mr -> kfd: {0}", Utility.DataFormat(temp));

                kmm.Add(temp);
            }

            toCrc.AddRange(kmm);

            // calculate crc
            byte[] expectedCrc = CRC16.CalculateCrc(toCrc.ToArray());

            Log.Debug("expected crc - high: 0x{0:X2}, low: 0x{1:X2}", expectedCrc[0], expectedCrc[1]);

            byte[] crc = new byte[2];

            // receive crc high byte
            Log.Debug("mr: crc high byte");
            crc[0] = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(crc[0]));

            // receive crc low byte
            Log.Debug("mr: crc low byte");
            crc[1] = Protocol.GetByte(TIMEOUT_STD);
            Log.Debug("mr -> kfd: {0}", Utility.DataFormat(crc[1]));

            if (expectedCrc[0] != crc[0])
            {
                throw new Exception(string.Format("mr: crc high byte mismatch, expected: 0x{0:X2}, got: 0x{1:X2}", expectedCrc[0], crc[0]));
            }

            if (expectedCrc[1] != crc[1])
            {
                throw new Exception(string.Format("mr: crc low byte mismatch, expected: 0x{0:X2}, got: 0x{1:X2}", expectedCrc[1], crc[1]));
            }

            return(kmm);
        }