ESPHome  2024.2.0
canbus.h
Go to the documentation of this file.
1 #pragma once
2 
6 
7 #include <cinttypes>
8 #include <vector>
9 
10 namespace esphome {
11 namespace canbus {
12 
13 enum Error : uint8_t {
14  ERROR_OK = 0,
20 };
21 
22 enum CanSpeed : uint8_t {
44 };
45 
46 class CanbusTrigger;
47 template<typename... Ts> class CanbusSendAction;
48 
49 /* CAN payload length definitions according to ISO 11898-1 */
50 static const uint8_t CAN_MAX_DATA_LENGTH = 8;
51 
52 /*
53 Can Frame describes a normative CAN Frame
54 The RTR = Remote Transmission Request is implemented in every CAN controller but rarely used
55 So currently the flag is passed to and from the hardware but currently ignored to the user application.
56 */
57 struct CanFrame {
58  bool use_extended_id = false;
60  uint32_t can_id; /* 29 or 11 bit CAN_ID */
61  uint8_t can_data_length_code; /* frame payload length in byte (0 .. CAN_MAX_DATA_LENGTH) */
62  uint8_t data[CAN_MAX_DATA_LENGTH] __attribute__((aligned(8)));
63 };
64 
65 class Canbus : public Component {
66  public:
67  Canbus(){};
68  void setup() override;
69  void dump_config() override;
70  float get_setup_priority() const override { return setup_priority::HARDWARE; }
71  void loop() override;
72 
73  void send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request,
74  const std::vector<uint8_t> &data);
75  void send_data(uint32_t can_id, bool use_extended_id, const std::vector<uint8_t> &data) {
76  // for backwards compatibility only
77  this->send_data(can_id, use_extended_id, false, data);
78  }
79  void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
80  void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; }
81  void set_bitrate(CanSpeed bit_rate) { this->bit_rate_ = bit_rate; }
82 
83  void add_trigger(CanbusTrigger *trigger);
84 
85  protected:
86  template<typename... Ts> friend class CanbusSendAction;
87  std::vector<CanbusTrigger *> triggers_{};
88  uint32_t can_id_;
91 
92  virtual bool setup_internal();
93  virtual Error send_message(struct CanFrame *frame);
94  virtual Error read_message(struct CanFrame *frame);
95 };
96 
97 template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public Parented<Canbus> {
98  public:
99  void set_data_template(const std::function<std::vector<uint8_t>(Ts...)> func) {
100  this->data_func_ = func;
101  this->static_ = false;
102  }
103  void set_data_static(const std::vector<uint8_t> &data) {
104  this->data_static_ = data;
105  this->static_ = true;
106  }
107 
108  void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
109 
110  void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; }
111 
112  void set_remote_transmission_request(bool remote_transmission_request) {
113  this->remote_transmission_request_ = remote_transmission_request;
114  }
115 
116  void play(Ts... x) override {
117  auto can_id = this->can_id_.has_value() ? *this->can_id_ : this->parent_->can_id_;
118  auto use_extended_id =
119  this->use_extended_id_.has_value() ? *this->use_extended_id_ : this->parent_->use_extended_id_;
120  if (this->static_) {
121  this->parent_->send_data(can_id, use_extended_id, this->remote_transmission_request_, this->data_static_);
122  } else {
123  auto val = this->data_func_(x...);
124  this->parent_->send_data(can_id, use_extended_id, this->remote_transmission_request_, val);
125  }
126  }
127 
128  protected:
130  optional<bool> use_extended_id_{};
131  bool remote_transmission_request_{false};
132  bool static_{false};
133  std::function<std::vector<uint8_t>(Ts...)> data_func_{};
134  std::vector<uint8_t> data_static_{};
135 };
136 
137 class CanbusTrigger : public Trigger<std::vector<uint8_t>, uint32_t, bool>, public Component {
138  friend class Canbus;
139 
140  public:
141  explicit CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const std::uint32_t can_id_mask,
142  const bool use_extended_id)
143  : parent_(parent), can_id_(can_id), can_id_mask_(can_id_mask), use_extended_id_(use_extended_id){};
144 
145  void set_remote_transmission_request(bool remote_transmission_request) {
146  this->remote_transmission_request_ = remote_transmission_request;
147  }
148 
149  void setup() override { this->parent_->add_trigger(this); }
150 
151  protected:
153  uint32_t can_id_;
154  uint32_t can_id_mask_;
156  optional<bool> remote_transmission_request_{};
157 };
158 
159 } // namespace canbus
160 } // namespace esphome
void setup()
void send_data(uint32_t can_id, bool use_extended_id, const std::vector< uint8_t > &data)
Definition: canbus.h:75
void loop()
void set_data_static(const std::vector< uint8_t > &data)
Definition: canbus.h:103
uint16_t x
Definition: tt21100.cpp:17
float get_setup_priority() const override
Definition: canbus.h:70
uint8_t can_data_length_code
Definition: canbus.h:61
void set_bitrate(CanSpeed bit_rate)
Definition: canbus.h:81
mopeka_std_values val[4]
CanbusTrigger(Canbus *parent, const std::uint32_t can_id, const std::uint32_t can_id_mask, const bool use_extended_id)
Definition: canbus.h:141
void set_can_id(uint32_t can_id)
Definition: canbus.h:108
CanSpeed bit_rate_
Definition: canbus.h:90
void setup() override
Definition: canbus.h:149
bool remote_transmission_request
Definition: canbus.h:59
void set_use_extended_id(bool use_extended_id)
Definition: canbus.h:110
void set_data_template(const std::function< std::vector< uint8_t >(Ts...)> func)
Definition: canbus.h:99
void set_remote_transmission_request(bool remote_transmission_request)
Definition: canbus.h:145
void set_use_extended_id(bool use_extended_id)
Definition: canbus.h:80
void play(Ts... x) override
Definition: canbus.h:116
uint8_t data [CAN_MAX_DATA_LENGTH] __attribute__((aligned(8)))
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
Definition: component.cpp:17
void set_can_id(uint32_t can_id)
Definition: canbus.h:79
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
Helper class to easily give an object a parent of type T.
Definition: helpers.h:515
void set_remote_transmission_request(bool remote_transmission_request)
Definition: canbus.h:112