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

Driver/ads1263 #1070

Merged
merged 2 commits into from
Sep 9, 2024
Merged
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
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
using Meadow.Hardware;
using Meadow.Units;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace Meadow.Foundation.ICs.IOExpanders
{
public partial class Ads1263
{
/// <summary>
/// Represents an Ads1263 analog input port
/// </summary>
public class AnalogInputPort : AnalogInputPortBase, IAnalogInputPort
{
/// <summary>
/// Is the port sampling
/// </summary>
public bool IsSampling { get; protected set; } = false;

private readonly Ads1263 controller;

private Voltage previousVoltageReading;

private CancellationTokenSource? SamplingTokenSource;

private readonly object _lock = new();

/// <summary>
/// Create a new AnalogInputPort object with a non-default reference voltage
/// </summary>
/// <param name="controller">The parent Ads1263 controller.</param>
/// <param name="pin">The pin associated with the port.</param>
/// <param name="channel">The channel information for the port.</param>
/// <param name="sampleCount">The number of samples to be taken during each reading.</param>
/// <param name="sampleInterval">The time interval between samples during each reading.</param>
/// <exception cref="ArgumentNullException">Thrown if <paramref name="pin"/> or <paramref name="channel"/> is <c>null</c>.</exception>
public AnalogInputPort(Ads1263 controller,
IPin pin,
IAnalogChannelInfo channel,
int sampleCount, TimeSpan sampleInterval)
: base(pin, channel, sampleCount, sampleInterval, controller.GetADCReferenceVoltage(pin))
{
// TODO: Validate pin is valid before using it?
this.controller = controller;

SampleCount = sampleCount;
}

/// <summary>
/// Start the ADC conversions
/// </summary>
public void StartConversions()
{
controller.ADCStart(Pin);
}

/// <summary>
/// Stop the ADC conversions
/// </summary>
public void StopConversions()
{
controller.ADCStop(Pin);
}

/// <inheritdoc />
/// <remarks>Assumes conversions have been started</remarks>
public override async Task<Voltage> Read()
{
var result = controller.ReadAnalog(Pin);
await Task.Delay(SampleInterval);
return result;
}

/// <summary>
/// Start updating
/// </summary>
public override void StartUpdating(TimeSpan? updateInterval = null)
{
// thread safety
lock (_lock)
{
if (IsSampling)
return;

StartConversions();
IsSampling = true;

// if an update interval was passed in, override the default value
if (updateInterval is { } ui)
{ UpdateInterval = ui; }

SamplingTokenSource = new CancellationTokenSource();
var ct = SamplingTokenSource.Token;

Task.Factory.StartNew(async () =>
{
while (true)
{
// cleanup
if (ct.IsCancellationRequested)
{
// do task clean up here
Observers.ForEach(x => x.OnCompleted());
break;
}

var newVoltage = await Read();
var result = new ChangeResult<Voltage>(newVoltage, previousVoltageReading);
previousVoltageReading = newVoltage;

// raise our events and notify our subs
RaiseChangedAndNotify(result);

await Task.Delay(UpdateInterval, ct);
}

IsSampling = false;
}, SamplingTokenSource.Token);
}
}

/// <summary>
/// Stop updating the port
/// </summary>
public override void StopUpdating()
{
lock (_lock)
{
if (!IsSampling)
return;

SamplingTokenSource?.Cancel();

IsSampling = false;

StopConversions();
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Meadow.Hardware;
using System;

namespace Meadow.Foundation.ICs.IOExpanders
{
public partial class Ads1263
{
/// <summary>
/// Represents an Ads1263 digital input port
/// </summary>
public class DigitalInputPort : DigitalInputPortBase
{
/// <inheritdoc/>
public override bool State
{
get
{
if (Pin.Controller is Ads1263 controller)
{
Update(controller.ReadPort(Pin));
}
return state;
}
}
private bool state = false;

/// <inheritdoc/>
public override ResistorMode Resistor
{
get => portResistorMode;
set => throw new NotSupportedException("Cannot change port resistor mode");
}
private readonly ResistorMode portResistorMode;

/// <summary>
/// Create a new DigitalInputPort object
/// </summary>
/// <param name="pin">The input pin</param>
public DigitalInputPort(IPin pin)
: base(pin, (IDigitalChannelInfo)pin.SupportedChannels![0])
{
portResistorMode = ResistorMode.Disabled;
}

/// <summary>
/// Update the port value
/// </summary>
/// <param name="newState">The new port state</param>
internal void Update(bool newState)
{
state = newState;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using Meadow.Hardware;

namespace Meadow.Foundation.ICs.IOExpanders
{
public partial class Ads1263
{
/// <summary>
/// Represents an Ads1263 DigitalOutputPort
/// </summary>
public class DigitalOutputPort : DigitalOutputPortBase
{
/// <summary>
/// Enable the caller to receive pin state updates
/// </summary>
/// <param name="pin"></param>
/// <param name="state"></param>
public delegate void SetPinStateDelegate(IPin pin, bool state);

/// <summary>
/// The SetPinState delegate
/// </summary>
public SetPinStateDelegate SetPinState = default!;

/// <summary>
/// The port state
/// True for high, false for low
/// </summary>
public override bool State
{
get => state;
set => SetPinState?.Invoke(Pin, state = value);
}
bool state;

/// <summary>
/// Create a new DigitalOutputPort
/// </summary>
/// <param name="pin">The pin representing the port</param>
/// <param name="initialState">The initial port state</param>
public DigitalOutputPort(
IPin pin,
bool initialState = false)
: base(pin, (IDigitalChannelInfo)pin.SupportedChannels![0], initialState, OutputType.PushPull)
{
}
}
}
}
Loading
Loading