-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathODriveESP32TWAI.hpp
More file actions
66 lines (53 loc) · 1.71 KB
/
ODriveESP32TWAI.hpp
File metadata and controls
66 lines (53 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// CAN glue layer for ESP32 platforms using the native TWAI driver.
// See ODriveHardwareCAN.hpp for documentation.
#pragma once
#include "ODriveCAN.h"
#include "driver/twai.h"
// Simple struct to hold TWAI interface state. Unlike other platforms, ESP32's
// TWAI driver uses global functions rather than a class instance.
struct ESP32TWAIIntf {
bool initialized = false;
};
struct CanMsg {
uint32_t id;
uint8_t len;
uint8_t buffer[8];
};
// Must be defined by the application
void onCanMessage(const CanMsg& msg);
static bool sendMsg(ESP32TWAIIntf& intf, uint32_t id, uint8_t length, const uint8_t* data) {
if (!intf.initialized) {
return false;
}
twai_message_t tx_msg = {};
tx_msg.identifier = id;
tx_msg.data_length_code = length;
tx_msg.extd = (id > 0x7FF) ? 1 : 0;
tx_msg.rtr = (data == nullptr) ? 1 : 0;
if (data) {
for (int i = 0; i < length; ++i) {
tx_msg.data[i] = data[i];
}
}
return twai_transmit(&tx_msg, pdMS_TO_TICKS(100)) == ESP_OK;
}
static void onReceive(const CanMsg& msg, ODriveCAN& odrive) {
odrive.onReceive(msg.id, msg.len, msg.buffer);
}
static void pumpEvents(ESP32TWAIIntf& intf, int max_events = 100) {
if (!intf.initialized) {
return;
}
// max_events prevents an infinite loop if messages come at a high rate
twai_message_t rx_msg;
while (twai_receive(&rx_msg, 0) == ESP_OK && max_events--) {
CanMsg msg;
msg.id = rx_msg.identifier;
msg.len = rx_msg.data_length_code;
for (int i = 0; i < rx_msg.data_length_code && i < 8; ++i) {
msg.buffer[i] = rx_msg.data[i];
}
onCanMessage(msg);
}
}
CREATE_CAN_INTF_WRAPPER(ESP32TWAIIntf)