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