Skip to content

Commit

Permalink
Merge pull request #633 from arduino/mbed-can-support
Browse files Browse the repository at this point in the history
Provide CAN library for enabling useage of CAN for ArduinoCore-mbed enabled boards.
  • Loading branch information
facchinm authored May 2, 2023
2 parents e594a0e + f4cad9f commit 8031008
Show file tree
Hide file tree
Showing 13 changed files with 350 additions and 4 deletions.
30 changes: 30 additions & 0 deletions libraries/Arduino_CAN/examples/CANRead/CANRead.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <Arduino_CAN.h>

/**************************************************************************************
* SETUP/LOOP
**************************************************************************************/

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

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

void loop()
{
if (CAN.available())
{
CanMsg const msg = CAN.read();
Serial.println(msg);
}
}
55 changes: 55 additions & 0 deletions libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <Arduino_CAN.h>

/**************************************************************************************
* CONSTANTS
**************************************************************************************/

static uint32_t const CAN_ID = 0x20;

/**************************************************************************************
* SETUP/LOOP
**************************************************************************************/

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

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

static uint32_t msg_cnt = 0;

void loop()
{
/* Assemble a CAN message with the format of
* 0xCA 0xFE 0x00 0x00 [4 byte message counter]
*/
uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
CanMsg msg(CAN_ID, sizeof(msg_data), msg_data);

/* Transmit the CAN message, capture and display an
* error core in case of failure.
*/
if (int const rc = CAN.write(msg); rc <= 0)
{
Serial.print ("CAN.write(...) failed with error code ");
Serial.println(rc);
for (;;) { }
}

/* Increase the message counter. */
msg_cnt++;

/* Only send one message per second. */
delay(1000);
}
16 changes: 16 additions & 0 deletions libraries/Arduino_CAN/extras/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
`extras/scripts`
================
This directory contains helpful shell scripts when working with CAN.

