foxBMS - Unit Tests  1.3.0
The foxBMS Unit Tests API Documentation
bms.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, 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 2022-05-30 (date of last update)
47  * @version v1.3.0
48  * @ingroup ENGINE
49  * @prefix BMS
50  *
51  * @brief bms driver implementation
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "bms.h"
56 
57 #include "battery_cell_cfg.h"
58 
59 #include "afe.h"
60 #include "bal.h"
61 #include "contactor.h"
62 #include "database.h"
63 #include "diag.h"
64 #include "foxmath.h"
65 #include "imd.h"
66 #include "led.h"
67 #include "meas.h"
68 #include "os.h"
69 #include "soa.h"
70 
71 /*========== Macros and Definitions =========================================*/
72 /** default value for unset "active delay time" */
73 #define BMS_NO_ACTIVE_DELAY_TIME_ms (UINT32_MAX)
74 
75 /**
76  * Saves the last state and the last substate
77  */
78 #define BMS_SAVELASTSTATES() \
79  bms_state.laststate = bms_state.state; \
80  bms_state.lastsubstate = bms_state.substate
81 
82 /*========== Static Constant and Variable Definitions =======================*/
83 
84 /**
85  * contains the state of the bms state machine
86  */
88  .timer = 0,
89  .stateRequest = BMS_STATE_NO_REQUEST,
91  .substate = BMS_ENTRY,
92  .laststate = BMS_STATEMACH_UNINITIALIZED,
93  .lastsubstate = BMS_ENTRY,
94  .triggerentry = 0u,
95  .ErrRequestCounter = 0u,
96  .initFinished = STD_NOT_OK,
97  .counter = 0u,
98  .OscillationTimeout = 0u,
99  .PrechargeTryCounter = 0u,
100  .powerPath = BMS_POWER_PATH_OPEN,
101  .closedStrings = {0u},
102  .closedPrechargeContactors = {0u},
103  .numberOfClosedStrings = 0u,
104  .deactivatedStrings = {0},
105  .firstClosedString = 0u,
106  .stringOpenTimeout = 0u,
107  .nextstringclosedtimer = 0u,
108  .stringCloseTimeout = 0u,
109  .nextstate = BMS_STATEMACH_STANDBY,
110  .restTimer_10ms = BS_RELAXATION_PERIOD_10ms,
111  .currentFlowState = BMS_RELAXATION,
112  .remainingDelay_ms = BMS_NO_ACTIVE_DELAY_TIME_ms,
113  .minimumActiveDelay_ms = BMS_NO_ACTIVE_DELAY_TIME_ms,
114  .transitionToErrorState = false,
115 };
116 
117 /** local copies of database tables */
118 /**@{*/
122 /**@}*/
123 
124 /*========== Extern Constant and Variable Definitions =======================*/
125 
126 /*========== Static Function Prototypes =====================================*/
127 
128 /**
129  * @brief checks the state requests that are made.
130  * @details This function checks the validity of the state requests. The
131  * results of the checked is returned immediately.
132  * @param[in] statereq state request to be checked
133  * @return result of the state request that was made
134  */
136 
137 /**
138  * @brief transfers the current state request to the state machine.
139  * @details This function takes the current state request from #bms_state
140  * transfers it to the state machine. It resets the value from
141  * #bms_state to #BMS_STATE_NO_REQUEST
142  * @return current state request
143  */
145 
146 /**
147  * @brief re-entrance check of SYS state machine trigger function
148  * @details This function is not re-entrant and should only be called time- or
149  * event-triggered. It increments the triggerentry counter from the
150  * state variable ltc_state. It should never be called by two
151  * different processes, so if it is the case, triggerentry should
152  * never be higher than 0 when this function is called.
153  * @return retval 0 if no further instance of the function is active, 0xff
154  * else
155  */
156 static uint8_t BMS_CheckReEntrance(void);
157 
158 /**
159  * @brief Checks the state requests made to the BMS state machine.
160  * @details Checks of the state request in the database and sets this value as
161  * return value.
162  * @return requested state
163  */
164 static uint8_t BMS_CheckCanRequests(void);
165 
166 /**
167  * @brief Checks all the error flags from diagnosis module with a severity of
168  * #DIAG_FATAL_ERROR
169  * @details Checks all the error flags from diagnosis module with a severity of
170  * #DIAG_FATAL_ERROR. Furthermore, sets parameter minimumActiveDelay_ms
171  * of bms_state variable.
172  * @return true if error flag is set, otherwise false
173  */
174 static bool BMS_IsAnyFatalErrorFlagSet(void);
175 
176 /**
177  * @brief Checks if any error flag is set and handles delay until contactors
178  * need to be opened.
179  * @details Checks all the diagnosis entries with severity of #DIAG_FATAL_ERROR
180  * and handles the configured delay until the contactors need to be
181  * opened. The shortest delay is used, if multiple errors are active at
182  * once.
183  * @return #STD_NOT_OK if error detected and delay time elapsed, otherwise #STD_OK
184  */
186 
187 /** Get latest database entries for static module variables */
188 static void BMS_GetMeasurementValues(void);
189 
190 /**
191  * @brief Check for any open voltage sense wire
192  */
193 static void BMS_CheckOpenSenseWire(void);
194 
195 /**
196  * @brief Checks if the current limitations are violated
197  * @param[in] stringNumber string addressed
198  * @param[in] pPackValues pointer to pack values database entry
199  * @return #STD_OK if the current limitations are NOT violated, else
200  * #STD_NOT_OK (type: #STD_RETURN_TYPE_e)
201  */
202 static STD_RETURN_TYPE_e BMS_CheckPrecharge(uint8_t stringNumber, const DATA_BLOCK_PACK_VALUES_s *pPackValues);
203 
204 /**
205  * @brief Returns ID of string with highest total voltage
206  * @details This is used to close the first string when drive-off is requested.
207  * @param[in] precharge If #BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT,
208  * precharge availability for string is ignored.
209  * if #BMS_TAKE_PRECHARGE_INTO_ACCCOUNT, only select
210  * string that has precharge available.
211  * @param[in] pPackValues pointer to pack values database entry
212  * @return index of string with highest voltage If no string is available,
213  * returns #BMS_NO_STRING_AVAILABLE.
214  */
215 static uint8_t BMS_GetHighestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues);
216 
217 /**
218  * @brief Returns ID of string with voltage closest to first closed string voltage
219  * @details This is used to close further strings in drive.
220  * @param[in] precharge If #BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT,
221  * precharge availability for string is ignored.
222  * if #BMS_TAKE_PRECHARGE_INTO_ACCCOUNT, only select
223  * string that has precharge available.
224  * @param[in] pPackValues pointer to pack values database entry
225  * @return index of string with voltage closest to the first closed string voltage.
226  * If no string is available, returns #BMS_NO_STRING_AVAILABLE.
227  */
228 static uint8_t BMS_GetClosestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues);
229 
230 /**
231  * @brief Returns ID of string with lowest total voltage
232  * @details This is used to close the first string when charge-off is requested.
233  *
234  * @param[in] precharge If 0, precharge availability for string is ignored.
235  * If 1, only selects a string that has precharge
236  * available.
237  * @param[in] pPackValues pointer to pack values database entry
238  * @return index of string with lowest voltage. If no string is available,
239  * returns #BMS_NO_STRING_AVAILABLE.
240  */
241 static uint8_t BMS_GetLowestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues);
242 
243 /**
244  * @brief Returns voltage difference between first closed string and
245  * string ID
246  * @details This function is used to check voltage when trying to close further
247  * strings.
248  * @param[in] string ID of string that must be compared with first closed
249  * string
250  * @param[in] pPackValues pointer to pack values database entry
251  * @return voltage difference in mV, will return INT32_MAX if voltages are
252  * invalid and difference can not be calculated
253  */
254 static int32_t BMS_GetStringVoltageDifference(uint8_t string, const DATA_BLOCK_PACK_VALUES_s *pPackValues);
255 
256 /**
257  * @brief Returns the average current flowing through all strings.
258  * @details This function is used when closing strings.
259  * @param[in] pPackValues pointer to pack values database entry
260  * @return average current taking all strings into account in mA. INT32_MAX if there is no valid current measurement
261  */
262 static int32_t BMS_GetAverageStringCurrent(DATA_BLOCK_PACK_VALUES_s *pPackValues);
263 
264 /**
265  * @brief Updates battery system state variable depending on measured/recent
266  * current values
267  * @param[in] pPackValues recent measured values from current sensor
268  */
269 static void BMS_UpdateBatsysState(DATA_BLOCK_PACK_VALUES_s *pPackValues);
270 
271 /*========== Static Function Implementations ================================*/
272 
274  if (statereq == BMS_STATE_ERROR_REQUEST) {
275  return BMS_OK;
276  }
277 
279  /* init only allowed from the uninitialized state */
280  if (statereq == BMS_STATE_INIT_REQUEST) {
282  return BMS_OK;
283  } else {
285  }
286  } else {
287  return BMS_ILLEGAL_REQUEST;
288  }
289  } else {
290  return BMS_REQUEST_PENDING;
291  }
292 }
293 
294 static uint8_t BMS_CheckReEntrance(void) {
295  uint8_t retval = 0;
297  if (!bms_state.triggerentry) {
299  } else {
300  retval = 0xFF; /* multiple calls of function */
301  }
303  return retval;
304 }
305 
308 
310  retval = bms_state.stateRequest;
313  return retval;
314 }
315 
316 static void BMS_GetMeasurementValues(void) {
318 }
319 
320 static uint8_t BMS_CheckCanRequests(void) {
321  uint8_t retVal = BMS_REQ_ID_NOREQ;
323 
324  DATA_READ_DATA(&request);
325 
326  if (request.stateRequestViaCan == BMS_REQ_ID_STANDBY) {
327  retVal = BMS_REQ_ID_STANDBY;
328  } else if (request.stateRequestViaCan == BMS_REQ_ID_NORMAL) {
329  retVal = BMS_REQ_ID_NORMAL;
330  } else if (request.stateRequestViaCan == BMS_REQ_ID_CHARGE) {
331  retVal = BMS_REQ_ID_CHARGE;
332  } else {
333  /* invalid or no request, default to BMS_REQ_ID_NOREQ (already set) */
334  }
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_PER_STRING; m++) {
345  /* Iterate over all voltage sense wires: cells per module + 1 */
346  for (uint8_t wire = 0u; wire < (BS_NR_OF_CELL_BLOCKS_PER_MODULE + 1); wire++) {
347  /* open wire detected */
348  if (bms_tableOpenWire.openwire[s][(wire + (m * (BS_NR_OF_CELL_BLOCKS_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 ((pPackValues->invalidStringCurrent[stringNumber] == 0u) &&
373  (pPackValues->invalidStringVoltage[stringNumber] == 0u) && (pPackValues->invalidHvBusVoltage == 0u)) {
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 (bms_state.transitionToErrorState == true) {
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 (isErrorActive == true) {
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 ((bms_state.transitionToErrorState == true) && (bms_state.remainingDelay_ms == 0u)) {
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  (pPackValues->invalidStringVoltage[s] == 0u)) {
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 (pPackValues->invalidStringVoltage[bms_state.firstClosedString] == 0u) {
485  closedStringVoltage_mV = pPackValues->stringVoltage_mV[bms_state.firstClosedString];
486  searchString = true;
487  } else if (pPackValues->invalidHvBusVoltage == 0u) {
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 (searchString == true) {
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 ((isStringClosed == false) && (isStringVoltageValid == 0u)) {
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  (pPackValues->invalidStringVoltage[s] == 0u)) {
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 ((pPackValues->invalidStringVoltage[string] == 0u) &&
552  (pPackValues->invalidStringVoltage[bms_state.firstClosedString] == 0u)) {
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 ((pPackValues->invalidStringVoltage[string] == 0u) && (pPackValues->invalidHvBusVoltage == 0u)) {
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 (pPackValues->invalidPackCurrent == 1u) {
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 (pPackValues->invalidPackCurrent == 0u) {
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******************************/
726  /* Initialization of IMD device not finished yet -> wait until this is finished before moving on */
728  } else {
733  }
734  break;
735 
736  /****************************IDLE*************************************/
737  case BMS_STATEMACH_IDLE:
739 
740  if (bms_state.substate == BMS_ENTRY) {
741  DATA_READ_DATA(&systemstate);
742  systemstate.bmsCanState = BMS_CANSTATE_IDLE;
743  DATA_WRITE_DATA(&systemstate);
746  break;
747  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
753  break;
754  } else {
757  break;
758  }
765  break;
766  } else {
769  break;
770  }
771  }
772  break;
773 
774  /****************************OPEN CONTACTORS**************************/
777 
778  if (bms_state.substate == BMS_ENTRY) {
782  break;
784  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
788  }
789  }
790  /* Now go to string opening */
791  stringNumber = BS_NR_OF_STRINGS - 1u; /* Select last string */
794  } else if (bms_state.substate == BMS_OPEN_STRINGS) {
795  CONT_OpenString(stringNumber);
799  break;
800  } else if (bms_state.substate == BMS_CHECK_STRING_OPEN) {
801  contstate = CONT_GetState(stringNumber);
802  if (contstate == CONT_SWITCH_OFF) {
803  if (bms_state.numberOfClosedStrings > 0u) {
805  }
806  bms_state.closedStrings[stringNumber] = 0u;
807  if (stringNumber > 0u) {
808  stringNumber--;
811  break;
812  } else {
815  }
816  break;
817  } else if (bms_state.stringOpenTimeout == 0u) {
818  /* String takes too long to close, go to next string */
821  break;
822  } else {
823  /* String not opened, re-issue closing request */
824  CONT_OpenString(nextStringNumber);
826  break;
827  }
828  } else if (bms_state.substate == BMS_OPEN_STRINGS_EXIT) {
833  break;
834  } else {
838  }
839  } else {
841  }
842  break;
843 
844  /****************************STANDBY**********************************/
847  if (bms_state.substate == BMS_ENTRY) {
849 #if BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE
850  nextOpenWireCheck = timestamp + BS_STANDBY_OPEN_WIRE_PERIOD_ms;
851 #endif /* BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE */
854  DATA_READ_DATA(&systemstate);
855  systemstate.bmsCanState = BMS_CANSTATE_STANDBY;
856  DATA_WRITE_DATA(&systemstate);
857  break;
864  break;
865  } else {
868  break;
869  }
870  } else if (bms_state.substate == BMS_INTERLOCK_CHECKED) {
873  break;
874  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
880  break;
881  } else {
884  break;
885  }
893  break;
894  }
901  break;
902  } else {
903 #if BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE
904  if (nextOpenWireCheck <= timestamp) {
906  nextOpenWireCheck = timestamp + BS_STANDBY_OPEN_WIRE_PERIOD_ms;
907  }
908 #endif /* BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE */
911  break;
912  }
913  } else {
915  }
916  break;
917 
918  /****************************PRECHARGE********************************/
921 
922  if (bms_state.substate == BMS_ENTRY) {
923  DATA_READ_DATA(&systemstate);
924  systemstate.bmsCanState = BMS_CANSTATE_PRECHARGE;
925  DATA_WRITE_DATA(&systemstate);
928  } else {
930  }
931  if (stringNumber == BMS_NO_STRING_AVAILABLE) {
936  break;
937  }
938  bms_state.firstClosedString = stringNumber;
939  if (bms_state.OscillationTimeout == 0u) {
942  } else if (BMS_IsBatterySystemStateOkay() == STD_NOT_OK) {
943  /* If precharge re-enter timeout not elapsed, wait (and check errors while waiting) */
948  break;
949  }
950  break;
954  bms_state.closedPrechargeContactors[stringNumber] = 1u;
955  if (contRetVal == STD_OK) {
959  } else {
964  }
965  break;
972  break;
973  } else {
976  break;
977  }
984  break;
985  } else {
988  }
991  if (retVal == STD_OK) {
995  break;
996  } else {
999  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1000  if (contRetVal == STD_OK) {
1004  } else {
1009  }
1010  break;
1011  } else {
1013  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1018  break;
1019  }
1020  }
1028  if (contstate == CONT_SWITCH_ON) {
1033  break;
1034  } else if (bms_state.stringCloseTimeout == 0u) {
1035  /* String takes too long to close */
1040  break;
1041  } else {
1042  /* String not closed, re-issue closing request */
1046  break;
1047  }
1054  break;
1055  } else {
1058  break;
1059  }
1061  /* Always make one error check after the first string was closed successfully */
1067  break;
1068  } else {
1071  break;
1072  }
1075  if (contRetVal == STD_OK) {
1076  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1080  } else {
1085  }
1086  break;
1087  } else {
1089  }
1090  break;
1091 
1092  /****************************NORMAL**************************************/
1093  case BMS_STATEMACH_NORMAL:
1095 
1096  if (bms_state.substate == BMS_ENTRY) {
1097 #if BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE
1098  nextOpenWireCheck = timestamp + BS_NORMAL_OPEN_WIRE_PERIOD_ms;
1099 #endif /* BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE */
1100  DATA_READ_DATA(&systemstate);
1102  systemstate.bmsCanState = BMS_CANSTATE_CHARGE;
1103  } else {
1104  systemstate.bmsCanState = BMS_CANSTATE_NORMAL;
1105  }
1106  DATA_WRITE_DATA(&systemstate);
1110  break;
1111  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
1116  break;
1117  } else {
1120  break;
1121  }
1128  break;
1129  } else {
1130 #if BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE
1131  if (nextOpenWireCheck <= timestamp) {
1133  nextOpenWireCheck = timestamp + BS_NORMAL_OPEN_WIRE_PERIOD_ms;
1134  }
1135 #endif /* BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE */
1138  break;
1139  }
1141  if (bms_state.nextstringclosedtimer == 0u) {
1142  nextStringNumber =
1144  if (nextStringNumber == BMS_NO_STRING_AVAILABLE) {
1147  break;
1148  } else if (
1149  (BMS_GetStringVoltageDifference(nextStringNumber, &bms_tablePackValues) <=
1152  /* Voltage/current conditions suitable to close a further string */
1153  CONT_CloseString(nextStringNumber);
1157  break;
1158  }
1159  } else {
1162  break;
1163  }
1164  } else if (bms_state.substate == BMS_CHECK_STRING_CLOSED) {
1165  contstate = CONT_GetState(nextStringNumber);
1166  if (contstate == CONT_SWITCH_ON) {
1168  bms_state.closedStrings[nextStringNumber] = 1u;
1170  /* Go to begin of NORMAL case to redo the full procedure with error check and request check */
1172  break;
1173  } else if (bms_state.stringCloseTimeout == 0u) {
1174  /* String takes too long to close */
1179  break;
1180  } else if (BMS_IsBatterySystemStateOkay() == STD_NOT_OK) {
1185  break;
1186  } else if (BMS_CheckCanRequests() == BMS_REQ_ID_STANDBY) {
1191  break;
1192  } else {
1193  /* String not closed, re-issue closing request */
1194  CONT_CloseString(nextStringNumber);
1196  break;
1197  }
1198  } else {
1200  }
1201  break;
1202 
1203  /****************************ERROR*************************************/
1204  case BMS_STATEMACH_ERROR:
1206 
1207  if (bms_state.substate == BMS_ENTRY) {
1208  /* Set BMS System state to error */
1209  DATA_READ_DATA(&systemstate);
1210  systemstate.bmsCanState = BMS_CANSTATE_ERROR;
1211  DATA_WRITE_DATA(&systemstate);
1212  /* Deactivate balancing */
1214  /* Change LED toggle frequency to indicate an error */
1216  /* Set timer for next open wire check */
1217  nextOpenWireCheck = timestamp + AFE_ERROR_OPEN_WIRE_PERIOD_ms;
1218  /* Switch to next substate */
1221  break;
1222  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
1223  if (DIAG_IsAnyFatalErrorSet() == true) {
1224  /* we stay already in requested state */
1225  if (nextOpenWireCheck <= timestamp) {
1226  /* Perform open-wire check periodically */
1227  /* MEAS_RequestOpenWireCheck(); */ /*TODO: check with strings */
1228  nextOpenWireCheck = timestamp + AFE_ERROR_OPEN_WIRE_PERIOD_ms;
1229  }
1230  } else {
1231  /* No error detected anymore - reset fatal error related variables */
1235  /* Check for STANDBY request */
1238  break;
1239  }
1242  /* Activate balancing again */
1244  /* Set LED frequency to normal operation as we leave error
1245  state subsequently */
1247 
1248  /* Verify that all contactors are opened and switch to
1249  * STANDBY state afterwards */
1253  break;
1254  } else {
1257  break;
1258  }
1259  } else {
1260  /* invalid state -> this should never be reached */
1262  }
1263  break;
1264  default:
1265  /* invalid state */
1267  break;
1268  } /* end switch (bms_state.state) */
1269 
1271  bms_state.counter++;
1272 }
1273 
1275  return bms_state.currentFlowState;
1276 }
1277 
1279  /* AXIVION Routine Generic-MissingParameterAssert: current_mA: parameter accepts whole range */
1281 
1282  if (POSITIVE_DISCHARGE_CURRENT == true) {
1283  if (current_mA >= BS_REST_CURRENT_mA) {
1284  retVal = BMS_DISCHARGING;
1285  } else if (current_mA <= -BS_REST_CURRENT_mA) {
1286  retVal = BMS_CHARGING;
1287  } else {
1288  retVal = BMS_AT_REST;
1289  }
1290  } else {
1291  if (current_mA <= -BS_REST_CURRENT_mA) {
1292  retVal = BMS_DISCHARGING;
1293  } else if (current_mA >= BS_REST_CURRENT_mA) {
1294  retVal = BMS_CHARGING;
1295  } else {
1296  retVal = BMS_AT_REST;
1297  }
1298  }
1299  return retVal;
1300 }
1301 
1302 extern bool BMS_IsStringClosed(uint8_t stringNumber) {
1303  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
1304  bool retval = false;
1305  if (bms_state.closedStrings[stringNumber] == 1u) {
1306  retval = true;
1307  }
1308  return retval;
1309 }
1310 
1311 extern bool BMS_IsStringPrecharging(uint8_t stringNumber) {
1312  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
1313  bool retval = false;
1314  if (bms_state.closedPrechargeContactors[stringNumber] == 1u) {
1315  retval = true;
1316  }
1317  return retval;
1318 }
1319 
1320 extern uint8_t BMS_GetNumberOfConnectedStrings(void) {
1322 }
1323 
1326 }
1327 
1328 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1329 #ifdef UNITY_UNIT_TEST
1331  return BMS_CheckStateRequest(statereq);
1332 }
1334  return BMS_TransferStateRequest();
1335 }
1336 extern uint8_t TEST_BMS_CheckReEntrance(void) {
1337  return BMS_CheckReEntrance();
1338 }
1339 extern uint8_t TEST_BMS_CheckCanRequests(void) {
1340  return BMS_CheckCanRequests();
1341 }
1343  return BMS_IsAnyFatalErrorFlagSet();
1344 }
1347 }
1350 }
1351 extern void TEST_BMS_CheckOpenSenseWire(void) {
1353 }
1354 extern STD_RETURN_TYPE_e TEST_BMS_CheckPrecharge(uint8_t stringNumber, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1355  return BMS_CheckPrecharge(stringNumber, pPackValues);
1356 }
1358  return BMS_GetHighestString(precharge, pPackValues);
1359 }
1361  return BMS_GetClosestString(precharge, pPackValues);
1362 }
1363 
1365  return BMS_GetLowestString(precharge, pPackValues);
1366 }
1367 extern int32_t TEST_BMS_GetStringVoltageDifference(uint8_t string, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1368  return BMS_GetStringVoltageDifference(string, pPackValues);
1369 }
1371  return BMS_GetAverageStringCurrent(pPackValues);
1372 }
1374  BMS_UpdateBatsysState(pPackValues);
1375 }
1376 
1377 #endif
AFE driver header.
#define AFE_ERROR_OPEN_WIRE_PERIOD_ms
Definition: afe.h:65
Header for the driver for balancing.
@ BAL_STATE_ALLOWBALANCING_REQUEST
Definition: bal.h:104
@ BAL_STATE_NO_BALANCING_REQUEST
Definition: bal.h:103
BAL_RETURN_TYPE_e BAL_SetStateRequest(BAL_STATE_REQUEST_e stateRequest)
sets the current state request of the state variable bal_state.
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_CELL_BLOCKS_PER_MODULE
number of cells per module
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_REST_CURRENT_mA
current threshold for determing rest state of battery. If absolute current is below this limit value ...
#define POSITIVE_DISCHARGE_CURRENT
#define BS_NR_OF_MODULES_PER_STRING
number of modules in a string
#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:1364
void TEST_BMS_CheckOpenSenseWire(void)
Definition: bms.c:1351
#define BMS_SAVELASTSTATES()
Definition: bms.c:78
static DATA_BLOCK_MIN_MAX_s bms_tableMinMax
Definition: bms.c:119
uint8_t TEST_BMS_GetClosestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1360
BMS_RETURN_TYPE_e TEST_BMS_CheckStateRequest(BMS_STATE_REQUEST_e statereq)
Definition: bms.c:1330
bool BMS_IsStringPrecharging(uint8_t stringNumber)
Returns if string is currently precharging or not.
Definition: bms.c:1311
bool BMS_IsTransitionToErrorStateActive(void)
Check if transition in to error state is active.
Definition: bms.c:1324
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:1333
STD_RETURN_TYPE_e TEST_BMS_CheckPrecharge(uint8_t stringNumber, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1354
static BMS_RETURN_TYPE_e BMS_CheckStateRequest(BMS_STATE_REQUEST_e statereq)
checks the state requests that are made.
Definition: bms.c:273
int32_t TEST_BMS_GetStringVoltageDifference(uint8_t string, DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1367
uint8_t TEST_BMS_CheckCanRequests(void)
Definition: bms.c:1339
static void BMS_GetMeasurementValues(void)
Definition: bms.c:316
static DATA_BLOCK_PACK_VALUES_s bms_tablePackValues
Definition: bms.c:121
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:73
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:1336
void TEST_BMS_GetMeasurementValues(void)
Definition: bms.c:1348
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:1320
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1302
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:1278
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:1345
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:1274
int32_t TEST_BMS_GetAverageStringCurrent(DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1370
bool TEST_BMS_IsAnyFatalErrorFlagSet(void)
Definition: bms.c:1342
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:294
static DATA_BLOCK_OPEN_WIRE_s bms_tableOpenWire
Definition: bms.c:120
static BMS_STATE_REQUEST_e BMS_TransferStateRequest(void)
transfers the current state request to the state machine.
Definition: bms.c:306
void TEST_BMS_UpdateBatsysState(DATA_BLOCK_PACK_VALUES_s *pPackValues)
Definition: bms.c:1373
static BMS_STATE_s bms_state
Definition: bms.c:87
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:320
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:1357
bms driver header
@ BMS_CANSTATE_NORMAL
Definition: bms.h:114
@ BMS_CANSTATE_CHARGE
Definition: bms.h:115
@ BMS_CANSTATE_STANDBY
Definition: bms.h:112
@ BMS_CANSTATE_ERROR
Definition: bms.h:116
@ BMS_CANSTATE_IDLE
Definition: bms.h:110
@ BMS_CANSTATE_PRECHARGE
Definition: bms.h:113
BMS_CONSIDER_PRECHARGE_e
Definition: bms.h:81
@ BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT
Definition: bms.h:82
@ BMS_TAKE_PRECHARGE_INTO_ACCCOUNT
Definition: bms.h:83
BMS_STATE_REQUEST_e
Definition: bms.h:154
@ BMS_STATE_NO_REQUEST
Definition: bms.h:157
@ BMS_STATE_INIT_REQUEST
Definition: bms.h:155
@ BMS_STATE_ERROR_REQUEST
Definition: bms.h:156
@ BMS_PRECHARGE_OPEN_PRECHARGE
Definition: bms.h:132
@ BMS_CHECK_STRING_OPEN
Definition: bms.h:149
@ BMS_OPEN_STRINGS_EXIT
Definition: bms.h:150
@ BMS_PRECHARGE_CLOSE_PRECHARGE
Definition: bms.h:130
@ BMS_NORMAL_CLOSE_NEXT_STRING
Definition: bms.h:144
@ BMS_CHECK_ERROR_FLAGS_PRECHARGE_CLOSINGSTRINGS
Definition: bms.h:142
@ BMS_ENTRY
Definition: bms.h:121
@ BMS_INTERLOCK_CHECKED
Definition: bms.h:123
@ BMS_OPEN_STRINGS
Definition: bms.h:148
@ BMS_CHECK_ERROR_FLAGS_PRECHARGE_FIRST_STRING
Definition: bms.h:139
@ BMS_CHECK_ERROR_FLAGS_CLOSINGPRECHARGE
Definition: bms.h:143
@ BMS_PRECHARGE_CHECK_VOLTAGES
Definition: bms.h:131
@ BMS_CHECK_STRING_CLOSED
Definition: bms.h:141
@ BMS_CHECK_ERROR_FLAGS
Definition: bms.h:126
@ BMS_OPEN_ALL_PRECHARGES
Definition: bms.h:145
@ BMS_CHECK_ERROR_FLAGS_INTERLOCK
Definition: bms.h:122
@ BMS_CHECK_STATE_REQUESTS
Definition: bms.h:124
@ BMS_CLOSE_FIRST_STRING_PRECHARGE_STATE
Definition: bms.h:136
@ BMS_CHECK_CLOSE_FIRST_STRING_PRECHARGE_STATE
Definition: bms.h:137
@ BMS_POWER_PATH_1
Definition: bms.h:174
@ BMS_POWER_PATH_OPEN
Definition: bms.h:172
@ BMS_POWER_PATH_0
Definition: bms.h:173
BMS_STATEMACH_e
Definition: bms.h:87
@ BMS_STATEMACH_PRECHARGE
Definition: bms.h:95
@ BMS_STATEMACH_STANDBY
Definition: bms.h:94
@ BMS_STATEMACH_CHARGE
Definition: bms.h:98
@ BMS_STATEMACH_OPENCONTACTORS
Definition: bms.h:93
@ BMS_STATEMACH_UNINITIALIZED
Definition: bms.h:89
@ BMS_STATEMACH_ERROR
Definition: bms.h:99
@ BMS_STATEMACH_NORMAL
Definition: bms.h:96
@ BMS_STATEMACH_INITIALIZATION
Definition: bms.h:90
@ BMS_STATEMACH_DISCHARGE
Definition: bms.h:97
@ BMS_STATEMACH_INITIALIZED
Definition: bms.h:91
@ BMS_STATEMACH_IDLE
Definition: bms.h:92
BMS_CURRENT_FLOW_STATE_e
Definition: bms.h:66
@ BMS_AT_REST
Definition: bms.h:70
@ BMS_DISCHARGING
Definition: bms.h:68
@ BMS_CHARGING
Definition: bms.h:67
@ BMS_RELAXATION
Definition: bms.h:69
BMS_RETURN_TYPE_e
Definition: bms.h:163
@ BMS_OK
Definition: bms.h:164
@ BMS_REQUEST_PENDING
Definition: bms.h:165
@ BMS_ALREADY_INITIALIZED
Definition: bms.h:167
@ BMS_ILLEGAL_REQUEST
Definition: bms.h:166
#define BMS_TIME_WAIT_AFTER_OPENING_STRING
Definition: bms_cfg.h:119
#define BMS_REQ_ID_STANDBY
Definition: bms_cfg.h:68
#define BMS_AVERAGE_STRING_CURRENT_LIMIT_MA
Definition: bms_cfg.h:137
#define BMS_TIME_WAIT_AFTER_OPENING_PRECHARGE
Definition: bms_cfg.h:143
#define BMS_STATEMACH_LONGTIME
BMS statemachine long time definition in BMS_Trigger() calls until next state/substate is processed.
Definition: bms_cfg.h:113
#define BMS_STRING_OPEN_TIMEOUT
Definition: bms_cfg.h:128
#define BMS_REQ_ID_NOREQ
Definition: bms_cfg.h:65
#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:125
#define BMS_TIME_WAIT_AFTER_STRING_CLOSED
Definition: bms_cfg.h:116
#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:134
#define BMS_PRECHARGE_TRIES
Definition: bms_cfg.h:159
#define BMS_STATEMACH_MEDIUMTIME
BMS statemachine medium time definition in BMS_Trigger() calls until next state/substate is processed...
Definition: bms_cfg.h:107
#define BMS_STATEMACH_SHORTTIME
BMS statemachine short time definition in BMS_Trigger() calls until next state/substate is processed.
Definition: bms_cfg.h:101
#define BMS_REQ_ID_CHARGE
Definition: bms_cfg.h:74
#define BMS_REQ_ID_NORMAL
Definition: bms_cfg.h:71
#define BMS_NO_STRING_AVAILABLE
Functions searching for next string return this value if no further string is available.
Definition: bms_cfg.h:79
#define BMS_OSCILLATION_TIMEOUT
Timeout in 1*10ms to wait before re-entering to precharge.
Definition: bms_cfg.h:156
#define BMS_TIME_WAIT_AFTERPRECHARGEFAIL
Time to wait in BMS_Trigger() calls after precharge opened because precharge failed.
Definition: bms_cfg.h:149
#define BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV
Definition: bms_cfg.h:162
#define BMS_PRECHARGE_CURRENT_THRESHOLD_mA
Definition: bms_cfg.h:165
#define BMS_TIME_WAIT_AFTER_CLOSING_PRECHARGE
Definition: bms_cfg.h:140
CONT_ELECTRICAL_STATE_TYPE_e CONT_GetState(uint8_t contactorNumber)
Gets the current state.
Definition: contactor.c:297
void CONT_CheckFeedback(void)
checks the feedback of the contactors
Definition: contactor.c:222
STD_RETURN_TYPE_e CONT_OpenPrecharge(uint8_t stringNumber)
Opens precharge.
Definition: contactor.c:271
STD_RETURN_TYPE_e CONT_CloseString(uint8_t stringNumber)
Closes the contactor of a string.
Definition: contactor.c:227
STD_RETURN_TYPE_e CONT_ClosePrecharge(uint8_t stringNumber)
Closes precharge.
Definition: contactor.c:244
STD_RETURN_TYPE_e CONT_OpenString(uint8_t stringNumber)
Opens the contactor of a string.
Definition: contactor.c:235
Headers for the driver for the contactors.
CONT_ELECTRICAL_STATE_TYPE_e
Definition: contactor_cfg.h:71
@ CONT_SWITCH_ON
Definition: contactor_cfg.h:73
@ CONT_SWITCH_OFF
Definition: contactor_cfg.h:72
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:83
#define DATA_WRITE_DATA(...)
Definition: database.h:93
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:78
@ DATA_BLOCK_ID_SYSTEMSTATE
Definition: database_cfg.h:90
@ DATA_BLOCK_ID_OPEN_WIRE_BASE
Definition: database_cfg.h:84
@ DATA_BLOCK_ID_PACK_VALUES
Definition: database_cfg.h:105
@ DATA_BLOCK_ID_STATEREQUEST
Definition: database_cfg.h:95
uint32_t DIAG_GetDelay(DIAG_ID_e diagnosisEntry)
Get configured delay of passed diagnosis entry.
Definition: diag.c:372
STD_RETURN_TYPE_e DIAG_GetDiagnosisEntryState(DIAG_ID_e diagnosisEntry)
Checks if passed diagnosis entry has been triggered or not.
Definition: diag.c:175
bool DIAG_IsAnyFatalErrorSet(void)
Check if any fatal error is set.
Definition: diag.c:377
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:229
Diagnosis driver header.
DIAG_DEV_s diag_device
Definition: diag_cfg.c:217
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:239
@ DIAG_EVENT_OK
Definition: diag_cfg.h:238
@ DIAG_STRING
Definition: diag_cfg.h:252
@ DIAG_ID_AFE_OPEN_WIRE
Definition: diag_cfg.h:210
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:237
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:115
int32_t MATH_AbsInt32_t(const int32_t value)
Returns the absolute value of passed int32_t value.
Definition: foxmath.c:153
int64_t MATH_AbsInt64_t(const int64_t value)
Returns the absolute value of passed int64_t value.
Definition: foxmath.c:161
math library for often used math functions
STD_RETURN_TYPE_e
Definition: fstd_types.h:81
@ STD_NOT_OK
Definition: fstd_types.h:83
@ STD_OK
Definition: fstd_types.h:82
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
#define BS_NORMAL_OPEN_WIRE_PERIOD_ms
#define BS_STANDBY_OPEN_WIRE_PERIOD_ms
IMD_RETURN_TYPE_e IMD_RequestInsulationMeasurement(void)
Request to activate the actual IMD measurement.
Definition: imd.c:512
API header for the insulation monitoring device.
@ IMD_ILLEGAL_REQUEST
Definition: imd.h:79
void LED_SetToggleTime(uint32_t onOffTime_ms)
Set debug LED with defined frequency.
Definition: led.c:110
Header file of the debug LED driver.
#define LED_NORMAL_OPERATION_ON_OFF_TIME_ms
Definition: led.h:73
#define LED_ERROR_OPERATION_ON_OFF_TIME_ms
Definition: led.h:75
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:120
Headers for the driver for the measurements needed by the BMS (e.g., I,V,T).
Declaration of the OS wrapper interface.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:135
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:131
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:139
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:145
void SOA_CheckVoltages(DATA_BLOCK_MIN_MAX_s *pMinimumMaximumCellVoltages)
checks the abidance by the safe operating area
Definition: soa.c:78
void SOA_CheckSlaveTemperatures(void)
FOR FUTURE COMPATIBILITY; DUMMY FUNCTION; DO NOT USE.
Definition: soa.c:351
void SOA_CheckCurrent(DATA_BLOCK_PACK_VALUES_s *pTablePackValues)
checks the abidance by the safe operating area
Definition: soa.c:269
Header for SOA module, responsible for checking battery parameters against safety limits.
uint32_t restTimer_10ms
Definition: bms.h:194
uint8_t PrechargeTryCounter
Definition: bms.h:196
uint8_t counter
Definition: bms.h:192
bool transitionToErrorState
Definition: bms.h:208
uint16_t timer
Definition: bms.h:183
BMS_CURRENT_FLOW_STATE_e currentFlowState
Definition: bms.h:193
uint8_t triggerentry
Definition: bms.h:191
STD_RETURN_TYPE_e initFinished
Definition: bms.h:190
uint8_t closedPrechargeContactors[BS_NR_OF_STRINGS]
Definition: bms.h:209
BMS_STATEMACH_e nextstate
Definition: bms.h:202
uint8_t closedStrings[BS_NR_OF_STRINGS]
Definition: bms.h:210
uint8_t firstClosedString
Definition: bms.h:203
uint8_t deactivatedStrings[BS_NR_OF_STRINGS]
Definition: bms.h:211
uint32_t nextstringclosedtimer
Definition: bms.h:200
BMS_STATE_REQUEST_e stateRequest
Definition: bms.h:184
uint32_t ErrRequestCounter
Definition: bms.h:189
uint32_t minimumActiveDelay_ms
Definition: bms.h:207
uint8_t numberOfClosedStrings
Definition: bms.h:198
BMS_STATEMACH_e state
Definition: bms.h:185
uint16_t stringCloseTimeout
Definition: bms.h:201
BMS_STATEMACH_SUB_e substate
Definition: bms.h:186
uint16_t stringOpenTimeout
Definition: bms.h:199
BMS_POWER_PATH_TYPE_e powerPath
Definition: bms.h:197
uint32_t remainingDelay_ms
Definition: bms.h:206
uint16_t OscillationTimeout
Definition: bms.h:195
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:119
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:159
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:302
uint8_t openwire[BS_NR_OF_STRINGS][BS_NR_OF_MODULES_PER_STRING *(BS_NR_OF_CELL_BLOCKS_PER_MODULE+1u)]
Definition: database_cfg.h:307
int32_t stringVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:198
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:187
int32_t stringCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:200
uint8_t invalidStringCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:201
uint8_t invalidStringVoltage[BS_NR_OF_STRINGS]
Definition: database_cfg.h:199
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:532
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:441
DIAG_ID_CFG_s * pFatalErrorLinkTable[DIAG_ID_MAX]
Definition: diag_cfg.h:328
uint16_t numberOfFatalErrors
Definition: diag_cfg.h:326
DIAG_ID_e id
Definition: diag_cfg.h:305