From 9b4868dbc89966147ed6c39fd153f0489f981ef4 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Mon, 6 Mar 2023 13:16:01 +0100 Subject: [PATCH] Provide CAN library for enabling useage of CAN for ArduinoCore-mbed enabled boards. Caveat: which also make CAN available on their GPIOs. --- .../Arduino_CAN/examples/CANRead/CANRead.ino | 30 ++++++ .../examples/CANWrite/CANWrite.ino | 55 +++++++++++ libraries/Arduino_CAN/keywords.txt | 32 +++++++ libraries/Arduino_CAN/library.properties | 10 ++ libraries/Arduino_CAN/src/Arduino_CAN.cpp | 96 +++++++++++++++++++ libraries/Arduino_CAN/src/Arduino_CAN.h | 86 +++++++++++++++++ variants/PORTENTA_H7_M4/pins_arduino.h | 2 +- variants/PORTENTA_H7_M4/variant.cpp | 2 +- variants/PORTENTA_H7_M7/pins_arduino.h | 5 + variants/PORTENTA_H7_M7/variant.cpp | 4 +- 10 files changed, 318 insertions(+), 4 deletions(-) create mode 100644 libraries/Arduino_CAN/examples/CANRead/CANRead.ino create mode 100644 libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino create mode 100644 libraries/Arduino_CAN/keywords.txt create mode 100644 libraries/Arduino_CAN/library.properties create mode 100644 libraries/Arduino_CAN/src/Arduino_CAN.cpp create mode 100644 libraries/Arduino_CAN/src/Arduino_CAN.h diff --git a/libraries/Arduino_CAN/examples/CANRead/CANRead.ino b/libraries/Arduino_CAN/examples/CANRead/CANRead.ino new file mode 100644 index 000000000..9b2e34a77 --- /dev/null +++ b/libraries/Arduino_CAN/examples/CANRead/CANRead.ino @@ -0,0 +1,30 @@ +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +/************************************************************************************** + * 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); + } +} diff --git a/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino b/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino new file mode 100644 index 000000000..2482e2c42 --- /dev/null +++ b/libraries/Arduino_CAN/examples/CANWrite/CANWrite.ino @@ -0,0 +1,55 @@ +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +/************************************************************************************** + * 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); +} diff --git a/libraries/Arduino_CAN/keywords.txt b/libraries/Arduino_CAN/keywords.txt new file mode 100644 index 000000000..81d46a86d --- /dev/null +++ b/libraries/Arduino_CAN/keywords.txt @@ -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 diff --git a/libraries/Arduino_CAN/library.properties b/libraries/Arduino_CAN/library.properties new file mode 100644 index 000000000..4b4eb945e --- /dev/null +++ b/libraries/Arduino_CAN/library.properties @@ -0,0 +1,10 @@ +name=Arduino_CAN +version=1.0.0 +author=Arduino +maintainer=Arduino +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 diff --git a/libraries/Arduino_CAN/src/Arduino_CAN.cpp b/libraries/Arduino_CAN/src/Arduino_CAN.cpp new file mode 100644 index 000000000..f2e1abbde --- /dev/null +++ b/libraries/Arduino_CAN/src/Arduino_CAN.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022 by Alexander Entinger + * 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(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; + + 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 diff --git a/libraries/Arduino_CAN/src/Arduino_CAN.h b/libraries/Arduino_CAN/src/Arduino_CAN.h new file mode 100644 index 000000000..c2a481f4e --- /dev/null +++ b/libraries/Arduino_CAN/src/Arduino_CAN.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2022 by Alexander Entinger + * 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 +#include + +#include "api/HardwareCAN.h" + +/************************************************************************************** + * COMPILE TIME CHECKS + **************************************************************************************/ + +#if !(defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)) +# error "CAN only available on Arduino Portenta H7 (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_ */ diff --git a/variants/PORTENTA_H7_M4/pins_arduino.h b/variants/PORTENTA_H7_M4/pins_arduino.h index e54178535..98b9d7f8f 100644 --- a/variants/PORTENTA_H7_M4/pins_arduino.h +++ b/variants/PORTENTA_H7_M4/pins_arduino.h @@ -8,4 +8,4 @@ #include "../GIGA/pins_arduino.h" #endif -#undef SERIAL_CDC \ No newline at end of file +#undef SERIAL_CDC diff --git a/variants/PORTENTA_H7_M4/variant.cpp b/variants/PORTENTA_H7_M4/variant.cpp index c949632aa..edb8add1b 100644 --- a/variants/PORTENTA_H7_M4/variant.cpp +++ b/variants/PORTENTA_H7_M4/variant.cpp @@ -12,4 +12,4 @@ #undef initVariant -void initVariant() {} \ No newline at end of file +void initVariant() {} diff --git a/variants/PORTENTA_H7_M7/pins_arduino.h b/variants/PORTENTA_H7_M7/pins_arduino.h index 45fde5367..d0ca4ed90 100644 --- a/variants/PORTENTA_H7_M7/pins_arduino.h +++ b/variants/PORTENTA_H7_M7/pins_arduino.h @@ -164,4 +164,9 @@ void _ontouch1200bps_(); #define USB_MAX_POWER (500) +#define CAN_HOWMANY 1 + +#define PIN_CAN0_TX (PH_13) +#define PIN_CAN0_RX (PB_8) + #endif //__PINS_ARDUINO__ diff --git a/variants/PORTENTA_H7_M7/variant.cpp b/variants/PORTENTA_H7_M7/variant.cpp index 4e85cf618..7c62eb086 100644 --- a/variants/PORTENTA_H7_M7/variant.cpp +++ b/variants/PORTENTA_H7_M7/variant.cpp @@ -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 }, // CAN1 RX { PB_9, NULL, NULL, NULL }, { PB_10, NULL, NULL, NULL }, { PB_11, NULL, NULL, NULL }, @@ -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 }, // CAN1 TX { PH_14, NULL, NULL, NULL }, { PH_15, NULL, NULL, NULL }, { PI_0, NULL, NULL, NULL },