foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
can_cbs_tx_bms-state.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file can_cbs_tx_bms-state.c
44  * @author foxBMS Team
45  * @date 2021-07-21 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVER
49  * @prefix CANTX
50  *
51  * @brief CAN driver Tx callback implementation
52  * @details CAN Tx callback for state messages
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "bms.h"
57 #include "can_cbs_tx.h"
59 #include "can_helper.h"
60 #include "diag.h"
61 #include "sys_mon.h"
62 
63 #include <math.h>
64 #include <stdint.h>
65 
66 /*========== Macros and Definitions =========================================*/
67 
68 /*========== Static Constant and Variable Definitions =======================*/
69 
70 /*========== Extern Constant and Variable Definitions =======================*/
71 
72 /*========== Static Function Prototypes =====================================*/
73 /** get a boolean for if any timing error (current or recorded) occurred */
74 static bool CANTX_AnySysMonTimingIssueDetected(const CAN_SHIM_s *const kpkCanShim);
75 
76 /*========== Static Function Implementations ================================*/
77 static bool CANTX_AnySysMonTimingIssueDetected(const CAN_SHIM_s *const kpkCanShim) {
78  FAS_ASSERT(kpkCanShim != NULL_PTR);
79  SYSM_TIMING_VIOLATION_RESPONSE_s recordedTimingViolations = {0};
80  SYSM_GetRecordedTimingViolations(&recordedTimingViolations);
81 
82  const bool anyTimingViolation =
83  (recordedTimingViolations.recordedViolationAny ||
89 
90  return anyTimingViolation;
91 }
92 
93 /*========== Extern Function Implementations ================================*/
94 extern uint32_t CANTX_BmsState(
96  uint8_t *pCanData,
97  uint8_t *pMuxId,
98  const CAN_SHIM_s *const kpkCanShim) {
99  FAS_ASSERT(message.id == CANTX_BMS_STATE_ID);
101  FAS_ASSERT(pCanData != NULL_PTR);
102  FAS_ASSERT(pMuxId == NULL_PTR); /* pMuxId is not used here, therefore has to be NULL_PTR */
103  FAS_ASSERT(kpkCanShim != NULL_PTR);
104  uint64_t messageData = 0u;
105 
106  DATA_READ_DATA(kpkCanShim->pTableErrorState, kpkCanShim->pTableInsulation, kpkCanShim->pTableMsl);
107 
108  /* AXIVION Disable Style Generic-NoMagicNumbers: Signal data defined in .dbc file. */
109  /* State */
110  uint64_t data = (uint64_t)BMS_GetState();
111  /* set data in CAN frame */
112  CAN_TxSetMessageDataWithSignalData(&messageData, 3u, 4u, data, message.endianness);
113 
114  /* Connected strings */
115  data = (uint64_t)BMS_GetNumberOfConnectedStrings();
116  /* set data in CAN frame */
117  CAN_TxSetMessageDataWithSignalData(&messageData, 7u, 4u, data, message.endianness);
118 
119  /* General warning: TODO */
120 
121  /* General error - implement now */
123  CAN_TxSetMessageDataWithSignalData(&messageData, 10u, 1u, data, message.endianness);
124 
125  /* Emergency shutoff */
127  CAN_TxSetMessageDataWithSignalData(&messageData, 11u, 1u, data, message.endianness);
128 
129  /* Number of deactivated strings: TODO */
130 
131  /* sys mon error */
133  CAN_TxSetMessageDataWithSignalData(&messageData, 12u, 1u, data, message.endianness);
134 
135  /* Insulation monitoring active */
137  CAN_TxSetMessageDataWithSignalData(&messageData, 13u, 1u, data, message.endianness);
138 
139  /* Error: insulation */
141  CAN_TxSetMessageDataWithSignalData(&messageData, 23u, 1u, data, message.endianness);
142 
143  /* Insulation resistance */
144  float_t signalData = (float_t)kpkCanShim->pTableInsulation->insulationResistance_kOhm;
145  signalData = signalData * 0.1f; /* convert kOhm to 10kOhm */
146  data = (uint64_t)signalData;
147  CAN_TxSetMessageDataWithSignalData(&messageData, 63u, 8u, data, message.endianness);
148 
149  /* Charging complete: TODO */
150 
151  /* Heater state: TODO */
152  /* Cooling state: TODO */
153 
154  /* Error: Precharge voltage */
155  data = 0u; /* No precharge error detected */
156  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
157  if (kpkCanShim->pTableErrorState->prechargeAbortedDueToVoltage[s] == true) {
158  data = 1u;
159  }
160  }
161  CAN_TxSetMessageDataWithSignalData(&messageData, 16u, 1u, data, message.endianness);
162 
163  /* Error: Precharge current */
164  data = 0u; /* No precharge error detected */
165  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
166  if (kpkCanShim->pTableErrorState->prechargeAbortedDueToCurrent[s] == true) {
167  data = 1u;
168  }
169  }
170  CAN_TxSetMessageDataWithSignalData(&messageData, 17u, 1u, data, message.endianness);
171 
172  /* Error: MCU die temperature */
174  CAN_TxSetMessageDataWithSignalData(&messageData, 18u, 1u, data, message.endianness);
175 
176  /* Error: master overtemperature: TODO */
177  /* Error: master undertemperature: TODO */
178 
179  /* Main fuse state */
181  CAN_TxSetMessageDataWithSignalData(&messageData, 21u, 1u, data, message.endianness);
182 
183  /* Error: interlock */
185  CAN_TxSetMessageDataWithSignalData(&messageData, 22u, 1u, data, message.endianness);
186 
187  /* Error: Can timing */
189  CAN_TxSetMessageDataWithSignalData(&messageData, 24u, 1u, data, message.endianness);
190 
191  /* Error: Overcurrent pack charge */
192  data = kpkCanShim->pTableMsl->packChargeOvercurrent;
193  CAN_TxSetMessageDataWithSignalData(&messageData, 25u, 1u, data, message.endianness);
194 
195  /* Error: Overcurrent pack discharge */
196  data = kpkCanShim->pTableMsl->packDischargeOvercurrent;
197  CAN_TxSetMessageDataWithSignalData(&messageData, 26u, 1u, data, message.endianness);
198 
199  /* Error: Alert flag */
201  CAN_TxSetMessageDataWithSignalData(&messageData, 27u, 1u, data, message.endianness);
202 
203  /* Error: NVRAM CRC */
205  CAN_TxSetMessageDataWithSignalData(&messageData, 28u, 1u, data, message.endianness);
206  /* AXIVION Enable Style Generic-NoMagicNumbers: */
207 
208  /* now copy data in the buffer that will be use to send data */
209  CAN_TxSetCanDataWithMessageData(messageData, pCanData, message.endianness);
210 
211  return 0;
212 }
213 
214 extern uint32_t CANTX_BmsStateDetails(
215  CAN_MESSAGE_PROPERTIES_s message,
216  uint8_t *pCanData,
217  uint8_t *pMuxId,
218  const CAN_SHIM_s *const kpkCanShim) {
222  FAS_ASSERT(pCanData != NULL_PTR);
223  FAS_ASSERT(pMuxId == NULL_PTR); /* pMuxId is not used here, therefore has to be NULL_PTR */
224  FAS_ASSERT(kpkCanShim != NULL_PTR);
225  uint64_t messageData = 0u;
226 
227  DATA_READ_DATA(kpkCanShim->pTableErrorState);
228  SYSM_TIMING_VIOLATION_RESPONSE_s recordedTimingViolations = {0};
229  SYSM_GetRecordedTimingViolations(&recordedTimingViolations);
230 
231  /* AXIVION Disable Style Generic-NoMagicNumbers: Signal data defined in .dbc file. */
232  /* current violation engine */
234  CAN_TxSetMessageDataWithSignalData(&messageData, 0u, 1u, data, message.endianness);
235  /* current violation 1ms */
237  CAN_TxSetMessageDataWithSignalData(&messageData, 1u, 1u, data, message.endianness);
238  /* current violation 10ms */
240  CAN_TxSetMessageDataWithSignalData(&messageData, 2u, 1u, data, message.endianness);
241  /* current violation 100ms */
243  CAN_TxSetMessageDataWithSignalData(&messageData, 3u, 1u, data, message.endianness);
244  /* current violation 100ms algorithm */
246  CAN_TxSetMessageDataWithSignalData(&messageData, 4u, 1u, data, message.endianness);
247 
248  /* recorded violation engine */
249  data = CAN_ConvertBooleanToInteger(recordedTimingViolations.recordedViolationEngine);
250  CAN_TxSetMessageDataWithSignalData(&messageData, 8u, 1u, data, message.endianness);
251  /* recorded violation 1ms */
252  data = CAN_ConvertBooleanToInteger(recordedTimingViolations.recordedViolation1ms);
253  CAN_TxSetMessageDataWithSignalData(&messageData, 9u, 1u, data, message.endianness);
254  /* recorded violation 10ms */
255  data = CAN_ConvertBooleanToInteger(recordedTimingViolations.recordedViolation10ms);
256  CAN_TxSetMessageDataWithSignalData(&messageData, 10u, 1u, data, message.endianness);
257  /* recorded violation 100ms */
258  data = CAN_ConvertBooleanToInteger(recordedTimingViolations.recordedViolation100ms);
259  CAN_TxSetMessageDataWithSignalData(&messageData, 11u, 1u, data, message.endianness);
260  /* recorded violation 100ms algorithm */
261  data = CAN_ConvertBooleanToInteger(recordedTimingViolations.recordedViolation100msAlgo);
262  CAN_TxSetMessageDataWithSignalData(&messageData, 12u, 1u, data, message.endianness);
263  /* AXIVION Enable Style Generic-NoMagicNumbers: */
264 
265  /* now copy data in the buffer that will be use to send data */
266  CAN_TxSetCanDataWithMessageData(messageData, pCanData, message.endianness);
267 
268  return 0;
269 }
270 
271 extern uint32_t CANTX_StringState(
272  CAN_MESSAGE_PROPERTIES_s message,
273  uint8_t *pCanData,
274  uint8_t *pMuxId,
275  const CAN_SHIM_s *const kpkCanShim) {
276  FAS_ASSERT(message.id == CANTX_STRING_STATE_ID);
279  FAS_ASSERT(pCanData != NULL_PTR);
280  FAS_ASSERT(pMuxId != NULL_PTR);
281  FAS_ASSERT(*pMuxId < BS_NR_OF_STRINGS);
282  FAS_ASSERT(kpkCanShim != NULL_PTR);
283  uint64_t messageData = 0u;
284  uint64_t data = 0;
285 
286  const uint8_t stringNumber = *pMuxId;
287 
288  /* First signal to transmit cell voltages: get database values */
289  if (stringNumber == 0u) {
290  /* Do not read pTableMsl and pTableErrorState as they already are read
291  * with a higher frequency from CAN_TxState callback */
292  DATA_READ_DATA(kpkCanShim->pTableRsl, kpkCanShim->pTableMol);
293  }
294 
295  /* AXIVION Disable Style Generic-NoMagicNumbers: Signal data defined in .dbc file. */
296  /* mux value */
297  data = (uint64_t)stringNumber;
298  /* set data in CAN frame */
299  CAN_TxSetMessageDataWithSignalData(&messageData, 3u, 4u, data, message.endianness);
300 
301  /* String connected */
302  data = CAN_ConvertBooleanToInteger(BMS_IsStringClosed(stringNumber));
303  CAN_TxSetMessageDataWithSignalData(&messageData, 4u, 1u, data, message.endianness);
304 
305  /* Balancing active: TODO */
306 
307  /* String fuse blown */
308  data = CAN_ConvertBooleanToInteger(kpkCanShim->pTableErrorState->stringFuseError[stringNumber]);
309  CAN_TxSetMessageDataWithSignalData(&messageData, 6u, 1u, data, message.endianness);
310 
311  /* Error: Deep-discharge */
313  CAN_TxSetMessageDataWithSignalData(&messageData, 7u, 1u, data, message.endianness);
314 
315  /* Error: Overtemperature charge */
316  data = kpkCanShim->pTableMsl->overtemperatureCharge[stringNumber];
317  CAN_TxSetMessageDataWithSignalData(&messageData, 8u, 1u, data, message.endianness);
318 
319  /* Error: Undertemperature charge */
320  data = kpkCanShim->pTableMsl->undertemperatureCharge[stringNumber];
321  CAN_TxSetMessageDataWithSignalData(&messageData, 9u, 1u, data, message.endianness);
322 
323  /* Error: Overtemperature discharge */
324  data = kpkCanShim->pTableMsl->overtemperatureDischarge[stringNumber];
325  CAN_TxSetMessageDataWithSignalData(&messageData, 10u, 1u, data, message.endianness);
326 
327  /* Error: Undertemperature discharge */
328  data = kpkCanShim->pTableMsl->undertemperatureDischarge[stringNumber];
329  CAN_TxSetMessageDataWithSignalData(&messageData, 11u, 1u, data, message.endianness);
330 
331  /* Error: Overcurrent charge */
332  if ((kpkCanShim->pTableMsl->cellChargeOvercurrent[stringNumber] == 1u) ||
333  (kpkCanShim->pTableMsl->stringChargeOvercurrent[stringNumber] == 1u)) {
334  data = 1u;
335  } else {
336  data = 0u;
337  }
338  CAN_TxSetMessageDataWithSignalData(&messageData, 12u, 1u, data, message.endianness);
339 
340  /* Error: Overcurrent discharge */
341  if ((kpkCanShim->pTableMsl->cellDischargeOvercurrent[stringNumber] == 1u) ||
342  (kpkCanShim->pTableMsl->stringDischargeOvercurrent[stringNumber] == 1u)) {
343  data = 1u;
344  } else {
345  data = 0u;
346  }
347  CAN_TxSetMessageDataWithSignalData(&messageData, 13u, 1u, data, message.endianness);
348 
349  /* Error: Overvoltage */
350  data = kpkCanShim->pTableMsl->overVoltage[stringNumber];
351  CAN_TxSetMessageDataWithSignalData(&messageData, 14u, 1u, data, message.endianness);
352 
353  /* Error: Undervoltage */
354  data = kpkCanShim->pTableMsl->underVoltage[stringNumber];
355  CAN_TxSetMessageDataWithSignalData(&messageData, 15u, 1u, data, message.endianness);
356 
357  /* Info: Overtemperature charge - MOL */
358  data = kpkCanShim->pTableMol->overtemperatureCharge[stringNumber];
359  CAN_TxSetMessageDataWithSignalData(&messageData, 16u, 1u, data, message.endianness);
360 
361  /* Info: Undertemperature charge - MOL */
362  data = kpkCanShim->pTableMol->undertemperatureCharge[stringNumber];
363  CAN_TxSetMessageDataWithSignalData(&messageData, 17u, 1u, data, message.endianness);
364 
365  /* Info: Overtemperature discharge - MOL */
366  data = kpkCanShim->pTableMol->overtemperatureDischarge[stringNumber];
367  CAN_TxSetMessageDataWithSignalData(&messageData, 18u, 1u, data, message.endianness);
368 
369  /* Info: Undertemperature discharge - MOL */
370  data = kpkCanShim->pTableMol->undertemperatureCharge[stringNumber];
371  CAN_TxSetMessageDataWithSignalData(&messageData, 19u, 1u, data, message.endianness);
372 
373  /* Info: Overcurrent charge - MOL */
374  if ((kpkCanShim->pTableMol->cellChargeOvercurrent[stringNumber] == 1u) ||
375  (kpkCanShim->pTableMol->stringChargeOvercurrent[stringNumber] == 1u)) {
376  data = 1u;
377  } else {
378  data = 0u;
379  }
380  CAN_TxSetMessageDataWithSignalData(&messageData, 20u, 1u, data, message.endianness);
381 
382  /* Info: Overcurrent discharge - MOL */
383  if ((kpkCanShim->pTableMol->cellDischargeOvercurrent[stringNumber] == 1u) ||
384  (kpkCanShim->pTableMol->stringDischargeOvercurrent[stringNumber] == 1u)) {
385  data = 1u;
386  } else {
387  data = 0u;
388  }
389  CAN_TxSetMessageDataWithSignalData(&messageData, 21u, 1u, data, message.endianness);
390 
391  /* Info: Overvoltage - MOL */
392  data = kpkCanShim->pTableMol->overVoltage[stringNumber];
393  CAN_TxSetMessageDataWithSignalData(&messageData, 22u, 1u, data, message.endianness);
394 
395  /* Info: Undervoltage - MOL */
396  data = kpkCanShim->pTableMol->underVoltage[stringNumber];
397  CAN_TxSetMessageDataWithSignalData(&messageData, 23u, 1u, data, message.endianness);
398 
399  /* Warning: Overtemperature charge - RSL */
400  data = kpkCanShim->pTableRsl->overtemperatureCharge[stringNumber];
401  CAN_TxSetMessageDataWithSignalData(&messageData, 24u, 1u, data, message.endianness);
402 
403  /* Warning: Undertemperature charge - RSL */
404  data = kpkCanShim->pTableRsl->undertemperatureCharge[stringNumber];
405  CAN_TxSetMessageDataWithSignalData(&messageData, 25u, 1u, data, message.endianness);
406 
407  /* Warning: Overtemperature discharge - RSL */
408  data = kpkCanShim->pTableRsl->overtemperatureDischarge[stringNumber];
409  CAN_TxSetMessageDataWithSignalData(&messageData, 26u, 1u, data, message.endianness);
410 
411  /* Warning: Undertemperature discharge - RSL */
412  data = kpkCanShim->pTableRsl->undertemperatureDischarge[stringNumber];
413  CAN_TxSetMessageDataWithSignalData(&messageData, 27u, 1u, data, message.endianness);
414 
415  /* Warning: Overcurrent charge - RSL */
416  if ((kpkCanShim->pTableRsl->cellChargeOvercurrent[stringNumber] == 1u) ||
417  (kpkCanShim->pTableRsl->stringChargeOvercurrent[stringNumber] == 1u)) {
418  data = 1u;
419  } else {
420  data = 0u;
421  }
422  CAN_TxSetMessageDataWithSignalData(&messageData, 28u, 1u, data, message.endianness);
423 
424  /* Warning: Overcurrent discharge - RSL */
425  if ((kpkCanShim->pTableMol->cellDischargeOvercurrent[stringNumber] == 1u) ||
426  (kpkCanShim->pTableMol->stringDischargeOvercurrent[stringNumber] == 1u)) {
427  data = 1u;
428  } else {
429  data = 0u;
430  }
431  CAN_TxSetMessageDataWithSignalData(&messageData, 29u, 1u, data, message.endianness);
432 
433  /* Warning: Overvoltage - RSL */
434  data = kpkCanShim->pTableRsl->overVoltage[stringNumber];
435  CAN_TxSetMessageDataWithSignalData(&messageData, 30u, 1u, data, message.endianness);
436 
437  /* Warning: Undervoltage - RSL */
438  data = kpkCanShim->pTableRsl->underVoltage[stringNumber];
439  CAN_TxSetMessageDataWithSignalData(&messageData, 31u, 1u, data, message.endianness);
440 
441  /* Error: Positive string contactor */
444  CAN_TxSetMessageDataWithSignalData(&messageData, 32u, 1u, data, message.endianness);
445 
446  /* Error: Negative string contactor */
449  CAN_TxSetMessageDataWithSignalData(&messageData, 33u, 1u, data, message.endianness);
450 
451  /* Error: Slave hardware: TODO */
452 
453  /* Error: Daisy-chain base: communication */
454  data = kpkCanShim->pTableErrorState->afeCommunicationSpiError[stringNumber];
455  CAN_TxSetMessageDataWithSignalData(&messageData, 35u, 1u, data, message.endianness);
456 
457  /* Error: Daisy-chain redundancy: communication: TODO */
458  /* Error: Daisy-chain base: CRC */
459  data = kpkCanShim->pTableErrorState->afeCommunicationCrcError[stringNumber];
460  CAN_TxSetMessageDataWithSignalData(&messageData, 37u, 1u, data, message.endianness);
461 
462  /* Error: Daisy-chain redundancy: CRC: TODO */
463  /* Error: Daisy-chain base: Voltage out of operating range */
464  data = kpkCanShim->pTableErrorState->afeCellVoltageInvalidError[stringNumber];
465  CAN_TxSetMessageDataWithSignalData(&messageData, 39u, 1u, data, message.endianness);
466 
467  /* Error: Daisy-chain redundancy: Voltage out of operating range: TODO */
468  /* Error: Daisy-chain base: Temperature out of operating range */
469  data = kpkCanShim->pTableErrorState->afeCellTemperatureInvalidError[stringNumber];
470  CAN_TxSetMessageDataWithSignalData(&messageData, 41u, 1u, data, message.endianness);
471 
472  /* Error: Daisy-chain redundancy: Voltage out of operating range: TODO */
473 
474  /* Error: current measurement */
475  if ((kpkCanShim->pTableErrorState->currentMeasurementInvalidError[stringNumber] == true) ||
476  (kpkCanShim->pTableErrorState->currentMeasurementTimeoutError[stringNumber] == true)) {
477  data = 1u;
478  } else {
479  data = 0u;
480  }
481  CAN_TxSetMessageDataWithSignalData(&messageData, 43u, 1u, data, message.endianness);
482 
483  /* Error: Coulomb counting measurement */
484  data = kpkCanShim->pTableErrorState->currentSensorCoulombCounterTimeoutError[stringNumber];
485  CAN_TxSetMessageDataWithSignalData(&messageData, 44u, 1u, data, message.endianness);
486 
487  /* Error: Energy counting measurement */
488  data = kpkCanShim->pTableErrorState->currentSensorEnergyCounterTimeoutError[stringNumber];
489  CAN_TxSetMessageDataWithSignalData(&messageData, 45u, 1u, data, message.endianness);
490 
491  /* Error: Current sensor V1 measurement */
492  data = kpkCanShim->pTableErrorState->currentSensorVoltage1TimeoutError[stringNumber];
493  CAN_TxSetMessageDataWithSignalData(&messageData, 46u, 1u, data, message.endianness);
494 
495  /* Error: Current sensor V2 measurement */
496  data = kpkCanShim->pTableErrorState->currentSensorVoltage2TimeoutError[stringNumber];
497  CAN_TxSetMessageDataWithSignalData(&messageData, 47u, 1u, data, message.endianness);
498 
499  /* Error: Current sensor V3 measurement */
500  data = kpkCanShim->pTableErrorState->currentSensorVoltage3TimeoutError[stringNumber];
501  CAN_TxSetMessageDataWithSignalData(&messageData, 48u, 1u, data, message.endianness);
502 
503  /* Error: Open wire */
504  data = kpkCanShim->pTableErrorState->openWireDetectedError[stringNumber];
505  CAN_TxSetMessageDataWithSignalData(&messageData, 49u, 1u, data, message.endianness);
506 
507  /* Error: Plausibility: Cell temperature */
508  data = kpkCanShim->pTableErrorState->plausibilityCheckCellTemperatureError[stringNumber];
509  CAN_TxSetMessageDataWithSignalData(&messageData, 51u, 1u, data, message.endianness);
510 
511  /* Error: Plausibility: Cell voltage */
512  data = kpkCanShim->pTableErrorState->plausibilityCheckCellVoltageError[stringNumber];
513  CAN_TxSetMessageDataWithSignalData(&messageData, 52u, 1u, data, message.endianness);
514 
515  /* Error: Plausibility: String voltage */
516  data = kpkCanShim->pTableErrorState->plausibilityCheckPackVoltageError[stringNumber];
517  CAN_TxSetMessageDataWithSignalData(&messageData, 53u, 1u, data, message.endianness);
518 
519  /* Error: Plausibility: Cell temperature spread */
520  data = kpkCanShim->pTableErrorState->plausibilityCheckCellTemperatureSpreadError[stringNumber];
521  CAN_TxSetMessageDataWithSignalData(&messageData, 54u, 1u, data, message.endianness);
522 
523  /* Error: Plausibility: Cell voltage spread */
524  data = kpkCanShim->pTableErrorState->plausibilityCheckCellVoltageSpreadError[stringNumber];
525  CAN_TxSetMessageDataWithSignalData(&messageData, 55u, 1u, data, message.endianness);
526  /* AXIVION Enable Style Generic-NoMagicNumbers: */
527 
528  /* Open wire number: TODO */
529 
530  /* now copy data in the buffer that will be used to send data */
531  CAN_TxSetCanDataWithMessageData(messageData, pCanData, message.endianness);
532 
533  /* Increment multiplexer for next cell */
534  (*pMuxId)++;
535 
536  /* Check mux value */
537  if (*pMuxId >= BS_NR_OF_STRINGS) {
538  *pMuxId = 0u;
539  }
540 
541  return 0;
542 }
543 
544 /*========== Externalized Static Function Implementations (Unit Test) =======*/
545 #ifdef UNITY_UNIT_TEST
546 #endif
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
bool BMS_IsTransitionToErrorStateActive(void)
Check if transition in to error state is active.
Definition: bms.c:1636
uint8_t BMS_GetNumberOfConnectedStrings(void)
Returns number of connected strings.
Definition: bms.c:1632
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1614
BMS_STATEMACH_e BMS_GetState(void)
Returns the current state.
Definition: bms.c:807
bms driver header
CAN callbacks header.
uint32_t CANTX_BmsState(CAN_MESSAGE_PROPERTIES_s message, uint8_t *pCanData, uint8_t *pMuxId, const CAN_SHIM_s *const kpkCanShim)
can tx callback function for state
static bool CANTX_AnySysMonTimingIssueDetected(const CAN_SHIM_s *const kpkCanShim)
uint32_t CANTX_BmsStateDetails(CAN_MESSAGE_PROPERTIES_s message, uint8_t *pCanData, uint8_t *pMuxId, const CAN_SHIM_s *const kpkCanShim)
can tx callback function for detail state
uint32_t CANTX_StringState(CAN_MESSAGE_PROPERTIES_s message, uint8_t *pCanData, uint8_t *pMuxId, const CAN_SHIM_s *const kpkCanShim)
can tx callback function for string state values
#define CAN_FOXBMS_MESSAGES_DEFAULT_DLC
Definition: can_cfg.h:106
Header for the driver for the CAN module.
#define CANTX_STRING_STATE_ID
#define CANTX_BMS_STATE_DETAILS_ID_TYPE
#define CANTX_BMS_STATE_DETAILS_ID
#define CANTX_STRING_STATE_ID_TYPE
#define CANTX_BMS_STATE_ID
void CAN_TxSetMessageDataWithSignalData(uint64_t *pMessage, uint64_t bitStart, uint8_t bitLength, uint64_t canSignal, CAN_ENDIANNESS_e endianness)
Puts CAN signal data in a 64-bit variable. This function is used to compose a 64-bit CAN message....
Definition: can_helper.c:173
void CAN_TxSetCanDataWithMessageData(uint64_t message, uint8_t *pCanData, CAN_ENDIANNESS_e endianness)
Copy CAN data from a 64-bit variable to 8 bytes. This function is used to copy a 64-bit CAN message t...
Definition: can_helper.c:212
uint8_t CAN_ConvertBooleanToInteger(bool input)
Transform a bool to a bit (set if true)
Definition: can_helper.c:342
Headers for the helper functions for the CAN module.
#define DATA_READ_DATA(...)
Definition: database.h:86
bool DIAG_IsAnyFatalErrorSet(void)
Check if any fatal error is set.
Definition: diag.c:391
Diagnosis driver header.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
CAN_IDENTIFIER_TYPE_e idType
Definition: can_cfg.h:201
CAN_ENDIANNESS_e endianness
Definition: can_cfg.h:203
DATA_BLOCK_ERROR_STATE_s * pTableErrorState
Definition: can_cfg.h:182
DATA_BLOCK_RSL_FLAG_s * pTableRsl
Definition: can_cfg.h:189
DATA_BLOCK_MSL_FLAG_s * pTableMsl
Definition: can_cfg.h:186
DATA_BLOCK_MOL_FLAG_s * pTableMol
Definition: can_cfg.h:185
DATA_BLOCK_INSULATION_MONITORING_s * pTableInsulation
Definition: can_cfg.h:183
bool openWireDetectedError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:359
bool deepDischargeDetectedError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:381
bool currentMeasurementInvalidError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:349
bool plausibilityCheckCellVoltageError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:365
bool prechargeAbortedDueToVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:379
bool afeCommunicationCrcError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:338
bool currentSensorVoltage2TimeoutError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:351
bool stringFuseError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:358
bool currentSensorVoltage3TimeoutError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:352
bool currentSensorCoulombCounterTimeoutError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:354
bool plausibilityCheckPackVoltageError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:364
bool contactorInNegativePathOfStringFeedbackError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:370
bool plausibilityCheckCellTemperatureSpreadError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:368
bool currentSensorVoltage1TimeoutError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:350
bool afeCommunicationSpiError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:340
bool plausibilityCheckCellVoltageSpreadError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:366
bool contactorInPositivePathOfStringFeedbackError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:371
bool prechargeAbortedDueToCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:380
bool currentMeasurementTimeoutError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:348
bool afeCellVoltageInvalidError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:342
bool afeCellTemperatureInvalidError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:343
bool plausibilityCheckCellTemperatureError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:367
bool currentSensorEnergyCounterTimeoutError[BS_NR_OF_STRINGS]
Definition: database_cfg.h:355
uint8_t cellChargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:504
uint8_t underVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:499
uint8_t cellDischargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:506
uint8_t overtemperatureDischarge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:501
uint8_t overVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:498
uint8_t overtemperatureCharge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:500
uint8_t undertemperatureCharge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:502
uint8_t stringChargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:505
uint8_t stringDischargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:507
uint8_t stringChargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:465
uint8_t undertemperatureDischarge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:463
uint8_t cellChargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:464
uint8_t overtemperatureCharge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:460
uint8_t overtemperatureDischarge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:461
uint8_t stringDischargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:467
uint8_t underVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:459
uint8_t cellDischargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:466
uint8_t overVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:458
uint8_t packDischargeOvercurrent
Definition: database_cfg.h:457
uint8_t undertemperatureCharge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:462
uint8_t underVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:479
uint8_t undertemperatureDischarge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:483
uint8_t stringChargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:485
uint8_t overVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:478
uint8_t cellChargeOvercurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:484
uint8_t undertemperatureCharge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:482
uint8_t overtemperatureDischarge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:481
uint8_t overtemperatureCharge[BS_NR_OF_STRINGS]
Definition: database_cfg.h:480
void SYSM_GetRecordedTimingViolations(SYSM_TIMING_VIOLATION_RESPONSE_s *pAnswer)
Returns the timing violation flags determined from fram state.
Definition: sys_mon.c:202
system monitoring module