Git Product home page Git Product logo

acan2517fd's People

Contributors

flole998 avatar pierremolinaro avatar tlewiscpp avatar turmary avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

acan2517fd's Issues

Issues initializing ACan2517FD with Arduino Due

My code for initialization is:

    # define MCP2517_CS 9
    # define MCP2517_INT 2
    canController = new ACAN2517FD{MCP2517_CS, SPI, MCP2517_INT};
     
     // Arbitration bit rate: 125 kbit/s, data bit rate: 500 kbit/s
    ACAN2517FDSettings settings{ACAN2517FDSettings::OSC_40MHz, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x4};
    uint32_t errorCode{0};
    for (uint8_t i = 0; i < CAN_INITIALIZATION_RETRY_COUNT; i++) {
        errorCode = canController->begin (settings, [] { canController->isr(); });
        if (errorCode == 0) {
            SerialUSB.println ("Can OK") ;
            return errorCode;
        } else{
            SerialUSB.print ("Error Can: 0x") ;
            SerialUSB.println (errorCode, HEX) ;
            delay(50);
        }
    }

I am using the following breakout board: CAN with the following wiring:
Arduino | CAN-FD
50 (MOSI) -> DO
51 (MISO) -> DI
52 (SCK) -> SCK
5v -> 5v
3.3v -> 3.3v
9 (CS) -> CS
2 (INT) -> INT

And I get the error code 1 (kRequestedConfigurationModeTimeOut). I have the jumper on the board set to 3.3v voltage levels. Can you see anything I can try or something I'm missing? Does CLKO need to be landed somewhere? I also don't know what the oscillator is, but I've tried every one of the ACan2517FDSettings::Oscillator enums and get the same result. I have also tried switching DO/DI. Thanks.

inSettings.mDataBitRateFactor error in ACAN2517.cpp

Hello,

The variable inSettings.mDataBitRateFactor is not good in ACAN2517.cpp at the ligne 476 when you wante to write if DataBitRate. It is always at 1.

I use your library with arduino Uno with a vector interface for debugging.

Packet sending issue with configuration error 0x1 with wemos lolin ESP32 and MCP2518FD click

Hi Pierre,

I'm trying to run the CAN2517FD example LoopBackESP32 - intensive with the aforementioned microcontroller and CAN board.

However, we are facing an issue that I cannot find a solution for.

Only the first packet is sent, but subsequent packets fail to send. The Pin connections were wired to work with the ones preset in your code.

As you can see, the first packet is sent, but none is received. Following that, no other packets are sent successfully so the number stays at 1. Would appreciate any help or advice. Thanks!
Screenshot from 2021-10-27 13-29-27

SPI connection with Arduino Nano 33 BLE

Hello!
First of all, thanks a lot for the library.

I currently have a MCP2518FD-Click and i wanted to use it along with my Arduino 33 nano BLE.

I already tried the example LoopBackDemoArduinoUno with an Arduino Uno and everything works fine.

But when i switch to the Arduino Nano the code seems to stuck (Arduino IDE stops working as long as i don't disconnect the Arduino from the USB) when calling the function "writeRegister8" inside ACAN2517FD::begin.
Could it be something wrong with the SPI communication? I double checked the wiring and it seems to be correct (it's equal to the one on my Arduino Uno).

Also, i'm using the MCP2518 with jumper on VIO=3.3 (used a shifter with arduino UNO) and i'm connecting both 3.3V and 5V.

Thanks for your time!

ESP32-S3 + MCP2518FD

Hi,

I use a custom board and I get "Configuration error 0x10000" - which means timeout initialising the SPI device.
Screenshot 2023-11-23 at 10 34 29

But when I disconnect the other can bus device (works - verified) it initializes correctly, but still doesnt send any data (CAN TX line is permanently high, also no CAN receive):
Screenshot 2023-11-23 at 10 52 08

Anything else I should capture or add files? CAN Select has a 10K pullup resistor. I use a 40MHz resonator with 22pF capacitors. Tansceiver is a TCAN332.

extract from the code:

SPIClass SPI2(HSPI);

const uint8_t SOFT_SCK_PIN  = 19;
const uint8_t SOFT_MISO_PIN = 20;
const uint8_t SOFT_MOSI_PIN = 21;
#define SELECT 17 
ACAN2517FD can2(SELECT, SPI2, 255)

setup() {

SPI2.begin(SOFT_SCK_PIN,SOFT_MISO_PIN,SOFT_MOSI_PIN);
SPI2.setFrequency(5000000);

ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_40MHz_DIVIDED_BY_2, 125 * 1000, DataBitRateFactor::x4) ;
settings.mRequestedMode = ACAN2517FDSettings::NormalFD; 

const uint32_t errorCode = can2.begin (settings, NULL) ;
}

Cheers

Software Buffer is overflowing instead of filling the hardware buffer

I think the current way of how the software/hardware buffers are handled is not ideal and I would suggest doing the following: If the software buffers are full do not simply drop the hardware buffers but instead allow them to fill up further by not reading them. I think this only requires a simple change:

if ((it & (1 << 1)) != 0) { // Receive FIFO interrupt

Here a isFull check for the buffer needs to be appended. As the bits are for "interrupt pending" it shouldn't matter if we do read the register but don't fetch the data from the FIFO and the interrupt should still be pending. As the return value of isr_core is telling the calling code if it should run it again it is important that in this case "false" is returned so we are not deadlocking. I am not sure how well this goes with the attachInterrupt though as LOW would constantly re-trigger the isr as the pin is never rising, so maybe we would have to temporarily disable interrupts in that case and re-enable them once dispatchReceivedMessage has been called as then we definitely have space in the software buffer again.

Suggestions/concerns/ideas are welcome!

Only one CANFD message is being sent

I am currently able to send only one can fd message and when I send multiple messages in one loop, only the top message is being sent. other messages are sent only for just few sec and it stopped. only the top message is continously being sent. why is it so? is there any change that I should do for setting the lib? in case of CAN , i can send multiple messages at sametime using ACAN2517 lib.

Arduino Nano RequestedModeTimeOut

Hi,

I'm trying to get the loopbackdemo sketch to run, but seem to be stuck. I'm using an mcp2517fd on a custom board with a 20MHz clock. The sketch seems to run quite well, until the requested mode is changed. It seems like the chip is stuck in configuration mode. I've tried to modify the library to stay on 800khz, but that didn't seem to have any effect.

Data transfer seems to work as expected (CS is pulled low and clock signal is sent when sending a message). The sketch does say that the message is sent, but when querying the operating mode, I can see that it is still in configuration mode.
I tried modifying the interrupt routine, but it seems like it is never triggered, even though the interrupt pin is going low.

Anyone who has an idea on how I could debug this further?

Conventional/Normal CAN messages possible?

Looking at the source I found that both CAN-FD and normal CAN messages are defined in the corresponding files (CANFDMessage.h, CANMessage.h), however the implementations for receive or tryToSend are using the CANFDMessage definitions.

This leads me to the question: Does your library support conventional / non-FD CAN messages?

According to the MCP2518 datasheet (page 27) the OPMOD will default to 000 which results in "Set Normal CAN FD mode; supports mixing of CAN FD and Classic CAN 2.0 frames". At this point I only skimmed over the source, but maybe somebody who knows this library better already tested this or knows a definite answer to this.

Issue with Buffer.

Hello,

Firstly thank you so much for the library!. I currently have a MCP2517fd click board by mikroE. after some good time, I was able to figure out how to get it to work. the issue I am currently facing is that I am just able to receive a small set of can message after which I don't receive any more messages.
I am using a teensy4.0.

Below is the code I am running on it. Could you let me know what I am doing wrong.. I have gone through the documentation but couldn't figure out why I was facing this issue? could you guide me?

//——————————————————————————————————————————————————————————————————————————————
//  ACAN2517FD or ACAN2518FD send-even, for Teensy 3.5 using SPI1
//——————————————————————————————————————————————————————————————————————————————

#include <ACAN2517FD.h>

//——————————————————————————————————————————————————————————————————————————————
//  MCP2517FD connections: adapt theses settings to your design
//  As hardware SPI is used, you should select pins that support SPI functions.
//  This sketch is designed for a Teensy 3.5, using SPI1
//  But standard Teensy 3.5 SPI1 pins are not used
//    SCK input of MCP2517 is connected to pin #32
//    SDI input of MCP2517 is connected to pin #0
//    SDO output of MCP2517 is connected to pin #1
//  CS input of MCP2517 should be connected to a digital output port
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2517_SCK = 13 ; // SCK input of MCP2517
static const byte MCP2517_SDI =  11 ; // SDI input of MCP2517
static const byte MCP2517_SDO =  12 ; // SDO output of MCP2517

static const byte MCP2517_CS  = 10 ; // CS input of MCP2517
static const byte MCP2517_INT = 9 ; // INT output of MCP2517

//——————————————————————————————————————————————————————————————————————————————
//  ACAN2517FD Driver object
//——————————————————————————————————————————————————————————————————————————————

ACAN2517FD can (MCP2517_CS, SPI, MCP2517_INT) ;
static unsigned gSendDate = 0 ;
static unsigned gSentCount = 0 ;
static unsigned gReceivedCount = 0 ;
//——————————————————————————————————————————————————————————————————————————————
//   SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup () {
//--- Switch on builtin led
  pinMode (LED_BUILTIN, OUTPUT) ;
  digitalWrite (LED_BUILTIN, HIGH) ;
//--- Wait for Serial monitor (blink at 5 Hz)
  Serial.begin (38400) ;
  while (!Serial) { digitalWrite (LED_BUILTIN, !digitalRead (LED_BUILTIN)) ; }
//----------------------------------- Begin SPI1
  SPI.begin () ;
//----------------------------------- Configure ACAN2517FD
//--- For version >= 2.1.0
  ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_40MHz, 250 * 1000, DataBitRateFactor::x8);
settings.mRequestedMode = ACAN2517FDSettings::NormalFD;

//--- For version < 2.1.0
//  ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_4MHz10xPLL, 1000 * 1000, ACAN2517FDSettings::DATA_BITRATE_x8) ;
  settings.mDriverReceiveFIFOSize = 5000 ;
//--- Begin
  const uint32_t errorCode = can.begin (settings, canISR) ;
  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.print ("Data Phase segment 1: ") ;
  Serial.println (settings.mDataPhaseSegment1) ;
  Serial.print ("Data Phase segment 2: ") ;
  Serial.println (settings.mDataPhaseSegment2) ;
  Serial.print ("Data SJW:") ;
  Serial.println (settings.mDataSJW) ;
  Serial.print ("TDCO:") ;
  Serial.println (settings.mTDCO) ;
  Serial.print ("Even, error code 0x") ;
  Serial.println (errorCode, HEX) ;
 //--- Endless  loop on error
  while (errorCode != 0) { }
}


