ESPHome  2023.3.2
esp32_can.cpp
Go to the documentation of this file.
1 #ifdef USE_ESP32
2 #include "esp32_can.h"
3 #include "esphome/core/log.h"
4 
5 #include <driver/twai.h>
6 
7 // WORKAROUND, because CAN_IO_UNUSED is just defined as (-1) in this version
8 // of the framework which does not work with -fpermissive
9 #undef CAN_IO_UNUSED
10 #define CAN_IO_UNUSED ((gpio_num_t) -1)
11 
12 namespace esphome {
13 namespace esp32_can {
14 
15 static const char *const TAG = "esp32_can";
16 
17 static bool get_bitrate(canbus::CanSpeed bitrate, twai_timing_config_t *t_config) {
18  switch (bitrate) {
19  case canbus::CAN_50KBPS:
20  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_50KBITS();
21  return true;
23  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_100KBITS();
24  return true;
26  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_125KBITS();
27  return true;
29  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_250KBITS();
30  return true;
32  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_500KBITS();
33  return true;
35  *t_config = (twai_timing_config_t) TWAI_TIMING_CONFIG_1MBITS();
36  return true;
37  default:
38  return false;
39  }
40 }
41 
43  twai_general_config_t g_config =
44  TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t) this->tx_, (gpio_num_t) this->rx_, TWAI_MODE_NORMAL);
45  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
46  twai_timing_config_t t_config;
47 
48  if (!get_bitrate(this->bit_rate_, &t_config)) {
49  // invalid bit rate
50  this->mark_failed();
51  return false;
52  }
53 
54  // Install TWAI driver
55  if (twai_driver_install(&g_config, &t_config, &f_config) != ESP_OK) {
56  // Failed to install driver
57  this->mark_failed();
58  return false;
59  }
60 
61  // Start TWAI driver
62  if (twai_start() != ESP_OK) {
63  // Failed to start driver
64  this->mark_failed();
65  return false;
66  }
67  return true;
68 }
69 
71  if (frame->can_data_length_code > canbus::CAN_MAX_DATA_LENGTH) {
72  return canbus::ERROR_FAILTX;
73  }
74 
75  uint32_t flags = TWAI_MSG_FLAG_NONE;
76  if (frame->use_extended_id) {
77  flags |= TWAI_MSG_FLAG_EXTD;
78  }
79  if (frame->remote_transmission_request) {
80  flags |= TWAI_MSG_FLAG_RTR;
81  }
82 
83  twai_message_t message = {
84  .flags = flags,
85  .identifier = frame->can_id,
86  .data_length_code = frame->can_data_length_code,
87  };
88  if (!frame->remote_transmission_request) {
89  memcpy(message.data, frame->data, frame->can_data_length_code);
90  }
91 
92  if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
93  return canbus::ERROR_OK;
94  } else {
96  }
97 }
98 
100  twai_message_t message;
101 
102  if (twai_receive(&message, 0) != ESP_OK) {
103  return canbus::ERROR_NOMSG;
104  }
105 
106  frame->can_id = message.identifier;
107  frame->use_extended_id = message.flags & TWAI_MSG_FLAG_EXTD;
108  frame->remote_transmission_request = message.flags & TWAI_MSG_FLAG_RTR;
109  frame->can_data_length_code = message.data_length_code;
110 
111  if (!frame->remote_transmission_request) {
112  size_t dlc =
113  message.data_length_code < canbus::CAN_MAX_DATA_LENGTH ? message.data_length_code : canbus::CAN_MAX_DATA_LENGTH;
114  memcpy(frame->data, message.data, dlc);
115  }
116 
117  return canbus::ERROR_OK;
118 }
119 
120 } // namespace esp32_can
121 } // namespace esphome
122 
123 #endif
bool setup_internal() override
Definition: esp32_can.cpp:42
uint8_t can_data_length_code
Definition: canbus.h:55
CanSpeed bit_rate_
Definition: canbus.h:84
bool remote_transmission_request
Definition: canbus.h:53
const uint32_t flags
Definition: stm32flash.h:85
canbus::Error read_message(struct canbus::CanFrame *frame) override
Definition: esp32_can.cpp:99
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:112
Definition: a4988.cpp:4
canbus::Error send_message(struct canbus::CanFrame *frame) override
Definition: esp32_can.cpp:70