arduino / arduino/ArduinoCore-mbed

Arduino_CAN des not work on Giga M4 core

Open
#795 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
411
Forks
225
PR merge metrics
No merged PRs in 30d

Description

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

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
#include

#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

#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.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reviewing the Arduino_CAN.h usage of CAN.begin() and CAN.write() in the CORE_CM4 example, then compare it with the working CORE_CM7 version and the related discussion in #787. Done means CAN writes are received by other devices and repeated reads no longer hang the Giga M4 core.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.