//——————————————————————————————————————————————————————————————————————————————
//   RECEIVE FUNCTION
//——————————————————————————————————————————————————————————————————————————————

void receiveFromFilter0 (const CANFDMessage & inMessage) {
  Serial.println ("Match filter 0") ;
}
//——————————————————————————————————————————————————————————————————————————————

void receiveFromFilter1 (const CANFDMessage & inMessage) {
  Serial.println ("Match filter 1") ;
}

//——————————————————————————————————————————————————————————————————————————————

void receiveFromFilter2 (const CANFDMessage & inMessage) {
  Serial.println ("Match filter 2") ;
}
//——————————————————————————————————————————————————————————————————————————————

static uint32_t gBlinkLedDate = 0 ;
static uint32_t gSentFrameCount = 0 ;
static uint32_t gReceivedFrameCount = 0 ;
static bool gCompleted = false ;
static const uint32_t SEND_COUNT = 50 * 1000 ;

//——————————————————————————————————————————————————————————————————————————————
void canISR () {
can.isr () ;
Serial.println("Interrupt Called");
handleReceivedMessages();

}
static void handleReceivedMessages (void) {
  CANFDMessage frame ;
//  Serial.println("Waiting ");
  while (can.receive (frame)) {
    gReceivedFrameCount ++;
    Serial.print("ID: ");
    Serial.print(frame.id,HEX);
    Serial.print(" len: ");
    Serial.print(frame.len);
    Serial.print(" data: ");
    for ( uint8_t i = 0; i < 8; i++ ) {
      Serial.print(frame.data[i], HEX); Serial.print(" ");
    }
    Serial.println("");
  }
}
static uint8_t gPhase = 0 ;

//——————————————————————————————————————————————————————————————————————————————
// 18F0010B 08FE6E0B
void loop () {
handleReceivedMessages();
}
void PrintHex8(uint8_t *data, uint8_t length) // prints 8-bit data in hex with leading zeroes
{
       Serial.print("0x");
       for (int i=0; i<length; i++) {
         if (data[i]<0x10) {Serial.print("0");}
         Serial.print(data[i],HEX);
         Serial.print(" ");
       }
}
//——————————————————————————————————————————————————————————————————————————————

image

10K ohm resistor on CS pin

Hi, where should I connect the 10k ohm resistor? I see in the manual that between vcc and CS line, but I couldnt find exactly what vcc pin is. is it 3.3v pin or 5v pin on mcp2517fd?

CANMessage in CANMessage.h

Hello,
is the following addition possible?
Also insert the signed int-variables in the union? I add this in every version

