foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
mxm_17852.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 mxm_17852.c
44  * @author foxBMS Team
45  * @date 2021-11-24 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix MXM
50  *
51  * @brief Operation state machine implementation for the MAX17852
52  *
53  * @details This file contains that part of the state machine that is executed
54  * during the operation state. It is adapted for MAX17852.
55  *
56  */
57 
58 /*========== Includes =======================================================*/
59 /* clang-format off */
60 #include "mxm_1785x.h"
61 /* clang-format on */
62 
63 #include "database.h"
64 #include "fassert.h"
65 #include "fstd_types.h"
66 #include "mxm_1785x_tools.h"
67 #include "mxm_battery_management.h"
68 #include "mxm_registry.h"
69 #include "os.h"
70 
71 #include <stdbool.h>
72 #include <stdint.h>
73 
74 /*========== Macros and Definitions =========================================*/
75 /** @defgroup MXM_I2C_IMPLEMENTATION symbols and settings pertaining to the I2C implementation in MXM
76  * @{
77  */
78 /** @brief address of MUX0 */
79 #define MXM_I2C_MUX0_ADDRESS (0x4Cu)
80 /** @brief address of MUX1 */
81 #define MXM_I2C_MUX1_ADDRESS (0x4Du)
82 /**@}*/
83 
84 /** @brief Delay in milliseconds before the balancing status is updated */
85 #define MXM_DELAY_BALANCING 10000u
86 
87 /*========== Static Constant and Variable Definitions =======================*/
88 
89 /*========== Extern Constant and Variable Definitions =======================*/
90 
91 /*========== Static Function Prototypes =====================================*/
92 
93 /*========== Static Function Implementations ================================*/
94 
95 /*========== Extern Function Implementations ================================*/
97  return MXM_MODEL_ID_MAX17852;
98 }
99 
101  FAS_ASSERT(pState != NULL_PTR);
102 
103  /**
104  * @brief Mapping of voltage registers
105  *
106  * This array maps registers of the monitoring IC onto cell-numbers. The
107  * register values are defined in the #MXM_REG_NAME_e enum.
108  * For now the length of this array is #MXM_VOLTAGE_READ_ARRAY_LENGTH
109  * as it is enabled for the measurement of all cells, two AUX-voltages and
110  * one block voltage. This has to be adapted once this driver is enabled for
111  * general operation.
112  */
113  const MXM_REG_NAME_e mxm_voltageCellAddresses[MXM_VOLTAGE_READ_ARRAY_LENGTH] = {
128  MXM_REG_AUX2,
129  MXM_REG_AUX3,
131  };
132 
133  pState->operationRequested = false;
134  /* TODO handle transition to measurement states properly with dedicated state-machine */
135  /* TODO parse DATACHECKBYTE where available */
136 
138 
139  switch (pState->operationSubstate) {
140  case MXM_OP_ENTRY_STATE:
142  break;
145  pState->diagnosticCounter = 0u;
147  } else {
148  pState->diagnosticCounter++;
150  }
151  break;
154  const uint8_t temp_len =
155  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
157  const bool someDeviceHasBeenReset = MXM_CheckIfADeviceHasBeenReset(pState);
158  if (someDeviceHasBeenReset == true) {
159  /* a device has been reset, we should immediately reset the daisy chain by restarting the driver */
160  MXM_ErrorHandlerReset(pState, true);
161  }
162  }
163  break;
166  const uint8_t temp_len =
167  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
169  }
170  break;
173  const uint8_t temp_len =
174  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
176  }
177  break;
180  const uint8_t temp_len =
181  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
183  }
184  break;
187  const uint8_t temp_len =
188  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
190  }
191  break;
193  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
195  pState->batteryCmdBuffer.lsb = 0x00u;
196  pState->batteryCmdBuffer.msb = 0x00u;
197  }
199  break;
201  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
203  pState->batteryCmdBuffer.lsb = 0x00u;
204  pState->batteryCmdBuffer.msb = 0x00u;
205  }
207  break;
209  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
211  pState->batteryCmdBuffer.lsb = 0x00u;
212  pState->batteryCmdBuffer.msb = 0x00u;
213  }
215  break;
218  break;
220  /* configure I2CPNTR to channel number corresponding to mux counter*/
222  pState->batteryCmdBuffer.lsb = (0x01u << pState->muxCounter);
223  pState->batteryCmdBuffer.msb = 0x00u;
225  break;
226  case MXM_OP_WRITE_MUX0:
227  /* send configuration to MUX0 for channel 0 (PNTR configured to 1u) */
229  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX0_ADDRESS << 1u);
230  pState->batteryCmdBuffer.msb = 0x40u;
232  break;
233  case MXM_OP_WRITE_MUX1:
234  /* send configuration to MUX1 for channel 0 (PNTR configured to 1u) */
236  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX1_ADDRESS << 1u);
237  pState->batteryCmdBuffer.msb = 0x40u;
239  break;
242  /* set SCANSTROBE, enable 4x OVERSAMPL */
243  pState->batteryCmdBuffer.lsb = 0x09u;
244  /* enable AUTOBALSWDIS */
245  pState->batteryCmdBuffer.msb = 0x10u;
247  break;
250  /* no additional handling needed */
251  }
252  break;
253  case MXM_OP_GET_VOLTAGES:
255  temp_mon_state = MXM_MonGetVoltages(pState, mxm_voltageCellAddresses[pState->mxmVoltageCellCounter]);
256 
257  if (temp_mon_state == MXM_MONITORING_STATE_PASS) {
258  if (pState->mxmVoltageCellCounter < (uint8_t)UINT8_MAX) {
259  pState->mxmVoltageCellCounter++;
260  }
262  MXM_VOLTAGE_READ_ARRAY_LENGTH <= (uint8_t)UINT8_MAX,
263  "invalid define MXM_VOLTAGE_READ_ARRAY_LENGTH");
264  /* modified: read one additional aux entry */
266  pState->mxmVoltageCellCounter = 0;
268  }
269  } else {
270  /* MXM_MONITORING_STATE_PENDING, do nothing */
271  }
272  break;
273  case MXM_OP_GET_ALRTSUM:
275  /* no additional handling needed */
276  }
277  break;
279  if (MXM_ParseVoltagesIntoDB(pState) == STD_OK) {
281  pState->firstMeasurementDone = true;
282  } else {
283  MXM_ErrorHandlerReset(pState, false);
284  }
285  if (pState->stopRequested == true) {
287  } else {
288  /* do nothing */
289  }
290  break;
292  if (pState->openWireRequested == true) {
294  pState->openWireRequested = false;
295  } else {
297  }
298  break;
299  case MXM_OP_PINOPEN_EXIT:
301  break;
303  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
305  pState->batteryCmdBuffer.lsb = 0xFFu;
306  pState->batteryCmdBuffer.msb = 0xFFu; /* execute diagnostic on every cell */
307  }
309  break;
311  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
313  pState->batteryCmdBuffer.lsb = 0x81u;
314  pState->batteryCmdBuffer.msb = 0x00u; /* request comp scan */
315  }
317  break;
320  /* no additional handling needed */
321  }
322  break;
325  /* no additional handling needed */
326  }
327  break;
329  if (MXM_ProcessOpenWire(pState) == STD_OK) {
331  } else {
332  MXM_ErrorHandlerReset(pState, false);
333  }
334  break;
336  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
338  pState->batteryCmdBuffer.lsb = 0x00u;
339  pState->batteryCmdBuffer.msb = 0x00u;
340  }
342  break;
343  case MXM_OP_BAL_ENTRY:
344  /* Get the current time */
346 
347  /* Wait 'MXM_DELAY_BALANCING' milliseconds before processing the balancing */
351  MXM_DELAY_BALANCING) == false) {
352  /* nothing to do, exit balancing state chain */
354  } else {
355  /* Balancing needs to be processed */
357  /* First reset the balancing switches, and THEN
358  set the balancing switches according to the database */
360 
361  /* Change the parity of cells to balance */
362  if (pState->pBalancingState->evenCellsBalancingProcessed == true) {
363  pState->pBalancingState->evenCellsNeedBalancing = false;
364  pState->pBalancingState->oddCellsNeedBalancing = true;
365  }
366  /* Same for odd cells */
367  if (pState->pBalancingState->oddCellsBalancingProcessed == true) {
368  pState->pBalancingState->evenCellsNeedBalancing = true;
369  pState->pBalancingState->oddCellsNeedBalancing = false;
370  }
371  }
372  break;
374  /* Send a WRITEALL command to stop all balancing action */
375  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
377  pState->batteryCmdBuffer.lsb = 0x00U;
378  pState->batteryCmdBuffer.msb = 0x00U;
379  }
381  break;
383  /* Send a WRITEALL command to open all balancing switches */
384  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
386  /* CBRESTART is not reset to 0, not needed. */
387  pState->batteryCmdBuffer.lsb = 0x00U;
388  pState->batteryCmdBuffer.msb = 0x00U;
389  }
391  break;
393  /* Send a WRITEDEVICE command to each module in a daisy-chain
394  to close appropriate balancing switches */
395  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
398 
400  if (database_retval == STD_OK) {
401  /* Construct the balancing buffer */
403 
404  if (retval == STD_OK) {
405  if (pState->pBalancingState->cellsToBalance > 0u) {
406  /* Some cells need to be balanced */
409  pState->batteryCmdBuffer.lsb =
410  (uint8_t)(pState->pBalancingState->cellsToBalance & MXM_BM_LSB);
411  pState->batteryCmdBuffer.msb =
412  (uint8_t)(pState->pBalancingState->cellsToBalance >> MXM_CELLS_IN_LSB);
413  pState->batteryCmdBuffer.msb &= ((uint8_t)1u << 7u); /* set CBRESTART bit */
414 
415  const STD_RETURN_TYPE_e setStateRequestReturn = MXM_5XSetStateRequest(
416  pState->pInstance5X,
418  pState->batteryCmdBuffer,
419  &pState->requestStatus5x);
420  FAS_ASSERT(setStateRequestReturn == STD_OK);
421  } else {
422  /* It is not necessary to re-send 0 to the device, because it has been done previously
423  in the BALANCING_CONTROL_RESET_ALL sub-state */
425  }
426  } else {
427  /* this should not happen if the software works as expected */
430  }
431  } else {
432  /* database read not successful, retry */
434  }
435  } else if (pState->requestStatus5x == MXM_5X_STATE_UNPROCESSED) {
436  /* wait for processing */
437  } else if (pState->requestStatus5x == MXM_5X_STATE_PROCESSED) {
438  if (pState->pBalancingState->moduleBalancingIndex < pState->highest5xDevice) {
439  /* Not all modules have been treated. Repeat this state with the next module */
442  /* Re-set the status to UNSENT to repeat the WRITE operation */
444  } else {
445  /* Finished the iteration of all modules in a daisy chain, continue */
447 
448  /* Update flags for the end of balancing */
449  if (pState->pBalancingState->evenCellsNeedBalancing == true) {
451  } else if (pState->pBalancingState->oddCellsNeedBalancing == true) {
453  } else {
454  /* nothing to do here */
455  }
458  }
459  } else if (pState->requestStatus5x == MXM_5X_STATE_ERROR) {
460  /* default-behavior: retry */
462  MXM_ErrorHandlerReset(pState, false);
463  } else {
465  }
466  break;
467  case MXM_OP_BAL_START:
468  /* Initiate balancing for all devices in a daisy chain */
469  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
471  /* Manual ON MODE + Balancing halt in case of High temperature
472  + Alert when cell balancing is finished */
473  pState->batteryCmdBuffer.lsb = 0x0EU;
474  pState->batteryCmdBuffer.msb = 0x18U;
475  }
477  break;
480  const uint8_t temp_len =
481  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
483  }
484  break;
485  case MXM_OP_BAL_EXIT:
487  break;
489  /* actions that should be taken at the end of a measurement cycle */
491  break;
493  if (pState->muxCounter < (8u - 1u)) {
494  pState->muxCounter++;
495  } else {
496  pState->muxCounter = 0u;
497  }
499  break;
502  break;
503  /* "initialization" from here on */
504  case MXM_INIT_ENTRY:
506  break;
507  case MXM_INIT_DEVCFG1:
508  /* switch to single UART with external loopback */
509  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
511  pState->batteryCmdBuffer.lsb = 0x00u; /* alert interface disabled */
512  pState->batteryCmdBuffer.msb = 0x01u; /* single uart with external loopback*/
513  }
515  break;
516  case MXM_INIT_DEVCFG2:
517  /* default value for DEVCFG2 */
518  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
520  pState->batteryCmdBuffer.lsb = 0x00u; /* activate CB watchdog */
521  pState->batteryCmdBuffer.msb = 0x40u; /* default*/
522  }
524  break;
526  /* clear ALRTDUALUART (as requested for startup routine in data-sheet) */
527  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
529  pState->batteryCmdBuffer.lsb = 0x00u; /* clear lsb */
530  pState->batteryCmdBuffer.msb = 0x00u; /* clear msb, containing ALRTDUALUART */
531  }
533  break;
534  case MXM_INIT_STATUS1:
535  /* clear ALRTRST */
536  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
538  pState->batteryCmdBuffer.lsb = 0x00u;
539  pState->batteryCmdBuffer.msb = 0x00u;
540  }
542  break;
544  /* add version information to registry */
546  uint8_t temp_len =
547  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
548  MXM_MonRegistryParseVersionIntoDevices(pState, temp_len);
549  }
550  break;
551  case MXM_INIT_GET_ID1:
552  /* add ID1 to registry */
553  if (MXM_HandleStateReadall(pState, MXM_REG_ID1, MXM_INIT_GET_ID2) == true) {
554  uint8_t temp_len =
555  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
557  }
558  break;
559  case MXM_INIT_GET_ID2:
560  /* add ID2 to registry */
562  uint8_t temp_len =
563  (uint8_t)((BATTERY_MANAGEMENT_TX_LENGTH_READALL + (2uL * MXM_5XGetNumberOfSatellites(pState->pInstance5X))) & (uint8_t)UINT8_MAX);
565  }
566  break;
567  case MXM_INIT_MEASUREEN1:
568  /* enable all 14 cells */
569  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
571  pState->batteryCmdBuffer.lsb = 0xFFu;
572  pState->batteryCmdBuffer.msb = 0x7Fu; /* TODO this also enables block measurement */
573  }
575  break;
576  case MXM_INIT_MEASUREEN2:
577  /* enable AUX2 and AUX3 */
578  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
580  pState->batteryCmdBuffer.lsb = 0x0Cu; /* AUX2 and AUX3 */
581  pState->batteryCmdBuffer.msb = 0x00u;
582  }
584  break;
585  case MXM_INIT_AUXGPIOCFG:
586  /* switch GPIO2 and GPIO3 to AUX, enable I2C */
587  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
589  pState->batteryCmdBuffer.lsb = 0x00u;
590  /* conf for MAX17853: 0x3Eu */
591  /* conf for MAX17852, I2C enable: 0x8Eu */
592  /* I2C enable, AUX2 and AUX3 */
593  pState->batteryCmdBuffer.msb = 0x80u;
594  }
596  break;
597  case MXM_INIT_AUXTIMEREG:
598  /* configure settling time that NTC network takes for measurement to 500us */
599  /* WARNING: reevaluate this value if thermistor supply is switched
600  during sampling */
601  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
603  pState->batteryCmdBuffer.lsb = 0x53u;
604  pState->batteryCmdBuffer.msb = 0x00u;
605  }
607  break;
608  case MXM_INIT_ACQCFG:
609  /* set ACQCFG */
610  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
612  /* default values */
613  pState->batteryCmdBuffer.lsb = 0x00u;
614  /* we have to turn thermistor switch manually on, as charging
615  the network takes to long */
616  pState->batteryCmdBuffer.msb = 0x06u;
617  }
619  break;
620  case MXM_INIT_UVTHSETREG:
621  /* configure UVTHSETREG */
622  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
626  &pState->batteryCmdBuffer.lsb,
627  &pState->batteryCmdBuffer.msb);
628  }
630  break;
631  case MXM_INIT_OVTHSETREG:
632  /* configure OVTHSETREG */
633  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
637  &pState->batteryCmdBuffer.lsb,
638  &pState->batteryCmdBuffer.msb);
639  }
641  break;
642  case MXM_INIT_BALEXP1:
643  /* set BALEXP1 to have 5 minute timeout in manual balancing */
644  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
646  pState->batteryCmdBuffer.lsb = 0x05u;
647  pState->batteryCmdBuffer.msb = 0x00u;
648  }
650  break;
651  case MXM_INIT_BALEXP2:
652  /* set BALEXP2 to have 0 minute timeout in manual balancing */
653  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
655  pState->batteryCmdBuffer.lsb = 0x00u;
656  pState->batteryCmdBuffer.msb = 0x00u;
657  }
659  break;
660  case MXM_INIT_BALEXP3:
661  /* set BALEXP3 to have 0 minute timeout in manual balancing */
662  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
664  pState->batteryCmdBuffer.lsb = 0x00u;
665  pState->batteryCmdBuffer.msb = 0x00u;
666  }
668  break;
669  case MXM_INIT_BALEXP4:
670  /* set BALEXP4 to have 0 minute timeout in manual balancing */
671  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
673  pState->batteryCmdBuffer.lsb = 0x00u;
674  pState->batteryCmdBuffer.msb = 0x00u;
675  }
677  break;
678  case MXM_INIT_BALEXP5:
679  /* set BALEXP5 to have 0 minute timeout in manual balancing */
680  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
682  pState->batteryCmdBuffer.lsb = 0x00u;
683  pState->batteryCmdBuffer.msb = 0x00u;
684  }
686  break;
687  case MXM_INIT_BALEXP6:
688  /* set BALEXP6 to have 0 minute timeout in manual balancing */
689  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
691  pState->batteryCmdBuffer.lsb = 0x00u;
692  pState->batteryCmdBuffer.msb = 0x00u;
693  }
695  break;
696  case MXM_INIT_BALEXP7:
697  /* set BALEXP7 to have 0 minute timeout in manual balancing */
698  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
700  pState->batteryCmdBuffer.lsb = 0x00u;
701  pState->batteryCmdBuffer.msb = 0x00u;
702  }
704  break;
705  case MXM_INIT_BALEXP8:
706  /* set BALEXP8 to have 0 minute timeout in manual balancing */
707  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
709  pState->batteryCmdBuffer.lsb = 0x00u;
710  pState->batteryCmdBuffer.msb = 0x00u;
711  }
713  break;
714  case MXM_INIT_BALEXP9:
715  /* set BALEXP9 to have 0 minute timeout in manual balancing */
716  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
718  pState->batteryCmdBuffer.lsb = 0x00u;
719  pState->batteryCmdBuffer.msb = 0x00u;
720  }
722  break;
723  case MXM_INIT_BALEXP10:
724  /* set BALEXP10 to have 0 minute timeout in manual balancing */
725  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
727  pState->batteryCmdBuffer.lsb = 0x00u;
728  pState->batteryCmdBuffer.msb = 0x00u;
729  }
731  break;
732  case MXM_INIT_BALEXP11:
733  /* set BALEXP11 to have 0 minute timeout in manual balancing */
734  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
736  pState->batteryCmdBuffer.lsb = 0x00u;
737  pState->batteryCmdBuffer.msb = 0x00u;
738  }
740  break;
741  case MXM_INIT_BALEXP12:
742  /* set BALEXP12 to have 0 minute timeout in manual balancing */
743  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
745  pState->batteryCmdBuffer.lsb = 0x00u;
746  pState->batteryCmdBuffer.msb = 0x00u;
747  }
749  break;
750  case MXM_INIT_BALEXP13:
751  /* set BALEXP13 to have 0 minute timeout in manual balancing */
752  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
754  pState->batteryCmdBuffer.lsb = 0x00u;
755  pState->batteryCmdBuffer.msb = 0x00u;
756  }
758  break;
759  case MXM_INIT_BALEXP14:
760  /* set BALEXP14 to have 0 minute timeout in manual balancing */
761  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
763  pState->batteryCmdBuffer.lsb = 0x00u;
764  pState->batteryCmdBuffer.msb = 0x00u;
765  }
767  break;
768  case MXM_INIT_BALSWDLY:
769  /* set BALSWDLY to 2 ms settling time after balancing */
770  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
772  /* CELLDLY = 1920us (~2ms) --> 20*96us
773  CELLDLY corresponds to the time to relax the cell before voltage measurement */
774  pState->batteryCmdBuffer.lsb = 0x00u;
775  pState->batteryCmdBuffer.msb = 0x14u;
776  }
778  break;
779  case MXM_INIT_ALRTOVEN:
780  /* enable ALRTOVEN */
781  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
783  pState->batteryCmdBuffer.lsb = 0xFFu;
784  pState->batteryCmdBuffer.msb = 0x3Fu;
785  }
787  break;
788  case MXM_INIT_ALRTUVEN:
789  /* enable ALRTUVEN */
790  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
792  pState->batteryCmdBuffer.lsb = 0xFFu;
793  pState->batteryCmdBuffer.msb = 0x3Fu;
794  }
796  break;
798  /* configure COMPOPNTHREG */
799  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
801  /* TODO 0.5V */
804  &pState->batteryCmdBuffer.lsb,
805  &pState->batteryCmdBuffer.msb);
806  }
808  break;
811  /* no additional handling needed */
812  }
813  break;
814  case MXM_INIT_I2C_CFG:
815  /* configure I2CCFG to
816  * 400kHz
817  * Alternate write Mode (just a pointer without data)
818  * Combined Format
819  * 7 Bit addressing
820  * one byte pointer length
821  * default
822  */
823  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
825  pState->batteryCmdBuffer.lsb = 0x00u;
826  pState->batteryCmdBuffer.msb = 0xE0u;
827  }
829  break;
830  case MXM_INIT_I2C_PNTR:
831  /* configure I2CPNTR */
832  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
834  pState->batteryCmdBuffer.lsb = 0x01u;
835  pState->batteryCmdBuffer.msb = 0x00u;
836  }
838  break;
840  /* send configuration to MUX0 for channel 0 (PNTR configured to 1u) */
841  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
843  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX0_ADDRESS << 1u);
844  pState->batteryCmdBuffer.msb = 0x40u;
845  }
847  break;
849  /* send configuration to MUX1 for channel 0 (PNTR configured to 1u) */
850  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
852  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX1_ADDRESS << 1u);
853  pState->batteryCmdBuffer.msb = 0x40u;
854  }
856  break;
859  /* no additional handling needed */
860  }
861  break;
862  default:
863  /* invalid state */
865  break;
866  }
867 }
868 
869 /*========== Externalized Static Function Implementations (Unit Test) =======*/
870 #ifdef UNITY_UNIT_TEST
871 #endif
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:86
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
#define FAS_STATIC_ASSERT(cond, msg)
Definition: fassert.h:285
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
#define MXM_I2C_MUX0_ADDRESS
address of MUX0
Definition: mxm_17852.c:79
#define MXM_I2C_MUX1_ADDRESS
address of MUX1
Definition: mxm_17852.c:81
#define MXM_BM_LSB
Monitoring Register LSB.
#define MXM_DELAY_BALANCING
Delay in milliseconds before the balancing status is updated.
Definition: mxm_17852.c:85
MXM_MODEL_ID_e MXM_GetModelIdOfDaisyChain(void)
returns the model ID of the daisy chain
Definition: mxm_17852.c:96
void MXM_StateMachineOperation(MXM_MONITORING_INSTANCE_s *pState)
State-Machine implementation for operation state.
Definition: mxm_17852.c:100
void MXM_ErrorHandlerReset(MXM_MONITORING_INSTANCE_s *pInstance, bool immediateReset)
This error handler is used as a last resort and tries a reset of the complete driver.
Definition: mxm_1785x.c:909
bool GEN_MUST_CHECK_RETURN MXM_HandleStateReadall(MXM_MONITORING_INSTANCE_s *pInstance, MXM_REG_NAME_e registerName, MXM_STATEMACHINE_OPERATION_STATES_e nextState)
Handle the state machine-transactions for a READALL.
Definition: mxm_1785x.c:948
STD_RETURN_TYPE_e MXM_ProcessOpenWire(const MXM_MONITORING_INSTANCE_s *const kpkInstance)
Processes the retrieved information on open wire.
Definition: mxm_1785x.c:979
STD_RETURN_TYPE_e MXM_ParseVoltagesIntoDB(const MXM_MONITORING_INSTANCE_s *const kpkInstance)
Copies measured voltage data into the database.
Definition: mxm_1785x.c:1083
STD_RETURN_TYPE_e MXM_ConstructBalancingBuffer(MXM_BALANCING_STATE_s *pBalancingInstance)
Fill the balancing data structure.
Definition: mxm_1785x.c:1024
MXM_MONITORING_STATE_e GEN_MUST_CHECK_RETURN MXM_MonGetVoltages(MXM_MONITORING_INSTANCE_s *pState, MXM_REG_NAME_e regAddress)
Encapsulation for reading voltages from a register.
Definition: mxm_1785x.c:1280
void MXM_HandleStateWriteall(MXM_MONITORING_INSTANCE_s *pInstance, MXM_STATEMACHINE_OPERATION_STATES_e nextState)
Handle the state machine-transactions for a WRITEALL.
Definition: mxm_1785x.c:920
Headers for the driver for the MAX17841B ASCI and MAX1785x analog front-end.
#define MXM_REF_UNIPOLAR_CELL_mV
Definition: mxm_1785x.h:111
#define MXM_CELLS_IN_LSB
Definition: mxm_1785x.h:108
#define MXM_THRESHOLD_DIAGNOSTIC_AFTER_CYCLES
Battery monitoring driver for MAX1785x battery monitoring ICs.
Definition: mxm_1785x.h:102
#define MXM_VOLTAGE_READ_ARRAY_LENGTH
Definition: mxm_1785x.h:105
void MXM_Unipolar14BitInto16Bit(uint16_t inputValue, uint8_t *lsb, uint8_t *msb)
convert a unipolar 14bit-value and shifts it into the 16bit-format
uint16_t MXM_VoltageIntoUnipolar14Bit(uint16_t voltage_mV, uint16_t fullscaleReference_mV)
convert a voltage value into a unipolar 14bit value
This is a collection of helper functions for the MAX1785x ICs.
MXM_MONITORING_STATE_e
@ MXM_MONITORING_STATE_PASS
@ MXM_MONITORING_STATE_PENDING
@ MXM_INIT_I2C_GET_STAT1
@ MXM_OP_DIAGNOSTIC_CLEAR_FMEA1
@ MXM_INIT_BALEXP5
@ MXM_OP_WRITE_MUX0
@ MXM_INIT_BALEXP6
@ MXM_OP_DIAGNOSTIC_FMEA2
@ MXM_OP_BAL_CONTROL_STOP_BALANCING
@ MXM_INIT_STATUS1
@ MXM_INIT_BALEXP13
@ MXM_INIT_OVTHSETREG
@ MXM_INIT_BALEXP1
@ MXM_INIT_BALEXP9
@ MXM_OP_PINOPEN_RESTORE_CURRENT_SOURCE_CONF
@ MXM_INIT_SET_STATUS2
@ MXM_OP_DIAGNOSTIC_FMEA1
@ MXM_INIT_I2C_SEND_MUX1
@ MXM_INIT_MEASUREEN1
@ MXM_OP_PINOPEN_SET_CURRENT_SOURCES
@ MXM_INIT_GET_ID2
@ MXM_INIT_MEASUREEN2
@ MXM_OP_PINOPEN_GET_SCAN_STROBE
@ MXM_OP_DIAGNOSTIC_CLEAR_STATUS2
@ MXM_INIT_I2C_PNTR
@ MXM_OP_BAL_START
@ MXM_INIT_BALEXP8
@ MXM_INIT_UVTHSETREG
@ MXM_OP_PINOPEN_COMPSCAN
@ MXM_INIT_I2C_SEND_MUX0
@ MXM_INIT_BALSWDLY
@ MXM_INIT_GET_VERSION
@ MXM_OP_DIAGNOSTIC_CLEAR_FMEA2
@ MXM_OP_BAL_CONTROL_SET_ALL
@ MXM_INIT_ENTRY
@ MXM_OP_BAL_READ_BALSTAT
@ MXM_INIT_GET_ID1
@ MXM_OP_DIAGNOSTIC_EXIT
@ MXM_OP_DIAGNOSTIC_STATUS1
@ MXM_INIT_GET_I2C_STAT2
@ MXM_OP_PINOPEN_EXIT
@ MXM_OP_PINOPEN_ENTRY
@ MXM_OP_PINOPEN_PROCESS_OPENWIRE
@ MXM_INIT_BALEXP10
@ MXM_INIT_BALEXP14
@ MXM_INIT_BALEXP12
@ MXM_OP_INCREMENT_MUX_COUNTER
@ MXM_OP_BAL_EXIT
@ MXM_OP_PARSE_VOLTAGES_INTO_DB
@ MXM_INIT_I2C_CFG
@ MXM_INIT_ALRTUVEN
@ MXM_INIT_BALEXP3
@ MXM_OP_SELECT_MUX_CHANNEL
@ MXM_INIT_BALEXP2
@ MXM_OP_WRITE_MUX1
@ MXM_INIT_ALRTOVEN
@ MXM_OP_ENTRY_STATE
@ MXM_INIT_BALEXP7
@ MXM_INIT_DEVCFG2
@ MXM_OP_CYCLE_END_EXIT
@ MXM_OP_GET_VOLTAGES
@ MXM_OP_GET_ALRTSUM
@ MXM_OP_CYCLE_END_ENTRY
@ MXM_OP_BAL_CONTROL_RESET_ALL
@ MXM_OP_BAL_ENTRY
@ MXM_INIT_ACQCFG
@ MXM_INIT_COMPOPNTHREG
@ MXM_OP_PINOPEN_GET_ALRT
@ MXM_OP_DIAGNOSTIC_STATUS2
@ MXM_INIT_BALEXP4
@ MXM_OP_DIAGNOSTIC_STATUS3
@ MXM_OP_SET_SCAN_STROBE
@ MXM_OP_GET_SCAN_STROBE
@ MXM_INIT_DEVCFG1
@ MXM_INIT_BALEXP11
@ MXM_INIT_AUXTIMEREG
@ MXM_INIT_AUXGPIOCFG
@ MXM_OP_DIAGNOSTIC_ENTRY
@ MXM_STATEMACHINE_STATES_IDLE
MXM_MODEL_ID_e
Type of monitoring device.
@ MXM_MODEL_ID_MAX17852
STD_RETURN_TYPE_e MXM_5XSetStateRequest(MXM_5X_INSTANCE_s *pInstance5x, MXM_STATEMACHINE_5X_e state, MXM_5X_COMMAND_PAYLOAD_s commandPayload, MXM_5X_STATE_REQUEST_STATUS_e *processed)
Set state request for the Battery Management Statemachine.
uint8_t MXM_5XGetNumberOfSatellites(const MXM_5X_INSTANCE_s *const kpkInstance)
Get number of satellites.
Headers for the driver for the MAX17841B ASCI and MAX1785x analog front-end.
@ MXM_STATEMACH_5X_WRITE_DEVICE
@ MXM_5X_STATE_UNSENT
@ MXM_5X_STATE_PROCESSED
@ MXM_5X_STATE_UNPROCESSED
@ MXM_5X_STATE_ERROR
#define BATTERY_MANAGEMENT_TX_LENGTH_READALL
Battery Management Protocol lengths of TX buffer.
MXM_REG_NAME_e
MAX1785x register names.
@ MXM_REG_CTSTCFG
@ MXM_REG_CELL1
@ MXM_REG_CELL4
@ MXM_REG_BALEXP11
@ MXM_REG_STATUS1
@ MXM_REG_BALEXP6
@ MXM_REG_STATUS3
@ MXM_REG_STATUS2
@ MXM_REG_BALEXP2
@ MXM_REG_ALRTSUM
@ MXM_REG_CELL10
@ MXM_REG_BALEXP13
@ MXM_REG_I2CCFG
@ MXM_REG_BALEXP5
@ MXM_REG_UVTHSET
@ MXM_REG_BALEXP10
@ MXM_REG_AUX3
@ MXM_REG_BALEXP1
@ MXM_REG_SCANCTRL
@ MXM_REG_BALSTAT
@ MXM_REG_VERSION
@ MXM_REG_MEASUREEN2
@ MXM_REG_I2CSTAT
@ MXM_REG_ID1
@ MXM_REG_BALEXP14
@ MXM_REG_I2CPNTR
@ MXM_REG_CELL9
@ MXM_REG_AUXTIME
@ MXM_REG_BLOCK
@ MXM_REG_DEVCFG2
@ MXM_REG_COMPOPNTH
@ MXM_REG_AUXGPIOCFG
@ MXM_REG_CELL3
@ MXM_REG_BALEXP8
@ MXM_REG_FMEA1
@ MXM_REG_ID2
@ MXM_REG_BALEXP9
@ MXM_REG_CELL14
@ MXM_REG_CELL6
@ MXM_REG_I2CSEND
@ MXM_REG_ACQCFG
@ MXM_REG_BALCTRL
@ MXM_REG_CELL2
@ MXM_REG_BALEXP7
@ MXM_REG_ALRTUVEN
@ MXM_REG_BALEXP3
@ MXM_REG_CELL11
@ MXM_REG_MEASUREEN1
@ MXM_REG_BALSWDLY
@ MXM_REG_CELL5
@ MXM_REG_CELL13
@ MXM_REG_OVTHSET
@ MXM_REG_AUX2
@ MXM_REG_BALSWCTRL
@ MXM_REG_FMEA2
@ MXM_REG_CELL7
@ MXM_REG_BALEXP12
@ MXM_REG_ALRTCOMPUV
@ MXM_REG_DEVCFG1
@ MXM_REG_ALRTOVEN
@ MXM_REG_CELL8
@ MXM_REG_CELL12
@ MXM_REG_BALEXP4
void MXM_MonRegistryParseIdIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength, MXM_REG_NAME_e type)
Parse ID (1 or 2) into the registry.
Definition: mxm_registry.c:125
void MXM_MonRegistryParseStatusFmeaIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse STATUS or FMEA into the registry.
Definition: mxm_registry.c:196
void MXM_MonRegistryParseVersionIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse Version into the registry.
Definition: mxm_registry.c:156
bool MXM_CheckIfADeviceHasBeenReset(const MXM_MONITORING_INSTANCE_s *const kpkState)
check if one of the devices in the registry has the ALRTRST bit set
Definition: mxm_registry.c:243
Functions in order to have a registry of monitoring ICs.
bool OS_CheckTimeHasPassedWithTimestamp(uint32_t oldTimeStamp_ms, uint32_t currentTimeStamp_ms, uint32_t timeToPass_ms)
This function checks if timeToPass has passed since the last timestamp to now.
Definition: os.c:124
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:158
DATA_BLOCK_BALANCING_CONTROL_s *const pBalancingControl_table
MXM_5X_COMMAND_PAYLOAD_s batteryCmdBuffer
MXM_STATEMACHINE_OPERATION_STATES_e operationSubstate
MXM_BALANCING_STATE_s *const pBalancingState
MXM_STATEMACHINE_STATES_e state
MXM_5X_INSTANCE_s *const pInstance5X
MXM_5X_STATE_REQUEST_STATUS_e requestStatus5x