81 Commits
Author SHA1 Message Date
alias pillar1989 cb607da7da bump version to 2.3.4 2026-05-26 11:32:12 +08:00
fc19066027 fix: use pSPI->begin() and add skipSpiBegin option for ESP32 compatibility (#159)
ESP32 users need to call SPI.begin() with custom pin assignments before
using the library (GPIO matrix). The hardcoded SPI.begin() in
mcp2518fd::begin() overwrites this configuration.

Changes:
- Replace SPI.begin() with pSPI->begin() (consistent with MCP2515)
- Add optional _initSPI parameter (default true) to begin() across
  MCP_CAN, mcp2515, and mcp2518fd so ESP32 users can skip SPI init

Existing code is unaffected — default behavior unchanged.

Closes #158

Co-authored-by: pillar1989 <zuobaozhu@gmail.com>
2026-05-26 11:23:15 +08:00
alias pillar1989andGitHub ca8fcc7fe3 Add MCP2515 8MHz 83.3kbps bitrate support
Add the missing MCP_8MHz_83k3BPS timing macros and wire CAN_83K3BPS into the MCP_8MHz bitrate switch. Fixes #79.
2026-04-28 11:09:23 +08:00
yuan_mo 31438c426b add send and receive extended frames examples 2025-04-21 09:48:53 +08:00
ShuishengPengandGitHub ad48756e56 Merge pull request #153 from techie66/bugfix_140
Change order of TX buffer fill to ensure in-order sending of frames.
2025-02-06 10:22:56 +08:00
Jacob Geigle c8556d5c1b Change order of TX buffer fill to ensure in-order sending of frames. 2025-02-02 11:45:28 -05:00
Lesords 23b23eff5c ci: add an action to automatically close stale issues and PRs 2025-01-08 07:43:42 +00:00
ackPeng 6f556e2ac8 add run-cl-arduino.yml and add SERIAL_PORT_MONITOR define 2024-12-27 14:48:26 +08:00
Matthew 491283753f Add sync_issues GitHub Action for workflows 2024-10-08 18:24:20 +08:00
EthanethiolandGitHub 23666a81df Added MCP_8MHz_95k2BPS (#150) 2024-03-18 09:06:42 +08:00
Micah MundyandGitHub 6dcfabc65e Patch four-argument sendmsgbuf (#146)
maintains backward compatibility with previous versions of
the function call
2023-08-09 08:23:01 +08:00
Pasakorn TiwatthanontandGitHub 02d18fb3b3 Reset rx overflow flag (#144) 2023-06-01 08:54:16 +08:00
JaxonandGitHub 7328966ef0 Merge pull request #139 from Maxwelltoo/master
fix subclass reference error
2023-01-10 10:30:59 +08:00
Jaxon adceb9b415 fix subclass reference error 2023-01-10 10:24:18 +08:00
Micah MundyandGitHub eb6887ba3c Move the four-argument sendMsgBuf wrapper to mcp_can.h (#136) 2022-08-30 13:44:00 +08:00
Lakshantha Dissanayake b946ae7c24 Update: library.json and library.properties 2022-04-11 23:38:18 +05:30
Lakshantha 58a38c9387 Update: version 2022-04-11 09:02:38 +05:30
Lucas DietrichandGitHub e2cbc7bb07 Fix compilation warning -Wshift-count-overflow (#134)
Fix issue #129

Signed-off-by: Lucas Dietrich <ld.adecy@gmail.com>
2022-03-14 14:08:36 +08:00
Baozhu ZuoandGitHub 06e6e163a9 Merge pull request #131 from ivankravets/patch-2
Sync version to 2.3.1
2021-12-06 08:27:11 +08:00
Ivan KravetsandGitHub 9226a0ae6b Sync version to 2.3.1 2021-12-04 14:26:14 +02:00
Lakshantha DissanayakeandGitHub 6acaf5a258 Update version 2021-07-22 14:05:23 +05:30
Baozhu ZuoandGitHub b517530d07 Merge pull request #127 from techie66/master
Support for 12Mhz Crystals
2021-07-22 16:32:45 +08:00
Jacob GandGitHub c991cacd9a Merge branch 'Seeed-Studio:master' into master 2021-07-06 16:44:28 -07:00
Baozhu ZuoandGitHub 5a41853758 Merge pull request #123 from QuentinTorg/uno_wifi_r2_compatibility
Fix Arduino Uno Wifi Rev2 and Arduino Nano Every Compatibility
2021-06-08 07:45:39 +08:00
QuentinTorg 4080671c63 fix variable collision that broke compatibility with Arudino Uno Wifi R2 boards. May also affect Arduino Nano Every 2021-06-06 09:31:59 -04:00
Baozhu ZuoandGitHub c110bf10c0 Merge pull request #122 from adamayd/master
Removed special character and updated keywords.
2021-06-05 12:37:13 +08:00
Adam Ayd 1351334686 Removed special character and updated keywords. 2021-06-05 00:17:25 -04:00
Baozhu ZuoandGitHub f579f66402 Merge pull request #121 from adamayd/master
Updated libary.json to current version
2021-06-05 10:34:53 +08:00
Adam AydandGitHub 1b63d26adc Updated libary.json to current version 2021-06-03 22:49:02 -04:00
Jacob Geigle e9adda5cea 12MHz 10KBPS and 5KBPS removed 2021-05-15 12:16:58 -07:00
Jacob Geigle bb92e93e9b Added definitions for mcp2515 to use 12MHz clock 2021-05-15 06:44:15 -04:00
Lakshantha DissanayakeandGitHub efbcf196f8 Change version to 2.3.0 2021-05-13 11:54:03 +05:30
Lakshantha DissanayakeandGitHub 14f1e98a12 Merge pull request #120 from per1234/revert-name
Revert library name change
2021-05-13 11:53:19 +05:30
per1234 78173b3225 Revert library name change
Libraries are locked to the `name` value specified by the library.properties metadata file in the release at the time of
the Library Manager submission.

Any release with a different name is rejected by the Arduino Library Manager indexer.

References:
- https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ#why-arent-releases-of-my-library-being-picked-up-by-library-manager
- https://github.com/arduino/Arduino/wiki/Library-Manager-FAQ#how-can-i-change-my-librarys-name
2021-05-12 18:18:47 -07:00
Baozhu ZuoandGitHub f8a04fd600 Merge pull request #118 from silviu-toderita/master
Removed unused include statement
2021-05-10 08:15:12 +08:00
Silviu ToderitaandGitHub 5863c67c70 Re-include SoftwareSerial in conditional in can-serial.cpp 2021-05-08 12:28:14 -07:00
Silviu ToderitaandGitHub f3ae9d0f10 Removed unused include statement 2021-05-07 11:20:06 -07:00
Baozhu ZuoandGitHub 7ba9b7deff Merge pull request #117 from TyphoonSB/master
Update mcp2518fd_can.cpp
2021-05-06 08:32:19 +08:00
TyphoonSBandGitHub d756ec0980 Update mcp2518fd_can.cpp
disable filter controle register before changing the filter, and reenable it after chage.
2021-05-04 12:48:16 +02:00
turmary ef05384659 Move: library version to 2.2.0 2021-02-03 10:02:05 +08:00
turmary 66305bbf5d Move: can-serial.{h,cpp} back to src folder 2021-02-03 10:01:21 +08:00
turmary d315924485 Remove: disable SoftwareSerial by default, or else waste flash/ram space 2021-02-03 10:00:29 +08:00
turmary 85648cd0fc Add: baudrate 800KBPS to canbus-monitor 2021-02-03 09:48:35 +08:00
turmary 8b82b6ef89 Add: 800KBPS highlight 2021-02-02 21:11:00 +08:00
turmary 240bb4de04 Add: predefined CAN baudrate 800KBPS 2021-02-02 21:08:26 +08:00
turmary 438ae2bb21 Fixed: inputString maybe contain multiple commands 2021-02-01 20:27:53 +08:00
turmary 8920835971 Move: adapt canbus example to new API attach() 2021-02-01 20:26:53 +08:00
turmary 7cb25da245 Move: use pointer not object to access the dirver, to get the ability of virtual function 2021-02-01 20:26:02 +08:00
turmary feeb26e4e1 Move: rename CAN232 api init() to attach() 2021-02-01 20:24:36 +08:00
turmary d73add5f0a Move: CANFD argument to uint32_t from byte 2021-01-29 23:32:51 +08:00
turmary b2247a8436 Add: arbitary baudrate for MCP2518FD, and MCP2515 compatible definitions 2021-01-29 23:32:51 +08:00
turmary 9826a04cae Move: all wrapper functions into header file 2021-01-29 23:32:51 +08:00
turmary e1047f27e3 Optimize: code style of mcp2518fd 2021-01-29 16:36:44 +08:00
turmary d89af776af Move: CAN baudrate definitions to common header mcp_can.h 2021-01-29 16:36:06 +08:00
turmary 3dea108ee3 Update: sync code from https://github.com/latonita/arduino-canbus-monitor 2021-01-29 16:16:46 +08:00
turmary 7c195a14ed Revert "- Use Hardware Serial in CAN-monitor example"
please uncomment the line to enable Hardware Serial "//#define debug Serial"
This reverts commit 1fc462f2b2.
2021-01-29 11:24:27 +08:00
turmary c45e7935ff Remove: duplicate error code definitions 2021-01-29 11:24:27 +08:00
turmary 300c1c4a4b Add: optional argument err_ptr for checkError() 2021-01-29 09:32:40 +08:00
turmary 3dff8e3d20 Fix: product table title 2021-01-28 15:26:27 +08:00
turmary 39d55dc608 Update: all FD example works 2021-01-21 13:52:46 +08:00
turmary cfd840cd23 Add: API CANFD::len2dlc() 2021-01-18 17:30:00 +08:00
turmary 92597cb97d Fix from: example receive_interruptFD compiling fail 2021-01-18 17:28:59 +08:00
turmary efad5bb364 Add: more comments about CANFD examples 2021-01-15 19:15:49 +08:00
turmary 6dc4e7d197 Fix to: remove delay() which decrease performance 2021-01-15 17:49:56 +08:00
turmary c522d7842f Fix to: sendMsgBuf() support ext & rtr 2021-01-15 15:48:32 +08:00
turmary 0677b13bfc Fix to: readMsgBufID support ext & rtrBit 2021-01-15 14:37:22 +08:00
turmary 544d2c8eeb Add: a baudrate compatible argument to MCP2518FD CAN.begin() 2021-01-15 11:32:22 +08:00
Baozhu ZuoandGitHub e3834de29c Merge pull request #108 from GunZi200/master
Use HardwareSerial instead of SoftwareSerial in CAN-monitor example
2021-01-08 19:21:39 +08:00
Gudni 1fc462f2b2 - Use Hardware Serial in CAN-monitor example 2021-01-06 12:35:20 +00:00
turmaryandBaozhu Zuo 3a35904217 Move: can-serial source to example directory 2021-01-04 09:00:15 +08:00
turmaryandBaozhu Zuo 4577e4fa7b Move: can-serial compiled pass again 2021-01-04 09:00:15 +08:00
turmary 36a70d5cdc Move: library version to 2.1.0 2020-12-28 22:41:04 +08:00
turmary d8ecb0ddcc Move: close DEBUG message to reduce Flash or RAM usage 2020-12-28 22:38:28 +08:00
turmary 6ad2ba8c4b Move: reduce const string (RAM used on AVR-GCC platform) in examples 2020-12-28 20:52:22 +08:00
turmary dad91a1dba Move: SERIAL to SERIAL_PORT_MONITOR in examples 2020-12-28 20:50:49 +08:00
turmary cf1fbfaddf Add: example to receive all frames and print all fields id/type/data 2020-12-27 14:03:50 +08:00
turmary 06cf5a136d Add: random packets generator example 2020-12-27 13:01:40 +08:00
turmary fc04762c9e Fix: make all examples sequence proper 2020-12-25 15:52:28 +08:00
turmary 4e171d138e Fix: make send example sequence proper 2020-12-21 21:01:14 +08:00
wangcoolc 9a153768ee Remove useless debugging information 2020-12-10 19:32:14 +08:00
wangcoolc 69791769cf Add TransmitChannelEventAttemptClear() function 2020-12-10 19:31:16 +08:00
40 changed files with 2251 additions and 2141 deletions
+87
View File
@@ -0,0 +1,87 @@
name: Run Ci Arduino
on:
push:
pull_request:
repository_dispatch:
types: [trigger-workflow]
jobs:
ci-arduino:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout script repository
uses: actions/checkout@v4
with:
repository: Seeed-Studio/ci-arduino
path: ci
- name: Setup arduino cli
uses: arduino/setup-arduino-cli@v2.0.0
- name: Create a depend.list file
run: |
# eg: echo "<repo>" >> depend.list
echo "arduino-libraries/SD" >> depend.list
echo "frankjoshua/rosserial_arduino_lib" >> depend.list
- name: Create a ignore.list file
run: |
# eg: echo "<path>,<fqbn>" >> ignore.list
# ROS library has some issue with std_msg, so we ignore them,waiting for the fix
echo "send_Blink_ROS,Seeeduino:samd:seeed_XIAO_m0" >> ignore.list
echo "send_Blink_ROS,Seeeduino:nrf52:xiaonRF52840" >> ignore.list
echo "send_Blink_ROS,Seeeduino:nrf52:xiaonRF52840Sense" >> ignore.list
echo "send_Blink_ROS,Seeeduino:renesas_uno:XIAO_RA4M1" >> ignore.list
echo "send_Blink_ROS,rp2040:rp2040:seeed_xiao_rp2040" >> ignore.list
echo "send_Blink_ROS,rp2040:rp2040:seeed_xiao_rp2350" >> ignore.list
echo "send_Blink_ROS,esp32:esp32:XIAO_ESP32C3" >> ignore.list
echo "send_Blink_ROS,esp32:esp32:XIAO_ESP32C6" >> ignore.list
echo "send_Blink_ROS,esp32:esp32:XIAO_ESP32S3" >> ignore.list
echo "receive_sleep,Seeeduino:samd:seeed_XIAO_m0" >> ignore.list
echo "receive_sleep,Seeeduino:nrf52:xiaonRF52840" >> ignore.list
echo "receive_sleep,Seeeduino:nrf52:xiaonRF52840Sense" >> ignore.list
echo "receive_sleep,Seeeduino:renesas_uno:XIAO_RA4M1" >> ignore.list
echo "receive_sleep,rp2040:rp2040:seeed_xiao_rp2040" >> ignore.list
echo "receive_sleep,rp2040:rp2040:seeed_xiao_rp2350" >> ignore.list
echo "receive_sleep,esp32:esp32:XIAO_ESP32C3" >> ignore.list
echo "receive_sleep,esp32:esp32:XIAO_ESP32C6" >> ignore.list
echo "receive_sleep,esp32:esp32:XIAO_ESP32S3" >> ignore.list
echo "send_sleep,Seeeduino:samd:seeed_XIAO_m0" >> ignore.list
echo "send_sleep,Seeeduino:nrf52:xiaonRF52840" >> ignore.list
echo "send_sleep,Seeeduino:nrf52:xiaonRF52840Sense" >> ignore.list
echo "send_sleep,Seeeduino:renesas_uno:XIAO_RA4M1" >> ignore.list
echo "send_sleep,rp2040:rp2040:seeed_xiao_rp2040" >> ignore.list
echo "send_sleep,rp2040:rp2040:seeed_xiao_rp2350" >> ignore.list
echo "send_sleep,esp32:esp32:XIAO_ESP32C3" >> ignore.list
echo "send_sleep,esp32:esp32:XIAO_ESP32C6" >> ignore.list
echo "send_sleep,esp32:esp32:XIAO_ESP32S3" >> ignore.list
- name: Build sketch
run: ./ci/tools/compile.sh
- name: Build result
run: |
cat build.log
if [ ${{ github.event_name }} == 'pull_request' ] && [ -f compile.failed ]; then
exit 1
fi
- name: Generate issue
if: ${{ github.event_name != 'pull_request' }}
run: ./ci/tools/issue.sh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+25
View File
@@ -0,0 +1,25 @@
name: 'Close stale issues and PRs'
on:
workflow_dispatch:
schedule:
- cron: '0 4 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout script repository
uses: actions/checkout@v4
with:
repository: Seeed-Studio/sync-github-all-issues
path: ci
- name: Run script
run: ./ci/tools/stale.sh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+24
View File
@@ -0,0 +1,24 @@
name: Automate Issue Management
on:
issues:
types:
- opened
- edited
- assigned
- unassigned
- labeled
- unlabeled
- reopened
jobs:
add_issue_to_project:
runs-on: ubuntu-latest
steps:
- name: Add issue to GitHub Project
uses: actions/add-to-project@v1.0.2
with:
project-url: https://github.com/orgs/Seeed-Studio/projects/17
github-token: ${{ secrets.ISSUE_ASSEMBLE }}
labeled: bug
label-operator: NOT
+9 -4
View File
@@ -1,7 +1,7 @@
# Seeed Arduino CAN [![Build Status](https://travis-ci.com/Seeed-Studio/CAN_BUS_Shield.svg?branch=master)](https://travis-ci.com/Seeed-Studio/CAN_BUS_Shield)
CAN BUS Shield | 2-Channel CAN-BUS(FD) Shield )
CAN BUS Shield | 2-Channel CAN-BUS(FD) Shield
:-------------------------:|:-------------------------:
[![CAN BUS Shield](https://statics3.seeedstudio.com/seeed/file/2017-08/bazaar528529_img_2653a.jpg)](https://www.seeedstudio.com/CAN-BUS-Shield-V2-p-2921.html) | [![CAN BUS Shield](https://files.seeedstudio.com/wiki/CANBUS-HAT-for-Raspberry-Pi/103990563%20_Preview-07.png)](https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html)
@@ -10,17 +10,22 @@ CAN BUS Shield | 2-Channel CAN-BUS(FD) Shield )
- [CAN-BUS Shield V2](https://www.seeedstudio.com/CAN-BUS-Shield-V2-p-2921.html)
- [ 2-Channel CAN-BUS(FD) Shield for Raspberry Pi (MCP2518FD)](https://www.seeedstudio.com/CAN-BUS-FD-HAT-for-Raspberry-Pi-p-4742.html)
CAN-BUS is a common industrial bus because of its long travel distance, medium communication speed and high reliability. It is commonly found on modern machine tools and as an automotive diagnostic bus.
CAN-BUS is a common industrial bus because of it's long travel distance, medium communication speed and high reliability.
It is commonly found on modern machine tools and as an automotive diagnostic bus.
For more information, please refer to [CAN-BUS_Shield_V2.0 wiki page](http://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/) and [CAN-BUS FD wiki page](https://wiki.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi/)
For more information, please refer to [CAN-BUS_Shield_V2.0 wiki page](http://wiki.seeedstudio.com/CAN-BUS_Shield_V2.0/) and
[CAN-BUS FD wiki page](https://wiki.seeedstudio.com/2-Channel-CAN-BUS-FD-Shield-for-Raspberry-Pi/)
# License
This software is written by seeed studio and is licensed under The MIT License. Check License.txt for more information.
Contributing to this software is warmly welcomed. You can do this basically by forking, committing modifications and then pulling requests (follow the links above for operating guide). Adding change log and your contact into file header is encouraged. Thanks for your contribution.
Contributing to this software is warmly welcomed.
You can do this basically by forking, committing modifications and then pulling requests (follow the links above for operating guide).
Adding change log and your contact into file header is encouraged.
Thanks for your contribution.
[![Analytics](https://ga-beacon.appspot.com/UA-46589105-3/CAN_BUS_Shield)](https://github.com/igrigorik/ga-beacon)
+26 -33
View File
@@ -16,38 +16,35 @@
***************************************************************************************************/
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
@@ -81,24 +78,20 @@ void set_mask_filt() {
void sendPid(unsigned char __pid) {
unsigned char tmp[8] = {0x02, 0x01, __pid, 0, 0, 0, 0, 0};
SERIAL.print("SEND PID: 0x");
SERIAL.println(__pid, HEX);
SERIAL_PORT_MONITOR.print("SEND PID: 0x");
SERIAL_PORT_MONITOR.println(__pid, HEX);
CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp);
}
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial){};
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
set_mask_filt();
}
@@ -121,21 +114,21 @@ void taskCanRecv() {
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if get data
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
SERIAL.println("\r\n------------------------------------------------------------------");
SERIAL.print("Get Data From id: 0x");
SERIAL.println(CAN.getCanId(), HEX);
SERIAL_PORT_MONITOR.println("\r\n------------------------------------------------------------------");
SERIAL_PORT_MONITOR.print("Get Data From id: 0x");
SERIAL_PORT_MONITOR.println(CAN.getCanId(), HEX);
for (int i = 0; i < len; i++) { // print the data
SERIAL.print("0x");
SERIAL.print(buf[i], HEX);
SERIAL.print("\t");
SERIAL_PORT_MONITOR.print("0x");
SERIAL_PORT_MONITOR.print(buf[i], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
void taskDbg() {
while (SERIAL.available()) {
char c = SERIAL.read();
while (SERIAL_PORT_MONITOR.available()) {
char c = SERIAL_PORT_MONITOR.read();
if (c >= '0' && c <= '9') {
PID_INPUT *= 0x10;
+54 -35
View File
@@ -7,7 +7,7 @@
* Copyright (C) 2015 Anton Viktorov <latonita@yandex.ru>
* https://github.com/latonita/arduino-canbus-monitor
*
* This library is free software. You may use/redistribute it under The MIT License terms.
* This library is free software. You may use/redistribute it under The MIT License terms.
*
*****************************************************************************************/
@@ -15,50 +15,66 @@
#include "mcp_can.h"
#include "can-serial.h"
// #define CAN_2518FD
#define CAN_2515
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif // Set CS pin
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
void setup() {
Serial.begin(LWUART_DEFAULT_BAUD_RATE); // default COM baud rate is 115200.
// Can232::init (RATE, CLOCK)
// Rates: CAN_10KBPS, CAN_20KBPS, CAN_50KBPS, CAN_100KBPS, CAN_125KBPS, CAN_250KBPS, CAN_500KBPS, CAN_500KBPS, CAN_1000KBPS, CAN_83K3BPS
// Default is CAN_83K3BPS ;)))))))))
// Clock: MCP_16MHz or MCP_8MHz.
// Default is MCP_16MHz. Please note, not all CAN speeds supported. check big switch in mcp_can.cpp
// defaults can be changed in mcp_can.h
Serial.begin(LW232_DEFAULT_BAUD_RATE); // default COM baud rate is 115200.
while (!Serial) {
delay(10);
}
// Can232::init(); // rate and clock = LW232_DEFAULT_CAN_RATE and LW232_DEFAULT_CLOCK_FREQ
// Can232::init(CAN_125KBPS); // rate = 125, clock = LW232_DEFAULT_CLOCK_FREQ
//CanSerial::init(CAN_125KBPS, MCP_16MHz); // set default rate you need here and clock frequency of CAN shield. Typically it is 16MHz, but on some MCP2515 + TJA1050 it is 8Mhz
// associate the Can232 and the CAN lowlevel driver
Can232::attach(&CAN);
/*
* Warning:
* CAN232 protocol command Sn[CR] --- setup with standard CAN bit-rates
* not works on ARDUINO UNO when used with Linux slcand.
*
* Linux slcand open the USB-SERAIL and send commands imediately,
* but the UNO are in startup(reset fired by UNO builtin USB-SERIAL),
* UNO missed those commands.
*
*/
// Can232::init (RATE, CLOCK)
// Rates: CAN_10KBPS, CAN_20KBPS, CAN_50KBPS, CAN_100KBPS, CAN_125KBPS, CAN_250KBPS, CAN_500KBPS, CAN_800KBPS, CAN_1000KBPS, CAN_83K3BPS
// Default is CAN_83K3BPS.
// Clock: MCP_16MHz or MCP_8MHz.
// Default is MCP_16MHz. Please note, not all CAN speeds supported. check big switch in mcp_can.cpp
// defaults can be changed according to mcp_can.h
// Can232::init(); // rate and clock = LW232_DEFAULT_CAN_RATE and LW232_DEFAULT_CLOCK_FREQ
// Can232::init(CAN_125KBPS); // rate = 125, clock = LW232_DEFAULT_CLOCK_FREQ
Can232::init(CAN_125KBPS, MCP_16MHz); // set default rate you need here and clock frequency of CAN shield. Typically it is 16MHz, but on some MCP2515 + TJA1050 it is 8Mhz
CanSerial::init(CAN);
// optional custom packet filter to reduce number of messages comingh through to canhacker
// Can232::setFilter(myCustomAddressFilter);
// Can232::setFilter(myCustomAddressFilter);
}
INT8U myCustomAddressFilter(INT32U addr) {
INT8U ret = LWUART_FILTER_SKIP; //LW232_FILTER_PROCESS or LW232_FILTER_SKIP
INT8U ret = LW232_FILTER_SKIP; //LW232_FILTER_PROCESS or LW232_FILTER_SKIP
switch(addr) {
// case 0x01b: //VIN
// case 0x1C8: //lights
// case 0x2C0: // pedals
case 0x3d0: // sound vol, treb..
ret = LWUART_FILTER_PROCESS;
ret = LW232_FILTER_PROCESS;
// case 0x000: // ?
// case 0x003: //shifter
// case 0x015: // dor open close affects this as well
@@ -67,20 +83,23 @@ INT8U myCustomAddressFilter(INT32U addr) {
// break;
// case 0x002:
// case 0x1a7: //fuel cons or some other
// ret = 1;
// break;
// default:
// ret = 0;
// ret = 1;
// break;
// default:
// ret = 0;
}
return ret;
return ret;
}
void loop() {
CanSerial::loop();
Can232::loop();
}
void serialEvent() {
CanSerial::serialEvent();
#if defined(ARDUINO_ARCH_AVR)
void serialEvent()
#else
void serialEventRun()
#endif
{
Can232::serialEvent();
}
+20 -27
View File
@@ -7,27 +7,25 @@
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
#define SPI_CS_PIN 9
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
#define SERIAL Serial
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
@@ -37,35 +35,30 @@ mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
void setup() {
SERIAL.begin(115200);
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#endif
#ifdef CAN_2515
SERIAL_PORT_MONITOR.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS)) {
#endif
SERIAL.println("CAN init failed, retry");
SERIAL_PORT_MONITOR.println("CAN init failed, retry...");
delay(100);
}
SERIAL.println("CAN init ok");
SERIAL_PORT_MONITOR.println("CAN init ok");
#ifdef CAN_2518FD
if (CAN.mcpPinMode(GPIO_PIN_0, GPIO_MODE_INT)) {
#else
if (CAN.mcpPinMode(MCP_TX2RTS, MCP_PIN_IN)) {
#endif
SERIAL.println("TX2RTS is now an input");
SERIAL_PORT_MONITOR.println("TX2RTS is now an input");
} else {
SERIAL.println("Could not switch TX2RTS");
SERIAL_PORT_MONITOR.println("Could not switch TX2RTS");
}
}
void loop() {
SERIAL.print("TX2RTS is currently ");
SERIAL_PORT_MONITOR.print("TX2RTS is currently ");
#ifdef CAN_2518FD
SERIAL.println(CAN.mcpDigitalRead(GPIO_PIN_0));
SERIAL_PORT_MONITOR.println(CAN.mcpDigitalRead(GPIO_PIN_0));
#else
SERIAL.println(CAN.mcpDigitalRead(MCP_TX2RTS));
SERIAL_PORT_MONITOR.println(CAN.mcpDigitalRead(MCP_TX2RTS));
#endif
delay(500);
}
+21 -29
View File
@@ -4,30 +4,27 @@
#include "mcp2515_can.h"
#include "mcp2518fd_can.h"
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#define SPI_CS_PIN 9
#ifdef CAN_2518FD
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
@@ -39,27 +36,22 @@ mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#endif
#ifdef CAN_2515
while (CAN_OK != CAN.begin(CAN_500KBPS)) {
#endif // init can bus : baudrate = 500k
SERIAL.println("CAN init failed, retry");
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println("CAN init failed, retry");
delay(100);
}
SERIAL.println("CAN init ok");
SERIAL_PORT_MONITOR.println("CAN init ok");
#ifdef CAN_2518FD
if (CAN.mcpPinMode(GPIO_PIN_0, GPIO_MODE_INT)) {
#else
if (CAN.mcpPinMode(MCP_TX2RTS, MCP_PIN_IN)) {
#endif
SERIAL.println("RX0BF is now an output");
SERIAL_PORT_MONITOR.println("RX0BF is now an output");
} else {
SERIAL.println("Could not switch RX0BF");
SERIAL_PORT_MONITOR.println("Could not switch RX0BF");
}
#ifdef CAN_2518FD
@@ -67,14 +59,14 @@ void setup() {
#else
if (CAN.mcpPinMode(MCP_TX2RTS, MCP_PIN_IN)) {
#endif
SERIAL.println("RX1BF is now an output");
SERIAL_PORT_MONITOR.println("RX1BF is now an output");
} else {
SERIAL.println("Could not switch RX1BF");
SERIAL_PORT_MONITOR.println("Could not switch RX1BF");
}
}
void loop() {
SERIAL.println("10");
SERIAL_PORT_MONITOR.println("10");
#ifdef CAN_2518FD
CAN.mcpDigitalWrite(GPIO_PIN_0, GPIO_HIGH);
CAN.mcpDigitalWrite(GPIO_PIN_1, GPIO_LOW);
@@ -84,7 +76,7 @@ void loop() {
#endif
delay(500);
SERIAL.println("01");
SERIAL_PORT_MONITOR.println("01");
#ifdef CAN_2518FD
CAN.mcpDigitalWrite(GPIO_PIN_0, GPIO_LOW);
CAN.mcpDigitalWrite(GPIO_PIN_1, GPIO_HIGH);
+22 -31
View File
@@ -4,59 +4,50 @@
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif // Set CS pin
#endif
const int LED = 8;
boolean ledON = 1;
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
pinMode(LED, OUTPUT);
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println("Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
@@ -69,13 +60,13 @@ void loop() {
unsigned long canId = CAN.getCanId();
SERIAL.println("-----------------------------");
SERIAL.println("get data from ID: 0x");
SERIAL.println(canId, HEX);
SERIAL_PORT_MONITOR.println("-----------------------------");
SERIAL_PORT_MONITOR.println("get data from ID: 0x");
SERIAL_PORT_MONITOR.println(canId, HEX);
for (int i = 0; i < len; i++) { // print the data
SERIAL.print(buf[i]);
SERIAL.print("\t");
SERIAL_PORT_MONITOR.print(buf[i]);
SERIAL_PORT_MONITOR.print("\t");
if (ledON && i == 0) {
digitalWrite(LED, buf[i]);
@@ -87,7 +78,7 @@ void loop() {
ledON = 1;
}
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
+21 -31
View File
@@ -1,58 +1,48 @@
// demo: CAN-BUS Shield, receive data with check mode
// send data coming to fast, such as less than 10ms, you can use this way
// loovee, 2014-6-13
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
@@ -65,15 +55,15 @@ void loop() {
unsigned long canId = CAN.getCanId();
SERIAL.println("-----------------------------");
SERIAL.print("Get data from ID: 0x");
SERIAL.println(canId, HEX);
SERIAL_PORT_MONITOR.println("-----------------------------");
SERIAL_PORT_MONITOR.print("Get data from ID: 0x");
SERIAL_PORT_MONITOR.println(canId, HEX);
for (int i = 0; i < len; i++) { // print the data
SERIAL.print(buf[i], HEX);
SERIAL.print("\t");
SERIAL_PORT_MONITOR.print(buf[i], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
@@ -4,41 +4,37 @@
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif // Set CS pin
#endif
unsigned char flagRecv = 0;
@@ -47,23 +43,16 @@ unsigned char buf[8];
char str[20];
void setup() {
SERIAL.begin(115200);
while (!SERIAL) {
SERIAL_PORT_MONITOR.begin(115200);
while (!SERIAL_PORT_MONITOR) {
; // wait for serial port to connect. Needed for native USB port only
}
attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif // init can bus : baudrate = 500k
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
delay(100);
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
void MCP2515_ISR() {
@@ -75,21 +64,21 @@ void loop() {
// check if get data
flagRecv = 0; // clear flag
SERIAL.println("into loop");
SERIAL_PORT_MONITOR.println("into loop");
// iterate over all pending messages
// If either the bus is saturated or the MCU is busy,
// both RX buffers may be in use and reading a single
// message does not clear the IRQ conditon.
while (CAN_MSGAVAIL == CAN.checkReceive()) {
// read data, len: data length, buf: data buf
SERIAL.println("checkReceive");
SERIAL_PORT_MONITOR.println("checkReceive");
CAN.readMsgBuf(&len, buf);
// print the data
for (int i = 0; i < len; i++) {
SERIAL.print(buf[i]); SERIAL.print("\t");
SERIAL_PORT_MONITOR.print(buf[i]); SERIAL_PORT_MONITOR.print("\t");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
}
@@ -5,19 +5,25 @@
#include <SPI.h>
#include "mcp2518fd_can.h"
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
@@ -26,24 +32,29 @@ mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[64];
char str[20];
void setup() {
SERIAL.begin(115200);
while (!SERIAL) {
SERIAL_PORT_MONITOR.begin(115200);
while (!SERIAL_PORT_MONITOR) {
; // wait for serial port to connect. Needed for native USB port only
}
attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt
CAN.setMode(0);
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
CAN.setMode(CAN_NORMAL_MODE);
// init can bus : arbitration bitrate = 500k, data bitrate = 1M
while (0 != CAN.begin(CAN_500K_1M)) {
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
byte mode = CAN.getMode();
SERIAL.printf("CAN BUS get mode = %d\n\r",mode);
SERIAL.println("CAN BUS Shield init ok!");
SERIAL.println("CAN BUS Shield init ok!");
#ifdef ARDUINO_XIAO_RA4M1
char buffer[50];
sprintf(buffer, "CAN BUS mode = %d\n\r", mode);
SERIAL_PORT_MONITOR.print(buffer);
#else
SERIAL_PORT_MONITOR.printf("CAN BUS mode = %d\n\r", mode);
#endif
}
void MCP2515_ISR() {
@@ -55,20 +66,20 @@ void loop() {
// check if get data
flagRecv = 0; // clear flag
SERIAL.println("into loop");
SERIAL_PORT_MONITOR.println("into loop");
// iterate over all pending messages
// If either the bus is saturated or the MCU is busy,
// both RX buffers may be in use and reading a single
// message does not clear the IRQ conditon.
while (CAN_MSGAVAIL == CAN.checkReceive()) {
// read data, len: data length, buf: data buf
SERIAL.println("checkReceive");
SERIAL_PORT_MONITOR.println("checkReceive");
CAN.readMsgBuf(&len, buf);
// print the data
for (int i = 0; i < len; i++) {
SERIAL.print(buf[i]); SERIAL.print("\t");
SERIAL_PORT_MONITOR.print(buf[i]); SERIAL_PORT_MONITOR.print("\t");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
}
@@ -0,0 +1,112 @@
/*
* demo: CAN-BUS Shield, receive all frames and print all fields id/type/data
* to receive frame fastly, a poll in loop() is required.
*
* Copyright (C) 2020 Seeed Technology Co.,Ltd.
*/
#include <SPI.h>
#define CAN_2515
// #define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
// To TEST MCP2518FD CAN2.0 data transfer
#define MAX_DATA_SIZE 8
// To TEST MCP2518FD CANFD data transfer, uncomment below lines
// #undef MAX_DATA_SIZE
// #define MAX_DATA_SIZE 64
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#define MAX_DATA_SIZE 8
#endif
void setup() {
SERIAL_PORT_MONITOR.begin(115200);
while (!SERIAL_PORT_MONITOR) {}
#if MAX_DATA_SIZE > 8
/*
* To compatible with MCP2515 API,
* default mode is CAN_CLASSIC_MODE
* Now set to CANFD mode.
*/
CAN.setMode(CAN_NORMAL_MODE);
#endif
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println(F("CAN init fail, retry..."));
delay(100);
}
SERIAL_PORT_MONITOR.println(F("CAN init ok!"));
}
uint32_t id;
uint8_t type; // bit0: ext, bit1: rtr
uint8_t len;
byte cdata[MAX_DATA_SIZE] = {0};
void loop() {
// check if data coming
if (CAN_MSGAVAIL != CAN.checkReceive()) {
return;
}
char prbuf[32 + MAX_DATA_SIZE * 3];
int i, n;
unsigned long t = millis();
// read data, len: data length, buf: data buf
CAN.readMsgBuf(&len, cdata);
id = CAN.getCanId();
type = (CAN.isExtendedFrame() << 0) |
(CAN.isRemoteRequest() << 1);
/*
* MCP2515(or this driver) could not handle properly
* the data carried by remote frame
*/
n = sprintf(prbuf, "%04lu.%03d ", t / 1000, int(t % 1000));
/* Displayed type:
*
* 0x00: standard data frame
* 0x02: extended data frame
* 0x30: standard remote frame
* 0x32: extended remote frame
*/
static const byte type2[] = {0x00, 0x02, 0x30, 0x32};
n += sprintf(prbuf + n, "RX: [%08lX](%02X) ", (unsigned long)id, type2[type]);
// n += sprintf(prbuf, "RX: [%08lX](%02X) ", id, type);
for (i = 0; i < len; i++) {
n += sprintf(prbuf + n, "%02X ", cdata[i]);
}
SERIAL_PORT_MONITOR.println(prbuf);
}
// END FILE
+9 -17
View File
@@ -18,13 +18,6 @@
#include "mcp2515_can.h"
#include <avr/sleep.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
@@ -52,14 +45,13 @@ unsigned long lastMsgTime = 0;
char str[20];
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS, MCP_16MHz)) { // init can bus : baudrate = 500k
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
// attach interrupt
pinMode(CAN_INT, INPUT);
@@ -105,14 +97,14 @@ void loop() {
// print the data
for (int i = 0; i < len; i++) {
SERIAL.print(buf[i]); SERIAL.print("\t");
SERIAL_PORT_MONITOR.print(buf[i]); SERIAL_PORT_MONITOR.print("\t");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
} else if (millis() > lastBusActivity + KEEP_AWAKE_TIME) {
// Put MCP2515 into sleep mode
SERIAL.println(F("CAN sleep"));
SERIAL_PORT_MONITOR.println(F("CAN sleep"));
CAN.sleep();
// Put the transceiver into standby (by pulling Rs high):
@@ -123,10 +115,10 @@ void loop() {
}
// Put the MCU to sleep
SERIAL.println(F("MCU sleep"));
SERIAL_PORT_MONITOR.println(F("MCU sleep"));
// Clear serial buffers before sleeping
SERIAL.flush();
SERIAL_PORT_MONITOR.flush();
cli(); // Disable interrupts
if (!flagRecv) { // Make sure we havn't missed an interrupt between the check above and now. If an interrupt happens between now and sei()/sleep_cpu() then sleep_cpu() will immediately wake up again
@@ -149,7 +141,7 @@ void loop() {
digitalWrite(RS_OUTPUT, LOW);
}
SERIAL.println(F("Woke up"));
SERIAL_PORT_MONITOR.println(F("Woke up"));
}
}
@@ -0,0 +1,124 @@
// This is an example of receiving both standard frames and extended frames simultaneously.
// I have used two arrays, STANDARD_CAN_IDS and EXTENDED_CAN_IDS, to receive CAN messages with specific IDs.
// You need to set filters and masks for these IDs,
// and make sure to refer to and coordinate with the example for sending extended frames
#include <SPI.h>
#define CAN_2515
// #define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
// Define the list of standard CAN IDs to receive
const unsigned long STANDARD_CAN_IDS[] = {0x123, 0x456};
const int STANDARD_CAN_ID_COUNT = sizeof(STANDARD_CAN_IDS) / sizeof(STANDARD_CAN_IDS[0]);
// Define the list of extended CAN IDs to receive
const unsigned long EXTENDED_CAN_IDS[] = {0x1234567, 0x89ABCDE};
const int EXTENDED_CAN_ID_COUNT = sizeof(EXTENDED_CAN_IDS) / sizeof(EXTENDED_CAN_IDS[0]);
void setup()
{
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial){};
while (CAN_OK != CAN.begin(CAN_250KBPS))
{ // init can bus : baudrate = 250k
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
// Configure the standard frame filters
for (int i = 0; i < STANDARD_CAN_ID_COUNT; i++)
{
CAN.init_Mask(i, 0, 0x7FF); // Check all 11 bits of the standard frame
CAN.init_Filt(i, 0, STANDARD_CAN_IDS[i]);
}
// Configure the extended frame filters
for (int i = 0; i < EXTENDED_CAN_ID_COUNT; i++)
{
CAN.init_Mask(i + STANDARD_CAN_ID_COUNT, 1, 0x1FFFFFFF); // Check all 29 bits of the extended frame
CAN.init_Filt(i + STANDARD_CAN_ID_COUNT, 1, EXTENDED_CAN_IDS[i]);
}
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
if (CAN_MSGAVAIL == CAN.checkReceive())
{ // check if data coming
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
unsigned long canId = CAN.getCanId();
// Check if it is a standard CAN ID
for (int i = 0; i < STANDARD_CAN_ID_COUNT; i++)
{
if (canId == STANDARD_CAN_IDS[i])
{
SERIAL_PORT_MONITOR.println("-----------------------------");
SERIAL_PORT_MONITOR.print("Get standard data from ID: 0x");
SERIAL_PORT_MONITOR.println(canId, HEX);
for (int j = 0; j < len; j++)
{ // print the data
SERIAL_PORT_MONITOR.print(buf[j], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL_PORT_MONITOR.println();
break;
}
}
// Check if it is an extended CAN ID
for (int i = 0; i < EXTENDED_CAN_ID_COUNT; i++)
{
if (canId == EXTENDED_CAN_IDS[i])
{
SERIAL_PORT_MONITOR.println("-----------------------------");
SERIAL_PORT_MONITOR.print("Get extended data from ID: 0x");
SERIAL_PORT_MONITOR.println(canId, HEX);
for (int j = 0; j < len; j++)
{ // print the data
SERIAL_PORT_MONITOR.print(buf[j], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL_PORT_MONITOR.println();
break;
}
}
}
}
+23 -32
View File
@@ -6,43 +6,39 @@
#include <SPI.h>
#include <SD.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
File myFile;
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif // Set CS pin
#endif
unsigned char flagRecv = 0;
unsigned char len = 0;
@@ -50,24 +46,19 @@ unsigned char buf[8];
char str[20];
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println("Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
if (!SD.begin(4)) {
SERIAL.println("SD initialization failed!");
SERIAL_PORT_MONITOR.println("SD init fail!");
while (1);
}
SERIAL.println("SD initialization done.");
SERIAL_PORT_MONITOR.println("SD init OK.");
}
void MCP2515_ISR() {
@@ -91,19 +82,19 @@ void loop() {
// read data, len: data length, buf: data buf
CAN.readMsgBufID(&id, &len, buf);
SERIAL.print(id);
SERIAL.print(",");
SERIAL_PORT_MONITOR.print(id);
SERIAL_PORT_MONITOR.print(",");
myFile.print(id);
myFile.print(",");
for (int i = 0; i < len; i++) {
SERIAL.print(buf[i]);
SERIAL.print(",");
SERIAL_PORT_MONITOR.print(buf[i]);
SERIAL_PORT_MONITOR.print(",");
myFile.print(buf[i]);
myFile.print(",");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
myFile.println();
}
+20 -30
View File
@@ -4,57 +4,47 @@
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
//#define CAN_2515
#define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif // Set CS pin
#endif
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial){};
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -67,13 +57,13 @@ void loop() {
if (stmp[6] == 100) {
stmp[6] = 0;
stmp[5] = stmp[6] + 1;
stmp[5] = stmp[5] + 1;
}
}
CAN.sendMsgBuf(0x00, 0, 8, stmp);
delay(100); // send data per 100ms
SERIAL.println("CAN BUS sendMsgBuf ok!");
SERIAL_PORT_MONITOR.println("CAN BUS sendMsgBuf ok!");
}
// END FILE
+39 -35
View File
@@ -1,58 +1,62 @@
// demo: CAN-BUS Shield, send data
// loovee@seeed.cc
// demo: sendFD
// show how to send CANFD frames.
// only used with MCP2518FD shield.
#include <SPI.h>
#include "mcp2518fd_can.h"
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#if defined(SEEED_WIO_TERMINAL)
const int SPI_CS_PIN = BCM8;
#else
#define SERIAL Serial
#endif
#define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
#ifdef CAN_2518FD
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
// CANFD could carry data up to 64 bytes
#define MAX_DATA_SIZE 64
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
void setup() {
SERIAL.begin(115200);
while(!Serial){};
CAN.setMode(0); // Set FD Mode
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.begin(115200);
while (!SERIAL_PORT_MONITOR) {}
/*
* To compatible with MCP2515 API,
* default mode is CAN_CLASSIC_MODE
* Now set to CANFD mode.
*/
CAN.setMode(CAN_NORMAL_MODE);
// init can bus : arbitration bitrate = 500k, data bitrate = 1M
while (0 != CAN.begin(CAN_500K_1M)) {
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
byte mode = CAN.getMode();
SERIAL.print("CAN BUS get mode = ");
SERIAL.println(mode);
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.print("CAN mode = ");
SERIAL_PORT_MONITOR.println(mode);
}
unsigned char stmp[64] = {0};
unsigned char stmp[MAX_DATA_SIZE] = {0};
void loop() {
// send data: id = 0x00, standrad frame, data len = 8, stmp: data buf
stmp[63] = stmp[63] + 1;
if (stmp[63] == 100) {
stmp[63] = 0;
stmp[62] = stmp[62] + 1;
// send data: id = 0x00, standrad frame, data len = 64, stmp: data buf
stmp[MAX_DATA_SIZE - 1] = stmp[MAX_DATA_SIZE - 1] + 1;
if (stmp[MAX_DATA_SIZE - 1] == 100) {
stmp[MAX_DATA_SIZE - 1] = 0;
if (stmp[62] == 100) {
stmp[62] = 0;
stmp[61] = stmp[62] + 1;
stmp[MAX_DATA_SIZE - 2] = stmp[MAX_DATA_SIZE - 2] + 1;
if (stmp[MAX_DATA_SIZE - 2] == 100) {
stmp[MAX_DATA_SIZE - 2] = 0;
stmp[MAX_DATA_SIZE - 3] = stmp[MAX_DATA_SIZE - 3] + 1;
}
}
CAN.sendMsgBuf(0x00, 0, 15, stmp);
CAN.sendMsgBuf(0x00, 0, CANFD::len2dlc(MAX_DATA_SIZE), stmp);
delay(100); // send data per 100ms
SERIAL.println("CAN BUS sendMsgBuf ok!");
SERIAL_PORT_MONITOR.println("CAN BUS sendMsgBuf ok!");
}
// END FILE
+19 -28
View File
@@ -1,65 +1,56 @@
// demo: CAN-BUS Shield, send data
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
//#define CAN_2515
#define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif // Set CS pin
#endif
const int ledHIGH = 1;
const int ledLOW = 0;
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
unsigned char stmp[8] = {ledHIGH, 1, 2, 3, ledLOW, 5, 6, 7};
void loop() {
SERIAL.println("In loop");
SERIAL_PORT_MONITOR.println("In loop");
// send data: id = 0x70, standard frame, data len = 8, stmp: data buf
CAN.sendMsgBuf(0x70, 0, 8, stmp);
delay(1000); // send data once per second
+3 -11
View File
@@ -14,13 +14,6 @@
#include <ros.h>
#include <std_msgs/Empty.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
ros::NodeHandle nh;
const int SPI_CS_PIN = 9;
@@ -45,16 +38,15 @@ ros::Subscriber<std_msgs::Empty> sub("toggle_led", &messageCb);
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
nh.initNode();
nh.subscribe(sub);
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
@@ -0,0 +1,93 @@
// demo: CAN-BUS Shield, send data
// This is an example of sending both standard frames and extended frames simultaneously.
// I have used two arrays, STANDARD_CAN_IDS and EXTENDED_CAN_IDS, to store the IDs to be sent, and it supports defining custom send IDs
#include <SPI.h>
#define CAN_2515
// #define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
// Define the list of standard CAN IDs to receive
const unsigned long STANDARD_CAN_IDS[] = {0x123, 0x456};
const int STANDARD_CAN_ID_COUNT = sizeof(STANDARD_CAN_IDS) / sizeof(STANDARD_CAN_IDS[0]);
// Define the list of extended CAN IDs to receive
const unsigned long EXTENDED_CAN_IDS[] = {0x1234567, 0x89ABCDE};
const int EXTENDED_CAN_ID_COUNT = sizeof(EXTENDED_CAN_IDS) / sizeof(EXTENDED_CAN_IDS[0]);
void setup()
{
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial){};
while (CAN_OK != CAN.begin(CAN_500KBPS))
{ // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void loop()
{
// send data: id = 0x00, standrad frame, data len = 8, stmp: data buf
stmp[7] = stmp[7] + 1;
if (stmp[7] == 100)
{
stmp[7] = 0;
stmp[6] = stmp[6] + 1;
if (stmp[6] == 100)
{
stmp[6] = 0;
stmp[5] = stmp[5] + 1;
}
}
for (int i = 0; i < STANDARD_CAN_ID_COUNT; i++)
{
CAN.sendMsgBuf(STANDARD_CAN_IDS[i], 0, 8, stmp);//using ID List ID
delay(100);
}
for (int i = 0; i < EXTENDED_CAN_ID_COUNT; i++)
{
CAN.sendMsgBuf(EXTENDED_CAN_IDS[i], 1, 8, stmp);//using ID List ID
delay(100);
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
+137
View File
@@ -0,0 +1,137 @@
/*
* demo: CAN-BUS Shield, send random id/type/data
* This code has a little same with linux can-utils 'cangen -v'
*
* Copyright (C) 2020 Seeed Technology Co.,Ltd.
*/
#include <SPI.h>
#define CAN_2515
// #define CAN_2518FD
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
// TEST TEST MCP2518FD CAN2.0 data transfer
#define MAX_DATA_SIZE 8
// To TEST MCP2518FD CANFD data transfer, uncomment below lines
// #undef MAX_DATA_SIZE
// #define MAX_DATA_SIZE 64
#endif//CAN_2518FD
#ifdef CAN_2515
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#define MAX_DATA_SIZE 8
#endif
void setup() {
SERIAL_PORT_MONITOR.begin(115200);
while (!SERIAL_PORT_MONITOR) {}
#if MAX_DATA_SIZE > 8
/*
* To compatible with MCP2515 API,
* default mode is CAN_CLASSIC_MODE
* Now set to CANFD mode.
*/
CAN.setMode(CAN_NORMAL_MODE);
#endif
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL_PORT_MONITOR.println("CAN init ok!");
randomSeed(millis());
}
uint32_t id;
uint8_t type; // bit0: ext, bit1: rtr
unsigned len;
byte cdata[MAX_DATA_SIZE] = {0};
void loop() {
type = random(4);
if (type & 0x1) {
// total 29 bits
// Arduino AVR only generate up to 16 bits random number
id = random(0x1U << 14);
id |= (uint32_t)random(0x1U << 15) << 14;
} else {
id = random(0x1U << 11);
}
if (type & 0x2) {
len = 0;
// remote frame could also carry data
// but don't do it.
// len = random(0, MAX_DATA_SIZE + 1);
} else {
len = random(0, MAX_DATA_SIZE + 1);
}
int i;
for (i = 0; i < len; i++) {
cdata[i] = random(0x100);
}
#if MAX_DATA_SIZE > 8
// pad CANFD extra bytes with 0
for (i = len; i < MAX_DATA_SIZE; i++) {
cdata[i] = 0;
}
#endif
CAN.sendMsgBuf(id, bool(type & 0x1),
bool(type & 0x2),
#if MAX_DATA_SIZE > 8
CANFD::len2dlc(len),
#else
len,
#endif
cdata);
char prbuf[32 + MAX_DATA_SIZE * 3];
int n;
/* Displayed type:
*
* 0x00: standard data frame
* 0x02: extended data frame
* 0x30: standard remote frame
* 0x32: extended remote frame
*/
static const byte type2[] = {0x00, 0x02, 0x30, 0x32};
n = sprintf(prbuf, "TX: [%08lX](%02X) ", (unsigned long)id, type2[type]);
// n = sprintf(prbuf, "TX: [%08lX](%02X) ", id, type);
for (i = 0; i < len; i++) {
n += sprintf(prbuf + n, "%02X ", cdata[i]);
}
SERIAL_PORT_MONITOR.println(prbuf);
unsigned d = random(30);
SERIAL_PORT_MONITOR.println(d);
delay(d);
}
// END FILE
+10 -17
View File
@@ -5,13 +5,6 @@
#include <SPI.h>
#include "mcp2518fd_can.h"
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
// Set SPI CS Pin according to your hardware
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
@@ -31,15 +24,15 @@ unsigned char len = 0;
unsigned char buf[8];
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial); // wait for Serial
if (CAN_SEND.begin((byte)CAN_500K_1M) != 0 || CAN_RECEIVE.begin((byte)CAN_500K_1M) != 0) {
Serial.println("CAN-BUS initiliased error!");
if (CAN_SEND.begin(CAN_500K_1M) != 0 || CAN_RECEIVE.begin(CAN_500K_1M) != 0) {
SERIAL_PORT_MONITOR.println("CAN-BUS initiliased error!");
while(1);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -52,27 +45,27 @@ void loop() {
if (stmp[6] == 100) {
stmp[6] = 0;
stmp[5] = stmp[6] + 1;
stmp[5] = stmp[5] + 1;
}
}
CAN_SEND.sendMsgBuf(0x00, 0, 8, stmp);
delay(100); // send data per 100ms
SERIAL.println("CAN BUS sendMsgBuf ok!");
SERIAL_PORT_MONITOR.println("CAN BUS sendMsgBuf ok!");
// ---------------------
if (CAN_MSGAVAIL == CAN_RECEIVE.checkReceive()) {
// read data, len: data length, buf: data buf
SERIAL.println("checkReceive");
SERIAL_PORT_MONITOR.println("checkReceive");
CAN_RECEIVE.readMsgBuf(&len, buf);
// print the data
for (int i = 0; i < len; i++) {
SERIAL.print(buf[i]); SERIAL.print(" ");
SERIAL_PORT_MONITOR.print(buf[i]); SERIAL_PORT_MONITOR.print(" ");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
SERIAL.println("---LOOP END---");
SERIAL_PORT_MONITOR.println("---LOOP END---");
}
// END FILE
+45 -40
View File
@@ -1,17 +1,11 @@
/*
This is an example of sending and receiving (FD) on its own, connect two channels to each other using jumpers.
*/
* This is an example of sending and receiving (FD) on its own,
* connect two channels to each other using jumpers.
*/
#include <SPI.h>
#include "mcp2518fd_can.h"
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
// Set SPI CS Pin according to your hardware
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
@@ -27,56 +21,67 @@ const int SPI_CS_PIN_RECEIVE = 2;
mcp2518fd CAN_SEND(SPI_CS_PIN_SEND);
mcp2518fd CAN_RECEIVE(SPI_CS_PIN_RECEIVE);
// CANFD could carry data up to 64 bytes
#define MAX_DATA_SIZE 64
void setup() {
SERIAL.begin(115200);
while(!Serial); // wait for Serial
CAN_SEND.setMode(0);
CAN_RECEIVE.setMode(0);
SERIAL_PORT_MONITOR.begin(115200);
while (!SERIAL_PORT_MONITOR) {} // wait for Serial
/*
* To compatible with MCP2515 API,
* default mode is CAN_CLASSIC_MODE
* Now set to CANFD mode.
*/
CAN_SEND.setMode(CAN_NORMAL_MODE);
CAN_RECEIVE.setMode(CAN_NORMAL_MODE);
if (CAN_SEND.begin((byte)CAN_500K_1M) != 0 || CAN_RECEIVE.begin((byte)CAN_500K_1M) != 0) {
Serial.println("CAN-BUS initiliased error!");
while(1);
if (CAN_SEND.begin(CAN_500K_1M) != 0 || CAN_RECEIVE.begin(CAN_500K_1M) != 0) {
SERIAL_PORT_MONITOR.println("CAN-BUS initiliased error!");
while (1);
}
byte send_mode = CAN_SEND.getMode();
byte receive_mode = CAN_RECEIVE.getMode();
SERIAL.print("CAN BUS Send Mode = "); SERIAL.println(send_mode);
SERIAL.print("CAN BUS Receive Mode = "); SERIAL.println(receive_mode);
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.print("CAN BUS Send Mode = "); SERIAL_PORT_MONITOR.println(send_mode);
SERIAL_PORT_MONITOR.print("CAN BUS Receive Mode = "); SERIAL_PORT_MONITOR.println(receive_mode);
SERIAL_PORT_MONITOR.println("CAN BUS Shield init ok!");
}
unsigned char stmp[64] = {0};
unsigned char stmp[MAX_DATA_SIZE] = {0};
unsigned char len = 0;
unsigned char buf[64];
unsigned char buf[MAX_DATA_SIZE];
void loop() {
stmp[63] = stmp[63] + 1;
if (stmp[63] == 100) {
stmp[63] = 0;
stmp[62] = stmp[62] + 1;
// send data: id = 0x00, standrad frame, data len = 64, stmp: data buf
stmp[MAX_DATA_SIZE - 1] = stmp[MAX_DATA_SIZE - 1] + 1;
if (stmp[MAX_DATA_SIZE - 1] == 100) {
stmp[MAX_DATA_SIZE - 1] = 0;
if (stmp[62] == 100) {
stmp[62] = 0;
stmp[61] = stmp[62] + 1;
stmp[MAX_DATA_SIZE - 2] = stmp[MAX_DATA_SIZE - 2] + 1;
if (stmp[MAX_DATA_SIZE - 2] == 100) {
stmp[MAX_DATA_SIZE - 2] = 0;
stmp[MAX_DATA_SIZE - 3] = stmp[MAX_DATA_SIZE - 3] + 1;
}
}
CAN_SEND.sendMsgBuf(0x00, 0, 15, stmp);
CAN_SEND.sendMsgBuf(0x00, 0, CANFD::len2dlc(MAX_DATA_SIZE), stmp);
delay(100); // send data per 100ms
SERIAL.println("CAN BUS sendMsgBuf ok!");
SERIAL_PORT_MONITOR.println("CAN BUS sendMsgBuf ok!");
// ---------------------
if (CAN_MSGAVAIL == CAN_RECEIVE.checkReceive()) {
// read data, len: data length, buf: data buf
SERIAL.println("checkReceive");
CAN_RECEIVE.readMsgBuf(&len, buf);
// print the data
for (int i = 0; i < len; i++) {
SERIAL.print(buf[i]); SERIAL.print("");
}
SERIAL.println();
// read data, len: data length, buf: data buf
SERIAL_PORT_MONITOR.println("checkReceive");
CAN_RECEIVE.readMsgBuf(&len, buf);
// print the data
for (int i = 0; i < len; i++) {
SERIAL_PORT_MONITOR.print(buf[i]);
SERIAL_PORT_MONITOR.print(' ');
}
SERIAL_PORT_MONITOR.println();
}
SERIAL.println("---LOOP END---");
SERIAL_PORT_MONITOR.println("---LOOP END---");
}
// END FILE
+9 -15
View File
@@ -1,4 +1,6 @@
// demo: CAN Sleep Example - send
// *** only works on AVR + MCP2515 platform
//
// by Kai, based on the send example by loovee and the additions from Zak Kemble (https://github.com/coryjfowler/MCP_CAN_lib/pull/10/files)
//
// See receive_sleep example for additional notes.
@@ -8,13 +10,6 @@
#include <avr/sleep.h>
#include <avr/wdt.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
@@ -62,14 +57,13 @@ void sleepMCU()
}
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while (CAN_OK != CAN.begin(CAN_500KBPS, MCP_16MHz)) { // init can bus : baudrate = 500k
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
CAN.setSleepWakeup(0); // the MCP2515 will NOT wake up on incoming messages,
// making it a 'send only' node
@@ -87,7 +81,7 @@ void setup() {
unsigned char stmp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void loop() {
SERIAL.println("Sending message");
SERIAL_PORT_MONITOR.println("Sending message");
CAN.sendMsgBuf(0x00, 0, 0, NULL); // Send empty wakeup message
@@ -102,7 +96,7 @@ void loop() {
if (stmp[6] == 100) {
stmp[6] = 0;
stmp[5] = stmp[6] + 1;
stmp[5] = stmp[5] + 1;
}
}
@@ -110,8 +104,8 @@ void loop() {
// sleep
SERIAL.println("Sleep");
SERIAL.flush();
SERIAL_PORT_MONITOR.println("Sleep");
SERIAL_PORT_MONITOR.flush();
// Put MCP2515 into sleep mode
CAN.sleep();
@@ -5,60 +5,52 @@
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
const byte interruptPin = 2;
unsigned char flagRecv = 0;
unsigned char len = 0;
unsigned char buf[8];
char str[20];
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial){};
attachInterrupt(digitalPinToInterrupt(interruptPin), MCP2515_ISR, FALLING); // start interrupt
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
attachInterrupt(digitalPinToInterrupt(CAN_INT_PIN), MCP2515_ISR, FALLING); // start interrupt
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
/*
set mask, set both the mask to 0x3ff
@@ -77,7 +69,6 @@ void setup() {
CAN.init_Filt(3, 0, 0x07); // there are 6 filter in mcp2515
CAN.init_Filt(4, 0, 0x08); // there are 6 filter in mcp2515
CAN.init_Filt(5, 0, 0x09); // there are 6 filter in mcp2515
}
void MCP2515_ISR() {
@@ -90,16 +81,15 @@ void loop() {
flagRecv = 0; // clear flag
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
SERIAL.println("\r\n------------------------------------------------------------------");
SERIAL.print("Get Data From id: ");
SERIAL.println(CAN.getCanId());
SERIAL_PORT_MONITOR.println("\r\n------------------------------------------------------------------");
SERIAL_PORT_MONITOR.print("Get Data From id: ");
SERIAL_PORT_MONITOR.println(CAN.getCanId());
for (int i = 0; i < len; i++) { // print the data
SERIAL.print("0x");
SERIAL.print(buf[i], HEX);
SERIAL.print("\t");
SERIAL_PORT_MONITOR.print("0x");
SERIAL_PORT_MONITOR.print(buf[i], HEX);
SERIAL_PORT_MONITOR.print("\t");
}
SERIAL.println();
SERIAL_PORT_MONITOR.println();
}
}
@@ -2,55 +2,48 @@
// this demo will show you how to use mask and filter
#include <SPI.h>
/*SAMD core*/
#ifdef ARDUINO_SAMD_VARIANT_COMPLIANCE
#define SERIAL SerialUSB
#else
#define SERIAL Serial
#endif
#define CAN_2515
// #define CAN_2518FD
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
// Set SPI CS Pin according to your hardware
#if defined(SEEED_WIO_TERMINAL) && defined(CAN_2518FD)
// For Wio Terminal w/ MCP2518FD RPi Hat
// Channel 0 SPI_CS Pin: BCM 8
// Channel 1 SPI_CS Pin: BCM 7
// Interupt Pin: BCM25
// *****************************************
const int SPI_CS_PIN = BCM8;
const int CAN_INT_PIN = BCM25;
#else
// For Arduino MCP2515 Hat:
// SPI_CS Pin: D9
// the cs pin of the version after v1.1 is default to D9
// v0.9b and v1.0 is default D10
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#endif
#ifdef CAN_2518FD
#include "mcp2518fd_can.h"
const int SPI_CS_PIN = 9;
mcp2518fd CAN(SPI_CS_PIN); // Set CS pin
#endif
#ifdef CAN_2515
#include "mcp2515_can.h"
const int SPI_CS_PIN = 9;
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
#endif
void setup() {
SERIAL.begin(115200);
SERIAL_PORT_MONITOR.begin(115200);
while(!Serial){};
#ifdef CAN_2518FD
while (0 != CAN.begin((byte)CAN_500K_1M)) { // init can bus : baudrate = 500k
#else
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
#endif
SERIAL.println("CAN BUS Shield init fail");
SERIAL.println(" Init CAN BUS Shield again");
SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
delay(100);
}
SERIAL.println("CAN BUS Shield init ok!");
SERIAL_PORT_MONITOR.println("CAN init ok!");
}
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+2
View File
@@ -36,12 +36,14 @@ CAN_50KBPS LITERAL1
CAN_80KBPS LITERAL1
CAN_83K3BPS LITERAL1
CAN_95KBPS LITERAL1
CAN_95K2BPS LITERAL1
CAN_100KBPS LITERAL1
CAN_125KBPS LITERAL1
CAN_200KBPS LITERAL1
CAN_250KBPS LITERAL1
CAN_500KBPS LITERAL1
CAN_666KBPS LITERAL1
CAN_800KBPS LITERAL1
CAN_1000KBPS LITERAL1
CAN_OK LITERAL1
CAN_FAILINIT LITERAL1
+3 -3
View File
@@ -1,13 +1,13 @@
{
"name": "CAN_BUS_Shield",
"keywords": "can, bus, MCP2518FD mcp2515, MCP-2515",
"description": "Seeed Arduino library to control CAN-BUS and CAN BUS FD.",
"keywords": "can, bus, mcp2518fd, mcp2515",
"description": "Seeed Arduino library to control CAN BUS and CAN BUS FD.",
"repository":
{
"type": "git",
"url": "https://github.com/Seeed-Studio/Seeed_Arduino_CAN.git"
},
"version": "1.20",
"version": "2.3.3",
"frameworks": "arduino",
"platforms": "*"
}
+4 -4
View File
@@ -1,9 +1,9 @@
name=Seeed Arduino CAN
version=1.0.0
name=CAN_BUS_Shield
version=2.3.4
author=Seeed Studio
maintainer=Seeed Studio <techsupport@seeed.cc>
sentence=Seeed Arduino library to control CAN-BUS and CAN BUS FD.
paragraph=Seeed Arduino library to control CAN-BUS and CAN BUS FD.
sentence=Seeed Arduino library to control CAN BUS and CAN BUS FD.
paragraph=Seeed Arduino library to control CAN BUS and CAN BUS FD.
category=Device Control
url=https://github.com/Seeed-Studio/Seeed_Arduino_CAN
architectures=*
+238 -224
View File
@@ -1,13 +1,13 @@
/*****************************************************************************************
* This is implementation of CAN BUS ASCII protocol based on LAWICEL v1.3 serial protocol
* of CanSerial/CANUSB device (http://www.CanSerial.com/docs/CanSerial_v3.pdf)
* of CAN232/CANUSB device (http://www.can232.com/docs/can232_v3.pdf)
*
* Made for Arduino with Seeduino/ElecFreaks CAN BUS Shield based on MCP2515
*
* Copyright (C) 2015 Anton Viktorov <latonita@yandex.ru>
* https://github.com/latonita/can-ascii
*
* This library is free software. You may use/redistribute it under The MIT License terms.
* This library is free software. You may use/redistribute it under The MIT License terms.
*
*****************************************************************************************/
@@ -15,7 +15,7 @@
#include "mcp_can.h"
#include "can-serial.h"
#define LOGGING_ENABLED
// #define LOGGING_ENABLED
#ifdef LOGGING_ENABLED
#define dbg_begin(x) debug.begin(x)
@@ -27,372 +27,382 @@
#define DEBUG_TX_PIN 9
#else
#define dbg_begin(x)
#define dbg0(x)
#define dbg1(x)
#define dbg0(x)
#define dbg1(x)
#define dbg2(x,y)
#define dbgH(x)
#endif
#ifdef LOGGING_ENABLED
#include "SoftwareSerial.h"
// software serial #2: TX = digital pin 8, RX = digital pin 9
// on the Mega, use other pins instead, since 8 and 9 don't work on the Mega
SoftwareSerial debug(DEBUG_RX_PIN, DEBUG_TX_PIN);
//#define debug Serial
SoftwareSerial debug(DEBUG_RX_PIN, DEBUG_TX_PIN);
//#define debug Serial
#endif
CanSerial* CanSerial::_instance = 0;
Can232* Can232::_instance = 0;
CanSerial* CanSerial::instance() {
Can232* Can232::instance() {
if (_instance == 0)
_instance = new CanSerial();
_instance = new Can232();
return _instance;
}
void CanSerial::init(INT8U defaultCanSpeed, const INT8U clock) {
dbg_begin(LWUART_DEFAULT_BAUD_RATE); // logging through software serial
void Can232::init(INT8U defaultCanSpeed, const INT8U clock) {
dbg_begin(LW232_DEFAULT_BAUD_RATE); // logging through software serial
dbg1("CAN ASCII. Welcome to debug");
instance()->LWUARTCanSpeedSelection = defaultCanSpeed;
instance()->LWUARTMcpModuleClock = clock;
instance()->lw232CanSpeedSelection = defaultCanSpeed;
instance()->lw232McpModuleClock = clock;
instance()->initFunc();
}
void CanSerial::init(MCP_CAN *CAN) {
LWUARTCAN = CAN;
MCP_CAN* Can232::MCP_OBJECT = NULL;
void Can232::attach(MCP_CAN *CAN) {
MCP_OBJECT = CAN;
#define lw232CAN MCP_OBJECT
}
void CanSerial::setFilter(INT8U (*userFunc)(INT32U)) {
void Can232::setFilter(INT8U (*userFunc)(INT32U)) {
instance()->setFilterFunc(userFunc);
}
void CanSerial::loop() {
void Can232::loop() {
instance()->loopFunc();
}
void CanSerial::serialEvent() {
void Can232::serialEvent() {
instance()->serialEventFunc();
}
void CanSerial::initFunc() {
if (!inputString.reserve(LWUART_INPUT_STRING_BUFFER_SIZE)) {
void Can232::initFunc() {
if (!inputString.reserve(LW232_INPUT_STRING_BUFFER_SIZE)) {
dbg0("inputString.reserve failed in initFunc. less optimal String work is expected");
}
// LWUARTAutoStart = true; //todo: read from eeprom
// LWUARTAutoPoll = false; //todo: read from eeprom
// LWUARTTimeStamp = //read from eeprom
// LWUARTMessage[0] = 'Z'; LWUARTMessage[1] = '1'; exec();
//if (LWUARTAutoStart) {
inputString = "O\0x0D";
// lw232AutoStart = true; //todo: read from eeprom
// lw232AutoPoll = false; //todo: read from eeprom
// lw232TimeStamp = //read from eeprom
// lw232Message[0] = 'Z'; lw232Message[1] = '1'; exec();
//if (lw232AutoStart) {
inputString = "O\x0D";
stringComplete = true;
loopFunc();
//}
}
void CanSerial::setFilterFunc(INT8U (*userFunc)(INT32U)) {
void Can232::setFilterFunc(INT8U (*userFunc)(INT32U)) {
instance()->userAddressFilterFunc = userFunc;
}
void CanSerial::loopFunc() {
void Can232::loopFunc() {
if (stringComplete) {
int len = inputString.length();
if (len > 0 && len < LWUART_FRAME_MAX_SIZE) {
strcpy((char*)LWUARTMessage, inputString.c_str());
exec();
unsigned len = inputString.length();
if (len > 0 && len < LW232_FRAME_MAX_SIZE) {
// maybe not single commands
int cr_pos;
for (; (cr_pos = inputString.indexOf(LW232_CR)) >= 0;) {
strncpy((char*)lw232Message, inputString.c_str(), cr_pos + 1);
lw232Message[cr_pos] = '\0';
exec();
inputString = inputString.substring(cr_pos + 1);
}
}
// clear the string:
inputString = "";
stringComplete = false;
}
if (LWUARTCanChannelMode != LWUART_STATUS_CAN_CLOSED) {
if (lw232CanChannelMode != LW232_STATUS_CAN_CLOSED) {
int recv = 0;
while (CAN_MSGAVAIL == checkReceive() && recv++<5) {
dbg0('+');
if (CAN_OK == receiveSingleFrame()) {
Serial.write(LWUART_CR);
Serial.write(LW232_CR);
}
}
Serial.flush();
}
}
void CanSerial::serialEventFunc() {
void Can232::serialEventFunc() {
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == LWUART_CR) {
if (inChar == LW232_CR) {
stringComplete = true;
}
}
}
INT8U CanSerial::exec() {
dbg2("Command received:", inputString);
LWUARTLastErr = parseAndRunCommand();
switch (LWUARTLastErr) {
case LWUART_OK:
Serial.write(LWUART_RET_ASCII_OK);
INT8U Can232::exec() {
lw232LastErr = parseAndRunCommand();
switch (lw232LastErr) {
case LW232_OK:
Serial.write(LW232_RET_ASCII_OK);
break;
case LWUART_OK_SMALL:
Serial.write(LWUART_RET_ASCII_OK_SMALL);
Serial.write(LWUART_RET_ASCII_OK);
case LW232_OK_SMALL:
Serial.write(LW232_RET_ASCII_OK_SMALL);
Serial.write(LW232_RET_ASCII_OK);
break;
case LWUART_OK_BIG:
Serial.write(LWUART_RET_ASCII_OK_BIG);
Serial.write(LWUART_RET_ASCII_OK);
case LW232_OK_BIG:
Serial.write(LW232_RET_ASCII_OK_BIG);
Serial.write(LW232_RET_ASCII_OK);
break;
case LWUART_ERR_NOT_IMPLEMENTED:
case LW232_ERR_NOT_IMPLEMENTED:
// Choose behavior: will it fail or not when not implemented command comes in. Some can monitors might be affected by this selection.
Serial.write(LWUART_RET_ASCII_ERROR);
//Serial.write(LWUART_RET_ASCII_OK);
Serial.write(LW232_RET_ASCII_ERROR);
//Serial.write(LW232_RET_ASCII_OK);
break;
default:
Serial.write(LWUART_RET_ASCII_ERROR);
Serial.write(LW232_RET_ASCII_ERROR);
}
return 0;
}
INT8U CanSerial::parseAndRunCommand() {
INT8U ret = LWUART_OK;
INT8U Can232::parseAndRunCommand() {
INT8U ret = LW232_OK;
INT8U idx = 0;
INT8U err = 0;
LWUARTLastErr = LWUART_OK;
lw232LastErr = LW232_OK;
switch (LWUARTMessage[0]) {
case LWUART_CMD_SETUP:
// __debug_buf("RX:", (char*)lw232Message, strlen((char*)lw232Message));
switch (lw232Message[0]) {
case LW232_CMD_SETUP:
// Sn[CR] Setup with standard CAN bit-rates where n is 0-9.
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_CLOSED) {
idx = HexHelper::parseNibbleWithLimit(LWUARTMessage[1], LWUART_CAN_BAUD_NUM);
LWUARTCanSpeedSelection = idx; //todo
if (lw232CanChannelMode == LW232_STATUS_CAN_CLOSED) {
idx = HexHelper::parseNibbleWithLimit(lw232Message[1], LW232_CAN_BAUD_NUM);
lw232CanSpeedSelection = lw232CanBaudRates[idx];
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_SETUP_BTR:
case LW232_CMD_SETUP_BTR:
// sxxyy[CR] Setup with BTR0/BTR1 CAN bit-rates where xx and yy is a hex value.
ret = LWUART_ERR; break;
case LWUART_CMD_OPEN:
ret = LW232_ERR; break;
case LW232_CMD_OPEN:
// O[CR] Open the CAN channel in normal mode (sending & receiving).
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_CLOSED) {
if (lw232CanChannelMode == LW232_STATUS_CAN_CLOSED) {
ret = openCanBus();
if (ret == LWUART_OK) {
LWUARTCanChannelMode = LWUART_STATUS_CAN_OPEN_NORMAL;
if (ret == LW232_OK) {
lw232CanChannelMode = LW232_STATUS_CAN_OPEN_NORMAL;
}
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_LISTEN:
case LW232_CMD_LISTEN:
// L[CR] Open the CAN channel in listen only mode (receiving).
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_CLOSED) {
if (lw232CanChannelMode == LW232_STATUS_CAN_CLOSED) {
ret = openCanBus();
if (ret == LWUART_OK) {
LWUARTCanChannelMode = LWUART_STATUS_CAN_OPEN_LISTEN;
if (ret == LW232_OK) {
lw232CanChannelMode = LW232_STATUS_CAN_OPEN_LISTEN;
}
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_CLOSE:
case LW232_CMD_CLOSE:
// C[CR] Close the CAN channel.
if (LWUARTCanChannelMode != LWUART_STATUS_CAN_CLOSED) {
LWUARTCanChannelMode = LWUART_STATUS_CAN_CLOSED;
if (lw232CanChannelMode != LW232_STATUS_CAN_CLOSED) {
lw232CanChannelMode = LW232_STATUS_CAN_CLOSED;
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_TX11:
case LW232_CMD_TX11:
// tiiildd...[CR] Transmit a standard (11bit) CAN frame.
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_OPEN_NORMAL) {
if (lw232CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
parseCanStdId();
LWUARTPacketLen = HexHelper::parseNibbleWithLimit(LWUARTMessage[LWUART_OFFSET_STD_PKT_LEN], LWUART_FRAME_MAX_LENGTH + 1);
for (; idx < LWUARTPacketLen; idx++) {
LWUARTBuffer[idx] = HexHelper::parseFullByte(LWUARTMessage[LWUART_OFFSET_STD_PKT_DATA + idx * 2], LWUARTMessage[LWUART_OFFSET_STD_PKT_DATA + idx * 2 + 1]);
lw232PacketLen = HexHelper::parseNibbleWithLimit(lw232Message[LW232_OFFSET_STD_PKT_LEN], LW232_FRAME_MAX_LENGTH + 1);
for (; idx < lw232PacketLen; idx++) {
lw232Buffer[idx] = HexHelper::parseFullByte(lw232Message[LW232_OFFSET_STD_PKT_DATA + idx * 2], lw232Message[LW232_OFFSET_STD_PKT_DATA + idx * 2 + 1]);
}
INT8U mcpErr = sendMsgBuf(LWUARTCanId, 0, 0, LWUARTPacketLen, LWUARTBuffer);
INT8U mcpErr = sendMsgBuf(lw232CanId, 0, 0, lw232PacketLen, lw232Buffer);
if (mcpErr != CAN_OK) {
ret = LWUART_ERR;
} else if (LWUARTAutoPoll) {
ret = LWUART_OK_SMALL;
}
ret = LW232_ERR;
} else if (lw232AutoPoll) {
ret = LW232_OK_SMALL;
}
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_TX29:
case LW232_CMD_TX29:
// Tiiiiiiiildd...[CR] Transmit an extended (29bit) CAN frame
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_OPEN_NORMAL) {
if (lw232CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
parseCanExtId();
LWUARTPacketLen = HexHelper::parseNibbleWithLimit(LWUARTMessage[LWUART_OFFSET_EXT_PKT_LEN], LWUART_FRAME_MAX_LENGTH + 1);
for (; idx < LWUARTPacketLen; idx++) {
LWUARTBuffer[idx] = HexHelper::parseFullByte(LWUARTMessage[LWUART_OFFSET_EXT_PKT_DATA + idx * 2], LWUARTMessage[LWUART_OFFSET_EXT_PKT_DATA + idx * 2 + 1]);
lw232PacketLen = HexHelper::parseNibbleWithLimit(lw232Message[LW232_OFFSET_EXT_PKT_LEN], LW232_FRAME_MAX_LENGTH + 1);
for (; idx < lw232PacketLen; idx++) {
lw232Buffer[idx] = HexHelper::parseFullByte(lw232Message[LW232_OFFSET_EXT_PKT_DATA + idx * 2], lw232Message[LW232_OFFSET_EXT_PKT_DATA + idx * 2 + 1]);
}
if (CAN_OK != sendMsgBuf(LWUARTCanId, 1, 0, LWUARTPacketLen, LWUARTBuffer)) {
ret = LWUART_ERR;
} else if (LWUARTAutoPoll) {
ret = LWUART_OK_BIG;
if (CAN_OK != sendMsgBuf(lw232CanId, 1, 0, lw232PacketLen, lw232Buffer)) {
ret = LW232_ERR;
} else if (lw232AutoPoll) {
ret = LW232_OK_BIG;
} else {
ret = LWUART_OK;
ret = LW232_OK;
}
}
break;
case LWUART_CMD_RTR11:
case LW232_CMD_RTR11:
// riiil[CR] Transmit an standard RTR (11bit) CAN frame.
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_OPEN_NORMAL) {
if (lw232CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
parseCanStdId();
LWUARTPacketLen = HexHelper::parseNibbleWithLimit(LWUARTMessage[LWUART_OFFSET_STD_PKT_LEN], LWUART_FRAME_MAX_LENGTH + 1);
if (CAN_OK != sendMsgBuf(LWUARTCanId, 0, 1, LWUARTPacketLen, LWUARTBuffer)) {
ret = LWUART_ERR;
lw232PacketLen = HexHelper::parseNibbleWithLimit(lw232Message[LW232_OFFSET_STD_PKT_LEN], LW232_FRAME_MAX_LENGTH + 1);
if (CAN_OK != sendMsgBuf(lw232CanId, 0, 1, lw232PacketLen, lw232Buffer)) {
ret = LW232_ERR;
}
else if (LWUARTAutoPoll) {
ret = LWUART_OK_SMALL;
else if (lw232AutoPoll) {
ret = LW232_OK_SMALL;
}
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_RTR29:
case LW232_CMD_RTR29:
// Riiiiiiiil[CR] Transmit an extended RTR (29bit) CAN frame.
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_OPEN_NORMAL) {
if (lw232CanChannelMode == LW232_STATUS_CAN_OPEN_NORMAL) {
parseCanExtId();
LWUARTPacketLen = HexHelper::parseNibbleWithLimit(LWUARTMessage[LWUART_OFFSET_EXT_PKT_LEN], LWUART_FRAME_MAX_LENGTH + 1);
if (CAN_OK != sendMsgBuf(LWUARTCanId, 1, 1, LWUARTPacketLen, LWUARTBuffer)) {
ret = LWUART_ERR;
lw232PacketLen = HexHelper::parseNibbleWithLimit(lw232Message[LW232_OFFSET_EXT_PKT_LEN], LW232_FRAME_MAX_LENGTH + 1);
if (CAN_OK != sendMsgBuf(lw232CanId, 1, 1, lw232PacketLen, lw232Buffer)) {
ret = LW232_ERR;
}
else if (LWUARTAutoPoll) {
ret = LWUART_OK_SMALL; // not a typo. strangely CanSerial_v3.pdf tells to return "z[CR]", not "Z[CR]" as in 29bit. todo: check if it is error in pdf???
else if (lw232AutoPoll) {
ret = LW232_OK_SMALL; // not a typo. strangely can232_v3.pdf tells to return "z[CR]", not "Z[CR]" as in 29bit. todo: check if it is error in pdf???
}
} else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_POLL_ONE:
case LW232_CMD_POLL_ONE:
// P[CR] Poll incomming FIFO for CAN frames (single poll)
if (LWUARTCanChannelMode != LWUART_STATUS_CAN_CLOSED && LWUARTAutoPoll == LWUART_AUTOPOLL_OFF) {
if (lw232CanChannelMode != LW232_STATUS_CAN_CLOSED && lw232AutoPoll == LW232_AUTOPOLL_OFF) {
if (CAN_MSGAVAIL == checkReceive()) {
ret = receiveSingleFrame();
}
} else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_POLL_MANY:
case LW232_CMD_POLL_MANY:
// A[CR] Polls incomming FIFO for CAN frames (all pending frames)
if (LWUARTCanChannelMode != LWUART_STATUS_CAN_CLOSED && LWUARTAutoPoll == LWUART_AUTOPOLL_OFF) {
if (lw232CanChannelMode != LW232_STATUS_CAN_CLOSED && lw232AutoPoll == LW232_AUTOPOLL_OFF) {
while (CAN_MSGAVAIL == checkReceive()) {
ret = ret ^ receiveSingleFrame();
if (ret != CAN_OK)
break;
Serial.write(LWUART_CR);
Serial.write(LW232_CR);
}
if (ret == CAN_OK)
Serial.print(LWUART_ALL);
Serial.print(LW232_ALL);
} else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_FLAGS:
case LW232_CMD_FLAGS:
// F[CR] Read Status Flags.
// LAWICEL CanSerial and CANUSB have some specific errors which differ from MCP2515/MCP2551 errors. We just return MCP2515 error.
Serial.print(LWUART_FLAG);
if (LWUARTCAN->checkError() == CAN_OK)
// LAWICEL CAN232 and CANUSB have some specific errors which differ from MCP2515/MCP2551 errors. We just return MCP2515 error.
Serial.print(LW232_FLAG);
if (lw232CAN && lw232CAN->checkError(&err) == CAN_OK)
err = 0;
HexHelper::printFullByte(err);
HexHelper::printFullByte(err /*& MCP_EFLG_ERRORMASK*/);
break;
case LWUART_CMD_AUTOPOLL:
case LW232_CMD_AUTOPOLL:
// Xn[CR] Sets Auto Poll/Send ON/OFF for received frames.
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_CLOSED) {
LWUARTAutoPoll = (LWUARTMessage[1] == LWUART_ON_ONE) ? LWUART_AUTOPOLL_ON : LWUART_AUTOPOLL_OFF;
if (lw232CanChannelMode == LW232_STATUS_CAN_CLOSED) {
lw232AutoPoll = (lw232Message[1] == LW232_ON_ONE) ? LW232_AUTOPOLL_ON : LW232_AUTOPOLL_OFF;
//todo: save to eeprom
} else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_FILTER:
// Wn[CR] Filter mode setting. By default CanSerial works in dual filter mode (0) and is backwards compatible with previous CanSerial versions.
ret = LWUART_ERR_NOT_IMPLEMENTED; break;
case LWUART_CMD_ACC_CODE:
case LW232_CMD_FILTER:
// Wn[CR] Filter mode setting. By default CAN232 works in dual filter mode (0) and is backwards compatible with previous CAN232 versions.
ret = LW232_ERR_NOT_IMPLEMENTED; break;
case LW232_CMD_ACC_CODE:
// Mxxxxxxxx[CR] Sets Acceptance Code Register (ACn Register of SJA1000). // we use MCP2515,
ret = LWUART_ERR_NOT_IMPLEMENTED; break;
case LWUART_CMD_ACC_MASK:
ret = LW232_ERR_NOT_IMPLEMENTED; break;
case LW232_CMD_ACC_MASK:
// mxxxxxxxx[CR] Sets Acceptance Mask Register (AMn Register of SJA1000).
ret = LWUART_ERR_NOT_IMPLEMENTED; break;
case LWUART_CMD_UART:
ret = LW232_ERR_NOT_IMPLEMENTED; break;
case LW232_CMD_UART:
// Un[CR] Setup UART with a new baud rate where n is 0-6.
idx = HexHelper::parseNibbleWithLimit(LWUARTMessage[1], LWUART_UART_BAUD_NUM);
Serial.begin(LWUARTSerialBaudRates[idx]);
idx = HexHelper::parseNibbleWithLimit(lw232Message[1], LW232_UART_BAUD_NUM);
Serial.begin(lw232SerialBaudRates[idx]);
break;
case LWUART_CMD_VERSION1:
case LWUART_CMD_VERSION2:
// V[CR] Get Version number of both CanSerial hardware and software
Serial.print(LWUART_LAWICEL_VERSION_STR);
case LW232_CMD_VERSION1:
case LW232_CMD_VERSION2:
// V[CR] Get Version number of both CAN232 hardware and software
Serial.print(LW232_LAWICEL_VERSION_STR);
break;
case LWUART_CMD_SERIAL:
// N[CR] Get Serial number of the CanSerial.
Serial.print(LWUART_LAWICEL_SERIAL_NUM);
case LW232_CMD_SERIAL:
// N[CR] Get Serial number of the CAN232.
Serial.print(LW232_LAWICEL_SERIAL_NUM);
break;
case LWUART_CMD_TIMESTAMP:
case LW232_CMD_TIMESTAMP:
// Zn[CR] Sets Time Stamp ON/OFF for received frames only. Z0 - OFF, Z1 - Lawicel's timestamp 2 bytes, Z2 - arduino timestamp 4 bytes.
if (LWUARTCanChannelMode == LWUART_STATUS_CAN_CLOSED) {
// LWUARTTimeStamp = (LWUARTMessage[1] == LWUART_ON_ONE);
if (LWUARTMessage[1] == LWUART_ON_ONE) {
LWUARTTimeStamp = LWUART_TIMESTAMP_ON_NORMAL;
if (lw232CanChannelMode == LW232_STATUS_CAN_CLOSED) {
// lw232TimeStamp = (lw232Message[1] == LW232_ON_ONE);
if (lw232Message[1] == LW232_ON_ONE) {
lw232TimeStamp = LW232_TIMESTAMP_ON_NORMAL;
}
else if (LWUARTMessage[1] == LWUART_ON_TWO) {
LWUARTTimeStamp = LWUART_TIMESTAMP_ON_EXTENDED;
else if (lw232Message[1] == LW232_ON_TWO) {
lw232TimeStamp = LW232_TIMESTAMP_ON_EXTENDED;
}
else {
LWUARTTimeStamp = LWUART_TIMESTAMP_OFF;
lw232TimeStamp = LW232_TIMESTAMP_OFF;
}
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
case LWUART_CMD_AUTOSTART:
case LW232_CMD_AUTOSTART:
// Qn[CR] Auto Startup feature (from power on).
if (LWUARTCanChannelMode != LWUART_STATUS_CAN_CLOSED) {
if (LWUARTMessage[1] == LWUART_ON_ONE) {
LWUARTAutoStart = LWUART_AUTOSTART_ON_NORMAL;
if (lw232CanChannelMode != LW232_STATUS_CAN_CLOSED) {
if (lw232Message[1] == LW232_ON_ONE) {
lw232AutoStart = LW232_AUTOSTART_ON_NORMAL;
}
else if (LWUARTMessage[1] == LWUART_ON_TWO) {
LWUARTAutoStart = LWUART_AUTOSTART_ON_LISTEN;
else if (lw232Message[1] == LW232_ON_TWO) {
lw232AutoStart = LW232_AUTOSTART_ON_LISTEN;
}
else {
LWUARTAutoStart = LWUART_AUTOSTART_OFF;
lw232AutoStart = LW232_AUTOSTART_OFF;
}
//todo: save to eeprom
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
break;
default:
ret = LWUART_ERR_UNKNOWN_CMD;
ret = LW232_ERR_UNKNOWN_CMD;
}
return ret;
}
INT8U CanSerial::checkReceive() {
INT8U Can232::checkReceive() {
#ifndef _MCP_FAKE_MODE_
return LWUARTCAN->checkReceive();
return lw232CAN? lw232CAN->checkReceive(): CAN_NOMSG;
#else
return CAN_MSGAVAIL;
#endif
}
INT8U CanSerial::readMsgBufID(INT32U *ID, INT8U *len, INT8U buf[]) {
INT8U Can232::readMsgBufID(INT32U *ID, INT8U *len, INT8U buf[]) {
#ifndef _MCP_FAKE_MODE_
return LWUARTCAN->readMsgBufID(ID, len, buf);
return lw232CAN? lw232CAN->readMsgBufID(ID, len, buf): CAN_NOMSG;
#else
*ID = random(0x100, 0x110);
*len = 4;
@@ -404,40 +414,38 @@ INT8U CanSerial::readMsgBufID(INT32U *ID, INT8U *len, INT8U buf[]) {
#endif
}
INT8U CanSerial::receiveSingleFrame() {
INT8U ret = LWUART_OK;
INT8U Can232::receiveSingleFrame() {
INT8U ret = LW232_OK;
INT8U idx = 0;
if (CAN_OK == readMsgBufID(&LWUARTCanId, &LWUARTPacketLen, LWUARTBuffer)) {
if (LWUARTCanId > 0x1FFFFFFF) {
ret = LWUART_ERR; // address if totally wrong
if (CAN_OK == readMsgBufID(&lw232CanId, &lw232PacketLen, lw232Buffer)) {
if (lw232CanId > 0x1FFFFFFF) {
ret = LW232_ERR; // address if totally wrong
}
else if (checkPassFilter(LWUARTCanId)) {// do we want to skip some addresses?
else if (checkPassFilter(lw232CanId)) {// do we want to skip some addresses?
if (isExtendedFrame()) {
Serial.print(LWUART_TR29);
HexHelper::printFullByte(HIGH_BYTE(HIGH_WORD(LWUARTCanId)));
HexHelper::printFullByte(LOW_BYTE(HIGH_WORD(LWUARTCanId)));
HexHelper::printFullByte(HIGH_BYTE(LOW_WORD(LWUARTCanId)));
HexHelper::printFullByte(LOW_BYTE(LOW_WORD(LWUARTCanId)));
Serial.print(LW232_TR29);
HexHelper::printFullByte(HIGH_BYTE(HIGH_WORD(lw232CanId)));
HexHelper::printFullByte(LOW_BYTE(HIGH_WORD(lw232CanId)));
HexHelper::printFullByte(HIGH_BYTE(LOW_WORD(lw232CanId)));
HexHelper::printFullByte(LOW_BYTE(LOW_WORD(lw232CanId)));
}
else {
Serial.print(LWUART_TR11);
HexHelper::printNibble(HIGH_BYTE(LOW_WORD(LWUARTCanId)));
HexHelper::printFullByte(LOW_BYTE(LOW_WORD(LWUARTCanId)));
Serial.print(LW232_TR11);
HexHelper::printNibble(HIGH_BYTE(LOW_WORD(lw232CanId)));
HexHelper::printFullByte(LOW_BYTE(LOW_WORD(lw232CanId)));
}
//write data len
HexHelper::printNibble(LWUARTPacketLen);
HexHelper::printNibble(lw232PacketLen);
//write data
for (idx = 0; idx < LWUARTPacketLen; idx++) {
HexHelper::printFullByte(LWUARTBuffer[idx]);
for (idx = 0; idx < lw232PacketLen; idx++) {
HexHelper::printFullByte(lw232Buffer[idx]);
}
//write timestamp if needed
if (LWUARTTimeStamp != LWUART_TIMESTAMP_OFF) {
if (lw232TimeStamp != LW232_TIMESTAMP_OFF) {
INT32U time = millis();
if (LWUARTTimeStamp == LWUART_TIMESTAMP_ON_NORMAL) {
if (lw232TimeStamp == LW232_TIMESTAMP_ON_NORMAL) {
// standard LAWICEL protocol. two bytes.
time %= 60000;
time %= 60000;
} else {
// non standard protocol - 4 bytes timestamp
HexHelper::printFullByte(HIGH_BYTE(HIGH_WORD(time)));
@@ -449,41 +457,47 @@ INT8U CanSerial::receiveSingleFrame() {
}
}
else {
ret = LWUART_ERR;
ret = LW232_ERR;
}
return ret;
}
INT8U CanSerial::isExtendedFrame() {
INT8U Can232::isExtendedFrame() {
#ifndef _MCP_FAKE_MODE_
return LWUARTCAN->isExtendedFrame();
return lw232CAN? lw232CAN->isExtendedFrame(): 0;
#else
return LWUARTCanId > 0x7FF ? 1 : 0; //simple hack for fake mode
return lw232CanId > 0x7FF ? 1 : 0; //simple hack for fake mode
#endif
}
INT8U CanSerial::checkPassFilter(INT32U addr) {
if (userAddressFilterFunc == 0)
return LWUART_FILTER_PROCESS;
INT8U Can232::checkPassFilter(INT32U addr) {
if (userAddressFilterFunc == 0)
return LW232_FILTER_PROCESS;
return (*userAddressFilterFunc)(addr);
}
INT8U CanSerial::openCanBus() {
INT8U ret = LWUART_OK;
INT8U Can232::openCanBus() {
INT8U ret = LW232_OK;
#ifndef _MCP_FAKE_MODE_
if (CAN_OK != LWUARTCAN->begin(LWUARTCanSpeedSelection, LWUARTMcpModuleClock))
ret = LWUART_ERR;
if (!lw232CAN) {
return CAN_FAILINIT;
}
if (CAN_OK != lw232CAN->begin(lw232CanSpeedSelection, lw232McpModuleClock))
ret = LW232_ERR;
#endif
return ret;
}
INT8U CanSerial::sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *buf) {
INT8U Can232::sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *buf) {
#ifndef _MCP_FAKE_MODE_
return LWUARTCAN->sendMsgBuf(id, ext, rtr, len, buf);
if (!lw232CAN) {
return CAN_FAILTX;
}
return lw232CAN->sendMsgBuf(id, ext, rtr, len, buf);
#else
Serial.print("<sending:");
Serial.print(id, HEX);
@@ -503,23 +517,23 @@ INT8U CanSerial::sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *b
void CanSerial::parseCanStdId() {
LWUARTCanId = (((INT32U)HexHelper::parseNibble(LWUARTMessage[1])) << 8)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[2])) << 4)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[3])));
LWUARTCanId &= 0x7FF;
void Can232::parseCanStdId() {
lw232CanId = (((INT32U)HexHelper::parseNibble(lw232Message[1])) << 8)
+ (((INT32U)HexHelper::parseNibble(lw232Message[2])) << 4)
+ (((INT32U)HexHelper::parseNibble(lw232Message[3])));
lw232CanId &= 0x7FF;
}
void CanSerial::parseCanExtId() {
LWUARTCanId = (((INT32U)HexHelper::parseNibble(LWUARTMessage[1])) << 28)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[2])) << 24)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[3])) << 20)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[4])) << 16)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[5])) << 12)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[6])) << 8)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[7])) << 4)
+ (((INT32U)HexHelper::parseNibble(LWUARTMessage[8])));
LWUARTCanId &= 0x1FFFFFFF;
void Can232::parseCanExtId() {
lw232CanId = (((INT32U)HexHelper::parseNibble(lw232Message[1])) << 28)
+ (((INT32U)HexHelper::parseNibble(lw232Message[2])) << 24)
+ (((INT32U)HexHelper::parseNibble(lw232Message[3])) << 20)
+ (((INT32U)HexHelper::parseNibble(lw232Message[4])) << 16)
+ (((INT32U)HexHelper::parseNibble(lw232Message[5])) << 12)
+ (((INT32U)HexHelper::parseNibble(lw232Message[6])) << 8)
+ (((INT32U)HexHelper::parseNibble(lw232Message[7])) << 4)
+ (((INT32U)HexHelper::parseNibble(lw232Message[8])));
lw232CanId &= 0x1FFFFFFF;
}
void HexHelper::printFullByte(INT8U b) {
+101 -120
View File
@@ -1,6 +1,6 @@
/*****************************************************************************************
* This is implementation of CAN BUS ASCII protocol based on LAWICEL v1.3 serial protocol
* of CanSerial/CANUSB device (http://www.CanSerial.com/docs/CanSerial_v3.pdf)
* of CAN232/CANUSB device (http://www.can232.com/docs/can232_v3.pdf)
*
* Made for Arduino with Seeduino/ElecFreaks CAN BUS Shield based on MCP2515
*
@@ -15,33 +15,18 @@
#ifndef _CAN_SERIAL_H_
#define _CAN_SERIAL_H_
//#if defined(ARDUINO) && ARDUINO >= 100
// #include "arduino.h"
//#else
// #include "WProgram.h"
//#endif
#include "mcp_can.h"
#define LOGGING_ENABLED
#ifdef LOGGING_ENABLED
#include "SoftwareSerial.h"
#define dbg_begin(x) debug.begin(x)
#define dbg0(x) debug.print(x)
#define dbg1(x) debug.println(x)
#define dbg2(x,y) debug.print(x); debug.println(y)
#define dbgH(x) debug.print(x,HEX)
#define DEBUG_RX_PIN 8
#define DEBUG_TX_PIN 9
#else
#define dbg_begin(x)
#define dbg0(x)
#define dbg1(x)
#define dbg2(x,y)
#define dbgH(x)
#endif
#define LWUART_LAWICEL_VERSION_STR "V1013"
#define LWUART_LAWICEL_SERIAL_NUM "NA123"
#define LWUART_CAN_BUS_SHIELD_CS_PIN 10
#define LW232_LAWICEL_VERSION_STR "V1013"
#define LW232_LAWICEL_SERIAL_NUM "NA123"
#define LW232_CAN_BUS_SHIELD_CS_PIN 10
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -59,32 +44,32 @@
//
// CODE SUPPORTED SYNTAX DESCRIPTION
//
#define LWUART_CMD_SETUP 'S' // YES+ Sn[CR] Setup with standard CAN bit-rates where n is 0-8.
#define LW232_CMD_SETUP 'S' // YES+ Sn[CR] Setup with standard CAN bit-rates where n is 0-8.
// S0 10Kbit S4 125Kbit S8 1Mbit
// S1 20Kbit S5 250Kbit S9 83.3Kbit
// S2 50Kbit S6 500Kbit
// S3 100Kbit S7 800Kbit
#define LWUART_CMD_SETUP_BTR 's' // - sxxyy[CR] Setup with BTR0/BTR1 CAN bit-rates where xx and yy is a hex value.
#define LWUART_CMD_OPEN 'O' // YES O[CR] Open the CAN channel in normal mode (sending & receiving).
#define LWUART_CMD_LISTEN 'L' // YES L[CR] Open the CAN channel in listen only mode (receiving).
#define LWUART_CMD_CLOSE 'C' // YES C[CR] Close the CAN channel.
#define LWUART_CMD_TX11 't' // YES tiiildd...[CR] Transmit a standard (11bit) CAN frame.
#define LWUART_CMD_TX29 'T' // YES Tiiiiiiiildd...[CR] Transmit an extended (29bit) CAN frame
#define LWUART_CMD_RTR11 'r' // YES riiil[CR] Transmit an standard RTR (11bit) CAN frame.
#define LWUART_CMD_RTR29 'R' // YES Riiiiiiiil[CR] Transmit an extended RTR (29bit) CAN frame.
#define LWUART_CMD_POLL_ONE 'P' // YES P[CR] Poll incomming FIFO for CAN frames (single poll)
#define LWUART_CMD_POLL_MANY 'A' // YES A[CR] Polls incomming FIFO for CAN frames (all pending frames)
#define LWUART_CMD_FLAGS 'F' // YES+ F[CR] Read Status Flags.
#define LWUART_CMD_AUTOPOLL 'X' // YES Xn[CR] Sets Auto Poll/Send ON/OFF for received frames.
#define LWUART_CMD_FILTER 'W' // - Wn[CR] Filter mode setting. By default CanSerial works in dual filter mode (0) and is backwards compatible with previous CanSerial versions.
#define LWUART_CMD_ACC_CODE 'M' // - Mxxxxxxxx[CR] Sets Acceptance Code Register (ACn Register of SJA1000). // we use MCP2515, not supported
#define LWUART_CMD_ACC_MASK 'm' // - mxxxxxxxx[CR] Sets Acceptance Mask Register (AMn Register of SJA1000). // we use MCP2515, not supported
#define LWUART_CMD_UART 'U' // YES Un[CR] Setup UART with a new baud rate where n is 0-6.
#define LWUART_CMD_VERSION1 'V' // YES v[CR] Get Version number of both CanSerial hardware and software
#define LWUART_CMD_VERSION2 'v' // YES V[CR] Get Version number of both CanSerial hardware and software
#define LWUART_CMD_SERIAL 'N' // YES N[CR] Get Serial number of the CanSerial.
#define LWUART_CMD_TIMESTAMP 'Z' // YES+ Zn[CR] Sets Time Stamp ON/OFF for received frames only. EXTENSION to LAWICEL: Z2 - millis() timestamp w/o standard 60000ms cycle
#define LWUART_CMD_AUTOSTART 'Q' // YES todo Qn[CR] Auto Startup feature (from power on).
#define LW232_CMD_SETUP_BTR 's' // - sxxyy[CR] Setup with BTR0/BTR1 CAN bit-rates where xx and yy is a hex value.
#define LW232_CMD_OPEN 'O' // YES O[CR] Open the CAN channel in normal mode (sending & receiving).
#define LW232_CMD_LISTEN 'L' // YES L[CR] Open the CAN channel in listen only mode (receiving).
#define LW232_CMD_CLOSE 'C' // YES C[CR] Close the CAN channel.
#define LW232_CMD_TX11 't' // YES tiiildd...[CR] Transmit a standard (11bit) CAN frame.
#define LW232_CMD_TX29 'T' // YES Tiiiiiiiildd...[CR] Transmit an extended (29bit) CAN frame
#define LW232_CMD_RTR11 'r' // YES riiil[CR] Transmit an standard RTR (11bit) CAN frame.
#define LW232_CMD_RTR29 'R' // YES Riiiiiiiil[CR] Transmit an extended RTR (29bit) CAN frame.
#define LW232_CMD_POLL_ONE 'P' // YES P[CR] Poll incomming FIFO for CAN frames (single poll)
#define LW232_CMD_POLL_MANY 'A' // YES A[CR] Polls incomming FIFO for CAN frames (all pending frames)
#define LW232_CMD_FLAGS 'F' // YES+ F[CR] Read Status Flags.
#define LW232_CMD_AUTOPOLL 'X' // YES Xn[CR] Sets Auto Poll/Send ON/OFF for received frames.
#define LW232_CMD_FILTER 'W' // - Wn[CR] Filter mode setting. By default CAN232 works in dual filter mode (0) and is backwards compatible with previous CAN232 versions.
#define LW232_CMD_ACC_CODE 'M' // - Mxxxxxxxx[CR] Sets Acceptance Code Register (ACn Register of SJA1000). // we use MCP2515, not supported
#define LW232_CMD_ACC_MASK 'm' // - mxxxxxxxx[CR] Sets Acceptance Mask Register (AMn Register of SJA1000). // we use MCP2515, not supported
#define LW232_CMD_UART 'U' // YES Un[CR] Setup UART with a new baud rate where n is 0-6.
#define LW232_CMD_VERSION1 'V' // YES v[CR] Get Version number of both CAN232 hardware and software
#define LW232_CMD_VERSION2 'v' // YES V[CR] Get Version number of both CAN232 hardware and software
#define LW232_CMD_SERIAL 'N' // YES N[CR] Get Serial number of the CAN232.
#define LW232_CMD_TIMESTAMP 'Z' // YES+ Zn[CR] Sets Time Stamp ON/OFF for received frames only. EXTENSION to LAWICEL: Z2 - millis() timestamp w/o standard 60000ms cycle
#define LW232_CMD_AUTOSTART 'Q' // YES todo Qn[CR] Auto Startup feature (from power on).
#define LOW_BYTE(x) ((unsigned char)((x)&0xFF))
#define HIGH_BYTE(x) ((unsigned char)(((x)>>8)&0xFF))
@@ -103,92 +88,87 @@
#define INT8U byte
#endif
#define LWUART_OK 0x00
#define LWUART_OK_SMALL 0x01
#define LWUART_OK_BIG 0x02
#define LWUART_ERR 0x03
#define LWUART_ERR_NOT_IMPLEMENTED 0x04
#define LWUART_ERR_UNKNOWN_CMD 0x05
#define LW232_OK 0x00
#define LW232_OK_SMALL 0x01
#define LW232_OK_BIG 0x02
#define LW232_ERR 0x03
#define LW232_ERR_NOT_IMPLEMENTED 0x04
#define LW232_ERR_UNKNOWN_CMD 0x05
#define LWUART_FILTER_SKIP 0x00
#define LWUART_FILTER_PROCESS 0x01
#define LW232_FILTER_SKIP 0x00
#define LW232_FILTER_PROCESS 0x01
//#define LWUART_IS_OK(x) ((x)==LWUART_OK ||(x)==LWUART_OK_NEW ? TRUE : FALSE)
//#define LW232_IS_OK(x) ((x)==LW232_OK ||(x)==LW232_OK_NEW ? TRUE : FALSE)
#define LWUART_CR '\r'
#define LWUART_ALL 'A'
#define LWUART_FLAG 'F'
#define LWUART_TR11 't'
#define LWUART_TR29 'T'
#define LW232_CR '\r'
#define LW232_ALL 'A'
#define LW232_FLAG 'F'
#define LW232_TR11 't'
#define LW232_TR29 'T'
#define LWUART_RET_ASCII_OK 0x0D
#define LWUART_RET_ASCII_ERROR 0x07
#define LWUART_RET_ASCII_OK_SMALL 'z'
#define LWUART_RET_ASCII_OK_BIG 'Z'
#define LW232_RET_ASCII_OK 0x0D
#define LW232_RET_ASCII_ERROR 0x07
#define LW232_RET_ASCII_OK_SMALL 'z'
#define LW232_RET_ASCII_OK_BIG 'Z'
#define LWUART_STATUS_CAN_CLOSED 0x00
#define LWUART_STATUS_CAN_OPEN_NORMAL 0x01
#define LWUART_STATUS_CAN_OPEN_LISTEN 0x01
#define LW232_STATUS_CAN_CLOSED 0x00
#define LW232_STATUS_CAN_OPEN_NORMAL 0x01
#define LW232_STATUS_CAN_OPEN_LISTEN 0x01
#define LWUART_FRAME_MAX_LENGTH 0x08
#define LWUART_FRAME_MAX_SIZE (sizeof("Tiiiiiiiildddddddddddddddd\r")+1)
#define LW232_FRAME_MAX_LENGTH 0x08
#define LW232_FRAME_MAX_SIZE (sizeof("Tiiiiiiiildddddddddddddddd\r")+1)
#define LWUART_INPUT_STRING_BUFFER_SIZE 200
#define LW232_INPUT_STRING_BUFFER_SIZE 200
#define LWUART_OFF '0'
#define LWUART_ON_ONE '1'
#define LWUART_ON_TWO '2'
#define LW232_OFF '0'
#define LW232_ON_ONE '1'
#define LW232_ON_TWO '2'
#define LWUART_AUTOPOLL_OFF 0x00
#define LWUART_AUTOPOLL_ON 0x01
#define LW232_AUTOPOLL_OFF 0x00
#define LW232_AUTOPOLL_ON 0x01
#define LWUART_AUTOSTART_OFF 0x00
#define LWUART_AUTOSTART_ON_NORMAL 0x01
#define LWUART_AUTOSTART_ON_LISTEN 0x02
#define LW232_AUTOSTART_OFF 0x00
#define LW232_AUTOSTART_ON_NORMAL 0x01
#define LW232_AUTOSTART_ON_LISTEN 0x02
#define LWUART_TIMESTAMP_OFF 0x00
#define LWUART_TIMESTAMP_ON_NORMAL 0x01
#define LWUART_TIMESTAMP_ON_EXTENDED 0x02
#define LW232_TIMESTAMP_OFF 0x00
#define LW232_TIMESTAMP_ON_NORMAL 0x01
#define LW232_TIMESTAMP_ON_EXTENDED 0x02
#define LWUART_OFFSET_STD_PKT_LEN 0x04
#define LWUART_OFFSET_STD_PKT_DATA 0x05
#define LWUART_OFFSET_EXT_PKT_LEN 0x09
#define LWUART_OFFSET_EXT_PKT_DATA 0x0A
#define LW232_OFFSET_STD_PKT_LEN 0x04
#define LW232_OFFSET_STD_PKT_DATA 0x05
#define LW232_OFFSET_EXT_PKT_LEN 0x09
#define LW232_OFFSET_EXT_PKT_DATA 0x0A
#define LWUART_DEFAULT_BAUD_RATE 115200
// #define LWUART_DEFAULT_CAN_RATE CAN_500KBPS
// #define LWUART_DEFAULT_CLOCK_FREQ MCP_16MHz
#define LW232_DEFAULT_BAUD_RATE 115200
#define LW232_DEFAULT_CAN_RATE CAN_500KBPS
#define LW232_DEFAULT_CLOCK_FREQ MCP_16MHz
#define LWUART_CAN_BAUD_NUM 0x0a
#define LWUART_UART_BAUD_NUM 0x07
#define CAN_OK (0)
#define CAN_FAILINIT (1)
#define CAN_FAILTX (2)
#define CAN_MSGAVAIL (3)
#define LW232_CAN_BAUD_NUM 0x0a
#define LW232_UART_BAUD_NUM 0x07
const INT32U LWUARTSerialBaudRates[] //PROGMEM
const INT32U lw232SerialBaudRates[] //PROGMEM
= { 230400, 115200, 57600, 38400, 19200, 9600, 2400 };
// const INT32U LWUARTCanBaudRates[] //PROGMEM
// = { CAN_10KBPS, CAN_20KBPS, CAN_50KBPS, CAN_100KBPS, CAN_125KBPS, CAN_250KBPS, CAN_500KBPS, CAN_500KBPS /*CAN_800KBPS*/, CAN_1000KBPS, CAN_83K3BPS };
const INT32U lw232CanBaudRates[] //PROGMEM
= { CAN_10KBPS, CAN_20KBPS, CAN_50KBPS, CAN_100KBPS, CAN_125KBPS, CAN_250KBPS, CAN_500KBPS, CAN_800KBPS, CAN_1000KBPS, CAN_83K3BPS };
class CanSerial
class Can232
{
public:
static void init(INT8U defaultCanSpeed, const INT8U clock);
void init(MCP_CAN *can);
static void init(INT8U defaultCanSpeed = LW232_DEFAULT_CAN_RATE, const INT8U clock = LW232_DEFAULT_CLOCK_FREQ);
static void attach(MCP_CAN *can);
static void setFilter(INT8U (*userFunc)(INT32U));
static void loop();
static void serialEvent();
private:
static CanSerial* _instance;
static CanSerial* instance();
static MCP_CAN *MCP_OBJECT;
static Can232* _instance;
static Can232* instance();
void initFunc();
void setFilterFunc(INT8U (*userFunc)(INT32U));
@@ -197,24 +177,25 @@ private:
INT8U (*userAddressFilterFunc)(INT32U addr) = 0;
MCP_CAN *LWUARTCAN;
//MCP_CAN LWUARTCAN = MCP_CAN(LWUART_CAN_BUS_SHIELD_CS_PIN);
/*
MCP_CAN lw232CAN = MCP_CAN(LW232_CAN_BUS_SHIELD_CS_PIN);
*/
INT8U LWUARTCanSpeedSelection ;
INT8U LWUARTMcpModuleClock ;
INT8U LWUARTCanChannelMode = LWUART_STATUS_CAN_CLOSED;
INT8U LWUARTLastErr = LWUART_OK;
INT8U lw232CanSpeedSelection = CAN_83K3BPS;
INT8U lw232McpModuleClock = MCP_16MHz;
INT8U lw232CanChannelMode = LW232_STATUS_CAN_CLOSED;
INT8U lw232LastErr = LW232_OK;
INT8U LWUARTAutoStart = LWUART_AUTOSTART_OFF;
INT8U LWUARTAutoPoll = LWUART_AUTOPOLL_OFF;
INT8U LWUARTTimeStamp = LWUART_TIMESTAMP_OFF;
INT8U lw232AutoStart = LW232_AUTOSTART_OFF;
INT8U lw232AutoPoll = LW232_AUTOPOLL_OFF;
INT8U lw232TimeStamp = LW232_TIMESTAMP_OFF;
INT32U LWUARTCanId = 0;
INT32U lw232CanId = 0;
INT8U LWUARTBuffer[8];
INT8U LWUARTPacketLen = 0;
INT8U lw232Buffer[8];
INT8U lw232PacketLen = 0;
INT8U LWUARTMessage[LWUART_FRAME_MAX_SIZE];
INT8U lw232Message[LW232_FRAME_MAX_SIZE];
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
@@ -230,7 +211,7 @@ private:
INT8U openCanBus();
INT8U sendMsgBuf(INT32U id, INT8U ext, INT8U rtr, INT8U len, INT8U *buf);
void parseCanStdId();
void parseCanExtId();
};
@@ -245,7 +226,7 @@ public:
static INT8U parseNibbleWithLimit(INT8U hex, INT8U limit);
};
class CanSerialFake : CanSerial {
class Can232Fake : Can232 {
};
+165 -82
View File
@@ -45,6 +45,7 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#define DEBUG_EN 0
#include "mcp2515_can.h"
#define spi_readwrite pSPI->transfer
@@ -514,6 +515,12 @@ byte mcp2515_can::mcp2515_configRate(const byte canSpeed, const byte clock) {
cfg3 = MCP_16MHz_666kBPS_CFG3;
break;
case (CAN_800KBPS) :
cfg1 = MCP_16MHz_800kBPS_CFG1;
cfg2 = MCP_16MHz_800kBPS_CFG2;
cfg3 = MCP_16MHz_800kBPS_CFG3;
break;
case (CAN_1000KBPS):
cfg1 = MCP_16MHz_1000kBPS_CFG1;
cfg2 = MCP_16MHz_1000kBPS_CFG2;
@@ -526,6 +533,109 @@ byte mcp2515_can::mcp2515_configRate(const byte canSpeed, const byte clock) {
}
break;
case (MCP_12MHz) :
switch (canSpeed) {
case (CAN_20KBPS) :
cfg1 = MCP_12MHz_20kBPS_CFG1;
cfg2 = MCP_12MHz_20kBPS_CFG2;
cfg3 = MCP_12MHz_20kBPS_CFG3;
break;
case (CAN_25KBPS) :
cfg1 = MCP_12MHz_25kBPS_CFG1;
cfg2 = MCP_12MHz_25kBPS_CFG2;
cfg3 = MCP_12MHz_25kBPS_CFG3;
break;
case (CAN_31K25BPS) :
cfg1 = MCP_12MHz_31k25BPS_CFG1;
cfg2 = MCP_12MHz_31k25BPS_CFG2;
cfg3 = MCP_12MHz_31k25BPS_CFG3;
break;
case (CAN_33KBPS) :
cfg1 = MCP_12MHz_33kBPS_CFG1;
cfg2 = MCP_12MHz_33kBPS_CFG2;
cfg3 = MCP_12MHz_33kBPS_CFG3;
break;
case (CAN_40KBPS) :
cfg1 = MCP_12MHz_40kBPS_CFG1;
cfg2 = MCP_12MHz_40kBPS_CFG2;
cfg3 = MCP_12MHz_40kBPS_CFG3;
break;
case (CAN_50KBPS) :
cfg1 = MCP_12MHz_50kBPS_CFG1;
cfg2 = MCP_12MHz_50kBPS_CFG2;
cfg3 = MCP_12MHz_50kBPS_CFG3;
break;
case (CAN_80KBPS) :
cfg1 = MCP_12MHz_80kBPS_CFG1;
cfg2 = MCP_12MHz_80kBPS_CFG2;
cfg3 = MCP_12MHz_80kBPS_CFG3;
break;
case (CAN_83K3BPS) :
cfg1 = MCP_12MHz_83k3BPS_CFG1;
cfg2 = MCP_12MHz_83k3BPS_CFG2;
cfg3 = MCP_12MHz_83k3BPS_CFG3;
break;
case (CAN_95KBPS) :
cfg1 = MCP_12MHz_95kBPS_CFG1;
cfg2 = MCP_12MHz_95kBPS_CFG2;
cfg3 = MCP_12MHz_95kBPS_CFG3;
break;
case (CAN_100KBPS) :
cfg1 = MCP_12MHz_100kBPS_CFG1;
cfg2 = MCP_12MHz_100kBPS_CFG2;
cfg3 = MCP_12MHz_100kBPS_CFG3;
break;
case (CAN_125KBPS) :
cfg1 = MCP_12MHz_125kBPS_CFG1;
cfg2 = MCP_12MHz_125kBPS_CFG2;
cfg3 = MCP_12MHz_125kBPS_CFG3;
break;
case (CAN_200KBPS) :
cfg1 = MCP_12MHz_200kBPS_CFG1;
cfg2 = MCP_12MHz_200kBPS_CFG2;
cfg3 = MCP_12MHz_200kBPS_CFG3;
break;
case (CAN_250KBPS) :
cfg1 = MCP_12MHz_250kBPS_CFG1;
cfg2 = MCP_12MHz_250kBPS_CFG2;
cfg3 = MCP_12MHz_250kBPS_CFG3;
break;
case (CAN_500KBPS) :
cfg1 = MCP_12MHz_500kBPS_CFG1;
cfg2 = MCP_12MHz_500kBPS_CFG2;
cfg3 = MCP_12MHz_500kBPS_CFG3;
break;
case (CAN_666KBPS) :
cfg1 = MCP_12MHz_666kBPS_CFG1;
cfg2 = MCP_12MHz_666kBPS_CFG2;
cfg3 = MCP_12MHz_666kBPS_CFG3;
break;
case (CAN_1000KBPS) :
cfg1 = MCP_12MHz_1000kBPS_CFG1;
cfg2 = MCP_12MHz_1000kBPS_CFG2;
cfg3 = MCP_12MHz_1000kBPS_CFG3;
break;
default:
set = 0;
break;
}
break;
case (MCP_8MHz) :
switch (canSpeed) {
case (CAN_5KBPS) :
@@ -570,6 +680,18 @@ byte mcp2515_can::mcp2515_configRate(const byte canSpeed, const byte clock) {
cfg3 = MCP_8MHz_80kBPS_CFG3;
break;
case (CAN_83K3BPS) :
cfg1 = MCP_8MHz_83k3BPS_CFG1;
cfg2 = MCP_8MHz_83k3BPS_CFG2;
cfg3 = MCP_8MHz_83k3BPS_CFG3;
break;
case (CAN_95K2BPS):
cfg1 = MCP_8MHz_95k2BPS_CFG1;
cfg2 = MCP_8MHz_95k2BPS_CFG2;
cfg3 = MCP_8MHz_95k2BPS_CFG3;
break;
case (CAN_100KBPS) :
cfg1 = MCP_8MHz_100kBPS_CFG1;
cfg2 = MCP_8MHz_100kBPS_CFG2;
@@ -600,6 +722,12 @@ byte mcp2515_can::mcp2515_configRate(const byte canSpeed, const byte clock) {
cfg3 = MCP_8MHz_500kBPS_CFG3;
break;
case (CAN_800KBPS) :
cfg1 = MCP_8MHz_800kBPS_CFG1;
cfg2 = MCP_8MHz_800kBPS_CFG2;
cfg3 = MCP_8MHz_800kBPS_CFG3;
break;
case (CAN_1000KBPS) :
cfg1 = MCP_8MHz_1000kBPS_CFG1;
cfg2 = MCP_8MHz_1000kBPS_CFG2;
@@ -662,14 +790,14 @@ byte mcp2515_can::mcp2515_init(const byte canSpeed, const byte clock) {
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
if (res > 0) {
#if DEBUG_EN
Serial.print("Enter setting mode fail\r\n");
SERIAL_PORT_MONITOR.println(F("Enter setting mode fail"));
#else
delay(10);
#endif
return res;
}
#if DEBUG_EN
Serial.print("Enter setting mode success \r\n");
SERIAL_PORT_MONITOR.println(F("Enter setting mode success "));
#else
delay(10);
#endif
@@ -677,14 +805,14 @@ byte mcp2515_can::mcp2515_init(const byte canSpeed, const byte clock) {
// set boadrate
if (mcp2515_configRate(canSpeed, clock)) {
#if DEBUG_EN
Serial.print("set rate fall!!\r\n");
SERIAL_PORT_MONITOR.println(F("set rate fall!!"));
#else
delay(10);
#endif
return res;
}
#if DEBUG_EN
Serial.print("set rate success!!\r\n");
SERIAL_PORT_MONITOR.println(F("set rate success!!"));
#else
delay(10);
#endif
@@ -716,7 +844,7 @@ byte mcp2515_can::mcp2515_init(const byte canSpeed, const byte clock) {
res = setMode(MODE_NORMAL);
if (res) {
#if DEBUG_EN
Serial.print("Enter Normal Mode Fail!!\r\n");
SERIAL_PORT_MONITOR.println(F("Enter Normal Mode Fail!!"));
#else
delay(10);
#endif
@@ -725,7 +853,7 @@ byte mcp2515_can::mcp2515_init(const byte canSpeed, const byte clock) {
#if DEBUG_EN
Serial.print("Enter Normal Mode Success!!\r\n");
SERIAL_PORT_MONITOR.println(F("Enter Normal Mode Success!!"));
#else
delay(10);
#endif
@@ -916,7 +1044,7 @@ byte mcp2515_can::mcp2515_getNextFreeTXBuf(byte* txbuf_n) { // get
}
// check all 3 TX-Buffers except reserved
for (i = 0; i < MCP_N_TXBUFFERS - nReservedTx; i++) {
for (i = MCP_N_TXBUFFERS - nReservedTx; i >= 0; i--) {
if ((status & txStatusPendingFlag(i)) == 0) {
*txbuf_n = txCtrlReg(i) + 1; // return SIDH-address of Buffer
mcp2515_modifyRegister(MCP_CANINTF, txIfFlag(i), 0);
@@ -930,9 +1058,9 @@ byte mcp2515_can::mcp2515_getNextFreeTXBuf(byte* txbuf_n) { // get
** Function name: begin
** Descriptions: init can and set speed
*********************************************************************************************************/
byte mcp2515_can::begin(byte speedset, const byte clockset) {
pSPI->begin();
byte res = mcp2515_init(speedset, clockset);
byte mcp2515_can::begin(uint32_t speedset, const byte clockset, const bool _initSPI) {
if (_initSPI) pSPI->begin();
byte res = mcp2515_init((byte)speedset, clockset);
return ((res == MCP2515_OK) ? CAN_OK : CAN_FAILINIT);
}
@@ -960,14 +1088,14 @@ void mcp2515_can::enableTxInterrupt(bool enable) {
byte mcp2515_can::init_Mask(byte num, byte ext, unsigned long ulData) {
byte res = MCP2515_OK;
#if DEBUG_EN
Serial.print("Begin to set Mask!!\r\n");
SERIAL_PORT_MONITOR.println(F("Begin to set Mask!!"));
#else
delay(10);
#endif
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
if (res > 0) {
#if DEBUG_EN
Serial.print("Enter setting mode fall\r\n");
SERIAL_PORT_MONITOR.println(F("Enter setting mode fall"));
#else
delay(10);
#endif
@@ -986,14 +1114,14 @@ byte mcp2515_can::init_Mask(byte num, byte ext, unsigned long ulData) {
res = mcp2515_setCANCTRL_Mode(mcpMode);
if (res > 0) {
#if DEBUG_EN
Serial.print("Enter normal mode fall\r\n");
SERIAL_PORT_MONITOR.println(F("Enter normal mode fall"));
#else
delay(10);
#endif
return res;
}
#if DEBUG_EN
Serial.print("set Mask success!!\r\n");
SERIAL_PORT_MONITOR.println(F("set Mask success!!"));
#else
delay(10);
#endif
@@ -1007,14 +1135,14 @@ byte mcp2515_can::init_Mask(byte num, byte ext, unsigned long ulData) {
byte mcp2515_can::init_Filt(byte num, byte ext, unsigned long ulData) {
byte res = MCP2515_OK;
#if DEBUG_EN
Serial.print("Begin to set Filter!!\r\n");
SERIAL_PORT_MONITOR.println(F("Begin to set Filter!!"));
#else
delay(10);
#endif
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
if (res > 0) {
#if DEBUG_EN
Serial.print("Enter setting mode fall\r\n");
SERIAL_PORT_MONITOR.println(F("Enter setting mode fall"));
#else
delay(10);
#endif
@@ -1053,14 +1181,14 @@ byte mcp2515_can::init_Filt(byte num, byte ext, unsigned long ulData) {
res = mcp2515_setCANCTRL_Mode(mcpMode);
if (res > 0) {
#if DEBUG_EN
Serial.print("Enter normal mode fall\r\nSet filter fail!!\r\n");
SERIAL_PORT_MONITOR.println(F("Enter normal mode fall\r\nSet filter fail!!"));
#else
delay(10);
#endif
return res;
}
#if DEBUG_EN
Serial.print("set Filter success!!\r\n");
SERIAL_PORT_MONITOR.println(F("set Filter success!!"));
#else
delay(10);
#endif
@@ -1161,31 +1289,6 @@ byte mcp2515_can::sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len,
return sendMsg(id, ext, rtrBit, len, buf, wait_sent);
}
/*********************************************************************************************************
** Function name: sendMsgBuf
** Descriptions: send buf
*********************************************************************************************************/
byte mcp2515_can::sendMsgBuf(unsigned long id, byte ext, byte len, const byte* buf, bool wait_sent) {
return sendMsg(id, ext, 0, len, buf, wait_sent);
}
/*********************************************************************************************************
** Function name: readMsgBuf
** Descriptions: read message buf
*********************************************************************************************************/
byte mcp2515_can::readMsgBuf(byte* len, byte buf[]) {
return readMsgBufID(readRxTxStatus(), &can_id, &ext_flg, &rtr, len, buf);
}
/*********************************************************************************************************
** Function name: readMsgBufID
** Descriptions: read message buf and can bus source ID
*********************************************************************************************************/
byte mcp2515_can::readMsgBufID(unsigned long* ID, byte* len, byte buf[]) {
return readMsgBufID(readRxTxStatus(), ID, &ext_flg, &rtr, len, buf);
}
/*********************************************************************************************************
** Function name: readMsgBufID
** Descriptions: Read message buf and can bus source ID according to status.
@@ -1303,35 +1406,15 @@ byte mcp2515_can::checkReceive(void) {
** Function name: checkError
** Descriptions: if something error
*********************************************************************************************************/
byte mcp2515_can::checkError(void) {
byte mcp2515_can::checkError(uint8_t* err_ptr) {
byte eflg = mcp2515_readRegister(MCP_EFLG);
mcp2515_modifyRegister(MCP_EFLG, 0xFF, 0);
if (err_ptr) {
*err_ptr = eflg;
}
return ((eflg & MCP_EFLG_ERRORMASK) ? CAN_CTRLERROR : CAN_OK);
}
/*********************************************************************************************************
** Function name: getCanId
** Descriptions: when receive something, you can get the can id!!
*********************************************************************************************************/
unsigned long mcp2515_can::getCanId(void) {
return can_id;
}
/*********************************************************************************************************
** Function name: isRemoteRequest
** Descriptions: when receive something, you can check if it was a request
*********************************************************************************************************/
byte mcp2515_can::isRemoteRequest(void) {
return rtr;
}
/*********************************************************************************************************
** Function name: isExtendedFrame
** Descriptions: did we just receive standard 11bit frame or extended 29bit? 0 = std, 1 = ext
*********************************************************************************************************/
byte mcp2515_can::isExtendedFrame(void) {
return ext_flg;
}
/*********************************************************************************************************
** Function name: mcpPinMode
** Descriptions: switch supported pins between HiZ, interrupt, output or input
@@ -1354,7 +1437,7 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin mode request\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin mode request"));
#endif
return false;
}
@@ -1373,7 +1456,7 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin mode request\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin mode request"));
#endif
return false;
}
@@ -1383,7 +1466,7 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
if (res > 0) {
#if DEBUG_EN
Serial.print("Entering Configuration Mode Failure...\r\n");
SERIAL_PORT_MONITOR.println(F("Entering Configuration Mode Failure..."));
#else
delay(10);
#endif
@@ -1398,14 +1481,14 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin mode request\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin mode request"));
#endif
ret = false;
}
res = mcp2515_setCANCTRL_Mode(mcpMode);
if (res) {
#if DEBUG_EN
Serial.print("`Setting ID Mode Failure...\r\n");
SERIAL_PORT_MONITOR.println(F("`Setting ID Mode Failure..."));
#else
delay(10);
#endif
@@ -1417,7 +1500,7 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
if (res > 0) {
#if DEBUG_EN
Serial.print("Entering Configuration Mode Failure...\r\n");
SERIAL_PORT_MONITOR.println(F("Entering Configuration Mode Failure..."));
#else
delay(10);
#endif
@@ -1432,14 +1515,14 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin mode request\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin mode request"));
#endif
ret = false;
}
res = mcp2515_setCANCTRL_Mode(mcpMode);
if (res) {
#if DEBUG_EN
Serial.print("`Setting ID Mode Failure...\r\n");
SERIAL_PORT_MONITOR.println(F("`Setting ID Mode Failure..."));
#else
delay(10);
#endif
@@ -1451,7 +1534,7 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
if (res > 0) {
#if DEBUG_EN
Serial.print("Entering Configuration Mode Failure...\r\n");
SERIAL_PORT_MONITOR.println(F("Entering Configuration Mode Failure..."));
#else
delay(10);
#endif
@@ -1466,14 +1549,14 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin mode request\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin mode request"));
#endif
ret = false;
}
res = mcp2515_setCANCTRL_Mode(mcpMode);
if (res) {
#if DEBUG_EN
Serial.print("`Setting ID Mode Failure...\r\n");
SERIAL_PORT_MONITOR.println(F("`Setting ID Mode Failure..."));
#else
delay(10);
#endif
@@ -1483,7 +1566,7 @@ bool mcp2515_can::mcpPinMode(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin for mode request\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin for mode request"));
#endif
return false;
}
@@ -1519,7 +1602,7 @@ bool mcp2515_can::mcpDigitalWrite(const byte pin, const byte mode) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin for mcpDigitalWrite\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin for mcpDigitalWrite"));
#endif
return false;
}
@@ -1568,7 +1651,7 @@ byte mcp2515_can::mcpDigitalRead(const byte pin) {
break;
default:
#if DEBUG_EN
Serial.print("Invalid pin for mcpDigitalRead\r\n");
SERIAL_PORT_MONITOR.println(F("Invalid pin for mcpDigitalRead"));
#endif
return LOW;
}
+14 -10
View File
@@ -69,7 +69,7 @@ public:
{
return MCP_N_TXBUFFERS - 1; // read index of last tx buffer
}
virtual byte begin(byte speedset, const byte clockset = MCP_16MHz); // init can
virtual byte begin(uint32_t speedset, const byte clockset = MCP_16MHz, const bool _initSPI = true); // init can
virtual byte init_Mask(byte num, byte ext, unsigned long ulData); // init Masks
virtual byte init_Filt(byte num, byte ext, unsigned long ulData); // init filters
virtual void setSleepWakeup(byte enable); // Enable or disable the wake up interrupt (If disabled the MCP2515 will not be woken up by CAN bus activity, making it send only)
@@ -77,18 +77,23 @@ public:
virtual byte wake(); // Wake MCP2515 manually from sleep
virtual byte setMode(byte opMode); // Set operational mode
virtual byte getMode(); // Get operational mode
virtual byte sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte *buf, bool wait_sent = true); // send buf
virtual byte sendMsgBuf(unsigned long id, byte ext, byte len, const byte *buf, bool wait_sent = true); // send buf
virtual byte readMsgBuf(byte *len, byte *buf); // read buf
virtual byte readMsgBufID(unsigned long *ID, byte *len, byte *buf); // read buf with object ID
virtual byte checkError(uint8_t* err_ptr = NULL); // if something error
virtual byte checkReceive(void); // if something received
virtual byte checkError(void); // if something error
virtual unsigned long getCanId(void); // get can id when receive
virtual byte isRemoteRequest(void); // get RR flag when receive
virtual byte isExtendedFrame(void); // did we recieve 29bit frame?
virtual byte readMsgBufID(byte status, volatile unsigned long *id, volatile byte *ext, volatile byte *rtr, volatile byte *len, volatile byte *buf); // read buf with object ID
/* wrapper */
byte readMsgBufID(unsigned long *ID, byte *len, byte *buf) {
return readMsgBufID(readRxTxStatus(), ID, &ext_flg, &rtr, len, buf);
}
byte readMsgBuf(byte *len, byte *buf) {
return readMsgBufID(readRxTxStatus(), &can_id, &ext_flg, &rtr, len, buf);
}
virtual byte trySendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte *buf, byte iTxBuf = 0xff); // as sendMsgBuf, but does not have any wait for free buffer
virtual byte sendMsgBuf(byte status, unsigned long id, byte ext, byte rtrBit, byte len, volatile const byte *buf); // send message buf by using parsed buffer status
virtual byte sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte *buf, bool wait_sent = true); // send buf
using MCP_CAN::sendMsgBuf; // make other overloads visible
virtual void clearBufferTransmitIfFlags(byte flags = 0); // Clear transmit flags according to status
virtual byte readRxTxStatus(void); // read has something send or received
virtual byte checkClearRxStatus(byte *status); // read and clear and return first found rx status bit
@@ -146,7 +151,6 @@ private:
byte sendMsg(unsigned long id, byte ext, byte rtrBit, byte len, const byte *buf, bool wait_sent = true); // send message
private:
byte rtr; // rtr
byte nReservedTx; // Count of tx buffers for reserved send
};
+87 -54
View File
@@ -271,17 +271,20 @@
#define B1RTSM 0x02
#define B0RTSM 0x01
// clock
#define MCP_16MHz 1
#define MCP_8MHz 2
// speed 16M
#define MCP_16MHz_1000kBPS_CFG1 (0x00)
#define MCP_16MHz_1000kBPS_CFG2 (0xD0)
#define MCP_16MHz_1000kBPS_CFG3 (0x82)
#define MCP_16MHz_800kBPS_CFG1 (0x40)
#define MCP_16MHz_800kBPS_CFG2 (0x92)
#define MCP_16MHz_800kBPS_CFG3 (0x02)
#define MCP_16MHz_666kBPS_CFG1 (0x00)
#define MCP_16MHz_666kBPS_CFG2 (0xA0)
#define MCP_16MHz_666kBPS_CFG3 (0x04)
#define MCP_16MHz_500kBPS_CFG1 (0x00)
#define MCP_16MHz_500kBPS_CFG2 (0xF0)
#define MCP_16MHz_500kBPS_CFG3 (0x86)
@@ -346,9 +349,73 @@
#define MCP_16MHz_5kBPS_CFG2 (0xFF)
#define MCP_16MHz_5kBPS_CFG3 (0x87)
#define MCP_16MHz_666kBPS_CFG1 (0x00)
#define MCP_16MHz_666kBPS_CFG2 (0xA0)
#define MCP_16MHz_666kBPS_CFG3 (0x04)
// speed 12M
#define MCP_12MHz_1000kBPS_CFG1 (0x00)//
#define MCP_12MHz_1000kBPS_CFG2 (0x88)//
#define MCP_12MHz_1000kBPS_CFG3 (0x01)//
#define MCP_12MHz_666kBPS_CFG1 (0x00)//
#define MCP_12MHz_666kBPS_CFG2 (0x92)//
#define MCP_12MHz_666kBPS_CFG3 (0x01)//
#define MCP_12MHz_500kBPS_CFG1 (0x00)
#define MCP_12MHz_500kBPS_CFG2 (0x9B)
#define MCP_12MHz_500kBPS_CFG3 (0x02)
#define MCP_12MHz_250kBPS_CFG1 (0x00)//
#define MCP_12MHz_250kBPS_CFG2 (0xBF)//
#define MCP_12MHz_250kBPS_CFG3 (0x06)///
#define MCP_12MHz_200kBPS_CFG1 (0x01)//
#define MCP_12MHz_200kBPS_CFG2 (0xA4)//
#define MCP_12MHz_200kBPS_CFG3 (0x03)//
#define MCP_12MHz_125kBPS_CFG1 (0x01)//
#define MCP_12MHz_125kBPS_CFG2 (0xBF)//
#define MCP_12MHz_125kBPS_CFG3 (0x06)//
#define MCP_12MHz_100kBPS_CFG1 (0x02)//
#define MCP_12MHz_100kBPS_CFG2 (0xB6)//
#define MCP_12MHz_100kBPS_CFG3 (0x04)//
#define MCP_12MHz_95kBPS_CFG1 (0x02)//
#define MCP_12MHz_95kBPS_CFG2 (0xBE)//
#define MCP_12MHz_95kBPS_CFG3 (0x04)//
#define MCP_12MHz_83k3BPS_CFG1 (0x03)//
#define MCP_12MHz_83k3BPS_CFG2 (0xB5)//
#define MCP_12MHz_83k3BPS_CFG3 (0x03)//
#define MCP_12MHz_80kBPS_CFG1 (0x04)//
#define MCP_12MHz_80kBPS_CFG2 (0xA4)//
#define MCP_12MHz_80kBPS_CFG3 (0x03)//
#define MCP_12MHz_50kBPS_CFG1 (0x05)//
#define MCP_12MHz_50kBPS_CFG2 (0xB6)//
#define MCP_12MHz_50kBPS_CFG3 (0x04)//
#define MCP_12MHz_40kBPS_CFG1 (0x09)//
#define MCP_12MHz_40kBPS_CFG2 (0xA4)//
#define MCP_12MHz_40kBPS_CFG3 (0x03)//
#define MCP_12MHz_33kBPS_CFG1 (0x0C)//
#define MCP_12MHz_33kBPS_CFG2 (0xA4)//
#define MCP_12MHz_33kBPS_CFG3 (0x02)//
#define MCP_12MHz_31k25BPS_CFG1 (0x0B)//
#define MCP_12MHz_31k25BPS_CFG2 (0xAC)//
#define MCP_12MHz_31k25BPS_CFG3 (0x03)//
#define MCP_12MHz_25kBPS_CFG1 (0X0B)//
#define MCP_12MHz_25kBPS_CFG2 (0XB6)//
#define MCP_12MHz_25kBPS_CFG3 (0X04)//
#define MCP_12MHz_20kBPS_CFG1 (0x0C)//
#define MCP_12MHz_20kBPS_CFG2 (0xBF)//
#define MCP_12MHz_20kBPS_CFG3 (0x05)//
// speed 8M
@@ -357,6 +424,10 @@
#define MCP_8MHz_1000kBPS_CFG2 (0x80)
#define MCP_8MHz_1000kBPS_CFG3 (0x00)
#define MCP_8MHz_800kBPS_CFG1 (0x00)
#define MCP_8MHz_800kBPS_CFG2 (0x80)
#define MCP_8MHz_800kBPS_CFG3 (0x01)
#define MCP_8MHz_500kBPS_CFG1 (0x00)
#define MCP_8MHz_500kBPS_CFG2 (0x90)
#define MCP_8MHz_500kBPS_CFG3 (0x02)
@@ -377,10 +448,18 @@
#define MCP_8MHz_100kBPS_CFG2 (0xb4)
#define MCP_8MHz_100kBPS_CFG3 (0x06)
#define MCP_8MHz_95k2BPS_CFG1 (0x01)
#define MCP_8MHz_95k2BPS_CFG2 (0xBB)
#define MCP_8MHz_95k2BPS_CFG3 (0x07)
#define MCP_8MHz_80kBPS_CFG1 (0x01)
#define MCP_8MHz_80kBPS_CFG2 (0xbf)
#define MCP_8MHz_80kBPS_CFG3 (0x07)
#define MCP_8MHz_83k3BPS_CFG1 (0x01)
#define MCP_8MHz_83k3BPS_CFG2 (0xBE)
#define MCP_8MHz_83k3BPS_CFG3 (0x07)
#define MCP_8MHz_50kBPS_CFG1 (0x03)
#define MCP_8MHz_50kBPS_CFG2 (0xb4)
#define MCP_8MHz_50kBPS_CFG3 (0x06)
@@ -448,52 +527,6 @@
#define CANDEFAULTIDENTEXT (CAN_EXTID)
typedef enum {
CAN_NOBPS,
CAN_5KBPS,
CAN_10KBPS,
CAN_20KBPS,
CAN_25KBPS,
CAN_31K25BPS,
CAN_33KBPS ,
CAN_40KBPS ,
CAN_50KBPS ,
CAN_80KBPS ,
CAN_83K3BPS ,
CAN_95KBPS ,
CAN_100KBPS ,
CAN_125KBPS ,
CAN_200KBPS ,
CAN_250KBPS ,
CAN_500KBPS ,
CAN_666KBPS ,
CAN_1000KBPS
} MCP2515_BITTIME_SETUP;
#define CAN_OK (0)
#define CAN_FAILINIT (1)
#define CAN_FAILTX (2)
#define CAN_MSGAVAIL (3)
#define CAN_NOMSG (4)
#define CAN_CTRLERROR (5)
#define CAN_GETTXBFTIMEOUT (6)
#define CAN_SENDMSGTIMEOUT (7)
#define CAN_FAIL (0xff)
// #define CAN_OK (0)
// #define CAN_FAILINIT (1)
// #define CAN_FAILTX (2)
// #define CAN_MSGAVAIL (3)
#define CAN_NOMSG (4)
#define CAN_CTRLERROR (5)
#define CAN_GETTXBFTIMEOUT (6)
#define CAN_SENDMSGTIMEOUT (7)
#define CAN_FAIL (0xff)
#define CAN_MAX_CHAR_IN_MESSAGE (8)
+384 -995
View File
File diff suppressed because it is too large Load Diff
+76 -35
View File
@@ -107,8 +107,13 @@ public:
virtual byte getLastTxBuffer() {
return 3 - 1; // read index of last tx buffer
}
virtual byte begin(byte speedset,
const byte clockset = CAN_SYSCLK_40M); // init can
/*
* speedset could be in MCP_BITTIME_SETUP,
* or fill by CANFD::BITRATE()
*/
virtual byte begin(uint32_t speedset,
const byte clockset = MCP2518FD_40MHz,
const bool _initSPI = true); // init can
virtual byte init_Mask(byte num, byte ext, unsigned long ulData);
virtual byte init_Filt(byte num, byte ext,
unsigned long ulData); // init filters
@@ -117,25 +122,42 @@ public:
virtual byte wake();
virtual byte setMode(const byte opMode);
virtual byte getMode();
virtual byte sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len,
const byte *buf, bool wait_sent = true);
virtual byte sendMsgBuf(unsigned long id, byte ext, byte len, const byte *buf,
bool wait_sent = true);
virtual byte readMsgBuf(byte *len, byte *buf);
virtual byte readMsgBufID(unsigned long *ID, byte *len, byte *buf);
virtual byte checkError(uint8_t* err_ptr = NULL);
/* ---- receiving ---- */
virtual byte checkReceive(void);
virtual byte checkError(void);
virtual unsigned long getCanId(void);
virtual byte isRemoteRequest(void);
virtual byte isExtendedFrame(void);
virtual byte readMsgBufID(byte status, volatile unsigned long *id,
volatile byte *ext, volatile byte *rtr,
volatile byte *len,
volatile byte *buf); // read buf with object ID
virtual byte trySendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len,
/* wrapper */
byte readMsgBufID(unsigned long *ID, byte *len, byte *buf) {
return readMsgBufID(readRxTxStatus(), ID, &ext_flg, &rtr, len, buf);
}
byte readMsgBuf(byte *len, byte *buf) {
return readMsgBufID(readRxTxStatus(), &can_id, &ext_flg, &rtr, len, buf);
}
/* ---- sending ---- */
/* dlc = CAN_DLC_0..CAN_DLC_64(0..15)
* CAN_DLC_0..CAN_DLC_8(0..8) = data bytes count, compatible to MCP2515 APIs
* CAN_DLC_12(9) = 12 bytes
* CAN_DLC_16(10) = 16 bytes
* CAN_DLC_20(11) = 20 bytes
* CAN_DLC_24(12) = 24 bytes
* CAN_DLC_32(13) = 32 bytes
* CAN_DLC_48(14) = 48 bytes
* CAN_DLC_64(15) = 64 bytes
*/
virtual byte trySendMsgBuf(unsigned long id, byte ext, byte rtr, byte dlc,
const byte *buf, byte iTxBuf = 0xff);
virtual byte sendMsgBuf(byte status, unsigned long id, byte ext, byte rtrBit,
byte len, volatile const byte *buf);
virtual byte sendMsgBuf(byte status, unsigned long id, byte ext, byte rtr,
byte dlc, volatile const byte *buf);
virtual byte sendMsgBuf(unsigned long id, byte ext, byte rtr, byte dlc,
const byte *buf, bool wait_sent = true);
using MCP_CAN::sendMsgBuf; // make other overloads visible
virtual void clearBufferTransmitIfFlags(byte flags = 0);
virtual byte readRxTxStatus(void);
virtual byte checkClearRxStatus(byte *status);
@@ -146,14 +168,12 @@ public:
private:
byte mcp2518fd_readMsgBufID(volatile byte *len, volatile byte *buf);
byte mcp2518fd_sendMsgBuf(const byte *buf, byte len, unsigned long id,
byte ext, bool wait_sent); // send buf
byte mcp2518fd_sendMsg(const byte *buf, byte len, unsigned long id, byte ext,
bool wait_sent);
byte rtr, bool wait_sent);
int8_t mcp2518fd_receiveMsg();
private:
uint8_t mcp2518fd_init(byte speedset, const byte clock); // mcp2518fdinit
uint8_t mcp2518fd_init(uint32_t speedset, const byte clock); // mcp2518fdinit
int8_t mcp2518fd_reset(void); // reset mcp2518fd
int8_t mcp2518fd_EccEnable(void); // Section: ECC
int8_t mcp2518fd_RamInit(uint8_t d);
@@ -172,7 +192,7 @@ private:
int8_t mcp2518fd_FilterMaskConfigure(CAN_FILTER filter, CAN_MASKOBJ_ID *mask);
int8_t mcp2518fd_FilterToFifoLink(CAN_FILTER filter, CAN_FIFO_CHANNEL channel,
bool enable);
int8_t mcp2518fd_BitTimeConfigure(MCP2518FD_BITTIME_SETUP bitTime,
int8_t mcp2518fd_BitTimeConfigure(uint32_t speedset,
CAN_SSP_MODE sspMode, CAN_SYSCLK_SPEED clk);
int8_t mcp2518fd_GpioModeConfigure(GPIO_PIN_MODE gpio0, GPIO_PIN_MODE gpio1);
int8_t mcp2518fd_TransmitChannelEventEnable(CAN_FIFO_CHANNEL channel,
@@ -202,6 +222,7 @@ private:
int8_t mcp2518fd_ErrorStateGet(CAN_ERROR_STATE *flags);
int8_t mcp2518fd_ModuleEventRxCodeGet(CAN_RXCODE *rxCode);
int8_t mcp2518fd_ModuleEventTxCodeGet(CAN_TXCODE *txCode);
int8_t mcp2518fd_TransmitChannelEventAttemptClear(CAN_FIFO_CHANNEL channel);
int8_t mcp2518fd_LowPowerModeEnable();
int8_t mcp2518fd_LowPowerModeDisable();
@@ -230,23 +251,43 @@ private:
private:
int8_t
mcp2518fd_BitTimeConfigureNominal40MHz(MCP2518FD_BITTIME_SETUP bitTime);
int8_t mcp2518fd_BitTimeConfigureData40MHz(MCP2518FD_BITTIME_SETUP bitTime,
CAN_SSP_MODE sspMode);
int8_t
mcp2518fd_BitTimeConfigureNominal20MHz(MCP2518FD_BITTIME_SETUP bitTime);
int8_t mcp2518fd_BitTimeConfigureData20MHz(MCP2518FD_BITTIME_SETUP bitTime,
CAN_SSP_MODE sspMode);
int8_t
mcp2518fd_BitTimeConfigureNominal10MHz(MCP2518FD_BITTIME_SETUP bitTime);
int8_t mcp2518fd_BitTimeConfigureData10MHz(MCP2518FD_BITTIME_SETUP bitTime,
CAN_SSP_MODE sspMode);
mcp2518fd_BitTimeConfigureNominal(void);
int8_t mcp2518fd_BitTimeConfigureData(CAN_SSP_MODE sspMode);
byte ext_flg; // identifier xxxID
// either extended (the 29 LSB) or standard (the 11 LSB)
unsigned long can_id; // can id
byte rtr; // rtr
byte nReservedTx; // Count of tx buffers for reserved send
CAN_OPERATION_MODE mcpMode = CAN_CLASSIC_MODE; // Current controller mode
uint32_t bittime_compat_to_mcp2518fd(uint32_t speedset);
int calcBittime(const uint32_t inDesiredArbitrationBitRate,
const uint32_t inTolerancePPM = 10000/* 1% */);
uint32_t mSysClock; // PLL disabled, mSysClock = Oscillator Frequency
uint32_t mDesiredArbitrationBitRate; // desired ArbitrationBitRate
uint8_t mDataBitRateFactor; // multiplier between ArbitrationBitRate and DataBitrate
//--- Data bit rate; if mDataBitRateFactor==1, theses properties are not used for configuring the MCP2517FD.
uint8_t mDataPhaseSegment1 = 0 ; // if mDataBitRateFactor > 1: 2...32, else equal to mArbitrationPhaseSegment1
uint8_t mDataPhaseSegment2 = 0 ; // if mDataBitRateFactor > 1: 1...16, else equal to mArbitrationPhaseSegment2
uint8_t mDataSJW = 0 ; // if mDataBitRateFactor > 1: 1...16, else equal to mArbitrationSJW
//--- Bit rate prescaler is common to arbitration and data bit rates
uint16_t mBitRatePrescaler = 0 ; // 1...256
//--- Arbitration bit rate
uint16_t mArbitrationPhaseSegment1 = 0 ; // 2...256
uint8_t mArbitrationPhaseSegment2 = 0 ; // 1...128
uint8_t mArbitrationSJW = 0 ; // 1...128
bool mArbitrationBitRateClosedToDesiredRate = false ; // The above configuration is not correct
//--- Transmitter Delay Compensation Offset
int8_t mTDCO = 0 ; // -64 ... +63
};
/* CANFD Auxiliary helper */
class CANFD {
public:
static byte dlc2len(byte dlc);
static byte len2dlc(byte len);
static uint32_t BITRATE(uint32_t arbitration, uint8_t factor) {
return ((uint32_t)factor << 24) | (arbitration & 0xFFFFFUL);
}
};
#endif
+31 -52
View File
@@ -47,6 +47,7 @@ DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
#include <Arduino.h>
#include <inttypes.h>
#include "mcp_can.h"
// DOM-IGNORE-BEGIN
#ifdef __cplusplus // Provide C++ Compatibility
@@ -130,8 +131,7 @@ extern "C" {
#define cRAMADDR_START 0x400
#define cRAMADDR_END (cRAMADDR_START + cRAM_SIZE)
/*spi cs set*/
extern uint8_t SPICS;
/* SPI Chip Select */
#define MCP2518fd_SELECT() \
pinMode(SPICS, OUTPUT); \
digitalWrite(SPICS, LOW)
@@ -589,51 +589,27 @@ typedef enum {
//! CAN Bit Time Setup: Arbitration/Data Bit Phase
typedef enum {
CAN_500K_1M, // 0x00
CAN_500K_2M, // 0x01
CAN_500K_3M,
CAN_500K_4M,
CAN_500K_5M, // 0x04
CAN_500K_6M7,
CAN_500K_8M, // 0x06
CAN_500K_10M,
CAN_250K_500K, // 0x08
CAN_250K_833K,
CAN_250K_1M,
CAN_250K_1M5,
CAN_250K_2M,
CAN_250K_3M,
CAN_250K_4M,
CAN_1000K_4M, // 0x0f
CAN_1000K_8M,
CAN_125K_500K // 0x11
} MCP2518FD_BITTIME_SETUP;
//! CAN Nominal Bit Time Setup
typedef enum {
CAN_NBT_125K,
CAN_NBT_250K,
CAN_NBT_500K,
CAN_NBT_1M
} CAN_NOMINAL_BITTIME_SETUP;
//! CAN Data Bit Time Setup
typedef enum {
CAN_DBT_500K,
CAN_DBT_833K,
CAN_DBT_1M,
CAN_DBT_1M5,
CAN_DBT_2M,
CAN_DBT_3M,
CAN_DBT_4M,
CAN_DBT_5M,
CAN_DBT_6M7,
CAN_DBT_8M,
CAN_DBT_10M
} CAN_DATA_BITTIME_SETUP;
/* not apply to AVR platform */
// typedef enum {
static const uint32_t CAN_125K_500K = ( 4UL << 24) | (125000UL);
static const uint32_t CAN_250K_500K = ( 2UL << 24) | (250000UL);
static const uint32_t CAN_250K_750K = ( 3UL << 24) | (250000UL);
static const uint32_t CAN_250K_1M = ( 4UL << 24) | (250000UL);
static const uint32_t CAN_250K_1M5 = ( 6UL << 24) | (250000UL);
static const uint32_t CAN_250K_2M = ( 8UL << 24) | (250000UL);
static const uint32_t CAN_250K_3M = (12UL << 24) | (250000UL);
static const uint32_t CAN_250K_4M = (16UL << 24) | (250000UL);
static const uint32_t CAN_500K_1M = ( 2UL << 24) | (500000UL);
static const uint32_t CAN_500K_2M = ( 4UL << 24) | (500000UL);
static const uint32_t CAN_500K_3M = ( 6UL << 24) | (500000UL);
static const uint32_t CAN_500K_4M = ( 8UL << 24) | (500000UL);
static const uint32_t CAN_500K_5M = (10UL << 24) | (500000UL);
static const uint32_t CAN_500K_6M5 = (13UL << 24) | (500000UL);
static const uint32_t CAN_500K_8M = (16UL << 24) | (500000UL);
static const uint32_t CAN_500K_10M = (20UL << 24) | (500000UL);
static const uint32_t CAN_1000K_4M = ( 4UL << 24) |(1000000UL);
static const uint32_t CAN_1000K_8M = ( 8UL << 24) |(1000000UL);
//} MCP2518FD_BITTIME_SETUP;
//! Secondary Sample Point Mode
@@ -942,9 +918,9 @@ typedef enum {
//! System Clock Selection
typedef enum {
CAN_SYSCLK_40M,
CAN_SYSCLK_20M,
CAN_SYSCLK_10M
CAN_SYSCLK_40M = MCP2518FD_40MHz,
CAN_SYSCLK_20M = MCP2518FD_20MHz,
CAN_SYSCLK_10M = MCP2518FD_10MHz,
} CAN_SYSCLK_SPEED;
//! CLKO Divide
@@ -1487,8 +1463,8 @@ typedef union _REG_IOCON {
uint32_t LAT1 : 1;
uint32_t unimplemented3 : 5;
uint32_t HVDETSEL : 1;
uint32_t GPIO0 : 1;
uint32_t GPIO1 : 1;
uint32_t GPIO0_ : 1;
uint32_t GPIO1_ : 1;
uint32_t unimplemented4 : 6;
uint32_t PinMode0 : 1;
uint32_t PinMode1 : 1;
@@ -1607,6 +1583,9 @@ static const uint32_t canFilterObjectResetValues[] = {0x00000000, 0x00000000};
static const uint32_t mcp25xxfdControlResetValues[] = {
0x00000460, 0x00000003, 0x00000000, 0x00000000, 0x00000000};
#endif
#ifdef __cplusplus // Provide C++ Compatibility
}
#endif
-8
View File
@@ -29,11 +29,3 @@ void MCP_CAN::setSPI(SPIClass *_pSPI)
{
pSPI = _pSPI; // define SPI port to use before begin()
}
inline byte MCP_CAN::trySendExtMsgBuf(unsigned long id, byte len, const byte *buf, byte iTxBuf)
{ // as trySendMsgBuf, but set ext=1 and rtr=0
return trySendMsgBuf(id, 1, 0, len, buf, iTxBuf);
}
inline byte MCP_CAN::sendExtMsgBuf(byte status, unsigned long id, byte len, volatile const byte *buf)
{ // as sendMsgBuf, but set ext=1 and rtr=0
return sendMsgBuf(status, id, 1, 0, len, buf);
}
+103 -31
View File
@@ -5,63 +5,135 @@
#include <SPI.h>
#include <inttypes.h>
#ifndef SERIAL_PORT_MONITOR
#ifdef SEEED_XIAO_M0
#define SERIAL_PORT_MONITOR Serial
#elif defined(ARDUINO_SAMD_VARIANT_COMPLIANCE)
#define SERIAL_PORT_MONITOR SerialUSB
#else
#define SERIAL_PORT_MONITOR Serial
#endif
#endif
#define CAN_OK (0)
#define CAN_FAILINIT (1)
#define CAN_FAILTX (2)
#define CAN_MSGAVAIL (3)
#define CAN_NOMSG (4)
#define CAN_CTRLERROR (5)
#define CAN_GETTXBFTIMEOUT (6)
#define CAN_SENDMSGTIMEOUT (7)
#define CAN_FAIL (0xff)
// clock
typedef enum {
MCP_NO_MHz,
/* apply to MCP2515 */
MCP_16MHz,
MCP_12MHz,
MCP_8MHz,
/* apply to MCP2518FD */
MCP2518FD_40MHz = MCP_16MHz /* To compatible MCP2515 shield */,
MCP2518FD_20MHz,
MCP2518FD_10MHz,
} MCP_CLOCK_T;
typedef enum {
CAN_NOBPS,
CAN_5KBPS,
CAN_10KBPS,
CAN_20KBPS,
CAN_25KBPS,
CAN_31K25BPS,
CAN_33KBPS ,
CAN_40KBPS ,
CAN_50KBPS ,
CAN_80KBPS ,
CAN_83K3BPS ,
CAN_95KBPS ,
CAN_95K2BPS ,
CAN_100KBPS ,
CAN_125KBPS ,
CAN_200KBPS ,
CAN_250KBPS ,
CAN_500KBPS ,
CAN_666KBPS ,
CAN_800KBPS ,
CAN_1000KBPS
} MCP_BITTIME_SETUP;
class MCP_CAN
{
public:
virtual void enableTxInterrupt(bool enable = true) = 0; // enable transmit interrupt
virtual void enableTxInterrupt(bool enable = true) = 0; // enable transmit interrupt
virtual void reserveTxBuffers(byte nTxBuf = 0) = 0;
virtual byte getLastTxBuffer() = 0;
virtual byte begin(byte speedset, const byte clockset) = 0; // init can
virtual byte init_Mask(byte num, byte ext, unsigned long ulData) = 0; // init Masks
virtual byte init_Filt(byte num, byte ext, unsigned long ulData) = 0; // init filters
virtual void setSleepWakeup(byte enable) = 0; // Enable or disable the wake up interrupt (If disabled the MCP2515 will not be woken up by CAN bus activity, making it send only)
virtual byte sleep() = 0; // Put the MCP2515 in sleep mode
virtual byte wake() = 0; // Wake MCP2515 manually from sleep
virtual byte setMode(byte opMode) = 0; // Set operational mode
virtual byte getMode() = 0; // Get operational mode
virtual byte sendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte *buf, bool wait_sent = true) = 0; // send buf
virtual byte sendMsgBuf(unsigned long id, byte ext, byte len, const byte *buf, bool wait_sent = true) = 0; // send buf
virtual byte readMsgBuf(byte *len, byte *buf) = 0; // read buf
virtual byte readMsgBufID(unsigned long *ID, byte *len, byte *buf) = 0; // read buf with object ID
virtual byte checkReceive(void) = 0; // if something received
virtual byte checkError(void) = 0; // if something error
virtual unsigned long getCanId(void) = 0; // get can id when receive
virtual byte isRemoteRequest(void) = 0; // get RR flag when receive
virtual byte isExtendedFrame(void) = 0; // did we recieve 29bit frame?
virtual byte readMsgBufID(byte status, volatile unsigned long *id, volatile byte *ext, volatile byte *rtr, volatile byte *len, volatile byte *buf) = 0; // read buf with object ID
virtual byte trySendMsgBuf(unsigned long id, byte ext, byte rtrBit, byte len, const byte *buf, byte iTxBuf = 0xff) = 0; // as sendMsgBuf, but does not have any wait for free buffer
virtual byte sendMsgBuf(byte status, unsigned long id, byte ext, byte rtrBit, byte len, volatile const byte *buf) = 0; // send message buf by using parsed buffer status
virtual void clearBufferTransmitIfFlags(byte flags = 0) = 0; // Clear transmit flags according to status
virtual byte readRxTxStatus(void) = 0; // read has something send or received
virtual byte checkClearRxStatus(byte *status) = 0; // read and clear and return first found rx status bit
virtual byte checkClearTxStatus(byte *status, byte iTxBuf = 0xff) = 0; // read and clear and return first found or buffer specified tx status bit
virtual bool mcpPinMode(const byte pin, const byte mode) = 0; // switch supported pins between HiZ, interrupt, output or input
virtual bool mcpDigitalWrite(const byte pin, const byte mode) = 0; // write HIGH or LOW to RX0BF/RX1BF
virtual byte mcpDigitalRead(const byte pin) = 0; // read HIGH or LOW from supported pins
/*
* speedset be in MCP_BITTIME_SETUP
* clockset be in MCP_CLOCK_T
*/
virtual byte begin(uint32_t speedset, const byte clockset, const bool _initSPI = true) = 0; // init can
virtual byte init_Mask(byte num, byte ext, unsigned long ulData) = 0; // init Masks
virtual byte init_Filt(byte num, byte ext, unsigned long ulData) = 0; // init filters
virtual void setSleepWakeup(byte enable) = 0; // Enable or disable the wake up interrupt
// (If disabled the MCP2515 will not be woken up by CAN bus activity, making it send only)
virtual byte sleep() = 0; // Put the MCP2515 in sleep mode
virtual byte wake() = 0; // Wake MCP2515 manually from sleep
virtual byte setMode(byte opMode) = 0; // Set operational mode
virtual byte getMode() = 0; // Get operational mode
virtual byte checkError(uint8_t* err_ptr = NULL) = 0; // if something error
/* ---- receiving ---- */
virtual byte checkReceive(void) = 0; // if something received
virtual byte readMsgBufID(byte status,
volatile unsigned long *id, volatile byte *ext, volatile byte *rtr,
volatile byte *len, volatile byte *buf) = 0; // read buf with object ID
/* wrapper */
virtual byte readMsgBufID(unsigned long *ID, byte *len, byte *buf) = 0;
virtual byte readMsgBuf(byte *len, byte *buf) = 0;
/* could be called after a successful readMsgBufID() */
unsigned long getCanId(void) { return can_id; }
byte isRemoteRequest(void) { return rtr; }
byte isExtendedFrame(void) { return ext_flg;}
/* ---- sending ---- */
virtual byte trySendMsgBuf(unsigned long id, byte ext, byte rtr,
byte len, const byte *buf, byte iTxBuf = 0xff) = 0; // as sendMsgBuf, but does not have any wait for free buffer
virtual byte sendMsgBuf(byte status, unsigned long id, byte ext, byte rtr,
byte len, volatile const byte *buf) = 0; // send message buf by using parsed buffer status
virtual byte sendMsgBuf(unsigned long id, byte ext, byte rtrBit,
byte len, const byte *buf, bool wait_sent = true) = 0; // send message with wait
/* wrapper */
inline byte sendMsgBuf(unsigned long id, byte ext, byte len, const byte *buf) {
return sendMsgBuf(id, ext, 0, len, buf, true);
}
virtual void clearBufferTransmitIfFlags(byte flags = 0) = 0; // Clear transmit flags according to status
virtual byte readRxTxStatus(void) = 0; // read has something send or received
virtual byte checkClearRxStatus(byte *status) = 0; // read and clear and return first found rx status bit
virtual byte checkClearTxStatus(byte *status, byte iTxBuf = 0xff) = 0; // read and clear and return first found or buffer specified tx status bit
virtual bool mcpPinMode(const byte pin, const byte mode) = 0; // switch supported pins between HiZ, interrupt, output or input
virtual bool mcpDigitalWrite(const byte pin, const byte mode) = 0; // write HIGH or LOW to RX0BF/RX1BF
virtual byte mcpDigitalRead(const byte pin) = 0; // read HIGH or LOW from supported pins
public:
MCP_CAN(byte _CS);
void init_CS(byte _CS); // define CS after construction before begin()
void setSPI(SPIClass *_pSPI);
inline byte trySendExtMsgBuf(unsigned long id, byte len, const byte *buf, byte iTxBuf = 0xff);
inline byte sendExtMsgBuf(byte status, unsigned long id, byte len, volatile const byte *buf);
protected:
byte ext_flg; // identifier xxxID
// either extended (the 29 LSB) or standard (the 11 LSB)
unsigned long can_id; // can id
byte rtr; // is remote frame
byte SPICS;
SPIClass *pSPI;
byte mcpMode; // Current controller mode
};
#endif
#endif