public : union {
uint64_t data64 ; // Caution: subject to endianness
int64_t data_s64 ; // Caution: subject to endianness <<
uint32_t data32 [2] ; // Caution: subject to endianness
int32_t data_s32 [2] ; // Caution: subject to endianness <<
uint16_t data16 [4] ; // Caution: subject to endianness
int16_t data_s16 [4] ; // Caution: subject to endianness <<
...

assertCS/deassertCS could be improved by directly writing to the registers

In an attempt to further improve the performance and in tackling down an issue I am having with a device I found this code in the Arduino Ethernet Library: https://github.com/arduino-libraries/Ethernet/blob/481f960bbef10e4b006fada962434d309c2b99b4/src/utility/w5100.h#L337

It directly accesses the ports/pins on some CPUs with a fallback to digitalWrite in case there is no direct method known for that CPU.

I believe that this could/should be implemented here aswell as it would reduce the size of the assert/deassert of the CS Line by a few microseconds (some tests show that this is 40 times faster, reducing the time from 5uS to 0.0125uS on a 16MHz AVR).

Trying to run on Arduino Giga R1

Hi everybody,

I'm trying to run "LoopBackDemoArduinoUnoNoInt" example on Arduino Giga R1 (I was able to run the ACAN2517FD library on Rapsberry Pico).

Each time I open the Serial Monitor the sketch freezes just after "MCP2517FD RAM Usage: 2016 bytes" (Arduino Giga R1 red led lights up).

It seems that sketch freezes on line : "const uint32_t errorCode = can.begin (settings, NULL)"

Is there a chance that ACAN2517FD works on Arduino Giga R1 or shall I stop my tests ?

Thanks !
(and thanks again to Pierre for this library !)

Additional features

First of all what a perfect library, thanks! i love the docu ❤️

It would be perfect to add following features

More operation modes

110 = Set Normal CAN 2.0 mode
001 = Set Sleep mode (this one is tricky to call in begin I believe so it would be nice to have dedicated function for sleep)

public: typedef enum : uint8_t {
InternalLoopBack = 2,
ExternalLoopBack = 5,
ListenOnly = 3,
NormalFD = 0
} RequestedMode ;

ideally there should be defined only one enum for modes, at the moment there are two - OperationMode and RequestedMode

Ability to use GPIOs

specifically use the XSTBYEN function, which will save one GPIO on MCU - together with added sleep function this is perfect duo


I can submit a PR and test physically after discussion

Code using millis() is not overflow-safe

There are functions using millis() similar to this (I found 4 of them):

bool ACAN2517FD::recoverFromRestrictedOperationMode (void) {
   bool recoveryDone = false ;
   if (currentOperationMode () == ACAN2517FD::RestrictedOperation) { // In Restricted Operation Mode
  //----------------------------------- Request mode (CON_REGISTER + 3)
  //  bits 7-4: Transmit Bandwith Sharing Bits ---> 0
  //  bit 3: Abort All Pending Transmissions bit --> 0
    writeRegister8 (CON_REGISTER + 3, mTXBWS_RequestedMode);
  //----------------------------------- Wait (10 ms max) until requested mode is reached
    bool wait = true ;
    const uint32_t deadline = millis () + 10 ;
    while (wait) {
      const uint8_t actualMode = (readRegister8 (CON_REGISTER + 2) >> 5) & 0x07 ;
      wait = actualMode != (mTXBWS_RequestedMode & 0x07) ;
      recoveryDone = !wait ;
      if (wait && (millis () >= deadline)) {
        wait = false ;
      }
    }
  }
  return recoveryDone ;
}

A deadline is defined as millis() + 10 and then it is checked if millis() is greater-equal this deadline. For simplicity let's assume the deadline and millis are returning an uint8_t (this can obviously scaled to larger values aswell with larger datatypes). When millis() is 250 then deadline would be 5 (because it overflowed), so millis() is greater 5 on the next run (somewhere between 250 and 255), causing an exit from the loop. Better would be setting starttime = millis() and then comparing millis() - starttime > 10 which would handle such overflows correctly: If millis() is 0 and starttime is 250 then 0 - 250 would be 5, which is correct.

noInterrupts() and Interrupts() call potentially unneccesary

I'm currently looking into code similar to this which can be found all over the library:

noInterrupts () ;

As far as I can see, as we are using attachInterrupt, the mSPI.beginTransaction (mSPISettings) ; a few lines before is taking care of that:

If your program will perform SPI transactions within an interrupt, call this function to register the interrupt number or name with the SPI library. This allows SPI.beginTransaction() to prevent usage conflicts. Note that the interrupt specified in the call to usingInterrupt() will be disabled on a call to beginTransaction() and re-enabled in endTransaction().

Looking at the SPI Library that seems to be the case: https://github.com/arduino/ArduinoCore-avr/blob/24e6edd475c287cdafee0a4db2eb98927ce3cf58/libraries/SPI/src/SPI.h#L181
As we are using attachInterrupt() the interruptMode is greater than 0 so it should not be necessary to do this.

Unless someone has any reason to not do so I would suggest to remove the noInterrupts() and Interrupts() calls. As far as the taskDISABLE_INTERRUPTS () ; for the ESP is concerned I think this should be moved before the beginTransaction() to prevent a race condition there. An interrupt could occur after the beginTransaction() call or in the middle of it messing up the settings. Same thing for the enabling, that should be done after the endTransaction().

These changes should remove quite some instructions from each SPI transaction, thus increasing the performance.

Error sending a message over CAN

Hi I am using examples of the project and using MCP2517fd breakout board with Adafruit itsybitsy M4 express to generate CAN messages. But I am getting the following output after changing certain thinngs in example code:

Bit Rate prescaler: 1
Arbitration Phase segment 1: 31
Arbitration Phase segment 2: 8
Arbitration SJW:8
Actual Arbitration Bit Rate: 1000000 bit/s
Exact Arbitration Bit Rate ? yes
Arbitration Sample point: 80%
Data Phase segment 1: 7
Data Phase segment 2: 2
Data SJW:2
TDCO:7
Even, error code 0x1
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0
Sent: 0, received: 0, errors 0, op mode 0, rcved buffer 0, overflows 0

Please help.
what else and what would be wrong possibly

Problem with SPI Communication

Dear all

I'm trying to set up a board using Microchip's MCP2518 controller (MCP2518FD CLICK Board) together with an Arduino Uno, but I can't get SPI communication working.

The example in ACAN2517FD\examples\LoopBackDemoArduinoUno\LoopBackDemoArduinoUno.ino seems to not be able to setup the SPI correctly.

Here a diagram of the SPI CLK (CH1) and SPI MOSI (CH2) using the example:

ACAN2517FD

As check I try the Arduino Barometric Pressure Sensor SPI example and here the SPI seems to be OK:

SPI_Example

Any suggestion how to proceed to find the root cause? Thanks in advance!

Ludwig

MCP2517FD CLICK with an Arduino UNO

Hello Pierre,

I hope you are doing well. I wanted to ask a question about code for a project I am working on. I am working on a development project for a company and I wanted to use this library. I am using the Mikroe MCP2517FD CLICK with an Arduino UNO. I have the arduino UNO connected to a sensor and I am getting values from the sensor. I want to transmit these data values to the CAN using CANFD and the Mikroe MCP2517FD CLICK. Once these data values are transmitted to the CAN BUS I want to receive it back in the arduino UNO board and print it to the serial monitor to verify that the data values have been properly transmitted/converted to the CAN BUS. Will this library work with the Mikroe MCP2517FD CLICK board? And I was looking at the example for arduino UNO but I could not understand some of it. It seems like there is no transmit data or receive data function in the library based on the example I saw, at least one that is compatible with Arduino UNO. Is that the case or is it that I am misinterpreting the code. I am a beginner when it comes to code and interfacing it with the CAN using bit registers, bit shifting and what not so it is also likely I just dont understand the code. My application seems pretty simple, that why I wanted to ask your help/opinion and what code or functions I should use.

Thank you,
Kareem

No data rate switching in CAN FD mode

Bonjour M. Molinaro and thank you for your work!

I tried to establish a CAN FD communication, using two Arduino Nano clones and two MCP2517FD click boards from Mikroelektronika, connected with a short DB9 cable (driver version 1.1.3). One is sender only, the other one receiver only.

It works perfectly transmitting some CAN FD Messages with 64 bytes payload, up to 1Mbit/s. But the data rate for the payload is not switched, as I can view on the scope. Even 125kbit/s arbitration rate and a x2 factor for data rate is ignored.

I found out that the the method ACAN2517FD::appendInControllerTxFIFO() is called, but the BRS bit is not set (as in the method ), so I copied the lines

if (mHasDataBitRate) { // Copied from sendViaTXQ()
  data |= 1 << 6 ; // Set BRS bit
} 

into this method.

Now, the sending controller seems to increase the data rate for the first bit and fails immediately. This is done exactly 32 times in a fast sequence, until it gives up. There is no error state, I can try to send the frames cyclically and it appears on the bus. Only, there is no valid data transmission.

Did you try the data rate switch using two MCP2517FD controllers? Am I missing an important configuration detail?

I did only slight modifications to your loopback example code, e.g.

ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_40MHz, 125UL * 1000UL, ACAN2517FDSettings::DATA_BITRATE_x4) ;

//settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack ; // No loopback here!

settings.mDriverTransmitFIFOSize = 2;
settings.mDriverReceiveFIFOSize = 2;
 

By the way:
Shouldn‘t it be

d = mUsesTXQ ? (1 << 4) : 0x00 ;
instead of

d = mUsesTXQ ? 0x04 : 0x00 ;

in ACAN2517FD::begin() ?

Kind regards,

Daniel

Configuration error 0x20000

Goood job... Thanks a lot Mr.Pierremolinaro #^_^#

I'm trying to send & receive sensors data between tow nodes ESP32 in FD mode.
I don't know how to append a specific data to frame when it declared:
CANFDMessage frame ;
when I uploaded the same example sketch to each ESP, serial monitor appears this lines without any received frame:

sizeof (ACAN2517FDSettings): 44 bytes
Configure ACAN2517FD
MCP2517FD RAM Usage: 2016 bytes
Configuration error 0x20000
Sent: 1
Sent: 2
Sent: 3
Sent: 4
Sent: 5
Sent: 6
Sent: 7
Sent: 8
Sent: 9

and continues sending...

SPI doesn't work on Arduino UNO

Thanks a lot Mr.Molinaro,

I'm trying to use 2517FD with an ATMega328P (arduino UNO), but it seems to SPI doesn´t work. Could you help me please?

Many thanks!
Jan

Arduino 1.8.8
I'm using standard SPI.h Arduino library.

Communication on serial monitor:

Hello
Error Can: 0x4
Sent: 1

No communication on MOSI/MISO/SCK ! (measured by oscilloscope).
By using direct SPI communication only (without your ACAN2517FD.h driver) SPI is working (measured by oscilloscope).

PINs: MOSI - PCINT3 (11)
MISO - PCINT4 (12)
SCK - PCINT5 (13)
CS - PCINT2 (10)
INT - PCINT19 (3)

Standard SPI PINs -> I'm using SPI.begin () ;

Used 20MHz crystal.

CODE: ( from your examples - only for HW function testing)

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

static const byte MCP2517_CS = 10 ; // CS input of MCP2517
static const byte MCP2517_INT = 3 ; // INT output of MCP2517

ACAN2517FD can (MCP2517_CS, SPI, MCP2517_INT) ;

void setup () {
pinMode(A0, OUTPUT); //LED1
pinMode(A1, OUTPUT); //LED2
pinMode(A5, OUTPUT); //PC5
digitalWrite (A5, LOW) ; //PC5 - CAN_STB transceiver (Normal mode)

Serial.begin (9600) ;
SPI.begin () ;    
while (!Serial) {}
Serial.println ("Hello") ;
// Arbitration bit rate: 125 kbit/s, data bit rate: 500 kbit/s
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_20MHz, 125 * 1000, ACAN2517FDSettings::DATA_BITRATE_x4) ;
settings.mRequestedMode = ACAN2517FDSettings::InternalLoopBack ; // Select loopback mode
const uint32_t errorCode = can.begin (settings, [] { can.isr () ; }) ;
if (0 == errorCode) {
  Serial.println ("Can ok") ;
} else {
  Serial.print ("Error Can: 0x") ;
  Serial.println (errorCode, HEX) ;
}

}

