Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sc16is7x2 code quality #1100

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,27 @@ public enum Addresses : byte
public enum FsrGain
{
/// <summary>
/// 2/3rds
/// Gain = 2/3rds. Range: ±6.144 V
/// </summary>
TwoThirds = 0x00,
/// <summary>
/// 1
/// Gain = 1. Range: ±4.096 V
/// </summary>
One = 0x01,
/// <summary>
/// 2
/// Gain = 2. Range: ±2.048 V
/// </summary>
Two = 0x02,
/// <summary>
/// 4
/// Gain = 4. Range: ±1.024 V
/// </summary>
Four = 0x03,
/// <summary>
/// 8
/// Gain = 8. Range: ±0.512 V
/// </summary>
Eight = 0x04,
/// <summary>
/// 16
/// Gain = 16. Range: ±0.256 V
/// </summary>
Sixteen = 0x05
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
using System;
using System.Text;
using System.Threading;

namespace Meadow.Foundation.ICs.IOExpanders;

/// <summary>
/// This FIFO buffer is implemented as a circular buffer. (Standard computer science stuff)
/// It operates on bytes. The only special method is WriteString,
/// which writes a string to the buffer after converting it with Encoding.ASCII.GetBytes().
///
/// 2024.04.20, KW: I've recently discovered the CircularBuffer class in the Meadow.Contracts library.
/// We should perhaps use that instead of this custom implementation.
/// But this method is specific to bytes, so it might still be more efficient.
/// </summary>
public class FifoBuffer
{
Expand Down Expand Up @@ -39,8 +44,8 @@ public FifoBuffer(int capacity)
throw new ArgumentException("Capacity must be greater than 0.", nameof(capacity));

_buffer = new byte[capacity];
_nextRead = 0; // The next read position.
_nextWrite = 0; // The next write position.
_nextRead = 0; // The next read position. (Tail)
_nextWrite = 0; // The next write position. (Head)
_count = 0; // The number of items in the buffer.
}

Expand All @@ -54,6 +59,8 @@ public void Clear()
_count = 0; // The number of items in the buffer.
}

private int skippedBytes = 0;
private DateTime skippedBytesLastLogged = DateTime.MinValue;
/// <summary>
/// Add new item to the _nestWrite position in the buffer.
/// Then move the _nextWrite position. If it goes beyond the capacity, it will wrap around to 0.
Expand All @@ -64,7 +71,18 @@ public void Clear()
public void Write(byte item)
{
if (_count == Capacity)
throw new InvalidOperationException("The buffer is full.");
{
//throw new InvalidOperationException($"The software FIFO buffer is full. Capacity is {Capacity} bytes.");
// 21.04.2024, KW: These exception must be handled by the caller. We count the occurences and throw an error every 5 seconds.
skippedBytes++;
if (DateTime.Now - skippedBytesLastLogged > TimeSpan.FromSeconds(5))
{
skippedBytesLastLogged = DateTime.Now;
//Resolver.Log.Info($"The software FIFO buffer is full. Capacity is {Capacity} bytes. Skipped bytes: {skippedBytes} (This message will be repeated every 5 seconds)");
throw new Exception($"The software FIFO buffer is full. Capacity is {Capacity} bytes. Skipped bytes: {skippedBytes} (This message will be repeated every 5 seconds)");
}
return;
}

_buffer[_nextWrite] = item;
_nextWrite = (_nextWrite + 1) % Capacity; // Move _nextWrite forward and possibly wrap.
Expand Down Expand Up @@ -134,4 +152,53 @@ public void WriteString(string text)
Write((byte)c);
}
}

