foxBMS  1.4.0
The foxBMS Battery Management System 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-07-28 (date of last update)
47  * @version v1.4.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 if (request.stateRequestViaCan == BMS_REQ_ID_NOREQ) {
333  retVal = BMS_REQ_ID_NOREQ;
334  } else {
335  /* invalid or no request, default to BMS_REQ_ID_NOREQ (already set) */
336  }
337 
338  return retVal;
339 }
340 
341 static void BMS_CheckOpenSenseWire(void) {
342  uint8_t openWireDetected = 0;
343 
344  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
345  /* Iterate over all modules */
346  for (uint8_t m = 0u; m < BS_NR_OF_MODULES_PER_STRING; m++) {
347  /* Iterate over all voltage sense wires: cells per module + 1 */
348  for (uint8_t wire = 0u; wire < (BS_NR_OF_CELL_BLOCKS_PER_MODULE + 1); wire++) {
349  /* open wire detected */
350  if (bms_tableOpenWire.openwire[s][(wire + (m * (BS_NR_OF_CELL_BLOCKS_PER_MODULE + 1))) == 1] > 0u) {
351  openWireDetected++;
352 
353  /* Add additional error handling here */
354  }
355  }
356  }
357  /* Set error if open wire detected */
358  if (openWireDetected == 0u) {
360  } else {
362  }
363  }
364 }
365 
366 static STD_RETURN_TYPE_e BMS_CheckPrecharge(uint8_t stringNumber, const DATA_BLOCK_PACK_VALUES_s *pPackValues) {
367  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
368  /* make sure that we do not access the arrays in the database
369  tables out of bounds */
370  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
371  FAS_ASSERT(pPackValues != NULL_PTR);
372 
373  /* Only check precharging if current value and voltages are valid */
374  if ((pPackValues->invalidStringCurrent[stringNumber] == 0u) &&
375  (pPackValues->invalidStringVoltage[stringNumber] == 0u) && (pPackValues->invalidHvBusVoltage == 0u)) {
376  /* Only current not current direction is checked */
377  const int32_t current_mA = MATH_AbsInt32_t(pPackValues->stringCurrent_mA[stringNumber]);
378  const int64_t cont_prechargeVoltDiff_mV = MATH_AbsInt64_t(
379  (int64_t)pPackValues->stringVoltage_mV[stringNumber] - (int64_t)pPackValues->highVoltageBusVoltage_mV);
380 
381  if ((cont_prechargeVoltDiff_mV < BMS_PRECHARGE_VOLTAGE_THRESHOLD_mV) &&
382  (current_mA < BMS_PRECHARGE_CURRENT_THRESHOLD_mA)) {
383  retVal = STD_OK;
384  } else {
385  retVal = STD_NOT_OK;
386  }
387  }
388 
389  return retVal;
390 }
391 
392 static bool BMS_IsAnyFatalErrorFlagSet(void) {
393  bool fatalErrorActive = false;
394 
395  for (uint16_t entry = 0u; entry < diag_device.numberOfFatalErrors; entry++) {
396  const STD_RETURN_TYPE_e diagnosisState =
398  if (STD_NOT_OK == diagnosisState) {
399  /* Fatal error detected -> get delay of this error until contactors shall be opened */
400  const uint32_t kDelay_ms = DIAG_GetDelay(diag_device.pFatalErrorLinkTable[entry]->id);
401  /* Check if delay of detected failure is smaller than the delay of a previously detected failure */
402  if (bms_state.minimumActiveDelay_ms > kDelay_ms) {
403  bms_state.minimumActiveDelay_ms = kDelay_ms;
404  }
405  fatalErrorActive = true;
406  }
407  }
408  return fatalErrorActive;
409 }
410 
412  STD_RETURN_TYPE_e retVal = STD_OK; /* is set to STD_NOT_OK if error detected */
413  static uint32_t previousTimestamp = 0u;
414  uint32_t timestamp = OS_GetTickCount();
415 
416  /* Check if any fatal error is detected */
417  const bool isErrorActive = BMS_IsAnyFatalErrorFlagSet();
418 
419  /** Check if a fatal error has been detected previously. If yes, check delay */
420  if (bms_state.transitionToErrorState == true) {
421  /* Decrease active delay since last call */
422  const uint32_t timeSinceLastCall_ms = timestamp - previousTimestamp;
423  if (timeSinceLastCall_ms <= bms_state.remainingDelay_ms) {
424  bms_state.remainingDelay_ms -= timeSinceLastCall_ms;
425  } else {
427  }
428 
429  /* Check if delay from a new error is shorter then active delay from
430  * previously detected error in BMS statemachine */
433  }
434  } else {
435  /* Delay is not active, check if it should be activated */
436  if (isErrorActive == true) {
439  }
440  }
441 
442  /** Set previous timestamp for next call */
443  previousTimestamp = timestamp;
444 
445  /* Check if bms statemachine should switch to error state. This is the case
446  * if the delay is activated and the remaining delay is down to 0 */
447  if ((bms_state.transitionToErrorState == true) && (bms_state.remainingDelay_ms == 0u)) {
448  retVal = STD_NOT_OK;
449  }
450 
451  return retVal;
452 }
453 
455  FAS_ASSERT(pPackValues != NULL_PTR);
456  uint8_t highest_string_index = BMS_NO_STRING_AVAILABLE;
457  int32_t max_stringVoltage_mV = INT32_MIN;
458 
459  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
460  if ((pPackValues->stringVoltage_mV[s] >= max_stringVoltage_mV) &&
461  (pPackValues->invalidStringVoltage[s] == 0u)) {
462  if (bms_state.deactivatedStrings[s] == 0u) {
463  if (precharge == BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT) {
464  max_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
465  highest_string_index = s;
466  } else {
468  max_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
469  highest_string_index = s;
470  }
471  }
472  }
473  }
474  }
475 
476  return highest_string_index;
477 }
478 
480  FAS_ASSERT(pPackValues != NULL_PTR);
481  uint8_t closestStringIndex = BMS_NO_STRING_AVAILABLE;
482  int32_t closedStringVoltage_mV = 0;
483  bool searchString = false;
484 
485  /* Get voltage of first closed string */
486  if (pPackValues->invalidStringVoltage[bms_state.firstClosedString] == 0u) {
487  closedStringVoltage_mV = pPackValues->stringVoltage_mV[bms_state.firstClosedString];
488  searchString = true;
489  } else if (pPackValues->invalidHvBusVoltage == 0u) {
490  /* Use high voltage bus voltage if measured string voltage is invalid */
491  closedStringVoltage_mV = pPackValues->highVoltageBusVoltage_mV;
492  searchString = true;
493  } else {
494  /* Do not search for next string if no valid voltages could be measured */
495  searchString = false;
496  }
497 
498  if (searchString == true) {
499  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
500  const bool isStringClosed = BMS_IsStringClosed(s);
501  const uint8_t isStringVoltageValid = pPackValues->invalidStringVoltage[s];
502  if ((isStringClosed == false) && (isStringVoltageValid == 0u)) {
503  /* Only check open strings with valid voltages */
504  int32_t minimumVoltageDifference_mV = INT32_MAX;
505  int32_t voltageDifference_mV = labs(closedStringVoltage_mV - pPackValues->stringVoltage_mV[s]);
506  if (voltageDifference_mV <= minimumVoltageDifference_mV) {
507  if (bms_state.deactivatedStrings[s] == 0u) {
508  if (precharge == BMS_TAKE_PRECHARGE_INTO_ACCCOUNT) {
510  minimumVoltageDifference_mV = voltageDifference_mV;
511  closestStringIndex = s;
512  }
513  } else {
514  minimumVoltageDifference_mV = voltageDifference_mV;
515  closestStringIndex = s;
516  }
517  }
518  }
519  }
520  }
521  }
522  return closestStringIndex;
523 }
524 
526  FAS_ASSERT(pPackValues != NULL_PTR);
527  uint8_t lowest_string_index = BMS_NO_STRING_AVAILABLE;
528  int32_t min_stringVoltage_mV = INT32_MAX;
529 
530  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
531  if ((pPackValues->stringVoltage_mV[s] <= min_stringVoltage_mV) &&
532  (pPackValues->invalidStringVoltage[s] == 0u)) {
533  if (bms_state.deactivatedStrings[s] == 0u) {
534  if (precharge == BMS_DO_NOT_TAKE_PRECHARGE_INTO_ACCCOUNT) {
535  min_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
536  lowest_string_index = s;
537  } else {
539  min_stringVoltage_mV = pPackValues->stringVoltage_mV[s];
540  lowest_string_index = s;
541  }
542  }
543  }
544  }
545  }
546  return lowest_string_index;
547 }
548 
549 static int32_t BMS_GetStringVoltageDifference(uint8_t string, const DATA_BLOCK_PACK_VALUES_s *pPackValues) {
550  FAS_ASSERT(string < BS_NR_OF_STRINGS);
551  FAS_ASSERT(pPackValues != NULL_PTR);
552  int32_t voltageDifference_mV = INT32_MAX;
553  if ((pPackValues->invalidStringVoltage[string] == 0u) &&
554  (pPackValues->invalidStringVoltage[bms_state.firstClosedString] == 0u)) {
555  /* Calculate difference between string voltages */
556  voltageDifference_mV = MATH_AbsInt32_t(
557  pPackValues->stringVoltage_mV[string] - pPackValues->stringVoltage_mV[bms_state.firstClosedString]);
558  } else if ((pPackValues->invalidStringVoltage[string] == 0u) && (pPackValues->invalidHvBusVoltage == 0u)) {
559  /* Calculate difference between string and high voltage bus voltage */
560  voltageDifference_mV =
561  MATH_AbsInt32_t(pPackValues->stringVoltage_mV[string] - pPackValues->highVoltageBusVoltage_mV);
562  } else {
563  /* No valid voltages for comparison -> do not calculate difference and return INT32_MAX */
564  voltageDifference_mV = INT32_MAX;
565  }
566  return voltageDifference_mV;
567 }
568 
570  FAS_ASSERT(pPackValues != NULL_PTR);
571  int32_t average_current = pPackValues->packCurrent_mA / (int32_t)BS_NR_OF_STRINGS;
572  if (pPackValues->invalidPackCurrent == 1u) {
573  average_current = INT32_MAX;
574  }
575  return average_current;
576 }
577 
579  FAS_ASSERT(pPackValues != NULL_PTR);
580 
581  /* Only update system state if current value is valid */
582  if (pPackValues->invalidPackCurrent == 0u) {
583  if (POSITIVE_DISCHARGE_CURRENT == true) {
584  /* Positive current values equal a discharge of the battery system */
585  if (pPackValues->packCurrent_mA >= BS_REST_CURRENT_mA) { /* TODO: string use pack current */
588  } else if (pPackValues->packCurrent_mA <= -BS_REST_CURRENT_mA) {
591  } else {
592  /* Current below rest current: either battery system is at rest
593  * or the relaxation process is still ongoing */
594  if (bms_state.restTimer_10ms == 0u) {
595  /* Rest timer elapsed -> battery system at rest */
597  } else {
600  }
601  }
602  } else {
603  /* Negative current values equal a discharge of the battery system */
604  if (pPackValues->packCurrent_mA <= -BS_REST_CURRENT_mA) {
607  } else if (pPackValues->packCurrent_mA >= BS_REST_CURRENT_mA) {
610  } else {
611  /* Current below rest current: either battery system is at rest
612  * or the relaxation process is still ongoing */
613  if (bms_state.restTimer_10ms == 0u) {
614  /* Rest timer elapsed -> battery system at rest */
616  } else {
619  }
620  }
621  }
622  }
623 }
624 
625 /*========== Extern Function Implementations ================================*/
626 
628  return bms_state.initFinished;
629 }
630 
632  return bms_state.state;
633 }
634 
636  BMS_RETURN_TYPE_e retVal = BMS_OK;
637 
639  retVal = BMS_CheckStateRequest(statereq);
640 
641  if (retVal == BMS_OK) {
642  bms_state.stateRequest = statereq;
643  }
645 
646  return retVal;
647 }
648 
649 void BMS_Trigger(void) {
652  uint32_t timestamp = OS_GetTickCount();
653  static uint32_t nextOpenWireCheck = 0;
654  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
655  static uint8_t stringNumber = 0u;
656  static uint8_t nextStringNumber = 0u;
658  STD_RETURN_TYPE_e contRetVal = STD_NOT_OK;
659 
669  }
670  /* Check re-entrance of function */
671  if (BMS_CheckReEntrance() > 0u) {
672  return;
673  }
674 
675  if (bms_state.nextstringclosedtimer > 0u) {
677  }
678  if (bms_state.stringOpenTimeout > 0u) {
680  }
681 
682  if (bms_state.stringCloseTimeout > 0u) {
684  }
685 
686  if (bms_state.OscillationTimeout > 0u) {
688  }
689 
690  if (bms_state.timer > 0u) {
691  if ((--bms_state.timer) > 0u) {
693  return; /* handle state machine only if timer has elapsed */
694  }
695  }
696 
697  /****Happens every time the state machine is triggered**************/
698  switch (bms_state.state) {
699  /****************************UNINITIALIZED****************************/
701  /* waiting for Initialization Request */
702  statereq = BMS_TransferStateRequest();
703  if (statereq == BMS_STATE_INIT_REQUEST) {
708  } else if (statereq == BMS_STATE_NO_REQUEST) {
709  /* no actual request pending */
710  } else {
711  bms_state.ErrRequestCounter++; /* illegal request pending */
712  }
713  break;
714 
715  /****************************INITIALIZATION***************************/
722  break;
723 
724  /****************************INITIALIZED******************************/
728  /* Initialization of IMD device not finished yet -> wait until this is finished before moving on */
730  } else {
734  }
735  break;
736 
737  /****************************IDLE*************************************/
738  case BMS_STATEMACH_IDLE:
740 
741  if (bms_state.substate == BMS_ENTRY) {
742  DATA_READ_DATA(&systemstate);
743  systemstate.bmsCanState = BMS_CANSTATE_IDLE;
744  DATA_WRITE_DATA(&systemstate);
747  break;
748  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
754  break;
755  } else {
758  break;
759  }
766  break;
767  } else {
770  break;
771  }
772  }
773  break;
774 
775  /****************************OPEN CONTACTORS**************************/
778 
779  if (bms_state.substate == BMS_ENTRY) {
783  break;
785  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
789  }
790  }
791  /* Now go to string opening */
792  stringNumber = BS_NR_OF_STRINGS - 1u; /* Select last string */
795  } else if (bms_state.substate == BMS_OPEN_STRINGS) {
796  CONT_OpenString(stringNumber);
800  break;
801  } else if (bms_state.substate == BMS_CHECK_STRING_OPEN) {
802  contstate = CONT_GetState(stringNumber);
803  if (contstate == CONT_SWITCH_OFF) {
804  if (bms_state.numberOfClosedStrings > 0u) {
806  }
807  bms_state.closedStrings[stringNumber] = 0u;
808  if (stringNumber > 0u) {
809  stringNumber--;
812  break;
813  } else {
816  }
817  break;
818  } else if (bms_state.stringOpenTimeout == 0u) {
819  /* String takes too long to close, go to next string */
822  break;
823  } else {
824  /* String not opened, re-issue closing request */
825  CONT_OpenString(nextStringNumber);
827  break;
828  }
829  } else if (bms_state.substate == BMS_OPEN_STRINGS_EXIT) {
834  break;
835  } else {
839  }
840  } else {
842  }
843  break;
844 
845  /****************************STANDBY**********************************/
848  if (bms_state.substate == BMS_ENTRY) {
850 #if BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE
851  nextOpenWireCheck = timestamp + BS_STANDBY_OPEN_WIRE_PERIOD_ms;
852 #endif /* BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE */
855  DATA_READ_DATA(&systemstate);
856  systemstate.bmsCanState = BMS_CANSTATE_STANDBY;
857  DATA_WRITE_DATA(&systemstate);
858  break;
865  break;
866  } else {
869  break;
870  }
871  } else if (bms_state.substate == BMS_INTERLOCK_CHECKED) {
874  break;
875  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
881  break;
882  } else {
885  break;
886  }
894  break;
895  }
902  break;
903  } else {
904 #if BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE
905  if (nextOpenWireCheck <= timestamp) {
907  nextOpenWireCheck = timestamp + BS_STANDBY_OPEN_WIRE_PERIOD_ms;
908  }
909 #endif /* BS_STANDBY_PERIODIC_OPEN_WIRE_CHECK == TRUE */
912  break;
913  }
914  } else {
916  }
917  break;
918 
919  /****************************PRECHARGE********************************/
922 
923  if (bms_state.substate == BMS_ENTRY) {
924  DATA_READ_DATA(&systemstate);
925  systemstate.bmsCanState = BMS_CANSTATE_PRECHARGE;
926  DATA_WRITE_DATA(&systemstate);
929  } else {
931  }
932  if (stringNumber == BMS_NO_STRING_AVAILABLE) {
937  break;
938  }
939  bms_state.firstClosedString = stringNumber;
940  if (bms_state.OscillationTimeout == 0u) {
943  } else if (BMS_IsBatterySystemStateOkay() == STD_NOT_OK) {
944  /* If precharge re-enter timeout not elapsed, wait (and check errors while waiting) */
949  break;
950  }
951  break;
955  bms_state.closedPrechargeContactors[stringNumber] = 1u;
956  if (contRetVal == STD_OK) {
960  } else {
965  }
966  break;
973  break;
974  } else {
977  break;
978  }
985  break;
986  } else {
989  }
992  if (retVal == STD_OK) {
996  break;
997  } else {
1000  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1001  if (contRetVal == STD_OK) {
1005  } else {
1010  }
1011  break;
1012  } else {
1014  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1019  break;
1020  }
1021  }
1029  if (contstate == CONT_SWITCH_ON) {
1034  break;
1035  } else if (bms_state.stringCloseTimeout == 0u) {
1036  /* String takes too long to close */
1041  break;
1042  } else {
1043  /* String not closed, re-issue closing request */
1047  break;
1048  }
1055  break;
1056  } else {
1059  break;
1060  }
1062  /* Always make one error check after the first string was closed successfully */
1068  break;
1069  } else {
1072  break;
1073  }
1076  if (contRetVal == STD_OK) {
1077  bms_state.closedPrechargeContactors[stringNumber] = 0u;
1081  } else {
1086  }
1087  break;
1088  } else {
1090  }
1091  break;
1092 
1093  /****************************NORMAL**************************************/
1094  case BMS_STATEMACH_NORMAL:
1096 
1097  if (bms_state.substate == BMS_ENTRY) {
1098 #if BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE
1099  nextOpenWireCheck = timestamp + BS_NORMAL_OPEN_WIRE_PERIOD_ms;
1100 #endif /* BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE */
1101  DATA_READ_DATA(&systemstate);
1103  systemstate.bmsCanState = BMS_CANSTATE_CHARGE;
1104  } else {
1105  systemstate.bmsCanState = BMS_CANSTATE_NORMAL;
1106  }
1107  DATA_WRITE_DATA(&systemstate);
1111  break;
1112  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
1117  break;
1118  } else {
1121  break;
1122  }
1129  break;
1130  } else {
1131 #if BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE
1132  if (nextOpenWireCheck <= timestamp) {
1134  nextOpenWireCheck = timestamp + BS_NORMAL_OPEN_WIRE_PERIOD_ms;
1135  }
1136 #endif /* BS_NORMAL_PERIODIC_OPEN_WIRE_CHECK == TRUE */
1139  break;
1140  }
1142  if (bms_state.nextstringclosedtimer == 0u) {
1143  nextStringNumber =
1145  if (nextStringNumber == BMS_NO_STRING_AVAILABLE) {
1148  break;
1149  } else if (
1150  (BMS_GetStringVoltageDifference(nextStringNumber, &bms_tablePackValues) <=
1153  /* Voltage/current conditions suitable to close a further string */
1154  CONT_CloseString(nextStringNumber);
1158  break;
1159  }
1160  } else {
1163  break;
1164  }
1165  } else if (bms_state.substate == BMS_CHECK_STRING_CLOSED) {
1166  contstate = CONT_GetState(nextStringNumber);
1167  if (contstate == CONT_SWITCH_ON) {
1169  bms_state.closedStrings[nextStringNumber] = 1u;
1171  /* Go to begin of NORMAL case to redo the full procedure with error check and request check */
1173  break;
1174  } else if (bms_state.stringCloseTimeout == 0u) {
1175  /* String takes too long to close */
1180  break;
1181  } else if (BMS_IsBatterySystemStateOkay() == STD_NOT_OK) {
1186  break;
1187  } else if (BMS_CheckCanRequests() == BMS_REQ_ID_STANDBY) {
1192  break;
1193  } else {
1194  /* String not closed, re-issue closing request */
1195  CONT_CloseString(nextStringNumber);
1197  break;
1198  }
1199  } else {
1201  }
1202  break;
1203 
1204  /****************************ERROR*************************************/
1205  case BMS_STATEMACH_ERROR:
1207 
1208  if (bms_state.substate == BMS_ENTRY) {
1209  /* Set BMS System state to error */
1210  DATA_READ_DATA(&systemstate);
1211  systemstate.bmsCanState = BMS_CANSTATE_ERROR;
1212  DATA_WRITE_DATA(&systemstate);
1213  /* Deactivate balancing */
1215  /* Change LED toggle frequency to indicate an error */
1217  /* Set timer for next open wire check */
1218  nextOpenWireCheck = timestamp + AFE_ERROR_OPEN_WIRE_PERIOD_ms;
1219  /* Switch to next substate */
1222  break;
1223  } else if (bms_state.substate == BMS_CHECK_ERROR_FLAGS) {
1224  if (DIAG_IsAnyFatalErrorSet() == true) {
1225  /* we stay already in requested state */
1226  if (nextOpenWireCheck <= timestamp) {
1227  /* Perform open-wire check periodically */
1228  /* MEAS_RequestOpenWireCheck(); */ /*TODO: check with strings */
1229  nextOpenWireCheck = timestamp + AFE_ERROR_OPEN_WIRE_PERIOD_ms;
1230  }
1231  } else {
1232  /* No error detected anymore - reset fatal error related variables */
1236  /* Check for STANDBY request */
1239  break;
1240  }
1243  /* Activate balancing again */
1245  /* Set LED frequency to normal operation as we leave error
1246  state subsequently */
1248 
1249  /* Verify that all contactors are opened and switch to
1250  * STANDBY state afterwards */
1254  break;
1255  } else {
1258  break;
1259  }
1260  } else {
1261  /* invalid state -> this should never be reached */
1263  }
1264  break;
1265  default:
1266  /* invalid state */
1268  break;
1269  } /* end switch (bms_state.state) */
1270 
1272  bms_state.counter++;
1273 }
1274 
1276  return bms_state.currentFlowState;
1277 }
1278 
1280  /* AXIVION Routine Generic-MissingParameterAssert: current_mA: parameter accepts whole range */
1282 
1283  if (POSITIVE_DISCHARGE_CURRENT == true) {
1284  if (current_mA >= BS_REST_CURRENT_mA) {
1285  retVal = BMS_DISCHARGING;
1286  } else if (current_mA <= -BS_REST_CURRENT_mA) {
1287  retVal = BMS_CHARGING;
1288  } else {
1289  retVal = BMS_AT_REST;
1290  }
1291  } else {
1292  if (current_mA <= -BS_REST_CURRENT_mA) {
1293  retVal = BMS_DISCHARGING;
1294  } else if (current_mA >= BS_REST_CURRENT_mA) {
1295  retVal = BMS_CHARGING;
1296  } else {
1297  retVal = BMS_AT_REST;
1298  }
1299  }
1300  return retVal;
1301 }
1302 
1303 extern bool BMS_IsStringClosed(uint8_t stringNumber) {
1304  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
1305  bool retval = false;
1306  if (bms_state.closedStrings[stringNumber] == 1u) {
1307  retval = true;
1308  }
1309  return retval;
1310 }
1311 
1312 extern bool BMS_IsStringPrecharging(uint8_t stringNumber) {
1313  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
1314  bool retval = false;
1315  if (bms_state.closedPrechargeContactors[stringNumber] == 1u) {
1316  retval = true;
1317  }
1318  return retval;
1319 }
1320 
1321 extern uint8_t BMS_GetNumberOfConnectedStrings(void) {
1323 }
1324 
1327 }
1328 
1329 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1330 #ifdef UNITY_UNIT_TEST
1331 extern BMS_RETURN_TYPE_e TEST_BMS_CheckStateRequest(BMS_STATE_REQUEST_e statereq) {
1332  return BMS_CheckStateRequest(statereq);
1333 }
1334 extern BMS_STATE_REQUEST_e TEST_BMS_TransferStateRequest(void) {
1335  return BMS_TransferStateRequest();
1336 }
1337 extern uint8_t TEST_BMS_CheckReEntrance(void) {
1338  return BMS_CheckReEntrance();
1339 }
1340 extern uint8_t TEST_BMS_CheckCanRequests(void) {
1341  return BMS_CheckCanRequests();
1342 }
1343 extern bool TEST_BMS_IsAnyFatalErrorFlagSet(void) {
1344  return BMS_IsAnyFatalErrorFlagSet();
1345 }
1346 extern STD_RETURN_TYPE_e TEST_BMS_IsBatterySystemStateOkay(void) {
1348 }
1349 extern void TEST_BMS_GetMeasurementValues(void) {
1351 }
1352 extern void TEST_BMS_CheckOpenSenseWire(void) {
1354 }
1355 extern STD_RETURN_TYPE_e TEST_BMS_CheckPrecharge(uint8_t stringNumber, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1356  return BMS_CheckPrecharge(stringNumber, pPackValues);
1357 }
1358 extern uint8_t TEST_BMS_GetHighestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1359  return BMS_GetHighestString(precharge, pPackValues);
1360 }
1361 extern uint8_t TEST_BMS_GetClosestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1362  return BMS_GetClosestString(precharge, pPackValues);
1363 }
1364 
1365 extern uint8_t TEST_BMS_GetLowestString(BMS_CONSIDER_PRECHARGE_e precharge, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1366  return BMS_GetLowestString(precharge, pPackValues);
1367 }
1368 extern int32_t TEST_BMS_GetStringVoltageDifference(uint8_t string, DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1369  return BMS_GetStringVoltageDifference(string, pPackValues);
1370 }
1371 extern int32_t TEST_BMS_GetAverageStringCurrent(DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1372  return BMS_GetAverageStringCurrent(pPackValues);
1373 }
1374 extern void TEST_BMS_UpdateBatsysState(DATA_BLOCK_PACK_VALUES_s *pPackValues) {
1375  BMS_UpdateBatsysState(pPackValues);
1376 }
1377 
1378 #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:366
#define BMS_SAVELASTSTATES()
Definition: bms.c:78
static DATA_BLOCK_MIN_MAX_s bms_tableMinMax
Definition: bms.c:119
bool BMS_IsStringPrecharging(uint8_t stringNumber)
Returns if string is currently precharging or not.
Definition: bms.c:1312
bool BMS_IsTransitionToErrorStateActive(void)
Check if transition in to error state is active.
Definition: bms.c:1325
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:635
static bool BMS_IsAnyFatalErrorFlagSet(void)
Checks all the error flags from diagnosis module with a severity of DIAG_FATAL_ERROR.
Definition: bms.c:392
static BMS_RETURN_TYPE_e BMS_CheckStateRequest(BMS_STATE_REQUEST_e statereq)
checks the state requests that are made.
Definition: bms.c:273
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:578
#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:569
void BMS_Trigger(void)
trigger function for the SYS driver state machine.
Definition: bms.c:649
uint8_t BMS_GetNumberOfConnectedStrings(void)
Returns number of connected strings.
Definition: bms.c:1321
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1303
static void BMS_CheckOpenSenseWire(void)
Check for any open voltage sense wire.
Definition: bms.c:341
BMS_CURRENT_FLOW_STATE_e BMS_GetCurrentFlowDirection(int32_t current_mA)
Get current flow direction, current value as function parameter.
Definition: bms.c:1279
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:549
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:525
BMS_CURRENT_FLOW_STATE_e BMS_GetBatterySystemState(void)
Returns current battery system state (charging/discharging, resting or in relaxation phase)
Definition: bms.c:1275
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:454
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
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:411
STD_RETURN_TYPE_e BMS_GetInitializationState(void)
Gets the initialization state.
Definition: bms.c:627
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:631
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:479
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:371
STD_RETURN_TYPE_e DIAG_GetDiagnosisEntryState(DIAG_ID_e diagnosisEntry)
Checks if passed diagnosis entry has been triggered or not.
Definition: diag.c:177
bool DIAG_IsAnyFatalErrorSet(void)
Check if any fatal error is set.
Definition: diag.c:376
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diagId, 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:231
Diagnosis driver header.
DIAG_DEV_s diag_device
Definition: diag_cfg.c:224
@ 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:252
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:126
int32_t MATH_AbsInt32_t(const int32_t value)
Returns the absolute value of passed int32_t value.
Definition: foxmath.c:154
int64_t MATH_AbsInt64_t(const int64_t value)
Returns the absolute value of passed int64_t value.
Definition: foxmath.c:162
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:513
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:350
void SOA_CheckCurrent(DATA_BLOCK_PACK_VALUES_s *pTablePackValues)
checks the abidance by the safe operating area
Definition: soa.c:268
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