Line data Source code
1 : // Copyright 2024 Accenture.
2 :
3 : /**
4 : * Contains Cpp2CAN CanId.
5 : * \file CanId.h
6 : * \ingroup cpp2can
7 : */
8 : #pragma once
9 :
10 : #include <cstdint>
11 :
12 : // The value EXTENDED_QUALIFIER_BIT_VALUE is intentionally defined as a macro.
13 : // This allows a check with other definitions on compiler - level.
14 : // Do not remove or change this definition without refactoring !
15 : #define EXTENDED_QUALIFIER_BIT_VALUE 0x80000000U
16 :
17 : namespace can
18 : {
19 : /**
20 : * Helper class for working with base and extended CAN identifiers side-by-side.
21 : *
22 : * CAN identifiers are represented using 32 bit values. Raw CAN identifiers consume up to 29 bits
23 : * (for extended ids). To distinguish base identifiers, extended identifiers and to allow also
24 : * representation of invalid identifiers 2 additional bits are used:
25 : *
26 : * \code{.cpp}
27 : * 0 1 2 3
28 : * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
29 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
30 : * | Raw id |F|I|X|
31 : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 : * \endcode
33 : *
34 : * with
35 : *
36 : * \par Raw id
37 : * 29 bit value holding the identifier value. Typically base identifiers will only
38 : * only consume up to 11 bits. Checking raw identifier values for validity is not scope of this
39 : * class.
40 : *
41 : * \par F
42 : * This bit indicates that the identifier is not compatible with can fd.
43 : *
44 : * \par I
45 : * This bit indicates an invalid identifier if set to 1.
46 : *
47 : * \par X
48 : * This bit indicates whether the identifier is an extended (1) or a base (0) identifier.
49 : */
50 : class CanId
51 : {
52 : CanId();
53 :
54 : public:
55 : /// bit mask for extended qualifier bit.
56 :
57 : static constexpr uint32_t EXTENDED_QUALIFIER_BIT = EXTENDED_QUALIFIER_BIT_VALUE;
58 : /// bit mask for invalid qualifier bit.
59 : static constexpr uint32_t INVALID_QUALIFIER_BIT = 0x40000000U;
60 : /// bit mask for non fd qualifier bit.
61 : static constexpr uint32_t FORCE_NON_FD_QUALIFIER_BIT = 0x20000000U;
62 : /// invalid identifier.
63 : static constexpr uint32_t INVALID_ID = 0xffffffffU;
64 :
65 : /// maximum value for a base identifier (11 bits).
66 : static constexpr uint32_t MAX_RAW_BASE_ID = 0x000007ffU;
67 : /// maximum value for an extended identifier (29 bits).
68 : static constexpr uint32_t MAX_RAW_EXTENDED_ID = 0x1fffffffU;
69 :
70 : /**
71 : * Helper class for retrieving a base CAN identifier at compile time.
72 : * \tparam RawId raw 11 bit base identifier.
73 : * \note The raw identifier is checked for the allowed value range (11 bits) to avoid unintended
74 : * typos
75 : */
76 : template<uint32_t RawId>
77 : struct Base
78 : {
79 : /// check value range
80 : static_assert(RawId <= MAX_RAW_BASE_ID, "");
81 :
82 : /// The represented CAN identifier value.
83 : static uint32_t const value = RawId;
84 : };
85 :
86 : /**
87 : * Helper class for retrieving an extended CAN identifier at compile time.
88 : * \tparam RawId raw 29 bit extended identifier
89 : * \note The raw identifier is checked for the allowed value range (29 bits) to avoid unintended
90 : * typos
91 : */
92 : template<uint32_t RawId>
93 : struct Extended
94 : {
95 : /// check value range
96 : static_assert(RawId <= MAX_RAW_EXTENDED_ID, "");
97 :
98 : /// The represented CAN identifier value.
99 : static uint32_t const value = CanId::EXTENDED_QUALIFIER_BIT | RawId;
100 : };
101 :
102 : /**
103 : * Helper class for retrieving a CAN identifier at compile time.
104 : * \tparam RawId raw identifier: 11 bit in case of normal identifier, 29 bit in case of extended
105 : * identifier \tparam IsExtended flag indicating whether the RawId should be interpreted as a
106 : * base or extended id.
107 : */
108 : template<uint32_t RawId, bool IsExtended>
109 : struct Id : public Base<RawId>
110 : {};
111 :
112 : template<uint32_t RawId>
113 : struct Id<RawId, true> : public Extended<RawId>
114 : {};
115 :
116 : /**
117 : * Helper class for retrieving an invalid CAN identifier at compile time.
118 : */
119 : struct Invalid
120 : {
121 : /// The represented CAN identifier value.
122 : static uint32_t const value = INVALID_ID;
123 : };
124 :
125 : /**
126 : * Convert a raw base identifier to a CAN identifier.
127 : * \param rawId raw base identifier (11 bit)
128 : * \return CAN identifier
129 : */
130 : static uint32_t base(uint16_t baseId);
131 : /**
132 : * Convert a raw extended identifier to a CAN identifier.
133 : * \param rawId raw extended identifier (29 bit)
134 : * \return CAN identifier
135 : */
136 : static uint32_t extended(uint32_t extendedId);
137 : /**
138 : * Convert a raw identifier to a CAN can identifier containing the force fd qualifier.
139 : * \param id raw identifier (29 bit)
140 : * \return new identifier with the force fd qualifiers set.
141 : */
142 : static uint32_t forceNoFd(uint32_t id);
143 : /**
144 : * Create an identifier from either base or extended identifier.
145 : * \param rawId raw value of CAN identifier (11 bit base or 29 bit extended)
146 : * \param isExtended true if the identifier is extended
147 : * \return CAN identifier
148 : */
149 : static uint32_t id(uint32_t value, bool isValueExtended);
150 : /**
151 : * Create an identifier with additional qualifier information.
152 : * \param rawId raw value of CAN identifier (11 bit base or 29 bit extended)
153 : * \param isExtended true if the identifier is extended
154 : * \param forceNoFd true if the force fd flag should be set within the identifier.
155 : * \return CAN identifier
156 : */
157 : static uint32_t id(uint32_t value, bool isValueExtended, bool forceNoFd);
158 : /**
159 : * Get the raw identifier value from a CAN identifier.
160 : * \return 29 bit identifier in case of an extended id, 11 bit base identifier otherwise
161 : */
162 : static uint32_t rawId(uint32_t value);
163 : /**
164 : * Check whether CAN identifier is a base identifier.
165 : * \param id identifier to check for base
166 : * \return true if the given identifier is a base identifier
167 : */
168 : static bool isBase(uint32_t value);
169 : /**
170 : * Check whether CAN identifier is an extended identifier.
171 : * \param id identifier to check for extended
172 : * \return true if the given identifier is a extended identifier
173 : */
174 : static bool isExtended(uint32_t value);
175 : /**
176 : * Check whether CAN identifier has the force fd qualifier set.
177 : * \param id identifier to check for force fd qualifier.
178 : * \return true if the given identifier is a force fd identifier
179 : */
180 : static bool isForceNoFd(uint32_t value);
181 : /**
182 : * Check the validity of a CAN identifier. A valid CAN identifier is either
183 : * a base identifier or an extended identifier.
184 : * \param id identifier to check for validity
185 : * \return true if the given identifier is valid
186 : */
187 : static bool isValid(uint32_t value);
188 : };
189 :
190 : template<uint32_t Id>
191 : uint32_t const CanId::Base<Id>::value;
192 :
193 : template<uint32_t Id>
194 : uint32_t const CanId::Extended<Id>::value;
195 :
196 1 : inline uint32_t CanId::base(uint16_t const baseId) { return static_cast<uint32_t>(baseId); }
197 :
198 1 : inline uint32_t CanId::extended(uint32_t const extendedId)
199 : {
200 1 : return extendedId | EXTENDED_QUALIFIER_BIT;
201 : }
202 :
203 1 : inline uint32_t CanId::forceNoFd(uint32_t const id) { return id | FORCE_NON_FD_QUALIFIER_BIT; }
204 :
205 10 : inline uint32_t CanId::id(uint32_t const value, bool const isValueExtended)
206 : {
207 10 : return value | (isValueExtended ? EXTENDED_QUALIFIER_BIT : 0U);
208 : }
209 :
210 3 : inline uint32_t CanId::id(uint32_t const value, bool const isValueExtended, bool const forceNoFd)
211 : {
212 3 : return value | (isValueExtended ? EXTENDED_QUALIFIER_BIT : 0U)
213 3 : | (forceNoFd ? FORCE_NON_FD_QUALIFIER_BIT : 0U);
214 : }
215 :
216 3 : inline uint32_t CanId::rawId(uint32_t const value)
217 : {
218 3 : return value & (~(EXTENDED_QUALIFIER_BIT | FORCE_NON_FD_QUALIFIER_BIT));
219 : }
220 :
221 54 : inline bool CanId::isValid(uint32_t const value) { return (value & INVALID_QUALIFIER_BIT) == 0U; }
222 :
223 74 : inline bool CanId::isBase(uint32_t const value) { return (value & EXTENDED_QUALIFIER_BIT) == 0U; }
224 :
225 2 : inline bool CanId::isExtended(uint32_t const value)
226 : {
227 2 : return (value & EXTENDED_QUALIFIER_BIT) != 0U;
228 : }
229 :
230 2 : inline bool CanId::isForceNoFd(uint32_t const value)
231 : {
232 2 : return (value & FORCE_NON_FD_QUALIFIER_BIT) != 0U;
233 : }
234 :
235 : } /* namespace can */
|