diff --git a/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.CanBus.cs b/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.CanBus.cs
index 362ffbf26..135c07b5e 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.CanBus.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.CanBus.cs
@@ -20,8 +20,8 @@ public class Mcp2515CanBus : ICanBus
///
public CanBitrate BitRate
{
- get => Controller._bitrate;
- set => Controller.Initialize(value, Controller._oscillator);
+ get => Controller.bitrate;
+ set => Controller.Initialize(value, Controller.oscillator);
}
///
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.cs b/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.cs
index ae0cd5113..5bd1967bf 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Driver/Mcp2515.cs
@@ -6,9 +6,9 @@
namespace Meadow.Foundation.ICs.CAN;
///
-/// Encapsulation for the Microchip MCP2515 CAN controller
+/// Represents a Microchip MCP2515 CAN controller, providing SPI-based communication with CAN functionality.
///
-public partial class Mcp2515 : ICanController
+public partial class Mcp2515 : ICanController, IDisposable
{
///
/// Default SPI clock mode for the MCP2515
@@ -23,20 +23,65 @@ public partial class Mcp2515 : ICanController
private byte PHASE_SEG2_Default = 0x03;//0x02;
private byte PROP_SEG_Default = 0x02;// 0x01;
- private ICanBus? _busInstance;
- private CanOscillator _oscillator;
- private CanBitrate _bitrate;
+ private bool portsCreated;
+ private ICanBus? busInstance;
+ private CanOscillator oscillator;
+ private CanBitrate bitrate;
private ISpiBus SpiBus { get; }
private IDigitalOutputPort ChipSelect { get; }
private Logger? Logger { get; }
private IDigitalInterruptPort? InterruptPort { get; }
+ private IDigitalOutputPort? ResetPort { get; }
+ ///
+ /// Returns true if the instance has been disposed, otherwise false
+ ///
+ public bool IsDisposed { get; private set; }
+
+ ///
+ /// Initializes a new instance of the class with specified SPI bus, chip select pin, and optional parameters.
+ ///
+ /// The SPI bus for communication.
+ /// The pin for chip select functionality.
+ /// The oscillator setting, default is 8 MHz.
+ /// Optional interrupt pin for CAN interrupts.
+ /// Optional reset pin for hardware resets.
+ /// Optional logger for diagnostic messages.
+ public Mcp2515(
+ ISpiBus bus,
+ IPin chipSelectPin,
+ CanOscillator oscillator = CanOscillator.Osc_8MHz,
+ IPin? interruptPin = null,
+ IPin? resetPin = null,
+ Logger? logger = null)
+ {
+ SpiBus = bus;
+ Logger = logger;
+ this.oscillator = oscillator;
+
+ ChipSelect = chipSelectPin.CreateDigitalOutputPort(true);
+ InterruptPort = interruptPin?.CreateDigitalInterruptPort(InterruptMode.EdgeFalling, ResistorMode.InternalPullUp);
+ ResetPort = resetPin?.CreateDigitalOutputPort(true);
+
+ portsCreated = true;
+ }
+
+ ///
+ /// Initializes a new instance of the class with a digital output chip select port and optional parameters.
+ ///
+ /// The SPI bus for communication.
+ /// The digital output port for chip select.
+ /// The oscillator setting, default is 8 MHz.
+ /// Optional interrupt port for CAN interrupts.
+ /// Optional reset port for hardware resets.
+ /// Optional logger for diagnostic messages.
public Mcp2515(
ISpiBus bus,
IDigitalOutputPort chipSelect,
CanOscillator oscillator = CanOscillator.Osc_8MHz,
IDigitalInterruptPort? interruptPort = null,
+ IDigitalOutputPort? resetPort = null,
Logger? logger = null)
{
if (interruptPort != null)
@@ -51,20 +96,22 @@ public Mcp2515(
ChipSelect = chipSelect;
Logger = logger;
InterruptPort = interruptPort;
- _oscillator = oscillator;
+ ResetPort = resetPort;
+
+ this.oscillator = oscillator;
}
///
public ICanBus CreateCanBus(CanBitrate bitrate, int busNumber = 0)
{
- if (_busInstance == null)
+ if (busInstance == null)
{
- Initialize(bitrate, _oscillator);
+ Initialize(bitrate, oscillator);
- _busInstance = new Mcp2515CanBus(this);
+ busInstance = new Mcp2515CanBus(this);
}
- return _busInstance;
+ return busInstance;
}
private void Initialize(CanBitrate bitrate, CanOscillator oscillator)
@@ -78,6 +125,12 @@ private void Initialize(CanBitrate bitrate, CanOscillator oscillator)
if (mode != Mode.Configure)
{
SetMode(Mode.Configure);
+
+ var check = ReadRegister(Register.CANSTAT)[0];
+ if (check == 0x00)
+ {
+ throw new Exception("Unable to read configuration register. Check signal lines are properly connected, including the RST.");
+ }
}
ClearFiltersAndMasks();
@@ -115,7 +168,7 @@ private void Initialize(CanBitrate bitrate, CanOscillator oscillator)
WriteRegister(Register.CNF1, cfg.CFG1);
WriteRegister(Register.CNF2, cfg.CFG2);
WriteRegister(Register.CNF3, cfg.CFG3);
- _bitrate = bitrate;
+ this.bitrate = bitrate;
LogRegisters(Register.CNF3, 3);
SetMode(Mode.Normal);
@@ -123,13 +176,13 @@ private void Initialize(CanBitrate bitrate, CanOscillator oscillator)
private CanBitrate Bitrate
{
- get => _bitrate;
+ get => bitrate;
set
{
var mode = GetMode();
SetMode(Mode.Configure);
- var cfg = GetConfigForOscillatorAndBitrate(_oscillator, value);
+ var cfg = GetConfigForOscillatorAndBitrate(oscillator, value);
WriteRegister(Register.CNF1, cfg.CFG1);
WriteRegister(Register.CNF2, cfg.CFG2);
WriteRegister(Register.CNF3, cfg.CFG3);
@@ -137,7 +190,7 @@ private CanBitrate Bitrate
SetMode(mode);
- _bitrate = value;
+ bitrate = value;
}
}
@@ -251,6 +304,13 @@ private void WriteFrame(ICanFrame frame, int bufferNumber)
private void Reset()
{
+ if (ResetPort != null)
+ {
+ ResetPort.State = false;
+ Thread.Sleep(10);
+ ResetPort.State = true;
+ }
+
Span tx = stackalloc byte[1];
Span rx = stackalloc byte[1];
@@ -263,7 +323,7 @@ private void LogRegisters(Register start, byte count)
{
var values = ReadRegister(start, count);
- Resolver.Log.Info($"{(byte)start:X2} ({start}): {BitConverter.ToString(values)}");
+ Resolver.Log.Debug($"{(byte)start:X2} ({start}): {BitConverter.ToString(values)}", "driver");
}
private Mode GetMode()
@@ -523,4 +583,31 @@ private DataFrame ReadDataFrame(RxBufferNumber bufferNumber)
return frame;
}
+
+ ///
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!IsDisposed)
+ {
+ if (disposing)
+ {
+ if (portsCreated)
+ {
+ ChipSelect.Dispose();
+ InterruptPort?.Dispose();
+ ResetPort?.Dispose();
+ }
+ }
+
+ IsDisposed = true;
+ }
+ }
+
+
+ ///
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
}
diff --git a/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Samples/Mcp2515_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Samples/Mcp2515_Sample/MeadowApp.cs
index 7e7403915..8d6b3d593 100644
--- a/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Samples/Mcp2515_Sample/MeadowApp.cs
+++ b/Source/Meadow.Foundation.Peripherals/ICs.CAN.Mcp2515/Samples/Mcp2515_Sample/MeadowApp.cs
@@ -23,10 +23,9 @@ public override Task Initialize()
expander = new Mcp2515(
Device.CreateSpiBus(),
- Device.Pins.D05.CreateDigitalOutputPort(true),
+ Device.Pins.D05,
Mcp2515.CanOscillator.Osc_8MHz,
- Device.Pins.D05.CreateDigitalInterruptPort(InterruptMode.EdgeFalling),
- Resolver.Log);
+ Device.Pins.D06);
return base.Initialize();