static unsigned gSendDate = 0 ;
static unsigned gSentCount = 0 ;
static unsigned gReceivedCount = 0 ;

void loop () {
CANFDMessage message ;
if (gSendDate < millis ()) {
message.id = 0x542 ;
const bool ok = can.tryToSend (message) ;
if (ok) {
gSendDate += 2000 ;
gSentCount += 1 ;
Serial.print ("Sent: ") ;
Serial.println (gSentCount) ;
}
}
if (can.receive (message)) {
gReceivedCount += 1 ;
Serial.print ("Received: ") ;
Serial.println (gReceivedCount) ;
}
}

Issue while trying to send message with len of 7

Hello,

From the documentation :
Note that len property contains the actual length, not its encoding in CANFD frames. So valid values are:
0, 1, ..., 8, 12, 16, 20, 24, 32, 48, 64.

I understood I could send message with length of 1,2,3,4,5,6,7,8,12,20,24,32,48,64.

I probably misunderstood because I have issue while sending a message with len of 7. It seems message is not sent.

I have no issue while sending FD CAN message with len of 1, 4 or 12 for example. (awesome library !)

Could you please confirm 7 is an authorized value ?

Thank you by advance !

Trying to run on Raspberry Pico

Hi

First, thank you Pierre for this great, very well documented, library.

It runs very fine on Arduino UNO + Mikroe Click board MCP2518FD.

I'm now trying to run the library on Raspberry PICO using Arduino IDE.
FYI, I have run severall other codes, initially intented to Arduino boards, on Pico with success.

But with acan2517FD, no way. When I upload LoopBackDemoArduinoUnoNoInt.ino (with pins adapt) => no compiler issue, code uploaded with success but I always get 0X1 errorCode...

I have tried many many many things : with or without interrupts, Teensy3.1 scketch (32bit), tried to adapt bit rates, etc, etc but no success...

Could someone give me a way to adapt LoopBackDemoArduinoUnoNoInt program to run on Pico.

Thanks !

Operation Mode is not changing using arduino uno Loopback example

Hi, many thanks for this library,
I am using an Arduino uno and the LoopBackDemo example and when the REQOP is changed to 010 (Set Internal Loopback mode) nothing happens and the deadline is reached. I checked the MODIF flag and it keeps in 0 and the OPMOD always keeps in 100 (Configuration mode).
The SPI communication is working and I Set the MODIE bit to enable Mode change Interruptions.
Is the arduino uno the one that should take care of the interruption or when the REQOP is changed the MCP2517FD controller should do it by it self?
Do you know what could it be for the OPMOD don't change?
Thanks.
Best Regards,
Gabriel Pinheiro.

Problem with arduino due

I encountered a timeout error while attempting to run one of your example codes, specifically the loopback code, on an Arduino Due. In order to investigate the issue further, I decided to write a small program to configure and trigger the GPIO of the click board, and that seemed to work without any problems.

Now, I'm wondering if there are any specific configurations that I should be aware of when trying to configure CANFD using the Arduino Due. Could you provide me with some guidance on this matter? Alternatively, is it possible that the issue I'm experiencing is a result of a bug in the code or the system?

Problem Recieving messages with MCP2517FD Click

Hi pierre,

First of all, thank you for your development of such a powerful library regarding CANFD.
My issue here is that I can't recieve CAN2.0 messages using a innomaker usb2can device. The code and hardware work perfectly when using external or internal loopback mode but with NormalFD mode i can't seem to recieve messages throurgh the db9 connector.

I'm using a mikrobus arduino uno click shield connected to an arducam ESP32. I've tried changing the VIO SEL jumper to 5v but hasn't helped. I've also added a 120ohm resistor to the innomakers output to have a 120 resistor on both ends. Didn't help either.

I'm attaching both the recieve error passive and the code. Thanks !!!

Screenshot 2023-04-06 at 20 59 06

#include <Ticker.h>

#include <FS.h>
#include <SPI.h>
#include <ACAN2517FD.h>
#include <SD.h>

//——————————————————————————————————————————————————————————————————————————————
// ACAN2517FD (ESP32) + SD Datalogger + Emulator
//——————————————————————————————————————————————————————————————————————————————

#ifndef ARDUINO_ARCH_ESP32
#error "Select an ESP32 board"
#endif

// Define EMULATOR for simulations
//#define EMULATOR

//——————————————————————————————————————————————————————————————————————————————
// Libraries
//——————————————————————————————————————————————————————————————————————————————

static const byte MCP2517_SCK = 25 ; // SCK input of MCP2517
static const byte MCP2517_MOSI = 27 ; // SDI input of MCP2517
static const byte MCP2517_MISO = 26 ; // SDO output of MCP2517
static const byte MCP2517_CS = 0 ; // CS input of MCP2517
static const byte MCP2517_INT = 13 ; // Interruption PIN of MCP2517

