2 * Copyright (C) 2015, 2016 "IoT.bzh"
3 * Author "Romain Forlot" <romain.forlot@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include "can-signals.hpp"
22 #include "../binding/configuration.hpp"
23 #include "../utils/signals.hpp"
24 #include "can-decoder.hpp"
25 #include "can-message.hpp"
26 #include "can-bus.hpp"
27 #include "../diagnostic/diagnostic-message.hpp"
28 #include "canutil/write.h"
30 std::string can_signal_t::prefix_ = "messages";
32 can_signal_t::can_signal_t(std::uint8_t message_set_id,
33 std::uint8_t message_id,
34 std::string generic_name,
41 frequency_clock_t frequency,
43 bool force_send_changed,
44 std::map<uint8_t, std::string> states,
46 SignalDecoder decoder,
47 SignalEncoder encoder,
49 : message_set_id_{ message_set_id }
50 , message_id_{ message_id }
51 , generic_name_{ generic_name }
52 , bit_position_{ bit_position }
53 , bit_size_{ bit_size }
56 , min_value_{min_value}
57 , max_value_{max_value}
58 , frequency_{frequency}
59 , send_same_{send_same}
60 , force_send_changed_{force_send_changed}
69 utils::socketcan_bcm_t can_signal_t::get_socket() const
74 can_message_definition_t& can_signal_t::get_message() const
76 return configuration_t::instance().get_can_message_definition(message_set_id_, message_id_);
79 const std::string& can_signal_t::get_generic_name() const
84 const std::string can_signal_t::get_name() const
86 return prefix_ + "." + generic_name_;
89 const std::string& can_signal_t::get_prefix() const
94 uint8_t can_signal_t::get_bit_position() const
99 uint8_t can_signal_t::get_bit_size() const
104 float can_signal_t::get_factor() const
109 float can_signal_t::get_offset() const
114 float can_signal_t::get_min_value() const
119 float can_signal_t::get_max_value() const
124 frequency_clock_t& can_signal_t::get_frequency()
129 bool can_signal_t::get_send_same() const
134 bool can_signal_t::get_force_send_changed() const
136 return force_send_changed_;
139 const std::map<uint8_t, std::string>& can_signal_t::get_states() const
144 const std::string can_signal_t::get_states(uint8_t value)
146 if (value < states_.size())
147 return states_[value];
148 return std::string();
151 size_t can_signal_t::get_state_count() const
153 return states_.size();
156 bool can_signal_t::get_writable() const
161 SignalDecoder& can_signal_t::get_decoder()
166 SignalEncoder& can_signal_t::get_encoder()
171 bool can_signal_t::get_received() const
175 float can_signal_t::get_last_value() const
180 void can_signal_t::set_prefix(std::string val)
185 void can_signal_t::set_received(bool r)
190 void can_signal_t::set_last_value(float val)
195 /// @brief Create a RX_SETUP receive job using the BCM socket.
197 /// @return 0 if ok else -1
198 int can_signal_t::create_rx_filter()
200 // Make sure that socket has been opened.
203 get_message().get_bus_name());
205 uint32_t can_id = get_message().get_id();
207 struct utils::simple_bcm_msg bcm_msg;
208 struct can_frame cfd;
210 memset(&cfd, 0, sizeof(cfd));
211 memset(&bcm_msg.msg_head, 0, sizeof(bcm_msg.msg_head));
212 float val = (float)(1 << bit_size_)-1;
213 float freq = frequency_.frequency_to_period();
217 bcm_msg.msg_head.opcode = RX_SETUP;
218 bcm_msg.msg_head.can_id = can_id;
219 bcm_msg.msg_head.flags = SETTIMER|RX_NO_AUTOTIMER;
220 bcm_msg.msg_head.ival2.tv_sec = long(freq);
221 bcm_msg.msg_head.ival2.tv_usec = (freq - (long)freq) * 1000000;
222 bcm_msg.msg_head.nframes = 1;
223 bitfield_encode_float(val,
231 bcm_msg.frames = cfd;
233 if(socket_ << bcm_msg)
238 void can_signal_t::read_socket()
241 can_bus_t& cbm = configuration_t::instance().get_can_bus_manager();
243 std::lock_guard<std::mutex> can_message_lock(cbm.get_can_message_mutex());
244 { cbm.push_new_can_message(msg); }
245 cbm.get_new_can_message_cv().notify_one();