public bool com_protocol_set_config_p2p(string comport) { stop(); Serport = new SerialPort(); Serport.BaudRate = 115200; Serport.PortName = comport; Serport.ReadTimeout = 100; Serport.WriteTimeout = 100; try { Serport.Open(); Buffer = new byte[COM_PROTOCOL_BUFFER_SIZE]; DeviceAddress = 0; p2p_mode = true; LastPacketNumber = 0; CurrentReceiveState = com_protocol_receiveStates.RCV_start; ReceivedEscape = false; } catch (System.Exception) { stop(); return(false); } return(true); }
//send a command to an address and wait for the client to response (bus mode) //response is NULL if client does not response within maximum response time (CANCMD_MAX_RESPONSE_TIME_MS) protected receiveData com_protocol_SendDataCommandInternal(UInt32 address, byte command, byte[] data, byte dataLength, bool responseMessage, byte responsePacketNumber) { if (Connected() == false) { return(null); } receiveData response = null; for (int i = 0; ((i < COM_PROTOCOL_MAX_RESPONSE_TRIES) && (response == null)); i++) { BufferIndex = 0; ClearChecksum(); Buffer[BufferIndex++] = COM_PROTOCOL_COMMAND_START; byte packetnmbr; if (responseMessage) { packetnmbr = responsePacketNumber; } else { packetnmbr = GetNextPacketNumber(); } AddToSendBuffer(packetnmbr); UpdateChecksum(packetnmbr); if (p2p_mode == false) { AddToSendBuffer((byte)(address >> 24)); UpdateChecksum((byte)(address >> 24)); AddToSendBuffer((byte)(address >> 16)); UpdateChecksum((byte)(address >> 16)); AddToSendBuffer((byte)(address >> 8)); UpdateChecksum((byte)(address >> 8)); AddToSendBuffer((byte)address); UpdateChecksum((byte)address); } AddToSendBuffer(dataLength); UpdateChecksum(dataLength); AddToSendBuffer(command); UpdateChecksum(command); for (int j = 0; j < dataLength; j++) { if (AddToSendBuffer(data[j]) == false) { //send buffer overflow return(null); } UpdateChecksum(data[j]); } if ((BufferIndex + 4) > COM_PROTOCOL_BUFFER_SIZE) { //send buffer overflow return(null); } AddToSendBuffer((byte)(GetChecksum() >> 8)); AddToSendBuffer((byte)GetChecksum()); try { Serport.Write(Buffer, 0, BufferIndex); //successfully send the data //delete any remaining data in the input buffer Serport.DiscardInBuffer(); } catch (System.Exception) { return(null); } if ((address == COM_PROTOCOL_ADDRESS_TO_ALL_NO_RESPONSE) || (responseMessage == true)) { //we are not expecting a response break; } else { CurrentReceiveState = com_protocol_receiveStates.RCV_start; ReceivedEscape = false; DateTime startTime = DateTime.Now; while ((DateTime.Now - startTime).TotalMilliseconds <= COM_PROTOCOL_MAX_RESPONSE_TIME_MS) { response = com_protocol_ReceiveUpdateInternal(address); if (response != null) { if ((((response.address != COM_PROTOCOL_ADDRESS_TO_ALL_NO_RESPONSE) && (response.address != COM_PROTOCOL_ADDRESS_TO_ALL)) || p2p_mode) && (response.packetNumber == packetnmbr)) { //valid response received break; } else { response = null; if (p2p_mode) { break; } } } Thread.Sleep(5); } } } CurrentReceiveState = com_protocol_receiveStates.RCV_start; ReceivedEscape = false; return(response); }
//synchronously receive a CAN command public receiveData com_protocol_ReceiveUpdateInternal(UInt32 listenAddress) { try { while (Serport.BytesToRead > 0) { byte val = (byte)Serport.ReadByte(); if (val == COM_PROTOCOL_COMMAND_ESC) { ReceivedEscape = true; } else { if (val == COM_PROTOCOL_COMMAND_START) { ClearChecksum(); CurrentReceiveState = com_protocol_receiveStates.RCV_packetnumber; ReceivedEscape = false; } else { if (ReceivedEscape) { ReceivedEscape = false; val = (byte)(val | COM_PROTOCOL_ESC_MASK); } switch (CurrentReceiveState) { case com_protocol_receiveStates.RCV_start: break; case com_protocol_receiveStates.RCV_packetnumber: CurrentRecieveData.packetNumber = val; if (p2p_mode) { CurrentReceiveState = com_protocol_receiveStates.RCV_length; } else { CurrentReceiveState = com_protocol_receiveStates.RCV_address3; } break; case com_protocol_receiveStates.RCV_address3: CurrentRecieveData.address = ((UInt32)val) << 24; CurrentReceiveState = com_protocol_receiveStates.RCV_address2; break; case com_protocol_receiveStates.RCV_address2: CurrentRecieveData.address = CurrentRecieveData.address + (((UInt32)val) << 16); CurrentReceiveState = com_protocol_receiveStates.RCV_address1; break; case com_protocol_receiveStates.RCV_address1: CurrentRecieveData.address = CurrentRecieveData.address + (((UInt32)val) << 8); CurrentReceiveState = com_protocol_receiveStates.RCV_address0; break; case com_protocol_receiveStates.RCV_address0: CurrentRecieveData.address = CurrentRecieveData.address + ((UInt32)val); if ((CurrentRecieveData.address == listenAddress) || (CurrentRecieveData.address == COM_PROTOCOL_ADDRESS_TO_ALL_NO_RESPONSE) || (CurrentRecieveData.address == COM_PROTOCOL_ADDRESS_TO_ALL)) { CurrentReceiveState = com_protocol_receiveStates.RCV_length; } else { //message not for us CurrentReceiveState = com_protocol_receiveStates.RCV_start; } break; case com_protocol_receiveStates.RCV_length: CurrentRecieveData.dataLength = val; if (CurrentRecieveData.dataLength > COM_PROTOCOL_BUFFER_SIZE) { //message is too big, so we are not even trying to receive it. CurrentReceiveState = com_protocol_receiveStates.RCV_start; } else { CurrentReceiveState = com_protocol_receiveStates.RCV_command; } break; case com_protocol_receiveStates.RCV_command: CurrentRecieveData.command = val; if (CurrentRecieveData.dataLength > 0) { BufferIndex = 0; CurrentReceiveState = com_protocol_receiveStates.RCV_data; } else { CurrentReceiveState = com_protocol_receiveStates.RCV_checksumH; } break; case com_protocol_receiveStates.RCV_data: Buffer[BufferIndex++] = val; if (BufferIndex >= CurrentRecieveData.dataLength) { CurrentReceiveState = com_protocol_receiveStates.RCV_checksumH; } break; case com_protocol_receiveStates.RCV_checksumH: ReceivedChecksum = (UInt16)(((UInt16)val) << 8); CurrentReceiveState = com_protocol_receiveStates.RCV_checksumL; break; case com_protocol_receiveStates.RCV_checksumL: ReceivedChecksum = (UInt16)(ReceivedChecksum + val); if (GetChecksum() == ReceivedChecksum) { //data valid CurrentRecieveData.data = Buffer; return(CurrentRecieveData); } CurrentReceiveState = com_protocol_receiveStates.RCV_start; break; } if (CurrentReceiveState != com_protocol_receiveStates.RCV_checksumL) { UpdateChecksum(val); } } } } } catch (System.Exception) { } //no response return(null); }