diff --git a/examples/SineWaveCAN/SineWaveCAN.ino b/examples/SineWaveCAN/SineWaveCAN.ino index 9328b45..06a673d 100644 --- a/examples/SineWaveCAN/SineWaveCAN.ino +++ b/examples/SineWaveCAN/SineWaveCAN.ino @@ -20,11 +20,12 @@ // #define IS_TEENSY_BUILTIN // Teensy boards with built-in CAN interface (e.g. Teensy 4.1). See below to select which interface to use. // #define IS_ARDUINO_BUILTIN // Arduino boards with built-in CAN interface (e.g. Arduino Uno R4 Minima) // #define IS_MCP2515 // Any board with external MCP2515 based extension module. See below to configure the module. +// #define IS_STM32_BUILTIN // STM32 boards with built-in CAN interface (e.g. STM32F4 Discovery). /* Board-specific includes ---------------------------------------------------*/ -#if defined(IS_TEENSY_BUILTIN) + defined(IS_ARDUINO_BUILTIN) + defined(IS_MCP2515) != 1 +#if defined(IS_TEENSY_BUILTIN) + defined(IS_ARDUINO_BUILTIN) + defined(IS_MCP2515) + defined(IS_STM32_BUILTIN) != 1 #warning "Select exactly one hardware option at the top of this file." #if CAN_HOWMANY > 0 || CANFD_HOWMANY > 0 @@ -58,6 +59,11 @@ struct ODriveStatus; // hack to prevent teensy compile error #endif // IS_TEENSY_BUILTIN +#ifdef IS_STM32_BUILTIN +// See https://github.com/pazi88/STM32_CAN +#include +#include "ODriveSTM32CAN.hpp" +#endif // IS_STM32_BUILTIN @@ -138,6 +144,22 @@ bool setupCan() { #endif +/* STM32 boards with built-in CAN */ + +#ifdef IS_STM32_BUILTIN + +STM32_CAN Can1( CAN1 ); +STM32_CAN& can_intf = Can1; + +bool setupCan() { + can_intf.begin(); + can_intf.setBaudRate(CAN_BAUDRATE); + return true; +} + +#endif // IS_STM32_BUILTIN + + /* Example sketch ------------------------------------------------------------*/ // Instantiate ODrive objects diff --git a/platformio.ini b/platformio.ini index bec6464..993d4af 100644 --- a/platformio.ini +++ b/platformio.ini @@ -31,3 +31,19 @@ framework = arduino build_flags = -DIS_MCP2515 lib_deps = https://github.com/sandeepmistry/arduino-CAN.git + +[env:stm32f405] +platform = ststm32 +board = adafruit_feather_f405 +framework = arduino +build_flags = + -DIS_STM32_BUILTIN + ; Enable serial. + ; See https://github.com/platformio/platform-ststm32/issues/420#issuecomment-672277396 + -USBCON + -DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC + ; Enable CAN module in HAL drivers. + ; See https://github.com/pazi88/STM32_CAN + -DHAL_CAN_MODULE_ENABLED +lib_deps = + https://github.com/pazi88/STM32_CAN.git#1.2.0 \ No newline at end of file diff --git a/src/ODriveSTM32CAN.hpp b/src/ODriveSTM32CAN.hpp new file mode 100644 index 0000000..cdc7ddb --- /dev/null +++ b/src/ODriveSTM32CAN.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include "ODriveCAN.h" +#include + +using CanMsg = CAN_message_t; + +// Must be defined by the application +void onCanMessage(const CanMsg& msg); + +static bool sendMsg(STM32_CAN& can_intf, uint32_t id, uint8_t length, const uint8_t* data) { + CanMsg msg; + msg.id = id; + msg.len = length; + if (data) { + for (int i = 0; i < length; ++i) { + msg.buf[i] = data[i]; + } + } + return can_intf.write(msg) >= 0; +} + +static void onReceive(const CanMsg& msg, ODriveCAN& odrive) { + odrive.onReceive(msg.id, msg.len, msg.buf); +} + +static void pumpEvents(STM32_CAN& intf, int max_events = 100) { + // max_events prevents an infinite loop if messages come at a high rate + CanMsg msg; + while (intf.read(msg) && max_events--) { + onCanMessage(msg); + } +} + +CREATE_CAN_INTF_WRAPPER(STM32_CAN)