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

added error support to MCP2515 #1068

Merged
merged 2 commits into from
Aug 21, 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
@@ -1,4 +1,5 @@
using Meadow.Hardware;
using System;

namespace Meadow.Foundation.ICs.CAN;

Expand Down Expand Up @@ -41,7 +42,18 @@ public partial class Mcp2515
break;

case CanOscillator.Osc_10MHz:
// TODO: add supported things here
switch (bitrate)
{
// case CanBitrate.Can_125kbps:
// return (0x03, 0xb8, 0x05);
case CanBitrate.Can_250kbps:
return (0x01, 0x90, 0x02);
case CanBitrate.Can_500kbps:
return (0x00, 0x90, 0x02);
case CanBitrate.Can_1Mbps:
return (0x00, 0x80, 0x00);
// TODO: add supported things here
}
break;

case CanOscillator.Osc_16MHz:
Expand Down Expand Up @@ -110,6 +122,39 @@ public partial class Mcp2515

}

throw new System.NotSupportedException("Provided Bitrate and Oscillator frequency is not supported");
// if we don't have a fixed, pre-calculated value, try to calculate one
var freq = oscillator switch
{
CanOscillator.Osc_8MHz => 8_000_000,
CanOscillator.Osc_10MHz => 10_000_000,
CanOscillator.Osc_16MHz => 16_000_000,
CanOscillator.Osc_20MHz => 20_000_000,
_ => throw new NotSupportedException(),
};

return CalculateConfigForOscillatorAndBitrate((int)oscillator, (int)bitrate);
}

private (byte CFG1, byte CFG2, byte CFG3) CalculateConfigForOscillatorAndBitrate(int oscillatorFreq, int bitRate)
{
int TQ = 16; // Assume 16 time quanta per bit time
int PropSeg = 3; // Propagation segment
int PhaseSeg1 = 5; // Phase Segment 1
int PhaseSeg2 = 5; // Phase Segment 2
int SJW = 1; // Synchronization Jump Width (1 TQ)

// Calculate Baud Rate Prescaler (BRP)
int brp = (oscillatorFreq / (2 * bitRate * TQ)) - 1;
if (brp < 0 || brp > 63) // BRP must fit in 6 bits
{
throw new ArgumentOutOfRangeException("Cannot calculate BRP for the given oscillator frequency and bitrate.");
}

// Calculate CNF1, CNF2, CNF3
var cfg1 = (byte)(((SJW - 1) << 6) | (brp & 0x3F)); // SJW is 2 bits, BRP is 6 bits
var cfg2 = (byte)(0x80 | ((PhaseSeg1 - 1) << 3) | (PropSeg - 1)); // Set SAM = 1 for single sampling
var cfg3 = (byte)(PhaseSeg2 - 1); // PhaseSeg2

return (cfg1, cfg2, cfg3);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public class Mcp2515CanBus : ICanBus

/// <inheritdoc/>
public event EventHandler<ICanFrame>? FrameReceived;
public event EventHandler<byte>? BusError;
/// <inheritdoc/>
public event EventHandler<CanErrorInfo>? BusError;

private Mcp2515 Controller { get; }

Expand Down Expand Up @@ -105,8 +106,20 @@ private void OnInterruptPortChanged(object sender, DigitalPortResult e)
}
break;
case InterruptCode.Error:
var errors = Controller.ReadRegister(Register.EFLG)[0];
BusError?.Invoke(this, errors);
if (BusError != null)
{
var errors = Controller.ReadRegister(Register.EFLG)[0];
// read the error counts
var tec = Controller.ReadRegister(Register.TEC)[0];
var rec = Controller.ReadRegister(Register.REC)[0];
BusError.Invoke(this, new CanErrorInfo
{
ReceiveErrorCount = rec,
TransmitErrorCount = tec
});
// clear the error interrupt
Controller.ClearInterrupt(InterruptFlag.ERRIF | InterruptFlag.MERRF);
}
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ public partial class Mcp2515
{
public enum CanOscillator
{
Osc_8MHz,
Osc_10MHz,
Osc_16MHz,
Osc_20MHz,
Osc_8MHz = 8_000_000,
Osc_10MHz = 10_000_000,
Osc_16MHz = 16_000_000,
Osc_20MHz = 20_000_000,
}

private enum Register : byte
Expand Down Expand Up @@ -143,8 +143,8 @@ private enum Control : byte
private enum Status : byte
{
NONE = 0,
RX0IF = (1 << 0),
RX1IF = (1 << 1)
RX0IF = 1 << 0,
RX1IF = 1 << 1
}

private enum Result : byte
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,7 @@ private void Initialize(CanBitrate bitrate, CanOscillator oscillator)

if (InterruptPort != null)
{
// TODO: add error condition handling
ConfigureInterrupts(InterruptEnable.RXB0 | InterruptEnable.RXB1 | InterruptEnable.ERR | InterruptEnable.MSG_ERR);
//ConfigureInterrupts(InterruptEnable.RXB0 | InterruptEnable.RXB1);
ConfigureInterrupts(InterruptEnable.RXB0 | InterruptEnable.RXB1 | InterruptEnable.ERR);
ClearInterrupt((InterruptFlag)0xff);
}
else
Expand Down Expand Up @@ -192,15 +190,15 @@ private void WriteFrame(ICanFrame frame, int bufferNumber)
{
// put the frame id into a buffer (0-2)
var sidh = (byte)(sdf.ID >> 3);
var sidl = (byte)(sdf.ID << 5 & 0xe0);
var sidl = (byte)((sdf.ID << 5) & 0xe0);
WriteRegister(ctrl_reg + 1, sidh);
WriteRegister(ctrl_reg + 2, sidl);
}
else if (frame is StandardRtrFrame srf)
{
// put the frame id into a buffer (0-2)
var sidh = (byte)(srf.ID >> 3);
var sidl = (byte)(srf.ID << 5 & 0xe0);
var sidl = (byte)((srf.ID << 5) & 0xe0);
WriteRegister(ctrl_reg + 1, sidh);
WriteRegister(ctrl_reg + 2, sidl);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public class PCanBus : ICanBus
{
/// <inheritdoc/>
public event EventHandler<ICanFrame>? FrameReceived;
/// <inheritdoc/>
public event EventHandler<CanErrorInfo>? BusError;

/// <inheritdoc/>
public CanAcceptanceFilterCollection AcceptanceFilters { get; } = new(5);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ namespace ICs.IOExpanders.PCanBasic;

public class PCanFdBus : ICanBus
{
/// <inheritdoc/>
public event EventHandler<ICanFrame>? FrameReceived;
/// <inheritdoc/>
public event EventHandler<CanErrorInfo>? BusError;

internal PCanFdBus(PCanConfiguration configuration)
{
throw new NotImplementedException();
Expand All @@ -13,8 +18,6 @@ internal PCanFdBus(PCanConfiguration configuration)

public CanAcceptanceFilterCollection AcceptanceFilters => throw new NotImplementedException();

public event EventHandler<ICanFrame>? FrameReceived;

public void ClearReceiveBuffers()
{
throw new NotImplementedException();
Expand Down
Loading