### How-to-`SocketCAN`
```bash
sudo ./setup_scan.sh
```
Display received CAN frames via [`candump`](https://manpages.ubuntu.com/manpages/jammy/man1/candump.1.html):
```bash
candump can0
```
Transmit CAN frames via [`cansend`](https://manpages.ubuntu.com/manpages/jammy/man1/cansend.1.html):
```bash
cansend can0 00001234#DEADBEEF
```
4 changes: 4 additions & 0 deletions libraries/Arduino_CAN/extras/scripts/setup_scan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
sudo ip link set can0 type can bitrate 250000
sudo ip link set can0 up

32 changes: 32 additions & 0 deletions libraries/Arduino_CAN/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#######################################
# Syntax Coloring Map for CAN
#######################################

#######################################
# Class (KEYWORD1)
#######################################

CAN KEYWORD1
CAN1 KEYWORD1
CanMsg KEYWORD1
CanBitRate KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

begin KEYWORD2
end KEYWORD2
write KEYWORD2
available KEYWORD2
read KEYWORD2

#######################################
# Constants (LITERAL1)
#######################################

BR_100k LITERAL1
BR_125k LITERAL1
BR_250k LITERAL1
BR_500k LITERAL1
BR_1000k LITERAL1
10 changes: 10 additions & 0 deletions libraries/Arduino_CAN/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name=Arduino_CAN
version=1.0.0
author=Arduino
maintainer=Arduino <[email protected]>
sentence=CAN communication library for ArduinoCore-mbed enabled boards.
paragraph=This library provides CAN for ArduinoCore-mbed enabled boards which expose CAN on their connectors.
category=Other
url=
architectures=mbed,mbed_portenta
include=Arduino_CAN.h
100 changes: 100 additions & 0 deletions libraries/Arduino_CAN/src/Arduino_CAN.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2022 by Alexander Entinger <[email protected]>
* Arduino_CAN library for Arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "Arduino_CAN.h"

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

namespace arduino
{

/**************************************************************************************
* CTOR/DTOR
**************************************************************************************/

Arduino_CAN::Arduino_CAN(PinName const can_tx_pin, PinName const can_rx_pin)
: _can(can_rx_pin, can_tx_pin)
{

}

/**************************************************************************************
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

bool Arduino_CAN::begin(CanBitRate const can_bitrate)
{
int const rc = _can.frequency(static_cast<int>(can_bitrate));
return (rc == 1);
}

void Arduino_CAN::end()
{
/* Nothing to do. */
}

int Arduino_CAN::write(CanMsg const & msg)
{
mbed::CANMessage const can_msg(
msg.id,
msg.data,
msg.data_length,
CANData,
CANStandard);

return _can.write(can_msg);
}

size_t Arduino_CAN::available()
{
mbed::CANMessage can_msg;
bool const msg_read = _can.read(can_msg) > 0;

if (msg_read)
{
CanMsg const msg(
can_msg.id,
can_msg.len,
can_msg.data);

_rx_msg_buf.enqueue(msg);
}

return _rx_msg_buf.available();
}

CanMsg Arduino_CAN::read()
{
return _rx_msg_buf.dequeue();
}

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

} /* arduino */

/**************************************************************************************
* OBJECT INSTANTIATION
**************************************************************************************/

#if CAN_HOWMANY > 0
arduino::Arduino_CAN CAN(PIN_CAN0_TX, PIN_CAN0_RX);
#endif

#if CAN_HOWMANY > 1
arduino::Arduino_CAN CAN1(PIN_CAN1_TX, PIN_CAN1_RX);
#endif
86 changes: 86 additions & 0 deletions libraries/Arduino_CAN/src/Arduino_CAN.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2022 by Alexander Entinger <[email protected]>
* CAN library for Arduino.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/

#ifndef ARDUINO_CORE_MBED_CAN_H_
#define ARDUINO_CORE_MBED_CAN_H_

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <Arduino.h>
#include <mbed.h>

#include "api/HardwareCAN.h"

/**************************************************************************************
* COMPILE TIME CHECKS
**************************************************************************************/

#if !(defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_GIGA))
# error "CAN only available on Arduino Portenta H7 and Arduino Giga (of all ArduinoCore-mbed enabled boards)."
#endif

/**************************************************************************************
* TYPEDEF
**************************************************************************************/

typedef arduino::CanMsg CanMsg;

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

namespace arduino
{

/**************************************************************************************
* CLASS DECLARATION
**************************************************************************************/

class Arduino_CAN final : public HardwareCAN
{
public:
Arduino_CAN(PinName const can_tx_pin, PinName const can_rx_pin);
virtual ~Arduino_CAN() { }


bool begin(CanBitRate const can_bitrate) override;
void end() override;


int write(CanMsg const & msg) override;
size_t available() override;
CanMsg read() override;

private:
mbed::CAN _can;
CanMsgRingbuffer _rx_msg_buf;
};

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

} /* arduino */

/**************************************************************************************
* EXTERN DECLARATION
**************************************************************************************/

#if CAN_HOWMANY > 0
extern arduino::Arduino_CAN CAN;
#endif

#if CAN_HOWMANY > 1
extern arduino::Arduino_CAN CAN1;
#endif

#endif /* ARDUINO_CORE_MBED_CAN_H_ */
8 changes: 8 additions & 0 deletions variants/GIGA/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,12 @@ void _ontouch1200bps_();

#define USB_MAX_POWER (500)

#define CAN_HOWMANY 2

#define PIN_CAN0_TX (PB_13)
#define PIN_CAN0_RX (PB_12)

#define PIN_CAN1_TX (PH_13)
#define PIN_CAN1_RX (PB_8)

#endif //__PINS_ARDUINO__
2 changes: 1 addition & 1 deletion variants/PORTENTA_H7_M4/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
#include "../GIGA/pins_arduino.h"
#endif

#undef SERIAL_CDC
#undef SERIAL_CDC
2 changes: 1 addition & 1 deletion variants/PORTENTA_H7_M4/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@

#undef initVariant

void initVariant() {}
void initVariant() {}
5 changes: 5 additions & 0 deletions variants/PORTENTA_H7_M7/pins_arduino.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,9 @@ void _ontouch1200bps_();

#define USB_MAX_POWER (500)

#define CAN_HOWMANY 1

#define PIN_CAN0_TX (PH_13) /* Labeled CAN1_TX on high-density connector. */
#define PIN_CAN0_RX (PB_8) /* Labeled CAN1_RX on high-density connector. */

#endif //__PINS_ARDUINO__
4 changes: 2 additions & 2 deletions variants/PORTENTA_H7_M7/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ PinDescription g_APinDescription[] = {
{ PB_5, NULL, NULL, NULL },
{ PB_6, NULL, NULL, NULL },
{ PB_7, NULL, NULL, NULL },
{ PB_8, NULL, NULL, NULL },
{ PB_8, NULL, NULL, NULL }, // HD-connector: CAN1_RX -> software object: CAN
{ PB_9, NULL, NULL, NULL },
{ PB_10, NULL, NULL, NULL },
{ PB_11, NULL, NULL, NULL },
Expand Down Expand Up @@ -179,7 +179,7 @@ PinDescription g_APinDescription[] = {
{ PH_10, NULL, NULL, NULL },
{ PH_11, NULL, NULL, NULL },
{ PH_12, NULL, NULL, NULL },
{ PH_13, NULL, NULL, NULL },
{ PH_13, NULL, NULL, NULL }, // HD-connector: CAN1_TX -> software object: CAN
{ PH_14, NULL, NULL, NULL },
{ PH_15, NULL, NULL, NULL },
{ PI_0, NULL, NULL, NULL },
Expand Down

0 comments on commit 8031008

Please sign in to comment.