foxBMS  1.2.1
The foxBMS Battery Management System API Documentation
mxm_17852.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file mxm_17852.c
44  * @author foxBMS Team
45  * @date 2021-11-24 (date of creation)
46  * @updated 2021-12-06 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix MXM
49  *
50  * @brief Operation state machine implementation for the MAX17852
51  *
52  * @details This file contains that part of the state machine that is executed
53  * during the operation state. It is adapted for MAX17852.
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 /* clang-format off */
59 #include "mxm_1785x.h"
60 /* clang-format on */
61 
62 #include "database.h"
63 #include "mxm_1785x_tools.h"
64 #include "mxm_battery_management.h"
65 #include "mxm_registry.h"
66 #include "os.h"
67 
68 /*========== Macros and Definitions =========================================*/
69 /** @defgroup MXM_I2C_IMPLEMENTATION symbols and settings pertaining to the I2C implementation in MXM
70  * @{
71  */
72 /** @brief address of MUX0 */
73 #define MXM_I2C_MUX0_ADDRESS (0x4Cu)
74 /** @brief address of MUX1 */
75 #define MXM_I2C_MUX1_ADDRESS (0x4Du)
76 /**@}*/
77 
78 /** @brief Delay in milliseconds before the balancing status is updated */
79 #define MXM_DELAY_BALANCING 10000u
80 
81 /*========== Static Constant and Variable Definitions =======================*/
82 
83 /*========== Extern Constant and Variable Definitions =======================*/
84 
85 /*========== Static Function Prototypes =====================================*/
86 
87 /*========== Static Function Implementations ================================*/
88 
89 /*========== Extern Function Implementations ================================*/
91  return MXM_MODEL_ID_MAX17852;
92 }
93 
95  FAS_ASSERT(pState != NULL_PTR);
96 
97  /**
98  * @brief Mapping of voltage registers
99  *
100  * This array maps registers of the monitoring IC onto cell-numbers. The
101  * register values are defined in the #MXM_REG_NAME_e enum.
102  * For now the length of this array is #MXM_VOLTAGE_READ_ARRAY_LENGTH
103  * as it is enabled for the measurement of all cells, two AUX-voltages and
104  * one block voltage. This has to be adapted once this driver is enabled for
105  * general operation.
106  */
107  const MXM_REG_NAME_e mxm_voltageCellAddresses[MXM_VOLTAGE_READ_ARRAY_LENGTH] = {
122  MXM_REG_AUX2,
123  MXM_REG_AUX3,
125  };
126 
127  pState->operationRequested = false;
128  /* TODO handle transition to measurement states properly with dedicated state-machine */
129  /* TODO parse DATACHECKBYTE where available */
130 
132 
133  switch (pState->operationSubstate) {
134  case MXM_OP_ENTRY_STATE:
136  break;
139  pState->diagnosticCounter = 0u;
141  } else {
142  pState->diagnosticCounter++;
144  }
145  break;
148  const uint8_t temp_len = (uint8_t)(
150  (uint8_t)UINT8_MAX);
152  const bool someDeviceHasBeenReset = MXM_CheckIfADeviceHasBeenReset(pState);
153  if (someDeviceHasBeenReset == true) {
154  /* a device has been reset, we should immediately reset the daisy chain by restarting the driver */
155  MXM_ErrorHandlerReset(pState, true);
156  }
157  }
158  break;
161  const uint8_t temp_len = (uint8_t)(
163  (uint8_t)UINT8_MAX);
165  }
166  break;
169  const uint8_t temp_len = (uint8_t)(
171  (uint8_t)UINT8_MAX);
173  }
174  break;
177  const uint8_t temp_len = (uint8_t)(
179  (uint8_t)UINT8_MAX);
181  }
182  break;
185  const uint8_t temp_len = (uint8_t)(
187  (uint8_t)UINT8_MAX);
189  }
190  break;
192  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
194  pState->batteryCmdBuffer.lsb = 0x00u;
195  pState->batteryCmdBuffer.msb = 0x00u;
196  }
198  break;
200  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
202  pState->batteryCmdBuffer.lsb = 0x00u;
203  pState->batteryCmdBuffer.msb = 0x00u;
204  }
206  break;
208  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
210  pState->batteryCmdBuffer.lsb = 0x00u;
211  pState->batteryCmdBuffer.msb = 0x00u;
212  }
214  break;
217  break;
219  /* configure I2CPNTR to channel number corresponding to mux counter*/
221  pState->batteryCmdBuffer.lsb = (0x01u << pState->muxCounter);
222  pState->batteryCmdBuffer.msb = 0x00u;
224  break;
225  case MXM_OP_WRITE_MUX0:
226  /* send configuration to MUX0 for channel 0 (PNTR configured to 1u) */
228  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX0_ADDRESS << 1u);
229  pState->batteryCmdBuffer.msb = 0x40u;
231  break;
232  case MXM_OP_WRITE_MUX1:
233  /* send configuration to MUX1 for channel 0 (PNTR configured to 1u) */
235  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX1_ADDRESS << 1u);
236  pState->batteryCmdBuffer.msb = 0x40u;
238  break;
241  /* set SCANSTROBE, enable 4x OVERSAMPL */
242  pState->batteryCmdBuffer.lsb = 0x09u;
243  /* enable AUTOBALSWDIS */
244  pState->batteryCmdBuffer.msb = 0x10u;
246  break;
249  /* no additional handling needed */
250  }
251  break;
252  case MXM_OP_GET_VOLTAGES:
254  temp_mon_state = MXM_MonGetVoltages(pState, mxm_voltageCellAddresses[pState->mxmVoltageCellCounter]);
255 
256  if (temp_mon_state == MXM_MONITORING_STATE_PASS) {
257  if (pState->mxmVoltageCellCounter < (uint8_t)UINT8_MAX) {
258  pState->mxmVoltageCellCounter++;
259  }
261  MXM_VOLTAGE_READ_ARRAY_LENGTH <= (uint8_t)UINT8_MAX,
262  "invalid define MXM_VOLTAGE_READ_ARRAY_LENGTH");
263  /* modified: read one additional aux entry */
265  pState->mxmVoltageCellCounter = 0;
267  }
268  } else {
269  /* MXM_MONITORING_STATE_PENDING, do nothing */
270  }
271  break;
272  case MXM_OP_GET_ALRTSUM:
274  /* no additional handling needed */
275  }
276  break;
278  if (MXM_ParseVoltagesIntoDB(pState) == STD_OK) {
280  pState->firstMeasurementDone = true;
281  } else {
282  MXM_ErrorHandlerReset(pState, false);
283  }
284  if (pState->stopRequested == true) {
286  } else {
287  /* do nothing */
288  }
289  break;
291  if (pState->openwireRequested == true) {
293  pState->openwireRequested = false;
294  } else {
296  }
297  break;
298  case MXM_OP_PINOPEN_EXIT:
300  break;
302  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
304  pState->batteryCmdBuffer.lsb = 0xFFu;
305  pState->batteryCmdBuffer.msb = 0xFFu; /* execute diagnostic on every cell */
306  }
308  break;
310  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
312  pState->batteryCmdBuffer.lsb = 0x81u;
313  pState->batteryCmdBuffer.msb = 0x00u; /* request comp scan */
314  }
316  break;
319  /* no additional handling needed */
320  }
321  break;
324  /* no additional handling needed */
325  }
326  break;
328  if (MXM_ProcessOpenWire(pState) == STD_OK) {
330  } else {
331  MXM_ErrorHandlerReset(pState, false);
332  }
333  break;
335  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
337  pState->batteryCmdBuffer.lsb = 0x00u;
338  pState->batteryCmdBuffer.msb = 0x00u;
339  }
341  break;
342  case MXM_OP_BAL_ENTRY:
343  /* Get the current time */
345 
346  /* Wait 'MXM_DELAY_BALANCING' milliseconds before processing the balancing */
351  /* nothing to do, exit balancing state chain */
353  } else {
354  /* Balancing needs to be processed */
356  /* First reset the balancing switches, and THEN
357  set the balancing switches according to the database */
359 
360  /* Change the parity of cells to balance */
361  if (pState->pBalancingState->evenCellsBalancingProcessed == true) {
362  pState->pBalancingState->evenCellsNeedBalancing = false;
363  pState->pBalancingState->oddCellsNeedBalancing = true;
364  }
365  /* Same for odd cells */
366  if (pState->pBalancingState->oddCellsBalancingProcessed == true) {
367  pState->pBalancingState->evenCellsNeedBalancing = true;
368  pState->pBalancingState->oddCellsNeedBalancing = false;
369  }
370  }
371  break;
373  /* Send a WRITEALL command to open all balancing switches */
374  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
376  /* CBRESTART is not reset to 0, not needed. */
377  pState->batteryCmdBuffer.lsb = 0x00U;
378  pState->batteryCmdBuffer.msb = 0x00U;
379  }
381  break;
383  /* Send a WRITEDEVICE command to each module in a daisy-chain
384  to close appropriate balancing switches */
385  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
388 
390  if (STD_OK == database_retval) {
391  /* Construct the balancing buffer */
393 
394  if (retval == STD_OK) {
395  if (pState->pBalancingState->cellsToBalance > 0u) {
396  /* Some cells need to be balanced */
399  pState->batteryCmdBuffer.lsb =
400  (uint8_t)(pState->pBalancingState->cellsToBalance & MXM_BM_LSB);
401  pState->batteryCmdBuffer.msb =
402  (uint8_t)(pState->pBalancingState->cellsToBalance >> MXM_CELLS_IN_LSB);
403 
404  const STD_RETURN_TYPE_e setStateRequestReturn = MXM_5XSetStateRequest(
405  pState->pInstance5X,
407  pState->batteryCmdBuffer,
408  &pState->requestStatus5x);
409  FAS_ASSERT(setStateRequestReturn == STD_OK);
410  } else {
411  /* It is not necessary to re-send 0 to the device, because it has been done previously
412  in the BALANCING_CONTROL_RESET_ALL sub-state */
414  }
415  } else {
416  /* this should not happen if the software works as expected */
419  }
420  } else {
421  /* database read not successful, retry */
423  }
424  } else if (pState->requestStatus5x == MXM_5X_STATE_UNPROCESSED) {
425  /* wait for processing */
426  } else if (pState->requestStatus5x == MXM_5X_STATE_PROCESSED) {
427  if (pState->pBalancingState->moduleBalancingIndex < pState->highest5xDevice) {
428  /* Not all modules have been treated. Repeat this state with the next module */
431  /* Re-set the status to UNSENT to repeat the WRITE operation */
433  } else {
434  /* Finished the iteration of all modules in a daisy chain, continue */
436 
437  /* Update flags for the end of balancing */
438  if (pState->pBalancingState->evenCellsNeedBalancing == true) {
440  } else if (pState->pBalancingState->oddCellsNeedBalancing == true) {
442  } else {
443  /* nothing to do here */
444  }
447  }
448  } else if (pState->requestStatus5x == MXM_5X_STATE_ERROR) {
449  /* default-behavior: retry */
451  MXM_ErrorHandlerReset(pState, false);
452  } else {
454  }
455  break;
456  case MXM_OP_BAL_START:
457  /* Initiate balancing for all devices in a daisy chain */
458  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
460  /* Manual ON MODE + Balancing halt in case of High temperature
461  + Alert when cell balancing is finished */
462  pState->batteryCmdBuffer.lsb = 0x0EU;
463  pState->batteryCmdBuffer.msb = 0x18U;
464  }
466  break;
467  case MXM_OP_BAL_EXIT:
469  break;
471  /* actions that should be taken at the end of a measurement cycle */
473  break;
475  if (pState->muxCounter < (8u - 1u)) {
476  pState->muxCounter++;
477  } else {
478  pState->muxCounter = 0u;
479  }
481  break;
484  break;
485  /* "initialization" from here on */
486  case MXM_INIT_ENTRY:
488  break;
489  case MXM_INIT_DEVCFG1:
490  /* switch to single UART with external loopback */
491  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
493  pState->batteryCmdBuffer.lsb = 0x00u; /* alert interface disabled */
494  pState->batteryCmdBuffer.msb = 0x01u; /* single uart with external loopback*/
495  }
497  break;
499  /* clear ALRTDUALUART (as requested for startup routine in data-sheet) */
500  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
502  pState->batteryCmdBuffer.lsb = 0x00u; /* clear lsb */
503  pState->batteryCmdBuffer.msb = 0x00u; /* clear msb, containing ALRTDUALUART */
504  }
506  break;
507  case MXM_INIT_STATUS1:
508  /* clear ALRTRST */
509  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
511  pState->batteryCmdBuffer.lsb = 0x00u;
512  pState->batteryCmdBuffer.msb = 0x00u;
513  }
515  break;
517  /* add version information to registry */
519  uint8_t temp_len = (uint8_t)(
521  (uint8_t)UINT8_MAX);
522  MXM_MonRegistryParseVersionIntoDevices(pState, temp_len);
523  }
524  break;
525  case MXM_INIT_GET_ID1:
526  /* add ID1 to registry */
527  if (true == MXM_HandleStateReadall(pState, MXM_REG_ID1, MXM_INIT_GET_ID2)) {
528  uint8_t temp_len = (uint8_t)(
530  (uint8_t)UINT8_MAX);
532  }
533  break;
534  case MXM_INIT_GET_ID2:
535  /* add ID2 to registry */
537  uint8_t temp_len = (uint8_t)(
539  (uint8_t)UINT8_MAX);
541  }
542  break;
543  case MXM_INIT_MEASUREEN1:
544  /* enable all 14 cells */
545  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
547  pState->batteryCmdBuffer.lsb = 0xFFu;
548  pState->batteryCmdBuffer.msb = 0x7Fu; /* TODO this also enables block measurement */
549  }
551  break;
552  case MXM_INIT_MEASUREEN2:
553  /* enable AUX2 and AUX3 */
554  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
556  pState->batteryCmdBuffer.lsb = 0x0Cu; /* AUX2 and AUX3 */
557  pState->batteryCmdBuffer.msb = 0x00u;
558  }
560  break;
561  case MXM_INIT_AUXGPIOCFG:
562  /* switch GPIO2 and GPIO3 to AUX, enable I2C */
563  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
565  pState->batteryCmdBuffer.lsb = 0x00u;
566  /* conf for MAX17853: 0x3Eu */
567  /* conf for MAX17852, I2C enable: 0x8Eu */
568  /* I2C enable, AUX2 and AUX3 */
569  pState->batteryCmdBuffer.msb = 0x80u;
570  }
572  break;
573  case MXM_INIT_AUXTIMEREG:
574  /* configure settling time that NTC network takes for measurement to 500us */
575  /* WARNING: reevaluate this value if thermistor supply is switched
576  during sampling */
577  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
579  pState->batteryCmdBuffer.lsb = 0x53u;
580  pState->batteryCmdBuffer.msb = 0x00u;
581  }
583  break;
584  case MXM_INIT_ACQCFG:
585  /* set ACQCFG */
586  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
588  /* default values */
589  pState->batteryCmdBuffer.lsb = 0x00u;
590  /* we have to turn thermistor switch manually on, as charging
591  the network takes to long */
592  pState->batteryCmdBuffer.msb = 0x06u;
593  }
595  break;
596  case MXM_INIT_UVTHSETREG:
597  /* configure UVTHSETREG */
598  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
602  &pState->batteryCmdBuffer.lsb,
603  &pState->batteryCmdBuffer.msb);
604  }
606  break;
607  case MXM_INIT_OVTHSETREG:
608  /* configure OVTHSETREG */
609  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
613  &pState->batteryCmdBuffer.lsb,
614  &pState->batteryCmdBuffer.msb);
615  }
617  break;
618  case MXM_INIT_BALEXP1:
619  /* set BALEXP1 to have 1 minute timeout in manual balancing */
620  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
622  pState->batteryCmdBuffer.lsb = 0x01u;
623  pState->batteryCmdBuffer.msb = 0x00u;
624  }
626  break;
627  case MXM_INIT_BALEXP2:
628  /* set BALEXP2 to have 1 minute timeout in manual balancing */
629  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
631  pState->batteryCmdBuffer.lsb = 0x01u;
632  pState->batteryCmdBuffer.msb = 0x00u;
633  }
635  break;
636  case MXM_INIT_BALEXP3:
637  /* set BALEXP3 to have 1 minute timeout in manual balancing */
638  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
640  pState->batteryCmdBuffer.lsb = 0x01u;
641  pState->batteryCmdBuffer.msb = 0x00u;
642  }
644  break;
645  case MXM_INIT_BALEXP4:
646  /* set BALEXP4 to have 1 minute timeout in manual balancing */
647  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
649  pState->batteryCmdBuffer.lsb = 0x01u;
650  pState->batteryCmdBuffer.msb = 0x00u;
651  }
653  break;
654  case MXM_INIT_BALEXP5:
655  /* set BALEXP5 to have 1 minute timeout in manual balancing */
656  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
658  pState->batteryCmdBuffer.lsb = 0x01u;
659  pState->batteryCmdBuffer.msb = 0x00u;
660  }
662  break;
663  case MXM_INIT_BALEXP6:
664  /* set BALEXP6 to have 1 minute timeout in manual balancing */
665  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
667  pState->batteryCmdBuffer.lsb = 0x01u;
668  pState->batteryCmdBuffer.msb = 0x00u;
669  }
671  break;
672  case MXM_INIT_BALEXP7:
673  /* set BALEXP7 to have 1 minute timeout in manual balancing */
674  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
676  pState->batteryCmdBuffer.lsb = 0x01u;
677  pState->batteryCmdBuffer.msb = 0x00u;
678  }
680  break;
681  case MXM_INIT_BALEXP8:
682  /* set BALEXP8 to have 1 minute timeout in manual balancing */
683  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
685  pState->batteryCmdBuffer.lsb = 0x01u;
686  pState->batteryCmdBuffer.msb = 0x00u;
687  }
689  break;
690  case MXM_INIT_BALEXP9:
691  /* set BALEXP9 to have 1 minute timeout in manual balancing */
692  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
694  pState->batteryCmdBuffer.lsb = 0x01u;
695  pState->batteryCmdBuffer.msb = 0x00u;
696  }
698  break;
699  case MXM_INIT_BALEXP10:
700  /* set BALEXP10 to have 1 minute timeout in manual balancing */
701  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
703  pState->batteryCmdBuffer.lsb = 0x01u;
704  pState->batteryCmdBuffer.msb = 0x00u;
705  }
707  break;
708  case MXM_INIT_BALEXP11:
709  /* set BALEXP11 to have 1 minute timeout in manual balancing */
710  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
712  pState->batteryCmdBuffer.lsb = 0x01u;
713  pState->batteryCmdBuffer.msb = 0x00u;
714  }
716  break;
717  case MXM_INIT_BALEXP12:
718  /* set BALEXP12 to have 1 minute timeout in manual balancing */
719  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
721  pState->batteryCmdBuffer.lsb = 0x01u;
722  pState->batteryCmdBuffer.msb = 0x00u;
723  }
725  break;
726  case MXM_INIT_BALEXP13:
727  /* set BALEXP13 to have 1 minute timeout in manual balancing */
728  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
730  pState->batteryCmdBuffer.lsb = 0x01u;
731  pState->batteryCmdBuffer.msb = 0x00u;
732  }
734  break;
735  case MXM_INIT_BALEXP14:
736  /* set BALEXP14 to have 1 minute timeout in manual balancing */
737  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
739  pState->batteryCmdBuffer.lsb = 0x01u;
740  pState->batteryCmdBuffer.msb = 0x00u;
741  }
743  break;
744  case MXM_INIT_BALSWDLY:
745  /* set BALSWDLY to 2 ms settling time after balancing */
746  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
748  /* CELLDLY = 1920us (~2ms) --> 20*96us
749  CELLDLY corresponds to the time to relax the cell before voltage measurement */
750  pState->batteryCmdBuffer.lsb = 0x00u;
751  pState->batteryCmdBuffer.msb = 0x14u;
752  }
754  break;
755  case MXM_INIT_ALRTOVEN:
756  /* enable ALRTOVEN */
757  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
759  pState->batteryCmdBuffer.lsb = 0xFFu;
760  pState->batteryCmdBuffer.msb = 0x3Fu;
761  }
763  break;
764  case MXM_INIT_ALRTUVEN:
765  /* enable ALRTUVEN */
766  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
768  pState->batteryCmdBuffer.lsb = 0xFFu;
769  pState->batteryCmdBuffer.msb = 0x3Fu;
770  }
772  break;
774  /* configure COMPOPNTHREG */
775  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
777  /* TODO 0.5V */
780  &pState->batteryCmdBuffer.lsb,
781  &pState->batteryCmdBuffer.msb);
782  }
784  break;
787  /* no additional handling needed */
788  }
789  break;
790  case MXM_INIT_I2C_CFG:
791  /* configure I2CCFG to
792  * 400kHz
793  * Alternate write Mode (just a pointer without data)
794  * Combined Format
795  * 7 Bit addressing
796  * one byte pointer length
797  * default
798  */
799  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
801  pState->batteryCmdBuffer.lsb = 0x00u;
802  pState->batteryCmdBuffer.msb = 0xE0u;
803  }
805  break;
806  case MXM_INIT_I2C_PNTR:
807  /* configure I2CPNTR */
808  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
810  pState->batteryCmdBuffer.lsb = 0x01u;
811  pState->batteryCmdBuffer.msb = 0x00u;
812  }
814  break;
816  /* send configuration to MUX0 for channel 0 (PNTR configured to 1u) */
817  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
819  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX0_ADDRESS << 1u);
820  pState->batteryCmdBuffer.msb = 0x40u;
821  }
823  break;
825  /* send configuration to MUX1 for channel 0 (PNTR configured to 1u) */
826  if (pState->requestStatus5x == MXM_5X_STATE_UNSENT) {
828  pState->batteryCmdBuffer.lsb = (MXM_I2C_MUX1_ADDRESS << 1u);
829  pState->batteryCmdBuffer.msb = 0x40u;
830  }
832  break;
835  /* no additional handling needed */
836  }
837  break;
838  default:
839  /* invalid state */
841  break;
842  }
843 }
844 
845 /*========== Externalized Static Function Implementations (Unit Test) =======*/
846 #ifdef UNITY_UNIT_TEST
847 
848 #endif
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:76
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:239
#define static_assert(cond, msg)
static assertion macro
Definition: fassert.h:254
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:110
@ STD_OK
Definition: fstd_types.h:81
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:75
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
#define MXM_I2C_MUX0_ADDRESS
address of MUX0
Definition: mxm_17852.c:73
#define MXM_I2C_MUX1_ADDRESS
address of MUX1
Definition: mxm_17852.c:75
#define MXM_BM_LSB
Monitoring Register LSB.
#define MXM_DELAY_BALANCING
Delay in milliseconds before the balancing status is updated.
Definition: mxm_17852.c:79
MXM_MODEL_ID_e MXM_GetModelIdOfDaisyChain(void)
returns the model ID of the daisy chain
Definition: mxm_17852.c:90
void MXM_StateMachineOperation(MXM_MONITORING_INSTANCE_s *pState)
State-Machine implementation for operation state.
Definition: mxm_17852.c:94
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:936
STD_RETURN_TYPE_e MXM_ProcessOpenWire(const MXM_MONITORING_INSTANCE_s *const kpkInstance)
Processes the retrieved information on openwire.
Definition: mxm_1785x.c:1006
bool must_check_return MXM_HandleStateReadall(MXM_MONITORING_INSTANCE_s *pInstance, MXM_REG_NAME_e registerName, MXM_STATEMACHINE_OPERATION_STATES_e nextState)
Handle the statemachine-transactions for a READALL.
Definition: mxm_1785x.c:975
STD_RETURN_TYPE_e MXM_ParseVoltagesIntoDB(const MXM_MONITORING_INSTANCE_s *const kpkInstance)
Copies measured voltage data into the database.
Definition: mxm_1785x.c:1109
STD_RETURN_TYPE_e MXM_ConstructBalancingBuffer(MXM_BALANCING_STATE_s *pBalancingInstance)
Fill the balancing datastructure.
Definition: mxm_1785x.c:1051
MXM_MONITORING_STATE_e 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:1275
void MXM_HandleStateWriteall(MXM_MONITORING_INSTANCE_s *pInstance, MXM_STATEMACHINE_OPERATION_STATES_e nextState)
Handle the statemachine-transactions for a WRITEALL.
Definition: mxm_1785x.c:947
Headers for the driver for the MAX17841B ASCI and MAX1785x monitoring chip.
#define MXM_REF_UNIPOLAR_CELL_mV
Definition: mxm_1785x.h:103
#define MXM_CELLS_IN_LSB
Definition: mxm_1785x.h:100
#define MXM_THRESHOLD_DIAGNOSTIC_AFTER_CYCLES
Battery monitoring driver for MAX1785x battery monitoring ICs.
Definition: mxm_1785x.h:94
#define MXM_VOLTAGE_READ_ARRAY_LENGTH
Definition: mxm_1785x.h:97
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_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_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_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 monitoring chip.
@ 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_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_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:118
void MXM_MonRegistryParseStatusFmeaIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse STATUS or FMEA into the registry.
Definition: mxm_registry.c:189
void MXM_MonRegistryParseVersionIntoDevices(MXM_MONITORING_INSTANCE_s *pState, uint8_t rxBufferLength)
Parse Version into the registry.
Definition: mxm_registry.c:149
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:233
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:114
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:129
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