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); } } */ }
/// <summary> /// Write a byte array to an address. /// </summary> /// <param name="address">Address. Must be greater than 0x1000</param> /// <param name="data">Data to be written</param> /// <returns></returns> //KWP2000 can read more than 6 bytes at a time.. but for now we are happy with this public bool writeMemory(int address, byte[] memdata) { if (!canUsbDevice.isOpen()) return false; _stallKeepAlive = true; /* for (int i = 0; i < 6; i++) { InitializeSession(); Thread.Sleep(1000); }*/ CANMessage response = new CANMessage(); ulong data = 0; // first send CANMessage msg = new CANMessage(0x7E0, 0, 7);//<GS-18052011> ELM327 support requires the length byte //Console.WriteLine("Writing " + address.ToString("X8") + " len: " + memdata.Length.ToString("X2")); ulong cmd = 0x0000000000003406; // 0x34 = upload data to ECU ulong addressHigh = (uint)address & 0x0000000000FF0000; addressHigh /= 0x10000; ulong addressMiddle = (uint)address & 0x000000000000FF00; addressMiddle /= 0x100; ulong addressLow = (uint)address & 0x00000000000000FF; ulong len = (ulong)memdata.Length; //cmd |= (addressLow * 0x100000000); //cmd |= (addressMiddle * 0x1000000); //cmd |= (addressHigh * 0x10000); // cmd |= (len * 0x1000000000000); msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); CastInfoEvent("Waited for response: " + data.ToString("X8"), ActivityType.ConvertingFile); if (getCanData(data, 0) != 0x01 || getCanData(data, 1) != 0x74) { CastInfoEvent("Unable to write to ECUs memory", ActivityType.ConvertingFile); AddToCanTrace("Unable to write data to ECUs memory"); //_stallKeepAlive = false; //return false; } //10 F0 36 00 00 10 24 00 cmd = 0x0000000000360010; // 0x34 = upload data to ECU cmd |= (addressLow * 0x100000000000000); cmd |= (addressMiddle * 0x1000000000000); cmd |= (addressHigh * 0x10000000000); cmd |= (len * 0x100); //Console.WriteLine("send: " + cmd.ToString("X16")); msg.setData(cmd); m_canListener.setupWaitMessage(0x7E8); if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } // wait for response, should be 30 00 00 00 00 00 00 00 data = 0; response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); int numberOfFrames = (int)len / 7; // remnants? if (((int)len % 7) > 0) numberOfFrames++; byte iFrameNumber = 0x21; int txpnt = 0; if (data == 0x0000000000000030) { for (int i = 0; i < numberOfFrames; i ++) { cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(memdata[txpnt++], 1); msg.setCanData(memdata[txpnt++], 2); msg.setCanData(memdata[txpnt++], 3); msg.setCanData(memdata[txpnt++], 4); msg.setCanData(memdata[txpnt++], 5); msg.setCanData(memdata[txpnt++], 6); msg.setCanData(memdata[txpnt++], 7); iFrameNumber++; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(1); // send the data with 7 bytes at a time } m_canListener.setupWaitMessage(0x7E8); response = new CANMessage(); response = m_canListener.waitMessage(1000); data = response.getData(); Console.WriteLine("received: " + data.ToString("X8")); } _stallKeepAlive = false; return true; }
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; }
public bool testSRAMWrite(/*int address, byte[] data*/) { 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(2000); Thread.Sleep(500); CastInfoEvent("Uploading data", ActivityType.UploadingBootloader); int startAddress = 0x102400; Bootloader btloaderdata = new Bootloader(); if (requestDownload()) { for (int i = 0; i < 0x46; i++) { //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); byte iFrameNumber = 0x21; if (SendTransferData(0xF0, startAddress, 0x7E8)) { // send 0x22 (34) frames with data from bootloader CANMessage msg = new CANMessage(0x7E0, 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(0x00, 1); msg.setCanData(0x01, 2); msg.setCanData(0x02, 3); msg.setCanData(0x03, 4); msg.setCanData(0x04, 5); msg.setCanData(0x05, 6); msg.setCanData(0x06, 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(1); } // send the remaining data m_canListener.setupWaitMessage(0x7E8); // now wait for 01 76 00 00 00 00 00 00 CANMessage response = new CANMessage(); response = new CANMessage(); response = m_canListener.waitMessage(1000); ulong datax = response.getData(); if (getCanData(datax, 0) != 0x01 || getCanData(datax, 1) != 0x76) { return false; } SendKeepAlive(); startAddress += 0xEA; } else { Console.WriteLine("Did not receive correct response from SendTransferData"); } } } return true; }
public bool UpdateFlash(string filename) { if (!canUsbDevice.isOpen()) return false; _needRecovery = false; BlockManager bm = new BlockManager(); bm.SetFilename(filename); _stallKeepAlive = true; int startAddress = 0x020000; 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(); // verified upto here _securityLevel = AccessLevel.AccessLevel01; CastInfoEvent("Requesting security access", ActivityType.UploadingBootloader); if (!RequestSecurityAccess(2000)) { CastInfoEvent("Failed to get security access", ActivityType.UploadingFlash); _stallKeepAlive = false; return false; } Thread.Sleep(500); CastInfoEvent("Uploading bootloader", ActivityType.UploadingBootloader); if(!UploadBootloaderProg()) { CastInfoEvent("Failed to upload bootloader", ActivityType.UploadingFlash); _stallKeepAlive = false; return false; } CastInfoEvent("Starting bootloader", ActivityType.UploadingBootloader); // start bootloader in ECU //SendKeepAlive(); Thread.Sleep(500); if(!StartBootloader()) { CastInfoEvent("Failed to start bootloader", ActivityType.UploadingFlash); _stallKeepAlive = false; return false; } Thread.Sleep(500); SendKeepAlive(); Thread.Sleep(200); CastInfoEvent("Erasing flash", ActivityType.StartErasingFlash); if (SendrequestDownload(false)) { _needRecovery = true; CastInfoEvent("Programming flash", ActivityType.UploadingFlash); for (int blockNumber = 0; blockNumber <= 0xF50; blockNumber++) { float percentage = ((float)blockNumber * 100) / 3920F; CastProgressWriteEvent(percentage); byte[] data2Send = bm.GetNextBlock(); int length = 0xF0; if (blockNumber == 0xF50) length = 0xE6; if (SendTransferData(length, startAddress + (blockNumber * 0xEA), 0x7E8)) { // send the data from the block // calculate number of frames int numberOfFrames = (int)data2Send.Length / 7; // remnants? if (((int)data2Send.Length % 7) > 0) numberOfFrames++; byte iFrameNumber = 0x21; int txpnt = 0; CANMessage msg = new CANMessage(0x7E0, 0, 8); for (int frame = 0; frame < numberOfFrames; frame++) { ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(data2Send[txpnt++], 1); msg.setCanData(data2Send[txpnt++], 2); msg.setCanData(data2Send[txpnt++], 3); msg.setCanData(data2Send[txpnt++], 4); msg.setCanData(data2Send[txpnt++], 5); msg.setCanData(data2Send[txpnt++], 6); msg.setCanData(data2Send[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(0x7E8); // 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) { _stallKeepAlive = false; return false; } SendKeepAlive(); } } sw.Stop(); _needRecovery = false; CastInfoEvent("Flash upload completed", ActivityType.FinishedFlashing); // what else to do? Send0120(); CastInfoEvent("Session ended", ActivityType.FinishedFlashing); } else { sw.Stop(); _needRecovery = false; _stallKeepAlive = false; CastInfoEvent("Failed to erase flash", ActivityType.FinishedFlashing); Send0120(); CastInfoEvent("Session ended", ActivityType.FinishedFlashing); return false; } _stallKeepAlive = false; return true; }
/// <summary> /// Send ONLY the erase and write commands, ECU is already in running bootloader /// </summary> /// <param name="filename"></param> /// <returns></returns> public bool RecoverECUOLD(string filename) { if (!canUsbDevice.isOpen()) return false; _stallKeepAlive = true; BlockManager bm = new BlockManager(); bm.SetFilename(filename); int startAddress = 0x020000; SendKeepAlive(); _securityLevel = AccessLevel.AccessLevel01; CastInfoEvent("Erasing flash", ActivityType.StartErasingFlash); if (SendrequestDownload(true)) { CastInfoEvent("Programming flash", ActivityType.UploadingFlash); for (int blockNumber = 0; blockNumber <= 0xF50; blockNumber++) { float percentage = ((float)blockNumber * 100) / 3920F; CastProgressWriteEvent(percentage); byte[] data2Send = bm.GetNextBlock(); int length = 0xF0; if (blockNumber == 0xF50) length = 0xE6; if (SendTransferData(length, startAddress + (blockNumber * 0xEA), 0x311)) { // send the data from the block // calculate number of frames int numberOfFrames = (int)data2Send.Length / 7; // remnants? if (((int)data2Send.Length % 7) > 0) numberOfFrames++; byte iFrameNumber = 0x21; int txpnt = 0; CANMessage msg = new CANMessage(0x7E0, 0, 8); for (int frame = 0; frame < numberOfFrames; frame++) { ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(data2Send[txpnt++], 1); msg.setCanData(data2Send[txpnt++], 2); msg.setCanData(data2Send[txpnt++], 3); msg.setCanData(data2Send[txpnt++], 4); msg.setCanData(data2Send[txpnt++], 5); msg.setCanData(data2Send[txpnt++], 6); msg.setCanData(data2Send[txpnt++], 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(1); } // send the remaining data m_canListener.setupWaitMessage(0x7E8); // 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; } SendKeepAlive(); } } sw.Stop(); CastInfoEvent("Flash upload completed", ActivityType.FinishedFlashing); // what else to do? Send0120(); CastInfoEvent("Session ended", ActivityType.FinishedFlashing); } else { sw.Stop(); CastInfoEvent("Failed to erase flash", ActivityType.FinishedFlashing); Send0120(); CastInfoEvent("Session ended", ActivityType.FinishedFlashing); return false; } _stallKeepAlive = false; return true; }
public bool RecoverECU(string filename) { string diagDataID = GetDiagnosticDataIdentifier0101(); Console.WriteLine("DataID: " + diagDataID); if (diagDataID == string.Empty) { BlockManager bm = new BlockManager(); bm.SetFilename(filename); int startAddress = 0x020000; sw.Reset(); sw.Start(); _stallKeepAlive = true; CastInfoEvent("Recovery needed...", ActivityType.UploadingBootloader); BroadcastKeepAlive(); Thread.Sleep(200); // was 1 BroadcastKeepAlive(); Thread.Sleep(500); CastInfoEvent("Starting session", ActivityType.UploadingBootloader); BroadcastSession10(); Thread.Sleep(200); // was 1 CastInfoEvent("Telling ECU to clear CANbus", ActivityType.UploadingBootloader); BroadcastShutup(); Thread.Sleep(200); // was 1 int progState = GetProgrammingState(0x311); if (progState == 0x01) { CastInfoEvent("Recovery needed phase 1", ActivityType.UploadingBootloader); BroadcastShutup011(); if (GetProgrammingState011() == 0x01) { CastInfoEvent("Recovery needed phase 2", ActivityType.UploadingBootloader); SendA5011(); Thread.Sleep(100); SendA503011(); Thread.Sleep(100); BroadcastKeepAlive(); Thread.Sleep(100); CastInfoEvent("Requesting security access...", ActivityType.UploadingBootloader); if (RequestSecurityAccess011(0)) { CastInfoEvent("Security access granted, uploading bootloader", ActivityType.UploadingBootloader); UploadBootloaderProg011(); CastInfoEvent("Starting bootloader", ActivityType.UploadingBootloader); Thread.Sleep(500); StartBootloader011(); Thread.Sleep(500); CastInfoEvent("Erasing flash", ActivityType.StartErasingFlash); if (SendrequestDownload(true)) { _needRecovery = true; CastInfoEvent("Programming flash", ActivityType.UploadingFlash); for (int blockNumber = 0; blockNumber <= 0xF50; blockNumber++) { float percentage = ((float)blockNumber * 100) / 3920F; CastProgressWriteEvent(percentage); byte[] data2Send = bm.GetNextBlock(); int length = 0xF0; if (blockNumber == 0xF50) length = 0xE6; if (SendTransferData(length, startAddress + (blockNumber * 0xEA), 0x311)) { // send the data from the block // calculate number of frames int numberOfFrames = (int)data2Send.Length / 7; // remnants? if (((int)data2Send.Length % 7) > 0) numberOfFrames++; byte iFrameNumber = 0x21; int txpnt = 0; CANMessage msg = new CANMessage(0x7E0, 0, 8); for (int frame = 0; frame < numberOfFrames; frame++) { ulong cmd = 0x0000000000000000; // 0x34 = upload data to ECU msg.setData(cmd); msg.setCanData(iFrameNumber, 0); msg.setCanData(data2Send[txpnt++], 1); msg.setCanData(data2Send[txpnt++], 2); msg.setCanData(data2Send[txpnt++], 3); msg.setCanData(data2Send[txpnt++], 4); msg.setCanData(data2Send[txpnt++], 5); msg.setCanData(data2Send[txpnt++], 6); msg.setCanData(data2Send[txpnt++], 7); iFrameNumber++; if (iFrameNumber > 0x2F) iFrameNumber = 0x20; if (!canUsbDevice.sendMessage(msg)) { AddToCanTrace("Couldn't send message"); } Thread.Sleep(1); } // send the remaining data m_canListener.setupWaitMessage(0x7E8); // 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) { _stallKeepAlive = false; return false; } BroadcastKeepAlive(); } } sw.Stop(); _needRecovery = false; CastInfoEvent("Recovery completed", ActivityType.FinishedFlashing); // what else to do? Send0120(); CastInfoEvent("Session ended", ActivityType.FinishedFlashing); return true; } else { sw.Stop(); _needRecovery = false; _stallKeepAlive = false; CastInfoEvent("Failed to erase flash", ActivityType.FinishedFlashing); Send0120(); CastInfoEvent("Session ended", ActivityType.FinishedFlashing); return false; } } } else { CastInfoEvent("Recovery not needed...", ActivityType.UploadingBootloader); } } else if (progState == 0x00) { CastInfoEvent("Recovery not needed...", ActivityType.UploadingBootloader); } else if (progState == -1) { CastInfoEvent("Unable to communicate with the ECU...", ActivityType.UploadingBootloader); } sw.Stop(); } else { CastInfoEvent("Recovery not needed...", ActivityType.UploadingBootloader); } return false; }
/// <summary> /// Send a message that starts a session. This is used to test if there is /// a connection. /// </summary> /// <returns></returns> public bool sendSessionRequest(byte unit) { AddToCanTrace("Sending session request to unit 0x" + unit.ToString("X2")); for (int i = 0; i < 5; i++) { CANMessage msg1 = new CANMessage(0x7E0, 0, 8); msg1.setData(0x000040021100813f); //msg1.setData(0x000040021100813f); msg1.setCanData(unit, 5); // overwrite the 0x11 with UNIT AddToCanTrace("Sending: " + msg1.getData().ToString("X16") + " id: 0x" + msg1.getID().ToString("X4") + " " + i.ToString()); if (!sendMessage(msg1)) { AddToCanTrace("Unable to send session request"); return false; } uint reponseID = GetIDforUnit(unit); AddToCanTrace("Waiting for ID: 0x" + reponseID.ToString("X4")); if (waitForMessage(reponseID, 500, out msg1) == reponseID) { AddToCanTrace("ResponseID seen"); Console.WriteLine("ResponseID seen"); return true; } AddToCanTrace("no reponse seen from unit 0x" + unit.ToString("X2")); Console.WriteLine("no reponse seen from unit 0x" + unit.ToString("X2")); } return false; }
public int query_data(byte unit, byte data_id, out byte[] answer) { byte[] data = new byte[8]; byte length= 0; byte i = 0; answer = new byte[8]; // test <GS-11012011> int rcv_length; byte[] query = new byte[8] { 0x40, 0x00, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00 }; byte[] ack = new byte[8] { 0x40, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00 }; //ulong query_long = 0x0000000021020040; //ulong ack_long = 0x00000000003F0040; query[1] = unit; ack[1] = unit; // If data_id is zero, decrease length field if (data_id != 0x00) query[4] = data_id; else query[2] = 0x01; data[0] = 0x00; rcv_length = 0; //for (int i = 0; i < 5; i++) { CANMessage msg = new CANMessage(0x240, 0, 8); //msg.setData(query_long); msg.setCanData(query[0], 0); msg.setCanData(query[1], 1); msg.setCanData(query[2], 2); msg.setCanData(query[3], 3); msg.setCanData(query[4], 4); msg.setCanData(query[5], 5); msg.setCanData(query[6], 6); msg.setCanData(query[7], 7); msg.setID(0x240); AddToCanTrace("Sending: 0x" + msg.getData().ToString("X16") + " id: 0x" + msg.getID().ToString("X4")); if (!sendMessage(msg)) { return -1; } uint reply_unit = GetReplyforUnit(unit); reply_unit = 0x258; // for testing purposes while (data[0] != 0x80 && data[0] != 0xC0) { CANMessage replyMessage = new CANMessage(); AddToCanTrace("Waiting for ID: 0x" + reply_unit.ToString("X4")); if (waitForMessage(reply_unit, 1000, out replyMessage) == reply_unit) { AddToCanTrace("Rx data: " + replyMessage.getData().ToString("X16")); data[0] = replyMessage.getCanData(0); data[1] = replyMessage.getCanData(1); data[2] = replyMessage.getCanData(2); data[3] = replyMessage.getCanData(3); data[4] = replyMessage.getCanData(4); data[5] = replyMessage.getCanData(5); data[6] = replyMessage.getCanData(6); data[7] = replyMessage.getCanData(7); int idx = 0; if ((data[0] & 0x40) > 0) { if (data[2] > 0x02) { length = data[2]; // subtract two non-payload bytes length -= 2; answer = new byte[length]; } else length = 0; if (--length > 0) { answer[idx++] = data[5]; rcv_length++; } if (--length > 0) { answer[idx++] = data[6]; rcv_length++; } if (--length > 0) { answer[idx++] = data[7]; rcv_length++; } } else { for (i = 0; i < 6; i++) { answer[idx++] = data[2 + i]; length--; rcv_length++; if (length == 0) i = 6; } } // Send acknowledgement ack[3] = Convert.ToByte(data[0] & 0xBF); CANMessage ackMessage = new CANMessage(); //ackMessage.setData(ack_long); ackMessage.setCanData(ack[0], 0); ackMessage.setCanData(ack[1], 1); ackMessage.setCanData(ack[2], 2); ackMessage.setCanData(ack[3], 3); ackMessage.setCanData(ack[4], 4); ackMessage.setCanData(ack[5], 5); ackMessage.setCanData(ack[6], 6); ackMessage.setCanData(ack[7], 7); ackMessage.setID(0x266); sendMessage(ackMessage); } else { // Timeout AddToCanTrace("Timeout waiting for 0x" + reply_unit.ToString("X3")); return -1; } } } return rcv_length; }
public void readMessages() { CANMessage canMessage = new CANMessage(); string rxMessage = string.Empty; Console.WriteLine("readMessages started"); while (true) { lock (m_synchObject) { if (m_endThread) { Console.WriteLine("readMessages ended"); return; } } try { if (m_serialPort.IsOpen) { do { rxMessage = m_serialPort.ReadLine(); rxMessage = rxMessage.Replace("\r", ""); // remove prompt characters... we don't need that stuff rxMessage = rxMessage.Replace("\n", ""); // remove prompt characters... we don't need that stuff } while (rxMessage.StartsWith("w") == false); uint id = Convert.ToUInt32(rxMessage.Substring(1, 3), 16); if (MessageContainsInformationForRealtime(id)) { canMessage.setID(id); canMessage.setLength(8); canMessage.setData(0x0000000000000000); for (uint i = 0; i < 8; i++) canMessage.setCanData(Convert.ToByte(rxMessage.Substring(5 + (2 * (int)i), 2), 16), i); lock (m_listeners) { AddToCanTrace("RX: " + canMessage.getID().ToString("X3") + " " + canMessage.getLength().ToString("X1") + " " + canMessage.getData().ToString("X16")); //Console.WriteLine("MSG: " + rxMessage); foreach (ICANListener listener in m_listeners) { listener.handleMessage(canMessage); } //CastInformationEvent(canMessage); // <GS-05042011> re-activated this function } //Thread.Sleep(1); } //else { // Thread.Sleep(1); // give others some air } } } catch (Exception) { Console.WriteLine("MSG: " + rxMessage); } } }