can: Add big endian CAN frame layout handle
authorCorentin Le Gall <corentin.legall@iot.bzh>
Thu, 14 Nov 2019 18:13:25 +0000 (19:13 +0100)
committerRomain Forlot <romain.forlot@iot.bzh>
Thu, 14 Nov 2019 18:13:25 +0000 (19:13 +0100)
- can-decoder.cpp: translate_signal() : Tests "frame_layout_is_little".
If false the signal's bit position is changed to fit the layout.

- message-definition.cpp: Added the new attribute
"frame_layout_is_little" and its getter.

- signals.cpp: Added a setter to the bit_position attribute.

- converter.cpp: Added a methode to convert a big endian bit_position
to a right (little endian) bit_position.

Change-Id: I004c9069eb00f389564927cd12d1b30470c3a59d
Signed-off-by: Corentin Le Gall <corentin.legall@iot.bzh>
low-can-binding/can/can-decoder.cpp
low-can-binding/can/message-definition.cpp
low-can-binding/can/message-definition.hpp
low-can-binding/can/signals.cpp
low-can-binding/can/signals.hpp
low-can-binding/utils/converter.cpp
low-can-binding/utils/converter.hpp

index e901240..a6b6c14 100644 (file)
@@ -294,7 +294,10 @@ openxc_DynamicField decoder_t::decode_state(signal_t& signal, std::shared_ptr<me
 ///
 openxc_DynamicField decoder_t::translate_signal(signal_t& signal, std::shared_ptr<message_t> message, bool* send)
 {
-
+       if(!signal.get_message()->frame_layout_is_little())
+       {
+               signal.set_bit_position(converter_t::bit_position_swap(signal.get_bit_position(),signal.get_bit_size()));
+       }       
        // Must call the decoders every time, regardless of if we are going to
        // decide to send the signal or not.
        openxc_DynamicField decoded_value = decoder_t::decode_signal(signal,
index 114307e..8060982 100644 (file)
@@ -23,6 +23,7 @@ message_definition_t::message_definition_t(
        const std::string bus,
        uint32_t id,
        uint32_t flags,
+       bool frame_layout_is_little,
        frequency_clock_t frequency_clock,
        bool force_send_changed,
        const vect_ptr_signal_t& signals)
@@ -30,6 +31,7 @@ message_definition_t::message_definition_t(
        bus_{bus},
        id_{id},
        flags_{flags},
+       frame_layout_is_little_{frame_layout_is_little},
        frequency_clock_{frequency_clock},
        force_send_changed_{force_send_changed},
        last_value_{CAN_MESSAGE_SIZE},
@@ -41,6 +43,7 @@ message_definition_t::message_definition_t(const std::string bus,
        const std::string name,
        uint32_t length,
        uint32_t flags,
+       bool frame_layout_is_little,
        frequency_clock_t frequency_clock,
        bool force_send_changed,
        const vect_ptr_signal_t& signals)
@@ -50,6 +53,7 @@ message_definition_t::message_definition_t(const std::string bus,
        name_{name},
        length_{length},
        flags_{flags},
+       frame_layout_is_little_{frame_layout_is_little},
        frequency_clock_{frequency_clock},
        force_send_changed_{force_send_changed},
        last_value_{CAN_MESSAGE_SIZE},
@@ -112,3 +116,7 @@ uint32_t message_definition_t::get_flags() const
 {
        return flags_;
 }
+
+bool message_definition_t::frame_layout_is_little() const{
+       return frame_layout_is_little_;
+}
index ca264b7..9d615ff 100644 (file)
@@ -49,6 +49,8 @@ private:
        frequency_clock_t frequency_clock_; ///<  clock_ - an optional frequency clock to control the output of this
                                                        ///      message, if sent raw, or simply to mark the max frequency for custom
                                                        ///      handlers to retrieve.*/
+       bool frame_layout_is_little_; ///<frame_layout_is_little_ Defines if the can frame layout is little endian or big endian.
+                                                                 /// Default is true;
        bool force_send_changed_; ///< force_send_changed_ - If true, regardless of the frequency, it will send CAN
                                                        ///     message if it has changed when using raw passthrough.*/
        std::vector<uint8_t> last_value_; ///< last_value_ - The last received value of the message. Defaults to undefined.
@@ -64,6 +66,7 @@ public:
        message_definition_t(const std::string bus,
                                 uint32_t id,
                                 uint32_t flags,
+                                bool frame_layout_is_little,
                                 frequency_clock_t frequency_clock,
                                 bool force_send_changed,
                                 const vect_ptr_signal_t& signals);
@@ -72,6 +75,7 @@ public:
                                 std::string name,
                                 uint32_t length,
                                 uint32_t flags,
+                                bool frame_layout_is_little,
                                 frequency_clock_t frequency_clock,
                                 bool force_send_changed,
                                 const vect_ptr_signal_t& signals);
@@ -87,6 +91,7 @@ public:
        vect_ptr_signal_t& get_signals();
        uint32_t get_length() const;
        uint32_t get_flags() const;
+       bool frame_layout_is_little() const;
 
        void set_parent(std::shared_ptr<message_set_t> parent);
        void set_last_value(std::shared_ptr<message_t>  m);
index 57aefa5..2b87dc6 100755 (executable)
@@ -220,7 +220,12 @@ void signal_t::set_timestamp(uint64_t timestamp)
        frequency_.tick(timestamp);
 }
 
-std::pair<bool, int> signal_t::get_multiplex() const
+void signal_t::set_bit_position(uint32_t bit_position)
+{
+       bit_position_=bit_position;
+}
+
+std::pair<bool,int> signal_t::get_multiplex() const
 {
        return multiplex_;
 }
index 32cd760..d9453c5 100755 (executable)
@@ -171,4 +171,5 @@ public:
        void set_received(bool r);
        void set_last_value(float val);
        void set_timestamp(uint64_t timestamp);
+       void set_bit_position(uint32_t bit_position);
 };
index e3db7f3..f790fc0 100644 (file)
@@ -55,3 +55,33 @@ void converter_t::signal_to_bits_bytes(uint32_t bit_position, uint32_t bit_size,
        new_end_byte = (bit_position + bit_size - 1) >> 3;
        new_end_bit = (bit_position + bit_size - 1) % 8;
 }
+
+
+/**
+ * @brief      This is to use when you have a big endian CAN frame layout.
+ *                     It converts the bit position so it matches with little endiant CAN frame layout.
+ *
+ * @param bit_position         Original bit position.
+ * @param bit_size             Size of the data.
+ * @return uint32_t    New little endian bit position.
+ */
+uint32_t converter_t::bit_position_swap(uint32_t bit_position,uint32_t bit_size)
+{
+       uint32_t start_byte_position = (uint32_t)(bit_position/8);
+       uint32_t bit_size_rest = bit_size;
+       if(bit_size<=8 && ((bit_position+bit_size)%8==bit_size || (bit_position+bit_size)%8==0))
+       {
+               return (uint32_t)(start_byte_position*8 + (8-bit_size));
+       }
+       else
+       {
+               do
+               {
+                       bit_size_rest = bit_size_rest - ((start_byte_position+1)*8-bit_position);
+                       start_byte_position--;
+                       bit_position = start_byte_position*8;
+               } while (bit_size_rest>8);
+               return (uint32_t)(start_byte_position*8 + (8-bit_size_rest));
+       }
+
+}
index d24096a..cb52f1a 100644 (file)
@@ -23,5 +23,6 @@ class converter_t
 {
        public:
                static std::string to_hex(const uint8_t data[], const size_t length);
-               static void signal_to_bits_bytes(uint32_t bit_position, uint32_t bit_size, int &new_start_byte, int &new_end_byte, uint8_t &new_start_bit, uint8_t &new_end_bit);
+               static void signal_to_bits_bytes(uint32_t bit_position, uint32_t bit_size, int &new_start_byte, int &new_end_byte, int &new_start_bit, int &new_end_bit);
+               static uint32_t bit_position_swap(uint32_t bit_position,uint32_t bit_size);
 };