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