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

Bug/x74595 #761

Merged
merged 4 commits into from
Sep 12, 2023
Merged
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 @@ -18,7 +18,7 @@ public partial class x74595 : IDigitalOutputController, ISpiPeripheral
/// <summary>
/// The pin definitions
/// </summary>
public PinDefinitions Pins { get; }
public PinDefinitions Pins { get; } = default!;

/// <summary>
/// The default SPI bus speed for the device
Expand Down Expand Up @@ -53,12 +53,12 @@ public SpiClockConfiguration.Mode SpiBusMode
/// </summary>
private readonly int numberOfChips;

private byte[] latchData;
private byte[] latchData = default!;

/// <summary>
/// SPI Communication bus used to communicate with the peripheral
/// </summary>
protected ISpiCommunications spiComms;
protected ISpiCommunications spiComms = default!;

/// <summary>
/// Default constructor.
Expand All @@ -76,8 +76,15 @@ private x74595()
/// <param name="pins">Number of pins in the shift register (should be a multiple of 8 pins).</param>
/// <param name="spiBus">SpiBus object</param>
/// <param name="pinChipSelect">The chip select pin</param>
public x74595(ISpiBus spiBus, IPin pinChipSelect, int pins = 8)
/// <param name="initialStates">An optional list of initial states for the pins. Omitting this will initialize all pins to low.</param>
/// <param name="outputEnable">An optional pin connected to OE used for initializing startup state</param>
public x74595(ISpiBus spiBus, IPin pinChipSelect, int pins = 8, IPin? outputEnable = null, bool[]? initialStates = null)
{
if (initialStates != null && initialStates.Length != pins)
{
throw new ArgumentException("If not null, initialStates length must match the pin count");
}

Pins = new PinDefinitions(this);

if (pins == 8)
Expand All @@ -86,7 +93,48 @@ public x74595(ISpiBus spiBus, IPin pinChipSelect, int pins = 8)

latchData = new byte[numberOfChips];

IDigitalOutputPort? oe = null;

if (outputEnable != null)
{
oe = outputEnable.CreateDigitalOutputPort(true);
}

// start with the CS/OE/lath *high* which put the outputs in high-Z while we clear things to a known state
spiComms = new SpiCommunications(spiBus, pinChipSelect?.CreateDigitalOutputPort(), DefaultSpiBusSpeed, DefaultSpiBusMode);

// the chip register is in an unknown state right now - we need to set the data before the initial latch
if (initialStates != null)
{
var pin = 0;

for (var chip = 0; chip < numberOfChips; chip++)
{
byte b = 0;

for (var bit = 0; bit < 8; bit++)
{
if (initialStates[pin])
{
b |= (byte)(1 << (7 - pin));
if (pin >= pins) break;
}
pin++;
}
latchData[chip] = b;
}

ParalellWrite(latchData);
}
else
{
Clear();
}

if (oe != null)
{
oe.State = false;
}
}
else
{
Expand All @@ -113,6 +161,11 @@ public IDigitalOutputPort CreateDigitalOutputPort(IPin pin, bool initialState, O
throw new Exception("Pin is out of range");
}

private void ParalellWrite(byte[] data)
{
spiComms.Write(data);
}

/// <summary>
/// Clear the shift register buffer
/// </summary>
Expand All @@ -123,7 +176,7 @@ public void Clear(bool update = true)

if (update)
{
spiComms.Write(latchData);
ParalellWrite(latchData);
}
}

Expand Down
Loading