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

Feature/can filtering #256

Merged
merged 4 commits into from
Aug 14, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Meadow.Hardware;

/// <summary>
/// Represents a base class for CAN acceptance filters.
/// </summary>
public abstract class CanAcceptanceFilter
{
/// <summary>
/// Creates a standard exact acceptance filter for the specified identifier.
/// </summary>
/// <param name="id">The identifier to be accepted by the filter.</param>
/// <returns>A <see cref="CanStandardExactAcceptanceFilter"/> instance.</returns>
public static CanAcceptanceFilter CreateStandardFilter(short id)
{
return new CanStandardExactAcceptanceFilter(id);
}

/// <summary>
/// Creates a standard range acceptance filter for the specified range of identifiers.
/// </summary>
/// <param name="firstID">The first identifier in the range to be accepted by the filter.</param>
/// <param name="lastID">The last identifier in the range to be accepted by the filter.</param>
/// <returns>A <see cref="CanStandardRangeAcceptanceFilter"/> instance.</returns>
public static CanAcceptanceFilter CreateStandardFilter(short firstID, short lastID)
{
return new CanStandardRangeAcceptanceFilter(firstID, lastID);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Meadow.Hardware;

/// <summary>
/// Represents a collection of CAN acceptance filters.
/// </summary>
public sealed class CanAcceptanceFilterCollection
{
/// <summary>
/// Occurs when the collection is changed.
/// </summary>
public event EventHandler<(CollectionChangeAction Action, CanAcceptanceFilter Filter)>? CollectionChanged;

private List<CanAcceptanceFilter> _filters = new();

/// <summary>
/// Gets the maximum number of filters that can be contained in the collection.
/// </summary>
public int MaxFilterCount { get; }

/// <summary>
/// Initializes a new instance of the <see cref="CanAcceptanceFilterCollection"/> class with the specified maximum number of filters.
/// </summary>
/// <param name="maxFilterCount">The maximum number of filters that the collection can contain.</param>
public CanAcceptanceFilterCollection(int maxFilterCount)
{
MaxFilterCount = maxFilterCount;
}

/// <summary>
/// Gets the filter at the specified index.
/// </summary>
/// <param name="index">The zero-based index of the filter to get.</param>
/// <returns>The filter at the specified index.</returns>
public CanAcceptanceFilter this[int index]
{
get
{
lock (_filters)
{
return _filters[index];
}
}
}

/// <summary>
/// Gets the count of filters in the collection
/// </summary>
public int Count
{
get
{
lock (_filters)
{
return _filters.Count;
}
}
}

/// <summary>
/// Removes all filters from the collection.
/// </summary>
public void Clear()
{
lock (_filters)
{
foreach (var f in _filters.ToList())
{
Remove(f);
}
}
}

/// <summary>
/// Adds a filter to the collection.
/// </summary>
/// <param name="filter">The filter to add.</param>
public void Add(CanAcceptanceFilter filter)
{
lock (_filters)
{
if (_filters.Count >= MaxFilterCount)
{
throw new ArgumentOutOfRangeException($"Maximum filter count of {MaxFilterCount} has been reached");
}

_filters.Add(filter);
}

CollectionChanged?.Invoke(this, new(CollectionChangeAction.Add, filter));
}

/// <summary>
/// Removes a filter from the collection.
/// </summary>
/// <param name="filter">The filter to remove.</param>
public void Remove(CanAcceptanceFilter filter)
{
lock (_filters)
{
_filters.Remove(filter);
}
CollectionChanged?.Invoke(this, new(CollectionChangeAction.Remove, filter));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Meadow.Hardware;

/// <summary>
/// Represents a CAN extended exact acceptance filter.
/// </summary>
public class CanExtendedExactAcceptanceFilter : CanAcceptanceFilter
{
/// <summary>
/// Gets the accepted identifier.
/// </summary>
public int AcceptID { get; }

/// <summary>
/// Initializes a new instance of the <see cref="CanExtendedExactAcceptanceFilter"/> class with the specified accepted identifier.
/// </summary>
/// <param name="acceptID">The accepted identifier.</param>
public CanExtendedExactAcceptanceFilter(short acceptID)
{
AcceptID = (short)(acceptID & 0x7ff);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Meadow.Hardware;

/// <summary>
/// Represents a CAN standard exact acceptance filter.
/// </summary>
public class CanStandardExactAcceptanceFilter : CanAcceptanceFilter
{
/// <summary>
/// Gets the accepted identifier.
/// </summary>
public short AcceptID { get; }

/// <summary>
/// Initializes a new instance of the <see cref="CanStandardExactAcceptanceFilter"/> class with the specified accepted identifier.
/// </summary>
/// <param name="acceptID">The accepted identifier.</param>
public CanStandardExactAcceptanceFilter(short acceptID)
{
AcceptID = (short)(acceptID & 0x7ff);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
namespace Meadow.Hardware;

/// <summary>
/// Represents a CAN extended range acceptance filter.
/// </summary>
public class CanExtendedRangeAcceptanceFilter : CanAcceptanceFilter
{
/// <summary>
/// Gets the first (inclusive) accepted identifier in the range.
/// </summary>
public int FirstAcceptID { get; }

/// <summary>
/// Gets the last (inclusive) accepted identifier in the range.
/// </summary>
public int LastAcceptID { get; }

/// <summary>
/// Initializes a new instance of the <see cref="CanExtendedRangeAcceptanceFilter"/> class with the specified range of accepted identifiers.
/// </summary>
/// <param name="firstAcceptID">The first accepted identifier in the range.</param>
/// <param name="lastAcceptID">The last accepted identifier in the range.</param>
public CanExtendedRangeAcceptanceFilter(int firstAcceptID, int lastAcceptID)
{
FirstAcceptID = firstAcceptID;
LastAcceptID = lastAcceptID;
}
}

/// <summary>
/// Represents a CAN standard range acceptance filter.
/// </summary>
public class CanStandardRangeAcceptanceFilter : CanAcceptanceFilter
{
/// <summary>
/// Gets the first (inclusive) accepted identifier in the range.
/// </summary>
public short FirstAcceptID { get; }

/// <summary>
/// Gets the last (inclusive) accepted identifier in the range.
/// </summary>
public short LastAcceptID { get; }

/// <summary>
/// Initializes a new instance of the <see cref="CanStandardRangeAcceptanceFilter"/> class with the specified range of accepted identifiers.
/// </summary>
/// <param name="firstAcceptID">The first accepted identifier in the range.</param>
/// <param name="lastAcceptID">The last accepted identifier in the range.</param>
public CanStandardRangeAcceptanceFilter(short firstAcceptID, short lastAcceptID)
{
FirstAcceptID = (short)(firstAcceptID & 0x7ff);
LastAcceptID = (short)(lastAcceptID & 0x7ff);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace Meadow.Hardware;
/// </summary>
public interface ICanBus
{
/// <summary>
/// Gets or sets the bus bit rate
/// </summary>
CanBitrate BitRate { get; set; }

/// <summary>
/// Occurs when a CAN frame is received.
/// </summary>
Expand All @@ -31,14 +36,12 @@ public interface ICanBus
ICanFrame? ReadFrame();

/// <summary>
/// Sets the CAN filter.
/// Clears any data currently in the bus receive buffers
/// </summary>
/// <param name="filter">The filter value.</param>
void SetFilter(int filter);
void ClearReceiveBuffers();

/// <summary>
/// Sets the CAN mask.
/// The collection of message acceptance filters for the bus
/// </summary>
/// <param name="filter">The mask value.</param>
void SetMask(int filter);
CanAcceptanceFilterCollection AcceptanceFilters { get; }
}
Loading