acan2517FD icon indicating copy to clipboard operation
acan2517FD copied to clipboard

can.begin returns ok but can.tryToSend leaves SPI lanes untouched

Open JDFranz opened this issue 9 months ago • 4 comments

Hi, I have a possible Bug (or if not, please enlighten me): Hardware: ESP32 S3 N16R8, MCP2517FD

I can Configure the MCP2517FD with SPI (errorCode 0x00). Configuration has a visible SPI signal. However, when trying to transmit. The SPI lanes remain ide. Thus, the chip cannot transmit any messages, since it receives none via spi.

#include <ACAN2517FD.h>
#include <SPI.h>
#include "config.h"

ACAN2517FD can(MCP2517_CS, SPI, MCP2517_INT);

void canSetup()
{

    ACAN2517FDSettings settings(ACAN2517FDSettings::OSC_20MHz, 125 * 1000, DataBitRateFactor::x1);
    //--- For version < 2.1.0
    //  ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x1) ;
    // settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack; // Select loopback mode
    settings.mRequestedMode = ACAN2517FDSettings::NormalFD; // Select loopback mode
    // -- -Configure regular transmit chain(used when message.idx == 0, default)

    SPI.begin(MCP2517_SCK, MCP2517_MISO, MCP2517_MOSI);

    //--- Configure ACAN2517FD
    delay(2000);

    while (1)
    {

        const uint32_t errorCode = can.begin(settings, []
                                             { can.isr(); });
        if (errorCode == 0)
        {
            Serial.print("Bit Rate prescaler: ");
            Serial.println(settings.mBitRatePrescaler);
            Serial.print("Arbitration Phase segment 1: ");
            Serial.println(settings.mArbitrationPhaseSegment1);
            Serial.print("Arbitration Phase segment 2: ");
            Serial.println(settings.mArbitrationPhaseSegment2);
            Serial.print("Arbitration SJW:");
            Serial.println(settings.mArbitrationSJW);
            Serial.print("Actual Arbitration Bit Rate: ");
            Serial.print(settings.actualArbitrationBitRate());
            Serial.println(" bit/s");
            Serial.print("Exact Arbitration Bit Rate ? ");
            Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no");
            Serial.print("Arbitration Sample point: ");
            Serial.print(settings.arbitrationSamplePointFromBitStart());
            Serial.println("%");
            Serial.println("Configuration seems successful");
            return;
        }
        else
        {

            Serial.print("Configuring went wrong with errorcode: ");
            Serial.print(errorCode);
            Serial.print("sizeof (ACAN2517FDSettings): ");
            Serial.print(sizeof(ACAN2517FDSettings));
            Serial.println(" bytes");
            Serial.println("Configure ACAN2517FD");
            //--- For version >= 2.1.0
            Serial.print("MCP2517FD RAM Usage: ");
            Serial.print(settings.ramUsage());
            Serial.println(" bytes");
        }
    }
}

void setup()
{
    Serial.begin(115200);
    //--- Wait for serial (blink led at 10 Hz during waiting)
    while (!Serial)
    {
        delay(50);
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    }

    canSetup();
}

static uint32_t gBlinkLedDate = 0;
static uint32_t gReceivedFrameCount = 0;
static uint32_t gSentFrameCount = 0;

void loop()
{

    if (gBlinkLedDate < millis())
    {
        gBlinkLedDate = millis() + 500; // Update this to send every 2 seconds
        CANFDMessage frame;             // This needs to be defined here, or outside loop()
        frame.id = micros() & 0x7FE;
        frame.len = 64; // Be aware of payload size settings for the FIFO
        bool messageOK = frame.isValid();
        Serial.print("is valid: ");
        Serial.println(messageOK ? "yes" : "no");
        const bool ok = can.tryToSend(frame);

        if (ok)
        {
            gSentFrameCount += 1;
            Serial.print("Sent: ");
            Serial.println(gSentFrameCount);
        }
        else
        {
            Serial.println("Send failure");
            // Add a check for error counters if you frequently get send failure
            // Serial.print("Error counters: ");
            // Serial.println(can.errorCounters()); // From section 22.5
        }
    }
    // Keep the receive part commented out for now to isolate TX issues.
}

