foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
sof_trapezoid.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file sof_trapezoid.c
44  * @author foxBMS Team
45  * @date 2020-10-07 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup APPLICATION_CONFIGURATION
49  * @prefix SOF
50  *
51  * @brief SOF modules responsible for current derating calculation
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "sof_trapezoid.h"
57 
58 #include "battery_cell_cfg.h"
59 #include "battery_system_cfg.h"
60 
61 #include "bms.h"
62 #include "database.h"
63 #include "foxmath.h"
64 #include "state_estimation.h"
65 
66 #include <float.h>
67 #include <math.h>
68 #include <stdbool.h>
69 #include <stdint.h>
70 
71 /*========== Macros and Definitions =========================================*/
72 
73 /*========== Static Constant and Variable Definitions =======================*/
74 /** @{
75  * module-local static variable that is calculated at startup and used later to avoid divisions at runtime
76  */
78 /** @} */
79 
80 /** local copies of database tables */
81 /**@{*/
84 /**@}*/
85 
86 /*========== Extern Constant and Variable Definitions =======================*/
87 
88 /*========== Static Function Prototypes =====================================*/
89 
90 /**
91  * @brief calculate SOF curve depending on configured configuration values
92  *
93  * @param[in] pConfigurationValues SOF curve configuration values
94  * @param[out] pCalculatedSofCurveValues calculate SOF curve
95  */
96 static void SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues);
97 
98 /**
99  * @brief calculates the SoF from voltage data (i.e., minimum and maximum voltage)
100  *
101  * @param[in] minimumCellVoltage_mV minimum cell voltage
102  * @param[in] maximumCellVoltage_mV maximum cell voltage
103  * @param[out] pAllowedVoltageBasedCurrent Voltage-based SOF
104  * @param[in] pConfigLimitValues pointer to the SOF configuration structure
105  * @param[in] pCalculatedSofCurves pointer to the SOF curve structure
106  */
108  int16_t minimumCellVoltage_mV,
109  int16_t maximumCellVoltage_mV,
110  SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent,
111  const SOF_CONFIG_s *pConfigLimitValues,
112  SOF_CURVE_s *pCalculatedSofCurves);
113 
114 /**
115  * @brief calculates the SoF from temperature data (i.e., minimum and maximum temperature of cells)
116  *
117  * @param[in] minimumCellTemperature_ddegC minimum temperature of cells
118  * @param[in] maximumCellTemperature_ddegC maximum temperature of cells
119  * @param[out] pAllowedTemperatureBasedCurrent pointer where to store the results
120  * @param[in] pConfigLimitValues pointer to the structure used for SOF calculation
121  * @param[in] pCalculatedSofCurves pointer to the structure containing limit values
122  */
124  int16_t minimumCellTemperature_ddegC,
125  int16_t maximumCellTemperature_ddegC,
126  SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent,
127  const SOF_CONFIG_s *pConfigLimitValues,
128  SOF_CURVE_s *pCalculatedSofCurves);
129 
130 /**
131  * @brief get the minimum current values of all variants of SoF calculation
132  *
133  * @param[in] voltageBasedLimits voltage constrained current derating values
134  * @param[in] temperatureBasedLimits temperature constrained current derating values
135  *
136  * @return minimum SoF current values
137  */
139  SOF_CURRENT_LIMITS_s voltageBasedLimits,
140  SOF_CURRENT_LIMITS_s temperatureBasedLimits);
141 
142 /*========== Static Function Implementations ================================*/
143 static void SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues) {
144  FAS_ASSERT(pConfigurationValues != NULL_PTR);
145  FAS_ASSERT(pCalculatedSofCurveValues != NULL_PTR);
146 
147  /* Calculating SOF curve for the maximum allowed current for MOL/RSL/MSL */
148  pCalculatedSofCurveValues->slopeLowTemperatureDischarge =
149  (pConfigurationValues->maximumDischargeCurrent_mA - pConfigurationValues->limpHomeCurrent_mA) /
150  (pConfigurationValues->cutoffLowTemperatureDischarge_ddegC -
151  pConfigurationValues->limitLowTemperatureDischarge_ddegC);
152  pCalculatedSofCurveValues->offsetLowTemperatureDischarge =
153  pConfigurationValues->limpHomeCurrent_mA - (pCalculatedSofCurveValues->slopeLowTemperatureDischarge *
154  pConfigurationValues->limitLowTemperatureDischarge_ddegC);
155 
156  pCalculatedSofCurveValues->slopeHighTemperatureDischarge =
157  (0.0f - pConfigurationValues->maximumDischargeCurrent_mA) /
158  (pConfigurationValues->limitHighTemperatureDischarge_ddegC -
159  pConfigurationValues->cutoffHighTemperatureDischarge_ddegC);
160  pCalculatedSofCurveValues->offsetHighTemperatureDischarge =
161  0.0f - (pCalculatedSofCurveValues->slopeHighTemperatureDischarge *
162  pConfigurationValues->limitHighTemperatureDischarge_ddegC);
163 
164  pCalculatedSofCurveValues->slopeLowTemperatureCharge = (pConfigurationValues->maximumChargeCurrent_mA - 0.0f) /
165  (pConfigurationValues->cutoffLowTemperatureCharge_ddegC -
166  pConfigurationValues->limitLowTemperatureCharge_ddegC);
167  pCalculatedSofCurveValues->offsetLowTemperatureCharge =
168  0.0f -
169  (pCalculatedSofCurveValues->slopeLowTemperatureCharge * pConfigurationValues->limitLowTemperatureCharge_ddegC);
170 
171  pCalculatedSofCurveValues->slopeHighTemperatureCharge = (0.0f - pConfigurationValues->maximumChargeCurrent_mA) /
172  (pConfigurationValues->limitHighTemperatureCharge_ddegC -
173  pConfigurationValues->cutoffHighTemperatureCharge_ddegC);
174  pCalculatedSofCurveValues->offsetHighTemperatureCharge = 0.0f -
175  (pCalculatedSofCurveValues->slopeHighTemperatureCharge *
176  pConfigurationValues->limitHighTemperatureCharge_ddegC);
177 
178  pCalculatedSofCurveValues->slopeUpperCellVoltage =
179  (pConfigurationValues->maximumDischargeCurrent_mA - 0.0f) /
180  (pConfigurationValues->cutoffLowerCellVoltage_mV - pConfigurationValues->limitLowerCellVoltage_mV);
181  pCalculatedSofCurveValues->offsetUpperCellVoltage =
182  0.0f - (pCalculatedSofCurveValues->slopeUpperCellVoltage * pConfigurationValues->limitLowerCellVoltage_mV);
183 
184  pCalculatedSofCurveValues->slopeLowerCellVoltage =
185  (pConfigurationValues->maximumChargeCurrent_mA - 0.0f) /
186  (pConfigurationValues->cutoffUpperCellVoltage_mV - pConfigurationValues->limitUpperCellVoltage_mV);
187  pCalculatedSofCurveValues->offsetLowerCellVoltage =
188  0.0f - (pCalculatedSofCurveValues->slopeLowerCellVoltage * pConfigurationValues->limitLowerCellVoltage_mV);
189 }
190 
192  int16_t minimumCellVoltage_mV,
193  int16_t maximumCellVoltage_mV,
194  SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent,
195  const SOF_CONFIG_s *pConfigLimitValues,
196  SOF_CURVE_s *pCalculatedSofCurves) {
197  FAS_ASSERT(pAllowedVoltageBasedCurrent != NULL_PTR);
198  FAS_ASSERT(pConfigLimitValues != NULL_PTR);
199  FAS_ASSERT(pCalculatedSofCurves != NULL_PTR);
200  /* AXIVION Routine Generic-MissingParameterAssert: minimumCellVoltage_mV: parameter accept whole range */
201  /* AXIVION Routine Generic-MissingParameterAssert: maximumCellVoltage_mV: parameter accept whole range */
202 
203  /* minimum cell voltage calculation */
204  if (minimumCellVoltage_mV <= pConfigLimitValues->limitLowerCellVoltage_mV) {
205  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA = 0.0f;
206  pAllowedVoltageBasedCurrent->peakDischargeCurrent_mA = 0.0f;
207  } else {
208  if (minimumCellVoltage_mV <= pConfigLimitValues->cutoffLowerCellVoltage_mV) {
209  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA =
210  (pCalculatedSofCurves->slopeUpperCellVoltage *
211  (minimumCellVoltage_mV - pConfigLimitValues->limitLowerCellVoltage_mV));
212  pAllowedVoltageBasedCurrent->peakDischargeCurrent_mA =
213  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA;
214  } else {
215  pAllowedVoltageBasedCurrent->continuousDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
216  pAllowedVoltageBasedCurrent->peakDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
217  }
218  }
219  /* maximum cell voltage calculation */
220  if (maximumCellVoltage_mV >= pConfigLimitValues->limitUpperCellVoltage_mV) {
221  pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA = 0.0f;
222  pAllowedVoltageBasedCurrent->peakChargeCurrent_mA = 0.0f;
223  } else {
224  if (maximumCellVoltage_mV >= pConfigLimitValues->cutoffUpperCellVoltage_mV) {
225  pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA =
226  (pCalculatedSofCurves->slopeLowerCellVoltage *
227  (maximumCellVoltage_mV - pConfigLimitValues->limitUpperCellVoltage_mV));
228  pAllowedVoltageBasedCurrent->peakChargeCurrent_mA = pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA;
229  } else {
230  pAllowedVoltageBasedCurrent->continuousChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
231  pAllowedVoltageBasedCurrent->peakChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
232  }
233  }
234 }
235 
237  int16_t minimumCellTemperature_ddegC,
238  int16_t maximumCellTemperature_ddegC,
239  SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent,
240  const SOF_CONFIG_s *pConfigLimitValues,
241  SOF_CURVE_s *pCalculatedSofCurves) {
242  FAS_ASSERT(pAllowedTemperatureBasedCurrent != NULL_PTR);
243  FAS_ASSERT(pConfigLimitValues != NULL_PTR);
244  FAS_ASSERT(pCalculatedSofCurves != NULL_PTR);
245  /* AXIVION Routine Generic-MissingParameterAssert: minimumCellTemperature_ddegC: parameter accepts whole range */
246  /* AXIVION Routine Generic-MissingParameterAssert: maximumCellTemperature_ddegC: parameter accepts whole range */
247 
248  SOF_CURRENT_LIMITS_s temporaryCurrentLimits = {0.0f, 0.0f, 0.0f, 0.0f};
249  /* Temperature low Discharge */
250  if (minimumCellTemperature_ddegC <= pConfigLimitValues->limitLowTemperatureDischarge_ddegC) {
251  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA = pConfigLimitValues->limpHomeCurrent_mA;
252  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = pConfigLimitValues->limpHomeCurrent_mA;
253  } else {
254  if (minimumCellTemperature_ddegC <= pConfigLimitValues->cutoffLowTemperatureDischarge_ddegC) {
255  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA =
256  (pCalculatedSofCurves->slopeLowTemperatureDischarge * minimumCellTemperature_ddegC) +
257  pCalculatedSofCurves->offsetLowTemperatureDischarge;
258  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA =
259  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA;
260  } else {
261  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA =
262  pConfigLimitValues->maximumDischargeCurrent_mA;
263  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
264  }
265  }
266  /* Temperature low charge */
267  if (minimumCellTemperature_ddegC <= pConfigLimitValues->limitLowTemperatureCharge_ddegC) {
268  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = 0;
269  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = 0;
270  } else {
271  if (minimumCellTemperature_ddegC <= pConfigLimitValues->cutoffLowTemperatureCharge_ddegC) {
272  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA =
273  (pCalculatedSofCurves->slopeLowTemperatureCharge * minimumCellTemperature_ddegC) +
274  pCalculatedSofCurves->offsetLowTemperatureCharge;
275  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA =
276  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA;
277  } else {
278  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
279  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
280  }
281  }
282  /* Temperature high discharge */
283  if (maximumCellTemperature_ddegC >= pConfigLimitValues->limitHighTemperatureDischarge_ddegC) {
284  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA = 0.0f;
285  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = 0.0f;
286  } else {
287  if (maximumCellTemperature_ddegC >= pConfigLimitValues->cutoffHighTemperatureDischarge_ddegC) {
288  temporaryCurrentLimits.continuousDischargeCurrent_mA =
289  (pCalculatedSofCurves->slopeHighTemperatureDischarge * maximumCellTemperature_ddegC) +
290  pCalculatedSofCurves->offsetHighTemperatureDischarge;
291  temporaryCurrentLimits.peakDischargeCurrent_mA = temporaryCurrentLimits.continuousDischargeCurrent_mA;
292  } else {
293  /* do nothing because this situation is handled with minimumCellTemperature_ddegC */
294  temporaryCurrentLimits.continuousDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
295  temporaryCurrentLimits.peakDischargeCurrent_mA = pConfigLimitValues->maximumDischargeCurrent_mA;
296  }
297  /* Derating value for minimum cell temperature has already been calculated and result is saved in
298  pAllowedTemperatureBasedCurrentCheck. Check now if newly calculated derating value for maximum
299  cell temperatures is smaller than the previously calculated value */
300  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA = MATH_MinimumOfTwoFloats(
301  pAllowedTemperatureBasedCurrent->continuousDischargeCurrent_mA,
302  temporaryCurrentLimits.continuousDischargeCurrent_mA);
303  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA = MATH_MinimumOfTwoFloats(
304  pAllowedTemperatureBasedCurrent->peakDischargeCurrent_mA, temporaryCurrentLimits.peakDischargeCurrent_mA);
305  }
306  /* Temperature high Charge */
307  if (maximumCellTemperature_ddegC >= pConfigLimitValues->limitHighTemperatureCharge_ddegC) {
308  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = 0.0f;
309  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = 0.0f;
310  } else {
311  if (maximumCellTemperature_ddegC >= pConfigLimitValues->cutoffHighTemperatureCharge_ddegC) {
312  temporaryCurrentLimits.continuousChargeCurrent_mA =
313  (pCalculatedSofCurves->slopeHighTemperatureCharge * maximumCellTemperature_ddegC) +
314  pCalculatedSofCurves->offsetHighTemperatureCharge;
315  temporaryCurrentLimits.peakChargeCurrent_mA = temporaryCurrentLimits.continuousChargeCurrent_mA;
316  } else {
317  /* do nothing because this situation is handled with minimumCellTemperature_ddegC */
318  temporaryCurrentLimits.continuousChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
319  temporaryCurrentLimits.peakChargeCurrent_mA = pConfigLimitValues->maximumChargeCurrent_mA;
320  }
321  /* Derating value for minimum cell temperature has already been calculated and result is saved in
322  pAllowedTemperatureBasedCurrentCheck. Check now if newly calculated derating value for maximum
323  cell temperatures is smaller than the previously calculated value */
324  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA = MATH_MinimumOfTwoFloats(
325  pAllowedTemperatureBasedCurrent->continuousChargeCurrent_mA,
326  temporaryCurrentLimits.continuousChargeCurrent_mA);
327  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA = MATH_MinimumOfTwoFloats(
328  pAllowedTemperatureBasedCurrent->peakChargeCurrent_mA, temporaryCurrentLimits.peakChargeCurrent_mA);
329  }
330 }
331 
333  SOF_CURRENT_LIMITS_s voltageBasedLimits,
334  SOF_CURRENT_LIMITS_s temperatureBasedLimits) {
335  /* AXIVION Routine Generic-MissingParameterAssert: voltageBasedLimits: parameter accepts whole range */
336  /* AXIVION Routine Generic-MissingParameterAssert: temperatureBasedLimits: parameter accepts whole range */
337  SOF_CURRENT_LIMITS_s retval = {0};
339  voltageBasedLimits.continuousChargeCurrent_mA, temperatureBasedLimits.continuousChargeCurrent_mA);
340  retval.peakChargeCurrent_mA =
341  MATH_MinimumOfTwoFloats(voltageBasedLimits.peakChargeCurrent_mA, temperatureBasedLimits.peakChargeCurrent_mA);
343  voltageBasedLimits.continuousDischargeCurrent_mA, temperatureBasedLimits.continuousDischargeCurrent_mA);
345  voltageBasedLimits.peakDischargeCurrent_mA, temperatureBasedLimits.peakDischargeCurrent_mA);
346  return retval;
347 }
348 
349 /*========== Extern Function Implementations ================================*/
350 extern void SOF_Init(void) {
351  /* Calculating SOF curve for the recommended operating current */
353 }
354 
355 extern void SOF_Calculation(void) {
356  SOF_CURRENT_LIMITS_s allowedCurrent = {0};
357 
359 
360  /* Reset allowed current values */
365 
366  uint8_t nrClosedStrings = 0;
367  float_t minDischarge_mA = FLT_MAX;
368  float_t minCharge_mA = FLT_MAX;
369 
370  for (uint8_t s = 0u; s < BS_NR_OF_STRINGS; s++) {
371  SOF_CURRENT_LIMITS_s voltageBasedSof = {0};
372  SOF_CURRENT_LIMITS_s temperatureBasedSof = {0};
373  /* Calculate allowed current if string is connected */
374  if (BMS_IsStringClosed(s) == true) {
378  &voltageBasedSof,
384  &temperatureBasedSof,
387  allowedCurrent = SOF_MinimumOfTwoSofValues(voltageBasedSof, temperatureBasedSof);
388 
391  allowedCurrent.continuousDischargeCurrent_mA;
394 
395  nrClosedStrings++;
398  }
401  }
402  } else {
407  }
408  }
409 
410  if (minCharge_mA > (float_t)BS_MAXIMUM_STRING_CURRENT_mA) {
411  minCharge_mA = (float_t)BS_MAXIMUM_STRING_CURRENT_mA;
412  }
413  if (minDischarge_mA > (float_t)BS_MAXIMUM_STRING_CURRENT_mA) {
414  minDischarge_mA = (float_t)BS_MAXIMUM_STRING_CURRENT_mA;
415  }
416 
417  /* Compute recommended pack values */
418  sof_tableSofValues.recommendedContinuousPackChargeCurrent_mA = (float_t)nrClosedStrings * minCharge_mA;
419  sof_tableSofValues.recommendedContinuousPackDischargeCurrent_mA = (float_t)nrClosedStrings * minDischarge_mA;
420  sof_tableSofValues.recommendedPeakPackChargeCurrent_mA = (float_t)nrClosedStrings * minCharge_mA;
421  sof_tableSofValues.recommendedPeakPackDischargeCurrent_mA = (float_t)nrClosedStrings * minDischarge_mA;
422 
423  /* Check if currently a transition into ERROR state in the BMS state
424  * machine is ongoing. Set allowed current to 0 if this is the case.
425  */
426  if (BMS_IsTransitionToErrorStateActive() == true) {
431  }
432 
434 }
435 
436 /*========== Externalized Static Function Implementations (Unit Test) =======*/
437 #ifdef UNITY_UNIT_TEST
438 extern void TEST_SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues) {
439  SOF_CalculateCurves(pConfigurationValues, pCalculatedSofCurveValues);
440 }
441 extern void TEST_SOF_CalculateVoltageBasedCurrentLimit(
442  int16_t minimumCellVoltage_mV,
443  int16_t maximumCellVoltage_mV,
444  SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent,
445  const SOF_CONFIG_s *pConfigLimitValues,
446  SOF_CURVE_s *pCalculatedSofCurves) {
448  minimumCellVoltage_mV,
449  maximumCellVoltage_mV,
450  pAllowedVoltageBasedCurrent,
451  pConfigLimitValues,
452  pCalculatedSofCurves);
453 }
454 extern void TEST_SOF_CalculateTemperatureBasedCurrentLimit(
455  int16_t minimumCellTemperature_ddegC,
456  int16_t maximumCellTemperature_ddegC,
457  SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent,
458  const SOF_CONFIG_s *pConfigLimitValues,
459  SOF_CURVE_s *pCalculatedSofCurves) {
461  minimumCellTemperature_ddegC,
462  maximumCellTemperature_ddegC,
463  pAllowedTemperatureBasedCurrent,
464  pConfigLimitValues,
465  pCalculatedSofCurves);
466 }
467 extern SOF_CURRENT_LIMITS_s TEST_SOF_MinimumOfTwoSofValues(
468  SOF_CURRENT_LIMITS_s voltageBasedLimits,
469  SOF_CURRENT_LIMITS_s temperatureBasedLimits) {
470  return SOF_MinimumOfTwoSofValues(voltageBasedLimits, temperatureBasedLimits);
471 }
472 #endif
Configuration of the battery cell (e.g., minimum and maximum cell voltage)
Configuration of the battery system (e.g., number of battery modules, battery cells,...
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_MAXIMUM_STRING_CURRENT_mA
Maximum string current limit in mA that is used in the SOA module to check for string overcurrent.
bool BMS_IsTransitionToErrorStateActive(void)
Check if transition in to error state is active.
Definition: bms.c:1636
bool BMS_IsStringClosed(uint8_t stringNumber)
Returns string state (closed or open)
Definition: bms.c:1614
bms driver header
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:86
#define DATA_WRITE_DATA(...)
Definition: database.h:96
@ DATA_BLOCK_ID_MIN_MAX
Definition: database_cfg.h:99
@ DATA_BLOCK_ID_SOF
Definition: database_cfg.h:110
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
float_t MATH_MinimumOfTwoFloats(const float_t value1, const float_t value2)
Returns the minimum of the passed float values.
Definition: foxmath.c:132
math library for often used math functions
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
static void SOF_CalculateTemperatureBasedCurrentLimit(int16_t minimumCellTemperature_ddegC, int16_t maximumCellTemperature_ddegC, SOF_CURRENT_LIMITS_s *pAllowedTemperatureBasedCurrent, const SOF_CONFIG_s *pConfigLimitValues, SOF_CURVE_s *pCalculatedSofCurves)
calculates the SoF from temperature data (i.e., minimum and maximum temperature of cells)
void SOF_Calculation(void)
triggers SOF calculation
static DATA_BLOCK_SOF_s sof_tableSofValues
Definition: sof_trapezoid.c:83
static DATA_BLOCK_MIN_MAX_s sof_tableMinimumMaximumValues
Definition: sof_trapezoid.c:82
static void SOF_CalculateVoltageBasedCurrentLimit(int16_t minimumCellVoltage_mV, int16_t maximumCellVoltage_mV, SOF_CURRENT_LIMITS_s *pAllowedVoltageBasedCurrent, const SOF_CONFIG_s *pConfigLimitValues, SOF_CURVE_s *pCalculatedSofCurves)
calculates the SoF from voltage data (i.e., minimum and maximum voltage)
static void SOF_CalculateCurves(const SOF_CONFIG_s *pConfigurationValues, SOF_CURVE_s *pCalculatedSofCurveValues)
calculate SOF curve depending on configured configuration values
static SOF_CURRENT_LIMITS_s SOF_MinimumOfTwoSofValues(SOF_CURRENT_LIMITS_s voltageBasedLimits, SOF_CURRENT_LIMITS_s temperatureBasedLimits)
get the minimum current values of all variants of SoF calculation
static SOF_CURVE_s sof_curveRecommendedOperatingCurrent
Definition: sof_trapezoid.c:77
void SOF_Init(void)
initializes the area for SOF (where derating starts and is fully active).
Header for SOX module, responsible for current derating calculation.
const SOF_CONFIG_s sof_recommendedCurrent
Header for state-estimation module responsible for the estimation of state-of-charge (SOC),...
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:125
int16_t minimumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:180
int16_t maximumTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:183
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:167
int16_t maximumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:172
int16_t minimumCellVoltage_mV[BS_NR_OF_STRINGS]
Definition: database_cfg.h:170
float_t recommendedPeakPackChargeCurrent_mA
Definition: database_cfg.h:431
float_t recommendedPeakChargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:437
float_t recommendedContinuousChargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:434
float_t recommendedContinuousDischargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:436
float_t recommendedContinuousPackChargeCurrent_mA
Definition: database_cfg.h:428
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:427
float_t recommendedPeakDischargeCurrent_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:438
float_t recommendedContinuousPackDischargeCurrent_mA
Definition: database_cfg.h:430
float_t recommendedPeakPackDischargeCurrent_mA
Definition: database_cfg.h:432
float_t maximumChargeCurrent_mA
float_t limpHomeCurrent_mA
int16_t limitLowTemperatureCharge_ddegC
int16_t limitLowerCellVoltage_mV
int16_t limitUpperCellVoltage_mV
int16_t cutoffHighTemperatureDischarge_ddegC
int16_t cutoffHighTemperatureCharge_ddegC
int16_t limitHighTemperatureCharge_ddegC
int16_t cutoffLowerCellVoltage_mV
float_t maximumDischargeCurrent_mA
int16_t limitHighTemperatureDischarge_ddegC
int16_t limitLowTemperatureDischarge_ddegC
int16_t cutoffLowTemperatureCharge_ddegC
int16_t cutoffLowTemperatureDischarge_ddegC
int16_t cutoffUpperCellVoltage_mV
float_t peakChargeCurrent_mA
Definition: sof_trapezoid.h:71
float_t continuousChargeCurrent_mA
Definition: sof_trapezoid.h:70
float_t continuousDischargeCurrent_mA
Definition: sof_trapezoid.h:72
float_t peakDischargeCurrent_mA
Definition: sof_trapezoid.h:73
float_t offsetHighTemperatureCharge
Definition: sof_trapezoid.h:89
float_t slopeHighTemperatureCharge
Definition: sof_trapezoid.h:88
float_t offsetLowTemperatureCharge
Definition: sof_trapezoid.h:87
float_t offsetLowTemperatureDischarge
Definition: sof_trapezoid.h:82
float_t offsetLowerCellVoltage
Definition: sof_trapezoid.h:94
float_t offsetHighTemperatureDischarge
Definition: sof_trapezoid.h:84
float_t slopeLowTemperatureCharge
Definition: sof_trapezoid.h:86
float_t slopeHighTemperatureDischarge
Definition: sof_trapezoid.h:83
float_t slopeUpperCellVoltage
Definition: sof_trapezoid.h:91
float_t offsetUpperCellVoltage
Definition: sof_trapezoid.h:92
float_t slopeLowTemperatureDischarge
Definition: sof_trapezoid.h:81
float_t slopeLowerCellVoltage
Definition: sof_trapezoid.h:93