Skip to content

Commit

Permalink
Merge pull request #351 from WildernessLabs/feature/Nxp74HC4051
Browse files Browse the repository at this point in the history
Feature/nxp74 hc4051
  • Loading branch information
ctacke authored Jul 8, 2022
2 parents 7c84e35 + a630ab8 commit e51ac2b
Show file tree
Hide file tree
Showing 13 changed files with 598 additions and 18 deletions.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Meadow.Hardware;

namespace Meadow.Foundation.ICs.IOExpanders
{
public abstract class AnalogInputMultiplexerBase : IAnalogInputMultiplexer
{
protected object SyncRoot { get; } = new object();

/// <summary>
/// The port connected to the Enable pin of the mux (otherwise must be tied low)
/// </summary>
public IDigitalOutputPort? EnablePort { get; }

/// <summary>
/// The analog input connected to the Mux output pin (Z)
/// </summary>
public IAnalogInputPort Signal { get; }

public abstract void SetInputChannel(int channel);

internal AnalogInputMultiplexerBase(IAnalogInputPort signalPort, IDigitalOutputPort? enablePort)
{
Signal = signalPort;
EnablePort = enablePort;
}

/// <summary>
/// Enables the multiplexer (if an enable port was provided)
/// </summary>
public void Enable()
{
if (EnablePort != null)
{
lock (SyncRoot)
{
EnablePort.State = false; // active low
}
}
}

/// <summary>
/// Disables the multiplexer (if an enable port was provided)
/// </summary>
public void Disable()
{
if (EnablePort != null)
{
lock (SyncRoot)
{
EnablePort.State = true;
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Meadow.Hardware;

namespace Meadow.Foundation.ICs.IOExpanders
{
/// <summary>
/// Represents an Ti HP4067 16-channel analog multiplexer.
/// </summary>
/// <remarks>This part is identical to the Nxp74HC4067</remarks>
public class Hp4067 : Nxp74HC4067
{
/// <summary>
/// Creates a new Hp4067 object
/// </summary>
public Hp4067(IAnalogInputPort z, IDigitalOutputPort s0, IDigitalOutputPort? s1 = null, IDigitalOutputPort? s2 = null, IDigitalOutputPort? s3 = null, IDigitalOutputPort? enable = null)
: base(z, s0, s1, s2, s3, enable)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
using Meadow.Hardware;
using System;

namespace Meadow.Foundation.ICs.IOExpanders
{
/// <summary>
/// Represents an NXP 74HC4051 8-channel analog multiplexer
/// </summary>
public class Nxp74HC4051 : AnalogInputMultiplexerBase
{
/// <summary>
/// The port connected to the mux's S0 selection pin
/// </summary>
public IDigitalOutputPort S0 { get; }
/// <summary>
/// The port connected to the mux's S1 selection pin
/// </summary>
public IDigitalOutputPort? S1 { get; }
/// <summary>
/// The port connected to the mux's S2 selection pin
/// </summary>
public IDigitalOutputPort? S2 { get; }

/// <summary>
/// Creates a new Nxp74HC4051 object using the default parameters
/// </summary>
public Nxp74HC4051(IAnalogInputPort z, IDigitalOutputPort s0, IDigitalOutputPort? s1 = null, IDigitalOutputPort? s2 = null, IDigitalOutputPort? enable = null)
: base (z, enable)
{
S0 = s0;
S1 = s1;
S2 = s2;
}

/// <summary>
/// Sets the channel input (Y pin) that will be routed to the mux output (Z pin)
/// </summary>
/// <param name="channel"></param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public override void SetInputChannel(int channel)
{
if (channel < 0 || channel > 7) throw new ArgumentOutOfRangeException();

lock (SyncRoot)
{
var reenable = false;

if (EnablePort != null)
{
if (EnablePort.State)
{
reenable = true;

// disable before switching to prevent possible mis-routing

Disable();
}
}

/*
Truth Table
E S2 S1 S0
-- -- -- --
L L L L Y0 to Z
L L L H Y1 to Z
L L H L Y2 to Z
L L H H Y3 to Z
L H L L Y4 to Z
L H L H Y5 to Z
L H H L Y6 to Z
L H H H Y7 to Z
H X X X switches of
*/

switch (channel)
{
case 0:
S0.State = false;
if (S1 != null) { S1.State = false; }
if (S2 != null) { S2.State = false; }
break;
case 1:
S0.State = true;
if (S1 != null) { S1.State = false; }
if (S2 != null) { S2.State = false; }
break;
case 2:
if (S1 == null) throw new ArgumentException("You must have an S1 connected to access channels > 1");
S0.State = false;
S1.State = true;
if (S2 != null) { S2.State = false; }
break;
case 3:
if (S1 == null) throw new ArgumentException("You must have an S1 connected to access channels > 1");
S0.State = true;
S1.State = true;
if (S2 != null) { S2.State = false; }
break;
case 4:
if (S1 == null) throw new ArgumentException("You must have an S1 connected to access channels > 1");
if (S2 == null) throw new ArgumentException("You must have an S2 connected to access channels > 3");
S0.State = false;
S1.State = false;
S2.State = true;
break;
case 5:
if (S1 == null) throw new ArgumentException("You must have an S1 connected to access channels > 1");
if (S2 == null) throw new ArgumentException("You must have an S2 connected to access channels > 3");
S0.State = true;
S1.State = false;
S2.State = true;
break;
case 6:
if (S1 == null) throw new ArgumentException("You must have an S1 connected to access channels > 1");
if (S2 == null) throw new ArgumentException("You must have an S2 connected to access channels > 3");
S0.State = false;
S1.State = true;
S2.State = true;
break;
case 7:
if (S1 == null) throw new ArgumentException("You must have an S1 connected to access channels > 1");
if (S2 == null) throw new ArgumentException("You must have an S2 connected to access channels > 3");
S0.State = true;
S1.State = true;
S2.State = true;
break;

}

if (reenable)
{
Enable();
}
}

}
}
}
Loading

0 comments on commit e51ac2b

Please sign in to comment.