SPI Signal: First successful configuration and then idle lanes: Image

JDFranz avatar Jun 26 '25 14:06 JDFranz

Hello,

The library should work with an ESP32S3.

What is your board ? What are the pin settings (MCP2517_CS, MCP2517_INT, MCP2517_SCK, MCP2517_MISO, MCP2517_MOSI) ?

Is the MCP2517FD alone on the bus ?

Note the MCP2517FD is quite buggy, it is better to use an MCP2518FD.

Pierre

Le 26 juin 2025 à 16:34, Jan Dominik Franz @.***> a écrit :

JDFranz created an issue (pierremolinaro/acan2517FD#58) https://github.com/pierremolinaro/acan2517FD/issues/58 Hi, I have a possible Bug (or if not, please enlighten me): Hardware: ESP32 S3 N16R8, MCP2517FD

I can Configure the MCP2517FD with SPI (errorCode 0x00). Configuration has a visible SPI signal. However, when trying to transmit. The SPI lanes remain ide. Thus, the chip cannot transmit any messages, since it receives none via spi.

`#include <ACAN2517FD.h> #include <SPI.h> #include "config.h"

ACAN2517FD can(MCP2517_CS, SPI, MCP2517_INT);

void canSetup() {

ACAN2517FDSettings settings(ACAN2517FDSettings::OSC_20MHz, 125 * 1000, DataBitRateFactor::x1); //--- For version < 2.1.0 // ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x1) ; // settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack; // Select loopback mode settings.mRequestedMode = ACAN2517FDSettings::NormalFD; // Select loopback mode // -- -Configure regular transmit chain(used when message.idx == 0, default)

SPI.begin(MCP2517_SCK, MCP2517_MISO, MCP2517_MOSI);

//--- Configure ACAN2517FD delay(2000);

while (1) {

const uint32_t errorCode = can.begin(settings, []
                                     { can.isr(); });
if (errorCode == 0)
{
    Serial.print("Bit Rate prescaler: ");
    Serial.println(settings.mBitRatePrescaler);
    Serial.print("Arbitration Phase segment 1: ");
    Serial.println(settings.mArbitrationPhaseSegment1);
    Serial.print("Arbitration Phase segment 2: ");
    Serial.println(settings.mArbitrationPhaseSegment2);
    Serial.print("Arbitration SJW:");
    Serial.println(settings.mArbitrationSJW);
    Serial.print("Actual Arbitration Bit Rate: ");
    Serial.print(settings.actualArbitrationBitRate());
    Serial.println(" bit/s");
    Serial.print("Exact Arbitration Bit Rate ? ");
    Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no");
    Serial.print("Arbitration Sample point: ");
    Serial.print(settings.arbitrationSamplePointFromBitStart());
    Serial.println("%");
    Serial.println("Configuration seems successful");
    return;
}
else
{

    Serial.print("Configuring went wrong with errorcode: ");
    Serial.print(errorCode);
    Serial.print("sizeof (ACAN2517FDSettings): ");
    Serial.print(sizeof(ACAN2517FDSettings));
    Serial.println(" bytes");
    Serial.println("Configure ACAN2517FD");
    //--- For version >= 2.1.0
    Serial.print("MCP2517FD RAM Usage: ");
    Serial.print(settings.ramUsage());
    Serial.println(" bytes");
}

} }

void setup() { Serial.begin(115200); //--- Wait for serial (blink led at 10 Hz during waiting) while (!Serial) { delay(50); digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); }

canSetup(); }

static uint32_t gBlinkLedDate = 0; static uint32_t gReceivedFrameCount = 0; static uint32_t gSentFrameCount = 0;

void loop() {

if (gBlinkLedDate < millis()) { gBlinkLedDate = millis() + 500; // Update this to send every 2 seconds CANFDMessage frame; // This needs to be defined here, or outside loop() frame.id = micros() & 0x7FE; frame.len = 64; // Be aware of payload size settings for the FIFO bool messageOK = frame.isValid(); Serial.print("is valid: "); Serial.println(messageOK ? "yes" : "no"); const bool ok = can.tryToSend(frame);

if (ok)
{
    gSentFrameCount += 1;
    Serial.print("Sent: ");
    Serial.println(gSentFrameCount);
}
else
{
    Serial.println("Send failure");
    // Add a check for error counters if you frequently get send failure
    // Serial.print("Error counters: ");
    // Serial.println(can.errorCounters()); // From section 22.5
}

} // Keep the receive part commented out for now to isolate TX issues. }`

SPI Signal: First successful configuration and then idle lanes: image.png (view on web) https://github.com/user-attachments/assets/0388fde5-63c4-40e7-bdb7-d6dbd04be1b8 — Reply to this email directly, view it on GitHub https://github.com/pierremolinaro/acan2517FD/issues/58, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEWKZVE7B5SRAZN6YEONFH33FQAHTAVCNFSM6AAAAACAGNNLKSVHI2DSMVQWIX3LMV43ASLTON2WKOZTGE3TSMZUGY3DANA. You are receiving this because you are subscribed to this thread.

pierremolinaro avatar Jun 27 '25 09:06 pierremolinaro

Hello,

Thank you for your fast reply.

What is your board ? > ESP32-S3 DevKitC-1 N16R8 Module

Pin Settings: // MCP2517FD CAN Controller Pins #define MCP2517_CS 45 // CS input of MCP2517FD // #define MCP2517_MISO 35 // SCK input of MCP2517FD // #define MCP2517_MOSI 36 // SDI input of MCP2517FD // #define MCP2517_SCK 37 // SDO output of MCP2517FD //

Is the MCP2517FD alone on the bus ? > Yes

Note the MCP2517FD is quite buggy, it is better to use an MCP2518FD. > Did do that, and we've had some progress with that:

The library communicates exactly one message over the SPI after each can.begin()

Thanks in advance,

JDF

JDFranz avatar Jun 27 '25 09:06 JDFranz

Ok, if the MCP2517FD is alone on the bus, you should select loopback mode.

In normal mode, a CAN controller sends repeatedly the first frame, as it is not acknowledged by a receiver.

Pierre

Le 27 juin 2025 à 11:21, Jan Dominik Franz @.***> a écrit :

JDFranz left a comment (pierremolinaro/acan2517FD#58) https://github.com/pierremolinaro/acan2517FD/issues/58#issuecomment-3012322504 Hello,

Thank you for your fast reply.

What is your board ? > ESP32-S3 DevKitC-1 N16R8 Module https://www.amazon.de/dp/B0DBHGL73T?ref=ppx_yo2ov_dt_b_fed_asin_title&th=1 Pin Settings: // MCP2517FD CAN Controller Pins #define MCP2517_CS 45 // CS input of MCP2517FD // #define MCP2517_MISO 35 // SCK input of MCP2517FD // #define MCP2517_MOSI 36 // SDI input of MCP2517FD // #define MCP2517_SCK 37 // SDO output of MCP2517FD //

Is the MCP2517FD alone on the bus ? > Yes

Note the MCP2517FD is quite buggy, it is better to use an MCP2518FD. > Did do that, and we've had some progress with that:

The library communicates exactly one message over the SPI after each can.begin()

Thanks in advance,

JDF

— Reply to this email directly, view it on GitHub https://github.com/pierremolinaro/acan2517FD/issues/58#issuecomment-3012322504, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEWKZVGUIZOI7IVZAW5WSKD3FUEJNAVCNFSM6AAAAACAGNNLKSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTAMJSGMZDENJQGQ. You are receiving this because you commented.

pierremolinaro avatar Jun 27 '25 10:06 pierremolinaro

Ok it was a Problem with our schematic. Turns out CANFD hardware is vrey easily disturbed when having inconsistent setups. » Always use a PCB or a professional breakoutboard ( Do not use a Breadboard like we did) Here's our breakout board for the MCP2518FD and ATA6263, that seems to have worked:

Image

Does anyone else see significant differences to their schematic?

JDFranz avatar Aug 06 '25 09:08 JDFranz