public void downloader() { int t = 0; CanPacket outCp = null; CanPacket cp = null; byte[] data = new byte[8]; byte offset = 0; ulong currentAddress = 0; try { while (true) { bool hasMessage = sc.getPacket(out cp); if (hasMessage) { Array.Copy(cp.data, data, 8); } bool hasMessageFromTarget = (hasMessage && cp.type== td.PACKET_TYPE.ptBOOT && cp.boot.rid==MY_ID && cp.sid == TARGET_ID); switch (pgs) { case dState.SEND_START: // Send boot start packet to target. // and wait for ack. currentAddress = hf.getAddrLower(); data[2] = (byte)((currentAddress & 0xFF0000) >> 16); data[1] = (byte)((currentAddress & 0xFF00) >> 8); data[0] = (byte)(currentAddress & 0xFF); outCp = new CanPacket(new CanPacket.canBOOTPacket(td.BOOT_TYPE.btADDR, 0, TARGET_ID), MY_ID, 3, data); sc.writePacket(outCp); t = Environment.TickCount; pgs = dState.WAIT_ACK; timeStart = Environment.TickCount; hasFoundNode = false; break; case dState.WAIT_ACK: // Check for timeout, resend start packet in that case.. if ((Environment.TickCount - t) > TIMEOUT_MS) { pgs = dState.SEND_START; } // If received ack. if (hasMessageFromTarget && cp.boot.type == td.BOOT_TYPE.btACK) { // Start sending program data.. offset = 0; pgs = dState.SEND_PGM_DATA; hasFoundNode = true; } // if nack if (hasMessageFromTarget && cp.boot.type == td.BOOT_TYPE.btNACK) { // else resend start.. pgs = dState.SEND_START; } break; case dState.SEND_PGM_DATA: // Send program data. for (ulong i = 0; i < 8; i++) { // Populate data. data[i] = hf.getByte(currentAddress + i + offset); } outCp = new CanPacket(new CanPacket.canBOOTPacket(td.BOOT_TYPE.btPGM, offset, TARGET_ID), MY_ID, 8, data); sc.writePacket(outCp); t = Environment.TickCount; pgs = dState.WAIT_OWN_PACKET; break; case dState.WAIT_OWN_PACKET: // Wait reciving own packet, if timeout, resend last. if ((Environment.TickCount - t) > TIMEOUT_MS) { pgs = dState.SEND_PGM_DATA; } // If received own packet.. if (hasMessage && outCp.Equals(cp)) { offset += 8; // Check if 64 bytes sent or not.. if (offset % 64 == 0) { // Yes, send crc. t = Environment.TickCount; pgs = dState.SEND_CRC; } else { // No, send more. pgs = dState.SEND_PGM_DATA; } } break; case dState.SEND_CRC: byte[] pgmData = new byte[64]; for(ulong i=0;i<64;i++) pgmData[i] = hf.getByte(i+currentAddress); ushort crc = crc16.calc_crc(pgmData, 64); data[4] = (byte)((crc & 0xFF00) >> 8); data[3] = (byte)(crc & 0xFF); data[2] = (byte)(((currentAddress + offset) & 0xFF0000) >> 16); data[1] = (byte)(((currentAddress + offset) & 0xFF00) >> 8); data[0] = (byte)((currentAddress + offset) & 0xFF); outCp = new CanPacket(new CanPacket.canBOOTPacket(td.BOOT_TYPE.btCRC, offset, TARGET_ID), MY_ID, 8, data); sc.writePacket(outCp); t = Environment.TickCount; pgs = dState.WAIT_CRC_ACK; break; case dState.WAIT_CRC_ACK: // Check for timeout, resend start packet in that case.. if ((Environment.TickCount - t) > TIMEOUT_MS) { pgs = dState.SEND_CRC; } // If received ack. if (hasMessageFromTarget && cp.boot.type == td.BOOT_TYPE.btACK) { // Start send more program data.. currentAddress += offset; offset = 0; pgs = dState.SEND_PGM_DATA; hasFoundNode = true; if (currentAddress > hf.getAddrUpper()) { // Yes, we are done, send done. pgs = dState.SEND_DONE; } } // if nack if (hasMessageFromTarget && cp.boot.type == td.BOOT_TYPE.btNACK) { // else resend pgm data... offset = 0; pgs = dState.SEND_PGM_DATA; } break; case dState.SEND_DONE: outCp = new CanPacket(new CanPacket.canBOOTPacket(td.BOOT_TYPE.btDONE, offset, TARGET_ID), MY_ID, 8, data); sc.writePacket(outCp); t = Environment.TickCount; pgs = dState.DONE; break; case dState.DONE: abortmode = abortMode.PROGRAM; down.Abort(); break; // -------------------------------- CHANGE ID NID ------------------------------------ case dState.CHANGE_ID_START: // Send change id packet // and wait for own packet. data[0] = tmp_new_id; outCp = new CanPacket(new CanPacket.canBOOTPacket(td.BOOT_TYPE.btCHANGEID, 0, TARGET_ID), MY_ID, 1, data); sc.writePacket(outCp); t = Environment.TickCount; pgs = dState.CHANGE_ID_WAIT_ACK_PACKET; timeStart = Environment.TickCount; break; case dState.CHANGE_ID_WAIT_ACK_PACKET: // Wait reciving own packet, if timeout, resend last. if ((Environment.TickCount - t) > TIMEOUT_MS) { pgs = dState.CHANGE_ID_START; } if (hasMessage && cp.type == td.PACKET_TYPE.ptBOOT && cp.sid == tmp_new_id && cp.boot.type == td.BOOT_TYPE.btACK) { pgs = dState.CHANGE_ID_DONE; } break; case dState.CHANGE_ID_DONE: abortmode = abortMode.CHANGE_ID; down.Abort(); break; } Thread.Sleep(0); } } catch(Exception) { int hfLength = 0; if (hf != null) hfLength = (int)hf.getLength(); threadAbort.Invoke(this, new threadAbortEvent((int)(Environment.TickCount - timeStart), hfLength, abortmode)); } }