//——————————————————————————————————————————————————————————————————————————————
// Global Variables: ACAN2517FD Driver object + SPI Class + unint8_t's
//——————————————————————————————————————————————————————————————————————————————

SPIClass hspi(HSPI);

ACAN2517FD can (MCP2517_CS, hspi, MCP2517_INT) ;

CANFDMessage frame ;

CANFDMessage FIFO[256];

uint8_t in, out = 0;

Ticker blinker;

const float blinkerPace = 0.005; //seconds

static uint32_t gWriteFrameCount = 0 ;
static uint32_t gSentFrameCount = 0 ;

File dataFile;
File readFile;

//——————————————————————————————————————————————————————————————————————————————
// SETUP
//——————————————————————————————————————————————————————————————————————————————

void setup () {

delay(2000);

//--- Start serial
Serial.begin (115200) ;

//--- Begin SPI

hspi.begin (MCP2517_SCK,MCP2517_MISO,MCP2517_MOSI,MCP2517_CS) ;

//--- Configure ACAN2517FD
Serial.print ("sizeof (ACAN2517FDSettings): ") ;
Serial.print (sizeof (ACAN2517FDSettings)) ;
Serial.println (" bytes") ;
Serial.println ("Configure ACAN2517FD") ;

//--- For version >= 2.1.0
ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_40MHz, 500UL * 1000UL, DataBitRateFactor::x1);

#ifdef EMULATOR
settings.mRequestedMode = ACAN2517FDSettings::ExternalLoopBack;
#else
settings.mRequestedMode = ACAN2517FDSettings::NormalFD;
#endif

//--- RAM Usage
Serial.print ("MCP2517FD RAM Usage: ");
Serial.print (settings.ramUsage ());
Serial.println (" bytes");

//----------------------------------- Append filters
ACAN2517FDFilters filters;
//filters.appendFrameFilter (kStandard,0x120,receiveFromFilter1) ; // Filter ID = 0x120, Water and Intake air temp
//filters.appendFrameFilter (kStandard,0x100,receiveFromFilter2) ; // Filter ID = 0x100, RPM
//filters.appendFilter (kStandard,0x001,0x001,receiveFromFilter2); // Filter Impar
//filters.appendFilter (kStandard,0x001,0x000,receiveFromFilter3); // Filter Par
filters.appendPassAllFilter (receiveFromFilter0); // Filter ALL

//----------------------------------- Filters ok ?
if (filters.filterStatus () != ACAN2517FDFilters::kFiltersOk) {
Serial.print ("Error filter ") ;
Serial.print (filters.filterErrorIndex ()) ;
Serial.print (": ") ;
Serial.println (filters.filterStatus ()) ;
}
/*
settings.mISOCRCEnabled=false;
settings.mDriverTransmitFIFOSize = 1 ;
settings.mDriverReceiveFIFOSize = 1 ;

*/
//--- Begin CAN
const uint32_t errorCode = can.begin (settings, canISR,filters) ;

//const uint32_t errorCode = can.begin (settings, canISR) ;
//Serial.println(errorCode);

if (errorCode == 0) {
Serial.println(settings.CANBitSettingConsistency(),HEX);
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 ("%") ;

//--- Start Ticker - CAN Sender
#ifdef EMULATOR
blinker.attach(blinkerPace,blink);
#endif


//--- Start SD
if(!SD.begin()){
    Serial.println("Card Mount Failed");
    return;
}

//createDir(SD,"/CAN_MOTO");
//writeFile(SD, "/CAN_MOTO/Data.dat", "This is the file which is gonna save the CAN Messages\n");
dataFile = SD.open("/datalog.dat", FILE_WRITE);
if(!dataFile){
Serial.println("Error opening file");
}
}
else{
Serial.print ("Configuration error 0x") ;
Serial.println (errorCode, HEX) ;

//Restart if CAN doesnt begin correctly
ESP.restart();

}

//fillDATA();
//if(can.tryToSend(frame)){Serial.println("SENT");}
}

//——————————————————————————————————————————————————————————————————————————————
// Interruption Function
//—————————————————————————————————————————————————————————————————————————————-

void canISR () {

can.isr () ;

}

//——————————————————————————————————————————————————————————————————————————————
// BLINK() CAN SENDER
//——————————————————————————————————————————————————————————————————————————————

void blink(){

// Send CAN Message

fillDATA();
delay(400);

if (can.tryToSend(frame)) {
  gSentFrameCount ++ ;
  Serial.print ("Sent: ") ;
  Serial.println (gSentFrameCount) ;
  
}else{
  Serial.println ("Send failure") ;
  //if (frame.isValid()) {
    //Serial.println("Is Valid");
  //}
  Serial.print(frame.id);
  Serial.println(frame.len);
  //Serial.println(frame.data[3]);
  //appendFile(SD,"/CANMessages4/Data.txt","send failure");
  
}

}

//——————————————————————————————————————————————————————————————————————————————
// LOOP
//——————————————————————————————————————————————————————————————————————————————

char msg[276], msgdata[276];

struct datastore {
unsigned long timestamp;
uint16_t id;
unsigned char msg_data[8];
};

