foxBMS - Unit Tests  1.2.0
The foxBMS Unit Tests API Documentation
bms.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, 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 bms.c
44  * @author foxBMS Team
45  * @date 2020-02-24 (date of creation)
46  * @updated 2021-10-18 (date of last update)
47  * @ingroup ENGINE
48  * @prefix BMS
49  *
50  * @brief bms driver implementation
51  */
52 
53 /*========== Includes =======================================================*/
54 #include "bms.h"
55 
56 #include "battery_cell_cfg.h"
57 
58 #include "afe.h"
59 #include "bal.h"
60 #include "contactor.h"
61 #include "database.h"
62 #include "diag.h"
63 #include "foxmath.h"
64 #include "led.h"
65 #include "meas.h"
66 #include "os.h"
67 #include "soa.h"
68 
69 /*========== Macros and Definitions =========================================*/
70 /** default value for unset "active delay time" */
71 #define BMS_NO_ACTIVE_DELAY_TIME_ms (UINT32_MAX)
72 
73 /**
74  * Saves the last state and the last substate
75  */
76 #define BMS_SAVELASTSTATES() \
77  bms_state.laststate = bms_state.state; \
78  bms_state.lastsubstate = bms_state.substate
79 
80 /*========== Static Constant and Variable Definitions =======================*/
81 
82 /**
83  * contains the state of the bms state machine
84  */
86  .timer = 0,
87  .stateRequest = BMS_STATE_NO_REQUEST,
89  .substate = BMS_ENTRY,
90  .laststate = BMS_STATEMACH_UNINITIALIZED,
91  .lastsubstate = BMS_ENTRY,
92  .triggerentry = 0u,
93  .ErrRequestCounter = 0u,
94  .initFinished = STD_NOT_OK,
95  .counter = 0u,
96  .OscillationTimeout = 0u,
97  .PrechargeTryCounter = 0u,
98  .powerPath = BMS_POWER_PATH_OPEN,
99  .closedStrings = {0u},
100  .closedPrechargeContactors = {0u},
101  .numberOfClosedStrings = 0u,
102  .deactivatedStrings = {0},
103  .firstClosedString = 0u,
104  .stringOpenTimeout = 0u,
105  .nextstringclosedtimer = 0u,
106  .stringCloseTimeout = 0u,
107  .nextstate = BMS_STATEMACH_STANDBY,
108  .restTimer_10ms = BS_RELAXATION_PERIOD_10ms,
109  .currentFlowState = BMS_RELAXATION,
110  .remainingDelay_ms = BMS_NO_ACTIVE_DELAY_TIME_ms,
111  .minimumActiveDelay_ms = BMS_NO_ACTIVE_DELAY_TIME_ms,
112  .transitionToErrorState = false,
113 };
114 
115 /** local copies of database tables */
116 /**@{*/
120 /**@}*/
121 
122 /*========== Extern Constant and Variable Definitions =======================*/
123 
124 /*========== Static Function Prototypes =====================================*/
125 
126 /**
127  * @brief checks the state requests that are made.
128  * @details This function checks the validity of the state requests. The
129  * results of the checked is returned immediately.
130  * @param[in] statereq state request to be checked
131  * @return result of the state request that was made
132  */
134 
135 /**
136  * @brief transfers the current state request to the state machine.
137  * @details This function takes the current state request from #bms_state
138  * transfers it to the state machine. It resets the value from
139  * #bms_state to #BMS_STATE_NO_REQUEST
140  * @return current state request
141  */
143 
144 /**
145  * @brief re-entrance check of SYS state machine trigger function
146  * @details This function is not re-entrant and should only be called time- or
147  * event-triggered. It increments the triggerentry counter from the
148  * state variable ltc_state. It should never be called by two
149  * different processes, so if it is the case, triggerentry should
150  * never be higher than 0 when this function is called.
151  * @return retval 0 if no further instance of the function is active, 0xff
152  * else
153  */
154 static uint8_t BMS_CheckReEntrance(void);
155 
156 /**
157  * @brief Checks the state requests made to the BMS state machine.
158  * @details Checks of the state request in the database and sets this value as
159  * return value.
160  * @return requested state
161  */
162 static uint8_t BMS_CheckCanRequests(void);
163 
164 /**
165  * @brief Checks all the error flags from diagnosis module with a severity of
166  * #DIAG_FATAL_ERROR
167  * @details Checks all the error flags from diagnosis module with a severity of
168  * #DIAG_FATAL_ERROR. Furthermore, sets parameter minimumActiveDelay_ms
169  * of bms_state variable.
170  * @return true if error flag is set, otherwise false
171  */
172 static bool BMS_IsAnyFatalErrorFlagSet(void);
173 
174 /**
175  * @brief Checks if any error flag is set and handles delay until contactors
176  * need to be opened.
177  * @details Checks all the diagnosis entries with severity of #DIAG_FATAL_ERROR
178  * and handles the configured delay until the contactors need to be
179  * opened. The shortest delay is used, if multiple errors are active at
180  * once.
181  * @return #STD_NOT_OK if error detected and delay time elapsed, otherwise #STD_OK
182  */
184 
185 /** Get latest database entries for static module variables */
186 static void BMS_GetMeasurementValues(void);
187 
188 /**
189  * @brief Check for any open voltage sense wire
190  */
191 static void BMS_CheckOpenSenseWire(void);
192 
193 /**
194  * @brief Checks if the current limitations are violated
195  * @param[in] stringNumber string addressed
196  * @param[in] pPackValues pointer to pack values database entry
197  * @return #STD_OK if the current limitations are NOT violated, else
198  * #STD_NOT_OK (type: #STD_RETURN_TYPE_e)
199  */
200 static STD_RETURN_TYPE_e BMS_CheckPrecharge(uint8_t stringNumber, const DATA_BLOCK_PACK_VALUES_s *pPackValues);
201 
202 /**
203  * @brief Returns ID of string with highest total voltage
204  * @details This is used to close the first string when drive-off is requested.
205  * @param[in] precharge If #BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT,
206  * precharge availability for string is ignored.
207  * if #BMS_TAKE_PRECHARGE_INTO_ACCCOUNT, only select
208  * string that has precharge available.
209  * @param[in] pPackValues pointer to pack values database entry
210  * @return index of string with highest voltage If no string is available,
211  * returns #BMS_NO_STRING_AVAILABLE.
212  */
213 static uint8_t BMS_GetHighestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues);
214 
215 /**
216  * @brief Returns ID of string with voltage closest to first closed string voltage
217  * @details This is used to close further strings in drive.
218  * @param[in] precharge If #BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT,
219  * precharge availability for string is ignored.
220  * if #BMS_TAKE_PRECHARGE_INTO_ACCCOUNT, only select
221  * string that has precharge available.
222  * @param[in] pPackValues pointer to pack values database entry
223  * @return index of string with voltage closest to the first closed string voltage.
224  * If no string is available, returns #BMS_NO_STRING_AVAILABLE.
225  */
226 static uint8_t BMS_GetClosestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues);
227 
228 /**
229  * @brief Returns ID of string with lowest total voltage
230  * @details This is used to close the first string when charge-off is requested.
231  *
232  * @param[in] precharge If 0, precharge availability for string is ignored.
233  * If 1, only selects a string that has precharge
234  * available.
235  * @param[in] pPackValues pointer to pack values database entry
236  * @return index of string with lowest voltage. If no string is available,
237  * returns #BMS_NO_STRING_AVAILABLE.
238  */
239 static uint8_t BMS_GetLowestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues);
240 
241 /**
242  * @brief Returns voltage difference between first closed string and
243  * string ID
244  * @details This function is used to check voltage when trying to close further
245  * strings.
246  * @param[in] string ID of string that must be compared with first closed
247  * string
248  * @param[in] pPackValues pointer to pack values database entry
249  * @return voltage difference in mV, will return INT32_MAX if voltages are
250  * invalid and difference can not be calculated
251  */
252 static int32_t BMS_GetStringVoltageDifference(uint8_t string, const DATA_BLOCK_PACK_VALUES_s *pPackValues);
253 
254 /**
255  * @brief Returns the average current flowing through all strings.
256  * @details This function is used when closing strings.
257  * @param[in] pPackValues pointer to pack values database entry
258  * @return average current taking all strings into account in mA. INT32_MAX if there is no valid current measurement
259  */
260 static int32_t BMS_GetAverageStringCurrent(DATA_BLOCK_PACK_VALUES_s *pPackValues);
261 
262 /**
263  * @brief Updates battery system state variable depending on measured/recent
264  * current values
265  * @param[in] pPackValues recent measured values from current sensor
266  */
267 static void BMS_UpdateBatsysState(DATA_BLOCK_PACK_VALUES_s *pPackValues);
268 
269 /*========== Static Function Implementations ================================*/
270 
272  if (statereq == BMS_STATE_ERROR_REQUEST) {
273  return BMS_OK;
274  }
275 
277  /* init only allowed from the uninitialized state */
278  if (statereq == BMS_STATE_INIT_REQUEST) {
280  return BMS_OK;
281  } else {
283  }
284  } else {
285  return BMS_ILLEGAL_REQUEST;
286  }
287  } else {
288  return BMS_REQUEST_PENDING;
289  }
290 }
291 
292 static uint8_t BMS_CheckReEntrance(void) {
293  uint8_t retval = 0;
295  if (!bms_state.triggerentry) {
297  } else {
298  retval = 0xFF; /* multiple calls of function */
299  }
301  return retval;
302 }
303 
306 
308  retval = bms_state.stateRequest;
311  return retval;
312 }
313 
314 static void BMS_GetMeasurementValues(void) {
316 }
317 
318 static uint8_t BMS_CheckCanRequests(void) {
319  uint8_t retVal = BMS_REQ_ID_NOREQ;
321 
322  DATA_READ_DATA(&request);
323 
324  if (request.stateRequestViaCan == BMS_REQ_ID_STANDBY) {
325  retVal = BMS_REQ_ID_STANDBY;
326  } else if (request.stateRequestViaCan == BMS_REQ_ID_NORMAL) {
327  retVal = BMS_REQ_ID_NORMAL;
328  }
329 
330 #if BS_SEPARATE_POWER_PATHS == 1
331  else if (request.stateRequestViaCan == BMS_REQ_ID_CHARGE) { /* NOLINT(readability/braces) */
332  retVal = BMS_REQ_ID_CHARGE;
333  }
334 #endif /* BS_SEPARATE_POWER_PATHS == 1 */
335 
336  return retVal;
337 }
338 
339 static void BMS_CheckOpenSenseWire(void) {
340  uint8_t openWireDetected = 0;
341 
342  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
343  /* Iterate over all modules */
344  for (uint8_t m = 0u; m < BS_NR_OF_MODULES; m++) {
345  /* Iterate over all voltage sense wires: cells per module + 1 */
346  for (uint8_t wire = 0u; wire < (BS_NR_OF_CELLS_PER_MODULE + 1); wire++) {
347  /* open wire detected */
348  if (bms_tableOpenWire.openwire[s][(wire + (m * (BS_NR_OF_CELLS_PER_MODULE + 1))) == 1] > 0u) {
349  openWireDetected++;
350 
351  /* Add additional error handling here */
352  }
353  }
354  }
355  /* Set error if open wire detected */
356  if (openWireDetected == 0u) {
358  } else {
360  }
361  }
362 }
363 
364 static STD_RETURN_TYPE_e BMS_CheckPrecharge(uint8_t stringNumber, const DATA_BLOCK_PACK_VALUES_s *pPackValues) {
365  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
366  /* make sure that we do not access the arrays in the database
367  tables out of bounds */
368  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
369  FAS_ASSERT(pPackValues != NULL_PTR);
370 
371  /* Only check precharging if current value and voltages are valid */
372  if ((0u == pPackValues->invalidStringCurrent[stringNumber]) &&
373  (0u == pPackValues->invalidStringVoltage[stringNumber]) && (0u == pPackValues->invalidHvBusVoltage)) {
374  /* Only current not current direction is checked */
375  const int32_t current_mA = MATH_AbsInt32_t(pPackValues->stringCurrent_mA[stringNumber]);
376  const int64_t cont_prechargeVoltDiff_mV = MATH_AbsInt64_t(
377  (int64_t)pPackValues->stringVoltage_mV[stringNumber] - (int64_t)pPackValues->highVoltageBusVoltage_mV);
378 
379  if ((cont_prechargeVoltDiff_mV < BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV) &&
380  (current_mA < BMS_PRECHARGE_CURRENT_THRESHOLD_mA)) {
381  retVal = STD_OK;
382  } else {
383  retVal = STD_NOT_OK;
384  }
385  }
386 
387  return retVal;
388 }
389 
390 static bool BMS_IsAnyFatalErrorFlagSet(void) {
391  bool fatalErrorActive = false;
392 
393  for (uint16_t entry = 0u; entry < diag_device.numberOfFatalErrors; entry++) {
394  const STD_RETURN_TYPE_e diagnosisState =
396  if (STD_NOT_OK == diagnosisState) {
397  /* Fatal error detected -> get delay of this error until contactors shall be opened */
398  const uint32_t kDelay_ms = DIAG_GetDelay(diag_device.pFatalErrorLinkTable[entry]->id);
399  /* Check if delay of detected failure is smaller than the delay of a previously detected failure */
400  if (bms_state.minimumActiveDelay_ms > kDelay_ms) {
401  bms_state.minimumActiveDelay_ms = kDelay_ms;
402  }
403  fatalErrorActive = true;
404  }
405  }
406  return fatalErrorActive;
407 }
408 
410  STD_RETURN_TYPE_e retVal = STD_OK; /* is set to STD_NOT_OK if error detected */
411  static uint32_t previousTimestamp = 0u;
412  uint32_t timestamp = OS_GetTickCount();
413 
414  /* Check if any fatal error is detected */
415  const bool isErrorActive = BMS_IsAnyFatalErrorFlagSet();
416 
417  /** Check if a fatal error has been detected previously. If yes, check delay */
418  if (true == bms_state.transitionToErrorState) {
419  /* Decrease active delay since last call */
420  const uint32_t timeSinceLastCall_ms = timestamp - previousTimestamp;
421  if (timeSinceLastCall_ms <= bms_state.remainingDelay_ms) {
422  bms_state.remainingDelay_ms -= timeSinceLastCall_ms;
423  } else {
425  }
426 
427  /* Check if delay from a new error is shorter then active delay from
428  * previously detected error in BMS statemachine */
431  }
432  } else {
433  /* Delay is not active, check if it should be activated */
434  if (true == isErrorActive) {
437  }
438  }
439 
440  /** Set previous timestamp for next call */
441  previousTimestamp = timestamp;
442 
443  /* Check if bms statemachine should switch to error state. This is the case
444  * if the delay is activated and the remaining delay is down to 0 */
445  if ((true == bms_state.transitionToErrorState) && (0u == bms_state.remainingDelay_ms)) {
446  retVal = STD_NOT_OK;
447  }
448 
449  return retVal;
450 }
451 
453  FAS_ASSERT(pPackValues != NULL_PTR);
454  uint8_t highest_string_index = BMS_NO_STRING_AVAILABLE;
455  int32_t max_stringVoltage_mV = INT32_MIN;
456 
457  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
458  if ((pPackValues->stringVoltage_mV[s] >= max_stringVoltage_mV) &&
459  (0u == pPackValues->invalidStringVoltage[s])) {
460  if (bms_state.deactivatedStrings[s] == 0u) {
461  if (precharge == BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT) {
462  max_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
463  highest_string_index = s;
464  } else {
466  max_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
467  highest_string_index = s;
468  }
469  }
470  }
471  }
472  }
473 
474  return highest_string_index;
475 }
476 
478  FAS_ASSERT(pPackValues != NULL_PTR);
479  uint8_t closestStringIndex = BMS_NO_STRING_AVAILABLE;
480  int32_t closedStringVoltage_mV = 0;
481  bool searchString = false;
482 
483  /* Get voltage of first closed string */
484  if (0u == pPackValues->invalidStringVoltage[bms_state.firstClosedString]) {
485  closedStringVoltage_mV = pPackValues->stringVoltage_mV[bms_state.firstClosedString];
486  searchString = true;
487  } else if (0u == pPackValues->invalidHvBusVoltage) {
488  /* Use high voltage bus voltage if measured string voltage is invalid */
489  closedStringVoltage_mV = pPackValues->highVoltageBusVoltage_mV;
490  searchString = true;
491  } else {
492  /* Do not search for next string if no valid voltages could be measured */
493  searchString = false;
494  }
495 
496  if (true == searchString) {
497  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
498  const bool isStringClosed = BMS_IsStringClosed(s);
499  const uint8_t isStringVoltageValid = pPackValues->invalidStringVoltage[s];
500  if ((false == isStringClosed) && (0u == isStringVoltageValid)) {
501  /* Only check open strings with valid voltages */
502  int32_t minimumVoltageDifference_mV = INT32_MAX;
503  int32_t voltageDifference_mV = labs(closedStringVoltage_mV - pPackValues->stringVoltage_mV[s]);
504  if (voltageDifference_mV <= minimumVoltageDifference_mV) {
505  if (bms_state.deactivatedStrings[s] == 0u) {
506  if (precharge == BMS_TAKE_PRECHARGE_INTO_ACCCOUNT) {
508  minimumVoltageDifference_mV = voltageDifference_mV;
509  closestStringIndex = s;
510  }
511  } else {
512  minimumVoltageDifference_mV = voltageDifference_mV;
513  closestStringIndex = s;
514  }
515  }
516  }
517  }
518  }
519  }
520  return closestStringIndex;
521 }
522 
524  FAS_ASSERT(pPackValues != NULL_PTR);
525  uint8_t lowest_string_index = BMS_NO_STRING_AVAILABLE;
526  int32_t min_stringVoltage_mV = INT32_MAX;
527 
528  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
529  if ((pPackValues->stringVoltage_mV[s] <= min_stringVoltage_mV) &&
530  (0u == pPackValues->invalidStringVoltage[s])) {
531  if (bms_state.deactivatedStrings[s] == 0u) {
532  if (precharge == BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT) {
533  min_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
534  lowest_string_index = s;
535  } else {
537  min_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
538  lowest_string_index = s;
539  }
540  }
541  }
542  }
543  }
544  return lowest_string_index;
545 }
546 
547 static int32_t BMS_GetStringVoltageDifference(uint8_t string, const DATA_BLOCK_PACK_VALUES_s *pPackValues) {
548  FAS_ASSERT(string < BS_NR_OF_STRINGS);
549  FAS_ASSERT(pPackValues != NULL_PTR);
550  int32_t voltageDifference_mV = INT32_MAX;
551  if ((0u == pPackValues->invalidStringVoltage[string]) &&
552  (0u == pPackValues->invalidStringVoltage[bms_state.firstClosedString])) {
553  /* Calculate difference between string voltages */
554  voltageDifference_mV = MATH_AbsInt32_t(
555  pPackValues->stringVoltage_mV[string] - pPackValues->stringVoltage_mV[bms_state.firstClosedString]);
556  } else if ((0u == pPackValues->invalidStringVoltage[string]) && (0u == pPackValues->invalidHvBusVoltage)) {
557  /* Calculate difference between string and high voltage bus voltage */
558  voltageDifference_mV =
559  MATH_AbsInt32_t(pPackValues->stringVoltage_mV[string] - pPackValues->highVoltageBusVoltage_mV);
560  } else {
561  /* No valid voltages for comparison -> do not calculate difference and return INT32_MAX */
562  voltageDifference_mV = INT32_MAX;
563  }
564  return voltageDifference_mV;
565 }
566 
568  FAS_ASSERT(pPackValues != NULL_PTR);
569  int32_t average_current = pPackValues->packCurrent_mA / (int32_t)BS_NR_OF_STRINGS;
570  if (1u == pPackValues->invalidPackCurrent) {
571  average_current = INT32_MAX;
572  }
573  return average_current;
574 }
575 
577  FAS_ASSERT(pPackValues != NULL_PTR);
578 
579  /* Only update system state if current value is valid */
580  if (0u == pPackValues->invalidPackCurrent) {
581  if (POSITIVE_DISCHARGE_CURRENT == true) {
582  /* Positive current values equal a discharge of the battery system */
583  if (pPackValues->packCurrent_mA >= BS_REST_CURRENT_mA) { /* TODO: string use pack current */
586  } else if (pPackValues->packCurrent_mA <= -BS_REST_CURRENT_mA) {
589  } else {
590  /* Current below rest current: either battery system is at rest
591  * or the relaxation process is still ongoing */
592  if (bms_state.restTimer_10ms == 0u) {
593  /* Rest timer elapsed -> battery system at rest */
595  } else {
598  }
599  }
600  } else {
601  /* Negative current values equal a discharge of the battery system */
602  if (pPackValues->packCurrent_mA <= -BS_REST_CURRENT_mA) {
605  } else if (pPackValues->packCurrent_mA >= BS_REST_CURRENT_mA) {
608  } else {
609  /* Current below rest current: either battery system is at rest
610  * or the relaxation process is still ongoing */
611  if (bms_state.restTimer_10ms == 0u) {
612  /* Rest timer elapsed -> battery system at rest */
614  } else {
617  }
618  }
619  }
620  }
621 }
622 
623 /*========== Extern Function Implementations ================================*/
624 
626  return bms_state.initFinished;
627 }
628 
630  return bms_state.state;
631 }
632 
634  BMS_RETURN_TYPE_e retVal = BMS_OK;
635 
637  retVal = BMS_CheckStateRequest(statereq);
638 
639  if (retVal == BMS_OK) {
640  bms_state.stateRequest = statereq;
641  }
643 
644  return retVal;
645 }
646 
647 void BMS_Trigger(void) {
650  uint32_t timestamp = OS_GetTickCount();
651  static uint32_t nextOpenWireCheck = 0;
652  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
653  static uint8_t stringNumber = 0u;
654  static uint8_t nextStringNumber = 0u;
656  STD_RETURN_TYPE_e contRetVal = STD_NOT_OK;
657 
667  }
668  /* Check re-entrance of function */
669  if (BMS_CheckReEntrance() > 0u) {
670  return;
671  }
672 
673  if (bms_state.nextstringclosedtimer > 0u) {
675  }
676  if (bms_state.stringOpenTimeout > 0u) {
678  }
679 
680  if (bms_state.stringCloseTimeout > 0u) {
682  }
683 
684  if (bms_state.OscillationTimeout > 0u) {
686  }
687 
688  if (bms_state.timer > 0u) {
689  if ((--bms_state.timer) > 0u) {
691  return; /* handle state machine only if timer has elapsed */
692  }
693  }
694 
695  /****Happens every time the state machine is triggered**************/
696  switch (bms_state.state) {
697  /****************************UNINITIALIZED****************************/
699  /* waiting for Initialization Request */
700  statereq = BMS_TransferStateRequest();
701  if (statereq == BMS_STATE_INIT_REQUEST) {
706  } else if (statereq == BMS_STATE_NO_REQUEST) {
707  /* no actual request pending */
708  } else {
709  bms_state.ErrRequestCounter++; /* illegal request pending */
710  }
711  break;
712 
713  /****************************INITIALIZATION***************************/
716 
720  break;
721 
722  /****************************INITIALIZED******************************/
729  break;
730 
731  /****************************IDLE*************************************/
732  case BMS_STATEMACH_IDLE:
734 
735  if (bms_state.substate == BMS_ENTRY) {
736  DATA_READ_DATA(&systemstate);
737  systemstate.bmsCanState = BMS_CANSTATE_IDLE;
738  DATA_WRITE_DATA(&systemstate);
741  break;
742  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
748  break;
749  } else {
752  break;
753  }
760  break;
761  } else {
764  break;
765  }
766  }
767  break;
768 
769  /****************************OPEN CONTACTORS**************************/
772 
773  if (bms_state.substate == BMS_ENTRY) {
777  break;
779  for (stringNumber = 0u; stringNumber < BS_NR_OF_STRINGS; stringNumber++) {
780  if (bs_stringsWithPrecharge[stringNumber] == BS_STRING_WITH_PRECHARGE) {
781  CONT_OpenPrecharge(stringNumber);
782  bms_state.closedPrechargeContactors[stringNumber] = 0u;
783  }
784  }
785  /* Now go to string opening */
786  stringNumber = BS_NR_OF_STRINGS - 1u; /* Select last string */
789  } else if (bms_state.substate == BMS_OPEN_STRINGS) {
790  CONT_OpenString(stringNumber);
794  break;
795  } else if (bms_state.substate == BMS_CHECK_STRING_OPEN) {
796  contstate = CONT_GetState(stringNumber);
797  if (contstate == CONT_SWITCH_OFF) {
798  if (bms_state.numberOfClosedStrings > 0u) {
800  }
801  bms_state.closedStrings[stringNumber] = 0u;
802  if (stringNumber > 0u) {
803  stringNumber--;
806  break;
807  } else {
810  }
811  break;
812  } else if (bms_state.stringOpenTimeout == 0u) {
813  /* String takes too long to close, go to next string */
816  break;
817  } else {
818  /* String not opened, re-issue closing request */
819  CONT_OpenString(nextStringNumber);
821  break;
822  }
823  } else if (bms_state.substate == BMS_OPEN_STRINGS_EXIT) {
828  break;
829  } else {
833  }
834  }
835  break;
836 
837  /****************************STANDBY**********************************/
840  if (bms_state.substate == BMS_ENTRY) {
842 #if LTC_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE
843  nextOpenWireCheck = timestamp + LTC_STANDBY_OPEN_WIRE_PERIOD_ms;
844 #endif /* LTC_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE */
847  DATA_READ_DATA(&systemstate);
848  systemstate.bmsCanState = BMS_CANSTATE_STANDBY;
849  DATA_WRITE_DATA(&systemstate);
850  break;
857  break;
858  } else {
861  break;
862  }
863  } else if (bms_state.substate == BMS_INTERLOCK_CHECKED) {
866  break;
867  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
873  break;
874  } else {
877  break;
878  }
886  break;
887  }
894  break;
895  } else {
896 #if LTC_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE
897  if (nextOpenWireCheck <= timestamp) {
899  nextOpenWireCheck = timestamp + LTC_STANDBY_OPEN_WIRE_PERIOD_ms;
900  }
901 #endif /* LTC_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE */
904  break;
905  }
906  }
907  break;
908 
909  /****************************PRECHARGE********************************/
912 
913  if (bms_state.substate == BMS_ENTRY) {
914  DATA_READ_DATA(&systemstate);
915  systemstate.bmsCanState = BMS_CANSTATE_PRECHARGE;
916  DATA_WRITE_DATA(&systemstate);
919  } else {
921  }
922  if (stringNumber == BMS_NO_STRING_AVAILABLE) {
927  break;
928  }
929  bms_state.firstClosedString = stringNumber;
930  if (bms_state.OscillationTimeout == 0u) {
933  } else if (BMS_IsBatterySystemStateOkay() == STD_NOT_OK) {
934  /* If precharge re-enter timeout not elapsed, wait (and check errors while waiting) */
939  break;
940  }
941  break;
945  bms_state.closedPrechargeContactors[stringNumber] = 1u;
946  if (contRetVal == STD_OK) {
950  } else {
955  }
956  break;
963  break;
964  } else {
967  break;
968  }
975  break;
976  } else {
979  }
982  if (retVal == STD_OK) {
986  break;
987  } else {
990  bms_state.closedPrechargeContactors[stringNumber] = 0u;
991  if (contRetVal == STD_OK) {
995  } else {
1000  }
1001  break;
1002  } else {
1004  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1009  break;
1010  }
1011  }
1019  if (contstate == CONT_SWITCH_ON) {
1024  break;
1025  } else if (bms_state.stringCloseTimeout == 0u) {
1026  /* String takes too long to close */
1031  break;
1032  } else {
1033  /* String not closed, re-issue closing request */
1037  break;
1038  }
1045  break;
1046  } else {
1049  break;
1050  }
1052  /* Always make one error check after the first string was closed successfully */
1058  break;
1059  } else {
1062  break;
1063  }
1066  if (contRetVal == STD_OK) {
1067  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1071  } else {
1076  }
1077  break;
1078  }
1079  break;
1080 
1081  /****************************NORMAL**************************************/
1082  case BMS_STATEMACH_NORMAL:
1084 
1085  if (bms_state.substate == BMS_ENTRY) {
1086 #if LTC_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE
1087  nextOpenWireCheck = timestamp + LTC_NORMAL_OPEN_WIRE_PERIOD_ms;
1088 #endif /* LTC_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE */
1089  DATA_READ_DATA(&systemstate);
1091  systemstate.bmsCanState = BMS_CANSTATE_CHARGE;
1092  } else {
1093  systemstate.bmsCanState = BMS_CANSTATE_NORMAL;
1094  }
1095  DATA_WRITE_DATA(&systemstate);
1099  break;
1100  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
1105  break;
1106  } else {
1109  break;
1110  }
1117  break;
1118  } else {
1119 #if LTC_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE
1120  if (nextOpenWireCheck <= timestamp) {
1122  nextOpenWireCheck = timestamp + LTC_NORMAL_OPEN_WIRE_PERIOD_ms;
1123  }
1124 #endif /* LTC_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE */
1127  break;
1128  }
1130  if (bms_state.nextstringclosedtimer == 0u) {
1131  nextStringNumber =
1133  if (nextStringNumber == BMS_NO_STRING_AVAILABLE) {
1136  break;
1137  } else if (
1138  (BMS_GetStringVoltageDifference(nextStringNumber, &bms_tablePackValues) <=
1141  /* Voltage/current conditions suitable to close a further string */
1142  CONT_CloseString(nextStringNumber);
1146  break;
1147  }
1148  } else {
1151  break;
1152  }
1153  } else if (bms_state.substate == BMS_CHECK_STRING_CLOSED) {
1154  contstate = CONT_GetState(nextStringNumber);
1155  if (contstate == CONT_SWITCH_ON) {
1157  bms_state.closedStrings[nextStringNumber] = 1u;
1159  /* Go to begin of NORMAL case to redo the full procedure with error check and request check */
1161  break;
1162  } else if (bms_state.stringCloseTimeout == 0u) {
1163  /* String takes too long to close */
1168  break;
1169  } else if (BMS_IsBatterySystemStateOkay() == STD_NOT_OK) {
1174  break;
1175  } else if (BMS_CheckCanRequests() == BMS_REQ_ID_STANDBY) {
1180  break;
1181  } else {
1182  /* String not closed, re-issue closing request */
1183  CONT_CloseString(nextStringNumber);
1185  break;
1186  }
1187  }
1188  break;
1189 
1190  /****************************ERROR*************************************/
1191  case BMS_STATEMACH_ERROR:
1193 
1194  if (bms_state.substate == BMS_ENTRY) {
1195  /* Set BMS System state to error */
1196  DATA_READ_DATA(&systemstate);
1197  systemstate.bmsCanState = BMS_CANSTATE_ERROR;
1198  DATA_WRITE_DATA(&systemstate);
1199  /* Deactivate balancing */
1201  /* Change LED toggle frequency to indicate an error */
1203  /* Set timer for next open wire check */
1204  nextOpenWireCheck = timestamp + AFE_ERROR_OPEN_WIRE_PERIOD_ms;
1205  /* Switch to next substate */
1208  break;
1209  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
1210  if (true == DIAG_IsAnyFatalErrorSet()) {
1211  /* we stay already in requested state */
1212  if (nextOpenWireCheck <= timestamp) {
1213  /* Perform open-wire check periodically */
1214  /* MEAS_RequestOpenWireCheck(); */ /*TODO: check with strings */
1215  nextOpenWireCheck = timestamp + AFE_ERROR_OPEN_WIRE_PERIOD_ms;
1216  }
1217  } else {
1218  /* No error detected anymore - reset fatal error related variables */
1222  /* Check for STANDBY request */
1225  break;
1226  }
1229  /* Activate balancing again */
1231  /* Set LED frequency to normal operation as we leave error
1232  state subsequently */
1234 
1235  /* Verify that all contactors are opened and switch to
1236  * STANDBY state afterwards */
1240  break;
1241  } else {
1244  break;
1245  }
1246  } else {
1247  /* invalid state -> this should never be reached */
1249  }
1250  break;
1251  default:
1252  /* invalid state */
1254  break;
1255  } /* end switch (bms_state.state) */
1256 
1258  bms_state.counter++;
1259 }
1260 
1262  return bms_state.currentFlowState;
1263 }
1264 
1267 
1268  if (POSITIVE_DISCHARGE_CURRENT == true) {
1269  if (current_mA >= BS_REST_CURRENT_mA) {
1270  retVal = BMS_DISCHARGING;
1271  } else if (current_mA <= -BS_REST_CURRENT_mA) {
1272  retVal = BMS_CHARGING;
1273  } else {
1274  retVal = BMS_AT_REST;
1275  }
1276  } else {
1277  if (current_mA <= -BS_REST_CURRENT_mA) {
1278  retVal = BMS_DISCHARGING;
1279  } else if (current_mA >= BS_REST_CURRENT_mA) {
1280  retVal = BMS_CHARGING;
1281  } else {
1282  retVal = BMS_AT_REST;
1283  }
1284  }
1285  return retVal;
1286 }
1287 
1288 extern bool BMS_IsStringClosed(uint8_t stringNumber) {
1289  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
1290  bool retval = false;
1291  if (bms_state.closedStrings[stringNumber] == 1u) {
1292  retval = true;
1293  }
1294  return retval;
1295 }
1296 
1297 extern bool BMS_IsStringPrecharging(uint8_t stringNumber) {
1298  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
1299  bool retval = false;
1300  if (bms_state.closedPrechargeContactors[stringNumber] == 1u) {
1301  retval = true;
1302  }
1303  return retval;
1304 }
1305 
1306 extern uint8_t BMS_GetNumberOfConnectedStrings(void) {
1308 }
1309 
1312 }
1313 
1314 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1315 #ifdef UNITY_UNIT_TEST
1317  return BMS_CheckStateRequest(statereq);
1318 }
1320  return BMS_TransferStateRequest();
1321 }
1322 extern uint8_t TEST_BMS_CheckReEntrance(void) {
1323  return BMS_CheckReEntrance();
1324 }
1325 extern uint8_t TEST_BMS_CheckCanRequests(void) {
1326  return BMS_CheckCanRequests();
1327 }
1329  return BMS_IsAnyFatalErrorFlagSet();
1330 }
1333 }
1336 }
1337 extern void TEST_BMS_CheckOpenSenseWire(void) {
1339 }
1340 extern STD_RETURN_TYPE_e TEST_BMS_CheckPrecharge(uint8_t stringNumber, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1341  return BMS_CheckPrecharge(stringNumber, pPackValues);
1342 }
1344  return BMS_GetHighestString(precharge, pPackValues);
1345 }
1347  return BMS_GetClosestString(precharge, pPackValues);
1348 }
1349 
1351  return BMS_GetLowestString(precharge, pPackValues);
1352 }
1353 extern int32_t TEST_BMS_GetStringVoltageDifference(uint8_t string, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1354  return BMS_GetStringVoltageDifference(string, pPackValues);
1355 }
1357  return BMS_GetAverageStringCurrent(pPackValues);
1358 }
1360  BMS_UpdateBatsysState(pPackValues);
1361 }
1362 
1363 #endif
AFE driver header.
#define AFE_ERROR_OPEN_WIRE_PERIOD_ms
Definition: afe.h:64
Header for the driver for balancing.
BAL_RETURN_TYPE_e BAL_SetStateRequest(BAL_STATE_REQUEST_e stateRequest)
sets the current state request of the state variable bal_state.
@ BAL_STATE_ALLOWBALANCING_REQUEST
Definition: bal.h:103
@ BAL_STATE_NO_BALANCING_REQUEST
Definition: bal.h:102
Configuration of the battery cell (e.g., minimum and maximum cell voltage)
BS_STRING_PRECHARGE_PRESENT_e bs_stringsWithPrecharge[BS_NR_OF_STRINGS]
#define BS_NR_OF_STRINGS
#define BS_NR_OF_CELLS_PER_MODULE
number of battery cells per battery module (parallel cells are counted as one)
#define BS_REST_CURRENT_mA
current threshold for determing rest state of battery. If absolute current is below this limit value ...
#define BS_NR_OF_MODULES
number of modules in battery pack
#define POSITIVE_DISCHARGE_CURRENT
#define BS_RELAXATION_PERIOD_10ms
Wait time in 10ms before battery system is at rest. Balancing for example only starts if battery syst...
@ BS_STRING_WITH_PRECHARGE
static STD_RETURN_TYPE_e BMS_CheckPrecharge(uint8_t stringNumber, const DATA_BLOCK_PACK_VALUES_s *pPackValues)
Checks if the current limitations are violated.
Definition: bms.c:364
uint8_t TEST_BMS_GetLowestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1350
void TEST_BMS_CheckOpenSenseWire(void)
Definition: bms.c:1337
#define BMS_SAVELASTSTATES()
Definition: bms.c:76
static DATA_BLOCK_MIN_MAX_s bms_tableMinMax
Definition: bms.c:117
uint8_t TEST_BMS_GetClosestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1346
BMS_RETURN_TYPE_e TEST_BMS_CheckStateRequest(BMS_STATE_REQUEST_e statereq)
Definition: bms.c:1316
bool BMS_IsStringPrecharging(uint8_t stringNumber)
Returns if string is currently precharging or not.
Definition: bms.c:1297
bool BMS_IsTransitionToErrorStateActive(void)
Check if transition in to error state is active.
Definition: bms.c:1310
BMS_RETURN_TYPE_e BMS_SetStateRequest(BMS_STATE_REQUEST_e statereq)
sets the current state request of the state variable bms_state.
Definition: bms.c:633
static bool BMS_IsAnyFatalErrorFlagSet(void)
Checks all the error flags from diagnosis module with a severity of DIAG_FATAL_ERROR.
Definition: bms.c:390
BMS_STATE_REQUEST_e TEST_BMS_TransferStateRequest(void)
Definition: bms.c:1319
STD_RETURN_TYPE_e TEST_BMS_CheckPrecharge(uint8_t stringNumber, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1340
static BMS_RETURN_TYPE_e BMS_CheckStateRequest(BMS_STATE_REQUEST_e statereq)
checks the state requests that are made.
Definition: bms.c:271
int32_t TEST_BMS_GetStringVoltageDifference(uint8_t string, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1353
uint8_t TEST_BMS_CheckCanRequests(void)
Definition: bms.c:1325
static void BMS_GetMeasurementValues(void)
Definition: bms.c:314
static DATA_BLOCK_PACK_VALUES_s bms_tablePackValues
Definition: bms.c:119
static void BMS_UpdateBatsysState(DATA_BLOCK_PACK_VALUES_s *pPackValues)
Updates battery system state variable depending on measured/recent current values.
Definition: bms.c:576
#define BMS_NO_ACTIVE_DELAY_TIME_ms
Definition: bms.c:71
static int32_t BMS_GetAverageStringCurrent(DATA_BLOCK_PACK_VALUES_s *pPackValues)
Returns the average current flowing through all strings.
Definition: bms.c:567
uint8_t TEST_BMS_CheckReEntrance(void)
Definition: bms.c:1322
void TEST_BMS_GetMeasurementValues(void)
Definition: bms.c:1334
void BMS_Trigger(void)
trigger function for the SYS driver state machine.
Definition: bms.c:647
uint8_t BMS_GetNumberOfConnectedStrings(void)
Returns number of connected strings.
Definition: bms.c:1306
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1288
static void BMS_CheckOpenSenseWire(void)
Check for any open voltage sense wire.
Definition: bms.c:339
BMS_CURRENT_FLOW_STATE_e BMS_GetCurrentFlowDirection(int32_t current_mA)
Get current flow direction, current value as function parameter.
Definition: bms.c:1265
static int32_t BMS_GetStringVoltageDifference(uint8_t string, const DATA_BLOCK_PACK_VALUES_s *pPackValues)
Returns voltage difference between first closed string and string ID.
Definition: bms.c:547
STD_RETURN_TYPE_e TEST_BMS_IsBatterySystemStateOkay(void)
Definition: bms.c:1331
static uint8_t BMS_GetLowestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Returns ID of string with lowest total voltage.
Definition: bms.c:523
BMS_CURRENT_FLOW_STATE_e BMS_GetBatterySystemState(void)
Returns current battery system state (charging/discharging, resting or in relaxation phase)
Definition: bms.c:1261
int32_t TEST_BMS_GetAverageStringCurrent(DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1356
bool TEST_BMS_IsAnyFatalErrorFlagSet(void)
Definition: bms.c:1328
static uint8_t BMS_GetHighestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Returns ID of string with highest total voltage.
Definition: bms.c:452
static uint8_t BMS_CheckReEntrance(void)
re-entrance check of SYS state machine trigger function
Definition: bms.c:292
static DATA_BLOCK_OPEN_WIRE_s bms_tableOpenWire
Definition: bms.c:118
static BMS_STATE_REQUEST_e BMS_TransferStateRequest(void)
transfers the current state request to the state machine.
Definition: bms.c:304
void TEST_BMS_UpdateBatsysState(DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1359
static BMS_STATE_s bms_state
Definition: bms.c:85
static STD_RETURN_TYPE_e BMS_IsBatterySystemStateOkay(void)
Checks if any error flag is set and handles delay until contactors need to be opened.
Definition: bms.c:409
STD_RETURN_TYPE_e BMS_GetInitializationState(void)
Gets the initialization state.
Definition: bms.c:625
static uint8_t BMS_CheckCanRequests(void)
Checks the state requests made to the BMS state machine.
Definition: bms.c:318
BMS_STATEMACH_e BMS_GetState(void)
Returns the current state.
Definition: bms.c:629
static uint8_t BMS_GetClosestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Returns ID of string with voltage closest to first closed string voltage.
Definition: bms.c:477
uint8_t TEST_BMS_GetHighestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1343
bms driver header
@ BMS_AT_REST
Definition: bms.h:69
@ BMS_DISCHARGING
Definition: bms.h:67
@ BMS_CHARGING
Definition: bms.h:66
@ BMS_RELAXATION
Definition: bms.h:68
@ BMS_CANSTATE_NORMAL
Definition: bms.h:113
@ BMS_CANSTATE_CHARGE
Definition: bms.h:114
@ BMS_CANSTATE_STANDBY
Definition: bms.h:111
@ BMS_CANSTATE_ERROR
Definition: bms.h:115
@ BMS_CANSTATE_IDLE
Definition: bms.h:109
@ BMS_CANSTATE_PRECHARGE
Definition: bms.h:112
enum BMS_RETURN_TYPE BMS_RETURN_TYPE_e
@ BMS_OK
Definition: bms.h:163
@ BMS_REQUEST_PENDING
Definition: bms.h:165
@ BMS_ALREADY_INITIALIZED
Definition: bms.h:167
@ BMS_ILLEGAL_REQUEST
Definition: bms.h:166
enum BMS_STATE_REQUEST BMS_STATE_REQUEST_e
enum BMS_STATEMACH BMS_STATEMACH_e
@ BMS_POWER_PATH_1
Definition: bms.h:175
@ BMS_POWER_PATH_OPEN
Definition: bms.h:173
@ BMS_POWER_PATH_0
Definition: bms.h:174
enum BMS_CURRENT_FLOW_STATE BMS_CURRENT_FLOW_STATE_e
@ BMS_STATE_NO_REQUEST
Definition: bms.h:156
@ BMS_STATE_INIT_REQUEST
Definition: bms.h:154
@ BMS_STATE_ERROR_REQUEST
Definition: bms.h:155
@ BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT
Definition: bms.h:81
@ BMS_TAKE_PRECHARGE_INTO_ACCCOUNT
Definition: bms.h:82
@ BMS_PRECHARGE_OPEN_PRECHARGE
Definition: bms.h:131
@ BMS_CHECK_STRING_OPEN
Definition: bms.h:148
@ BMS_OPEN_STRINGS_EXIT
Definition: bms.h:149
@ BMS_PRECHARGE_CLOSE_PRECHARGE
Definition: bms.h:129
@ BMS_NORMAL_CLOSE_NEXT_STRING
Definition: bms.h:143
@ BMS_CHECK_ERROR_FLAGS_PRECHARGE_CLOSINGSTRINGS
Definition: bms.h:141
@ BMS_ENTRY
Definition: bms.h:120
@ BMS_INTERLOCK_CHECKED
Definition: bms.h:122
@ BMS_OPEN_STRINGS
Definition: bms.h:147
@ BMS_CHECK_ERROR_FLAGS_PRECHARGE_FIRST_STRING
Definition: bms.h:138
@ BMS_CHECK_ERROR_FLAGS_CLOSINGPRECHARGE
Definition: bms.h:142
@ BMS_PRECHARGE_CHECK_VOLTAGES
Definition: bms.h:130
@ BMS_CHECK_STRING_CLOSED
Definition: bms.h:140
@ BMS_CHECK_ERROR_FLAGS
Definition: bms.h:125
@ BMS_OPEN_ALL_PRECHARGES
Definition: bms.h:144
@ BMS_CHECK_ERROR_FLAGS_INTERLOCK
Definition: bms.h:121
@ BMS_CHECK_STATE_REQUESTS
Definition: bms.h:123
@ BMS_CLOSE_FIRST_STRING_PRECHARGE_STATE
Definition: bms.h:135
@ BMS_CHECK_CLOSE_FIRST_STRING_PRECHARGE_STATE
Definition: bms.h:136
enum BMS_CONSIDER_PRECHARGE BMS_CONSIDER_PRECHARGE_e
@ BMS_STATEMACH_PRECHARGE
Definition: bms.h:94
@ BMS_STATEMACH_STANDBY
Definition: bms.h:93
@ BMS_STATEMACH_CHARGE
Definition: bms.h:97
@ BMS_STATEMACH_OPENCONTACTORS
Definition: bms.h:92
@ BMS_STATEMACH_UNINITIALIZED
Definition: bms.h:88
@ BMS_STATEMACH_ERROR
Definition: bms.h:98
@ BMS_STATEMACH_NORMAL
Definition: bms.h:95
@ BMS_STATEMACH_INITIALIZATION
Definition: bms.h:89
@ BMS_STATEMACH_DISCHARGE
Definition: bms.h:96
@ BMS_STATEMACH_INITIALIZED
Definition: bms.h:90
@ BMS_STATEMACH_IDLE
Definition: bms.h:91
#define BMS_TIME_WAIT_AFTER_OPENING_STRING
Definition: bms_cfg.h:118
#define BMS_REQ_ID_STANDBY
Definition: bms_cfg.h:67
#define BMS_AVERAGE_STRING_CURRENT_LIMIT_MA
Definition: bms_cfg.h:136
#define BMS_TIME_WAIT_AFTER_OPENING_PRECHARGE
Definition: bms_cfg.h:142
#define BMS_STATEMACH_LONGTIME
BMS statemachine long time definition in BMS_Trigger() calls until next state/substate is processed.
Definition: bms_cfg.h:112
#define BMS_STRING_OPEN_TIMEOUT
Definition: bms_cfg.h:127
#define BMS_REQ_ID_NOREQ
Definition: bms_cfg.h:64
#define BMS_STRING_CLOSE_TIMEOUT
Timeout in BMS_Trigger() calls when closing a string after which the state machines goes to error if ...
Definition: bms_cfg.h:124
#define BMS_TIME_WAIT_AFTER_STRING_CLOSED
Definition: bms_cfg.h:115
#define BMS_NEXT_STRING_VOLTAGE_LIMIT_MV
Max voltage difference in mV between two strings to allow closing the next string.
Definition: bms_cfg.h:133
#define BMS_PRECHARGE_TRIES
Definition: bms_cfg.h:158
#define BMS_STATEMACH_MEDIUMTIME
BMS statemachine medium time definition in BMS_Trigger() calls until next state/substate is processed...
Definition: bms_cfg.h:106
#define BMS_STATEMACH_SHORTTIME
BMS statemachine short time definition in BMS_Trigger() calls until next state/substate is processed.
Definition: bms_cfg.h:100
#define BMS_REQ_ID_CHARGE
Definition: bms_cfg.h:73
#define BMS_REQ_ID_NORMAL
Definition: bms_cfg.h:70
#define BMS_NO_STRING_AVAILABLE
Functions searching for next string return this value if no further string is available.
Definition: bms_cfg.h:78
#define BMS_OSCILLATION_TIMEOUT
Timeout in 1*10ms to wait before re-entering to precharge.
Definition: bms_cfg.h:155
#define BMS_TIME_WAIT_AFTERPRECHARGEFAIL
Time to wait in BMS_Trigger() calls after precharge opened because precharge failed.
Definition: bms_cfg.h:148
#define BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV
Definition: bms_cfg.h:161
#define BMS_PRECHARGE_CURRENT_THRESHOLD_mA
Definition: bms_cfg.h:164
#define BMS_TIME_WAIT_AFTER_CLOSING_PRECHARGE
Definition: bms_cfg.h:139
CONT_ELECTRICAL_STATE_TYPE_e CONT_GetState(uint8_t contactorNumber)
Gets the current state.
Definition: contactor.c:292
void CONT_CheckFeedback(void)
checks the feedback of the contactors
Definition: contactor.c:217
STD_RETURN_TYPE_e CONT_OpenPrecharge(uint8_t stringNumber)
Opens precharge.
Definition: contactor.c:266
STD_RETURN_TYPE_e CONT_CloseString(uint8_t stringNumber)
Closes the contactor of a string.
Definition: contactor.c:222
STD_RETURN_TYPE_e CONT_ClosePrecharge(uint8_t stringNumber)
Closes precharge.
Definition: contactor.c:239
STD_RETURN_TYPE_e CONT_OpenString(uint8_t stringNumber)
Opens the contactor of a string.
Definition: contactor.c:230
Headers for the driver for the contactors.
enum CONT_ELECTRICAL_STATE_TYPE CONT_ELECTRICAL_STATE_TYPE_e
@ CONT_SWITCH_ON
Definition: contactor_cfg.h:72
@ CONT_SWITCH_OFF
Definition: contactor_cfg.h:71
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:76
#define DATA_WRITE_DATA(...)
Definition: database.h:86
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:75
@ DATA_BLOCK_ID_SYSTEMSTATE
Definition: database_cfg.h:87
@ DATA_BLOCK_ID_OPEN_WIRE_BASE
Definition: database_cfg.h:81
@ DATA_BLOCK_ID_PACK_VALUES
Definition: database_cfg.h:102
@ DATA_BLOCK_ID_STATEREQUEST
Definition: database_cfg.h:92
uint32_t DIAG_GetDelay(DIAG_ID_e diagnosisEntry)
Get configured delay of passed diagnosis entry.
Definition: diag.c:369
STD_RETURN_TYPE_e DIAG_GetDiagnosisEntryState(DIAG_ID_e diagnosisEntry)
Checks if passed diagnosis entry has been triggered or not.
Definition: diag.c:173
bool DIAG_IsAnyFatalErrorSet(void)
Check if any fatal error is set.
Definition: diag.c:374
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diag_id, DIAG_EVENT_e event, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_Handler provides generic error handling, based on diagnosis group.
Definition: diag.c:226
Diagnosis driver header.
DIAG_DEV_s diag_device
Definition: diag_cfg.c:213
@ DIAG_STRING
Definition: diag_cfg.h:249
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:236
@ DIAG_EVENT_OK
Definition: diag_cfg.h:235
@ DIAG_ID_OPEN_WIRE
Definition: diag_cfg.h:209
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:233
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:108
int32_t MATH_AbsInt32_t(const int32_t value)
Returns the absolute value of passed int32_t value.
Definition: foxmath.c:152
int64_t MATH_AbsInt64_t(const int64_t value)
Returns the absolute value of passed int64_t value.
Definition: foxmath.c:160
math library for often used math functions
@ STD_NOT_OK
Definition: fstd_types.h:73
@ STD_OK
Definition: fstd_types.h:72
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:66
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
void LED_SetToggleTime(uint32_t onOffTime_ms)
Set debug LED with defined frequency.
Definition: led.c:109
Header file of the debug LED driver.
#define LED_NORMAL_OPERATION_ON_OFF_TIME_ms
Definition: led.h:72
#define LED_ERROR_OPERATION_ON_OFF_TIME_ms
Definition: led.h:74
#define LTC_STANDBY_OPEN_WIRE_PERIOD_ms
Definition: ltc_6806_cfg.h:258
#define LTC_NORMAL_OPEN_WIRE_PERIOD_ms
Definition: ltc_6806_cfg.h:264
STD_RETURN_TYPE_e MEAS_RequestOpenWireCheck(uint8_t string)
Makes the request to the AFE state machine to perform open-wire check.
Definition: meas.c:119
Headers for the driver for the measurements needed by the BMS (e.g., I,V,T).
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:178
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:174
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os.c:182
Implementation of the tasks used by the system, headers.
void SOA_CheckTemperatures(DATA_BLOCK_MIN_MAX_s *pMinimumMaximumCellTemperatures, DATA_BLOCK_PACK_VALUES_s *pCurrent)
checks the abidance by the safe operating area
Definition: soa.c:143
void SOA_CheckVoltages(DATA_BLOCK_MIN_MAX_s *pMinimumMaximumCellVoltages)
checks the abidance by the safe operating area
Definition: soa.c:77
void SOA_CheckSlaveTemperatures(void)
FOR FUTURE COMPATIBILITY; DUMMY FUNCTION; DO NOT USE.
Definition: soa.c:357
void SOA_CheckCurrent(DATA_BLOCK_PACK_VALUES_s *pTablePackValues)
checks the abidance by the safe operating area
Definition: soa.c:275
Header for SOA module, responsible for checking battery parameters against safety limits.
Definition: bms.h:183
uint8_t deactivatedStrings[BS_NR_OF_STRINGS]
Definition: bms.h:212
BMS_STATEMACH_e nextstate
Definition: bms.h:203
BMS_STATEMACH_e state
Definition: bms.h:186
uint8_t numberOfClosedStrings
Definition: bms.h:199
uint16_t stringCloseTimeout
Definition: bms.h:202
BMS_STATE_REQUEST_e stateRequest
Definition: bms.h:185
uint8_t firstClosedString
Definition: bms.h:204
uint32_t minimumActiveDelay_ms
Definition: bms.h:208
BMS_POWER_PATH_TYPE_e powerPath
Definition: bms.h:198
uint8_t PrechargeTryCounter
Definition: bms.h:197
uint16_t OscillationTimeout
Definition: bms.h:196
uint8_t counter
Definition: bms.h:193
BMS_STATEMACH_SUB_e substate
Definition: bms.h:187
uint8_t triggerentry
Definition: bms.h:192
STD_RETURN_TYPE_e initFinished
Definition: bms.h:191
uint16_t timer
Definition: bms.h:184
uint32_t ErrRequestCounter
Definition: bms.h:190
uint32_t nextstringclosedtimer
Definition: bms.h:201
uint8_t closedStrings[BS_NR_OF_STRINGS]
Definition: bms.h:211
uint16_t stringOpenTimeout
Definition: bms.h:200
uint32_t restTimer_10ms
Definition: bms.h:195
bool transitionToErrorState
Definition: bms.h:209
uint32_t remainingDelay_ms
Definition: bms.h:207
uint8_t closedPrechargeContactors[BS_NR_OF_STRINGS]
Definition: bms.h:210
BMS_CURRENT_FLOW_STATE_e currentFlowState
Definition: bms.h:194
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:111
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:150
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:290
uint8_t openwire[BS_NR_OF_STRINGS][BS_NR_OF_MODULES *(BS_NR_OF_CELLS_PER_MODULE+1u)]
Definition: database_cfg.h:294
int32_t stringCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:191
int32_t highVoltageBusVoltage_mV
Definition: database_cfg.h:185
uint8_t invalidStringCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:192
int32_t stringVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:189
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:178
uint8_t invalidStringVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:190
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:502
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:414
DIAG_ID_e id
Definition: diag_cfg.h:302
DIAG_ID_CFG_s * pFatalErrorLinkTable[DIAG_ID_MAX]
Definition: diag_cfg.h:325
uint16_t numberOfFatalErrors
Definition: diag_cfg.h:323