foxBMS  1.5.0
The foxBMS Battery Management System API Documentation
mxm_battery_management.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_battery_management.c
44  * @author foxBMS Team
45  * @date 2019-01-14 (date of creation)
46  * @updated 2023-02-03 (date of last update)
47  * @version v1.5.0
48  * @ingroup DRIVERS
49  * @prefix MXM
50  *
51  * @brief Driver for the MAX17841B ASCI and MAX1785x analog front-end
52  *
53  * @details def
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "general.h"
59 
60 #include "mxm_battery_management.h"
61 
62 #include "diag.h"
63 #include "fassert.h"
64 #include "fstd_types.h"
65 #include "os.h"
66 
67 #include <stdbool.h>
68 #include <stdint.h>
69 
70 /*========== Macros and Definitions =========================================*/
71 
72 /** length of the helloall command @{*/
73 #define HELLOALL_TX_LENGTH (3u)
74 #define HELLOALL_RX_LENGTH HELLOALL_TX_LENGTH
75 /**@}*/
76 
77 /** threshold above which an error handling procedure is triggered */
78 #define MXM_5X_ERROR_THRESHOLD (3u)
79 
80 /** time in milliseconds that should be waited in order to ensure that the slaves shut off */
81 #define MXM_5X_SLAVE_SHUTDOWN_TIMEOUT_MS (400u)
82 
83 /** (uint8_t) one byte bit mask */
84 #define MXM_5X_BIT_MASK_ONE_BYTE (0xFFu)
85 
86 /**
87  * @brief bit masks for writing the device address in write device command
88  */
89 #define MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS ((uint16_t)0xF8u)
90 
91 /*========== Static Constant and Variable Definitions =======================*/
92 
93 /*========== Extern Constant and Variable Definitions =======================*/
94 
95 /*========== Static Function Prototypes =====================================*/
96 
97 /**
98  * @brief Clear the command-buffer.
99  * @details Clears #MXM_5X_INSTANCE_s::commandBuffer by writing 0x00 to every entry.
100  * @param[in,out] pInstance pointer to the state-struct
101  * @return always return #STD_OK
102  */
103 static void MXM_5XClearCommandBuffer(MXM_5X_INSTANCE_s *pInstance);
104 
105 /**
106  * @brief Check if a register address is user accessible
107  * @details Checks if a register address is inside the user accessible memory
108  * range. This range is specified in the data sheet of the monitoring
109  * IC as following:
110  * - user memory is contained in the range 0x00 to 0x98
111  * - reserved addresses in the user address space are:
112  * - 0x2C, 0x2D, 0x2E, 0x2F
113  * - 0x46
114  * - 0x84 through 0x8B
115  * @param[in] regAddress register address to be checked
116  * @param[in] model model id of the IC that shall be addressed
117  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
118  */
119 static STD_RETURN_TYPE_e MXM_5XIsUserAccessibleRegister(uint8_t regAddress, MXM_MODEL_ID_e model);
120 
121 /**
122  * @brief Check if a register address is user accessible in MAX17852
123  * @details Checks if a register address is inside the user accessible memory
124  * range.
125  * This range is specified in the data sheet of the monitoring IC.
126  * @param[in] regAddress register address to be checked
127  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
128  */
129 static STD_RETURN_TYPE_e MXM_52IsUserAccessibleRegister(uint8_t regAddress);
130 
131 /**
132  * @brief Check if a register address is user accessible in MAX17853
133  * @details Checks if a register address is inside the user accessible memory
134  * range.
135  * This range is specified in the data sheet of the monitoring IC as
136  * the following:
137  * - user memory is contained in the range 0x00 to 0x98
138  * - reserved addresses in the user address space are:
139  * - 0x2C, 0x2D, 0x2E, 0x2F
140  * - 0x46
141  * - 0x84 through 0x8B
142  * @param[in] regAddress register address to be checked
143  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
144  */
145 static STD_RETURN_TYPE_e MXM_53IsUserAccessibleRegister(uint8_t regAddress);
146 
147 /**
148  * @brief clears the command buffer and writes HELLOALL into the buffer
149  * @details Fills the command buffer with a HELLOALL message after having it
150  * cleaned.
151  * @param[in,out] pInstance pointer to the state-struct
152  */
154 
155 /**
156  * @brief clears the command buffer and writes WRITEALL into the buffer
157  * @details Fills the command buffer with a WRITEALL command. This command
158  * writes the same lsb and msb to every satellite in the daisy-chain
159  * in the same register. The data to be written has to be set before
160  * calling this function in #MXM_5X_INSTANCE_s::commandPayload.
161  * @param[in,out] pInstance pointer to the state-struct
162  * @return #STD_OK if an accessible register address has been selected,
163  * #STD_NOT_OK if not.
164  */
166 
167 /**
168  * @brief clears the command buffer and writes a WRITEDEVICE message
169  * @details Fills the command buffer with a WRITEDEVICE message. This message
170  * is addressed to one specific device in the daisy-chain. Therefore
171  * the address of the device has to be supplied together with the
172  * register and the data that should be written. The data to be
173  * written has to be set before calling this function in
174  * #MXM_5X_INSTANCE_s::commandPayload.
175  * @param[in,out] pInstance pointer to the state-struct
176  * @return #STD_OK if an accessible register address has been selected,
177  * #STD_NOT_OK if not.
178  */
180 
181 /**
182  * @brief clears the command buffer and writes READALL into the buffer
183  * @details Fills the command buffer with a READALL command. This command
184  * retrieves the LSB and MSB of exactly one register of every device
185  * in the daisy-chain. The data to be written has to be set before
186  * calling this function in #MXM_5X_INSTANCE_s::commandPayload.
187  * @param[in,out] pInstance pointer to the state-struct
188  * @return #STD_OK if an accessible register address has been selected,
189  * #STD_NOT_OK if not.
190  */
192 
193 /**
194  * @brief handles the error of the underlying state-machine (by resetting it and counting the error)
195  * @param[in,out] pInstance pointer to the state-struct
196  */
197 static void MXM_5XHandle41BErrorState(MXM_5X_INSTANCE_s *pInstance);
198 
199 /**
200  * @brief sets all internal state variables so that upon next execution the next substate is entered
201  * @param[out] pInstance pointer to the state-struct
202  * @param[in] substate identifier of the next substate
203  */
204 static void MXM_5XTransitionToSubstate(MXM_5X_INSTANCE_s *pInstance, MXM_5X_SUBSTATES_e substate);
205 
206 /**
207  * @brief repeat the current substate (by resetting to the entry state)
208  * @param[out] pInstance pointer to the state-struct
209  */
210 static void MXM_5XRepeatCurrentSubstate(MXM_5X_INSTANCE_s *pInstance);
211 
212 /**
213  * @brief Signal that a chain of substates has been successfully handled
214  * @param[out] pInstance pointer to the state-struct
215  */
216 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance);
217 
218 /**
219  * @brief Signal that an error has occurred in a chain of substates
220  * @param[out] pInstance pointer to the state-struct
221  */
222 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance);
223 
224 /**
225  * @brief Handle the state #MXM_STATEMACH_5X_41B_FMEA_CHECK
226  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
227  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
228  */
229 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
230 
231 /**
232  * @brief Handle the state #MXM_STATEMACH_5X_INIT
233  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
234  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
235  */
236 static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
237 
238 /**
239  * @brief Handle the states #MXM_STATEMACH_5X_WRITEALL and #MXM_STATEMACH_5X_WRITE_DEVICE
240  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
241  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
242  * @param[in] writeDevice true: write device, false: write all
243  */
244 static void MXM_5XStateHandlerWrite(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b, bool writeDevice);
245 
246 /**
247  * @brief Handle the state #MXM_STATEMACH_5X_READALL
248  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
249  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
250  */
251 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
252 
253 /*========== Static Function Implementations ================================*/
255  FAS_ASSERT(pInstance != NULL_PTR);
256  for (uint8_t i = 0; i < COMMAND_BUFFER_LENGTH; i++) {
257  pInstance->commandBuffer[i] = 0x00U;
258  }
260 }
261 
264  /* AXIVION Routine Generic-MissingParameterAssert: regAddress: parameter accepts whole range */
265 
266  STD_RETURN_TYPE_e retval = STD_NOT_OK;
267 
268  switch (model) {
270  retval = MXM_52IsUserAccessibleRegister(regAddress);
271  break;
273  retval = MXM_53IsUserAccessibleRegister(regAddress);
274  break;
276  case MXM_MODEL_ID_NONE:
278  /* not implemented or invalid model id */
279  break;
280  default:
281  /* invalid state, should not happen */
283  break;
284  }
285  return retval;
286 }
287 
289  /* AXIVION Routine Generic-MissingParameterAssert: regAddress: parameter accepts whole range */
290 
291  STD_RETURN_TYPE_e retval = STD_NOT_OK;
292  /* check if regAddress is outside user-accessible area */
293  /* AXIVION Disable Style Generic-NoMagicNumbers: memory limits of ICs are specific and unchangeable, therefore hardcoded */
294  bool registerAddressIsInvalid = (regAddress == 0x5Du);
295  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress == 0x5Eu);
296  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress > 0x98u);
297  /* AXIVION Enable Style Generic-NoMagicNumbers: */
298 
299  if (registerAddressIsInvalid == false) {
300  /* valid MAX17852 register address */
301  retval = STD_OK;
302  }
303  return retval;
304 }
305 
307  STD_RETURN_TYPE_e retval = STD_NOT_OK;
308  /* check if regAddress is outside user-accessible area */
309  /* AXIVION Disable Style Generic-NoMagicNumbers: memory limits of ICs are specific and unchangeable, therefore hardcoded */
310  bool registerAddressIsInvalid = (regAddress == 0x46u);
311  registerAddressIsInvalid = registerAddressIsInvalid || ((0x2Cu <= regAddress) && (regAddress <= 0x2Fu));
312  registerAddressIsInvalid = registerAddressIsInvalid || ((0x84u <= regAddress) && (regAddress <= 0x8Bu));
313  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress > 0x98u);
314  /* AXIVION Enable Style Generic-NoMagicNumbers: */
315 
316  if (registerAddressIsInvalid == false) {
317  /* valid MAX17853 register address */
318  retval = STD_OK;
319  }
320  return retval;
321 }
322 
324  FAS_ASSERT(pInstance != NULL_PTR);
325  MXM_5XClearCommandBuffer(pInstance);
327  pInstance->commandBuffer[1] = 0x00;
328  pInstance->commandBuffer[2] = HELLOALL_START_SEED;
329  pInstance->commandBufferCurrentLength = 3;
330 }
331 
333  FAS_ASSERT(pInstance != NULL_PTR);
334  STD_RETURN_TYPE_e retval = STD_NOT_OK;
335 
336  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
337  FAS_ASSERT(pPayload != NULL_PTR);
338 
339  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
340  /* clear command buffer */
341  MXM_5XClearCommandBuffer(pInstance);
342 
343  /* construct command buffer */
345  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
346  pInstance->commandBuffer[2] = pPayload->lsb;
347  pInstance->commandBuffer[3] = pPayload->msb;
348  /* PEC byte */
349  pInstance->commandBuffer[4] = MXM_CRC8(pInstance->commandBuffer, 4);
350  /* TODO alive-counter? */
351  pInstance->commandBufferCurrentLength = 5;
352  retval = STD_OK;
353  }
354 
355  return retval;
356 }
357 
359  FAS_ASSERT(pInstance != NULL_PTR);
360  STD_RETURN_TYPE_e retval = STD_NOT_OK;
361 
362  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
363  FAS_ASSERT(pPayload != NULL_PTR);
364 
365  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
366  /* clear command buffer */
367  MXM_5XClearCommandBuffer(pInstance);
368 
369  /* construct command buffer */
370 
371  /* commandBuffer[0] = Device address in a daisy chain + 0b100
372  * DA = deviceAddress
373  * Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
374  * Content | DA[4] | DA[3] | DA[2] | DA[1] | DA[0] | 1 | 0 | 0
375  */
376  pInstance->commandBuffer[0] =
377  ((((uint16_t)pPayload->deviceAddress << 3u) & MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS) |
379  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
380  pInstance->commandBuffer[2] = pPayload->lsb;
381  pInstance->commandBuffer[3] = pPayload->msb;
382  /* PEC byte */
383  pInstance->commandBuffer[4] = MXM_CRC8(pInstance->commandBuffer, 4);
384  /* TODO alive-counter? */
385  pInstance->commandBufferCurrentLength = 5;
386  retval = STD_OK;
387  }
388 
389  return retval;
390 }
391 
393  FAS_ASSERT(pInstance != NULL_PTR);
394  STD_RETURN_TYPE_e retval = STD_NOT_OK;
395  /* TODO test these functions */
396 
397  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
398  FAS_ASSERT(pPayload != NULL_PTR);
399 
400  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
401  /* clear command buffer */
402  MXM_5XClearCommandBuffer(pInstance);
403 
404  /* construct command buffer */
406  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
407  pInstance->commandBuffer[2] = DATA_CHECK_BYTE_SEED;
408  /* PEC byte */
409  pInstance->commandBuffer[3] = MXM_CRC8(pInstance->commandBuffer, 3);
410  /* TODO alive-counter? */
411  pInstance->commandBufferCurrentLength = 4;
412  retval = STD_OK;
413  }
414 
416  /* define containing command buffer length does
417  * not match actual buffer */
418  retval = STD_NOT_OK;
419  }
420 
421  return retval;
422 }
423 
425  FAS_ASSERT(pInstance != NULL_PTR);
426  pInstance->status41b = MXM_41B_STATE_UNSENT;
427  if (pInstance->errorCounter < (uint8_t)UINT8_MAX) {
428  pInstance->errorCounter++;
429  }
430  return;
431 }
432 
434  FAS_ASSERT(pInstance != NULL_PTR);
435  FAS_ASSERT(substate <= MXM_5X_ENTRY_SUBSTATE);
436  pInstance->substate = substate;
437  if ((pInstance->status41b == MXM_41B_STATE_PROCESSED) || (pInstance->status41b == MXM_41B_STATE_ERROR)) {
438  pInstance->status41b = MXM_41B_STATE_UNSENT;
439  }
440  return;
441 }
442 
444  FAS_ASSERT(pInstance != NULL_PTR);
445  pInstance->status41b = MXM_41B_STATE_UNSENT;
446  return;
447 }
448 
449 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance) {
450  FAS_ASSERT(pInstance != NULL_PTR);
452  FAS_ASSERT(pInstance->processed != NULL_PTR);
453  *pInstance->processed = MXM_5X_STATE_PROCESSED;
454  pInstance->state = MXM_STATEMACH_5X_IDLE;
455  return;
456 }
457 
458 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance) {
459  FAS_ASSERT(pInstance != NULL_PTR);
461  FAS_ASSERT(pInstance->processed != NULL_PTR);
462  *pInstance->processed = MXM_5X_STATE_ERROR;
463  pInstance->state = MXM_STATEMACH_5X_IDLE;
464  return;
465 }
466 
467 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
468  FAS_ASSERT(pInstance5x != NULL_PTR);
469  FAS_ASSERT(pInstance41b != NULL_PTR);
470  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
471  /* entry of state --> set to first substate */
473  }
474 
475  if (pInstance5x->substate == MXM_5X_41B_FMEA_REQUEST) {
476  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
477  pInstance41b, MXM_STATEMACH_41B_CHECK_FMEA, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
478  FAS_ASSERT(stateRequestReturn == STD_OK);
480  } else if (pInstance5x->substate == MXM_5X_41B_FMEA_CHECK) {
481  if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
482  /* wait for processing */
483  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
484  /* failure in FMEA; signal error */
485  MXM_5XSignalError(pInstance5x);
486  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
487  MXM_5XSignalSuccess(pInstance5x);
488  } else {
490  }
491  } else {
493  }
494 }
495 
496 static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
497  FAS_ASSERT(pInstance5x != NULL_PTR);
498  FAS_ASSERT(pInstance41b != NULL_PTR);
499  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
500  /* entry of state --> set to first substate */
502  }
503 
504  if (pInstance5x->substate == MXM_5X_INIT_41B_INIT) {
505  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
506  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
507  pInstance41b, MXM_STATEMACH_41B_INIT, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
508  FAS_ASSERT(stateRequestReturn == STD_OK);
509  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
510  /* wait for processing */
511  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
512  MXM_5XHandle41BErrorState(pInstance5x);
513  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
515  pInstance5x->resetWaitTimestamp = OS_GetTickCount();
516  } else {
518  }
519  } else if (pInstance5x->substate == MXM_5X_INIT_41B_GET_VERSION) {
520  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
521  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
522  pInstance41b, MXM_STATEMACH_41B_GET_VERSION, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
523  FAS_ASSERT(stateRequestReturn == STD_OK);
524  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
525  /* wait for processing */
526  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
527  MXM_5XHandle41BErrorState(pInstance5x);
528  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
530  } else {
532  }
533  } else if (pInstance5x->substate == MXM_5X_INIT_WAIT_FOR_RESET) {
534  /* wait so that shutdown low of the satellites discharges and they switch off */
535  const bool shutdownTimeoutHasPassed =
537  if (shutdownTimeoutHasPassed) {
539  }
540  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_RX_INTERRUPT_FLAGS) {
541  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
542  const STD_RETURN_TYPE_e writeRegisterRxErrorReturn =
544  FAS_ASSERT(writeRegisterRxErrorReturn == STD_OK);
545  const STD_RETURN_TYPE_e writeRegisterRxOverflowReturn =
547  FAS_ASSERT(writeRegisterRxOverflowReturn == STD_OK);
548 
549  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
550  pInstance41b,
552  NULL_PTR,
553  0,
554  0,
555  NULL_PTR,
556  0,
557  &pInstance5x->status41b);
558  FAS_ASSERT(stateRequestReturn == STD_OK);
559  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
560  /* wait for processing */
561  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
562  MXM_5XHandle41BErrorState(pInstance5x);
563  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
565  } else {
567  }
569  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
570  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
571  pInstance41b,
573  NULL_PTR,
574  0,
575  0,
576  NULL_PTR,
577  0,
578  &pInstance5x->status41b);
579  FAS_ASSERT(stateRequestReturn == STD_OK);
580  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
581  /* wait for processing */
582  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
583  MXM_5XHandle41BErrorState(pInstance5x);
584  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
586  } else {
588  }
590  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
591  const STD_RETURN_TYPE_e writeRegisterReturn =
593  FAS_ASSERT(writeRegisterReturn == STD_OK);
594 
595  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
596  pInstance41b,
598  NULL_PTR,
599  0,
600  0,
601  NULL_PTR,
602  0,
603  &pInstance5x->status41b);
604  FAS_ASSERT(stateRequestReturn == STD_OK);
605  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
606  /* wait for processing */
607  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
608  MXM_5XHandle41BErrorState(pInstance5x);
609  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
611  } else {
613  }
614  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_KEEP_ALIVE) {
615  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
616  const uint8_t mxm_kConfig3KeepAlive160us41BRegister = 0x05;
617  const STD_RETURN_TYPE_e writeRegisterReturn = MXM_41BWriteRegisterFunction(
618  pInstance41b, MXM_41B_REG_FUNCTION_KEEP_ALIVE, mxm_kConfig3KeepAlive160us41BRegister);
619  FAS_ASSERT(writeRegisterReturn == STD_OK);
620 
621  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
622  pInstance41b,
624  NULL_PTR,
625  0,
626  0,
627  NULL_PTR,
628  0,
629  &pInstance5x->status41b);
630  FAS_ASSERT(stateRequestReturn == STD_OK);
631  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
632  /* wait for processing */
633  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
634  MXM_5XHandle41BErrorState(pInstance5x);
635  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
637  } else {
639  }
641  /* wait for rx status change busy */
642  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
643  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
644  pInstance41b,
646  NULL_PTR,
647  0,
648  0,
649  NULL_PTR,
650  0,
651  &pInstance5x->status41b);
652  FAS_ASSERT(stateRequestReturn == STD_OK);
653  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
654  /* wait for processing */
655  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
656  MXM_5XHandle41BErrorState(pInstance5x);
657  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
658  MXM_41B_REG_BIT_VALUE functionValue;
659  const STD_RETURN_TYPE_e readRegisterReturn =
661  FAS_ASSERT(readRegisterReturn == STD_OK);
662  if (functionValue == MXM_41B_REG_FALSE) {
663  MXM_5XRepeatCurrentSubstate(pInstance5x);
664  } else if (functionValue == MXM_41B_REG_TRUE) {
666  } else {
668  }
669  } else {
671  }
673  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
674  const STD_RETURN_TYPE_e writeRegisterReturn =
676  FAS_ASSERT(writeRegisterReturn == STD_OK);
677 
678  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
679  pInstance41b,
681  NULL_PTR,
682  0,
683  0,
684  NULL_PTR,
685  0,
686  &pInstance5x->status41b);
687  FAS_ASSERT(stateRequestReturn == STD_OK);
688  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
689  /* wait for processing */
690  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
691  MXM_5XHandle41BErrorState(pInstance5x);
692  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
694  } else {
696  }
698  /* wait for rx status change busy */
699  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
700  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
701  pInstance41b,
703  NULL_PTR,
704  0,
705  0,
706  NULL_PTR,
707  0,
708  &pInstance5x->status41b);
709  FAS_ASSERT(stateRequestReturn == STD_OK);
710  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
711  /* wait for processing */
712  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
713  MXM_5XHandle41BErrorState(pInstance5x);
714  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
715  MXM_41B_REG_BIT_VALUE functionValue;
716  const STD_RETURN_TYPE_e readRegisterReturn =
718  FAS_ASSERT(readRegisterReturn == STD_OK);
719 
720  if (functionValue == MXM_41B_REG_TRUE) {
721  MXM_5XRepeatCurrentSubstate(pInstance5x);
722  } else if (functionValue == MXM_41B_REG_FALSE) {
724  } else {
726  }
727  } else {
729  }
731  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
732  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
733  pInstance41b,
735  NULL_PTR,
736  0,
737  0,
738  NULL_PTR,
739  0,
740  &pInstance5x->status41b);
741  FAS_ASSERT(stateRequestReturn == STD_OK);
742  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
743  /* wait for processing */
744  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
745  MXM_5XHandle41BErrorState(pInstance5x);
746  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
748  } else {
750  }
752  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
753  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
754  pInstance41b,
756  NULL_PTR,
757  0,
758  0,
759  NULL_PTR,
760  0,
761  &pInstance5x->status41b);
762  FAS_ASSERT(stateRequestReturn == STD_OK);
763  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
764  /* wait for processing */
765  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
766  MXM_5XHandle41BErrorState(pInstance5x);
767  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
769  } else {
771  }
772  } else if (pInstance5x->substate == MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_HELLOALL) {
773  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
775  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
776  pInstance41b,
778  pInstance5x->commandBuffer,
779  pInstance5x->commandBufferCurrentLength,
780  0,
781  pInstance5x->rxBuffer,
783  &pInstance5x->status41b);
784  FAS_ASSERT(stateRequestReturn == STD_OK);
785  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
786  /* wait for processing */
787  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
788  MXM_5XHandle41BErrorState(pInstance5x);
789  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
791  } else {
793  }
794  /* TODO check for receive buffer errors and handle */
796  /* check if the commandBuffer matches with the receive buffer */
797  STD_RETURN_TYPE_e commandBufferMatchesReceiveBuffer = STD_OK;
798  for (uint8_t i = 0u; i < (pInstance5x->commandBufferCurrentLength - 1u); i++) {
799  if (pInstance5x->commandBuffer[i] != pInstance5x->rxBuffer[i]) {
800  commandBufferMatchesReceiveBuffer = STD_NOT_OK;
801  }
802  }
803  /* update number of satellites */
804  pInstance5x->numberOfSatellites =
805  (uint8_t)((pInstance5x->rxBuffer[HELLOALL_RX_LENGTH - 1u] - HELLOALL_START_SEED) & MXM_5X_BIT_MASK_ONE_BYTE);
806 
807  /* Plausibility check, compare with preset number of satellites */
809  pInstance5x->numberOfSatellitesIsGood = STD_OK;
810  }
811 
812  if (commandBufferMatchesReceiveBuffer == STD_NOT_OK) {
813  /* TODO error handling */
814  } else {
815  MXM_5XSignalSuccess(pInstance5x);
816  }
817  } else {
818  /* something is very broken */
820  }
821 }
822 
824  MXM_5X_INSTANCE_s *pInstance5x,
825  MXM_41B_INSTANCE_s *pInstance41b,
826  bool writeDevice) {
827  FAS_ASSERT(pInstance5x != NULL_PTR);
828  FAS_ASSERT(pInstance41b != NULL_PTR);
829  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
830  /* entry of state --> set to first substate */
832  }
833 
834  if (pInstance5x->substate == MXM_5X_WRITE_UART_TRANSACTION) {
835  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
836  if (writeDevice == true) {
837  /* write device: call function for write device buffer */
838  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteDevice(pInstance5x);
839  FAS_ASSERT(resultAddressCorrect == STD_OK);
840  } else {
841  /* write all: call function for write all buffer */
842  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteall(pInstance5x);
843  FAS_ASSERT(resultAddressCorrect == STD_OK);
844  }
845 
846  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
847  pInstance41b,
849  pInstance5x->commandBuffer,
850  pInstance5x->commandBufferCurrentLength,
851  0,
852  pInstance5x->rxBuffer,
853  pInstance5x->commandBufferCurrentLength,
854  &pInstance5x->status41b);
855  FAS_ASSERT(stateRequestReturn == STD_OK);
856  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
857  /* wait for processing */
858  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
859  MXM_5XHandle41BErrorState(pInstance5x);
860  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
861  MXM_5XSignalSuccess(pInstance5x); /* TODO continue and check CRC */
862  } else {
864  }
865  }
866 }
867 
868 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
869  FAS_ASSERT(pInstance5x != NULL_PTR);
870  FAS_ASSERT(pInstance41b != NULL_PTR);
871  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
872  /* entry of state --> set to first substate */
874  }
875 
876  if (pInstance5x->substate == MXM_5X_READALL_UART_TRANSACTION) {
877  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
878  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferReadall(pInstance5x);
879  FAS_ASSERT(resultAddressCorrect == STD_OK);
880  /* TODO parse rx buffer here into values and parse CRC before passing on*/
881  /* stretch message length in order to accommodate 2 bytes per satellite */
882  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
883  pInstance41b,
885  pInstance5x->commandBuffer,
886  pInstance5x->commandBufferCurrentLength,
887  2u * pInstance5x->numberOfSatellites,
888  pInstance5x->rxBuffer,
890  &pInstance5x->status41b);
891  FAS_ASSERT(stateRequestReturn == STD_OK);
892  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
893  /* wait for processing */
894  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
895  MXM_5XHandle41BErrorState(pInstance5x);
896  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
898  } else {
900  }
901  } else if (pInstance5x->substate == MXM_5X_READALL_CHECK_CRC) {
902  /* check CRC */
903  if (MXM_CRC8(
904  pInstance5x->rxBuffer,
905  ((int32_t)pInstance5x->commandBufferCurrentLength + (2 * (int32_t)pInstance5x->numberOfSatellites))) ==
906  0x00u) {
907  /* currently only one physical string is supported, therefore reporting always to string 0 */
910  } else {
911  /* currently only one physical string is supported, therefore reporting always to string 0 */
913  MXM_5XSignalError(pInstance5x);
914  }
915  } else if (pInstance5x->substate == MXM_5X_READALL_GET_DC) {
916  /* get DC */ /* TODO check DC in this state */
917  /* dc byte position is after data */
918  FAS_ASSERT(((uint16_t)2u + ((uint16_t)2u * pInstance5x->numberOfSatellites)) <= (uint16_t)UINT8_MAX);
919  uint8_t dc_byte_position = 2u + (2u * pInstance5x->numberOfSatellites);
920 
921  pInstance5x->lastDCByte = (uint8_t)(pInstance5x->rxBuffer[dc_byte_position] & MXM_5X_BIT_MASK_ONE_BYTE);
922 
923  MXM_5XSignalSuccess(pInstance5x);
924  } else {
926  }
927 }
928 
929 /*========== Extern Function Implementations ================================*/
930 
932  FAS_ASSERT(pInstance != NULL_PTR);
933 
935  pInstance->substate = MXM_5X_ENTRY_SUBSTATE;
937  pInstance->commandPayload.lsb = 0u;
938  pInstance->commandPayload.msb = 0u;
939  pInstance->commandPayload.blocksize = 0u;
940  pInstance->commandPayload.deviceAddress = 0u;
941  pInstance->processed = NULL_PTR;
942  pInstance->status41b = MXM_41B_STATE_UNSENT;
943  pInstance->numberOfSatellites = 0u;
945  pInstance->lastDCByte = 0u;
946  pInstance->errorCounter = 0u;
947  pInstance->resetWaitTimestamp = 0u;
948  pInstance->commandBufferCurrentLength = 0u;
949 
950  for (uint32_t i = 0u; i < COMMAND_BUFFER_LENGTH; i++) {
951  pInstance->commandBuffer[i] = 0u;
952  }
953 
954  for (uint32_t i = 0u; i < MXM_5X_RX_BUFFER_LEN; i++) {
955  pInstance->rxBuffer[i] = 0u;
956  }
957 }
958 
960  const MXM_5X_INSTANCE_s *const kpkInstance,
961  uint8_t *rxBuffer,
962  uint16_t rxBufferLength) {
963  FAS_ASSERT(kpkInstance != NULL_PTR);
964  FAS_ASSERT(rxBufferLength <= MXM_5X_RX_BUFFER_LEN);
965  /* AXIVION Routine Generic-MissingParameterAssert: rxBuffer: pointer may be NULL */
966 
967  STD_RETURN_TYPE_e retval = STD_OK;
968 
969  if ((rxBuffer != NULL_PTR) && (rxBufferLength != 0u)) {
970  for (uint16_t i = 0; i < rxBufferLength; i++) {
971  if (i < MXM_5X_RX_BUFFER_LEN) {
972  rxBuffer[i] = (uint8_t)(kpkInstance->rxBuffer[i] & MXM_5X_BIT_MASK_ONE_BYTE);
973  }
974  }
975  } else {
976  retval = STD_NOT_OK;
977  }
978 
979  return retval;
980 }
981 
982 extern MXM_DC_BYTE_e MXM_5XGetLastDCByte(const MXM_5X_INSTANCE_s *const kpkInstance) {
983  FAS_ASSERT(kpkInstance != NULL_PTR);
984  return (MXM_DC_BYTE_e)kpkInstance->lastDCByte;
985 }
986 
987 extern uint8_t MXM_5XGetNumberOfSatellites(const MXM_5X_INSTANCE_s *const kpkInstance) {
988  FAS_ASSERT(kpkInstance != NULL_PTR);
989  const uint8_t numberOfSatellites = kpkInstance->numberOfSatellites;
990  FAS_ASSERT(numberOfSatellites <= MXM_MAXIMUM_NR_OF_MODULES);
991  return numberOfSatellites;
992 }
993 
995  FAS_ASSERT(kpkInstance != NULL_PTR);
996  return kpkInstance->numberOfSatellitesIsGood;
997 }
998 
1000  MXM_5X_INSTANCE_s *pInstance5x,
1001  MXM_STATEMACHINE_5X_e state,
1002  MXM_5X_COMMAND_PAYLOAD_s commandPayload,
1003  MXM_5X_STATE_REQUEST_STATUS_e *processed) {
1004  FAS_ASSERT(pInstance5x != NULL_PTR);
1005  /* AXIVION Routine Generic-MissingParameterAssert: state: parameter accepts whole range */
1006  /* AXIVION Routine Generic-MissingParameterAssert: commandPayload: parameter accepts whole range */
1007  /* AXIVION Routine Generic-MissingParameterAssert: processed: pointer may be NULL */
1008 
1009  STD_RETURN_TYPE_e retval = STD_OK;
1010  if (state >= MXM_STATEMACH_5X_MAXSTATE) {
1011  retval = STD_NOT_OK;
1012  } else if (processed == NULL_PTR) {
1013  retval = STD_NOT_OK;
1014  } else if (pInstance5x->state == MXM_STATEMACH_5X_UNINITIALIZED) {
1015  if (state == MXM_STATEMACH_5X_INIT) {
1016  pInstance5x->state = state;
1017  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1018  pInstance5x->commandPayload = commandPayload;
1019  pInstance5x->processed = processed;
1020  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1021  } else {
1022  retval = STD_NOT_OK;
1023  }
1024  } else if (pInstance5x->state == MXM_STATEMACH_5X_IDLE) {
1025  pInstance5x->state = state;
1026  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1027  pInstance5x->commandPayload = commandPayload;
1028  pInstance5x->processed = processed;
1029  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1030  } else {
1031  retval = STD_NOT_OK;
1032  }
1033  return retval;
1034 }
1035 
1036 void MXM_5XStateMachine(MXM_41B_INSTANCE_s *pInstance41b, MXM_5X_INSTANCE_s *pInstance5x) {
1037  FAS_ASSERT(pInstance41b != NULL_PTR);
1038  FAS_ASSERT(pInstance5x != NULL_PTR);
1039 
1040  /* failure handling */
1041  if (pInstance5x->errorCounter > MXM_5X_ERROR_THRESHOLD) {
1042  /* error, reset both this state-machine and the underlying */
1043  pInstance41b->state = MXM_STATEMACH_41B_IDLE;
1044  pInstance41b->substate = MXM_41B_ENTRY_SUBSTATE;
1045  pInstance41b->waitCounter = 0u;
1046  MXM_5XSignalError(pInstance5x);
1047  pInstance5x->errorCounter = 0u;
1048  }
1049 
1050  switch (pInstance5x->state) {
1052  /* statemachine waits here for initialization */
1053  break;
1054  case MXM_STATEMACH_5X_IDLE:
1055  /* idle state currently does nothing */
1056  break;
1058  MXM_5XStateHandler41BFmeaCheck(pInstance5x, pInstance41b);
1059  break;
1060  case MXM_STATEMACH_5X_INIT:
1061  MXM_5XStateHandlerInit(pInstance5x, pInstance41b);
1062  break;
1064  MXM_5XStateHandlerWrite(pInstance5x, pInstance41b, false);
1065  break;
1067  MXM_5XStateHandlerWrite(pInstance5x, pInstance41b, true);
1068  break;
1070  MXM_5XStateHandlerReadAll(pInstance5x, pInstance41b);
1071  break;
1072  default:
1074  break; /* LCOV_EXCL_LINE */
1075  }
1076 }
1077 
1079  /* check:
1080  * - user memory is contained in range 0x00 to 0x98
1081  * - reserved addresses in user address space:
1082  * 0x2C, 0x2D, 0x2E, 0x2F, 0x46 and 0x84 through 0x8B */
1083 
1084  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
1085  /* expected #STD_OK */
1089 
1093 
1097 
1098  /* expected #STD_NOT_OK */
1105 
1109 
1110  /* AXIVION Enable Style Generic-NoMagicNumbers: */
1111 
1112  STD_RETURN_TYPE_e retval = STD_NOT_OK;
1113 
1114  if ((retval_check0 == STD_OK) && (retval_check1 == STD_OK) && (retval_check2 == STD_OK) &&
1115  (retval_check3 == STD_OK) && (retval_check4 == STD_OK) && (retval_check5 == STD_OK) &&
1116  (retval_check6 == STD_OK) && (retval_check7 == STD_OK) && (retval_check8 == STD_OK) &&
1117  (retval_check9 == STD_NOT_OK) && (retval_check10 == STD_NOT_OK) && (retval_check11 == STD_NOT_OK) &&
1118  (retval_check12 == STD_NOT_OK) && (retval_check13 == STD_NOT_OK) && (retval_check14 == STD_NOT_OK) &&
1119  (retval_check15 == STD_NOT_OK) && (retval_check16 == STD_NOT_OK) && (retval_check17 == STD_NOT_OK)) {
1120  retval = STD_OK;
1121  }
1122  return retval;
1123 }
1124 
1125 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1126 #ifdef UNITY_UNIT_TEST
1127 #endif
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
#define BS_NR_OF_MODULES_PER_STRING
number of modules in a string
STD_RETURN_TYPE_e DIAG_CheckEvent(STD_RETURN_TYPE_e cond, DIAG_ID_e diagId, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_CheckEvent provides a simple interface to check an event for STD_OK.
Definition: diag.c:374
Diagnosis driver header.
@ DIAG_STRING
Definition: diag_cfg.h:279
@ DIAG_ID_AFE_COM_INTEGRITY
Definition: diag_cfg.h:181
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:254
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
General macros and definitions for the whole platform.
#define GEN_MUST_CHECK_RETURN
Allows functions to generate warnings in GCC for unused returns.
Definition: general.h:87
STD_RETURN_TYPE_e MXM_41BSetStateRequest(MXM_41B_INSTANCE_s *pInstance, MXM_STATEMACH_41B_e state, uint16_t *pPayload, uint8_t payloadLength, uint8_t extendMessageBytes, uint16_t *pRxBuffer, uint16_t rxBufferLength, MXM_41B_STATE_REQUEST_STATUS_e *processed)
Set state transition for MAX17841B-state-machine.
Definition: mxm_17841b.c:788
STD_RETURN_TYPE_e MXM_41BWriteRegisterFunction(MXM_41B_INSTANCE_s *pInstance, MXM_41B_REG_FUNCTION_e registerFunction, MXM_41B_REG_BIT_VALUE value)
Write a register function.
Definition: mxm_17841b.c:850
STD_RETURN_TYPE_e MXM_41BReadRegisterFunction(const MXM_41B_INSTANCE_s *const kpkInstance, MXM_41B_REG_FUNCTION_e registerFunction, MXM_41B_REG_BIT_VALUE *pValue)
Read the value of a register function.
Definition: mxm_17841b.c:896
@ MXM_STATEMACH_41B_GET_VERSION
Definition: mxm_17841b.h:92
@ MXM_STATEMACH_41B_CLEAR_RECEIVE_BUFFER
Definition: mxm_17841b.h:96
@ MXM_STATEMACH_41B_CLEAR_TRANSMIT_BUFFER
Definition: mxm_17841b.h:97
@ MXM_STATEMACH_41B_INIT
Definition: mxm_17841b.h:89
@ MXM_STATEMACH_41B_WRITE_CONF_AND_INT_REGISTER
Definition: mxm_17841b.h:93
@ MXM_STATEMACH_41B_CHECK_FMEA
Definition: mxm_17841b.h:91
@ MXM_STATEMACH_41B_READ_STATUS_REGISTER
Definition: mxm_17841b.h:94
@ MXM_STATEMACH_41B_IDLE
Definition: mxm_17841b.h:90
@ MXM_STATEMACH_41B_UART_TRANSACTION
Definition: mxm_17841b.h:95
@ MXM_41B_ENTRY_SUBSTATE
Definition: mxm_17841b.h:105
@ MXM_41B_REG_FUNCTION_RX_BUSY_STATUS
Definition: mxm_17841b.h:145
@ MXM_41B_REG_FUNCTION_RX_EMPTY_STATUS
Definition: mxm_17841b.h:148
@ MXM_41B_REG_FUNCTION_TX_PREAMBLES
Definition: mxm_17841b.h:149
@ MXM_41B_REG_FUNCTION_RX_ERROR_INT
Definition: mxm_17841b.h:151
@ MXM_41B_REG_FUNCTION_KEEP_ALIVE
Definition: mxm_17841b.h:150
@ MXM_41B_REG_FUNCTION_RX_OVERFLOW_INT
Definition: mxm_17841b.h:152
@ MXM_41B_STATE_UNSENT
Definition: mxm_17841b.h:135
@ MXM_41B_STATE_ERROR
Definition: mxm_17841b.h:138
@ MXM_41B_STATE_UNPROCESSED
Definition: mxm_17841b.h:136
@ MXM_41B_STATE_PROCESSED
Definition: mxm_17841b.h:137
MXM_MODEL_ID_e
Type of monitoring device.
@ MXM_MODEL_ID_MAX17853
@ MXM_MODEL_ID_MAX17852
@ MXM_MODEL_ID_MAX17854
@ MXM_MODEL_ID_NONE
@ MXM_MODEL_ID_invalid
MXM_DC_BYTE_e
#define MXM_MAXIMUM_NR_OF_MODULES
Maximum number of modules.
void MXM_5X_InitializeStateStruct(MXM_5X_INSTANCE_s *pInstance)
Initializes the state struct with default values.
static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b)
Handle the state MXM_STATEMACH_5X_41B_FMEA_CHECK.
static void MXM_5XTransitionToSubstate(MXM_5X_INSTANCE_s *pInstance, MXM_5X_SUBSTATES_e substate)
sets all internal state variables so that upon next execution the next substate is entered
static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance)
Signal that a chain of substates has been successfully handled.
static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b)
Handle the state MXM_STATEMACH_5X_READALL.
static STD_RETURN_TYPE_e MXM_5XConstructCommandBufferReadall(MXM_5X_INSTANCE_s *pInstance)
clears the command buffer and writes READALL into the buffer
void MXM_5XStateMachine(MXM_41B_INSTANCE_s *pInstance41b, MXM_5X_INSTANCE_s *pInstance5x)
Execute state-machine for Battery Management Protocol.
static STD_RETURN_TYPE_e MXM_5XConstructCommandBufferWriteall(MXM_5X_INSTANCE_s *pInstance)
clears the command buffer and writes WRITEALL into the buffer
#define MXM_5X_BIT_MASK_ONE_BYTE
static void MXM_5XClearCommandBuffer(MXM_5X_INSTANCE_s *pInstance)
Clear the command-buffer.
static void MXM_5XStateHandlerWrite(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b, bool writeDevice)
Handle the states MXM_STATEMACH_5X_WRITEALL and MXM_STATEMACH_5X_WRITE_DEVICE.
STD_RETURN_TYPE_e GEN_MUST_CHECK_RETURN MXM_5XUserAccessibleAddressSpaceCheckerSelfCheck(void)
runs a selfcheck for the address space check
STD_RETURN_TYPE_e MXM_5XGetRXBuffer(const MXM_5X_INSTANCE_s *const kpkInstance, uint8_t *rxBuffer, uint16_t rxBufferLength)
Copy RX buffer into variable.
static void MXM_5XHandle41BErrorState(MXM_5X_INSTANCE_s *pInstance)
handles the error of the underlying state-machine (by resetting it and counting the error)
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.
static STD_RETURN_TYPE_e MXM_52IsUserAccessibleRegister(uint8_t regAddress)
Check if a register address is user accessible in MAX17852.
static void MXM_5XConstructCommandBufferHelloall(MXM_5X_INSTANCE_s *pInstance)
clears the command buffer and writes HELLOALL into the buffer
STD_RETURN_TYPE_e MXM_5XGetNumberOfSatellitesGood(const MXM_5X_INSTANCE_s *const kpkInstance)
Get the value of MXM_5X_INSTANCE_s::numberOfSatellitesIsGood.
#define HELLOALL_RX_LENGTH
static STD_RETURN_TYPE_e MXM_53IsUserAccessibleRegister(uint8_t regAddress)
Check if a register address is user accessible in MAX17853.
#define MXM_5X_ERROR_THRESHOLD
MXM_DC_BYTE_e MXM_5XGetLastDCByte(const MXM_5X_INSTANCE_s *const kpkInstance)
Returns the last received DC byte.
static STD_RETURN_TYPE_e MXM_5XIsUserAccessibleRegister(uint8_t regAddress, MXM_MODEL_ID_e model)
Check if a register address is user accessible.
static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b)
Handle the state MXM_STATEMACH_5X_INIT.
static STD_RETURN_TYPE_e MXM_5XConstructCommandBufferWriteDevice(MXM_5X_INSTANCE_s *pInstance)
clears the command buffer and writes a WRITEDEVICE message
static void MXM_5XRepeatCurrentSubstate(MXM_5X_INSTANCE_s *pInstance)
repeat the current substate (by resetting to the entry state)
#define MXM_5X_SLAVE_SHUTDOWN_TIMEOUT_MS
uint8_t MXM_5XGetNumberOfSatellites(const MXM_5X_INSTANCE_s *const kpkInstance)
Get number of satellites.
static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance)
Signal that an error has occurred in a chain of substates.
#define MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS
bit masks for writing the device address in write device command
Headers for the driver for the MAX17841B ASCI and MAX1785x analog front-end.
MXM_STATEMACHINE_5X_e
States of the Battery Management Protocol state-machine.
@ MXM_STATEMACH_5X_INIT
@ MXM_STATEMACH_5X_IDLE
@ MXM_STATEMACH_5X_READALL
@ MXM_STATEMACH_5X_WRITEALL
@ MXM_STATEMACH_5X_WRITE_DEVICE
@ MXM_STATEMACH_5X_UNINITIALIZED
@ MXM_STATEMACH_5X_MAXSTATE
@ MXM_STATEMACH_5X_41B_FMEA_CHECK
#define MXM_5X_RX_BUFFER_LEN
MXM_5X_STATE_REQUEST_STATUS_e
Request status of Battery Management Protocol states.
@ MXM_5X_STATE_PROCESSED
@ MXM_5X_STATE_UNPROCESSED
@ MXM_5X_STATE_ERROR
MXM_5X_SUBSTATES_e
Sub-states of the Battery Management Protocol state-machine.
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_CLEAR_RECEIVE_BUFFER
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_HELLOALL
@ MXM_5X_READALL_UART_TRANSACTION
@ MXM_5X_READALL_CHECK_CRC
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_EN_PREAMBLES
@ MXM_5X_INIT_41B_GET_VERSION
@ MXM_5X_READALL_GET_DC
@ MXM_5X_41B_FMEA_REQUEST
@ MXM_5X_INIT_ENABLE_RX_INTERRUPT_FLAGS
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_CLEAR_RECEIVE_BUFFER_2
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_HELLOALL_VERIFY_MSG_AND_COUNT
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_WAIT_FOR_RX_STATUS_BUSY
@ MXM_5X_INIT_41B_INIT
@ MXM_5X_ENTRY_SUBSTATE
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_WAIT_FOR_RX_STATUS_EMPTY
@ MXM_5X_INIT_WAIT_FOR_RESET
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_CLEAR_TRANSMIT_BUFFER
@ MXM_5X_WRITE_UART_TRANSACTION
@ MXM_5X_INIT_ENABLE_KEEP_ALIVE
@ MXM_5X_41B_FMEA_CHECK
@ MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_DIS_PREAMBLES
#define BATTERY_MANAGEMENT_HELLOALL
HELLOALL message.
#define BATTERY_MANAGEMENT_WRITEALL
WRITEALL message (write single register of all daisy-chain devices)
#define BATTERY_MANAGEMENT_READALL
READALL message (read single register of all daisy-chain devices)
#define BATTERY_MANAGEMENT_TX_LENGTH_READALL
Battery Management Protocol lengths of TX buffer.
#define HELLOALL_START_SEED
#define DATA_CHECK_BYTE_SEED
#define COMMAND_BUFFER_LENGTH
#define BATTERY_MANAGEMENT_WRITEDEVICE
WRITEDEVICE message (write single register of a single device)
#define MXM_41B_REG_FALSE
uint8_t MXM_41B_REG_BIT_VALUE
Bit-values for registers.
#define MXM_41B_REG_TRUE
uint8_t MXM_CRC8(uint16_t *pData, int32_t lenData)
Compute CRC8 with initial value set to 0x00.
Definition: mxm_crc8.c:140
@ MXM_REG_VERSION
bool OS_CheckTimeHasPassed(uint32_t oldTimeStamp_ms, uint32_t timeToPass_ms)
This function checks if timeToPass has passed since the last timestamp to now.
Definition: os.c:150
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:142
Struct for the state-variable of state-machine.
Definition: mxm_17841b.h:161
MXM_41B_SUBSTATES_e substate
Definition: mxm_17841b.h:163
MXM_STATEMACH_41B_e state
Definition: mxm_17841b.h:162
5x statemachine structure
uint8_t lastDCByte
Tracks the last received DC byte.
MXM_41B_STATE_REQUEST_STATUS_e status41b
STD_RETURN_TYPE_e numberOfSatellitesIsGood
Number of monitoring ICs matches the expected number.
uint16_t commandBuffer[COMMAND_BUFFER_LENGTH]
Command Buffer.
uint8_t commandBufferCurrentLength
Length of Command Buffer.
MXM_STATEMACHINE_5X_e state
MXM_5X_COMMAND_PAYLOAD_s commandPayload
uint16_t rxBuffer[MXM_5X_RX_BUFFER_LEN]
uint8_t numberOfSatellites
Number of satellites.
MXM_5X_SUBSTATES_e substate
MXM_5X_STATE_REQUEST_STATUS_e * processed