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 : inline uint32_t CanId::base(uint16_t const baseId) { return static_cast<uint32_t>(baseId); } 197 : 198 : inline uint32_t CanId::extended(uint32_t const extendedId) 199 : { 200 : return extendedId | EXTENDED_QUALIFIER_BIT; 201 : } 202 : 203 : inline uint32_t CanId::forceNoFd(uint32_t const id) { return id | FORCE_NON_FD_QUALIFIER_BIT; } 204 : 205 6 : 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 : inline uint32_t CanId::id(uint32_t const value, bool const isValueExtended, bool const forceNoFd) 211 : { 212 : return value | (isValueExtended ? EXTENDED_QUALIFIER_BIT : 0U) 213 : | (forceNoFd ? FORCE_NON_FD_QUALIFIER_BIT : 0U); 214 : } 215 : 216 : inline uint32_t CanId::rawId(uint32_t const value) 217 : { 218 : return value & (~(EXTENDED_QUALIFIER_BIT | FORCE_NON_FD_QUALIFIER_BIT)); 219 : } 220 : 221 49 : inline bool CanId::isValid(uint32_t const value) { return (value & INVALID_QUALIFIER_BIT) == 0U; } 222 : 223 63 : inline bool CanId::isBase(uint32_t const value) { return (value & EXTENDED_QUALIFIER_BIT) == 0U; } 224 : 225 : inline bool CanId::isExtended(uint32_t const value) 226 : { 227 : return (value & EXTENDED_QUALIFIER_BIT) != 0U; 228 : } 229 : 230 : inline bool CanId::isForceNoFd(uint32_t const value) 231 : { 232 : return (value & FORCE_NON_FD_QUALIFIER_BIT) != 0U; 233 : } 234 : 235 : } /* namespace can */