/// <summary> /// Syncronously reads data from the BioHarness. /// Handles the maximum message size constraints, splitting the /// request into manageable chunks, and reassembling the response. /// </summary> /// <param name="offset">The byte to start read at</param> /// <param name="length">The number of bytes to read</param> /// <returns>A byte array conaining the requested data</returns> private static byte[] SyncRead(int offset, int length) { CRC8 crc = new CRC8(0x8c); var response = new byte[length]; var answer = new byte[133]; /* request = STX, MSG_ID_LOG, DLC, ... ETX */ byte[] request = new byte[] { STX, MSG_ID_GET_LOG, DLC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ETX }; var loop = length / 128; if ((length % 128) > 0) { loop++; } int read = 0; byte nb = 128; do { if ((length - read) < 128) { nb = (byte)(length - read); } var offsetBytes = BitConverter.GetBytes(offset); request[4] = offsetBytes[0]; request[5] = offsetBytes[1]; request[6] = offsetBytes[2]; request[7] = offsetBytes[3]; request[8] = nb; request[9] = crc.Calculate(request.Skip(3).Take(6).ToArray()); vcp.Write(request, 0, 11); int r = 0; while ((r += vcp.Read(answer, r, nb + 5 - r)) < nb + 5) { } Array.Copy(answer, 3, response, read, nb); offset += nb; read += nb; }while (--loop > 0); return(response); }
/// <summary> /// Read bytes from the device /// </summary> /// <param name="offset">Location or address in the device</param> /// <param name="length">Number of bytes to read</param> /// <param name="ok">A ref to a bool that indicates success</param> /// <returns>An array of bytes read from the device</returns> private static byte[] Read(int offset, int length, out bool ok) { var response = new byte[length]; var answer = new byte[133]; bool nak = false; var loop = length / 128; if ((length % 128) > 0) { loop++; } int read = 0; byte nb = 128; int badDataRetryCount = 0; bool badData = false; do /* Each 128 byte (max) frame */ { do /* Retry up to BAD_DATA_RETRIES times when bad data is read */ { badData = false; if ((length - read) < 128) { nb = (byte)(length - read); } var offsetBytes = BitConverter.GetBytes(offset); request[4] = offsetBytes[0]; request[5] = offsetBytes[1]; request[6] = offsetBytes[2]; request[7] = offsetBytes[3]; request[8] = nb; request[9] = crc.Calculate(request.Skip(3).Take(6).ToArray()); vcp.Write(request, 0, 11); int r = 0; try { while ((r += vcp.Read(answer, r, nb + 5 - r)) < nb + 5) { /* Read into answer until full chunk is recieved */ } } catch { /* Typically timeout*/ nak = true; } if (r > 0) { /* Error checking */ /* Device said NAK */ if (answer[r - 1] == NAK) { nak = true; break; } /* Check for device ACK */ if (answer[nb + 4] != ACK) { badData = true; } /* STX header */ if (answer[0] != STX) { badData = true; } /* MsgID header */ if (answer[1] != MSG_ID_GET_LOG) { badData = true; } /* Number of bytes read matches request */ if (answer[2] != nb) { badData = true; } /* CRC */ CRC8 frameCrc = new CRC8(0x8c); byte crcVal = frameCrc.Calculate(answer.Skip(3).Take(nb).ToArray()); if (answer[nb + 3] != crcVal) { badData = true; } } if (nak == true) { break; } if (badData) { badDataRetryCount++; } else { Array.Copy(answer, 3, response, read, nb); offset += nb; read += nb; } }while (badData && badDataRetryCount < BAD_DATA_RETRIES); if (badData) { /* If we still had bad data after BAD_DATA_RETRIES then give up with NAK * Read() function will be called once more externally on NAK (ok = false) */ nak = true; break; } }while (--loop > 0); /* Next 128 byte frame */ ok = !nak; return(response); }