Rework, use ESP32 native CAN, include library
This commit is contained in:
parent
36274df86b
commit
f194398326
33 changed files with 1974 additions and 2337 deletions
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2018 Longan Labs Inc.
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
|
@ -1,143 +0,0 @@
|
||||||
# CAN Bus Library
|
|
||||||
[![GitHub](https://img.shields.io/github/license/Longan-Labs/Arduino_CAN_BUS_MCP2515)](https://github.com/Longan-Labs/Arduino_CAN_BUS_MCP2515/blob/master/LICENSE)
|
|
||||||
[![Installation instructions](https://www.ardu-badge.com/badge/mcp_canbus.svg?)](https://www.ardu-badge.com/mcp_canbus)
|
|
||||||
[![GitHub version](https://img.shields.io/github/release/Longan-Labs/Arduino_CAN_BUS_MCP2515.svg?logo=github&logoColor=ffffff)](https://github.com/Longan-Labs/Arduino_CAN_BUS_MCP2515/releases/latest)
|
|
||||||
[![GitHub Release Date](https://img.shields.io/github/release-date/Longan-Labs/Arduino_CAN_BUS_MCP2515.svg?logo=github&logoColor=ffffff)](https://github.com/Longan-Labs/Arduino_CAN_BUS_MCP2515/releases/latest)
|
|
||||||
[![GitHub Repo stars](https://img.shields.io/github/stars/Longan-Labs/Arduino_CAN_BUS_MCP2515?logo=github&logoColor=ffffff)](https://github.com/Longan-Labs/Arduino_CAN_BUS_MCP2515/stargazers)
|
|
||||||
[![GitHub issues](https://img.shields.io/github/issues/Longan-Labs/Arduino_CAN_BUS_MCP2515.svg?logo=github&logoColor=ffffff)](https://github.com/Longan-Labs/Arduino_CAN_BUS_MCP2515/issues)
|
|
||||||
|
|
||||||
Arduino library for MCP2515, it's available for most of theArduino boards, we test it with Arduino UNO, Leonardo, Mega as well as Zero.
|
|
||||||
|
|
||||||
With this library, you can,
|
|
||||||
|
|
||||||
1. Send a CAN2.0 frame
|
|
||||||
2. Receive a CAN2.0 frame
|
|
||||||
3. Get data from OBD-II
|
|
||||||
4. Set the masks and filters, there're 32 masks and filters.
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
You can install it similiar to any other Arduino libraries, using the Library Manager or from a Zip file in the Arduino IDE.
|
|
||||||
|
|
||||||
- Install using the Library Manager
|
|
||||||
1. In the Arduino IDE, navigate to Sketch > Include Library > Manage Libraries...
|
|
||||||
2. Search for "mcp_canbus" to find this library
|
|
||||||
3. Click "INSTALL"
|
|
||||||
|
|
||||||
- Install from a Zip file
|
|
||||||
1. [Download this library](https://github.com/Longan-Labs/Aruino_CAN_BUS_MCP2515/archive/refs/heads/master.zip)
|
|
||||||
2. Extract the zip file
|
|
||||||
3. In the Arduino IDE, navigate to Sketch > Include Library > Add .ZIP Library
|
|
||||||
|
|
||||||
You can also read [how to install mcp_canbus library](https://www.ardu-badge.com/mcp_canbus) for a reference.
|
|
||||||
|
|
||||||
## Respository Contents
|
|
||||||
|
|
||||||
* [**/examples**](./examples) - Example sketches for the library (.ino). Run these from the Arduino IDE.
|
|
||||||
* [**/src**](./src) - Source files for the library (.cpp, .h).
|
|
||||||
* [**keywords.txt**](./keywords.txt) - Keywords from this library that will be highlighted in the Arduino IDE.
|
|
||||||
* [**library.properties**](./library.properties) - General library properties for the Arduino package manager.
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
### Header
|
|
||||||
```
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Functions
|
|
||||||
|
|
||||||
- begin()
|
|
||||||
- init_Mask()
|
|
||||||
- init_filt()
|
|
||||||
- checkReceive()
|
|
||||||
- readMsgBufID()
|
|
||||||
- readMsgBuf()
|
|
||||||
- getCanId()
|
|
||||||
- sendMsgBuf()
|
|
||||||
- isRemoteRequest()
|
|
||||||
- isExtendedFrame()
|
|
||||||
|
|
||||||
### Examples
|
|
||||||
|
|
||||||
here are many examples implemented in this library. One of the examples is below. You can find other examples [here](./examples)
|
|
||||||
|
|
||||||
```Cpp
|
|
||||||
/* send a frame from can bus
|
|
||||||
support@longan-labs.cc
|
|
||||||
|
|
||||||
CAN Baudrate,
|
|
||||||
|
|
||||||
#define CAN_5KBPS 1
|
|
||||||
#define CAN_10KBPS 2
|
|
||||||
#define CAN_20KBPS 3
|
|
||||||
#define CAN_25KBPS 4
|
|
||||||
#define CAN_31K25BPS 5
|
|
||||||
#define CAN_33KBPS 6
|
|
||||||
#define CAN_40KBPS 7
|
|
||||||
#define CAN_50KBPS 8
|
|
||||||
#define CAN_80KBPS 9
|
|
||||||
#define CAN_83K3BPS 10
|
|
||||||
#define CAN_95KBPS 11
|
|
||||||
#define CAN_100KBPS 12
|
|
||||||
#define CAN_125KBPS 13
|
|
||||||
#define CAN_200KBPS 14
|
|
||||||
#define CAN_250KBPS 15
|
|
||||||
#define CAN_500KBPS 16
|
|
||||||
#define CAN_666KBPS 17
|
|
||||||
#define CAN_1000KBPS 18
|
|
||||||
|
|
||||||
CANBed V1: https://www.longan-labs.cc/1030008.html
|
|
||||||
CANBed M0: https://www.longan-labs.cc/1030014.html
|
|
||||||
CAN Bus Shield: https://www.longan-labs.cc/1030016.html
|
|
||||||
OBD-II CAN Bus GPS Dev Kit: https://www.longan-labs.cc/1030003.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
const int SPI_CS_PIN = 17; // CANBed V1
|
|
||||||
// const int SPI_CS_PIN = 3; // CANBed M0
|
|
||||||
// const int SPI_CS_PIN = 9; // CAN Bus Shield
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
|
|
||||||
{
|
|
||||||
Serial.println("CAN BUS FAIL!");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN BUS OK!");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
CAN.sendMsgBuf(0x00, 0, 8, stmp);
|
|
||||||
delay(100); // send data per 100ms
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
||||||
```
|
|
||||||
|
|
||||||
## Get a Dev Board
|
|
||||||
|
|
||||||
If you need a Dev board, plese try,
|
|
||||||
|
|
||||||
- [CAN Bus Shield for Arduino](https://www.longan-labs.cc/1030016.html)
|
|
||||||
- [CANBed V1](https://www.longan-labs.cc/1030008.html)
|
|
||||||
- [CANBed M0](https://www.longan-labs.cc/1030014.html)
|
|
||||||
- [OBD-II CAN Bus GPS Dev Kit](https://www.longan-labs.cc/1030003.html)
|
|
||||||
|
|
||||||
## Contact us
|
|
||||||
|
|
||||||
If you have any question, please feel free to contact [support@longan-labs.cc](support@longan-labs.cc)
|
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
/*************************************************************************************************
|
|
||||||
OBD-II_PIDs TEST CODE
|
|
||||||
|
|
||||||
Query
|
|
||||||
send id: 0x7df
|
|
||||||
dta: 0x02, 0x01, PID_CODE, 0, 0, 0, 0, 0
|
|
||||||
|
|
||||||
Response
|
|
||||||
From id: 0x7E9 or 0x7EA or 0x7EB
|
|
||||||
dta: len, 0x41, PID_CODE, byte0, byte1(option), byte2(option), byte3(option), byte4(option)
|
|
||||||
|
|
||||||
https://en.wikipedia.org/wiki/OBD-II_PIDs
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
|
|
||||||
/* Please modify SPI_CS_PIN to adapt to your board.
|
|
||||||
|
|
||||||
CANBed V1 - 17
|
|
||||||
CANBed M0 - 3
|
|
||||||
CAN Bus Shield - 9
|
|
||||||
CANBed 2040 - 9
|
|
||||||
CANBed Dual - 9
|
|
||||||
OBD-2G Dev Kit - 9
|
|
||||||
OBD-II GPS Kit - 9
|
|
||||||
Hud Dev Kit - 9
|
|
||||||
|
|
||||||
Seeed Studio CAN-Bus Breakout Board for XIAO and QT Py - D7
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SPI_CS_PIN 9
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
#define PID_ENGIN_PRM 0x0C
|
|
||||||
#define PID_VEHICLE_SPEED 0x0D
|
|
||||||
#define PID_COOLANT_TEMP 0x05
|
|
||||||
|
|
||||||
#define CAN_ID_PID 0x7DF
|
|
||||||
|
|
||||||
void set_mask_filt()
|
|
||||||
{
|
|
||||||
// set mask, set both the mask to 0x3ff
|
|
||||||
|
|
||||||
CAN.init_Mask(0, 0, 0x7FC);
|
|
||||||
CAN.init_Mask(1, 0, 0x7FC);
|
|
||||||
|
|
||||||
// set filter, we can receive id from 0x04 ~ 0x09
|
|
||||||
|
|
||||||
CAN.init_Filt(0, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(1, 0, 0x7E8);
|
|
||||||
|
|
||||||
CAN.init_Filt(2, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(3, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(4, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(5, 0, 0x7E8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendPid(unsigned char __pid) {
|
|
||||||
unsigned char tmp[8] = {0x02, 0x01, __pid, 0, 0, 0, 0, 0};
|
|
||||||
CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getRPM(int *r)
|
|
||||||
{
|
|
||||||
sendPid(PID_ENGIN_PRM);
|
|
||||||
unsigned long __timeout = millis();
|
|
||||||
|
|
||||||
while(millis()-__timeout < 1000) // 1s time out
|
|
||||||
{
|
|
||||||
unsigned char len = 0;
|
|
||||||
unsigned char buf[8];
|
|
||||||
|
|
||||||
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if get data
|
|
||||||
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
|
|
||||||
|
|
||||||
if(buf[1] == 0x41)
|
|
||||||
{
|
|
||||||
*r = (256*buf[3]+buf[4])/4;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit Atemga32U4 version
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit RP2040 version
|
|
||||||
// pinMode(12, OUTPUT);
|
|
||||||
// digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
|
|
||||||
Serial.println("CAN init fail, retry...");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN init ok!");
|
|
||||||
set_mask_filt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
int __rpm = 0;
|
|
||||||
|
|
||||||
int ret = getRPM(&__rpm);
|
|
||||||
|
|
||||||
if(ret)
|
|
||||||
{
|
|
||||||
Serial.print("Engin Speed: ");
|
|
||||||
Serial.print(__rpm);
|
|
||||||
Serial.println(" rpm");
|
|
||||||
}else Serial.println("get Engin Speed Fail...");
|
|
||||||
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*************************************************************************************************
|
|
||||||
OBD-II_PIDs TEST CODE
|
|
||||||
|
|
||||||
Query
|
|
||||||
send id: 0x7df
|
|
||||||
dta: 0x02, 0x01, PID_CODE, 0, 0, 0, 0, 0
|
|
||||||
|
|
||||||
Response
|
|
||||||
From id: 0x7E9 or 0x7EA or 0x7EB
|
|
||||||
dta: len, 0x41, PID_CODE, byte0, byte1(option), byte2(option), byte3(option), byte4(option)
|
|
||||||
|
|
||||||
https://en.wikipedia.org/wiki/OBD-II_PIDs
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
|
|
||||||
/* Please modify SPI_CS_PIN to adapt to your board.
|
|
||||||
|
|
||||||
CANBed V1 - 17
|
|
||||||
CANBed M0 - 3
|
|
||||||
CAN Bus Shield - 9
|
|
||||||
CANBed 2040 - 9
|
|
||||||
CANBed Dual - 9
|
|
||||||
OBD-2G Dev Kit - 9
|
|
||||||
OBD-II GPS Kit - 9
|
|
||||||
Hud Dev Kit - 9
|
|
||||||
|
|
||||||
Seeed Studio CAN-Bus Breakout Board for XIAO and QT Py - D7
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SPI_CS_PIN 9
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
#define PID_ENGIN_PRM 0x0C
|
|
||||||
#define PID_VEHICLE_SPEED 0x0D
|
|
||||||
#define PID_COOLANT_TEMP 0x05
|
|
||||||
|
|
||||||
#define CAN_ID_PID 0x7DF
|
|
||||||
|
|
||||||
void set_mask_filt()
|
|
||||||
{
|
|
||||||
// set mask, set both the mask to 0x3ff
|
|
||||||
|
|
||||||
CAN.init_Mask(0, 0, 0x7FC);
|
|
||||||
CAN.init_Mask(1, 0, 0x7FC);
|
|
||||||
|
|
||||||
// set filter, we can receive id from 0x04 ~ 0x09
|
|
||||||
|
|
||||||
CAN.init_Filt(0, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(1, 0, 0x7E8);
|
|
||||||
|
|
||||||
CAN.init_Filt(2, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(3, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(4, 0, 0x7E8);
|
|
||||||
CAN.init_Filt(5, 0, 0x7E8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendPid(unsigned char __pid) {
|
|
||||||
unsigned char tmp[8] = {0x02, 0x01, __pid, 0, 0, 0, 0, 0};
|
|
||||||
CAN.sendMsgBuf(CAN_ID_PID, 0, 8, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getSpeed(int *s)
|
|
||||||
{
|
|
||||||
sendPid(PID_VEHICLE_SPEED);
|
|
||||||
unsigned long __timeout = millis();
|
|
||||||
|
|
||||||
while(millis()-__timeout < 1000) // 1s time out
|
|
||||||
{
|
|
||||||
unsigned char len = 0;
|
|
||||||
unsigned char buf[8];
|
|
||||||
|
|
||||||
if (CAN_MSGAVAIL == CAN.checkReceive()) { // check if get data
|
|
||||||
CAN.readMsgBuf(&len, buf); // read data, len: data length, buf: data buf
|
|
||||||
|
|
||||||
if(buf[1] == 0x41)
|
|
||||||
{
|
|
||||||
*s = buf[3];
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit Atemga32U4 version
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit RP2040 version
|
|
||||||
// pinMode(12, OUTPUT);
|
|
||||||
// digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) { // init can bus : baudrate = 500k
|
|
||||||
Serial.println("CAN init fail, retry...");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN init ok!");
|
|
||||||
set_mask_filt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
int __speed = 0;
|
|
||||||
int ret = getSpeed(&__speed);
|
|
||||||
if(ret)
|
|
||||||
{
|
|
||||||
Serial.print("Vehicle Speed: ");
|
|
||||||
Serial.print(__speed);
|
|
||||||
Serial.println(" kmh");
|
|
||||||
}
|
|
||||||
delay(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
|
@ -1,99 +0,0 @@
|
||||||
/* receive a frame from can bus
|
|
||||||
|
|
||||||
CAN Baudrate,
|
|
||||||
|
|
||||||
#define CAN_5KBPS 1
|
|
||||||
#define CAN_10KBPS 2
|
|
||||||
#define CAN_20KBPS 3
|
|
||||||
#define CAN_25KBPS 4
|
|
||||||
#define CAN_31K25BPS 5
|
|
||||||
#define CAN_33KBPS 6
|
|
||||||
#define CAN_40KBPS 7
|
|
||||||
#define CAN_50KBPS 8
|
|
||||||
#define CAN_80KBPS 9
|
|
||||||
#define CAN_83K3BPS 10
|
|
||||||
#define CAN_95KBPS 11
|
|
||||||
#define CAN_100KBPS 12
|
|
||||||
#define CAN_125KBPS 13
|
|
||||||
#define CAN_200KBPS 14
|
|
||||||
#define CAN_250KBPS 15
|
|
||||||
#define CAN_500KBPS 16
|
|
||||||
#define CAN_666KBPS 17
|
|
||||||
#define CAN_1000KBPS 18
|
|
||||||
|
|
||||||
CANBed V1: https://www.longan-labs.cc/1030008.html
|
|
||||||
CANBed M0: https://www.longan-labs.cc/1030014.html
|
|
||||||
CAN Bus Shield: https://www.longan-labs.cc/1030016.html
|
|
||||||
OBD-II CAN Bus GPS Dev Kit: https://www.longan-labs.cc/1030003.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
|
|
||||||
/* Please modify SPI_CS_PIN to adapt to your board.
|
|
||||||
|
|
||||||
CANBed V1 - 17
|
|
||||||
CANBed M0 - 3
|
|
||||||
CAN Bus Shield - 9
|
|
||||||
CANBed 2040 - 9
|
|
||||||
CANBed Dual - 9
|
|
||||||
OBD-2G Dev Kit - 9
|
|
||||||
OBD-II GPS Kit - 9
|
|
||||||
Hud Dev Kit - 9
|
|
||||||
|
|
||||||
Seeed Studio CAN-Bus Breakout Board for XIAO and QT Py - D7
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define SPI_CS_PIN 9
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit Atemga32U4 version
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit RP2040 version
|
|
||||||
// pinMode(12, OUTPUT);
|
|
||||||
// digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
|
|
||||||
{
|
|
||||||
Serial.println("CAN BUS FAIL!");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN BUS OK!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
Serial.println("-----------------------------");
|
|
||||||
Serial.print("Get data from ID: ");
|
|
||||||
Serial.println(canId, HEX);
|
|
||||||
|
|
||||||
for(int i = 0; i<len; i++) // print the data
|
|
||||||
{
|
|
||||||
Serial.print(buf[i], HEX);
|
|
||||||
Serial.print("\t");
|
|
||||||
}
|
|
||||||
Serial.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
|
@ -1,75 +0,0 @@
|
||||||
/* send a frame from can bus
|
|
||||||
|
|
||||||
CAN Baudrate,
|
|
||||||
|
|
||||||
#define CAN_5KBPS 1
|
|
||||||
#define CAN_10KBPS 2
|
|
||||||
#define CAN_20KBPS 3
|
|
||||||
#define CAN_25KBPS 4
|
|
||||||
#define CAN_31K25BPS 5
|
|
||||||
#define CAN_33KBPS 6
|
|
||||||
#define CAN_40KBPS 7
|
|
||||||
#define CAN_50KBPS 8
|
|
||||||
#define CAN_80KBPS 9
|
|
||||||
#define CAN_83K3BPS 10
|
|
||||||
#define CAN_95KBPS 11
|
|
||||||
#define CAN_100KBPS 12
|
|
||||||
#define CAN_125KBPS 13
|
|
||||||
#define CAN_200KBPS 14
|
|
||||||
#define CAN_250KBPS 15
|
|
||||||
#define CAN_500KBPS 16
|
|
||||||
#define CAN_666KBPS 17
|
|
||||||
#define CAN_1000KBPS 18
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
/* Please modify SPI_CS_PIN to adapt to your board.
|
|
||||||
|
|
||||||
CANBed V1 - 17
|
|
||||||
CANBed M0 - 3
|
|
||||||
CAN Bus Shield - 9
|
|
||||||
CANBed 2040 - 9
|
|
||||||
CANBed Dual - 9
|
|
||||||
OBD-2G Dev Kit - 9
|
|
||||||
OBD-II GPS Kit - 9
|
|
||||||
Hud Dev Kit - 9
|
|
||||||
|
|
||||||
Seeed Studio CAN-Bus Breakout Board for XIAO and QT Py - D7
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SPI_CS_PIN 9
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit Atemga32U4 version
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit RP2040 version
|
|
||||||
// pinMode(12, OUTPUT);
|
|
||||||
// digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
|
|
||||||
{
|
|
||||||
Serial.println("CAN BUS FAIL!");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN BUS OK!");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
CAN.sendMsgBuf(0x00, 0, 8, stmp);
|
|
||||||
delay(100); // send data per 100ms
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
/* receive a frame from can bus with mask and filter setting
|
|
||||||
|
|
||||||
CAN Baudrate,
|
|
||||||
|
|
||||||
#define CAN_5KBPS 1
|
|
||||||
#define CAN_10KBPS 2
|
|
||||||
#define CAN_20KBPS 3
|
|
||||||
#define CAN_25KBPS 4
|
|
||||||
#define CAN_31K25BPS 5
|
|
||||||
#define CAN_33KBPS 6
|
|
||||||
#define CAN_40KBPS 7
|
|
||||||
#define CAN_50KBPS 8
|
|
||||||
#define CAN_80KBPS 9
|
|
||||||
#define CAN_83K3BPS 10
|
|
||||||
#define CAN_95KBPS 11
|
|
||||||
#define CAN_100KBPS 12
|
|
||||||
#define CAN_125KBPS 13
|
|
||||||
#define CAN_200KBPS 14
|
|
||||||
#define CAN_250KBPS 15
|
|
||||||
#define CAN_500KBPS 16
|
|
||||||
#define CAN_666KBPS 17
|
|
||||||
#define CAN_1000KBPS 18
|
|
||||||
|
|
||||||
CANBed V1: https://www.longan-labs.cc/1030008.html
|
|
||||||
CANBed M0: https://www.longan-labs.cc/1030014.html
|
|
||||||
CAN Bus Shield: https://www.longan-labs.cc/1030016.html
|
|
||||||
OBD-II CAN Bus GPS Dev Kit: https://www.longan-labs.cc/1030003.html
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <SPI.h>
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
|
|
||||||
/* Please modify SPI_CS_PIN to adapt to your board.
|
|
||||||
|
|
||||||
CANBed V1 - 17
|
|
||||||
CANBed M0 - 3
|
|
||||||
CAN Bus Shield - 9
|
|
||||||
CANBed 2040 - 9
|
|
||||||
CANBed Dual - 9
|
|
||||||
OBD-2G Dev Kit - 9
|
|
||||||
OBD-II GPS Kit - 9
|
|
||||||
Hud Dev Kit - 9
|
|
||||||
|
|
||||||
Seeed Studio CAN-Bus Breakout Board for XIAO and QT Py - D7
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SPI_CS_PIN 9
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
unsigned char flagRecv = 0;
|
|
||||||
unsigned char len = 0;
|
|
||||||
unsigned char buf[8];
|
|
||||||
char str[20];
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit Atemga32U4 version
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit RP2040 version
|
|
||||||
// pinMode(12, OUTPUT);
|
|
||||||
// digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
|
|
||||||
{
|
|
||||||
Serial.println("CAN BUS FAIL!");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN BUS OK!");
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set mask, set both the mask to 0x3ff
|
|
||||||
*/
|
|
||||||
CAN.init_Mask(0, 0, 0x3ff); // there are 2 mask in mcp2515, you need to set both of them
|
|
||||||
CAN.init_Mask(1, 0, 0x3ff);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* set filter, we can receive id from 0x04 ~ 0x09
|
|
||||||
*/
|
|
||||||
CAN.init_Filt(0, 0, 0x04); // there are 6 filter in mcp2515
|
|
||||||
CAN.init_Filt(1, 0, 0x05); // there are 6 filter in mcp2515
|
|
||||||
|
|
||||||
CAN.init_Filt(2, 0, 0x06); // there are 6 filter in mcp2515
|
|
||||||
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 loop()
|
|
||||||
{
|
|
||||||
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: ");
|
|
||||||
Serial.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.println();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
|
@ -1,85 +0,0 @@
|
||||||
/* demo: set_mask_filter_send
|
|
||||||
this demo will show you how to use mask and filter
|
|
||||||
|
|
||||||
CAN Baudrate,
|
|
||||||
|
|
||||||
#define CAN_5KBPS 1
|
|
||||||
#define CAN_10KBPS 2
|
|
||||||
#define CAN_20KBPS 3
|
|
||||||
#define CAN_25KBPS 4
|
|
||||||
#define CAN_31K25BPS 5
|
|
||||||
#define CAN_33KBPS 6
|
|
||||||
#define CAN_40KBPS 7
|
|
||||||
#define CAN_50KBPS 8
|
|
||||||
#define CAN_80KBPS 9
|
|
||||||
#define CAN_83K3BPS 10
|
|
||||||
#define CAN_95KBPS 11
|
|
||||||
#define CAN_100KBPS 12
|
|
||||||
#define CAN_125KBPS 13
|
|
||||||
#define CAN_200KBPS 14
|
|
||||||
#define CAN_250KBPS 15
|
|
||||||
#define CAN_500KBPS 16
|
|
||||||
#define CAN_666KBPS 17
|
|
||||||
#define CAN_1000KBPS 18
|
|
||||||
|
|
||||||
CANBed V1: https://www.longan-labs.cc/1030008.html
|
|
||||||
CANBed M0: https://www.longan-labs.cc/1030014.html
|
|
||||||
CAN Bus Shield: https://www.longan-labs.cc/1030016.html
|
|
||||||
OBD-II CAN Bus GPS Dev Kit: https://www.longan-labs.cc/1030003.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <mcp_canbus.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
/* Please modify SPI_CS_PIN to adapt to your board.
|
|
||||||
|
|
||||||
CANBed V1 - 17
|
|
||||||
CANBed M0 - 3
|
|
||||||
CAN Bus Shield - 9
|
|
||||||
CANBed 2040 - 9
|
|
||||||
CANBed Dual - 9
|
|
||||||
OBD-2G Dev Kit - 9
|
|
||||||
OBD-II GPS Kit - 9
|
|
||||||
Hud Dev Kit - 9
|
|
||||||
|
|
||||||
Seeed Studio CAN-Bus Breakout Board for XIAO and QT Py - D7
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define SPI_CS_PIN 9
|
|
||||||
|
|
||||||
MCP_CAN CAN(SPI_CS_PIN); // Set CS pin
|
|
||||||
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
Serial.begin(115200);
|
|
||||||
while(!Serial);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit Atemga32U4 version
|
|
||||||
// pinMode(A3, OUTPUT);
|
|
||||||
// digitalWrite(A3, HIGH);
|
|
||||||
|
|
||||||
// below code need for OBD-II GPS Dev Kit RP2040 version
|
|
||||||
// pinMode(12, OUTPUT);
|
|
||||||
// digitalWrite(12, HIGH);
|
|
||||||
|
|
||||||
while (CAN_OK != CAN.begin(CAN_500KBPS)) // init can bus : baudrate = 500k
|
|
||||||
{
|
|
||||||
Serial.println("CAN BUS FAIL!");
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
Serial.println("CAN BUS OK!");
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
|
|
||||||
|
|
||||||
void loop()
|
|
||||||
{
|
|
||||||
for(int id=0; id<10; id++)
|
|
||||||
{
|
|
||||||
memset(stmp, id, sizeof(stmp)); // set id to send data buff
|
|
||||||
CAN.sendMsgBuf(id, 0, sizeof(stmp), stmp);
|
|
||||||
delay(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// END FILE
|
|
|
@ -1,55 +0,0 @@
|
||||||
#######################################
|
|
||||||
# Syntax Coloring Map For debug_lvc
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
|
||||||
#######################################
|
|
||||||
MCP_CAN KEYWORD1
|
|
||||||
mcp_can_dfs KEYWORD1
|
|
||||||
mcp_can KEYWORD1
|
|
||||||
CAN KEYWORD1
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
begin KEYWORD2
|
|
||||||
init_Mask KEYWORD2
|
|
||||||
init_Filt KEYWORD2
|
|
||||||
sendMsgBuf KEYWORD2
|
|
||||||
readMsgBuf KEYWORD2
|
|
||||||
checkReceive KEYWORD2
|
|
||||||
checkError KEYWORD2
|
|
||||||
getCanId KEYWORD2
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
|
||||||
#######################################
|
|
||||||
CAN_5KBPS LITERAL1
|
|
||||||
CAN_10KBPS LITERAL1
|
|
||||||
CAN_20KBPS LITERAL1
|
|
||||||
CAN_25KBPS LITERAL1
|
|
||||||
CAN_31KBPS LITERAL1
|
|
||||||
CAN_33KBPS LITERAL1
|
|
||||||
CAN_40KBPS LITERAL1
|
|
||||||
CAN_50KBPS LITERAL1
|
|
||||||
CAN_80KBPS LITERAL1
|
|
||||||
CAN_83KBPS LITERAL1
|
|
||||||
CAN_95KBPS LITERAL1
|
|
||||||
CAN_100KBPS LITERAL1
|
|
||||||
CAN_125KBPS LITERAL1
|
|
||||||
CAN_200KBPS LITERAL1
|
|
||||||
CAN_250KBPS LITERAL1
|
|
||||||
CAN_500KBPS LITERAL1
|
|
||||||
CAN_666KBPS LITERAL1
|
|
||||||
CAN_1000KBPS LITERAL1
|
|
||||||
CAN_OK LITERAL1
|
|
||||||
CAN_FAILINIT LITERAL1
|
|
||||||
CAN_FAILTX LITERAL1
|
|
||||||
CAN_MSGAVAIL LITERAL1
|
|
||||||
CAN_NOMSG LITERAL1
|
|
||||||
CAN_CTRLERROR LITERAL1
|
|
||||||
CAN_GETTXBFTIMEOUT LITERAL1
|
|
||||||
CAN_SENDMSGTIMEOUT LITERAL1
|
|
||||||
CAN_FAIL LITERAL1
|
|
||||||
SPI_CS_PIN LITERAL1
|
|
|
@ -1,13 +0,0 @@
|
||||||
{
|
|
||||||
"name": "CAN_BUS_Shield",
|
|
||||||
"keywords": "can, bus, mcp2515, MCP-2515",
|
|
||||||
"description": "Arduino Library for MCP2515",
|
|
||||||
"repository":
|
|
||||||
{
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/Longan-Labs/Aruino_CAN_BUS_MCP2515.git"
|
|
||||||
},
|
|
||||||
"version": "1.0.0",
|
|
||||||
"frameworks": "arduino",
|
|
||||||
"platforms": "atmelavr"
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
name=mcp_canbus
|
|
||||||
version=1.0.0
|
|
||||||
author=Longan Labs
|
|
||||||
maintainer=Longan Labs
|
|
||||||
sentence=A library for MCP2515
|
|
||||||
paragraph=Arduino CAN Bus Library for MCP2515
|
|
||||||
category=Communication
|
|
||||||
url=https://github.com/Longan-Labs/Aruino_CAN_BUS_MCP2515
|
|
||||||
architectures=*
|
|
|
@ -1,356 +0,0 @@
|
||||||
/*
|
|
||||||
mcp_can_dfs.h
|
|
||||||
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef _MCP2515DFS_H_
|
|
||||||
#define _MCP2515DFS_H_
|
|
||||||
|
|
||||||
#include <Arduino.h>
|
|
||||||
#include <SPI.h>
|
|
||||||
//#include <inttypes.h>
|
|
||||||
|
|
||||||
|
|
||||||
// if print debug information
|
|
||||||
#define DEBUG_EN 0
|
|
||||||
|
|
||||||
// Begin mt
|
|
||||||
|
|
||||||
#define TIMEOUTVALUE 50
|
|
||||||
#define MCP_SIDH 0
|
|
||||||
#define MCP_SIDL 1
|
|
||||||
#define MCP_EID8 2
|
|
||||||
#define MCP_EID0 3
|
|
||||||
|
|
||||||
#define MCP_TXB_EXIDE_M 0x08 // In TXBnSIDL
|
|
||||||
#define MCP_DLC_MASK 0x0F // 4 LSBits
|
|
||||||
#define MCP_RTR_MASK 0x40 // (1<<6) Bit 6
|
|
||||||
|
|
||||||
#define MCP_RXB_RX_ANY 0x60
|
|
||||||
#define MCP_RXB_RX_EXT 0x40
|
|
||||||
#define MCP_RXB_RX_STD 0x20
|
|
||||||
#define MCP_RXB_RX_STDEXT 0x00
|
|
||||||
#define MCP_RXB_RX_MASK 0x60
|
|
||||||
#define MCP_RXB_BUKT_MASK (1<<2)
|
|
||||||
|
|
||||||
|
|
||||||
// Bits in the TXBnCTRL registers.
|
|
||||||
|
|
||||||
#define MCP_TXB_TXBUFE_M 0x80
|
|
||||||
#define MCP_TXB_ABTF_M 0x40
|
|
||||||
#define MCP_TXB_MLOA_M 0x20
|
|
||||||
#define MCP_TXB_TXERR_M 0x10
|
|
||||||
#define MCP_TXB_TXREQ_M 0x08
|
|
||||||
#define MCP_TXB_TXIE_M 0x04
|
|
||||||
#define MCP_TXB_TXP10_M 0x03
|
|
||||||
|
|
||||||
#define MCP_TXB_RTR_M 0x40 // In TXBnDLC
|
|
||||||
#define MCP_RXB_IDE_M 0x08 // In RXBnSIDL
|
|
||||||
#define MCP_RXB_RTR_M 0x40 // In RXBnDLC
|
|
||||||
|
|
||||||
#define MCP_STAT_RXIF_MASK (0x03)
|
|
||||||
#define MCP_STAT_RX0IF (1<<0)
|
|
||||||
#define MCP_STAT_RX1IF (1<<1)
|
|
||||||
|
|
||||||
#define MCP_EFLG_RX1OVR (1<<7)
|
|
||||||
#define MCP_EFLG_RX0OVR (1<<6)
|
|
||||||
#define MCP_EFLG_TXBO (1<<5)
|
|
||||||
#define MCP_EFLG_TXEP (1<<4)
|
|
||||||
#define MCP_EFLG_RXEP (1<<3)
|
|
||||||
#define MCP_EFLG_TXWAR (1<<2)
|
|
||||||
#define MCP_EFLG_RXWAR (1<<1)
|
|
||||||
#define MCP_EFLG_EWARN (1<<0)
|
|
||||||
#define MCP_EFLG_ERRORMASK (0xF8) // 5 MS-Bits
|
|
||||||
|
|
||||||
// Define MCP2515 register addresses
|
|
||||||
|
|
||||||
#define MCP_RXF0SIDH 0x00
|
|
||||||
#define MCP_RXF0SIDL 0x01
|
|
||||||
#define MCP_RXF0EID8 0x02
|
|
||||||
#define MCP_RXF0EID0 0x03
|
|
||||||
#define MCP_RXF1SIDH 0x04
|
|
||||||
#define MCP_RXF1SIDL 0x05
|
|
||||||
#define MCP_RXF1EID8 0x06
|
|
||||||
#define MCP_RXF1EID0 0x07
|
|
||||||
#define MCP_RXF2SIDH 0x08
|
|
||||||
#define MCP_RXF2SIDL 0x09
|
|
||||||
#define MCP_RXF2EID8 0x0A
|
|
||||||
#define MCP_RXF2EID0 0x0B
|
|
||||||
#define MCP_CANSTAT 0x0E
|
|
||||||
#define MCP_CANCTRL 0x0F
|
|
||||||
#define MCP_RXF3SIDH 0x10
|
|
||||||
#define MCP_RXF3SIDL 0x11
|
|
||||||
#define MCP_RXF3EID8 0x12
|
|
||||||
#define MCP_RXF3EID0 0x13
|
|
||||||
#define MCP_RXF4SIDH 0x14
|
|
||||||
#define MCP_RXF4SIDL 0x15
|
|
||||||
#define MCP_RXF4EID8 0x16
|
|
||||||
#define MCP_RXF4EID0 0x17
|
|
||||||
#define MCP_RXF5SIDH 0x18
|
|
||||||
#define MCP_RXF5SIDL 0x19
|
|
||||||
#define MCP_RXF5EID8 0x1A
|
|
||||||
#define MCP_RXF5EID0 0x1B
|
|
||||||
#define MCP_TEC 0x1C
|
|
||||||
#define MCP_REC 0x1D
|
|
||||||
#define MCP_RXM0SIDH 0x20
|
|
||||||
#define MCP_RXM0SIDL 0x21
|
|
||||||
#define MCP_RXM0EID8 0x22
|
|
||||||
#define MCP_RXM0EID0 0x23
|
|
||||||
#define MCP_RXM1SIDH 0x24
|
|
||||||
#define MCP_RXM1SIDL 0x25
|
|
||||||
#define MCP_RXM1EID8 0x26
|
|
||||||
#define MCP_RXM1EID0 0x27
|
|
||||||
#define MCP_CNF3 0x28
|
|
||||||
#define MCP_CNF2 0x29
|
|
||||||
#define MCP_CNF1 0x2A
|
|
||||||
#define MCP_CANINTE 0x2B
|
|
||||||
#define MCP_CANINTF 0x2C
|
|
||||||
#define MCP_EFLG 0x2D
|
|
||||||
#define MCP_TXB0CTRL 0x30
|
|
||||||
#define MCP_TXB1CTRL 0x40
|
|
||||||
#define MCP_TXB2CTRL 0x50
|
|
||||||
#define MCP_RXB0CTRL 0x60
|
|
||||||
#define MCP_RXB0SIDH 0x61
|
|
||||||
#define MCP_RXB1CTRL 0x70
|
|
||||||
#define MCP_RXB1SIDH 0x71
|
|
||||||
#define MCP_TX_INT 0x1C // Enable all transmit interrup ts
|
|
||||||
#define MCP_TX01_INT 0x0C // Enable TXB0 and TXB1 interru pts
|
|
||||||
#define MCP_RX_INT 0x03 // Enable receive interrupts
|
|
||||||
#define MCP_NO_INT 0x00 // Disable all interrupts
|
|
||||||
|
|
||||||
#define MCP_TX01_MASK 0x14
|
|
||||||
#define MCP_TX_MASK 0x54
|
|
||||||
|
|
||||||
|
|
||||||
// Define SPI Instruction Set
|
|
||||||
|
|
||||||
#define MCP_WRITE 0x02
|
|
||||||
#define MCP_READ 0x03
|
|
||||||
#define MCP_BITMOD 0x05
|
|
||||||
#define MCP_LOAD_TX0 0x40
|
|
||||||
#define MCP_LOAD_TX1 0x42
|
|
||||||
#define MCP_LOAD_TX2 0x44
|
|
||||||
|
|
||||||
#define MCP_RTS_TX0 0x81
|
|
||||||
#define MCP_RTS_TX1 0x82
|
|
||||||
#define MCP_RTS_TX2 0x84
|
|
||||||
#define MCP_RTS_ALL 0x87
|
|
||||||
#define MCP_READ_RX0 0x90
|
|
||||||
#define MCP_READ_RX1 0x94
|
|
||||||
#define MCP_READ_STATUS 0xA0
|
|
||||||
#define MCP_RX_STATUS 0xB0
|
|
||||||
#define MCP_RESET 0xC0
|
|
||||||
|
|
||||||
|
|
||||||
// CANCTRL Register Values
|
|
||||||
|
|
||||||
#define MODE_NORMAL 0x00
|
|
||||||
#define MODE_SLEEP 0x20
|
|
||||||
#define MODE_LOOPBACK 0x40
|
|
||||||
#define MODE_LISTENONLY 0x60
|
|
||||||
#define MODE_CONFIG 0x80
|
|
||||||
#define MODE_POWERUP 0xE0
|
|
||||||
#define MODE_MASK 0xE0
|
|
||||||
#define ABORT_TX 0x10
|
|
||||||
#define MODE_ONESHOT 0x08
|
|
||||||
#define CLKOUT_ENABLE 0x04
|
|
||||||
#define CLKOUT_DISABLE 0x00
|
|
||||||
#define CLKOUT_PS1 0x00
|
|
||||||
#define CLKOUT_PS2 0x01
|
|
||||||
#define CLKOUT_PS4 0x02
|
|
||||||
#define CLKOUT_PS8 0x03
|
|
||||||
|
|
||||||
|
|
||||||
// CNF1 Register Values
|
|
||||||
|
|
||||||
#define SJW1 0x00
|
|
||||||
#define SJW2 0x40
|
|
||||||
#define SJW3 0x80
|
|
||||||
#define SJW4 0xC0
|
|
||||||
|
|
||||||
|
|
||||||
// CNF2 Register Values
|
|
||||||
|
|
||||||
#define BTLMODE 0x80
|
|
||||||
#define SAMPLE_1X 0x00
|
|
||||||
#define SAMPLE_3X 0x40
|
|
||||||
|
|
||||||
|
|
||||||
// CNF3 Register Values
|
|
||||||
|
|
||||||
#define SOF_ENABLE 0x80
|
|
||||||
#define SOF_DISABLE 0x00
|
|
||||||
#define WAKFIL_ENABLE 0x40
|
|
||||||
#define WAKFIL_DISABLE 0x00
|
|
||||||
|
|
||||||
|
|
||||||
// CANINTF Register Bits
|
|
||||||
|
|
||||||
#define MCP_RX0IF 0x01
|
|
||||||
#define MCP_RX1IF 0x02
|
|
||||||
#define MCP_TX0IF 0x04
|
|
||||||
#define MCP_TX1IF 0x08
|
|
||||||
#define MCP_TX2IF 0x10
|
|
||||||
#define MCP_ERRIF 0x20
|
|
||||||
#define MCP_WAKIF 0x40
|
|
||||||
#define MCP_MERRF 0x80
|
|
||||||
|
|
||||||
// speed 16M
|
|
||||||
|
|
||||||
#define MCP_16MHz_1000kBPS_CFG1 (0x00)
|
|
||||||
#define MCP_16MHz_1000kBPS_CFG2 (0xD0)
|
|
||||||
#define MCP_16MHz_1000kBPS_CFG3 (0x82)
|
|
||||||
|
|
||||||
#define MCP_16MHz_500kBPS_CFG1 (0x00)
|
|
||||||
#define MCP_16MHz_500kBPS_CFG2 (0xF0)
|
|
||||||
#define MCP_16MHz_500kBPS_CFG3 (0x86)
|
|
||||||
|
|
||||||
#define MCP_16MHz_250kBPS_CFG1 (0x41)
|
|
||||||
#define MCP_16MHz_250kBPS_CFG2 (0xF1)
|
|
||||||
#define MCP_16MHz_250kBPS_CFG3 (0x85)
|
|
||||||
|
|
||||||
#define MCP_16MHz_200kBPS_CFG1 (0x01)
|
|
||||||
#define MCP_16MHz_200kBPS_CFG2 (0xFA)
|
|
||||||
#define MCP_16MHz_200kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_125kBPS_CFG1 (0x03)
|
|
||||||
#define MCP_16MHz_125kBPS_CFG2 (0xF0)
|
|
||||||
#define MCP_16MHz_125kBPS_CFG3 (0x86)
|
|
||||||
|
|
||||||
#define MCP_16MHz_100kBPS_CFG1 (0x03)
|
|
||||||
#define MCP_16MHz_100kBPS_CFG2 (0xFA)
|
|
||||||
#define MCP_16MHz_100kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_95kBPS_CFG1 (0x03)
|
|
||||||
#define MCP_16MHz_95kBPS_CFG2 (0xAD)
|
|
||||||
#define MCP_16MHz_95kBPS_CFG3 (0x07)
|
|
||||||
|
|
||||||
#define MCP_16MHz_83k3BPS_CFG1 (0x03)
|
|
||||||
#define MCP_16MHz_83k3BPS_CFG2 (0xBE)
|
|
||||||
#define MCP_16MHz_83k3BPS_CFG3 (0x07)
|
|
||||||
|
|
||||||
#define MCP_16MHz_80kBPS_CFG1 (0x03)
|
|
||||||
#define MCP_16MHz_80kBPS_CFG2 (0xFF)
|
|
||||||
#define MCP_16MHz_80kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_50kBPS_CFG1 (0x07)
|
|
||||||
#define MCP_16MHz_50kBPS_CFG2 (0xFA)
|
|
||||||
#define MCP_16MHz_50kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_40kBPS_CFG1 (0x07)
|
|
||||||
#define MCP_16MHz_40kBPS_CFG2 (0xFF)
|
|
||||||
#define MCP_16MHz_40kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_33kBPS_CFG1 (0x09)
|
|
||||||
#define MCP_16MHz_33kBPS_CFG2 (0xBE)
|
|
||||||
#define MCP_16MHz_33kBPS_CFG3 (0x07)
|
|
||||||
|
|
||||||
#define MCP_16MHz_31k25BPS_CFG1 (0x0F)
|
|
||||||
#define MCP_16MHz_31k25BPS_CFG2 (0xF1)
|
|
||||||
#define MCP_16MHz_31k25BPS_CFG3 (0x85)
|
|
||||||
|
|
||||||
#define MCP_16MHz_25kBPS_CFG1 (0X0F)
|
|
||||||
#define MCP_16MHz_25kBPS_CFG2 (0XBA)
|
|
||||||
#define MCP_16MHz_25kBPS_CFG3 (0X07)
|
|
||||||
|
|
||||||
#define MCP_16MHz_20kBPS_CFG1 (0x0F)
|
|
||||||
#define MCP_16MHz_20kBPS_CFG2 (0xFF)
|
|
||||||
#define MCP_16MHz_20kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_10kBPS_CFG1 (0x1F)
|
|
||||||
#define MCP_16MHz_10kBPS_CFG2 (0xFF)
|
|
||||||
#define MCP_16MHz_10kBPS_CFG3 (0x87)
|
|
||||||
|
|
||||||
#define MCP_16MHz_5kBPS_CFG1 (0x3F)
|
|
||||||
#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)
|
|
||||||
|
|
||||||
|
|
||||||
#define MCPDEBUG (0)
|
|
||||||
#define MCPDEBUG_TXBUF (0)
|
|
||||||
#define MCP_N_TXBUFFERS (3)
|
|
||||||
|
|
||||||
#define MCP_RXBUF_0 (MCP_RXB0SIDH)
|
|
||||||
#define MCP_RXBUF_1 (MCP_RXB1SIDH)
|
|
||||||
|
|
||||||
#define MCP2515_SELECT() digitalWrite(SPICS, LOW)
|
|
||||||
#define MCP2515_UNSELECT() digitalWrite(SPICS, HIGH)
|
|
||||||
|
|
||||||
#define MCP2515_OK (0)
|
|
||||||
#define MCP2515_FAIL (1)
|
|
||||||
#define MCP_ALLTXBUSY (2)
|
|
||||||
|
|
||||||
#define CANDEBUG 1
|
|
||||||
|
|
||||||
#define CANUSELOOP 0
|
|
||||||
|
|
||||||
#define CANSENDTIMEOUT (200) // milliseconds
|
|
||||||
|
|
||||||
|
|
||||||
// initial value of gCANAutoProcess
|
|
||||||
|
|
||||||
#define CANAUTOPROCESS (1)
|
|
||||||
#define CANAUTOON (1)
|
|
||||||
#define CANAUTOOFF (0)
|
|
||||||
#define CAN_STDID (0)
|
|
||||||
#define CAN_EXTID (1)
|
|
||||||
#define CANDEFAULTIDENT (0x55CC)
|
|
||||||
#define CANDEFAULTIDENTEXT (CAN_EXTID)
|
|
||||||
|
|
||||||
#define CAN_5KBPS 1
|
|
||||||
#define CAN_10KBPS 2
|
|
||||||
#define CAN_20KBPS 3
|
|
||||||
#define CAN_25KBPS 4
|
|
||||||
#define CAN_31K25BPS 5
|
|
||||||
#define CAN_33KBPS 6
|
|
||||||
#define CAN_40KBPS 7
|
|
||||||
#define CAN_50KBPS 8
|
|
||||||
#define CAN_80KBPS 9
|
|
||||||
#define CAN_83K3BPS 10
|
|
||||||
#define CAN_95KBPS 11
|
|
||||||
#define CAN_100KBPS 12
|
|
||||||
#define CAN_125KBPS 13
|
|
||||||
#define CAN_200KBPS 14
|
|
||||||
#define CAN_250KBPS 15
|
|
||||||
#define CAN_500KBPS 16
|
|
||||||
#define CAN_666KBPS 17
|
|
||||||
#define CAN_1000KBPS 18
|
|
||||||
|
|
||||||
#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)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*********************************************************************************************************
|
|
||||||
END FILE
|
|
||||||
*********************************************************************************************************/
|
|
|
@ -1,971 +0,0 @@
|
||||||
/*
|
|
||||||
mcp_can.cpp
|
|
||||||
|
|
||||||
Author:Stephen Lo
|
|
||||||
2014-1-16
|
|
||||||
|
|
||||||
Contributor:
|
|
||||||
|
|
||||||
Cory J. Fowler
|
|
||||||
Latonita
|
|
||||||
Woodward1
|
|
||||||
Mehtajaghvi
|
|
||||||
BykeBlast
|
|
||||||
TheRo0T
|
|
||||||
Tsipizic
|
|
||||||
ralfEdmund
|
|
||||||
Nathancheek
|
|
||||||
BlueAndi
|
|
||||||
Adlerweb
|
|
||||||
Btetz
|
|
||||||
Hurvajs
|
|
||||||
xboxpro1
|
|
||||||
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "mcp_canbus.h"
|
|
||||||
|
|
||||||
#define spi_readwrite SPI.transfer
|
|
||||||
#define spi_read() spi_readwrite(0x00)
|
|
||||||
#define SPI_BEGIN() SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0))
|
|
||||||
#define SPI_END() SPI.endTransaction()
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_reset
|
|
||||||
** Descriptions: reset the device
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_reset(void)
|
|
||||||
{
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_RESET);
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
delay(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_readRegister
|
|
||||||
** Descriptions: read register
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::mcp2515_readRegister(const byte address)
|
|
||||||
{
|
|
||||||
byte ret;
|
|
||||||
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_READ);
|
|
||||||
spi_readwrite(address);
|
|
||||||
ret = spi_read();
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_readRegisterS
|
|
||||||
** Descriptions: read registerS
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_readRegisterS(const byte address, byte values[], const byte n)
|
|
||||||
{
|
|
||||||
byte i;
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_READ);
|
|
||||||
spi_readwrite(address);
|
|
||||||
// mcp2515 has auto-increment of address-pointer
|
|
||||||
for(i=0; i<n && i<CAN_MAX_CHAR_IN_MESSAGE; i++)
|
|
||||||
{
|
|
||||||
values[i] = spi_read();
|
|
||||||
}
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_setRegister
|
|
||||||
** Descriptions: set register
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_setRegister(const byte address, const byte value)
|
|
||||||
{
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_WRITE);
|
|
||||||
spi_readwrite(address);
|
|
||||||
spi_readwrite(value);
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_setRegisterS
|
|
||||||
** Descriptions: set registerS
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_setRegisterS(const byte address, const byte values[], const byte n)
|
|
||||||
{
|
|
||||||
byte i;
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_WRITE);
|
|
||||||
spi_readwrite(address);
|
|
||||||
|
|
||||||
for(i=0; i<n; i++)
|
|
||||||
{
|
|
||||||
spi_readwrite(values[i]);
|
|
||||||
}
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_modifyRegister
|
|
||||||
** Descriptions: set bit of one register
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_modifyRegister(const byte address, const byte mask, const byte data)
|
|
||||||
{
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_BITMOD);
|
|
||||||
spi_readwrite(address);
|
|
||||||
spi_readwrite(mask);
|
|
||||||
spi_readwrite(data);
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_readStatus
|
|
||||||
** Descriptions: read mcp2515's Status
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::mcp2515_readStatus(void)
|
|
||||||
{
|
|
||||||
byte i;
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_BEGIN();
|
|
||||||
#endif
|
|
||||||
MCP2515_SELECT();
|
|
||||||
spi_readwrite(MCP_READ_STATUS);
|
|
||||||
i = spi_read();
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
#ifdef SPI_HAS_TRANSACTION
|
|
||||||
SPI_END();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_setCANCTRL_Mode
|
|
||||||
** Descriptions: set control mode
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::mcp2515_setCANCTRL_Mode(const byte newmode)
|
|
||||||
{
|
|
||||||
byte i;
|
|
||||||
|
|
||||||
mcp2515_modifyRegister(MCP_CANCTRL, MODE_MASK, newmode);
|
|
||||||
|
|
||||||
i = mcp2515_readRegister(MCP_CANCTRL);
|
|
||||||
i &= MODE_MASK;
|
|
||||||
|
|
||||||
if(i == newmode)
|
|
||||||
{
|
|
||||||
return MCP2515_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MCP2515_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_configRate
|
|
||||||
** Descriptions: set boadrate
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::mcp2515_configRate(const byte canSpeed)
|
|
||||||
{
|
|
||||||
byte set, cfg1, cfg2, cfg3;
|
|
||||||
set = 1;
|
|
||||||
switch (canSpeed)
|
|
||||||
{
|
|
||||||
case (CAN_5KBPS):
|
|
||||||
cfg1 = MCP_16MHz_5kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_5kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_5kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_10KBPS):
|
|
||||||
cfg1 = MCP_16MHz_10kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_10kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_10kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_20KBPS):
|
|
||||||
cfg1 = MCP_16MHz_20kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_20kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_20kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_25KBPS):
|
|
||||||
cfg1 = MCP_16MHz_25kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_25kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_25kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_31K25BPS):
|
|
||||||
cfg1 = MCP_16MHz_31k25BPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_31k25BPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_31k25BPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_33KBPS):
|
|
||||||
cfg1 = MCP_16MHz_33kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_33kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_33kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_40KBPS):
|
|
||||||
cfg1 = MCP_16MHz_40kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_40kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_40kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_50KBPS):
|
|
||||||
cfg1 = MCP_16MHz_50kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_50kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_50kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_80KBPS):
|
|
||||||
cfg1 = MCP_16MHz_80kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_80kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_80kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_83K3BPS):
|
|
||||||
cfg1 = MCP_16MHz_83k3BPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_83k3BPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_83k3BPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_95KBPS):
|
|
||||||
cfg1 = MCP_16MHz_95kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_95kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_95kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_100KBPS):
|
|
||||||
cfg1 = MCP_16MHz_100kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_100kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_100kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_125KBPS):
|
|
||||||
cfg1 = MCP_16MHz_125kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_125kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_125kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_200KBPS):
|
|
||||||
cfg1 = MCP_16MHz_200kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_200kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_200kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_250KBPS):
|
|
||||||
cfg1 = MCP_16MHz_250kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_250kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_250kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_500KBPS):
|
|
||||||
cfg1 = MCP_16MHz_500kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_500kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_500kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_666KBPS):
|
|
||||||
cfg1 = MCP_16MHz_666kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_666kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_666kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case (CAN_1000KBPS):
|
|
||||||
cfg1 = MCP_16MHz_1000kBPS_CFG1;
|
|
||||||
cfg2 = MCP_16MHz_1000kBPS_CFG2;
|
|
||||||
cfg3 = MCP_16MHz_1000kBPS_CFG3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
set = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(set) {
|
|
||||||
mcp2515_setRegister(MCP_CNF1, cfg1);
|
|
||||||
mcp2515_setRegister(MCP_CNF2, cfg2);
|
|
||||||
mcp2515_setRegister(MCP_CNF3, cfg3);
|
|
||||||
return MCP2515_OK;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return MCP2515_FAIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_initCANBuffers
|
|
||||||
** Descriptions: init canbuffers
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_initCANBuffers(void)
|
|
||||||
{
|
|
||||||
byte i, a1, a2, a3;
|
|
||||||
|
|
||||||
a1 = MCP_TXB0CTRL;
|
|
||||||
a2 = MCP_TXB1CTRL;
|
|
||||||
a3 = MCP_TXB2CTRL;
|
|
||||||
for(i = 0; i < 14; i++) // in-buffer loop
|
|
||||||
{
|
|
||||||
mcp2515_setRegister(a1, 0);
|
|
||||||
mcp2515_setRegister(a2, 0);
|
|
||||||
mcp2515_setRegister(a3, 0);
|
|
||||||
a1++;
|
|
||||||
a2++;
|
|
||||||
a3++;
|
|
||||||
}
|
|
||||||
mcp2515_setRegister(MCP_RXB0CTRL, 0);
|
|
||||||
mcp2515_setRegister(MCP_RXB1CTRL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_init
|
|
||||||
** Descriptions: init the device
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::mcp2515_init(const byte canSpeed)
|
|
||||||
{
|
|
||||||
|
|
||||||
byte res;
|
|
||||||
|
|
||||||
mcp2515_reset();
|
|
||||||
|
|
||||||
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
|
|
||||||
if(res > 0)
|
|
||||||
{
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter setting mode fall\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter setting mode success \r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// set boadrate
|
|
||||||
if(mcp2515_configRate(canSpeed))
|
|
||||||
{
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("set rate fall!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("set rate success!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(res == MCP2515_OK) {
|
|
||||||
|
|
||||||
// init canbuffers
|
|
||||||
mcp2515_initCANBuffers();
|
|
||||||
|
|
||||||
// interrupt mode
|
|
||||||
mcp2515_setRegister(MCP_CANINTE, MCP_RX0IF | MCP_RX1IF);
|
|
||||||
|
|
||||||
#if (DEBUG_RXANY==1)
|
|
||||||
// enable both receive-buffers to receive any message and enable rollover
|
|
||||||
mcp2515_modifyRegister(MCP_RXB0CTRL,
|
|
||||||
MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
|
|
||||||
MCP_RXB_RX_ANY | MCP_RXB_BUKT_MASK);
|
|
||||||
mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
|
|
||||||
MCP_RXB_RX_ANY);
|
|
||||||
#else
|
|
||||||
// enable both receive-buffers to receive messages with std. and ext. identifiers and enable rollover
|
|
||||||
mcp2515_modifyRegister(MCP_RXB0CTRL,
|
|
||||||
MCP_RXB_RX_MASK | MCP_RXB_BUKT_MASK,
|
|
||||||
MCP_RXB_RX_STDEXT | MCP_RXB_BUKT_MASK);
|
|
||||||
mcp2515_modifyRegister(MCP_RXB1CTRL, MCP_RXB_RX_MASK,
|
|
||||||
MCP_RXB_RX_STDEXT);
|
|
||||||
#endif
|
|
||||||
// enter normal mode
|
|
||||||
res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
|
|
||||||
if(res)
|
|
||||||
{
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter Normal Mode Fall!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter Normal Mode Success!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_write_id
|
|
||||||
** Descriptions: write can id
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_write_id(const byte mcp_addr, const byte ext, const unsigned long id)
|
|
||||||
{
|
|
||||||
uint16_t canid;
|
|
||||||
byte tbufdata[4];
|
|
||||||
|
|
||||||
canid = (uint16_t)(id & 0x0FFFF);
|
|
||||||
|
|
||||||
if(ext == 1)
|
|
||||||
{
|
|
||||||
tbufdata[MCP_EID0] = (byte) (canid & 0xFF);
|
|
||||||
tbufdata[MCP_EID8] = (byte) (canid >> 8);
|
|
||||||
canid = (uint16_t)(id >> 16);
|
|
||||||
tbufdata[MCP_SIDL] = (byte) (canid & 0x03);
|
|
||||||
tbufdata[MCP_SIDL] += (byte) ((canid & 0x1C) << 3);
|
|
||||||
tbufdata[MCP_SIDL] |= MCP_TXB_EXIDE_M;
|
|
||||||
tbufdata[MCP_SIDH] = (byte) (canid >> 5);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tbufdata[MCP_SIDH] = (byte) (canid >> 3);
|
|
||||||
tbufdata[MCP_SIDL] = (byte) ((canid & 0x07) << 5);
|
|
||||||
tbufdata[MCP_EID0] = 0;
|
|
||||||
tbufdata[MCP_EID8] = 0;
|
|
||||||
}
|
|
||||||
mcp2515_setRegisterS(mcp_addr, tbufdata, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_read_id
|
|
||||||
** Descriptions: read can id
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_read_id(const byte mcp_addr, byte* ext, unsigned long* id)
|
|
||||||
{
|
|
||||||
byte tbufdata[4];
|
|
||||||
|
|
||||||
*ext = 0;
|
|
||||||
*id = 0;
|
|
||||||
|
|
||||||
mcp2515_readRegisterS(mcp_addr, tbufdata, 4);
|
|
||||||
|
|
||||||
*id = (tbufdata[MCP_SIDH]<<3) + (tbufdata[MCP_SIDL]>>5);
|
|
||||||
|
|
||||||
if((tbufdata[MCP_SIDL] & MCP_TXB_EXIDE_M) == MCP_TXB_EXIDE_M)
|
|
||||||
{
|
|
||||||
// extended id
|
|
||||||
*id = (*id<<2) + (tbufdata[MCP_SIDL] & 0x03);
|
|
||||||
*id = (*id<<8) + tbufdata[MCP_EID8];
|
|
||||||
*id = (*id<<8) + tbufdata[MCP_EID0];
|
|
||||||
*ext = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_write_canMsg
|
|
||||||
** Descriptions: write msg
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_write_canMsg(const byte buffer_sidh_addr, int rtrBit)
|
|
||||||
{
|
|
||||||
byte mcp_addr;
|
|
||||||
mcp_addr = buffer_sidh_addr;
|
|
||||||
mcp2515_setRegisterS(mcp_addr+5, dta, dta_len); // write data bytes
|
|
||||||
// Serial.print("RTR: ");
|
|
||||||
// Serial.println(rtrBit);
|
|
||||||
if(rtrBit == 1) // if RTR set bit in byte
|
|
||||||
{
|
|
||||||
dta_len |= MCP_RTR_MASK;
|
|
||||||
}
|
|
||||||
mcp2515_setRegister((mcp_addr+4), dta_len); // write the RTR and DLC
|
|
||||||
mcp2515_write_id(mcp_addr, ext_flg, can_id); // write CAN id
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_read_canMsg
|
|
||||||
** Descriptions: read message
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_read_canMsg(const byte buffer_sidh_addr) // read can msg
|
|
||||||
{
|
|
||||||
byte mcp_addr, ctrl;
|
|
||||||
|
|
||||||
mcp_addr = buffer_sidh_addr;
|
|
||||||
mcp2515_read_id(mcp_addr, &ext_flg,&can_id);
|
|
||||||
ctrl = mcp2515_readRegister(mcp_addr-1);
|
|
||||||
dta_len = mcp2515_readRegister(mcp_addr+4);
|
|
||||||
|
|
||||||
rtr = (ctrl & 0x08) ? 1 : 0;
|
|
||||||
|
|
||||||
dta_len &= MCP_DLC_MASK;
|
|
||||||
mcp2515_readRegisterS(mcp_addr+5, &(dta[0]), dta_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_start_transmit
|
|
||||||
** Descriptions: start transmit
|
|
||||||
*********************************************************************************************************/
|
|
||||||
void MCP_CAN::mcp2515_start_transmit(const byte mcp_addr) // start transmit
|
|
||||||
{
|
|
||||||
mcp2515_modifyRegister(mcp_addr-1 , MCP_TXB_TXREQ_M, MCP_TXB_TXREQ_M);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: mcp2515_getNextFreeTXBuf
|
|
||||||
** Descriptions: get Next free txbuf
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::mcp2515_getNextFreeTXBuf(byte *txbuf_n) // get Next free txbuf
|
|
||||||
{
|
|
||||||
byte res, i, ctrlval;
|
|
||||||
byte ctrlregs[MCP_N_TXBUFFERS] = { MCP_TXB0CTRL, MCP_TXB1CTRL, MCP_TXB2CTRL };
|
|
||||||
|
|
||||||
res = MCP_ALLTXBUSY;
|
|
||||||
*txbuf_n = 0x00;
|
|
||||||
|
|
||||||
// check all 3 TX-Buffers
|
|
||||||
for(i=0; i<MCP_N_TXBUFFERS; i++)
|
|
||||||
{
|
|
||||||
ctrlval = mcp2515_readRegister(ctrlregs[i]);
|
|
||||||
if((ctrlval & MCP_TXB_TXREQ_M) == 0) {
|
|
||||||
*txbuf_n = ctrlregs[i]+1; // return SIDH-address of Buffer
|
|
||||||
res = MCP2515_OK;
|
|
||||||
return res; // ! function exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: set CS
|
|
||||||
** Descriptions: init CS pin and set UNSELECTED
|
|
||||||
*********************************************************************************************************/
|
|
||||||
MCP_CAN::MCP_CAN(byte _CS)
|
|
||||||
{
|
|
||||||
SPICS = _CS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: init
|
|
||||||
** Descriptions: init can and set speed
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::begin(byte speedset)
|
|
||||||
{
|
|
||||||
pinMode(SPICS, OUTPUT);
|
|
||||||
MCP2515_UNSELECT();
|
|
||||||
SPI.begin();
|
|
||||||
byte res = mcp2515_init(speedset);
|
|
||||||
return ((res == MCP2515_OK) ? CAN_OK : CAN_FAILINIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: init_Mask
|
|
||||||
** Descriptions: init canid Masks
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_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");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
|
|
||||||
if(res > 0){
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter setting mode fall\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(num == 0){
|
|
||||||
mcp2515_write_id(MCP_RXM0SIDH, ext, ulData);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(num == 1){
|
|
||||||
mcp2515_write_id(MCP_RXM1SIDH, ext, ulData);
|
|
||||||
}
|
|
||||||
else res = MCP2515_FAIL;
|
|
||||||
|
|
||||||
res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
|
|
||||||
if(res > 0){
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter normal mode fall\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("set Mask success!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: init_Filt
|
|
||||||
** Descriptions: init canid filters
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_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");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
res = mcp2515_setCANCTRL_Mode(MODE_CONFIG);
|
|
||||||
if(res > 0)
|
|
||||||
{
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter setting mode fall\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(num)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
mcp2515_write_id(MCP_RXF0SIDH, ext, ulData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
mcp2515_write_id(MCP_RXF1SIDH, ext, ulData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
mcp2515_write_id(MCP_RXF2SIDH, ext, ulData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
mcp2515_write_id(MCP_RXF3SIDH, ext, ulData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
mcp2515_write_id(MCP_RXF4SIDH, ext, ulData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
mcp2515_write_id(MCP_RXF5SIDH, ext, ulData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
res = MCP2515_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = mcp2515_setCANCTRL_Mode(MODE_NORMAL);
|
|
||||||
if(res > 0)
|
|
||||||
{
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("Enter normal mode fall\r\nSet filter fail!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#if DEBUG_EN
|
|
||||||
Serial.print("set Filter success!!\r\n");
|
|
||||||
#else
|
|
||||||
delay(10);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: setMsg
|
|
||||||
** Descriptions: set can message, such as dlc, id, dta[] and so on
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::setMsg(unsigned long id, byte ext, byte len, byte rtr, byte *pData)
|
|
||||||
{
|
|
||||||
ext_flg = ext;
|
|
||||||
can_id = id;
|
|
||||||
//dta_len = min(len, MAX_CHAR_IN_MESSAGE);
|
|
||||||
dta_len = len > MAX_CHAR_IN_MESSAGE ? MAX_CHAR_IN_MESSAGE: len;
|
|
||||||
rtr = rtr;
|
|
||||||
for(int i = 0; i<dta_len; i++)
|
|
||||||
{
|
|
||||||
dta[i] = *(pData+i);
|
|
||||||
}
|
|
||||||
return MCP2515_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: setMsg
|
|
||||||
** Descriptions: set can message, such as dlc, id, dta[] and so on
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::setMsg(unsigned long id, byte ext, byte len, byte *pData)
|
|
||||||
{
|
|
||||||
return setMsg(id, ext, len, 0, pData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: clearMsg
|
|
||||||
** Descriptions: set all message to zero
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::clearMsg()
|
|
||||||
{
|
|
||||||
can_id = 0;
|
|
||||||
dta_len = 0;
|
|
||||||
ext_flg = 0;
|
|
||||||
rtr = 0;
|
|
||||||
filhit = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i<dta_len; i++)
|
|
||||||
{
|
|
||||||
dta[i] = 0x00;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MCP2515_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: sendMsg
|
|
||||||
** Descriptions: send message
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::sendMsg(int rtrBit)
|
|
||||||
{
|
|
||||||
byte res, res1, txbuf_n;
|
|
||||||
uint16_t uiTimeOut = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
res = mcp2515_getNextFreeTXBuf(&txbuf_n); // info = addr.
|
|
||||||
uiTimeOut++;
|
|
||||||
} while (res == MCP_ALLTXBUSY && (uiTimeOut < TIMEOUTVALUE));
|
|
||||||
|
|
||||||
if(uiTimeOut == TIMEOUTVALUE)
|
|
||||||
{
|
|
||||||
return CAN_GETTXBFTIMEOUT; // get tx buff time out
|
|
||||||
}
|
|
||||||
|
|
||||||
uiTimeOut = 0;
|
|
||||||
mcp2515_write_canMsg(txbuf_n, rtrBit);
|
|
||||||
mcp2515_start_transmit(txbuf_n);
|
|
||||||
|
|
||||||
do {
|
|
||||||
uiTimeOut++;
|
|
||||||
res1= mcp2515_readRegister(txbuf_n-1 /* the ctrl reg is located at txbuf_n-1 */); // read send buff ctrl reg
|
|
||||||
res1 = res1 & 0x08;
|
|
||||||
}while(res1 && (uiTimeOut < TIMEOUTVALUE));
|
|
||||||
|
|
||||||
if(uiTimeOut == TIMEOUTVALUE) // send msg timeout
|
|
||||||
{
|
|
||||||
return CAN_SENDMSGTIMEOUT;
|
|
||||||
}
|
|
||||||
return CAN_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: sendMsgBuf
|
|
||||||
** Descriptions: send buf
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::sendMsgBuf(unsigned long id, byte ext, byte rtr, byte len, byte *buf)
|
|
||||||
{
|
|
||||||
setMsg(id, ext, len, rtr, buf);
|
|
||||||
// Serial.print("RTR00: ");
|
|
||||||
// Serial.println(rtr, HEX);
|
|
||||||
return sendMsg(rtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: sendMsgBuf
|
|
||||||
** Descriptions: send buf
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::sendMsgBuf(unsigned long id, byte ext, byte len, byte *buf)
|
|
||||||
{
|
|
||||||
setMsg(id, ext, len, buf);
|
|
||||||
return sendMsg(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: readMsg
|
|
||||||
** Descriptions: read message
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::readMsg()
|
|
||||||
{
|
|
||||||
byte stat, res;
|
|
||||||
|
|
||||||
stat = mcp2515_readStatus();
|
|
||||||
|
|
||||||
if(stat & MCP_STAT_RX0IF) // Msg in Buffer 0
|
|
||||||
{
|
|
||||||
mcp2515_read_canMsg(MCP_RXBUF_0);
|
|
||||||
mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
|
|
||||||
res = CAN_OK;
|
|
||||||
}
|
|
||||||
else if(stat & MCP_STAT_RX1IF) // Msg in Buffer 1
|
|
||||||
{
|
|
||||||
mcp2515_read_canMsg(MCP_RXBUF_1);
|
|
||||||
mcp2515_modifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
|
|
||||||
res = CAN_OK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
res = CAN_NOMSG;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: readMsgBuf
|
|
||||||
** Descriptions: read message buf
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::readMsgBuf(byte *len, byte buf[])
|
|
||||||
{
|
|
||||||
byte rc;
|
|
||||||
|
|
||||||
rc = readMsg();
|
|
||||||
|
|
||||||
if(rc == CAN_OK) {
|
|
||||||
*len = dta_len;
|
|
||||||
for(int i = 0; i<dta_len; i++)
|
|
||||||
{
|
|
||||||
buf[i] = dta[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*len = 0;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: readMsgBufID
|
|
||||||
** Descriptions: read message buf and can bus source ID
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::readMsgBufID(unsigned long *ID, byte *len, byte buf[])
|
|
||||||
{
|
|
||||||
byte rc;
|
|
||||||
rc = readMsg();
|
|
||||||
|
|
||||||
if(rc == CAN_OK) {
|
|
||||||
*len = dta_len;
|
|
||||||
*ID = can_id;
|
|
||||||
for(int i = 0; i<dta_len && i < MAX_CHAR_IN_MESSAGE; i++)
|
|
||||||
{
|
|
||||||
buf[i] = dta[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*len = 0;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: checkReceive
|
|
||||||
** Descriptions: check if got something
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::checkReceive(void)
|
|
||||||
{
|
|
||||||
byte res;
|
|
||||||
res = mcp2515_readStatus(); // RXnIF in Bit 1 and 0
|
|
||||||
return ((res & MCP_STAT_RXIF_MASK)?CAN_MSGAVAIL:CAN_NOMSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: checkError
|
|
||||||
** Descriptions: if something error
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::checkError(void)
|
|
||||||
{
|
|
||||||
byte eflg = mcp2515_readRegister(MCP_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 MCP_CAN::getCanId(void)
|
|
||||||
{
|
|
||||||
return can_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: isRemoteRequest
|
|
||||||
** Descriptions: when receive something you can check if it was a request
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::isRemoteRequest(void)
|
|
||||||
{
|
|
||||||
return rtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
** Function name: isExtendedFrame
|
|
||||||
** Descriptions: did we just receive standard 11bit frame or extended 29bit? 0 = std, 1 = ext
|
|
||||||
*********************************************************************************************************/
|
|
||||||
byte MCP_CAN::isExtendedFrame(void)
|
|
||||||
{
|
|
||||||
return ext_flg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************************
|
|
||||||
END FILE
|
|
||||||
*********************************************************************************************************/
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
mcp_can.h
|
|
||||||
|
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef _MCP2515_H_
|
|
||||||
#define _MCP2515_H_
|
|
||||||
|
|
||||||
#include "mcp_can_dfs.h"
|
|
||||||
|
|
||||||
#define MAX_CHAR_IN_MESSAGE 8
|
|
||||||
|
|
||||||
class MCP_CAN
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
|
|
||||||
byte ext_flg; // identifier xxxID
|
|
||||||
// either extended (the 29 LSB) or standard (the 11 LSB)
|
|
||||||
unsigned long can_id; // can id
|
|
||||||
byte dta_len; // data length
|
|
||||||
byte dta[MAX_CHAR_IN_MESSAGE]; // data
|
|
||||||
byte rtr; // rtr
|
|
||||||
byte filhit;
|
|
||||||
byte SPICS;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mcp2515 driver function
|
|
||||||
*/
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void mcp2515_reset(void); // reset mcp2515
|
|
||||||
|
|
||||||
byte mcp2515_readRegister(const byte address); // read mcp2515's register
|
|
||||||
|
|
||||||
void mcp2515_readRegisterS(const byte address,
|
|
||||||
byte values[],
|
|
||||||
const byte n);
|
|
||||||
void mcp2515_setRegister(const byte address, // set mcp2515's register
|
|
||||||
const byte value);
|
|
||||||
|
|
||||||
void mcp2515_setRegisterS(const byte address, // set mcp2515's registers
|
|
||||||
const byte values[],
|
|
||||||
const byte n);
|
|
||||||
|
|
||||||
void mcp2515_initCANBuffers(void);
|
|
||||||
|
|
||||||
void mcp2515_modifyRegister(const byte address, // set bit of one register
|
|
||||||
const byte mask,
|
|
||||||
const byte data);
|
|
||||||
|
|
||||||
byte mcp2515_readStatus(void); // read mcp2515's Status
|
|
||||||
byte mcp2515_setCANCTRL_Mode(const byte newmode); // set mode
|
|
||||||
byte mcp2515_configRate(const byte canSpeed); // set boadrate
|
|
||||||
byte mcp2515_init(const byte canSpeed); // mcp2515init
|
|
||||||
|
|
||||||
void mcp2515_write_id( const byte mcp_addr, // write can id
|
|
||||||
const byte ext,
|
|
||||||
const unsigned long id );
|
|
||||||
|
|
||||||
void mcp2515_read_id( const byte mcp_addr, // read can id
|
|
||||||
byte* ext,
|
|
||||||
unsigned long* id );
|
|
||||||
|
|
||||||
void mcp2515_write_canMsg( const byte buffer_sidh_addr, int rtrBit ); // write can msg
|
|
||||||
void mcp2515_read_canMsg( const byte buffer_sidh_addr); // read can msg
|
|
||||||
void mcp2515_start_transmit(const byte mcp_addr); // start transmit
|
|
||||||
byte mcp2515_getNextFreeTXBuf(byte *txbuf_n); // get Next free txbuf
|
|
||||||
|
|
||||||
/*
|
|
||||||
* can operator function
|
|
||||||
*/
|
|
||||||
|
|
||||||
byte setMsg(unsigned long id, byte ext, byte len, byte rtr, byte *pData); // set message
|
|
||||||
byte setMsg(unsigned long id, byte ext, byte len, byte *pData); // set message
|
|
||||||
byte clearMsg(); // clear all message to zero
|
|
||||||
byte readMsg(); // read message
|
|
||||||
byte sendMsg(int rtrBit); // send message
|
|
||||||
|
|
||||||
public:
|
|
||||||
MCP_CAN(byte _CS);
|
|
||||||
byte begin(byte speedset); // init can
|
|
||||||
byte init_Mask(byte num, byte ext, unsigned long ulData); // init Masks
|
|
||||||
byte init_Filt(byte num, byte ext, unsigned long ulData); // init filters
|
|
||||||
byte sendMsgBuf(unsigned long id, byte ext, byte rtr, byte len, byte *buf); // send buf
|
|
||||||
byte sendMsgBuf(unsigned long id, byte ext, byte len, byte *buf); // send buf
|
|
||||||
byte readMsgBuf(byte *len, byte *buf); // read buf
|
|
||||||
byte readMsgBufID(unsigned long *ID, byte *len, byte *buf); // read buf with object ID
|
|
||||||
byte checkReceive(void); // if something received
|
|
||||||
byte checkError(void); // if something error
|
|
||||||
unsigned long getCanId(void); // get can id when receive
|
|
||||||
byte isRemoteRequest(void); // get RR flag when receive
|
|
||||||
byte isExtendedFrame(void); // did we recieve 29bit frame?
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/*********************************************************************************************************
|
|
||||||
END FILE
|
|
||||||
*********************************************************************************************************/
|
|
3
Easylink_CAN_Waker/lib/arduino-CAN-master/.github/FUNDING.yml
vendored
Normal file
3
Easylink_CAN_Waker/lib/arduino-CAN-master/.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: [sandeepmistry]
|
31
Easylink_CAN_Waker/lib/arduino-CAN-master/.travis.yml
Normal file
31
Easylink_CAN_Waker/lib/arduino-CAN-master/.travis.yml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
language: generic
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- IDE_VERSION=1.8.5
|
||||||
|
matrix:
|
||||||
|
- BOARD="arduino:avr:uno"
|
||||||
|
- BOARD="arduino:samd:mkrzero"
|
||||||
|
- BOARD="espressif:esp32:esp32"
|
||||||
|
before_install:
|
||||||
|
- wget http://downloads.arduino.cc/arduino-$IDE_VERSION-linux64.tar.xz
|
||||||
|
- tar xf arduino-$IDE_VERSION-linux64.tar.xz
|
||||||
|
- mv arduino-$IDE_VERSION $HOME/arduino-ide
|
||||||
|
- export PATH=$PATH:$HOME/arduino-ide
|
||||||
|
- if [[ "$BOARD" =~ "arduino:samd:" ]]; then
|
||||||
|
arduino --install-boards arduino:samd;
|
||||||
|
fi
|
||||||
|
- if [[ "$BOARD" =~ "espressif:esp32:" ]]; then
|
||||||
|
mkdir -p $HOME/Arduino/hardware/espressif;
|
||||||
|
git clone https://github.com/espressif/arduino-esp32.git $HOME/Arduino/hardware/espressif/esp32;
|
||||||
|
pushd $HOME/Arduino/hardware/espressif/esp32/tools/;
|
||||||
|
python get.py;
|
||||||
|
popd;
|
||||||
|
fi
|
||||||
|
- buildExampleSketch() { arduino --verbose-build --verify --board $BOARD $PWD/examples/$1/$1.ino; }
|
||||||
|
install:
|
||||||
|
- mkdir -p $HOME/Arduino/libraries
|
||||||
|
- ln -s $PWD $HOME/Arduino/libraries/CAN
|
||||||
|
script:
|
||||||
|
- buildExampleSketch CANReceiver
|
||||||
|
- buildExampleSketch CANReceiverCallback
|
||||||
|
- buildExampleSketch CANSender
|
272
Easylink_CAN_Waker/lib/arduino-CAN-master/API.md
Normal file
272
Easylink_CAN_Waker/lib/arduino-CAN-master/API.md
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
# CAN API
|
||||||
|
|
||||||
|
## Include Library
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
#include <CAN.h>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### Begin
|
||||||
|
|
||||||
|
Initialize the library with the specified bit rate.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.begin(bitrate);
|
||||||
|
```
|
||||||
|
* `bitrate` - bit rate in bits per seconds (bps) (`1000E3`, `500E3`, `250E3`, `200E3`, `125E3`, `100E3`, `80E3`, `50E3`, `40E3`, `20E3`, `10E3`, `5E3`)
|
||||||
|
|
||||||
|
Returns `1` on success, `0` on failure.
|
||||||
|
|
||||||
|
### Set pins
|
||||||
|
|
||||||
|
#### MCP2515
|
||||||
|
|
||||||
|
Override the default `CS` and `INT` pins used by the library. **Must** be called before `CAN.begin(...)`.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.setPins(cs, irq);
|
||||||
|
```
|
||||||
|
* `cs` - new chip select pin to use, defaults to `10`
|
||||||
|
* `irq` - new INT pin to use, defaults to `2`. **Must** be interrupt capable via [attachInterrupt(...)](https://www.arduino.cc/en/Reference/AttachInterrupt).
|
||||||
|
|
||||||
|
This call is optional and only needs to be used if you need to change the default pins used.
|
||||||
|
|
||||||
|
#### ESP32
|
||||||
|
|
||||||
|
Override the default `CTX` and `CRX` pins used by the library. **Must** be called before `CAN.begin(...)`.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.setPins(rx, tx);
|
||||||
|
```
|
||||||
|
* `rx` - new CRX pin to use, defaults to `4`
|
||||||
|
* `tx` - new CTX pin to use, defaults to `5`.
|
||||||
|
|
||||||
|
This call is optional and only needs to be used if you need to change the default pins used.
|
||||||
|
|
||||||
|
### Set SPI Frequency
|
||||||
|
|
||||||
|
**MCP2515 only**
|
||||||
|
|
||||||
|
Override the default SPI frequency of 10 MHz used by the library. **Must** be called before `CAN.begin(...)`.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.setSPIFrequency(frequency);
|
||||||
|
```
|
||||||
|
* `frequency` - new SPI frequency to use, defaults to `10E6`
|
||||||
|
|
||||||
|
This call is optional and only needs to be used if you need to change the default SPI frequency used. Some logic level converters cannot support high speeds such as 10 MHz, so a lower SPI frequency can be selected with `CAN.setSPIFrequency(frequency)`.
|
||||||
|
|
||||||
|
### Set Clock Frequency
|
||||||
|
|
||||||
|
**MCP2515 only**
|
||||||
|
|
||||||
|
Override the default clock source frequency that is connected to the MCP2515. **Must** be called before `CAN.begin(...)`.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.setClockFrequency(clockFrequency);
|
||||||
|
```
|
||||||
|
* `clockFrequency` - new clock frequency to use (`8E6`, `16E6`) connected to MCP2515, defaults to `16 Mhz`
|
||||||
|
|
||||||
|
This call is optional and only needs to be used if you need to change the clock source frequency connected to the MCP2515. Most shields have a 16 MHz clock source on board, some breakout boards have a 8 MHz source.
|
||||||
|
|
||||||
|
### End
|
||||||
|
|
||||||
|
Stop the library
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.end()
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sending data
|
||||||
|
|
||||||
|
### Begin packet
|
||||||
|
|
||||||
|
Start the sequence of sending a packet.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.beginPacket(id);
|
||||||
|
CAN.beginPacket(id, dlc);
|
||||||
|
CAN.beginPacket(id, dlc, rtr);
|
||||||
|
|
||||||
|
CAN.beginExtendedPacket(id);
|
||||||
|
CAN.beginExtendedPacket(id, dlc);
|
||||||
|
CAN.beginExtendedPacket(id, dlc, rtr);
|
||||||
|
```
|
||||||
|
|
||||||
|
* `id` - 11-bit id (standard packet) or 29-bit packet id (extended packet)
|
||||||
|
* `dlc` - (optional) value of Data Length Code (DLC) field of packet, default is size of data written in packet
|
||||||
|
* `rtr` - (optional) value of Remote Transmission Request (RTR) field of packet (`false` or `true`), defaults to `false`. RTR packets contain no data, the DLC field of the packet represents the requested length.
|
||||||
|
|
||||||
|
Returns `1` on success, `0` on failure.
|
||||||
|
|
||||||
|
### Writing
|
||||||
|
|
||||||
|
Write data to the packet. Each packet can contain up to 8 bytes.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.write(byte);
|
||||||
|
|
||||||
|
CAN.write(buffer, length);
|
||||||
|
```
|
||||||
|
* `byte` - single byte to write to packet
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
* `buffer` - data to write to packet
|
||||||
|
* `length` - size of data to write
|
||||||
|
|
||||||
|
Returns the number of bytes written.
|
||||||
|
|
||||||
|
**Note:** Other Arduino `Print` API's can also be used to write data into the packet
|
||||||
|
|
||||||
|
### End packet
|
||||||
|
|
||||||
|
End the sequence of sending a packet.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.endPacket()
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `1` on success, `0` on failure.
|
||||||
|
|
||||||
|
## Receiving data
|
||||||
|
|
||||||
|
### Parsing packet
|
||||||
|
|
||||||
|
Check if a packet has been received.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
int packetSize = CAN.parsePacket();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the packet size in bytes or `0` if no packet was received. For RTR packets the size reflects the DLC field of the packet.
|
||||||
|
|
||||||
|
### Register callback
|
||||||
|
|
||||||
|
Register a callback function for when a packet is received.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.onReceive(onReceive);
|
||||||
|
|
||||||
|
void onReceive(int packetSize) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* `onReceive` - function to call when a packet is received.
|
||||||
|
|
||||||
|
### Packet ID
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
long id = CAN.packetId();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the id (11-bit or 29 bit) of the received packet. Standard packets have an 11-bit id, extended packets have an 29-bit id.
|
||||||
|
|
||||||
|
### Packet Extended
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
bool extended = CAN.packetExtended();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `true` if the received packet is extended, `false` otherwise.
|
||||||
|
|
||||||
|
### Packet RTR
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
bool rtr = CAN.packetRtr();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the value of the Remote Transmission Request (RTR) field of the packet `true`/`false`. RTR packets contain no data, the DLC field is the requested data length.
|
||||||
|
|
||||||
|
### Packet DLC
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
int DLC = CAN.packetDlc();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the value of the Data Length Code (DLC) field of the packet.
|
||||||
|
|
||||||
|
|
||||||
|
### Available
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
int availableBytes = CAN.available()
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns number of bytes available for reading.
|
||||||
|
|
||||||
|
### Peeking
|
||||||
|
|
||||||
|
Peek at the next byte in the packet.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
int b = CAN.peek();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the next byte in the packet or `-1` if no bytes are available.
|
||||||
|
|
||||||
|
### Reading
|
||||||
|
|
||||||
|
Read the next byte from the packet.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
int b = CAN.read();
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the next byte in the packet or `-1` if no bytes are available.
|
||||||
|
|
||||||
|
**Note:** Other Arduino [`Stream` API's](https://www.arduino.cc/en/Reference/Stream) can also be used to read data from the packet
|
||||||
|
|
||||||
|
### Filtering
|
||||||
|
|
||||||
|
Filter packets that meet the desired criteria.
|
||||||
|
|
||||||
|
```
|
||||||
|
CAN.filter(id);
|
||||||
|
CAN.filter(id, mask);
|
||||||
|
|
||||||
|
CAN.filterExtended(id);
|
||||||
|
CAN.filterExtended(id, mask);
|
||||||
|
```
|
||||||
|
|
||||||
|
* `id` - 11-bit id (standard packet) or 29-bit packet id (extended packet)
|
||||||
|
* `mask` - (optional) 11-bit mask (standard packet) or 29-bit mask (extended packet), defaults to `0x7ff` or `0x1fffffff` (extended)
|
||||||
|
|
||||||
|
Only packets that meet the following criteria are acknowleged and received, other packets are ignored:
|
||||||
|
|
||||||
|
```
|
||||||
|
if ((packetId & mask) == id) {
|
||||||
|
// acknowleged and received
|
||||||
|
} else {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns `1` on success, `0` on failure.
|
||||||
|
|
||||||
|
## Other modes
|
||||||
|
|
||||||
|
### Loopback mode
|
||||||
|
|
||||||
|
Put the CAN controller in loopback mode, any outgoing packets will also be received.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.loopback();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sleep mode
|
||||||
|
|
||||||
|
Put the CAN contoller in sleep mode.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.sleep();
|
||||||
|
```
|
||||||
|
|
||||||
|
Wake up the CAN contoller if it was previously in sleep mode.
|
||||||
|
|
||||||
|
```arduino
|
||||||
|
CAN.wakeup();
|
||||||
|
```
|
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018 @ Longan Labs
|
Copyright (c) 2017 Sandeep Mistry
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
71
Easylink_CAN_Waker/lib/arduino-CAN-master/README.md
Normal file
71
Easylink_CAN_Waker/lib/arduino-CAN-master/README.md
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
# Arduino CAN
|
||||||
|
|
||||||
|
[![Build Status](https://travis-ci.org/sandeepmistry/arduino-CAN.svg?branch=master)](https://travis-ci.org/sandeepmistry/arduino-CAN)
|
||||||
|
|
||||||
|
An Arduino library for sending and receiving data using CAN bus.
|
||||||
|
|
||||||
|
## Compatible Hardware
|
||||||
|
|
||||||
|
* [Microchip MCP2515](http://www.microchip.com/wwwproducts/en/en010406) based boards/shields
|
||||||
|
* [Arduino MKR CAN shield](https://store.arduino.cc/arduino-mkr-can-shield)
|
||||||
|
* [Espressif ESP32](http://espressif.com/en/products/hardware/esp32/overview)'s built-in [SJA1000](https://www.nxp.com/products/analog/interfaces/in-vehicle-network/can-transceiver-and-controllers/stand-alone-can-controller:SJA1000T) compatible CAN controller with an external 3.3V CAN transceiver
|
||||||
|
|
||||||
|
### Microchip MCP2515 wiring
|
||||||
|
|
||||||
|
| Microchip MCP2515 | Arduino |
|
||||||
|
| :---------------: | :-----: |
|
||||||
|
| VCC | 5V |
|
||||||
|
| GND | GND |
|
||||||
|
| SCK | SCK |
|
||||||
|
| SO | MISO |
|
||||||
|
| SI | MOSI |
|
||||||
|
| CS | 10 |
|
||||||
|
| INT | 2 |
|
||||||
|
|
||||||
|
|
||||||
|
`CS` and `INT` pins can be changed by using `CAN.setPins(cs, irq)`. `INT` pin is optional, it is only needed for receive callback mode. If `INT` pin is used, it **must** be interrupt capable via [`attachInterrupt(...)`](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/).
|
||||||
|
|
||||||
|
**NOTE**: Logic level converters must be used for boards which operate at 3.3V.
|
||||||
|
|
||||||
|
### Espressif ESP32 wiring
|
||||||
|
|
||||||
|
Requires an external 3.3V CAN transceiver, such as a [TI SN65HVD230](http://www.ti.com/product/SN65HVD230).
|
||||||
|
|
||||||
|
| CAN transceiver | ESP32 |
|
||||||
|
| :-------------: | :---: |
|
||||||
|
| 3V3 | 3V3 |
|
||||||
|
| GND | GND |
|
||||||
|
| CTX | GPIO_5 |
|
||||||
|
| CRX | GPIO_4 |
|
||||||
|
|
||||||
|
`CTX` and `CRX` pins can be changed by using `CAN.setPins(rx, tx)`.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Using the Arduino IDE Library Manager
|
||||||
|
|
||||||
|
1. Choose `Sketch` -> `Include Library` -> `Manage Libraries...`
|
||||||
|
2. Type `CAN` into the search box.
|
||||||
|
3. Click the row to select the library.
|
||||||
|
4. Click the `Install` button to install the library.
|
||||||
|
|
||||||
|
### Using Git
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/Documents/Arduino/libraries/
|
||||||
|
git clone https://github.com/sandeepmistry/arduino-CAN CAN
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
See [API.md](API.md).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
See [examples](examples) folder.
|
||||||
|
|
||||||
|
For OBD-II examples, checkout the [arduino-OBD2](https://github.com/sandeepmistry/arduino-OBD2) library's [examples](https://github.com/sandeepmistry/arduino-OBD2/examples).
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This library is [licensed](LICENSE) under the [MIT Licence](http://en.wikipedia.org/wiki/MIT_License).
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#include <CAN.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
while (!Serial);
|
||||||
|
|
||||||
|
Serial.println("CAN Receiver");
|
||||||
|
|
||||||
|
// start the CAN bus at 500 kbps
|
||||||
|
if (!CAN.begin(500E3)) {
|
||||||
|
Serial.println("Starting CAN failed!");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// try to parse packet
|
||||||
|
int packetSize = CAN.parsePacket();
|
||||||
|
|
||||||
|
if (packetSize || CAN.packetId() != -1) {
|
||||||
|
// received a packet
|
||||||
|
Serial.print("Received ");
|
||||||
|
|
||||||
|
if (CAN.packetExtended()) {
|
||||||
|
Serial.print("extended ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN.packetRtr()) {
|
||||||
|
// Remote transmission request, packet contains no data
|
||||||
|
Serial.print("RTR ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("packet with id 0x");
|
||||||
|
Serial.print(CAN.packetId(), HEX);
|
||||||
|
|
||||||
|
if (CAN.packetRtr()) {
|
||||||
|
Serial.print(" and requested length ");
|
||||||
|
Serial.println(CAN.packetDlc());
|
||||||
|
} else {
|
||||||
|
Serial.print(" and length ");
|
||||||
|
Serial.println(packetSize);
|
||||||
|
|
||||||
|
// only print packet data for non-RTR packets
|
||||||
|
while (CAN.available()) {
|
||||||
|
Serial.print((char)CAN.read());
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#include <CAN.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
while (!Serial);
|
||||||
|
|
||||||
|
Serial.println("CAN Receiver Callback");
|
||||||
|
|
||||||
|
// start the CAN bus at 500 kbps
|
||||||
|
if (!CAN.begin(500E3)) {
|
||||||
|
Serial.println("Starting CAN failed!");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the receive callback
|
||||||
|
CAN.onReceive(onReceive);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void onReceive(int packetSize) {
|
||||||
|
// received a packet
|
||||||
|
Serial.print("Received ");
|
||||||
|
|
||||||
|
if (CAN.packetExtended()) {
|
||||||
|
Serial.print("extended ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CAN.packetRtr()) {
|
||||||
|
// Remote transmission request, packet contains no data
|
||||||
|
Serial.print("RTR ");
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print("packet with id 0x");
|
||||||
|
Serial.print(CAN.packetId(), HEX);
|
||||||
|
|
||||||
|
if (CAN.packetRtr()) {
|
||||||
|
Serial.print(" and requested length ");
|
||||||
|
Serial.println(CAN.packetDlc());
|
||||||
|
} else {
|
||||||
|
Serial.print(" and length ");
|
||||||
|
Serial.println(packetSize);
|
||||||
|
|
||||||
|
// only print packet data for non-RTR packets
|
||||||
|
while (CAN.available()) {
|
||||||
|
Serial.print((char)CAN.read());
|
||||||
|
}
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#include <CAN.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(9600);
|
||||||
|
while (!Serial);
|
||||||
|
|
||||||
|
Serial.println("CAN Sender");
|
||||||
|
|
||||||
|
// start the CAN bus at 500 kbps
|
||||||
|
if (!CAN.begin(500E3)) {
|
||||||
|
Serial.println("Starting CAN failed!");
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
// send packet: id is 11 bits, packet can contain up to 8 bytes of data
|
||||||
|
Serial.print("Sending packet ... ");
|
||||||
|
|
||||||
|
CAN.beginPacket(0x12);
|
||||||
|
CAN.write('h');
|
||||||
|
CAN.write('e');
|
||||||
|
CAN.write('l');
|
||||||
|
CAN.write('l');
|
||||||
|
CAN.write('o');
|
||||||
|
CAN.endPacket();
|
||||||
|
|
||||||
|
Serial.println("done");
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
|
||||||
|
// send extended packet: id is 29 bits, packet can contain up to 8 bytes of data
|
||||||
|
Serial.print("Sending extended packet ... ");
|
||||||
|
|
||||||
|
CAN.beginExtendedPacket(0xabcdef);
|
||||||
|
CAN.write('w');
|
||||||
|
CAN.write('o');
|
||||||
|
CAN.write('r');
|
||||||
|
CAN.write('l');
|
||||||
|
CAN.write('d');
|
||||||
|
CAN.endPacket();
|
||||||
|
|
||||||
|
Serial.println("done");
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
49
Easylink_CAN_Waker/lib/arduino-CAN-master/keywords.txt
Normal file
49
Easylink_CAN_Waker/lib/arduino-CAN-master/keywords.txt
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#######################################
|
||||||
|
# Syntax Coloring Map For CAN
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Datatypes (KEYWORD1)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
CAN KEYWORD1
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Methods and Functions (KEYWORD2)
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
begin KEYWORD2
|
||||||
|
end KEYWORD2
|
||||||
|
|
||||||
|
beginPacket KEYWORD2
|
||||||
|
beginExtendedPacket KEYWORD2
|
||||||
|
endPacket KEYWORD2
|
||||||
|
|
||||||
|
parsePacket KEYWORD2
|
||||||
|
packetId KEYWORD2
|
||||||
|
packetExtended KEYWORD2
|
||||||
|
packetRtr KEYWORD2
|
||||||
|
packetDlc KEYWORD2
|
||||||
|
|
||||||
|
write KEYWORD2
|
||||||
|
|
||||||
|
available KEYWORD2
|
||||||
|
read KEYWORD2
|
||||||
|
peek KEYWORD2
|
||||||
|
flush KEYWORD2
|
||||||
|
|
||||||
|
onReceive KEYWORD2
|
||||||
|
filter KEYWORD2
|
||||||
|
filterExtended KEYWORD2
|
||||||
|
loopback KEYWORD2
|
||||||
|
sleep KEYWORD2
|
||||||
|
wakeup KEYWORD2
|
||||||
|
|
||||||
|
setPins KEYWORD2
|
||||||
|
setSPIFrequency KEYWORD2
|
||||||
|
setClockFrequency KEYWORD2
|
||||||
|
dumpRegisters KEYWORD2
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
# Constants (LITERAL1)
|
||||||
|
#######################################
|
10
Easylink_CAN_Waker/lib/arduino-CAN-master/library.properties
Normal file
10
Easylink_CAN_Waker/lib/arduino-CAN-master/library.properties
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
name=CAN
|
||||||
|
version=0.3.1
|
||||||
|
author=Sandeep Mistry <sandeep.mistry@gmail.com>
|
||||||
|
maintainer=Sandeep Mistry <sandeep.mistry@gmail.com>
|
||||||
|
sentence=An Arduino library for sending and receiving data using CAN bus.
|
||||||
|
paragraph=Supports Microchip MCP2515 based boards/shields and the Espressif ESP32's built-in SJA1000 compatible CAN controller.
|
||||||
|
category=Communication
|
||||||
|
url=https://github.com/sandeepmistry/arduino-CAN
|
||||||
|
architectures=*
|
||||||
|
includes=CAN.h
|
13
Easylink_CAN_Waker/lib/arduino-CAN-master/src/CAN.h
Normal file
13
Easylink_CAN_Waker/lib/arduino-CAN-master/src/CAN.h
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#ifndef CAN_H
|
||||||
|
#define CAN_H
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#include "ESP32SJA1000.h"
|
||||||
|
#else
|
||||||
|
#include "MCP2515.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
216
Easylink_CAN_Waker/lib/arduino-CAN-master/src/CANController.cpp
Normal file
216
Easylink_CAN_Waker/lib/arduino-CAN-master/src/CANController.cpp
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#include "CANController.h"
|
||||||
|
|
||||||
|
CANControllerClass::CANControllerClass() :
|
||||||
|
_onReceive(NULL),
|
||||||
|
|
||||||
|
_packetBegun(false),
|
||||||
|
_txId(-1),
|
||||||
|
_txExtended(-1),
|
||||||
|
_txRtr(false),
|
||||||
|
_txDlc(0),
|
||||||
|
_txLength(0),
|
||||||
|
|
||||||
|
_rxId(-1),
|
||||||
|
_rxExtended(false),
|
||||||
|
_rxRtr(false),
|
||||||
|
_rxDlc(0),
|
||||||
|
_rxLength(0),
|
||||||
|
_rxIndex(0)
|
||||||
|
{
|
||||||
|
// overide Stream timeout value
|
||||||
|
setTimeout(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CANControllerClass::~CANControllerClass()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::begin(long /*baudRate*/)
|
||||||
|
{
|
||||||
|
_packetBegun = false;
|
||||||
|
_txId = -1;
|
||||||
|
_txRtr =false;
|
||||||
|
_txDlc = 0;
|
||||||
|
_txLength = 0;
|
||||||
|
|
||||||
|
_rxId = -1;
|
||||||
|
_rxRtr = false;
|
||||||
|
_rxDlc = 0;
|
||||||
|
_rxLength = 0;
|
||||||
|
_rxIndex = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CANControllerClass::end()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::beginPacket(int id, int dlc, bool rtr)
|
||||||
|
{
|
||||||
|
if (id < 0 || id > 0x7FF) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dlc > 8) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_packetBegun = true;
|
||||||
|
_txId = id;
|
||||||
|
_txExtended = false;
|
||||||
|
_txRtr = rtr;
|
||||||
|
_txDlc = dlc;
|
||||||
|
_txLength = 0;
|
||||||
|
|
||||||
|
memset(_txData, 0x00, sizeof(_txData));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::beginExtendedPacket(long id, int dlc, bool rtr)
|
||||||
|
{
|
||||||
|
if (id < 0 || id > 0x1FFFFFFF) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dlc > 8) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_packetBegun = true;
|
||||||
|
_txId = id;
|
||||||
|
_txExtended = true;
|
||||||
|
_txRtr = rtr;
|
||||||
|
_txDlc = dlc;
|
||||||
|
_txLength = 0;
|
||||||
|
|
||||||
|
memset(_txData, 0x00, sizeof(_txData));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::endPacket()
|
||||||
|
{
|
||||||
|
if (!_packetBegun) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_packetBegun = false;
|
||||||
|
|
||||||
|
if (_txDlc >= 0) {
|
||||||
|
_txLength = _txDlc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::parsePacket()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long CANControllerClass::packetId()
|
||||||
|
{
|
||||||
|
return _rxId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CANControllerClass::packetExtended()
|
||||||
|
{
|
||||||
|
return _rxExtended;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CANControllerClass::packetRtr()
|
||||||
|
{
|
||||||
|
return _rxRtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::packetDlc()
|
||||||
|
{
|
||||||
|
return _rxDlc;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CANControllerClass::write(uint8_t byte)
|
||||||
|
{
|
||||||
|
return write(&byte, sizeof(byte));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CANControllerClass::write(const uint8_t *buffer, size_t size)
|
||||||
|
{
|
||||||
|
if (!_packetBegun) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size > (sizeof(_txData) - _txLength)) {
|
||||||
|
size = sizeof(_txData) - _txLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&_txData[_txLength], buffer, size);
|
||||||
|
_txLength += size;
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::available()
|
||||||
|
{
|
||||||
|
return (_rxLength - _rxIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::read()
|
||||||
|
{
|
||||||
|
if (!available()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _rxData[_rxIndex++];
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::peek()
|
||||||
|
{
|
||||||
|
if (!available()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _rxData[_rxIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CANControllerClass::flush()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CANControllerClass::onReceive(void(*callback)(int))
|
||||||
|
{
|
||||||
|
_onReceive = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::filter(int /*id*/, int /*mask*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::filterExtended(long /*id*/, long /*mask*/)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::observe()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::loopback()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::sleep()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CANControllerClass::wakeup()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#ifndef CAN_CONTROLLER_H
|
||||||
|
#define CAN_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
|
class CANControllerClass : public Stream {
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int begin(long baudRate);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
int beginPacket(int id, int dlc = -1, bool rtr = false);
|
||||||
|
int beginExtendedPacket(long id, int dlc = -1, bool rtr = false);
|
||||||
|
virtual int endPacket();
|
||||||
|
|
||||||
|
virtual int parsePacket();
|
||||||
|
long packetId();
|
||||||
|
bool packetExtended();
|
||||||
|
bool packetRtr();
|
||||||
|
int packetDlc();
|
||||||
|
|
||||||
|
// from Print
|
||||||
|
virtual size_t write(uint8_t byte);
|
||||||
|
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||||
|
|
||||||
|
// from Stream
|
||||||
|
virtual int available();
|
||||||
|
virtual int read();
|
||||||
|
virtual int peek();
|
||||||
|
virtual void flush();
|
||||||
|
|
||||||
|
virtual void onReceive(void(*callback)(int));
|
||||||
|
|
||||||
|
virtual int filter(int id) { return filter(id, 0x7ff); }
|
||||||
|
virtual int filter(int id, int mask);
|
||||||
|
virtual int filterExtended(long id) { return filterExtended(id, 0x1fffffff); }
|
||||||
|
virtual int filterExtended(long id, long mask);
|
||||||
|
|
||||||
|
virtual int observe();
|
||||||
|
virtual int loopback();
|
||||||
|
virtual int sleep();
|
||||||
|
virtual int wakeup();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CANControllerClass();
|
||||||
|
virtual ~CANControllerClass();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void (*_onReceive)(int);
|
||||||
|
|
||||||
|
bool _packetBegun;
|
||||||
|
long _txId;
|
||||||
|
bool _txExtended;
|
||||||
|
bool _txRtr;
|
||||||
|
int _txDlc;
|
||||||
|
int _txLength;
|
||||||
|
uint8_t _txData[8];
|
||||||
|
|
||||||
|
long _rxId;
|
||||||
|
bool _rxExtended;
|
||||||
|
bool _rxRtr;
|
||||||
|
int _rxDlc;
|
||||||
|
int _rxLength;
|
||||||
|
int _rxIndex;
|
||||||
|
uint8_t _rxData[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
415
Easylink_CAN_Waker/lib/arduino-CAN-master/src/ESP32SJA1000.cpp
Normal file
415
Easylink_CAN_Waker/lib/arduino-CAN-master/src/ESP32SJA1000.cpp
Normal file
|
@ -0,0 +1,415 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
#include "esp_intr.h"
|
||||||
|
#include "soc/dport_reg.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
#include "ESP32SJA1000.h"
|
||||||
|
|
||||||
|
#define REG_BASE 0x3ff6b000
|
||||||
|
|
||||||
|
#define REG_MOD 0x00
|
||||||
|
#define REG_CMR 0x01
|
||||||
|
#define REG_SR 0x02
|
||||||
|
#define REG_IR 0x03
|
||||||
|
#define REG_IER 0x04
|
||||||
|
|
||||||
|
#define REG_BTR0 0x06
|
||||||
|
#define REG_BTR1 0x07
|
||||||
|
#define REG_OCR 0x08
|
||||||
|
|
||||||
|
#define REG_ALC 0x0b
|
||||||
|
#define REG_ECC 0x0c
|
||||||
|
#define REG_EWLR 0x0d
|
||||||
|
#define REG_RXERR 0x0e
|
||||||
|
#define REG_TXERR 0x0f
|
||||||
|
#define REG_SFF 0x10
|
||||||
|
#define REG_EFF 0x10
|
||||||
|
#define REG_ACRn(n) (0x10 + n)
|
||||||
|
#define REG_AMRn(n) (0x14 + n)
|
||||||
|
|
||||||
|
#define REG_CDR 0x1F
|
||||||
|
|
||||||
|
|
||||||
|
ESP32SJA1000Class::ESP32SJA1000Class() :
|
||||||
|
CANControllerClass(),
|
||||||
|
_rxPin(DEFAULT_CAN_RX_PIN),
|
||||||
|
_txPin(DEFAULT_CAN_TX_PIN),
|
||||||
|
_loopback(false),
|
||||||
|
_intrHandle(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP32SJA1000Class::~ESP32SJA1000Class()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::begin(long baudRate)
|
||||||
|
{
|
||||||
|
CANControllerClass::begin(baudRate);
|
||||||
|
|
||||||
|
_loopback = false;
|
||||||
|
|
||||||
|
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST);
|
||||||
|
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN);
|
||||||
|
|
||||||
|
// RX pin
|
||||||
|
gpio_set_direction(_rxPin, GPIO_MODE_INPUT);
|
||||||
|
gpio_matrix_in(_rxPin, CAN_RX_IDX, 0);
|
||||||
|
gpio_pad_select_gpio(_rxPin);
|
||||||
|
|
||||||
|
// TX pin
|
||||||
|
gpio_set_direction(_txPin, GPIO_MODE_OUTPUT);
|
||||||
|
gpio_matrix_out(_txPin, CAN_TX_IDX, 0, 0);
|
||||||
|
gpio_pad_select_gpio(_txPin);
|
||||||
|
|
||||||
|
modifyRegister(REG_CDR, 0x80, 0x80); // pelican mode
|
||||||
|
modifyRegister(REG_BTR0, 0xc0, 0x40); // SJW = 1
|
||||||
|
modifyRegister(REG_BTR1, 0x70, 0x10); // TSEG2 = 1
|
||||||
|
|
||||||
|
switch (baudRate) {
|
||||||
|
case (long)1000E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x04);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)500E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)250E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 9);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)200E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 12);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)125E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 19);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)100E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 24);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)80E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 30);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (long)50E3:
|
||||||
|
modifyRegister(REG_BTR1, 0x0f, 0x0c);
|
||||||
|
modifyRegister(REG_BTR0, 0x3f, 49);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Due to limitations in ESP32 hardware and/or RTOS software, baudrate can't be lower than 50kbps.
|
||||||
|
See https://esp32.com/viewtopic.php?t=2142
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyRegister(REG_BTR1, 0x80, 0x80); // SAM = 1
|
||||||
|
writeRegister(REG_IER, 0xff); // enable all interrupts
|
||||||
|
|
||||||
|
// set filter to allow anything
|
||||||
|
writeRegister(REG_ACRn(0), 0x00);
|
||||||
|
writeRegister(REG_ACRn(1), 0x00);
|
||||||
|
writeRegister(REG_ACRn(2), 0x00);
|
||||||
|
writeRegister(REG_ACRn(3), 0x00);
|
||||||
|
writeRegister(REG_AMRn(0), 0xff);
|
||||||
|
writeRegister(REG_AMRn(1), 0xff);
|
||||||
|
writeRegister(REG_AMRn(2), 0xff);
|
||||||
|
writeRegister(REG_AMRn(3), 0xff);
|
||||||
|
|
||||||
|
modifyRegister(REG_OCR, 0x03, 0x02); // normal output mode
|
||||||
|
// reset error counters
|
||||||
|
writeRegister(REG_TXERR, 0x00);
|
||||||
|
writeRegister(REG_RXERR, 0x00);
|
||||||
|
|
||||||
|
// clear errors and interrupts
|
||||||
|
readRegister(REG_ECC);
|
||||||
|
readRegister(REG_IR);
|
||||||
|
|
||||||
|
// normal mode
|
||||||
|
modifyRegister(REG_MOD, 0x08, 0x08);
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x00);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::end()
|
||||||
|
{
|
||||||
|
if (_intrHandle) {
|
||||||
|
esp_intr_free(_intrHandle);
|
||||||
|
_intrHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST);
|
||||||
|
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN);
|
||||||
|
|
||||||
|
CANControllerClass::end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::endPacket()
|
||||||
|
{
|
||||||
|
if (!CANControllerClass::endPacket()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for TX buffer to free
|
||||||
|
while ((readRegister(REG_SR) & 0x04) != 0x04) {
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
int dataReg;
|
||||||
|
|
||||||
|
if (_txExtended) {
|
||||||
|
writeRegister(REG_EFF, 0x80 | (_txRtr ? 0x40 : 0x00) | (0x0f & _txLength));
|
||||||
|
writeRegister(REG_EFF + 1, _txId >> 21);
|
||||||
|
writeRegister(REG_EFF + 2, _txId >> 13);
|
||||||
|
writeRegister(REG_EFF + 3, _txId >> 5);
|
||||||
|
writeRegister(REG_EFF + 4, _txId << 3);
|
||||||
|
|
||||||
|
dataReg = REG_EFF + 5;
|
||||||
|
} else {
|
||||||
|
writeRegister(REG_SFF, (_txRtr ? 0x40 : 0x00) | (0x0f & _txLength));
|
||||||
|
writeRegister(REG_SFF + 1, _txId >> 3);
|
||||||
|
writeRegister(REG_SFF + 2, _txId << 5);
|
||||||
|
|
||||||
|
dataReg = REG_SFF + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _txLength; i++) {
|
||||||
|
writeRegister(dataReg + i, _txData[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( _loopback) {
|
||||||
|
// self reception request
|
||||||
|
modifyRegister(REG_CMR, 0x1f, 0x10);
|
||||||
|
} else {
|
||||||
|
// transmit request
|
||||||
|
modifyRegister(REG_CMR, 0x1f, 0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for TX complete
|
||||||
|
while ((readRegister(REG_SR) & 0x08) != 0x08) {
|
||||||
|
if (readRegister(REG_ECC) == 0xd9) {
|
||||||
|
modifyRegister(REG_CMR, 0x1f, 0x02); // error, abort
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::parsePacket()
|
||||||
|
{
|
||||||
|
if ((readRegister(REG_SR) & 0x01) != 0x01) {
|
||||||
|
// no packet
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rxExtended = (readRegister(REG_SFF) & 0x80) ? true : false;
|
||||||
|
_rxRtr = (readRegister(REG_SFF) & 0x40) ? true : false;
|
||||||
|
_rxDlc = (readRegister(REG_SFF) & 0x0f);
|
||||||
|
_rxIndex = 0;
|
||||||
|
|
||||||
|
int dataReg;
|
||||||
|
|
||||||
|
if (_rxExtended) {
|
||||||
|
_rxId = (readRegister(REG_EFF + 1) << 21) |
|
||||||
|
(readRegister(REG_EFF + 2) << 13) |
|
||||||
|
(readRegister(REG_EFF + 3) << 5) |
|
||||||
|
(readRegister(REG_EFF + 4) >> 3);
|
||||||
|
|
||||||
|
dataReg = REG_EFF + 5;
|
||||||
|
} else {
|
||||||
|
_rxId = (readRegister(REG_SFF + 1) << 3) | ((readRegister(REG_SFF + 2) >> 5) & 0x07);
|
||||||
|
|
||||||
|
dataReg = REG_SFF + 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_rxRtr) {
|
||||||
|
_rxLength = 0;
|
||||||
|
} else {
|
||||||
|
_rxLength = _rxDlc;
|
||||||
|
|
||||||
|
for (int i = 0; i < _rxLength; i++) {
|
||||||
|
_rxData[i] = readRegister(dataReg + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// release RX buffer
|
||||||
|
modifyRegister(REG_CMR, 0x04, 0x04);
|
||||||
|
|
||||||
|
return _rxDlc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::onReceive(void(*callback)(int))
|
||||||
|
{
|
||||||
|
CANControllerClass::onReceive(callback);
|
||||||
|
|
||||||
|
if (_intrHandle) {
|
||||||
|
esp_intr_free(_intrHandle);
|
||||||
|
_intrHandle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
esp_intr_alloc(ETS_CAN_INTR_SOURCE, 0, ESP32SJA1000Class::onInterrupt, this, &_intrHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::filter(int id, int mask)
|
||||||
|
{
|
||||||
|
id &= 0x7ff;
|
||||||
|
mask = ~(mask & 0x7ff);
|
||||||
|
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x01); // reset
|
||||||
|
|
||||||
|
writeRegister(REG_ACRn(0), id >> 3);
|
||||||
|
writeRegister(REG_ACRn(1), id << 5);
|
||||||
|
writeRegister(REG_ACRn(2), 0x00);
|
||||||
|
writeRegister(REG_ACRn(3), 0x00);
|
||||||
|
|
||||||
|
writeRegister(REG_AMRn(0), mask >> 3);
|
||||||
|
writeRegister(REG_AMRn(1), (mask << 5) | 0x1f);
|
||||||
|
writeRegister(REG_AMRn(2), 0xff);
|
||||||
|
writeRegister(REG_AMRn(3), 0xff);
|
||||||
|
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x00); // normal
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::filterExtended(long id, long mask)
|
||||||
|
{
|
||||||
|
id &= 0x1FFFFFFF;
|
||||||
|
mask &= ~(mask & 0x1FFFFFFF);
|
||||||
|
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x01); // reset
|
||||||
|
|
||||||
|
writeRegister(REG_ACRn(0), id >> 21);
|
||||||
|
writeRegister(REG_ACRn(1), id >> 13);
|
||||||
|
writeRegister(REG_ACRn(2), id >> 5);
|
||||||
|
writeRegister(REG_ACRn(3), id << 3);
|
||||||
|
|
||||||
|
writeRegister(REG_AMRn(0), mask >> 21);
|
||||||
|
writeRegister(REG_AMRn(1), mask >> 13);
|
||||||
|
writeRegister(REG_AMRn(2), mask >> 5);
|
||||||
|
writeRegister(REG_AMRn(3), (mask << 3) | 0x1f);
|
||||||
|
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x00); // normal
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::observe()
|
||||||
|
{
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x01); // reset
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x02); // observe
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::loopback()
|
||||||
|
{
|
||||||
|
_loopback = true;
|
||||||
|
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x01); // reset
|
||||||
|
modifyRegister(REG_MOD, 0x17, 0x04); // self test mode
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::sleep()
|
||||||
|
{
|
||||||
|
modifyRegister(REG_MOD, 0x1f, 0x10);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ESP32SJA1000Class::wakeup()
|
||||||
|
{
|
||||||
|
modifyRegister(REG_MOD, 0x1f, 0x00);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::setPins(int rx, int tx)
|
||||||
|
{
|
||||||
|
_rxPin = (gpio_num_t)rx;
|
||||||
|
_txPin = (gpio_num_t)tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::dumpRegisters(Stream& out)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
byte b = readRegister(i);
|
||||||
|
|
||||||
|
out.print("0x");
|
||||||
|
if (i < 16) {
|
||||||
|
out.print('0');
|
||||||
|
}
|
||||||
|
out.print(i, HEX);
|
||||||
|
out.print(": 0x");
|
||||||
|
if (b < 16) {
|
||||||
|
out.print('0');
|
||||||
|
}
|
||||||
|
out.println(b, HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::handleInterrupt()
|
||||||
|
{
|
||||||
|
uint8_t ir = readRegister(REG_IR);
|
||||||
|
|
||||||
|
if (ir & 0x01) {
|
||||||
|
// received packet, parse and call callback
|
||||||
|
parsePacket();
|
||||||
|
|
||||||
|
_onReceive(available());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ESP32SJA1000Class::readRegister(uint8_t address)
|
||||||
|
{
|
||||||
|
volatile uint32_t* reg = (volatile uint32_t*)(REG_BASE + address * 4);
|
||||||
|
|
||||||
|
return *reg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::modifyRegister(uint8_t address, uint8_t mask, uint8_t value)
|
||||||
|
{
|
||||||
|
volatile uint32_t* reg = (volatile uint32_t*)(REG_BASE + address * 4);
|
||||||
|
|
||||||
|
*reg = (*reg & ~mask) | value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::writeRegister(uint8_t address, uint8_t value)
|
||||||
|
{
|
||||||
|
volatile uint32_t* reg = (volatile uint32_t*)(REG_BASE + address * 4);
|
||||||
|
|
||||||
|
*reg = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ESP32SJA1000Class::onInterrupt(void* arg)
|
||||||
|
{
|
||||||
|
((ESP32SJA1000Class*)arg)->handleInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP32SJA1000Class CAN;
|
||||||
|
|
||||||
|
#endif
|
65
Easylink_CAN_Waker/lib/arduino-CAN-master/src/ESP32SJA1000.h
Normal file
65
Easylink_CAN_Waker/lib/arduino-CAN-master/src/ESP32SJA1000.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
#ifndef ESP32_SJA1000_H
|
||||||
|
#define ESP32_SJA1000_H
|
||||||
|
|
||||||
|
#include "CANController.h"
|
||||||
|
|
||||||
|
#define DEFAULT_CAN_RX_PIN GPIO_NUM_4
|
||||||
|
#define DEFAULT_CAN_TX_PIN GPIO_NUM_5
|
||||||
|
|
||||||
|
class ESP32SJA1000Class : public CANControllerClass {
|
||||||
|
|
||||||
|
public:
|
||||||
|
ESP32SJA1000Class();
|
||||||
|
virtual ~ESP32SJA1000Class();
|
||||||
|
|
||||||
|
virtual int begin(long baudRate);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
virtual int endPacket();
|
||||||
|
|
||||||
|
virtual int parsePacket();
|
||||||
|
|
||||||
|
virtual void onReceive(void(*callback)(int));
|
||||||
|
|
||||||
|
using CANControllerClass::filter;
|
||||||
|
virtual int filter(int id, int mask);
|
||||||
|
using CANControllerClass::filterExtended;
|
||||||
|
virtual int filterExtended(long id, long mask);
|
||||||
|
|
||||||
|
virtual int observe();
|
||||||
|
virtual int loopback();
|
||||||
|
virtual int sleep();
|
||||||
|
virtual int wakeup();
|
||||||
|
|
||||||
|
void setPins(int rx, int tx);
|
||||||
|
|
||||||
|
void dumpRegisters(Stream& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void handleInterrupt();
|
||||||
|
|
||||||
|
uint8_t readRegister(uint8_t address);
|
||||||
|
void modifyRegister(uint8_t address, uint8_t mask, uint8_t value);
|
||||||
|
void writeRegister(uint8_t address, uint8_t value);
|
||||||
|
|
||||||
|
static void onInterrupt(void* arg);
|
||||||
|
|
||||||
|
private:
|
||||||
|
gpio_num_t _rxPin;
|
||||||
|
gpio_num_t _txPin;
|
||||||
|
bool _loopback;
|
||||||
|
intr_handle_t _intrHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ESP32SJA1000Class CAN;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
495
Easylink_CAN_Waker/lib/arduino-CAN-master/src/MCP2515.cpp
Normal file
495
Easylink_CAN_Waker/lib/arduino-CAN-master/src/MCP2515.cpp
Normal file
|
@ -0,0 +1,495 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#ifndef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
#include "MCP2515.h"
|
||||||
|
|
||||||
|
#define REG_BFPCTRL 0x0c
|
||||||
|
#define REG_TXRTSCTRL 0x0d
|
||||||
|
|
||||||
|
#define REG_CANCTRL 0x0f
|
||||||
|
|
||||||
|
#define REG_CNF3 0x28
|
||||||
|
#define REG_CNF2 0x29
|
||||||
|
#define REG_CNF1 0x2a
|
||||||
|
|
||||||
|
#define REG_CANINTE 0x2b
|
||||||
|
#define REG_CANINTF 0x2c
|
||||||
|
|
||||||
|
#define FLAG_RXnIE(n) (0x01 << n)
|
||||||
|
#define FLAG_RXnIF(n) (0x01 << n)
|
||||||
|
#define FLAG_TXnIF(n) (0x04 << n)
|
||||||
|
|
||||||
|
#define REG_RXFnSIDH(n) (0x00 + (n * 4))
|
||||||
|
#define REG_RXFnSIDL(n) (0x01 + (n * 4))
|
||||||
|
#define REG_RXFnEID8(n) (0x02 + (n * 4))
|
||||||
|
#define REG_RXFnEID0(n) (0x03 + (n * 4))
|
||||||
|
|
||||||
|
#define REG_RXMnSIDH(n) (0x20 + (n * 0x04))
|
||||||
|
#define REG_RXMnSIDL(n) (0x21 + (n * 0x04))
|
||||||
|
#define REG_RXMnEID8(n) (0x22 + (n * 0x04))
|
||||||
|
#define REG_RXMnEID0(n) (0x23 + (n * 0x04))
|
||||||
|
|
||||||
|
#define REG_TXBnCTRL(n) (0x30 + (n * 0x10))
|
||||||
|
#define REG_TXBnSIDH(n) (0x31 + (n * 0x10))
|
||||||
|
#define REG_TXBnSIDL(n) (0x32 + (n * 0x10))
|
||||||
|
#define REG_TXBnEID8(n) (0x33 + (n * 0x10))
|
||||||
|
#define REG_TXBnEID0(n) (0x34 + (n * 0x10))
|
||||||
|
#define REG_TXBnDLC(n) (0x35 + (n * 0x10))
|
||||||
|
#define REG_TXBnD0(n) (0x36 + (n * 0x10))
|
||||||
|
|
||||||
|
#define REG_RXBnCTRL(n) (0x60 + (n * 0x10))
|
||||||
|
#define REG_RXBnSIDH(n) (0x61 + (n * 0x10))
|
||||||
|
#define REG_RXBnSIDL(n) (0x62 + (n * 0x10))
|
||||||
|
#define REG_RXBnEID8(n) (0x63 + (n * 0x10))
|
||||||
|
#define REG_RXBnEID0(n) (0x64 + (n * 0x10))
|
||||||
|
#define REG_RXBnDLC(n) (0x65 + (n * 0x10))
|
||||||
|
#define REG_RXBnD0(n) (0x66 + (n * 0x10))
|
||||||
|
|
||||||
|
#define FLAG_IDE 0x08
|
||||||
|
#define FLAG_SRR 0x10
|
||||||
|
#define FLAG_RTR 0x40
|
||||||
|
#define FLAG_EXIDE 0x08
|
||||||
|
|
||||||
|
#define FLAG_RXM0 0x20
|
||||||
|
#define FLAG_RXM1 0x40
|
||||||
|
|
||||||
|
|
||||||
|
MCP2515Class::MCP2515Class() :
|
||||||
|
CANControllerClass(),
|
||||||
|
_spiSettings(10E6, MSBFIRST, SPI_MODE0),
|
||||||
|
_csPin(MCP2515_DEFAULT_CS_PIN),
|
||||||
|
_intPin(MCP2515_DEFAULT_INT_PIN),
|
||||||
|
_clockFrequency(MCP2515_DEFAULT_CLOCK_FREQUENCY)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MCP2515Class::~MCP2515Class()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::begin(long baudRate)
|
||||||
|
{
|
||||||
|
CANControllerClass::begin(baudRate);
|
||||||
|
|
||||||
|
pinMode(_csPin, OUTPUT);
|
||||||
|
|
||||||
|
// start SPI
|
||||||
|
SPI.begin();
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
writeRegister(REG_CANCTRL, 0x80);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x80) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
long clockFrequency;
|
||||||
|
long baudRate;
|
||||||
|
uint8_t cnf[3];
|
||||||
|
} CNF_MAPPER[] = {
|
||||||
|
{ (long)8E6, (long)1000E3, { 0x00, 0x80, 0x00 } },
|
||||||
|
{ (long)8E6, (long)500E3, { 0x00, 0x90, 0x02 } },
|
||||||
|
{ (long)8E6, (long)250E3, { 0x00, 0xb1, 0x05 } },
|
||||||
|
{ (long)8E6, (long)200E3, { 0x00, 0xb4, 0x06 } },
|
||||||
|
{ (long)8E6, (long)125E3, { 0x01, 0xb1, 0x05 } },
|
||||||
|
{ (long)8E6, (long)100E3, { 0x01, 0xb4, 0x06 } },
|
||||||
|
{ (long)8E6, (long)80E3, { 0x01, 0xbf, 0x07 } },
|
||||||
|
{ (long)8E6, (long)50E3, { 0x03, 0xb4, 0x06 } },
|
||||||
|
{ (long)8E6, (long)40E3, { 0x03, 0xbf, 0x07 } },
|
||||||
|
{ (long)8E6, (long)20E3, { 0x07, 0xbf, 0x07 } },
|
||||||
|
{ (long)8E6, (long)10E3, { 0x0f, 0xbf, 0x07 } },
|
||||||
|
{ (long)8E6, (long)5E3, { 0x1f, 0xbf, 0x07 } },
|
||||||
|
|
||||||
|
{ (long)16E6, (long)1000E3, { 0x00, 0xd0, 0x82 } },
|
||||||
|
{ (long)16E6, (long)500E3, { 0x00, 0xf0, 0x86 } },
|
||||||
|
{ (long)16E6, (long)250E3, { 0x41, 0xf1, 0x85 } },
|
||||||
|
{ (long)16E6, (long)200E3, { 0x01, 0xfa, 0x87 } },
|
||||||
|
{ (long)16E6, (long)125E3, { 0x03, 0xf0, 0x86 } },
|
||||||
|
{ (long)16E6, (long)100E3, { 0x03, 0xfa, 0x87 } },
|
||||||
|
{ (long)16E6, (long)80E3, { 0x03, 0xff, 0x87 } },
|
||||||
|
{ (long)16E6, (long)50E3, { 0x07, 0xfa, 0x87 } },
|
||||||
|
{ (long)16E6, (long)40E3, { 0x07, 0xff, 0x87 } },
|
||||||
|
{ (long)16E6, (long)20E3, { 0x0f, 0xff, 0x87 } },
|
||||||
|
{ (long)16E6, (long)10E3, { 0x1f, 0xff, 0x87 } },
|
||||||
|
{ (long)16E6, (long)5E3, { 0x3f, 0xff, 0x87 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t* cnf = NULL;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < (sizeof(CNF_MAPPER) / sizeof(CNF_MAPPER[0])); i++) {
|
||||||
|
if (CNF_MAPPER[i].clockFrequency == _clockFrequency && CNF_MAPPER[i].baudRate == baudRate) {
|
||||||
|
cnf = CNF_MAPPER[i].cnf;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnf == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeRegister(REG_CNF1, cnf[0]);
|
||||||
|
writeRegister(REG_CNF2, cnf[1]);
|
||||||
|
writeRegister(REG_CNF3, cnf[2]);
|
||||||
|
|
||||||
|
writeRegister(REG_CANINTE, FLAG_RXnIE(1) | FLAG_RXnIE(0));
|
||||||
|
writeRegister(REG_BFPCTRL, 0x00);
|
||||||
|
writeRegister(REG_TXRTSCTRL, 0x00);
|
||||||
|
writeRegister(REG_RXBnCTRL(0), FLAG_RXM1 | FLAG_RXM0);
|
||||||
|
writeRegister(REG_RXBnCTRL(1), FLAG_RXM1 | FLAG_RXM0);
|
||||||
|
|
||||||
|
writeRegister(REG_CANCTRL, 0x00);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x00) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::end()
|
||||||
|
{
|
||||||
|
SPI.end();
|
||||||
|
|
||||||
|
CANControllerClass::end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::endPacket()
|
||||||
|
{
|
||||||
|
if (!CANControllerClass::endPacket()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (_txExtended) {
|
||||||
|
writeRegister(REG_TXBnSIDH(n), _txId >> 21);
|
||||||
|
writeRegister(REG_TXBnSIDL(n), (((_txId >> 18) & 0x07) << 5) | FLAG_EXIDE | ((_txId >> 16) & 0x03));
|
||||||
|
writeRegister(REG_TXBnEID8(n), (_txId >> 8) & 0xff);
|
||||||
|
writeRegister(REG_TXBnEID0(n), _txId & 0xff);
|
||||||
|
} else {
|
||||||
|
writeRegister(REG_TXBnSIDH(n), _txId >> 3);
|
||||||
|
writeRegister(REG_TXBnSIDL(n), _txId << 5);
|
||||||
|
writeRegister(REG_TXBnEID8(n), 0x00);
|
||||||
|
writeRegister(REG_TXBnEID0(n), 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_txRtr) {
|
||||||
|
writeRegister(REG_TXBnDLC(n), 0x40 | _txLength);
|
||||||
|
} else {
|
||||||
|
writeRegister(REG_TXBnDLC(n), _txLength);
|
||||||
|
|
||||||
|
for (int i = 0; i < _txLength; i++) {
|
||||||
|
writeRegister(REG_TXBnD0(n) + i, _txData[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeRegister(REG_TXBnCTRL(n), 0x08);
|
||||||
|
|
||||||
|
bool aborted = false;
|
||||||
|
|
||||||
|
while (readRegister(REG_TXBnCTRL(n)) & 0x08) {
|
||||||
|
if (readRegister(REG_TXBnCTRL(n)) & 0x10) {
|
||||||
|
// abort
|
||||||
|
aborted = true;
|
||||||
|
|
||||||
|
modifyRegister(REG_CANCTRL, 0x10, 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aborted) {
|
||||||
|
// clear abort command
|
||||||
|
modifyRegister(REG_CANCTRL, 0x10, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyRegister(REG_CANINTF, FLAG_TXnIF(n), 0x00);
|
||||||
|
|
||||||
|
return (readRegister(REG_TXBnCTRL(n)) & 0x70) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::parsePacket()
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
uint8_t intf = readRegister(REG_CANINTF);
|
||||||
|
|
||||||
|
if (intf & FLAG_RXnIF(0)) {
|
||||||
|
n = 0;
|
||||||
|
} else if (intf & FLAG_RXnIF(1)) {
|
||||||
|
n = 1;
|
||||||
|
} else {
|
||||||
|
_rxId = -1;
|
||||||
|
_rxExtended = false;
|
||||||
|
_rxRtr = false;
|
||||||
|
_rxLength = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rxExtended = (readRegister(REG_RXBnSIDL(n)) & FLAG_IDE) ? true : false;
|
||||||
|
|
||||||
|
uint32_t idA = ((readRegister(REG_RXBnSIDH(n)) << 3) & 0x07f8) | ((readRegister(REG_RXBnSIDL(n)) >> 5) & 0x07);
|
||||||
|
if (_rxExtended) {
|
||||||
|
uint32_t idB = (((uint32_t)(readRegister(REG_RXBnSIDL(n)) & 0x03) << 16) & 0x30000) | ((readRegister(REG_RXBnEID8(n)) << 8) & 0xff00) | readRegister(REG_RXBnEID0(n));
|
||||||
|
|
||||||
|
_rxId = (idA << 18) | idB;
|
||||||
|
_rxRtr = (readRegister(REG_RXBnDLC(n)) & FLAG_RTR) ? true : false;
|
||||||
|
} else {
|
||||||
|
_rxId = idA;
|
||||||
|
_rxRtr = (readRegister(REG_RXBnSIDL(n)) & FLAG_SRR) ? true : false;
|
||||||
|
}
|
||||||
|
_rxDlc = readRegister(REG_RXBnDLC(n)) & 0x0f;
|
||||||
|
_rxIndex = 0;
|
||||||
|
|
||||||
|
if (_rxRtr) {
|
||||||
|
_rxLength = 0;
|
||||||
|
} else {
|
||||||
|
_rxLength = _rxDlc;
|
||||||
|
|
||||||
|
for (int i = 0; i < _rxLength; i++) {
|
||||||
|
_rxData[i] = readRegister(REG_RXBnD0(n) + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modifyRegister(REG_CANINTF, FLAG_RXnIF(n), 0x00);
|
||||||
|
|
||||||
|
return _rxDlc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::onReceive(void(*callback)(int))
|
||||||
|
{
|
||||||
|
CANControllerClass::onReceive(callback);
|
||||||
|
|
||||||
|
pinMode(_intPin, INPUT);
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
SPI.usingInterrupt(digitalPinToInterrupt(_intPin));
|
||||||
|
attachInterrupt(digitalPinToInterrupt(_intPin), MCP2515Class::onInterrupt, LOW);
|
||||||
|
} else {
|
||||||
|
detachInterrupt(digitalPinToInterrupt(_intPin));
|
||||||
|
#ifdef SPI_HAS_NOTUSINGINTERRUPT
|
||||||
|
SPI.notUsingInterrupt(digitalPinToInterrupt(_intPin));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::filter(int id, int mask)
|
||||||
|
{
|
||||||
|
id &= 0x7ff;
|
||||||
|
mask &= 0x7ff;
|
||||||
|
|
||||||
|
// config mode
|
||||||
|
writeRegister(REG_CANCTRL, 0x80);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x80) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < 2; n++) {
|
||||||
|
// standard only
|
||||||
|
writeRegister(REG_RXBnCTRL(n), FLAG_RXM0);
|
||||||
|
writeRegister(REG_RXBnCTRL(n), FLAG_RXM0);
|
||||||
|
|
||||||
|
writeRegister(REG_RXMnSIDH(n), mask >> 3);
|
||||||
|
writeRegister(REG_RXMnSIDL(n), mask << 5);
|
||||||
|
writeRegister(REG_RXMnEID8(n), 0);
|
||||||
|
writeRegister(REG_RXMnEID0(n), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < 6; n++) {
|
||||||
|
writeRegister(REG_RXFnSIDH(n), id >> 3);
|
||||||
|
writeRegister(REG_RXFnSIDL(n), id << 5);
|
||||||
|
writeRegister(REG_RXFnEID8(n), 0);
|
||||||
|
writeRegister(REG_RXFnEID0(n), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal mode
|
||||||
|
writeRegister(REG_CANCTRL, 0x00);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x00) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::filterExtended(long id, long mask)
|
||||||
|
{
|
||||||
|
id &= 0x1FFFFFFF;
|
||||||
|
mask &= 0x1FFFFFFF;
|
||||||
|
|
||||||
|
// config mode
|
||||||
|
writeRegister(REG_CANCTRL, 0x80);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x80) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < 2; n++) {
|
||||||
|
// extended only
|
||||||
|
writeRegister(REG_RXBnCTRL(n), FLAG_RXM1);
|
||||||
|
writeRegister(REG_RXBnCTRL(n), FLAG_RXM1);
|
||||||
|
|
||||||
|
writeRegister(REG_RXMnSIDH(n), mask >> 21);
|
||||||
|
writeRegister(REG_RXMnSIDL(n), (((mask >> 18) & 0x03) << 5) | FLAG_EXIDE | ((mask >> 16) & 0x03));
|
||||||
|
writeRegister(REG_RXMnEID8(n), (mask >> 8) & 0xff);
|
||||||
|
writeRegister(REG_RXMnEID0(n), mask & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < 6; n++) {
|
||||||
|
writeRegister(REG_RXFnSIDH(n), id >> 21);
|
||||||
|
writeRegister(REG_RXFnSIDL(n), (((id >> 18) & 0x03) << 5) | FLAG_EXIDE | ((id >> 16) & 0x03));
|
||||||
|
writeRegister(REG_RXFnEID8(n), (id >> 8) & 0xff);
|
||||||
|
writeRegister(REG_RXFnEID0(n), id & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal mode
|
||||||
|
writeRegister(REG_CANCTRL, 0x00);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x00) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::observe()
|
||||||
|
{
|
||||||
|
writeRegister(REG_CANCTRL, 0x60);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x60) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::loopback()
|
||||||
|
{
|
||||||
|
writeRegister(REG_CANCTRL, 0x40);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x40) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::sleep()
|
||||||
|
{
|
||||||
|
writeRegister(REG_CANCTRL, 0x01);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x01) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MCP2515Class::wakeup()
|
||||||
|
{
|
||||||
|
writeRegister(REG_CANCTRL, 0x00);
|
||||||
|
if (readRegister(REG_CANCTRL) != 0x00) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::setPins(int cs, int irq)
|
||||||
|
{
|
||||||
|
_csPin = cs;
|
||||||
|
_intPin = irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::setSPIFrequency(uint32_t frequency)
|
||||||
|
{
|
||||||
|
_spiSettings = SPISettings(frequency, MSBFIRST, SPI_MODE0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::setClockFrequency(long clockFrequency)
|
||||||
|
{
|
||||||
|
_clockFrequency = clockFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::dumpRegisters(Stream& out)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 128; i++) {
|
||||||
|
byte b = readRegister(i);
|
||||||
|
|
||||||
|
out.print("0x");
|
||||||
|
if (i < 16) {
|
||||||
|
out.print('0');
|
||||||
|
}
|
||||||
|
out.print(i, HEX);
|
||||||
|
out.print(": 0x");
|
||||||
|
if (b < 16) {
|
||||||
|
out.print('0');
|
||||||
|
}
|
||||||
|
out.println(b, HEX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::reset()
|
||||||
|
{
|
||||||
|
SPI.beginTransaction(_spiSettings);
|
||||||
|
digitalWrite(_csPin, LOW);
|
||||||
|
SPI.transfer(0xc0);
|
||||||
|
digitalWrite(_csPin, HIGH);
|
||||||
|
SPI.endTransaction();
|
||||||
|
|
||||||
|
delayMicroseconds(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::handleInterrupt()
|
||||||
|
{
|
||||||
|
if (readRegister(REG_CANINTF) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (parsePacket() || _rxId != -1) {
|
||||||
|
_onReceive(available());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t MCP2515Class::readRegister(uint8_t address)
|
||||||
|
{
|
||||||
|
uint8_t value;
|
||||||
|
|
||||||
|
SPI.beginTransaction(_spiSettings);
|
||||||
|
digitalWrite(_csPin, LOW);
|
||||||
|
SPI.transfer(0x03);
|
||||||
|
SPI.transfer(address);
|
||||||
|
value = SPI.transfer(0x00);
|
||||||
|
digitalWrite(_csPin, HIGH);
|
||||||
|
SPI.endTransaction();
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::modifyRegister(uint8_t address, uint8_t mask, uint8_t value)
|
||||||
|
{
|
||||||
|
SPI.beginTransaction(_spiSettings);
|
||||||
|
digitalWrite(_csPin, LOW);
|
||||||
|
SPI.transfer(0x05);
|
||||||
|
SPI.transfer(address);
|
||||||
|
SPI.transfer(mask);
|
||||||
|
SPI.transfer(value);
|
||||||
|
digitalWrite(_csPin, HIGH);
|
||||||
|
SPI.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::writeRegister(uint8_t address, uint8_t value)
|
||||||
|
{
|
||||||
|
SPI.beginTransaction(_spiSettings);
|
||||||
|
digitalWrite(_csPin, LOW);
|
||||||
|
SPI.transfer(0x02);
|
||||||
|
SPI.transfer(address);
|
||||||
|
SPI.transfer(value);
|
||||||
|
digitalWrite(_csPin, HIGH);
|
||||||
|
SPI.endTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MCP2515Class::onInterrupt()
|
||||||
|
{
|
||||||
|
CAN.handleInterrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
MCP2515Class CAN;
|
||||||
|
|
||||||
|
#endif
|
77
Easylink_CAN_Waker/lib/arduino-CAN-master/src/MCP2515.h
Normal file
77
Easylink_CAN_Waker/lib/arduino-CAN-master/src/MCP2515.h
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// Copyright (c) Sandeep Mistry. All rights reserved.
|
||||||
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
|
#ifndef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
#ifndef MCP2515_H
|
||||||
|
#define MCP2515_H
|
||||||
|
|
||||||
|
#include <SPI.h>
|
||||||
|
|
||||||
|
#include "CANController.h"
|
||||||
|
|
||||||
|
#define MCP2515_DEFAULT_CLOCK_FREQUENCY 16e6
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_SAMD) && defined(PIN_SPI_MISO) && defined(PIN_SPI_MOSI) && defined(PIN_SPI_SCK) && (PIN_SPI_MISO == 10) && (PIN_SPI_MOSI == 8) && (PIN_SPI_SCK == 9)
|
||||||
|
// Arduino MKR board: MKR CAN shield CS is pin 3, INT is pin 7
|
||||||
|
#define MCP2515_DEFAULT_CS_PIN 3
|
||||||
|
#define MCP2515_DEFAULT_INT_PIN 7
|
||||||
|
#else
|
||||||
|
#define MCP2515_DEFAULT_CS_PIN 10
|
||||||
|
#define MCP2515_DEFAULT_INT_PIN 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class MCP2515Class : public CANControllerClass {
|
||||||
|
|
||||||
|
public:
|
||||||
|
MCP2515Class();
|
||||||
|
virtual ~MCP2515Class();
|
||||||
|
|
||||||
|
virtual int begin(long baudRate);
|
||||||
|
virtual void end();
|
||||||
|
|
||||||
|
virtual int endPacket();
|
||||||
|
|
||||||
|
virtual int parsePacket();
|
||||||
|
|
||||||
|
virtual void onReceive(void(*callback)(int));
|
||||||
|
|
||||||
|
using CANControllerClass::filter;
|
||||||
|
virtual int filter(int id, int mask);
|
||||||
|
using CANControllerClass::filterExtended;
|
||||||
|
virtual int filterExtended(long id, long mask);
|
||||||
|
|
||||||
|
virtual int observe();
|
||||||
|
virtual int loopback();
|
||||||
|
virtual int sleep();
|
||||||
|
virtual int wakeup();
|
||||||
|
|
||||||
|
void setPins(int cs = MCP2515_DEFAULT_CS_PIN, int irq = MCP2515_DEFAULT_INT_PIN);
|
||||||
|
void setSPIFrequency(uint32_t frequency);
|
||||||
|
void setClockFrequency(long clockFrequency);
|
||||||
|
|
||||||
|
void dumpRegisters(Stream& out);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void handleInterrupt();
|
||||||
|
|
||||||
|
uint8_t readRegister(uint8_t address);
|
||||||
|
void modifyRegister(uint8_t address, uint8_t mask, uint8_t value);
|
||||||
|
void writeRegister(uint8_t address, uint8_t value);
|
||||||
|
|
||||||
|
static void onInterrupt();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SPISettings _spiSettings;
|
||||||
|
int _csPin;
|
||||||
|
int _intPin;
|
||||||
|
long _clockFrequency;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MCP2515Class CAN;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,8 +8,8 @@
|
||||||
; Please visit documentation for the other options and examples
|
; Please visit documentation for the other options and examples
|
||||||
; https://docs.platformio.org/page/projectconf.html
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
[env:megaatmega2560]
|
[env:nodemcu-32s]
|
||||||
platform = atmelavr
|
platform = espressif32
|
||||||
board = megaatmega2560
|
board = nodemcu-32s
|
||||||
framework = arduino
|
framework = arduino
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
|
@ -1,8 +1,6 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <mcp_canbus.h>
|
#include <CAN.h>
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
MCP_CAN CAN0(53); // Set CS pin for MCP2515
|
|
||||||
#define TX_DELAY 3 // Delay between messages
|
#define TX_DELAY 3 // Delay between messages
|
||||||
|
|
||||||
byte sndStat; // Status of the sent message (global variable)
|
byte sndStat; // Status of the sent message (global variable)
|
||||||
|
@ -1177,8 +1175,6 @@ const CanPacket packets[] PROGMEM = {
|
||||||
{0x46F, "10 EE F5 00 24 84 07 30"},
|
{0x46F, "10 EE F5 00 24 84 07 30"},
|
||||||
{0x0AC, "21 7E 00 2E 4F 19 80 A0"},
|
{0x0AC, "21 7E 00 2E 4F 19 80 A0"},
|
||||||
{0x0B4, "F9 60 7E 17 DE 7C 77 CD"},
|
{0x0B4, "F9 60 7E 17 DE 7C 77 CD"},
|
||||||
};
|
|
||||||
/*
|
|
||||||
{0x46F, "30 58 9E 00 24 84 07 30"},
|
{0x46F, "30 58 9E 00 24 84 07 30"},
|
||||||
{0x0AC, "71 7E 00 2E 4F 1D 80 A0"},
|
{0x0AC, "71 7E 00 2E 4F 1D 80 A0"},
|
||||||
{0x46F, "50 92 46 00 24 84 07 30"},
|
{0x46F, "50 92 46 00 24 84 07 30"},
|
||||||
|
@ -1411,7 +1407,7 @@ const CanPacket packets[] PROGMEM = {
|
||||||
{0x47F, "94 84 96 00 7A 5E C4 00"},
|
{0x47F, "94 84 96 00 7A 5E C4 00"},
|
||||||
{0x0B4, "78 90 7D C7 D9 7C C7 D0"},
|
{0x0B4, "78 90 7D C7 D9 7C C7 D0"},
|
||||||
{0x0AC, "91 7E 00 2E 4F 17 80 A0"},
|
{0x0AC, "91 7E 00 2E 4F 17 80 A0"},
|
||||||
};*/
|
};
|
||||||
|
|
||||||
// Function to send a CAN message
|
// Function to send a CAN message
|
||||||
void sendCanMessage(unsigned long canId, const char* hexString) {
|
void sendCanMessage(unsigned long canId, const char* hexString) {
|
||||||
|
@ -1425,32 +1421,28 @@ void sendCanMessage(unsigned long canId, const char* hexString) {
|
||||||
data[i] = (byte)byteData;
|
data[i] = (byte)byteData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the CAN message
|
CAN.beginPacket(canId);
|
||||||
sndStat = CAN0.sendMsgBuf(canId, 0, len, data);
|
CAN.write(data, len);
|
||||||
|
CAN.endPacket();
|
||||||
|
|
||||||
if (sndStat == CAN_OK) {
|
Serial.print("Message Sent: ID = ");
|
||||||
Serial.print("Message Sent: ID = ");
|
Serial.print(canId, HEX);
|
||||||
Serial.print(canId, HEX);
|
Serial.print(", Data = ");
|
||||||
Serial.print(", Data = ");
|
Serial.println(hexString);
|
||||||
Serial.println(hexString);
|
|
||||||
} else {
|
|
||||||
Serial.println("Error Sending Message...");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.println("CAN_Waker starting up...");
|
Serial.println("CAN_Waker starting up...");
|
||||||
// Initialize MCP2515
|
|
||||||
if (CAN0.begin(CAN_500KBPS) == CAN_OK) {
|
|
||||||
Serial.println("MCP2515 Initialized Successfully!");
|
// start the CAN bus at 500 kbps
|
||||||
} else {
|
if (!CAN.begin(500E3)) {
|
||||||
Serial.println("Error Initializing MCP2515...");
|
Serial.println("Starting CAN failed!");
|
||||||
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//CAN0.setMode(MCP_NORMAL); // Change to normal mode
|
|
||||||
//CAN0.setMode(MODE_ONESHOT); // Change to normal mode
|
|
||||||
delay(2000);
|
delay(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue