/* public CANMessage waitForMessage(uint a_canID, int a_timeout) { CANMessage retMsg; m_canMessage.setID(0); // init so we cannot receive the same frame twice <GS-10022010> lock (m_canMessage) { m_waitMsgID = a_canID; } m_resetEvent.WaitOne(a_timeout, true); lock (m_canMessage) { retMsg = m_canMessage; } return retMsg; } */ public override void handleMessage(CANMessage a_message) { lock (m_canMessage) { if (a_message.getID() == m_waitMsgID) { m_canMessage.setData(a_message.getData()); m_canMessage.setFlags(a_message.getFlags()); m_canMessage.setID(a_message.getID()); m_canMessage.setLength(a_message.getLength()); m_canMessage.setTimeStamp(a_message.getTimeStamp()); messageReceived = true; m_resetEvent.Set(); } } }
public override void handleMessage(CANMessage a_message) { if (_queue == null) { _queue = new CANMessage[16]; _receiveMessageIndex = 0; _readMessageIndex = 0; } // add the message to a queue for later processing ... // the queue is a ringbuffer for CANMessage objects. // X objects are supported // we need a receive and a read pointer for this to work properly messageReceived = false; //_queue[_receiveMessageIndex] = a_message; _queue[_receiveMessageIndex] = new CANMessage(); _queue[_receiveMessageIndex].setData(a_message.getData()); _queue[_receiveMessageIndex].setID(a_message.getID()); _queue[_receiveMessageIndex].setLength(a_message.getLength()); _receiveMessageIndex++; if(_receiveMessageIndex > _queue.Length - 1) _receiveMessageIndex = 0; // make it circular //DetermineSize(); /* lock (m_canMessage) { if (a_message.getID() == m_waitMsgID) { m_canMessage = a_message; messageReceived = true; } } if (messageReceived) { m_resetEvent.Set(); }*/ }
//--------------------------------------------------------------------------------------------- /** Waits for arrival of a specific CAN message or any message if ID = 0. @param a_canID message ID @param timeout timeout, ms @param canMsg message @return message ID */ public override uint waitForMessage(uint a_canID, uint timeout, out CANMessage canMsg) { canMsg = new CANMessage(); Debug.Assert(canMsg != null); canMsg.setID(0); caCombiAdapter.caCANFrame frame = new caCombiAdapter.caCANFrame(); if (this.combi.CAN_GetMessage(ref frame, timeout) && (frame.id == a_canID || a_canID == 0)) { // message received canMsg.setID(frame.id); canMsg.setLength(frame.length); canMsg.setData(frame.data); return frame.id; } // timed out return 0; }
public override uint waitForMessage(uint a_canID, uint timeout, out CANMessage canMsg) { canMsg = new CANMessage(); return 0; }
private void SendKeepAlive() { CANMessage msg = new CANMessage(0x7E0, 0, 2);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0000000000003E01; // always 2 bytes msg.setData(cmd); //Console.WriteLine("KA sent"); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); //Console.WriteLine("received KA: " + response.getCanData(1).ToString("X2")); }
/// <summary> /// Start a KWP session. /// </summary> /// <remarks> /// A KWP session must be started before any requests can be sent. /// </remarks> /// <returns>True if the session was started, otherwise false.</returns> public bool startSession() { CANMessage msg = new CANMessage(0x7E0, 0, 8); msg.setData(0x000040021100813F); // what is this stuff??? msg.setData(0x0000000000008102); // startCommunication AddToCanTrace("Sending 0x0000000000008102 message"); m_kwpCanListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Unable to send 0x0000000000008102 message"); return false; } Console.WriteLine("Init msg sent"); if (m_kwpCanListener.waitMessage(timeoutPeriod).getID() == 0x7E8) { AddToCanTrace("Successfully sent 0x0000000000008102 message and received reply 0x7E8"); return true; } else { AddToCanTrace("Didn't receive 0x7E8 message as reply on 0x0000000000008102 message"); return false; } }
public void readMessages() { CANMessage canMessage = new CANMessage(); byte[] receiveBuffer = new byte[1024]; // circular buffer for reception of data string receiveString = string.Empty; Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } if (m_serialPort != null) { if (m_serialPort.IsOpen) { if (m_serialPort.BytesToRead > 0) { string rxString = m_serialPort.ReadExisting(); if (rxString.Length > 0) AddToSerialTrace("SERRX: " + rxString); receiveString += rxString; //Console.WriteLine("BUF1: " + receiveString); receiveString = receiveString.Replace(">", ""); // remove prompt characters... we don't need that stuff receiveString = receiveString.Replace("NO DATA", ""); // remove prompt characters... we don't need that stuff while (receiveString.StartsWith("\n") || receiveString.StartsWith("\r")) { receiveString = receiveString.Substring(1, receiveString.Length - 1); } while (receiveString.Contains('\r')) { // process the line int idx = receiveString.IndexOf('\r'); string rxMessage = receiveString.Substring(0, idx); receiveString = receiveString.Substring(idx + 1, receiveString.Length - idx - 1); while (receiveString.StartsWith("\n") || receiveString.StartsWith("\r")) { receiveString = receiveString.Substring(1, receiveString.Length - 1); } //Console.WriteLine("BUF2: " + receiveString); // is it a valid line if (rxMessage.Length >= 6) { try { uint id = Convert.ToUInt32(rxMessage.Substring(0, 3), 16); if (MessageContainsInformationForRealtime(id)) { canMessage.setID(id); canMessage.setLength(8); // TODO: alter to match data canMessage.setData(0x0000000000000000); // reset message content byte b1 = Convert.ToByte(rxMessage.Substring(4, 2), 16); if (b1 < 7) { canMessage.setCanData(b1, 0); //Console.WriteLine("Byte 1: " + Convert.ToByte(rxMessage.Substring(4, 2), 16).ToString("X2")); if (b1 >= 1) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(7, 2), 16), 1); if (b1 >= 2) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(10, 2), 16), 2); if (b1 >= 3) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(13, 2), 16), 3); if (b1 >= 4) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(16, 2), 16), 4); if (b1 >= 5) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(19, 2), 16), 5); if (b1 >= 6) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(22, 2), 16), 6); if (b1 >= 7) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(25, 2), 16), 7); } else { canMessage.setCanData(b1, 0); //Console.WriteLine("Byte 1: " + Convert.ToByte(rxMessage.Substring(4, 2), 16).ToString("X2")); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(7, 2), 16), 1); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(10, 2), 16), 2); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(13, 2), 16), 3); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(16, 2), 16), 4); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(19, 2), 16), 5); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(22, 2), 16), 6); canMessage.setCanData(Convert.ToByte(rxMessage.Substring(25, 2), 16), 7); } lock (m_listeners) { AddToCanTrace("RX: " + canMessage.getData().ToString("X16")); //Console.WriteLine("MSG: " + rxMessage); foreach (ICANListener listener in m_listeners) { listener.handleMessage(canMessage); } } } } catch (Exception) { Console.WriteLine("MSG: " + rxMessage); } } } } else { Thread.Sleep(1); // give others some air } } } } // parse the receive string /*int readResult = 0; LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg(); CANMessage canMessage = new CANMessage(); Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { //Console.WriteLine(r_canMsg.id.ToString("X3") + " " + r_canMsg.data.ToString("X8")); if (MessageContainsInformationForRealtime(r_canMsg.id)) { canMessage.setID(r_canMsg.id); canMessage.setLength(r_canMsg.len); canMessage.setTimeStamp(r_canMsg.timestamp); canMessage.setFlags(r_canMsg.flags); canMessage.setData(r_canMsg.data); lock (m_listeners) { AddToCanTrace("RX: " + r_canMsg.data.ToString("X16")); foreach (ICANListener listener in m_listeners) { //while (listener.messagePending()) ; // dirty, make this better listener.handleMessage(canMessage); } //CastInformationEvent(canMessage); // <GS-05042011> re-activated this function } //Thread.Sleep(1); } // cast event to application to process message //if (MessageContainsInformationForRealtime(r_canMsg.id)) //{ //TODO: process all other known msg id's into the realtime view // CastInformationEvent(canMessage); // <GS-05042011> re-activated this function //} } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); } } */ }
/*private void AddToCanTrace(string line) { if (m_EnableCanLog) { DateTime dtnow = DateTime.Now; using (StreamWriter sw = new StreamWriter(System.Windows.Forms.Application.StartupPath + "\\CanTraceCANUSBDevice.txt", true)) { sw.WriteLine(dtnow.ToString("dd/MM/yyyy HH:mm:ss") + " - " + line); } } }*/ /// <summary> /// sendMessage send a CANMessage. /// </summary> /// <param name="a_message">A CANMessage.</param> /// <returns>true on success, othewise false.</returns> public override bool sendMessage(CANMessage a_message) { LAWICEL.CANMsg msg = new LAWICEL.CANMsg(); msg.id = a_message.getID(); msg.len = a_message.getLength(); msg.flags = a_message.getFlags(); msg.data = a_message.getData(); int writeResult; //AddToCanTrace("Sending message"); AddToCanTrace("TX: " + msg.id.ToString("X4") + " " + msg.data.ToString("X16")); writeResult = LAWICEL.canusb_Write(m_deviceHandle, ref msg); if (writeResult == LAWICEL.ERROR_CANUSB_OK) { //AddToCanTrace("Message sent successfully"); return true; } else { switch (writeResult) { case LAWICEL.ERROR_CANUSB_COMMAND_SUBSYSTEM: AddToCanTrace("Message failed to send: ERROR_CANUSB_COMMAND_SUBSYSTEM"); break; case LAWICEL.ERROR_CANUSB_INVALID_PARAM: AddToCanTrace("Message failed to send: ERROR_CANUSB_INVALID_PARAM"); break; case LAWICEL.ERROR_CANUSB_NO_MESSAGE: AddToCanTrace("Message failed to send: ERROR_CANUSB_NO_MESSAGE"); break; case LAWICEL.ERROR_CANUSB_NOT_OPEN: AddToCanTrace("Message failed to send: ERROR_CANUSB_NOT_OPEN"); break; case LAWICEL.ERROR_CANUSB_OPEN_SUBSYSTEM: AddToCanTrace("Message failed to send: ERROR_CANUSB_OPEN_SUBSYSTEM"); break; case LAWICEL.ERROR_CANUSB_TX_FIFO_FULL: AddToCanTrace("Message failed to send: ERROR_CANUSB_TX_FIFO_FULL"); break; default: AddToCanTrace("Message failed to send: " + writeResult.ToString()); break; } return false; } }
/// <summary> /// Send a message that starts a session. This is used to test if there is /// a connection. /// </summary> /// <returns></returns> private bool sendSessionRequest() { Console.WriteLine("Sending session request"); // 0x220 is for T7 // 0x7E0 is for T8 CANMessage msg1 = new CANMessage(0x7E0, 0, 8); LAWICEL.CANMsg msg = new LAWICEL.CANMsg(); msg1.setData(0x000040021100813f); if (!sendMessage(msg1)) { Console.WriteLine("Unable to send session request"); return false; } if (waitForMessage(0x7E8, 1000, out msg) == 0x7E8) { Console.WriteLine("Message 0x7E8 seen"); //Ok, there seems to be a ECU somewhere out there. //Now, sleep for 10 seconds to get a session timeout. This is needed for //applications on higher level. Otherwise there will be no reply when the //higher level application tries to start a session. Thread.Sleep(10000); Console.WriteLine("sendSessionRequest: TRUE"); return true; } Console.WriteLine("sendSessionRequest: FALSE"); return false; }
private bool SendTransferData011(int length, int address, uint waitforResponseID) { CANMessage msg = new CANMessage(0x11, 0, 8); // <GS-24052011> test for ELM327, set length to 16 (0x10) ulong cmd = 0x0000000000360010; // 0x36 = transferData ulong addressHigh = (uint)address & 0x0000000000FF0000; addressHigh /= 0x10000; ulong addressMiddle = (uint)address & 0x000000000000FF00; addressMiddle /= 0x100; ulong addressLow = (uint)address & 0x00000000000000FF; ulong len = (ulong)length; cmd |= (addressLow * 0x100000000000000); cmd |= (addressMiddle * 0x1000000000000); cmd |= (addressHigh * 0x10000000000); cmd |= (len * 0x100); //Console.WriteLine("send: " + cmd.ToString("X16")); msg.setData(cmd); m_canListener.setupWaitMessage(waitforResponseID); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); //Console.WriteLine("Received in SendTransferData: " + data.ToString("X16")); if (getCanData(data, 0) != 0x30 || getCanData(data, 1) != 0x00) { return false; } return true; }
private bool StartBootloader011() { CANMessage msg = new CANMessage(0x11, 0, 7); //<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0060241000803606; msg.setData(cmd); m_canListener.setupWaitMessage(0x311); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x76) { return false; } return true; }
private bool SendSecretCode2() { //44585349006EAE07 CANMessage msg = new CANMessage(0x7E0, 0, 8); ulong cmd = 0x44585349006EAE07; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); ulong rxdata = ECMresponse.getData(); if (getCanData(rxdata, 1) == 0xEE && getCanData(rxdata, 2) == 0x6E) { return true; } return false; }
private bool SendSecretCodetoCIM() { //0044585349603B06 CANMessage msg = new CANMessage(0x245, 0, 8); ulong cmd = 0x0044585349603B06; msg.setData(cmd); m_canListener.setupWaitMessage(0x645); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); ulong rxdata = ECMresponse.getData(); if(getCanData(rxdata, 1) == 0x7B && getCanData(rxdata, 2) == 0x60) { return true; } return false; }
private bool SendrequestDownload(bool recoveryMode) { CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte //06 34 01 00 00 00 00 00 ulong cmd = 0x0000000000013406; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } bool eraseDone = false; int eraseCount = 0; int waitCount = 0; while (!eraseDone) { m_canListener.setupWaitMessage(0x7E8); // TEST ELM327 31082011 CANMessage response = new CANMessage(); response = m_canListener.waitMessage(500); // 1 seconds! ulong data = response.getData(); if (data == 0) { m_canListener.setupWaitMessage(0x311); // TEST ELM327 31082011 response = new CANMessage(); response = m_canListener.waitMessage(500); // 1 seconds! data = response.getData(); } // response will be 03 7F 34 78 00 00 00 00 a couple of times while erasing if (getCanData(data, 0) == 0x03 && getCanData(data, 1) == 0x7F && getCanData(data, 2) == 0x34 && getCanData(data, 3) == 0x78 ) { if (recoveryMode) BroadcastKeepAlive(); else SendKeepAlive(); eraseCount ++; string info = "Erasing flash"; for(int i = 0; i < eraseCount; i ++) info += "."; CastInfoEvent(info, ActivityType.ErasingFlash); } else if (getCanData(data, 0) == 0x01 && getCanData(data, 1) == 0x74) { if (recoveryMode) BroadcastKeepAlive(); else SendKeepAlive(); eraseDone = true; return true; } else if (getCanData(data, 0) == 0x03 && getCanData(data, 1) == 0x7F && getCanData(data, 2) == 0x34 && getCanData(data, 3) == 0x11) { CastInfoEvent("Erase cannot be performed", ActivityType.ErasingFlash); return false; } else { Console.WriteLine("Rx: " + data.ToString("X16")); if (!recoveryMode && canUsbDevice is CANELM327Device) SendKeepAlive(); } waitCount++; if (waitCount > 30) { CastInfoEvent("Erase timed out after 30 seconds", ActivityType.ErasingFlash); // ELM327 seem to be unable to wait long enough for this response // Instead we assume its finnished ok after 30 seconds if (canUsbDevice is CANELM327Device) { return true; } else { return false; } } Thread.Sleep(2); } return true; }
private byte[] sendReadDataByLocalIdentifier(int address, int length, out bool success) { // we send: 0040000000002106 // .. send: 06 21 80 00 00 00 00 00 success = false; byte[] retData = new byte[length]; if (!canUsbDevice.isOpen()) return retData; CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte //Console.WriteLine("Reading " + address.ToString("X8") + " len: " + length.ToString("X2")); ulong cmd = 0x0000000000002106; // always 2 bytes ulong addressHigh = (uint)address & 0x0000000000FF0000; addressHigh /= 0x10000; ulong addressMiddle = (uint)address & 0x000000000000FF00; addressMiddle /= 0x100; ulong addressLow = (uint)address & 0x00000000000000FF; ulong len = (ulong)length; cmd |= (addressLow * 0x1000000000000); cmd |= (addressMiddle * 0x10000000000); cmd |= (addressHigh * 0x100000000); cmd |= (len * 0x10000); // << 2 * 8 //Console.WriteLine("send: " + cmd.ToString("X16")); /*cmd |= (ulong)(byte)(address & 0x000000FF) << 4 * 8; cmd |= (ulong)(byte)((address & 0x0000FF00) >> 8) << 3 * 8; cmd |= (ulong)(byte)((address & 0x00FF0000) >> 2 * 8) << 2 * 8; cmd |= (ulong)(byte)((address & 0xFF000000) >> 3 * 8) << 8;*/ msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } // wait for max two messages to get rid of the alive ack message CANMessage response = new CANMessage(); ulong data = 0; response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); if (getCanData(data, 0) == 0x7E) { AddToCanTrace("Got 0x7E message as response to 0x21, ReadDataByLocalIdentifier command"); success = false; return retData; } else if (response.getData() == 0x00000000) { AddToCanTrace("Get blank response message to 0x21, ReadDataByLocalIdentifier"); success = false; return retData; } else if (getCanData(data, 0) == 0x03 && getCanData(data, 1) == 0x7F && getCanData(data, 2) == 0x23) { // reason was 0x31 AddToCanTrace("No security access granted"); RequestSecurityAccess(0); success = false; return retData; } else if (getCanData(data, 2) != 0x61 && getCanData(data, 1) != 0x61) { if (data == 0x0000000000007E01) { // was a response to a KA. } AddToCanTrace("Incorrect response to 0x23, sendReadDataByLocalIdentifier. Byte 2 was " + getCanData(data, 2).ToString("X2")); success = false; return retData; } //TODO: Check whether we need more than 2 bytes of data and wait for that many records after sending an ACK int rx_cnt = 0; byte frameIndex = 0x21; if (length > 4) { retData[rx_cnt++] = getCanData(data, 4); retData[rx_cnt++] = getCanData(data, 5); retData[rx_cnt++] = getCanData(data, 6); retData[rx_cnt++] = getCanData(data, 7); // in that case, we need more records from the ECU // Thread.Sleep(1); SendMessage(0x7E0, 0x0000000000000030); // send ack to request more bytes //Thread.Sleep(1); // now we wait for the correct number of records to be received int m_nrFrameToReceive = ((length - 4) / 7); if ((len - 4) % 7 > 0) m_nrFrameToReceive++; //AddToCanTrace("Number of frames: " + m_nrFrameToReceive.ToString()); while (m_nrFrameToReceive > 0) { // response = new CANMessage(); //response.setData(0); //response.setID(0); // m_canListener.setupWaitMessage(0x7E8); response = m_canListener.waitMessage(1000); data = response.getData(); //AddToCanTrace("frame " + frameIndex.ToString("X2") + ": " + data.ToString("X16")); if (frameIndex != getCanData(data, 0)) { // sequence broken AddToCanTrace("Received invalid sequenced frame " + frameIndex.ToString("X2") + ": " + data.ToString("X16")); m_canListener.dumpQueue(); success = false; return retData; } else if (data == 0x0000000000000000) { AddToCanTrace("Received blank message while waiting for data"); success = false; return retData; } frameIndex++; if (frameIndex > 0x2F) frameIndex = 0x20; // additional check for sequencing of frames m_nrFrameToReceive--; //AddToCanTrace("frames left: " + m_nrFrameToReceive.ToString()); // add the bytes to the receive buffer //string checkLine = string.Empty; for (uint fi = 1; fi < 8; fi++) { //checkLine += getCanData(data, fi).ToString("X2"); if (rx_cnt < retData.Length) // prevent overrun { retData[rx_cnt++] = getCanData(data, fi); } } //AddToCanTrace("frame(2): " + checkLine); //Thread.Sleep(1); } } else { if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 4); if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 5); if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 6); if (retData.Length > rx_cnt) retData[rx_cnt++] = getCanData(data, 7); //AddToCanTrace("received data: " + retData[0].ToString("X2")); } /*string line = address.ToString("X8") + " "; foreach (byte b in retData) { line += b.ToString("X2") + " "; } AddToCanTrace(line);*/ success = true; return retData; }
private void SendMessage(uint id, ulong data) { if(canUsbDevice is CANELM327Device) return; CANMessage msg = new CANMessage(); msg.setID(id); msg.setLength(8); msg.setData(data); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Failed to send message"); } }
//--------------------------------------------------------------------------------------------- /** Tries to connect to CAN bus using the specified bitrate. @param bitrate bitrate @param check_traffic check for CAN traffic @return succ / fail */ private bool try_bitrate(uint bitrate, bool check_traffic) { try { // try connecting this.combi.CAN_SetBitrate(bitrate); this.combi.CAN_Open(true); if (check_traffic) { // look for bus activity CANMessage msg = new CANMessage(); Debug.Assert(msg != null); if (this.waitForMessage(0, 1000, out msg) < 1) { throw new Exception("No traffic at given bitrate"); } } return true; } catch { // failed this.combi.CAN_Open(false); return false; } }
private bool StartSession20() { CANMessage msg = new CANMessage(0x7E0, 0, 2);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x0000000000002001; // 0x02 0x10 0x02 msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x60) { return false; } return true; }
/// <summary> /// readMessages is the "run" method of this class. It reads all incomming messages /// and publishes them to registered ICANListeners. /// </summary> public void readMessages() { int readResult = 0; LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg(); CANMessage canMessage = new CANMessage(); Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { // Console.WriteLine(r_canMsg.id.ToString("X3") + " " + r_canMsg.data.ToString("X8")); if (MessageContainsInformationForRealtime(r_canMsg.id)) { canMessage.setID(r_canMsg.id); canMessage.setLength(r_canMsg.len); canMessage.setTimeStamp(r_canMsg.timestamp); canMessage.setFlags(r_canMsg.flags); canMessage.setData(r_canMsg.data); lock (m_listeners) { AddToCanTrace("RX: " + r_canMsg.id.ToString("X4") + " " + r_canMsg.data.ToString("X16")); foreach (ICANListener listener in m_listeners) { //while (listener.messagePending()) ; // dirty, make this better listener.handleMessage(canMessage); } //CastInformationEvent(canMessage); // <GS-05042011> re-activated this function } //Thread.Sleep(1); } // cast event to application to process message //if (MessageContainsInformationForRealtime(r_canMsg.id)) //{ //TODO: process all other known msg id's into the realtime view // CastInformationEvent(canMessage); // <GS-05042011> re-activated this function //} } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); } } }
private bool UploadBootloaderProg011() { int startAddress = 0x102400; Bootloader btloaderdata = new Bootloader(); int txpnt = 0; byte iFrameNumber = 0x21; if (requestDownload011()) { for (int i = 0; i < 0x46; i++) { iFrameNumber = 0x21; //10 F0 36 00 00 10 24 00 //Console.WriteLine("Sending bootloader: " + startAddress.ToString("X8")); // cast event float percentage = ((float)i * 100) / 70F; CastProgressWriteEvent(percentage); if (SendTransferData011(0xF0, startAddress, 0x311)) { // send 0x22 (34) frames with data from bootloader CANMessage msg = new CANMessage(0x11, 0, 8); for (int j = 0; j < 0x22; j++) { ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 1); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 2); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 3); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 4); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 5); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 6); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(2); } // send the remaining data m_canListener.setupWaitMessage(0x311); // now wait for 01 76 00 00 00 00 00 00 CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x76) { return false; } BroadcastKeepAlive(); startAddress += 0xEA; } else { Console.WriteLine("Did not receive correct response from SendTransferData"); } } iFrameNumber = 0x21; if (SendTransferData011(0x0A, startAddress, 0x311)) { // send 0x22 (34) frames with data from bootloader CANMessage msg = new CANMessage(0x11, 0, 8); ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 1); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 2); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 3); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 4); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 5); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 6); msg.setCanData(btloaderdata.BootloaderProgBytes[txpnt++], 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(2); // send the remaining data m_canListener.setupWaitMessage(0x311); // now wait for 01 76 00 00 00 00 00 00 CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong data = response.getData(); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x76) { return false; } BroadcastKeepAlive(); startAddress += 0x06; } else { Console.WriteLine("Did not receive correct response from SendTransferData"); } CastProgressWriteEvent(100); } return true; }
/// <summary> /// waitForMessage waits for a specific CAN message give by a CAN id. /// </summary> /// <param name="a_canID">The CAN id to listen for</param> /// <param name="timeout">Listen timeout</param> /// <param name="r_canMsg">The CAN message with a_canID that we where listening for.</param> /// <returns>The CAN id for the message we where listening for, otherwise 0.</returns> public override uint waitForMessage(uint a_canID, uint timeout, out CANMessage canMsg) { /* int readResult = 0; int nrOfWait = 0; while (nrOfWait < timeout) { LAWICEL.CANMsg r_canMsg = new LAWICEL.CANMsg(); canMsg = new CANMessage(); readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { //Console.WriteLine("rx id: 0x" + r_canMsg.id.ToString("X4")); if (r_canMsg.id != a_canID) { nrOfWait++; continue; } else { canMsg.setID(r_canMsg.id); canMsg.setData(r_canMsg.data); canMsg.setFlags(r_canMsg.flags); return (uint)r_canMsg.id; } } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); nrOfWait++; } } canMsg = new CANMessage(); return 0;*/ LAWICEL.CANMsg r_canMsg; canMsg = new CANMessage(); int readResult = 0; int nrOfWait = 0; while (nrOfWait < timeout) { r_canMsg = new LAWICEL.CANMsg(); readResult = LAWICEL.canusb_Read(m_deviceHandle, out r_canMsg); if (readResult == LAWICEL.ERROR_CANUSB_OK) { Thread.Sleep(1); AddToCanTrace("rx: 0x" + r_canMsg.id.ToString("X4") + r_canMsg.data.ToString("X16")); if (r_canMsg.id == 0x00) { nrOfWait++; } else if (r_canMsg.id != a_canID) continue; canMsg.setData(r_canMsg.data); canMsg.setID(r_canMsg.id); canMsg.setLength(r_canMsg.len); return (uint)r_canMsg.id; } else if (readResult == LAWICEL.ERROR_CANUSB_NO_MESSAGE) { Thread.Sleep(1); nrOfWait++; } } r_canMsg = new LAWICEL.CANMsg(); return 0; }
public byte[] getSRAMSnapshotWithBootloader() { _stallKeepAlive = true; bool success = false; int retryCount = 0; int startAddress = 0x100000; int blockSize = 0x80; // defined in bootloader... keep it that way! int bufpnt = 0; byte[] buf = new byte[0x008000]; int blockCount = 0; SendKeepAlive(); sw.Reset(); sw.Start(); CastInfoEvent("Starting session", ActivityType.UploadingBootloader); StartSession10(); CastInfoEvent("Requesting mandatory data", ActivityType.UploadingBootloader); RequestECUInfo(0x90); RequestECUInfo(0x97); RequestECUInfo(0x92); RequestECUInfo(0xB4); RequestECUInfo(0xC1); RequestECUInfo(0xC2); RequestECUInfo(0xC3); RequestECUInfo(0xC4); RequestECUInfo(0xC5); RequestECUInfo(0xC6); Send0120(); Thread.Sleep(1000); StartSession1081(); StartSession10(); CastInfoEvent("Telling ECU to clear CANbus", ActivityType.UploadingBootloader); SendShutup(); SendA2(); SendA5(); SendA503(); Thread.Sleep(500); SendKeepAlive(); _securityLevel = AccessLevel.AccessLevel01; CastInfoEvent("Requesting security access", ActivityType.UploadingBootloader); RequestSecurityAccess(500); Thread.Sleep(500); CastInfoEvent("Uploading bootloader", ActivityType.UploadingBootloader); UploadBootloader(); CastInfoEvent("Starting bootloader", ActivityType.UploadingBootloader); // start bootloader in ECU Thread.Sleep(500); StartBootloader(); SendKeepAlive(); Thread.Sleep(500); CastInfoEvent("Downloading snapshot", ActivityType.DownloadingFlash); // now start sending commands: //06 21 80 00 00 00 00 00 // response: //10 82 61 80 00 10 0C 00 // 4 bytes data already //for (int i = 0; i < buf.Length / blockSize; i++) while (startAddress < 0x108000) { if (!canUsbDevice.isOpen()) { _stallKeepAlive = false; return buf; } byte[] readbuf = readDataByLocalIdentifier(startAddress, blockSize, out success); if (success) { if (readbuf.Length == blockSize) { for (int j = 0; j < blockSize; j++) { buf[bufpnt++] = readbuf[j]; } } //string infoStr = "Address: " + startAddress.ToString("X8"); //+ " "; CastProgressReadEvent((float)(bufpnt * 100) / (float)buf.Length); startAddress += blockSize; retryCount = 0; } else { CastInfoEvent("Frame dropped, retrying " + startAddress.ToString("X8") + " " + retryCount.ToString(), ActivityType.DownloadingFlash); retryCount++; // read all available message from the bus now for (int i = 0; i < 10; i++) { CANMessage response = new CANMessage(); ulong data = 0; response = new CANMessage(); response = m_canListener.waitMessage(10); data = response.getData(); } if (retryCount == maxRetries) { CastInfoEvent("Failed to download flash content", ActivityType.ConvertingFile); _stallKeepAlive = false; return buf; } } blockCount++; if (sw.ElapsedMilliseconds > 3000) // once every 3 seconds //if ((blockCount % 10) == 0) { sw.Stop(); sw.Reset(); SendKeepAlive(); sw.Start(); } } sw.Stop(); _stallKeepAlive = false; return buf; }
/// <summary> /// Send a KWP request. /// </summary> /// <param name="a_request">A KWP request.</param> /// <param name="r_reply">A KWP reply.</param> /// <returns>The status of the request.</returns> public RequestResult sendRequest(KWPRequest a_request, out KWPReply r_reply) { CANMessage msg = new CANMessage(0x7E0, 0, 8); uint row = nrOfRowsToSend(a_request.getData()); m_kwpCanListener.setupWaitMessage(0x7E8); // Send one or several request messages. for (; row > 0; row--) { msg.setData(createCanMessage(a_request.getData(), row - 1)); if (!m_canDevice.sendMessage(msg)) { r_reply = new KWPReply(); return RequestResult.ErrorSending; } } msg = m_kwpCanListener.waitMessage(timeoutPeriod); // msg = m_kwpCanListener.waitForMessage(0x7E8, timeoutPeriod); // Receive one or several replys and send an ack for each reply. if (msg.getID() == 0x7E8) { uint nrOfRows = (uint)(msg.getCanData(0) & 0x3F)+ 1; row = 0; if (nrOfRows == 0) throw new Exception("Wrong nr of rows"); //Assume that no KWP reply contains more than 0x200 bytes byte[] reply = new byte[0x200]; reply = collectReply(reply, msg.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; m_kwpCanListener.setupWaitMessage(0x7E8); while (nrOfRows > 0) { // msg = m_kwpCanListener.waitForMessage(0x7E8, timeoutPeriod); msg = m_kwpCanListener.waitMessage(timeoutPeriod); if (msg.getID() == 0x7E8) { row++; reply = collectReply(reply, msg.getData(), row); sendAck(nrOfRows - 1); nrOfRows--; } else { r_reply = new KWPReply(); return RequestResult.Timeout; } } r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.NoError; } else { r_reply = new KWPReply(); return RequestResult.Timeout; } }
public void InitializeSession() { CANMessage response = new CANMessage(); //101 8 FE 01 3E 00 00 00 00 00 CANMessage msg = new CANMessage(0x11, 0, 2); ulong cmd = 0x0000000000003E01; msg.setData(cmd); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } /* // first send ulong data = 0; CANMessage msg = new CANMessage(0x7E0, 0, 8); ulong cmd = 0x0000000000005001; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received1: " + data.ToString("X8")); cmd = 0x0000000000006801; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received2: " + data.ToString("X8")); response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received3: " + data.ToString("X8")); cmd = 0x000000000000E501; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!m_canDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("Received4: " + data.ToString("X8"));*/ }
/// <summary> /// Send an acknowledgement message. /// </summary> /// <param name="a_rowNr">The row number that should be acknowledged.</param> private void sendAck(uint a_rowNr) { CANMessage msg = new CANMessage(0x266,0,8); uint i = 0; ulong data = 0; data = setCanData(data, (byte)0x40, i++); // ? data = setCanData(data, (byte)0xA1, i++); data = setCanData(data, (byte)0x3F, i++); data = setCanData(data, (byte)(0x80 | (int)(a_rowNr)), i++); msg.setData(data); if (!m_canDevice.sendMessage(msg)) throw new Exception("Error sending ack"); }
private void SendDeviceControlMessage(byte command) { CANMessage msg = new CANMessage(0x7E0, 0, 3);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000000AE02; ulong lcommand = command; cmd |= (lcommand * 0x10000); msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); }
public override bool sendMessage(CANMessage a_message) { string sendString = " "; /*if (a_message.getID() == 0x11) { // try to insert length ourselves sendString = " "; sendString += a_message.getLength().ToString("X2"); }*/ Console.WriteLine("send: " + a_message.getID().ToString("X3") + " " + a_message.getData().ToString("X16")); if (a_message.getID() != _ECUAddress) { _ECUAddress = a_message.getID(); string command = "ATSH" + a_message.getID().ToString("X3"); /*if (_ECUAddress == 0x11) { command = "ATSH 0000" + a_message.getID().ToString("X3"); }*/ m_serialPort.Write(command + "\r"); //Set header to 7E0 = ECU AddToSerialTrace("SERTX: " + command); CastInformationEvent("Switching to ID: " + a_message.getID().ToString("X3")); string answer = m_serialPort.ReadTo(">"); CastInformationEvent(command + " response: " + answer); } for (uint i = 0; i < a_message.getLength(); i++) // leave out the length field, the ELM chip assigns that for us { //if (i <= 7) { sendString += a_message.getCanData(i).ToString("X2"); } /*else { sendString += "00"; // fill with zeros }*/ } //sendString = sendString.Trim(); sendString += "\r"; if (m_serialPort.IsOpen) { m_serialPort.Write(sendString); AddToSerialTrace("SERTX: " + sendString); //Console.WriteLine("TX: " + sendString); AddToCanTrace("TX: " + a_message.getID().ToString("X3") + " " + sendString); } // bitrate = 38400bps -> 4800 bytes per second // sending each byte will take 0.2 ms approx // bitrate = 115200bps -> 14400 bytes per second // sending each byte will take 0,07 ms approx Thread.Sleep(2); // sleep length ms //07E0 0000000000003E01 if (a_message.getID() == 0x7E0 && a_message.getCanData(0) == 0x01 && a_message.getCanData(1) == 0x3E) { //m_serialPort.Write("ATMA\r"); //AddToSerialTrace("SERTX: ATMA"); } // Thread.Sleep(10); //receiveString = "49 01 01 00 00 00 31 \n\r49 02 02 44 34 47 50 \n\r49 02 03 30 30 52 35 \n\r49 02 04 25 42";// m_serialPort.ReadTo(">"); /*receiveString = m_serialPort.ReadTo(">"); char[] chrArray = receiveString.ToCharArray(); byte[] reply = new byte[0xFF]; int insertPos = 1; int index = 0; string subString = ""; while (receiveString.Length > 4) { //Remove first three bytes //TODO. Remove Mode and PIDs for (int i = 0; i < 3; i++) { index = receiveString.IndexOf(" "); receiveString = receiveString.Remove(0, index + 1); } //Read data for the rest of the row. for (int i = 0; i < 4; i++) { index = receiveString.IndexOf(" "); if (index == 0) //Last row not 4 bytes of data. { continue; } subString = receiveString.Substring(0, index); reply[insertPos] = (byte)Convert.ToInt16("0x" + subString, 16); insertPos++; receiveString = receiveString.Remove(0, index + 1); } } reply[0] = (byte)insertPos; //Length r_reply = new KWPReply(reply, a_request.getNrOfPID()); return RequestResult.NoError;*/ return true; // remove after implementation }
//--------------------------------------------------------------------------------------------- /** Sends a 11 bit CAN data frame. @param msg CAN message @return success (true/false) */ public override bool sendMessage(CANMessage msg) { //Console.WriteLine("TX: " + msg.getID().ToString("X4") + " " + msg.getData().ToString("X16")); this.AddToCanTrace("Sending message: " + msg.getID().ToString("X4") + " " + msg.getData().ToString("X16") + " " + msg.getLength().ToString("X2")); try { Combi.caCombiAdapter.caCANFrame frame; frame.id = msg.getID(); frame.length = msg.getLength(); frame.data = msg.getData(); frame.is_extended = 0; frame.is_remote = 0; this.combi.CAN_SendMessage(ref frame); this.AddToCanTrace("Message sent successfully"); return true; } catch (Exception e) { this.AddToCanTrace("Message failed to send: " + e.Message); return false; } }
/// <summary> /// This method is called by ICANDevices where derived objects of this class /// are registered. The method is called for each received CANMessage. /// What this method does is application dependent. /// </summary> /// <param name="a_canMessage">The CANMessage to be handled by this method.</param> public abstract void handleMessage(CANMessage a_canMessage);
private void SendDeviceControlMessageWithCode(byte command, string secretcode /*ulong code*/) { CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte ulong cmd = 0x000000000000AE07; ulong lcommand = command; cmd |= (lcommand * 0x10000); ulong code = 0; //0x4D4E415100000000 code |= Convert.ToByte(secretcode[3]); code = code << 8; code |= Convert.ToByte(secretcode[2]); code = code << 8; code |= Convert.ToByte(secretcode[1]); code = code << 8; code |= Convert.ToByte(secretcode[0]); code = code << 4 * 8; cmd |= code; msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { Console.WriteLine("Couldn't send message"); } CANMessage ECMresponse = new CANMessage(); ECMresponse = m_canListener.waitMessage(1000); }