/// <summary>
/// Copied from the CircularBuffer class in the Meadow.Contracts library.
/// Removes items from the buffer and places them in a target array
/// </summary>
/// <param name="destination">The destination array for the move</param>
/// <param name="index">The beginning index of the destination</param>
/// <param name="count">The desired number of items to move</param>
/// <returns>The actual number of items moved</returns>
public int MoveItemsTo(byte[] destination, int index, int count)
{
if (count <= 0) { return 0; }

// How many are we moving?
// Move from current toward the tail
var actual = (count > Count) ? Count : count;
var fromReadToEnd = _buffer.Length - _nextRead;

//Resolver.Log.Info($"MoveItemsTo() _nextRead={_nextRead} _nextWrite={_nextWrite} actual={actual} fromReadToEnd={fromReadToEnd}");

if ((_nextRead < _nextWrite)
|| (_nextRead == 0 && _count == Capacity)
|| (fromReadToEnd >= actual))
{
// the data is linear, just copy
Array.Copy(_buffer, _nextRead, destination, index, actual);

// move the tail pointer
_nextRead += actual;
_count -= actual;
}
else
{
// there's a data wrap
// copy from here to the end
Array.Copy(_buffer, _nextRead, destination, index, fromReadToEnd);
// now copy from the start (tail == 0) the remaining data
_nextRead = 0;
_count -= fromReadToEnd;
var remaining = actual - fromReadToEnd;
Array.Copy(_buffer, _nextRead, destination, index + fromReadToEnd, remaining);

// move the tail pointer
_nextRead = remaining;
_count -= remaining;
}

return actual;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,75 @@ public enum Addresses : byte
/// The default bus address (0x48)
/// </summary>
Default = Address_0x48,

// A new set of constants that show the direct relationship between the address pins and the I2C address
// Please refer to the datasheet for the SC16IS752/SC16IS762 page 39.
// Note that the address in the datasheet multiplied by 2, because they include a left shit for the R/W bit.

/// <summary>
/// A1 pin connected to Vdd, A0 pin connected to Vdd
/// </summary>
A1Vdd_A0Vdd = 0x48,
/// <summary>
/// A1 pin connected to Vdd, A0 pin connected to Gnd
/// </summary>
A1Vdd_A0Gnd = 0x49,
/// <summary>
/// A1 pin connected to Vdd, A0 pin connected to SCL
/// </summary>
A1Vdd_A0Scl = 0x4A,
/// <summary>
/// A1 pin connected to Vdd, A0 pin connected to SDA
/// </summary>
A1Vdd_A0Sda = 0x4B,
/// <summary>
/// A1 pin connected to Gnd, A0 pin connected to Vdd
/// </summary>
A1Gnd_A0Vdd = 0x4C,
/// <summary>
/// A1 pin connected to Gnd, A0 pin connected to Gnd
/// </summary>
A1Gnd_A0Gnd = 0x4D,
/// <summary>
/// A1 pin connected to Gnd, A0 pin connected to SCL
/// </summary>
A1Gnd_A0Scl = 0x4E,
/// <summary>
/// A1 pin connected to Gnd, A0 pin connected to SDA
/// </summary>
A1Gnd_A0Sda = 0x4F,
/// <summary>
/// A1 pin connected to SCL, A0 pin connected to Vdd
/// </summary>
A1Scl_A0Vdd = 0x50,
/// <summary>
/// A1 pin connected to SCL, A0 pin connected to Gnd
/// </summary>
A1Scl_A0Gnd = 0x51,
/// <summary>
/// A1 pin connected to SCL, A0 pin connected to SCL
/// </summary>
A1Scl_A0Scl = 0x52,
/// <summary>
/// A1 pin connected to SCL, A0 pin connected to SDA
/// </summary>
A1Scl_A0Sda = 0x53,
/// <summary>
/// A1 pin connected to SDA, A0 pin connected to Vdd
/// </summary>
A1Sda_A0Vdd = 0x54,
/// <summary>
/// A1 pin connected to SDA, A0 pin connected to Gnd
/// </summary>
A1Sda_A0Gnd = 0x55,
/// <summary>
/// A1 pin connected to SDA, A0 pin connected to SCL
/// </summary>
A1Sda_A0Scl = 0x56,
/// <summary>
/// A1 pin connected to SDA, A0 pin connected to SDA
/// </summary>
A1Sda_A0Sda = 0x57,
}

internal enum Registers : byte
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public Sc16is7x2(II2cBus i2cBus, Frequency oscillatorFrequency, Addresses addres
: this(oscillatorFrequency, irq, latchGpioInterrupt)
{
_i2cComms = new I2cCommunications(i2cBus, (byte)address);
Reset(); // We need to call this _after_ the I2C communications object is created
}
}
}
Loading
Loading