/// <summary> /// Write a PiJuice command /// </summary> /// <param name="command">The PiJuice command</param> /// <param name="data">The data to write</param> internal void WriteCommand(PiJuiceCommand command, ReadOnlySpan <byte> data) { byte tries = 0; Span <byte> buffer = stackalloc byte[data.Length + 2]; data.CopyTo(buffer.Slice(1)); buffer[0] = (byte)command; buffer[buffer.Length - 1] = GetCheckSum(data, checkLastByte: true); // When writing/reading to the I2C port, PiJuice doesn't respond on time in some cases // So we wait a little bit before retrying // In most cases, the I2C read/write can go thru without waiting while (tries < MaxRetries) { try { _i2cDevice.Write(buffer); return; } catch (IOException ex) { tries++; if (tries >= MaxRetries) { throw new IOException($"{nameof(WriteCommand)}: Failed to write command {command}", ex); } DelayHelper.DelayMilliseconds(ReadRetryDelay, false); } } }
/// <summary> /// Read data from PiJuice /// </summary> /// <param name="command">The PiJuice command</param> /// <param name="length">The length of the data to be read</param> /// <returns>Returns an array of the bytes read</returns> internal byte[] ReadCommand(PiJuiceCommand command, byte length) { byte tries = 0; Span <byte> outArray = stackalloc byte[length + 1]; outArray.Clear(); // When writing/reading the I2C port, PiJuice doesn't respond on time in some cases // So we wait a little bit before retrying // In most cases, the I2C read/write can go thru without waiting while (tries < MaxRetries) { try { _i2cDevice.Write(new byte[] { (byte)command }); _i2cDevice.Read(outArray); var checksum = GetCheckSum(outArray); if (checksum != outArray[length]) { outArray[0] |= 0x80; checksum = GetCheckSum(outArray); if (checksum != outArray[length]) { tries++; if (tries >= MaxRetries) { throw new InvalidDataException($"{nameof(ReadCommand)}: Invalid checksum read command {command}, checksum {checksum}"); } DelayHelper.DelayMilliseconds(ReadRetryDelay, false); continue; } } break; } catch (IOException ex) { tries++; if (tries >= MaxRetries - 1) { throw new IOException($"{nameof(ReadCommand)}: Failed to read command {command}", ex); } DelayHelper.DelayMilliseconds(ReadRetryDelay, false); } } return(outArray.Slice(0, length).ToArray()); }
/// <summary> /// Write a PiJuice command and verify /// </summary> /// <param name="command">The PiJuice command</param> /// <param name="data">The data to write</param> /// <param name="delay">The delay before reading the data</param> internal void WriteCommandVerify(PiJuiceCommand command, ReadOnlySpan <byte> data, int delay = 0) { WriteCommand(command, data); if (delay > 0) { DelayHelper.DelayMilliseconds(delay, false); } var response = ReadCommand(command, (byte)data.Length); if (!data.SequenceEqual(response)) { throw new IOException($"{nameof(WriteCommandVerify)}: Failed to write command {command}"); } }