1+ #include < gtest/gtest.h>
2+ #include < gmock/gmock.h>
3+
4+ #include < cstring>
5+ #include " fixed_point.h"
6+ #include " port.h"
7+
8+ #pragma GCC diagnostic push
9+ #pragma GCC diagnostic ignored "-Wunused-const-variable"
10+ namespace ConfigSizes {
11+ constexpr size_t TAG = 4 ;
12+ constexpr size_t NO_LONGER_USED_0 = 1 ;
13+ constexpr size_t AUX_OUT_BINS = 64 ;
14+ constexpr size_t AUX_OUT_VALUES = 64 ;
15+ constexpr size_t AUX_OUTPUT_SOURCE = 2 ;
16+ constexpr size_t SENSOR_TYPE = 1 ;
17+ constexpr size_t AFR_CHANNEL = 8 ;
18+ constexpr size_t AFR_SETTINGS = AFR_CHANNEL * 2 ;
19+ constexpr size_t EGT_CHANNEL = 8 ;
20+ constexpr size_t EGT_SETTINGS = EGT_CHANNEL * 2 ;
21+ constexpr size_t HEATER_CONFIG = 8 ;
22+ }
23+ #pragma GCC diagnostic pop
24+
25+ template <typename T>
26+ void WriteAtOffset (Configuration& config, size_t offset, T value) {
27+ uint8_t * bytes = reinterpret_cast <uint8_t *>(&config);
28+ std::memcpy (bytes + offset, &value, sizeof (T));
29+ }
30+
31+ TEST (ConfigLayout, BinaryCompatibility_NoLongerUsed0) {
32+ Configuration config = {};
33+
34+ size_t offset = ConfigSizes::TAG ;
35+ uint8_t expectedValue = 0x42 ;
36+ WriteAtOffset (config, offset, expectedValue);
37+
38+ EXPECT_EQ (config.NoLongerUsed0 , expectedValue);
39+ }
40+
41+ TEST (ConfigLayout, BinaryCompatibility_AuxOutBins) {
42+ Configuration config = {};
43+
44+ size_t offset = ConfigSizes::TAG
45+ + ConfigSizes::NO_LONGER_USED_0 ;
46+
47+ // Test auxOutBins[0]
48+ for (int i = 0 ; i < 8 ; i++) {
49+ float testValue = 10 .0f + i;
50+ WriteAtOffset (config, offset + i * sizeof (float ), testValue);
51+ }
52+
53+ for (int i = 0 ; i < 8 ; i++) {
54+ EXPECT_FLOAT_EQ (config.auxOutBins [0 ][i], 10 .0f + i);
55+ }
56+
57+ // Test auxOutBins[1]
58+ offset += 8 * sizeof (float );
59+ for (int i = 0 ; i < 8 ; i++) {
60+ float testValue = 20 .0f + i;
61+ WriteAtOffset (config, offset + i * sizeof (float ), testValue);
62+ }
63+
64+ for (int i = 0 ; i < 8 ; i++) {
65+ EXPECT_FLOAT_EQ (config.auxOutBins [1 ][i], 20 .0f + i);
66+ }
67+ }
68+
69+ TEST (ConfigLayout, BinaryCompatibility_AuxOutValues) {
70+ Configuration config = {};
71+
72+ size_t offset = ConfigSizes::TAG
73+ + ConfigSizes::NO_LONGER_USED_0
74+ + ConfigSizes::AUX_OUT_BINS ;
75+
76+ for (int j = 0 ; j < 2 ; j++) {
77+ for (int i = 0 ; i < 8 ; i++) {
78+ float testValue = 100 .0f + j * 10 + i;
79+ WriteAtOffset (config, offset + (j * 8 + i) * sizeof (float ), testValue);
80+ }
81+ }
82+
83+ for (int j = 0 ; j < 2 ; j++) {
84+ for (int i = 0 ; i < 8 ; i++) {
85+ EXPECT_FLOAT_EQ (config.auxOutValues [j][i], 100 .0f + j * 10 + i);
86+ }
87+ }
88+ }
89+
90+ TEST (ConfigLayout, BinaryCompatibility_AuxOutputSource) {
91+ Configuration config = {};
92+
93+ size_t offset = ConfigSizes::TAG
94+ + ConfigSizes::NO_LONGER_USED_0
95+ + ConfigSizes::AUX_OUT_BINS
96+ + ConfigSizes::AUX_OUT_VALUES ;
97+
98+ WriteAtOffset (config, offset, static_cast <uint8_t >(AuxOutputMode::Lambda0));
99+ WriteAtOffset (config, offset + 1 , static_cast <uint8_t >(AuxOutputMode::Egt1));
100+
101+ EXPECT_EQ (config.auxOutputSource [0 ], AuxOutputMode::Lambda0);
102+ EXPECT_EQ (config.auxOutputSource [1 ], AuxOutputMode::Egt1);
103+ }
104+
105+ TEST (ConfigLayout, BinaryCompatibility_SensorType) {
106+ Configuration config = {};
107+
108+ size_t offset = ConfigSizes::TAG
109+ + ConfigSizes::NO_LONGER_USED_0
110+ + ConfigSizes::AUX_OUT_BINS
111+ + ConfigSizes::AUX_OUT_VALUES
112+ + ConfigSizes::AUX_OUTPUT_SOURCE ;
113+
114+ WriteAtOffset (config, offset, static_cast <uint8_t >(SensorType::LSU42 ));
115+
116+ EXPECT_EQ (config.sensorType , SensorType::LSU42 );
117+ }
118+
119+ TEST (ConfigLayout, BinaryCompatibility_AfrChannelSettings) {
120+ Configuration config = {};
121+
122+ size_t offset = ConfigSizes::TAG
123+ + ConfigSizes::NO_LONGER_USED_0
124+ + ConfigSizes::AUX_OUT_BINS
125+ + ConfigSizes::AUX_OUT_VALUES
126+ + ConfigSizes::AUX_OUTPUT_SOURCE
127+ + ConfigSizes::SENSOR_TYPE ;
128+
129+ // Write first AFR channel
130+ uint8_t bitfield0 = 0b00000111 ; // RusEfiTx=1, RusEfiTxDiag=1, AemNetTx=1
131+ WriteAtOffset (config, offset, bitfield0);
132+ WriteAtOffset (config, offset + 1 , static_cast <uint8_t >(5 )); // RusEfiIdx
133+ WriteAtOffset (config, offset + 2 , static_cast <uint8_t >(10 )); // AemNetIdOffset
134+
135+ EXPECT_TRUE (config.afr [0 ].RusEfiTx );
136+ EXPECT_TRUE (config.afr [0 ].RusEfiTxDiag );
137+ EXPECT_TRUE (config.afr [0 ].AemNetTx );
138+ EXPECT_EQ (config.afr [0 ].RusEfiIdx , 5 );
139+ EXPECT_EQ (config.afr [0 ].AemNetIdOffset , 10 );
140+
141+ // Write second AFR channel
142+ offset += ConfigSizes::AFR_CHANNEL ;
143+ uint8_t bitfield1 = 0b00000010 ; // RusEfiTx=0, RusEfiTxDiag=1, AemNetTx=0
144+ WriteAtOffset (config, offset, bitfield1);
145+ WriteAtOffset (config, offset + 1 , static_cast <uint8_t >(7 )); // RusEfiIdx
146+ WriteAtOffset (config, offset + 2 , static_cast <uint8_t >(15 )); // AemNetIdOffset
147+
148+ EXPECT_FALSE (config.afr [1 ].RusEfiTx );
149+ EXPECT_TRUE (config.afr [1 ].RusEfiTxDiag );
150+ EXPECT_FALSE (config.afr [1 ].AemNetTx );
151+ EXPECT_EQ (config.afr [1 ].RusEfiIdx , 7 );
152+ EXPECT_EQ (config.afr [1 ].AemNetIdOffset , 15 );
153+ }
154+
155+ TEST (ConfigLayout, BinaryCompatibility_EgtChannelSettings) {
156+ Configuration config = {};
157+
158+ size_t offset = ConfigSizes::TAG
159+ + ConfigSizes::NO_LONGER_USED_0
160+ + ConfigSizes::AUX_OUT_BINS
161+ + ConfigSizes::AUX_OUT_VALUES
162+ + ConfigSizes::AUX_OUTPUT_SOURCE
163+ + ConfigSizes::SENSOR_TYPE
164+ + ConfigSizes::AFR_SETTINGS ;
165+
166+ // Write first EGT channel
167+ uint8_t bitfield0 = 0b00000101 ; // RusEfiTx=1, RusEfiTxDiag=0, AemNetTx=1
168+ WriteAtOffset (config, offset, bitfield0);
169+ WriteAtOffset (config, offset + 1 , static_cast <uint8_t >(3 )); // RusEfiIdx
170+ WriteAtOffset (config, offset + 2 , static_cast <uint8_t >(8 )); // AemNetIdOffset
171+
172+ EXPECT_TRUE (config.egt [0 ].RusEfiTx );
173+ EXPECT_FALSE (config.egt [0 ].RusEfiTxDiag );
174+ EXPECT_TRUE (config.egt [0 ].AemNetTx );
175+ EXPECT_EQ (config.egt [0 ].RusEfiIdx , 3 );
176+ EXPECT_EQ (config.egt [0 ].AemNetIdOffset , 8 );
177+
178+ // Write second EGT channel
179+ offset += ConfigSizes::EGT_CHANNEL ;
180+ uint8_t bitfield1 = 0b00000010 ; // RusEfiTx=0, RusEfiTxDiag=1, AemNetTx=0
181+ WriteAtOffset (config, offset, bitfield1);
182+ WriteAtOffset (config, offset + 1 , static_cast <uint8_t >(7 )); // RusEfiIdx
183+ WriteAtOffset (config, offset + 2 , static_cast <uint8_t >(15 )); // AemNetIdOffset
184+
185+ EXPECT_FALSE (config.egt [1 ].RusEfiTx );
186+ EXPECT_TRUE (config.egt [1 ].RusEfiTxDiag );
187+ EXPECT_FALSE (config.egt [1 ].AemNetTx );
188+ EXPECT_EQ (config.egt [1 ].RusEfiIdx , 7 );
189+ EXPECT_EQ (config.egt [1 ].AemNetIdOffset , 15 );
190+ }
191+
192+ TEST (ConfigLayout, BinaryCompatibility_HeaterConfig) {
193+ Configuration config = {};
194+
195+ size_t offset = ConfigSizes::TAG
196+ + ConfigSizes::NO_LONGER_USED_0
197+ + ConfigSizes::AUX_OUT_BINS
198+ + ConfigSizes::AUX_OUT_VALUES
199+ + ConfigSizes::AUX_OUTPUT_SOURCE
200+ + ConfigSizes::SENSOR_TYPE
201+ + ConfigSizes::AFR_SETTINGS
202+ + ConfigSizes::EGT_SETTINGS ;
203+
204+ WriteAtOffset (config, offset, static_cast <uint8_t >(120 )); // HeaterSupplyOffVoltage
205+ WriteAtOffset (config, offset + 1 , static_cast <uint8_t >(135 )); // HeaterSupplyOnVoltage
206+ WriteAtOffset (config, offset + 2 , static_cast <uint8_t >(50 )); // HeaterBatteryStabTime
207+ WriteAtOffset (config, offset + 3 , static_cast <uint16_t >(180 )); // PreheatTimeSec
208+ WriteAtOffset (config, offset + 5 , static_cast <uint16_t >(240 )); // WarmupTimeSec
209+
210+ EXPECT_FLOAT_EQ (config.heaterConfig .HeaterSupplyOffVoltage .getValue (), 12 .0f );
211+ EXPECT_FLOAT_EQ (config.heaterConfig .HeaterSupplyOnVoltage .getValue (), 13 .5f );
212+ EXPECT_FLOAT_EQ (config.heaterConfig .HeaterBatteryStabTime .getValue (), 5 .0f );
213+ EXPECT_EQ (config.heaterConfig .PreheatTimeSec , 180 );
214+ EXPECT_EQ (config.heaterConfig .WarmupTimeSec , 240 );
215+ }
216+
217+ TEST (ConfigLayout, SizeVerification) {
218+ // Verify the total size is exactly 256 bytes
219+ EXPECT_EQ (sizeof (Configuration), 256UL );
220+
221+ // Verify union size
222+ Configuration config;
223+ EXPECT_EQ (sizeof (config.pad ), 252UL ); // 256 - 4 (Tag size)
224+ }
0 commit comments