ArduinoCore-mbed icon indicating copy to clipboard operation
ArduinoCore-mbed copied to clipboard

Arduino_CAN des not work on Giga M4 core

Open tineira opened this issue 1 year ago • 0 comments

It is not possible to use CAN communications on the Giga M4 core. If you try to write something to the CAN network, the message is not recieved by other devices and if you try to read messages on the network, the core hangs after about 3 tries.

This is an example code of trying to write to the CAN bus that does not work, on the M4.

#ifdef CORE_CM7
// Core M7 code

  #include <RPC.h>
  
  void setup() {
      Serial.begin(115200);
      while(!Serial) ;
      
      RPC.begin();
  }

  void loop() {

    String buffer = "";
    while (RPC.available()) {
      buffer += (char)RPC.read();
    }
    if (buffer.length() > 0) {
      Serial.print(buffer);
    }
    delay(1000);
  }

#endif

/*------------------------------------------------------------------------------*/

#ifdef CORE_CM4
// Core M4 code

  #include <RPC.h>
  #include <Arduino_CAN.h>

  #define CAN_WRITE_EVERY 1000 

  // Write
  bool DI1 = true;
  bool DI2 = false;
  bool DI3 = true;
  bool DI4 = false;
  bool DI5 = true;
  bool DI6 = false;
  bool DI7 = true;
  bool DI8 = false;

  void changeValues(){
    //change values 
    DI1 = !DI1;
    DI2 = !DI2;
    DI3 = !DI3;
    DI4 = !DI4;
    DI5 = !DI5;
    DI6 = !DI6;
    DI7 = !DI7;
    DI8 = !DI8;
  }

  void canWork() {
    static unsigned long lastWriteMillis = 0;
   
    // CAN write
    if (lastWriteMillis + CAN_WRITE_EVERY < millis()) {
      // reset timer
      lastWriteMillis = millis();

      changeValues();

      RPC.println("Ready to send CAN Message");
      delay(50);
      // hardcoded can id
      static uint32_t const CAN_ID = 200;
      uint8_t const msg_data[] = {DI1,DI2,DI3,DI4,DI5,DI6,DI7,DI8};
      CanMsg msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);
      CAN.write(msg);

      delay(50);
      RPC.println("CAN Message sent");
      delay(50);
      RPC.println("Waiting");
    }
  }

  void setup() {
    RPC.begin();
    RPC.println("M4: Started");

    if (!CAN.begin(CanBitRate::BR_1000k))
    {
      RPC.println("CAN.begin(...) failed.");
      for (;;) {}
    }

    RPC.println("Can begun");

  }

  void loop() {
    canWork();
    RPC.print(".");
    delay(100);
  }

#endif

This is the same code but just running on the M7 and it works ok:

#ifndef CORE_CM7
#error Must run on M7 Core
#endif

#include <Arduino_CAN.h>

  #define CAN_WRITE_EVERY 1000 

  // Write
  bool DI1 = true;
  bool DI2 = false;
  bool DI3 = true;
  bool DI4 = false;
  bool DI5 = true;
  bool DI6 = false;
  bool DI7 = true;
  bool DI8 = false;

  void changeValues(){
    //change values 
    DI1 = !DI1;
    DI2 = !DI2;
    DI3 = !DI3;
    DI4 = !DI4;
    DI5 = !DI5;
    DI6 = !DI6;
    DI7 = !DI7;
    DI8 = !DI8;
  }

  void canWork() {
    static unsigned long lastWriteMillis = 0;
   
    // CAN write
    if (lastWriteMillis + CAN_WRITE_EVERY < millis()) {
      // reset timer
      lastWriteMillis = millis();

      changeValues();

      Serial.println("Ready to send CAN Message");
      delay(50);
      // hardcoded can id
      static uint32_t const CAN_ID = 200;
      uint8_t const msg_data[] = {DI1,DI2,DI3,DI4,DI5,DI6,DI7,DI8};
      CanMsg msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);
      CAN.write(msg);

      delay(50);
      Serial.println("CAN Message sent");
      delay(50);
      Serial.println("Waiting");
    }
  }

  void setup() {
      Serial.begin(115200);
      while(!Serial) ;

      if (!CAN.begin(CanBitRate::BR_1000k))
      {
        Serial.println("CAN.begin(...) failed.");
        for (;;) {}
      }

      Serial.println("Can begun");
  }


  void loop() {
    canWork();
    Serial.print(".");
    delay(100);
  }

This bug is related to #787 but that issue was closed and the solution does not work.

tineira avatar Dec 08 '23 14:12 tineira