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 : /// maximum value for a base identifier (11 bits).
74 : static constexpr uint32_t MAX_RAW_BASE_ID = 0x000007ffU;
75 : /// maximum value for an extended identifier (29 bits).
76 : static constexpr uint32_t MAX_RAW_EXTENDED_ID = 0x1fffffffU;
77 :
78 : /**
79 : * Helper class for retrieving a base CAN identifier at compile time.
80 : * \tparam RawId raw 11 bit base identifier.
81 : * \note The raw identifier is checked for the allowed value range (11 bits) to avoid unintended
82 : * typos
83 : */
84 : template<uint32_t RawId>
85 : struct Base
86 : {
87 : /// check value range
88 : static_assert(RawId <= MAX_RAW_BASE_ID, "");
89 :
90 : /// The represented CAN identifier value.
91 : static uint32_t const value = RawId;
92 : };
93 :
94 : /**
95 : * Helper class for retrieving an extended CAN identifier at compile time.
96 : * \tparam RawId raw 29 bit extended identifier
97 : * \note The raw identifier is checked for the allowed value range (29 bits) to avoid unintended
98 : * typos
99 : */
100 : template<uint32_t RawId>
101 : struct Extended
102 : {
103 : /// check value range
104 : static_assert(RawId <= MAX_RAW_EXTENDED_ID, "");
105 :
106 : /// The represented CAN identifier value.
107 : static uint32_t const value = CanId::EXTENDED_QUALIFIER_BIT | RawId;
108 : };
109 :
110 : /**
111 : * Helper class for retrieving a CAN identifier at compile time.
112 : * \tparam RawId raw identifier: 11 bit in case of normal identifier, 29 bit in case of extended
113 : * identifier \tparam IsExtended flag indicating whether the RawId should be interpreted as a
114 : * base or extended id.
115 : */
116 : template<uint32_t RawId, bool IsExtended>
117 : struct Id : public Base<RawId>
118 : {};
119 :
120 : template<uint32_t RawId>
121 : struct Id<RawId, true> : public Extended<RawId>
122 : {};
123 :
124 : /**
125 : * Helper class for retrieving an invalid CAN identifier at compile time.
126 : */
127 : struct Invalid
128 : {
129 : /// The represented CAN identifier value.
130 : static uint32_t const value = INVALID_ID;
131 : };
132 :
133 : /**
134 : * Convert a raw base identifier to a CAN identifier.
135 : * \param rawId raw base identifier (11 bit)
136 : * \return CAN identifier
137 : */
138 : static uint32_t base(uint16_t baseId);
139 : /**
140 : * Convert a raw extended identifier to a CAN identifier.
141 : * \param rawId raw extended identifier (29 bit)
142 : * \return CAN identifier
143 : */
144 : static uint32_t extended(uint32_t extendedId);
145 : /**
146 : * Convert a raw identifier to a CAN can identifier containing the force fd qualifier.
147 : * \param id raw identifier (29 bit)
148 : * \return new identifier with the force fd qualifiers set.
149 : */
150 : static uint32_t forceNoFd(uint32_t id);
151 : /**
152 : * Create an identifier from either base or extended identifier.
153 : * \param rawId raw value of CAN identifier (11 bit base or 29 bit extended)
154 : * \param isExtended true if the identifier is extended
155 : * \return CAN identifier
156 : */
157 : static uint32_t id(uint32_t value, bool isValueExtended);
158 : /**
159 : * Create an identifier with additional qualifier information.
160 : * \param rawId raw value of CAN identifier (11 bit base or 29 bit extended)
161 : * \param isExtended true if the identifier is extended
162 : * \param forceNoFd true if the force fd flag should be set within the identifier.
163 : * \return CAN identifier
164 : */
165 : static uint32_t id(uint32_t value, bool isValueExtended, bool forceNoFd);
166 : /**
167 : * Get the raw identifier value from a CAN identifier.
168 : * \return 29 bit identifier in case of an extended id, 11 bit base identifier otherwise
169 : */
170 : static uint32_t rawId(uint32_t value);
171 : /**
172 : * Check whether CAN identifier is a base identifier.
173 : * \param id identifier to check for base
174 : * \return true if the given identifier is a base identifier
175 : */
176 : static bool isBase(uint32_t value);
177 : /**
178 : * Check whether CAN identifier is an extended identifier.
179 : * \param id identifier to check for extended
180 : * \return true if the given identifier is a extended identifier
181 : */
182 : static bool isExtended(uint32_t value);
183 : /**
184 : * Check whether CAN identifier has the force fd qualifier set.
185 : * \param id identifier to check for force fd qualifier.
186 : * \return true if the given identifier is a force fd identifier
187 : */
188 : static bool isForceNoFd(uint32_t value);
189 : /**
190 : * Check the validity of a CAN identifier. A valid CAN identifier is either
191 : * a base identifier or an extended identifier.
192 : * \param id identifier to check for validity
193 : * \return true if the given identifier is valid
194 : */
195 : static bool isValid(uint32_t value);
196 : };
197 :
198 : template<uint32_t Id>
199 : uint32_t const CanId::Base<Id>::value;
200 :
201 : template<uint32_t Id>
202 : uint32_t const CanId::Extended<Id>::value;
203 :
204 1 : inline uint32_t CanId::base(uint16_t const baseId) { return static_cast<uint32_t>(baseId); }
205 :
206 1 : inline uint32_t CanId::extended(uint32_t const extendedId)
207 : {
208 1 : return extendedId | EXTENDED_QUALIFIER_BIT;
209 : }
210 :
211 1 : inline uint32_t CanId::forceNoFd(uint32_t const id) { return id | FORCE_NON_FD_QUALIFIER_BIT; }
212 :
213 10 : inline uint32_t CanId::id(uint32_t const value, bool const isValueExtended)
214 : {
215 10 : return value | (isValueExtended ? EXTENDED_QUALIFIER_BIT : 0U);
216 : }
217 :
218 3 : inline uint32_t CanId::id(uint32_t const value, bool const isValueExtended, bool const forceNoFd)
219 : {
220 3 : return value | (isValueExtended ? EXTENDED_QUALIFIER_BIT : 0U)
221 3 : | (forceNoFd ? FORCE_NON_FD_QUALIFIER_BIT : 0U);
222 : }
223 :
224 3 : inline uint32_t CanId::rawId(uint32_t const value)
225 : {
226 3 : return value & (~(EXTENDED_QUALIFIER_BIT | FORCE_NON_FD_QUALIFIER_BIT));
227 : }
228 :
229 54 : inline bool CanId::isValid(uint32_t const value) { return (value & INVALID_QUALIFIER_BIT) == 0U; }
230 :
231 74 : inline bool CanId::isBase(uint32_t const value) { return (value & EXTENDED_QUALIFIER_BIT) == 0U; }
232 :
233 2 : inline bool CanId::isExtended(uint32_t const value)
234 : {
235 2 : return (value & EXTENDED_QUALIFIER_BIT) != 0U;
236 : }
237 :
238 2 : inline bool CanId::isForceNoFd(uint32_t const value)
239 : {
240 2 : return (value & FORCE_NON_FD_QUALIFIER_BIT) != 0U;
241 : }
242 :
243 : } /* namespace can */
|