コード例 #1
0
ファイル: PiJuice.cs プロジェクト: richlander/iot
        /// <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);
                }
            }
        }
コード例 #2
0
ファイル: PiJuice.cs プロジェクト: richlander/iot
        /// <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());
        }
コード例 #3
0
ファイル: PiJuice.cs プロジェクト: richlander/iot
        /// <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}");
            }
        }