I built a firmware updater app for a device and the host app connects to the device via a serial connection. The app has been working on small apps (~18KB) and I recently upped the firmware size to ~200KB.
Now the host app (C#) hangs on a serial port write and pausing the program in debug shows a Debugger Break.
The code pictured below reads a .HEX file line by line (not pictured) and writes blocks of 256 bytes one byte at a time using UART (serial comm). After 256 bytes, a checksum is sent for the block, and the loop is left to set up the next transfer.
What could be the reason for the app to hang on the write command? Is there some port or buffer maintenance that has to be done between blocks? I can see the byte counter for the block (0 to 255) and it doesn't hang on the same byte number.
This app is connecting to an ARM processor on a STM32F417IGT dev board.
Thanks for your help!
Complete write function, in code:
public void WriteNewAppToFlash(SerialPort _serialPort)
{
int byte_read = 0;
long checksum = 0;
var ff = new byte[] { 0xFF };
// ------------------------------------------------------------------------------
// -------- WRITE MEMORY --------------------------------------------------------
// ------------------------------------------------------------------------------
// for Address
int baseAddress = 0x08004000;
int offset = 0;
// for string from HEX file
string line;
int length;
int type;
int hexChecksum = 0;
bool sendAddress = true;
int counter = 0; // Counting the number of lines in the file
int byteCounter = 0; // Counting nmumber of bytes in the current block
// Read the file and process one line at a time
System.IO.StreamReader file = new System.IO.StreamReader(path);
while ((line = file.ReadLine()) != null)
{
if (sendAddress == true)
{
/*
-------------------------------------------------------------------------------------------------------
SEND WRITE COMMAND
-----------------------------------------------------------------------------------------------------*/
// Send 0x43 (erase memory) and 0xBC
var writeMem = new byte[] { 0x31 };
var ce = new byte[] { 0xCE };
_serialPort.Write(writeMem, 0, 1);
//Console.WriteLine("writeMem = 0x" + BitConverter.ToInt32(writeMem, 0).ToString("X"));
_serialPort.Write(ce, 0, 1);
//Console.WriteLine("CE = 0x" + BitConverter.ToInt32(writeMem, 0).ToString("X"));
// Receive ACK byte
byte_read = _serialPort.ReadByte();
//Console.WriteLine("ACK = 0x" + byte_read.ToString("X"));
//Console.WriteLine("");
if (byte_read == NACK)
{
//Console.WriteLine("NACK received for WRITE MEMORY start");
//Console.WriteLine("");
}
// -- end SEND 0x31 and 0xCE and wait for ACK -----------------------------------------
-------------------------------------------------------------------------------------------------------
SEND CURRENT ADDRESS AND CHECKSUM TO FLASH MEMORY
-----------------------------------------------------------------------------------------------------*/
Byte[] currentAddr = BitConverter.GetBytes(baseAddress + offset);
// Increment offset by 0x100 (256 bytes)
offset = offset + 0x00000100;
//int msb;
// Reset Checksum and XOR address
checksum = 0;
foreach (byte b in currentAddr)
{
checksum ^= b;
}
//Console.WriteLine("cksum = " + checksum);
Byte[] cksum = BitConverter.GetBytes(checksum);
// Send address, MSB first, LSB last
_serialPort.Write(currentAddr, 3, 1);
_serialPort.Write(currentAddr, 2, 1);
_serialPort.Write(currentAddr, 1, 1);
_serialPort.Write(currentAddr, 0, 1);
// Send checksum of address bytes
_serialPort.Write(cksum, 0, 1);
// Receive ACK byte
byte_read = _serialPort.ReadByte();
//Console.WriteLine("ACK = 0x" + byte_read.ToString("X"));
//Console.WriteLine("");
if (byte_read == NACK)
{
//Console.WriteLine("NACK received for WRITE MEMORY address received");
//Console.WriteLine("");
}
// -- end addr or increment ---------------------------------------------------------
sendAddress = false;
// Send number of bytes, always 256, the last group will be padded with 0xFF
_serialPort.Write(ff, 0, 1);
hexChecksum = 0;
} // end IF for WRITE COMMAND and ADDRESS
/*
-------------------------------------------------------------------------------------------------------
WRITE 256 BYTES FROM HEX FILE TO FLASH MEMORY
-----------------------------------------------------------------------------------------------------*/
// FIRST CHARACTER in HEX FILE
// The colon indicates the start of a "record"
// Remove colon from beginning of string
line = line.Substring(1, line.Length - 1);
//Console.WriteLine(line);
// Create byte array from string
var bytes = GetBytesFromByteString(line).ToArray();
// Assign values to variables from byte array
type = bytes[3];
/* Next TWO CHARACTERS in HEX FILE 00-data
are the record type: 01-EOF
02-
03-
04-
05- */
// Check type for data = 00
if (type == 0)
{
// The first two characters represent the number of data bytes for the record
// Obtain length, convert to int (counter for sending data)
length = bytes[0];
for ( int i = 0; i < length; i++ )
{
// Send individual characters to device
_serialPort.Write(bytes, 4 + i, 1);
//Thread.Sleep(100);
// increment counter
byteCounter++;
if( byteCounter % 32 == 0 )
{
Thread.Sleep(40);
}
// Add byte to checksum
hexChecksum ^= bytes[4 + i];
//Console.WriteLine("cum checksum = " + hexChecksum);
// If counter == 256, reset counter, send checksum
if (byteCounter == 256)
{
sendAddress = true;
byteCounter = 0;
//Console.WriteLine("checksum = " + hexChecksum.ToString("X"));
// Convert checksum to a byte value and send
hexChecksum = hexChecksum ^ 0xFF;
byte csByte = Convert.ToByte(hexChecksum);
//Console.WriteLine("CSBYTE = " + Convert.ToInt32(csByte));
Byte[] csByte_arr = BitConverter.GetBytes(csByte);
_serialPort.Write(csByte_arr, 0, 1);
// Receive ACK byte
byte_read = _serialPort.ReadByte();
//Console.WriteLine("ACK = 0x" + byte_read.ToString("X"));
//Console.WriteLine("");
if (byte_read == NACK)
{
//Console.WriteLine("NACK received for write memory DATA received");
//Console.WriteLine("");
}
} // end IF byteCounter == 256
//Console.WriteLine(byteCounter);
} // end FOR loop
}
else if (type == 5)
{
// Address thingy
//Console.WriteLine("Hit address thingy");
//Console.WriteLine("");
}
else if (type == 1) // Check for end of file
{
// End of file
while (byteCounter != 0)
{
// Send individual bytes to device
_serialPort.Write(ff, 0, 1);
// increment counter
byteCounter++;
// Add byte to checksum
hexChecksum ^= 0xFF;
//Console.WriteLine("cum checksum = " + hexChecksum);
if (byteCounter == 256)
{
byteCounter = 0;
hexChecksum = hexChecksum ^ 0xFF;
byte csByte = Convert.ToByte(hexChecksum);
//Console.WriteLine("CSBYTE = " + Convert.ToInt32(csByte));
Byte[] csByte_arr = BitConverter.GetBytes(csByte);
_serialPort.Write(csByte_arr, 0, 1);
// Receive ACK byte
byte_read = _serialPort.ReadByte();
//Console.WriteLine("ACK = 0x" + byte_read.ToString("X"));
//Console.WriteLine("");
if (byte_read == NACK)
{
//Console.WriteLine("NACK received for write memory DATA received");
//Console.WriteLine("");
}
}
}
} // end ELSE if TYPE == 1
counter++;
} // end WHILE loop for loading hex file
file.Close();
//System.Console.WriteLine("There were {0} lines.", counter);
//Console.WriteLine("");
// -- end WRITE MEMORY ------------------------------------------------------
} // end WriteNewAppToFlash
Changed the code to write a block of 256 bytes. It now writes two blocks and will not write the third block. The program executes to the Write line, the byte buffer is full, but it will not initiate the write.
if (byteCounter >= 255)
{
// Convert checksum to a byte value
hexChecksum = hexChecksum ^ 0xFF;
byte csByte = Convert.ToByte(hexChecksum);
Byte[] csByte_arr = BitConverter.GetBytes(csByte);
do
{
// send byte array
_serialPort.Write(buffer256, 0, 256);
Thread.Sleep(70);
// send checksum
_serialPort.Write(csByte_arr, 0, 1);
// Receive ACK byte
byte_read = _serialPort.ReadByte();
Thread.Sleep(100);
if (byte_read == NACK)
{
//Console.WriteLine("NACK received for write memory DATA received");
//Console.WriteLine("");
}
} while (byte_read != ACK);
// Clear buffer, reset byte count, set flag to send write cmd and send new addr
Array.Clear(buffer256, 0, buffer256.Length);
byteCounter = 0;
sendAddress = true;
}
I eventually got this app to work, but the exact reason for it working is unclear. Here is what I looked at and what changes I made:
Switched from transmitting single bytes and then a checksum at the end of 256 bytes, to placing 256 in a buffer and then transmitting all at once, followed by the checksum. This method was failing at first, but turned out to be faster than the previous method.
Changed the order of processing lines of HEX code and checking that a block is ready to send (see code below). The difference is small, but that more than anything seems to have allowed the whole thing to work. Before, it was checking for 256 bytes to send, sending it and then putting the data from a line in the next block of 256. I stepped through the code and didn't see anything that would make it fail, but it must have done something.
Since then the app has worked great and I no longer have any qualms about using the .NET SerialPort class with embedded devices.
// BLOCK WRITE TO MEMORY
if (type == 0)
{
// Length of line is stored at byte 0, in this case 0x10, or 16 bytes of data
length = bytes[0];
// Add data from current line to buffer of 256 bytes
for (int i = 0; i < length; i++)
{
// Stuff all bytes from line into buffer of 256 bytes
buffer256[byteCounter++] = bytes[4 + i];
// Add byte to checksum
hexChecksum ^= bytes[4 + i];
}
// When buffer is full, send block of 256 bytes and checksum, reset variables for next block
if (byteCounter >= 255)
{
// Convert checksum to a byte value
hexChecksum = hexChecksum ^ 0xFF;
byte csByte = Convert.ToByte(hexChecksum);
Byte[] csByte_arr = BitConverter.GetBytes(csByte);
// Send byte array
_serialPort.Write(buffer256, 0, 256);
// For testing
// Console.WriteLine("block number [{0}]", ++blockCount);
//send checksum
_serialPort.Write(csByte_arr, 0, 1);
//Receive ACK byte
byte_read = _serialPort.ReadByte();
Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read);
while (byte_read != ACK)
{
Array.Clear(buffer256, 0, buffer256.Length);
hexChecksum = 0;
lineCount = 0;
// reprocess the previous 16 lines stored in the line buffer
for ( int j = 0; j < 16; j++ )
{
line = lineBuffer[j];
line = line.Substring(1, line.Length - 1);
var bytesLocal = GetBytesFromByteString(line).ToArray();
length = bytesLocal[0];
for (int i = 0; i < length; i++)
{
buffer256[byteCounter++] = bytesLocal[4 + i];
hexChecksum ^= bytesLocal[4 + i];
}
}
// Convert checksum to a byte value
hexChecksum = hexChecksum ^ 0xFF;
byte csByteLocal = Convert.ToByte(hexChecksum);
Byte[] csByte_arrLocal = BitConverter.GetBytes(csByteLocal);
// Send byte array
_serialPort.Write(buffer256, 0, 256);
//send checksum
_serialPort.Write(csByte_arrLocal, 0, 1);
//Receive ACK byte
byte_read = _serialPort.ReadByte();
Console.WriteLine("block/ACK = [{0}] | {1}", ++blockCount, byte_read);
}
// Clear buffer, reset byte count, clear checksum, set flag to send write cmd/send new addr
Array.Clear(buffer256, 0, buffer256.Length);
byteCounter = 0;
hexChecksum = 0;
lineCount = 0;
sendAddress = true;
}
} // end BLOCK WRITE TO MEMORY
Related
Good afternoon everyone. Faced a problem: it is necessary to read data from the devices using the modbus protocol. I can not understand how to get a response from the device.
So I call my function, but how do I get data from the device? Maybe someone can help.
P.S. Please, do not advise using ready-made libraries like nmodbus - with them I did everything, I want to try it myself. Thank you.
static void Main(string[] args)
{
var serial = new SerialPort("COM6", 19200);
serial.Handshake = Handshake.None;
serial.Parity = Parity.None;
serial.DataBits = 8;
serial.StopBits = StopBits.One;
serial.Open();
serial.Write(ReadHoldingRegister(2, 1024, 16), 0, 8);
serial.Close();
Console.ReadLine();
}
#region Function 3
public static byte[] ReadHoldingRegister(int id, int startAddress, int length)
{
byte[] data = new byte[8];
byte High, Low;
data[0] = Convert.ToByte(id);
data[1] = Convert.ToByte(3);
byte[] _adr = BitConverter.GetBytes(startAddress - 1);
data[2] = _adr[1];
data[3] = _adr[0];
byte[] _length = BitConverter.GetBytes(length);
data[4] = _length[1];
data[5] = _length[0];
myCRC(data, 6, out High, out Low);
data[6] = Low;
data[7] = High;
return data;
}
#endregion
#region CRC
public static void myCRC(byte[] message, int length, out byte CRCHigh, out byte CRCLow)
{
ushort CRCFull = 0xFFFF;
for (int i = 0; i < length; i++)
{
CRCFull = (ushort)(CRCFull ^ message[i]);
for (int j = 0; j < 8; j++)
{
if ((CRCFull & 0x0001) == 0)
CRCFull = (ushort)(CRCFull >> 1);
else
{
CRCFull = (ushort)((CRCFull >> 1) ^ 0xA001);
}
}
}
CRCHigh = (byte)((CRCFull >> 8) & 0xFF);
CRCLow = (byte)(CRCFull & 0xFF);
}
#endregion
}
Processing a response is not "simple", you really need to account for errors, inter character and inter packet timing, etc. It should also probably be on a separate high-priority thread. The Modbus specs have some processing state diagrams that illustrate what (at a minimum) should be done. However, as a VERY SIMPLE, brute force, polling EXAMPLE, you could start with something like this:
static Queue<byte> GetResponse(SerialPort serial, int timeoutMSecs)
{
Queue<byte> response = new Queue<byte>();
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (stopwatch.ElapsedMilliseconds < timeoutMSecs)
{
if (serial.BytesToRead == 0) continue; // Nothing received, continue waiting
response.Enqueue((byte)serial.ReadByte()); // Add rx byte to queue
stopwatch.Reset(); // Reset timeout
if (response.Count > 255) break; // Maximum RTU packet?
}
return response;
}
In your main function
static void Main(string[] args)
{
...
serial.DiscardInBuffer(); // Clear any remaining rx bytes
serial.Write(ReadHoldingRegister(2, 1024, 16), 0, 8);
Queue<byte> response = GetResponse(serial, 5);
if (response.Count > 0)
{
// Process Response
// 1) check the CRC
// 2) if crc ok, check if it is an exception response
// 3) if not an exception check that it "matches" the request
// ...
}
...
}
I have an array of audio data, which is a lot of Int32 numbers represented by array of bytes (each 4 byte element represents an Int32) and i want to do some manipulation on the data (for example, add 10 to each Int32).
I converted the bytes to Int32, do the manipulation and convert it back to bytes as in this example:
//byte[] buffer;
for (int i=0; i<buffer.Length; i+=4)
{
Int32 temp0 = BitConverter.ToInt32(buffer, i);
temp0 += 10;
byte[] temp1 = BitConverter.GetBytes(temp0);
for (int j=0;j<4;j++)
{
buffer[i + j] = temp1[j];
}
}
But I would like to know if there is a better way to do such manipulation.
You can check the .NET Reference Source for pointers (grin) on how to convert from/to big endian.
class intFromBigEndianByteArray {
public byte[] b;
public int this[int i] {
get {
i <<= 2; // i *= 4; // optional
return (int)b[i] << 24 | (int)b[i + 1] << 16 | (int)b[i + 2] << 8 | b[i + 3];
}
set {
i <<= 2; // i *= 4; // optional
b[i ] = (byte)(value >> 24);
b[i + 1] = (byte)(value >> 16);
b[i + 2] = (byte)(value >> 8);
b[i + 3] = (byte)value;
}
}
}
and sample use:
byte[] buffer = { 127, 255, 255, 255, 255, 255, 255, 255 };//big endian { int.MaxValue, -1 }
//bool check = BitConverter.IsLittleEndian; // true
//int test = BitConverter.ToInt32(buffer, 0); // -129 (incorrect because little endian)
var fakeIntBuffer = new intFromBigEndianByteArray() { b = buffer };
fakeIntBuffer[0] += 2; // { 128, 0, 0, 1 } = big endian int.MinValue - 1
fakeIntBuffer[1] += 2; // { 0, 0, 0, 1 } = big endian 1
Debug.Print(string.Join(", ", buffer)); // "128, 0, 0, 0, 1, 0, 0, 1"
For better performance you can look into parallel processing and SIMD instructions - Using SSE in C#
For even better performance, you can look into Utilizing the GPU with c#
How about the following approach:
struct My
{
public int Int;
}
var bytes = Enumerable.Range(0, 20).Select(n => (byte)(n + 240)).ToArray();
foreach (var b in bytes) Console.Write("{0,-4}", b);
// Pin the managed memory
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
for (int i = 0; i < bytes.Length; i += 4)
{
// Copy the data
My my = (My)Marshal.PtrToStructure<My>(handle.AddrOfPinnedObject() + i);
my.Int += 10;
// Copy back
Marshal.StructureToPtr(my, handle.AddrOfPinnedObject() + i, true);
}
// Unpin
handle.Free();
foreach (var b in bytes) Console.Write("{0,-4}", b);
I made it just for fun.
Not sure that's less ugly.
I don't know, will it be faster? Test it.
I am receiving data from serial port in an byte array
How can I calculate the checksum of the data not included the sync (54) and checksum (F2) byte and want to match with the last check sum byte.
Updated :
int bytes = comport.BytesToRead;
byte indexCRC;
int sumCRC = 0;
byte checksumCRC = 0;
byte checksum;
byte[] RXBuffer = new byte[bytes];
comport.Read(RXBuffer, 0, bytes);
checksum = RXBuffer.Last();
byte[] RXBufferCRC = new byte[bytes];
for (indexCRC = 1; indexCRC < RXBufferCRC.Length; indexCRC++)
{
sumCRC = sumCRC + RXBufferCRC[indexCRC];
}
checksumCRC = (byte)(sumCRC);
Start the index from 1 but before doing that delete the last index of the array and store the array in an other array something like that
int Secbytes = comport.BytesToRead;
byte[] SecRXBuffer = new byte[Secbytes];
Array.Copy(SecRXBuffer, VanguardConstants.RECEIVEINDEX, RXBuffer, 0, Secbytes);
byte[] tmp = new byte[bytes - 1];
Array.Copy(RXBuffer, tmp, Secbytes - 1);
for (i = 1; i < tmp.Length; i++)
{
Sum = (byte)(Sum + tmp[i]);
}
Checksum = ((byte)Sum);
http://err.se/crc8-for-ibutton-in-c/
Here is an implementation of a CRC8 function in C#.
I have the following code:
using (BinaryReader br = new BinaryReader(
File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite)))
{
int pos = 0;
int length = (int) br.BaseStream.Length;
while (pos < length)
{
b[pos] = br.ReadByte();
pos++;
}
pos = 0;
while (pos < length)
{
Console.WriteLine(Convert.ToString(b[pos]));
pos++;
}
}
The FILE_PATH is a const string that contains the path to the binary file being read.
The binary file is a mixture of integers and characters.
The integers are 1 bytes each and each character is written to the file as 2 bytes.
For example, the file has the following data :
1HELLO HOW ARE YOU45YOU ARE LOOKING GREAT //and so on
Please note: Each integer is associated with the string of characters following it. So 1 is associated with "HELLO HOW ARE YOU" and 45 with "YOU ARE LOOKING GREAT" and so on.
Now the binary is written (I do not know why but I have to live with this) such that '1' will take only 1 byte while 'H' (and other characters) take 2 bytes each.
So here is what the file actually contains:
0100480045..and so on
Heres the breakdown:
01 is the first byte for the integer 1
0048 are the 2 bytes for 'H' (H is 48 in Hex)
0045 are the 2 bytes for 'E' (E = 0x45)
and so on..
I want my Console to print human readable format out of this file: That I want it to print "1 HELLO HOW ARE YOU" and then "45 YOU ARE LOOKING GREAT" and so on...
Is what I am doing correct? Is there an easier/efficient way?
My line Console.WriteLine(Convert.ToString(b[pos])); does nothing but prints the integer value and not the actual character I want. It is OK for integers in the file but then how do I read out characters?
Any help would be much appreciated.
Thanks
I think what you are looking for is Encoding.GetString.
Since your string data is composed of 2 byte characters, how you can get your string out is:
for (int i = 0; i < b.Length; i++)
{
byte curByte = b[i];
// Assuming that the first byte of a 2-byte character sequence will be 0
if (curByte != 0)
{
// This is a 1 byte number
Console.WriteLine(Convert.ToString(curByte));
}
else
{
// This is a 2 byte character. Print it out.
Console.WriteLine(Encoding.Unicode.GetString(b, i, 2));
// We consumed the next character as well, no need to deal with it
// in the next round of the loop.
i++;
}
}
You can use String System.Text.UnicodeEncoding.GetString() which takes a byte[] array and produces a string.
I found this link very useful
Note that this is not the same as just blindly copying the bytes from the byte[] array into a hunk of memory and calling it a string. The GetString() method must validate the bytes and forbid invalid surrogates, for example.
using (BinaryReader br = new BinaryReader(File.Open(FILE_PATH, FileMode.Open, FileAccess.ReadWrite)))
{
int length = (int)br.BaseStream.Length;
byte[] buffer = new byte[length * 2];
int bufferPosition = 0;
while (pos < length)
{
byte b = br.ReadByte();
if(b < 10)
{
buffer[bufferPosition] = 0;
buffer[bufferPosition + 1] = b + 0x30;
pos++;
}
else
{
buffer[bufferPosition] = b;
buffer[bufferPosition + 1] = br.ReadByte();
pos += 2;
}
bufferPosition += 2;
}
Console.WriteLine(System.Text.Encoding.Unicode.GetString(buffer, 0, bufferPosition));
}
How to format the number which can be converted to Byte[] (array);
I know how to convert the result value to byte[], but the problem is how to format the intermediate number.
This is by data,
int packet = 10;
int value = 20;
long data = 02; // This will take 3 bytes [Last 3 Bytes]
i need the long value, through that i can shift and I'll fill the byte array like this
Byte[0] = 10;
Byte[1] = 20;
Byte[2] = 00;
Byte[3] = 00;
Byte[4] = 02;
Byte 2,3,4 are data
but formatting the intermediate value is the problem. How to form this
Here is the sample
long data= 683990319104; ///I referred this as intermediate value.
This is the number i receiving from built in application.
Byte[] by = new byte[5];
for (int i = 0; i < 5; i++)
{
by[i] = (byte)(data & 0xFF);
data>>= 8;
}
Here
Byte[0] = 00;
Byte[1] = 00; //Byte 0,1,2 are Data (ie data = 0)
Byte[2] = 00;
Byte[3] = 65; //Byte 3 is value (ie Value = 65)
Byte[4] = 159; // Byte 4 is packet (is Packet = 159);
This is one sample.
Currently BitConverter.GetBytes(..) is ues to receive.
Byte while sending, the parameter is long.
So i want the format to generate the number 683990319104 from
packet = 159
value = 65
data = 0
I think now its in understandable format :)
Not entirely sure what you are asking exactly, but I think you are looking for BitConverter.GetBytes(data).
The use of 3 bytes to define the long seems unusual; if it is just the 3 bytes... why a long? why not an int?
For example (note I've had to make assumptions about your byte-trimming based on your example - you won't have the full int/long range...):
static void Main() {
int packet = 10;
int value = 20;
long data = 02;
byte[] buffer = new byte[5];
WritePacket(buffer, 0, packet, value, data);
for (int i = 0; i < buffer.Length; i++)
{
Console.Write(buffer[i].ToString("x2"));
}
Console.WriteLine();
ReadPacket(buffer, 0, out packet, out value, out data);
Console.WriteLine(packet);
Console.WriteLine(value);
Console.WriteLine(data);
}
static void WritePacket(byte[] buffer, int offset, int packet,
int value, long data)
{
// note I'm trimming as per the original question
buffer[offset++] = (byte)packet;
buffer[offset++] = (byte)value;
int tmp = (int)(data); // more efficient to work with int, and
// we're going to lose the MSB anyway...
buffer[offset++] = (byte)(tmp>>2);
buffer[offset++] = (byte)(tmp>>1);
buffer[offset] = (byte)(tmp);
}
static void ReadPacket(byte[] buffer, int offset, out int packet,
out int value, out long data)
{
// note I'm trimming as per the original question
packet = buffer[offset++];
value = buffer[offset++];
data = ((int)buffer[offset++] << 2)
| ((int)buffer[offset++] << 1)
| (int)buffer[offset];
}
oooh,
Its simple
int packet = 159
int value = 65
int data = 0
long address = packet;
address = address<<8;
address = address|value;
address = address<<24;
address = address|data;
now the value of address is 683990319104 and i termed this as intermediate value. Let me know the exact term.