private void serial_conn_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) { System.IO.Ports.SerialPort port = (System.IO.Ports.SerialPort)sender; byte[] data = new byte[port.BytesToRead]; int bytesToRead = port.BytesToRead; // Fyll på array hela tiden i slutet. port.Read(data, 0, data.Length); Array.Copy(data, 0, iBuff, iBuffPointer, data.Length); iBuffPointer += bytesToRead; // När array större eller lika med PACKET_LENGTH... while (iBuffPointer >= PACKET_LENGTH) { int startIndex = 0; // Sök igenom efter start byte från början. for (int i = 0; i < iBuffPointer; i++) { // Poppa alla bytes som inte är startbyte. if (iBuff[i] != UART_START_BYTE) startIndex++; else { // När startbyte hittas, kolla om återstående längd är större eller lika med PACKET_LENGTH (inkl startbyte) if ((iBuffPointer - startIndex) >= PACKET_LENGTH) { //om så, kolla PACKET_LENGTH-1 byte fram. if (iBuff[startIndex + PACKET_LENGTH-1] == UART_END_BYTE) { // Om byte PACKET_LENGTH-1 är slutbyte så extraktas startIndex till slutbyteindex. CanPacket cm = new CanPacket(iBuff, (uint)startIndex + 1); cmQueue.Enqueue(cm); if (newIncommingCanMessage != null) newIncommingCanMessage.Invoke(this, EventArgs.Empty); // Sätt ny startindex och avsluta loop. startIndex += PACKET_LENGTH; break; } } } } // och i slutet göra en array copy. // Flytta ner allt efter slutbyte till index 0 i array. Array.Copy(iBuff, startIndex, iBuff, 0, iBuffPointer - PACKET_LENGTH); iBuffPointer -= startIndex; } }
public bool getPacket(out CanPacket cm) { cm = null; if (cmQueue.Count > 0) { cm = cmQueue.Dequeue(); return true; } return false; }
public bool sendPacket(CanPacket cm) { if (serial_conn.IsOpen) { byte[] b = new byte[PACKET_LENGTH]; b[0] = UART_START_BYTE; Array.Copy(cm.getBytes(), 0, b, 1, PACKET_LENGTH-2); b[PACKET_LENGTH-1] = UART_END_BYTE; serial_conn.Write(b, 0, PACKET_LENGTH); return true; } return false; }
public void downloader() { int t = 0; CanPacket outCp = null; CanPacket cp = null; byte[] data = new byte[8]; byte offset = 0; ulong currentAddress = 0; int doneCount = DONE_TO_SEND; 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.ptPGM && cp.pgm._class == td.PGM_CLASS.pcCTRL && cp.sid == TARGET_ID); switch (pgs) { case dState.SEND_START: // Send boot start packet to target. // and wait for ack. currentAddress = eestart; data[4] = TARGET_ID; data[3] = (byte)eetype; data[2] = (byte)((currentAddress & 0xFF0000) >> 16); data[1] = (byte)((currentAddress & 0xFF00) >> 8); data[0] = (byte)(currentAddress & 0xFF); outCp = new CanPacket(new CanPacket.canPGMPacket(td.PGM_CLASS.pcCTRL,(ushort)td.PGM_CTRL_TYPE.pctEE_START),MY_ID,5,data); sc.sendPacket(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.pgm.id==(ushort)td.PGM_CTRL_TYPE.pctEE_ACK) { // Start sending program data.. offset = 0; pgs = dState.SEND_PGM_DATA; hasFoundNode = true; } // if nack if (hasMessageFromTarget && cp.pgm.id == (ushort)td.PGM_CTRL_TYPE.pctEE_NACK) { // else resend start.. pgs = dState.SEND_START; } break; case dState.SEND_PGM_DATA: // Send program data. for (ulong i = 0; i < 7; i++) { // Populate data. data[i] = eebytes[currentAddress + i + offset]; } data[7] = offset; outCp = new CanPacket(new CanPacket.canPGMPacket(td.PGM_CLASS.pcCTRL,(ushort)td.PGM_CTRL_TYPE.pctEE_PGM), MY_ID, 8, data); sc.sendPacket(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 += 7; // Check if 56 bytes sent or not.. if (offset % 56 == 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[56]; for(ulong i=0;i<56;i++) pgmData[i] = eebytes[i+currentAddress]; ushort crc = crc16.calc_crc(pgmData, 56); 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.canPGMPacket(td.PGM_CLASS.pcCTRL,(ushort)td.PGM_CTRL_TYPE.pctEE_CRC), MY_ID, 8, data); sc.sendPacket(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.pgm.id == (ushort)td.PGM_CTRL_TYPE.pctEE_ACK) { // Start send more program data.. currentAddress += offset; offset = 0; pgs = dState.SEND_PGM_DATA; hasFoundNode = true; if (currentAddress > (eelength+eestart)) { // Yes, we are done, send done. pgs = dState.SEND_DONE; } } // if nack if (hasMessageFromTarget && cp.pgm.id == (ushort)td.PGM_CTRL_TYPE.pctEE_NACK) { // else resend pgm data... offset = 0; pgs = dState.SEND_PGM_DATA; } break; case dState.SEND_DONE: data[2] = (byte)(((eelength) & 0xFF0000) >> 16); data[1] = (byte)(((eelength) & 0xFF00) >> 8); data[0] = (byte)((eelength) & 0xFF); outCp = new CanPacket(new CanPacket.canPGMPacket(td.PGM_CLASS.pcCTRL,(ushort)td.PGM_CTRL_TYPE.pctEE_DONE), MY_ID, 3, data); sc.sendPacket(outCp); t = Environment.TickCount; pgs = dState.SEND_WAIT_DONE; doneCount--; break; case dState.SEND_WAIT_DONE: if (doneCount < 0) { pgs = dState.DONE; } else if ((Environment.TickCount-t)>TIMEOUT_MS) { pgs = dState.SEND_DONE; } break; case dState.DONE: abortmode = abortMode.PROGRAM; down.Abort(); break; } Thread.Sleep(10); } } catch(Exception) { threadAbort.Invoke(this, new threadAbortEvent((int)(Environment.TickCount - timeStart), eelength, abortmode)); } }