PER Firmware
Loading...
Searching...
No Matches
can_codec.h
Go to the documentation of this file.
1#ifndef CAN_CODEC_H
2#define CAN_CODEC_H
3
11#include <stdint.h>
12#include <string.h>
13
14typedef enum : uint8_t {
15 BSWAP_NONE = 0,
16 BSWAP_16 = 16,
17 BSWAP_32 = 32,
18 BSWAP_64 = 64
19} bswap_width_t;
20
21[[gnu::always_inline]]
22static inline uint64_t CAN_apply_bswap(uint64_t raw, bswap_width_t bswap_width) {
23 switch (bswap_width) {
24 case BSWAP_16:
25 return __builtin_bswap16((uint16_t)raw);
26 case BSWAP_32:
27 return __builtin_bswap32((uint32_t)raw);
28 case BSWAP_64:
29 return __builtin_bswap64(raw);
30 default:
31 return raw;
32 }
33}
34
35[[gnu::always_inline]]
36static inline uint64_t CAN_load_payload_u64(const uint8_t *data, uint8_t len) {
37 uint64_t payload = 0;
38 memcpy(&payload, data, len);
39 return payload;
40}
41
42[[gnu::always_inline]]
43static inline void CAN_store_payload_u64(uint8_t *dest, uint64_t payload, uint8_t len) {
44 memcpy(dest, &payload, len);
45}
46
47[[gnu::always_inline]]
48static inline uint64_t CAN_pack_raw_signal(
49 uint64_t payload,
50 uint64_t raw,
51 uint64_t mask,
52 uint8_t bit_shift,
53 bswap_width_t bswap_width
54) {
55 raw &= mask;
56 raw = CAN_apply_bswap(raw, bswap_width);
57 payload |= (raw & mask) << bit_shift;
58 return payload;
59}
60
61[[gnu::always_inline]]
62static inline uint64_t CAN_unpack_raw_signal(
63 uint64_t payload,
64 uint64_t mask,
65 uint8_t bit_shift,
66 bswap_width_t bswap_width
67) {
68 uint64_t raw = (payload >> bit_shift) & mask;
69 return CAN_apply_bswap(raw, bswap_width);
70}
71
72[[gnu::always_inline]]
73static inline int64_t CAN_sign_extend_raw(uint64_t raw, uint8_t bit_length) {
74 if (bit_length == 0) {
75 return 0;
76 }
77 if (bit_length >= 64) {
78 return (int64_t)raw;
79 }
80
81 uint8_t shift = 64U - bit_length;
82 return (int64_t)(raw << shift) >> shift;
83}
84
85[[gnu::always_inline]]
86static inline uint64_t CAN_float32_to_raw(float value) {
87 uint32_t raw = 0;
88 memcpy(&raw, &value, sizeof(raw));
89 return raw;
90}
91
92[[gnu::always_inline]]
93static inline float CAN_raw_to_float32(uint64_t raw) {
94 uint32_t bits = (uint32_t)raw;
95 float value = 0.0f;
96 memcpy(&value, &bits, sizeof(value));
97 return value;
98}
99
100#endif // CAN_CODEC_H