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