void loop () {

// When Received (in != out) --> Pop out of FIFO
while(can.dispatchReceivedMessage()){
if (in != out){
  
   struct datastore myData;
   struct datastore readData;
   
   //Initialize all the data from FIFO[out] = Frame recieved from interruption
   
   
   myData.id=FIFO[out].id;
    
   unsigned int len=0;
   len = FIFO[out].len;

   myData.timestamp = millis();

   //Serial.println(FIFO[out].type);

   //uint8_t data[64]; // Fixed to maximum length of CANFD-Data  (64 bytes)             
   for (int i = 0; i<len;i++)  // Array index --> From position 0 to (lenght-1)
    {
      myData.msg_data[i]=FIFO[out].data[i];
    }

    dataFile.write((const uint8_t *)&myData, sizeof(myData));


    // Print array to char 
    PrintHex8(myData.msg_data,len,msgdata);
   
     //Concatenates chars
    sprintf (msg,"%d %X %d ",myData.timestamp,myData.id,sizeof(myData.msg_data));
    strcat(msg,msgdata); 
    Serial.println(msg);

    out++;

#ifdef EMULATOR
if (gWriteFrameCount == 100){
  blinker.detach();
  dataFile.close();
  ReadMsg();
  //Stop();
  }
#endif

 gWriteFrameCount ++ ;
 
}
}

}

//——————————————————————————————————————————————————————————————————————————————

Cannot work with CAN FD 500kbps and 5Mbps

Hi,

I'm using CANFD with 500kpbs and 5Mbps, but your code only implements max DataBitRateFactor::x8.

To solve my problem I've changed your enum:

enum class DataBitRateFactor : uint8_t {
x1 = 1,
x2 = 2,
x3 = 3,
x4 = 4,
x5 = 5,
x6 = 6,
x7 = 7,
x8 = 8,
x9 = 9, //add for x9
x10 = 10 //add for x10
} ;

Could you update your library?

Thanks and best regards

Setting configuration error 0x10000 with ESP32 and MCP2518FD Click

I'm trying to add CAN FD to my ESP32 project with a Mikroe MCP2518FD CLICK. I am running the LoopBackDemoESP32 example. My only changes were the pin numbers and the oscillator frequency.

#define LED_BUILTIN 17

static const byte MCP2517_SCK = 18 ; // SCK input of MCP2517FD
static const byte MCP2517_MOSI = 19 ; // SDI input of MCP2517FD
static const byte MCP2517_MISO = 23 ; // SDO output of MCP2517FD

static const byte MCP2517_CS = 5 ; // CS input of MCP2517FD
static const byte MCP2517_INT = 14 ; // INT output of MCP2517FD

and

ACAN2517FDSettings settings (ACAN2517FDSettings::OSC_40MHz, 125 * 1000, DataBitRateFactor::x1) ;

The MCP2518FD is connected like this:
image

When I go the terminal I get a config error 0x10000 followed by a bunch of Sent packets, but none Received:
18:16:55.690 -> rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
18:16:55.690 -> configsip: 0, SPIWP:0xee
18:16:55.690 -> clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
18:16:55.690 -> mode:DIO, clock div:1
18:16:55.690 -> load:0x3fff0018,len:4
18:16:55.690 -> load:0x3fff001c,len:1216
18:16:55.690 -> ho 0 tail 12 room 4
18:16:55.690 -> load:0x40078000,len:9720
18:16:55.690 -> ho 0 tail 12 room 4
18:16:55.690 -> load:0x40080400,len:6352
18:16:55.690 -> entry 0x400806b8
18:16:55.861 -> sizeof (ACAN2517FDSettings): 44 bytes
18:16:55.861 -> Configure ACAN2517FD
18:16:55.861 -> MCP2517FD RAM Usage: 2016 bytes
18:16:55.861 -> Configuration error 0x10000
18:16:55.861 -> Sent: 1
18:16:57.794 -> Sent: 2
18:16:59.797 -> Sent: 3
18:17:01.807 -> Sent: 4
18:17:03.779 -> Sent: 5
18:17:05.837 -> Sent: 6

Can't loopback new library with an arduino mega

Hello,
I tried the sample test LoopBackDemoArduinoUno, before the new release it's ok,
But now i've a Configuration error 0x1 and i can't received anything.
Send return no error.
Can you help me ?

Thank you

Possible Bug regarding Retransmission Setting

The datasheet of the MCP2518FD says on page 27:

RTXAT: Restrict Retransmission Attempts bit( 1)
1 = Restricted retransmission attempts, CiFIFOCONm.TXAT is used
0 = Unlimited number of retransmission attempts, CiFIFOCONm.TXAT will be ignored

Current code says:
data8 = mUsesTXQ ? (1 << 4) : 0x00 ; // Bug fix in 1.1.4 (thanks to danielhenz)
I changed it to

data8 = 0x01 ; //Enable RTXAT to limit retransmissions (Flole)
data8 |= mUsesTXQ ? (1 << 4) : 0x00 ; // Bug fix in 1.1.4 (thanks to danielhenz)

Do I see that correctly that right now RTXAT is not set, causing the retransmissions to be always unlimited and the code should be modified just as I did it above?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.