private async Task Read(uint address, byte[] buf, int offset, int length)
{
/* command word */
var tx = new byte[9];
/* temporary storage for response bytes */
var tmp = new byte[1];
/* command code */
tx[0] = (byte)STCmds.READ;
/* checksum */
tx[1] = ComputeChecksum(tx, 0, 1);
/* store address */
tx[2] = (byte)((address >> 24) & 0xff);
tx[3] = (byte)((address >> 16) & 0xff);
tx[4] = (byte)((address >> 8) & 0xff);
tx[5] = (byte)(address & 0xff);
/* address checksum (needs to be not negated. why? because ST!
* that's why. */
tx[6] = (byte)~ComputeChecksum(tx, 2, 4);
/* store number of bytes */
tx[7] = (byte)(length - 1);
/* size checksum */
tx[8] = ComputeChecksum(tx, 7, 1);
/* try to send command and wait for response */
try {
/* send bytes */
await SerialWrite(tx, 0, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Command Rejected");
/* send address */
await SerialWrite(tx, 2, 5);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Address Rejected");
/* send address */
await SerialWrite(tx, 7, 2);
/* wait for response code */
await SerialRead(tmp, 0, 1);
/* check response code */
if (tmp[0] != (byte)STResps.ACK)
throw new STBootException("Size Rejected");
/* receive response */
await SerialRead(buf, offset, length);
/* oops, something baaad happened! */
} catch (Exception) {
/* release semaphore */
sem.Release();
/* re-throw */
throw;
}
/* release semaphore */
sem.Release();
}