foxBMS  1.6.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-10-12 (date of last update)
47  * @version v1.6.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 }
431 
433  FAS_ASSERT(pInstance != NULL_PTR);
434  FAS_ASSERT(substate <= MXM_5X_ENTRY_SUBSTATE);
435  pInstance->substate = substate;
436  if ((pInstance->status41b == MXM_41B_STATE_PROCESSED) || (pInstance->status41b == MXM_41B_STATE_ERROR)) {
437  pInstance->status41b = MXM_41B_STATE_UNSENT;
438  }
439 }
440 
442  FAS_ASSERT(pInstance != NULL_PTR);
443  pInstance->status41b = MXM_41B_STATE_UNSENT;
444 }
445 
446 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance) {
447  FAS_ASSERT(pInstance != NULL_PTR);
449  FAS_ASSERT(pInstance->processed != NULL_PTR);
450  *pInstance->processed = MXM_5X_STATE_PROCESSED;
451  pInstance->state = MXM_STATEMACH_5X_IDLE;
452 }
453 
454 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance) {
455  FAS_ASSERT(pInstance != NULL_PTR);
457  FAS_ASSERT(pInstance->processed != NULL_PTR);
458  *pInstance->processed = MXM_5X_STATE_ERROR;
459  pInstance->state = MXM_STATEMACH_5X_IDLE;
460 }
461 
462 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
463  FAS_ASSERT(pInstance5x != NULL_PTR);
464  FAS_ASSERT(pInstance41b != NULL_PTR);
465  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
466  /* entry of state --> set to first substate */
468  }
469 
470  if (pInstance5x->substate == MXM_5X_41B_FMEA_REQUEST) {
471  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
472  pInstance41b, MXM_STATEMACH_41B_CHECK_FMEA, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
473  FAS_ASSERT(stateRequestReturn == STD_OK);
475  } else if (pInstance5x->substate == MXM_5X_41B_FMEA_CHECK) {
476  if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
477  /* wait for processing */
478  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
479  /* failure in FMEA; signal error */
480  MXM_5XSignalError(pInstance5x);
481  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
482  MXM_5XSignalSuccess(pInstance5x);
483  } else {
485  }
486  } else {
488  }
489 }
490 
491 static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
492  FAS_ASSERT(pInstance5x != NULL_PTR);
493  FAS_ASSERT(pInstance41b != NULL_PTR);
494  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
495  /* entry of state --> set to first substate */
497  }
498 
499  if (pInstance5x->substate == MXM_5X_INIT_41B_INIT) {
500  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
501  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
502  pInstance41b, MXM_STATEMACH_41B_INIT, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
503  FAS_ASSERT(stateRequestReturn == STD_OK);
504  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
505  /* wait for processing */
506  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
507  MXM_5XHandle41BErrorState(pInstance5x);
508  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
510  pInstance5x->resetWaitTimestamp = OS_GetTickCount();
511  } else {
513  }
514  } else if (pInstance5x->substate == MXM_5X_INIT_41B_GET_VERSION) {
515  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
516  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
517  pInstance41b, MXM_STATEMACH_41B_GET_VERSION, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
518  FAS_ASSERT(stateRequestReturn == STD_OK);
519  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
520  /* wait for processing */
521  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
522  MXM_5XHandle41BErrorState(pInstance5x);
523  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
525  } else {
527  }
528  } else if (pInstance5x->substate == MXM_5X_INIT_WAIT_FOR_RESET) {
529  /* wait so that shutdown low of the satellites discharges and they switch off */
530  const bool shutdownTimeoutHasPassed =
532  if (shutdownTimeoutHasPassed) {
534  }
535  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_RX_INTERRUPT_FLAGS) {
536  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
537  const STD_RETURN_TYPE_e writeRegisterRxErrorReturn =
539  FAS_ASSERT(writeRegisterRxErrorReturn == STD_OK);
540  const STD_RETURN_TYPE_e writeRegisterRxOverflowReturn =
542  FAS_ASSERT(writeRegisterRxOverflowReturn == STD_OK);
543 
544  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
545  pInstance41b,
547  NULL_PTR,
548  0,
549  0,
550  NULL_PTR,
551  0,
552  &pInstance5x->status41b);
553  FAS_ASSERT(stateRequestReturn == STD_OK);
554  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
555  /* wait for processing */
556  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
557  MXM_5XHandle41BErrorState(pInstance5x);
558  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
560  } else {
562  }
564  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
565  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
566  pInstance41b,
568  NULL_PTR,
569  0,
570  0,
571  NULL_PTR,
572  0,
573  &pInstance5x->status41b);
574  FAS_ASSERT(stateRequestReturn == STD_OK);
575  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
576  /* wait for processing */
577  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
578  MXM_5XHandle41BErrorState(pInstance5x);
579  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
581  } else {
583  }
585  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
586  const STD_RETURN_TYPE_e writeRegisterReturn =
588  FAS_ASSERT(writeRegisterReturn == STD_OK);
589 
590  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
591  pInstance41b,
593  NULL_PTR,
594  0,
595  0,
596  NULL_PTR,
597  0,
598  &pInstance5x->status41b);
599  FAS_ASSERT(stateRequestReturn == STD_OK);
600  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
601  /* wait for processing */
602  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
603  MXM_5XHandle41BErrorState(pInstance5x);
604  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
606  } else {
608  }
609  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_KEEP_ALIVE) {
610  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
611  const uint8_t mxm_kConfig3KeepAlive160us41BRegister = 0x05;
612  const STD_RETURN_TYPE_e writeRegisterReturn = MXM_41BWriteRegisterFunction(
613  pInstance41b, MXM_41B_REG_FUNCTION_KEEP_ALIVE, mxm_kConfig3KeepAlive160us41BRegister);
614  FAS_ASSERT(writeRegisterReturn == STD_OK);
615 
616  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
617  pInstance41b,
619  NULL_PTR,
620  0,
621  0,
622  NULL_PTR,
623  0,
624  &pInstance5x->status41b);
625  FAS_ASSERT(stateRequestReturn == STD_OK);
626  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
627  /* wait for processing */
628  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
629  MXM_5XHandle41BErrorState(pInstance5x);
630  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
632  } else {
634  }
636  /* wait for rx status change busy */
637  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
638  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
639  pInstance41b,
641  NULL_PTR,
642  0,
643  0,
644  NULL_PTR,
645  0,
646  &pInstance5x->status41b);
647  FAS_ASSERT(stateRequestReturn == STD_OK);
648  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
649  /* wait for processing */
650  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
651  MXM_5XHandle41BErrorState(pInstance5x);
652  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
653  MXM_41B_REG_BIT_VALUE functionValue;
654  const STD_RETURN_TYPE_e readRegisterReturn =
656  FAS_ASSERT(readRegisterReturn == STD_OK);
657  if (functionValue == MXM_41B_REG_FALSE) {
658  MXM_5XRepeatCurrentSubstate(pInstance5x);
659  } else if (functionValue == MXM_41B_REG_TRUE) {
661  } else {
663  }
664  } else {
666  }
668  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
669  const STD_RETURN_TYPE_e writeRegisterReturn =
671  FAS_ASSERT(writeRegisterReturn == STD_OK);
672 
673  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
674  pInstance41b,
676  NULL_PTR,
677  0,
678  0,
679  NULL_PTR,
680  0,
681  &pInstance5x->status41b);
682  FAS_ASSERT(stateRequestReturn == STD_OK);
683  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
684  /* wait for processing */
685  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
686  MXM_5XHandle41BErrorState(pInstance5x);
687  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
689  } else {
691  }
693  /* wait for rx status change busy */
694  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
695  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
696  pInstance41b,
698  NULL_PTR,
699  0,
700  0,
701  NULL_PTR,
702  0,
703  &pInstance5x->status41b);
704  FAS_ASSERT(stateRequestReturn == STD_OK);
705  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
706  /* wait for processing */
707  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
708  MXM_5XHandle41BErrorState(pInstance5x);
709  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
710  MXM_41B_REG_BIT_VALUE functionValue;
711  const STD_RETURN_TYPE_e readRegisterReturn =
713  FAS_ASSERT(readRegisterReturn == STD_OK);
714 
715  if (functionValue == MXM_41B_REG_TRUE) {
716  MXM_5XRepeatCurrentSubstate(pInstance5x);
717  } else if (functionValue == MXM_41B_REG_FALSE) {
719  } else {
721  }
722  } else {
724  }
726  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
727  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
728  pInstance41b,
730  NULL_PTR,
731  0,
732  0,
733  NULL_PTR,
734  0,
735  &pInstance5x->status41b);
736  FAS_ASSERT(stateRequestReturn == STD_OK);
737  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
738  /* wait for processing */
739  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
740  MXM_5XHandle41BErrorState(pInstance5x);
741  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
743  } else {
745  }
747  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
748  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
749  pInstance41b,
751  NULL_PTR,
752  0,
753  0,
754  NULL_PTR,
755  0,
756  &pInstance5x->status41b);
757  FAS_ASSERT(stateRequestReturn == STD_OK);
758  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
759  /* wait for processing */
760  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
761  MXM_5XHandle41BErrorState(pInstance5x);
762  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
764  } else {
766  }
767  } else if (pInstance5x->substate == MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_HELLOALL) {
768  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
770  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
771  pInstance41b,
773  pInstance5x->commandBuffer,
774  pInstance5x->commandBufferCurrentLength,
775  0,
776  pInstance5x->rxBuffer,
778  &pInstance5x->status41b);
779  FAS_ASSERT(stateRequestReturn == STD_OK);
780  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
781  /* wait for processing */
782  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
783  MXM_5XHandle41BErrorState(pInstance5x);
784  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
786  } else {
788  }
789  /* TODO check for receive buffer errors and handle */
791  /* check if the commandBuffer matches with the receive buffer */
792  STD_RETURN_TYPE_e commandBufferMatchesReceiveBuffer = STD_OK;
793  for (uint8_t i = 0u; i < (pInstance5x->commandBufferCurrentLength - 1u); i++) {
794  if (pInstance5x->commandBuffer[i] != pInstance5x->rxBuffer[i]) {
795  commandBufferMatchesReceiveBuffer = STD_NOT_OK;
796  }
797  }
798  /* update number of satellites */
799  pInstance5x->numberOfSatellites =
800  (uint8_t)((pInstance5x->rxBuffer[HELLOALL_RX_LENGTH - 1u] - HELLOALL_START_SEED) & MXM_5X_BIT_MASK_ONE_BYTE);
801 
802  /* Plausibility check, compare with preset number of satellites */
804  pInstance5x->numberOfSatellitesIsGood = STD_OK;
805  }
806 
807  if (commandBufferMatchesReceiveBuffer == STD_NOT_OK) {
808  /* TODO error handling */
809  } else {
810  MXM_5XSignalSuccess(pInstance5x);
811  }
812  } else {
813  /* something is very broken */
815  }
816 }
817 
819  MXM_5X_INSTANCE_s *pInstance5x,
820  MXM_41B_INSTANCE_s *pInstance41b,
821  bool writeDevice) {
822  FAS_ASSERT(pInstance5x != NULL_PTR);
823  FAS_ASSERT(pInstance41b != NULL_PTR);
824  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
825  /* entry of state --> set to first substate */
827  }
828 
829  if (pInstance5x->substate == MXM_5X_WRITE_UART_TRANSACTION) {
830  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
831  if (writeDevice == true) {
832  /* write device: call function for write device buffer */
833  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteDevice(pInstance5x);
834  FAS_ASSERT(resultAddressCorrect == STD_OK);
835  } else {
836  /* write all: call function for write all buffer */
837  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteall(pInstance5x);
838  FAS_ASSERT(resultAddressCorrect == STD_OK);
839  }
840 
841  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
842  pInstance41b,
844  pInstance5x->commandBuffer,
845  pInstance5x->commandBufferCurrentLength,
846  0,
847  pInstance5x->rxBuffer,
848  pInstance5x->commandBufferCurrentLength,
849  &pInstance5x->status41b);
850  FAS_ASSERT(stateRequestReturn == STD_OK);
851  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
852  /* wait for processing */
853  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
854  MXM_5XHandle41BErrorState(pInstance5x);
855  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
856  MXM_5XSignalSuccess(pInstance5x); /* TODO continue and check CRC */
857  } else {
859  }
860  }
861 }
862 
863 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
864  FAS_ASSERT(pInstance5x != NULL_PTR);
865  FAS_ASSERT(pInstance41b != NULL_PTR);
866  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
867  /* entry of state --> set to first substate */
869  }
870 
871  if (pInstance5x->substate == MXM_5X_READALL_UART_TRANSACTION) {
872  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
873  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferReadall(pInstance5x);
874  FAS_ASSERT(resultAddressCorrect == STD_OK);
875  /* TODO parse rx buffer here into values and parse CRC before passing on*/
876  /* stretch message length in order to accommodate 2 bytes per satellite */
877  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
878  pInstance41b,
880  pInstance5x->commandBuffer,
881  pInstance5x->commandBufferCurrentLength,
882  2u * pInstance5x->numberOfSatellites,
883  pInstance5x->rxBuffer,
885  &pInstance5x->status41b);
886  FAS_ASSERT(stateRequestReturn == STD_OK);
887  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
888  /* wait for processing */
889  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
890  MXM_5XHandle41BErrorState(pInstance5x);
891  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
893  } else {
895  }
896  } else if (pInstance5x->substate == MXM_5X_READALL_CHECK_CRC) {
897  /* check CRC */
898  if (MXM_CRC8(
899  pInstance5x->rxBuffer,
900  ((int32_t)pInstance5x->commandBufferCurrentLength + (2 * (int32_t)pInstance5x->numberOfSatellites))) ==
901  0x00u) {
902  /* currently only one physical string is supported, therefore reporting always to string 0 */
905  } else {
906  /* currently only one physical string is supported, therefore reporting always to string 0 */
908  MXM_5XSignalError(pInstance5x);
909  }
910  } else if (pInstance5x->substate == MXM_5X_READALL_GET_DC) {
911  /* get DC */ /* TODO check DC in this state */
912  /* dc byte position is after data */
913  FAS_ASSERT(((uint16_t)2u + ((uint16_t)2u * pInstance5x->numberOfSatellites)) <= (uint16_t)UINT8_MAX);
914  uint8_t dc_byte_position = 2u + (2u * pInstance5x->numberOfSatellites);
915 
916  pInstance5x->lastDCByte = (uint8_t)(pInstance5x->rxBuffer[dc_byte_position] & MXM_5X_BIT_MASK_ONE_BYTE);
917 
918  MXM_5XSignalSuccess(pInstance5x);
919  } else {
921  }
922 }
923 
924 /*========== Extern Function Implementations ================================*/
925 
927  FAS_ASSERT(pInstance != NULL_PTR);
928 
930  pInstance->substate = MXM_5X_ENTRY_SUBSTATE;
932  pInstance->commandPayload.lsb = 0u;
933  pInstance->commandPayload.msb = 0u;
934  pInstance->commandPayload.blocksize = 0u;
935  pInstance->commandPayload.deviceAddress = 0u;
936  pInstance->processed = NULL_PTR;
937  pInstance->status41b = MXM_41B_STATE_UNSENT;
938  pInstance->numberOfSatellites = 0u;
940  pInstance->lastDCByte = 0u;
941  pInstance->errorCounter = 0u;
942  pInstance->resetWaitTimestamp = 0u;
943  pInstance->commandBufferCurrentLength = 0u;
944 
945  for (uint32_t i = 0u; i < COMMAND_BUFFER_LENGTH; i++) {
946  pInstance->commandBuffer[i] = 0u;
947  }
948 
949  for (uint32_t i = 0u; i < MXM_5X_RX_BUFFER_LEN; i++) {
950  pInstance->rxBuffer[i] = 0u;
951  }
952 }
953 
955  const MXM_5X_INSTANCE_s *const kpkInstance,
956  uint8_t *rxBuffer,
957  uint16_t rxBufferLength) {
958  FAS_ASSERT(kpkInstance != NULL_PTR);
959  FAS_ASSERT(rxBufferLength <= MXM_5X_RX_BUFFER_LEN);
960  /* AXIVION Routine Generic-MissingParameterAssert: rxBuffer: pointer may be NULL */
961 
962  STD_RETURN_TYPE_e retval = STD_OK;
963 
964  if ((rxBuffer != NULL_PTR) && (rxBufferLength != 0u)) {
965  for (uint16_t i = 0; i < rxBufferLength; i++) {
966  if (i < MXM_5X_RX_BUFFER_LEN) {
967  rxBuffer[i] = (uint8_t)(kpkInstance->rxBuffer[i] & MXM_5X_BIT_MASK_ONE_BYTE);
968  }
969  }
970  } else {
971  retval = STD_NOT_OK;
972  }
973 
974  return retval;
975 }
976 
977 extern MXM_DC_BYTE_e MXM_5XGetLastDCByte(const MXM_5X_INSTANCE_s *const kpkInstance) {
978  FAS_ASSERT(kpkInstance != NULL_PTR);
979  return (MXM_DC_BYTE_e)kpkInstance->lastDCByte;
980 }
981 
982 extern uint8_t MXM_5XGetNumberOfSatellites(const MXM_5X_INSTANCE_s *const kpkInstance) {
983  FAS_ASSERT(kpkInstance != NULL_PTR);
984  const uint8_t numberOfSatellites = kpkInstance->numberOfSatellites;
985  FAS_ASSERT(numberOfSatellites <= MXM_MAXIMUM_NR_OF_MODULES);
986  return numberOfSatellites;
987 }
988 
990  FAS_ASSERT(kpkInstance != NULL_PTR);
991  return kpkInstance->numberOfSatellitesIsGood;
992 }
993 
995  MXM_5X_INSTANCE_s *pInstance5x,
996  MXM_STATEMACHINE_5X_e state,
997  MXM_5X_COMMAND_PAYLOAD_s commandPayload,
998  MXM_5X_STATE_REQUEST_STATUS_e *processed) {
999  FAS_ASSERT(pInstance5x != NULL_PTR);
1000  /* AXIVION Routine Generic-MissingParameterAssert: state: parameter accepts whole range */
1001  /* AXIVION Routine Generic-MissingParameterAssert: commandPayload: parameter accepts whole range */
1002  /* AXIVION Routine Generic-MissingParameterAssert: processed: pointer may be NULL */
1003 
1004  STD_RETURN_TYPE_e retval = STD_OK;
1005  if (state >= MXM_STATEMACH_5X_MAXSTATE) {
1006  retval = STD_NOT_OK;
1007  } else if (processed == NULL_PTR) {
1008  retval = STD_NOT_OK;
1009  } else if (pInstance5x->state == MXM_STATEMACH_5X_UNINITIALIZED) {
1010  if (state == MXM_STATEMACH_5X_INIT) {
1011  pInstance5x->state = state;
1012  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1013  pInstance5x->commandPayload = commandPayload;
1014  pInstance5x->processed = processed;
1015  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1016  } else {
1017  retval = STD_NOT_OK;
1018  }
1019  } else if (pInstance5x->state == MXM_STATEMACH_5X_IDLE) {
1020  pInstance5x->state = state;
1021  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1022  pInstance5x->commandPayload = commandPayload;
1023  pInstance5x->processed = processed;
1024  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1025  } else {
1026  retval = STD_NOT_OK;
1027  }
1028  return retval;
1029 }
1030 
1031 void MXM_5XStateMachine(MXM_41B_INSTANCE_s *pInstance41b, MXM_5X_INSTANCE_s *pInstance5x) {
1032  FAS_ASSERT(pInstance41b != NULL_PTR);
1033  FAS_ASSERT(pInstance5x != NULL_PTR);
1034 
1035  /* failure handling */
1036  if (pInstance5x->errorCounter > MXM_5X_ERROR_THRESHOLD) {
1037  /* error, reset both this state-machine and the underlying */
1038  pInstance41b->state = MXM_STATEMACH_41B_IDLE;
1039  pInstance41b->substate = MXM_41B_ENTRY_SUBSTATE;
1040  pInstance41b->waitCounter = 0u;
1041  MXM_5XSignalError(pInstance5x);
1042  pInstance5x->errorCounter = 0u;
1043  }
1044 
1045  switch (pInstance5x->state) {
1047  /* state machine waits here for initialization */
1048  break;
1049  case MXM_STATEMACH_5X_IDLE:
1050  /* idle state currently does nothing */
1051  break;
1053  MXM_5XStateHandler41BFmeaCheck(pInstance5x, pInstance41b);
1054  break;
1055  case MXM_STATEMACH_5X_INIT:
1056  MXM_5XStateHandlerInit(pInstance5x, pInstance41b);
1057  break;
1059  MXM_5XStateHandlerWrite(pInstance5x, pInstance41b, false);
1060  break;
1062  MXM_5XStateHandlerWrite(pInstance5x, pInstance41b, true);
1063  break;
1065  MXM_5XStateHandlerReadAll(pInstance5x, pInstance41b);
1066  break;
1067  default:
1069  break; /* LCOV_EXCL_LINE */
1070  }
1071 }
1072 
1074  /* check:
1075  * - user memory is contained in range 0x00 to 0x98
1076  * - reserved addresses in user address space:
1077  * 0x2C, 0x2D, 0x2E, 0x2F, 0x46 and 0x84 through 0x8B */
1078 
1079  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
1080  /* expected #STD_OK */
1084 
1088 
1092 
1093  /* expected #STD_NOT_OK */
1100 
1104 
1105  /* AXIVION Enable Style Generic-NoMagicNumbers: */
1106 
1107  STD_RETURN_TYPE_e retval = STD_NOT_OK;
1108 
1109  if ((retval_check0 == STD_OK) && (retval_check1 == STD_OK) && (retval_check2 == STD_OK) &&
1110  (retval_check3 == STD_OK) && (retval_check4 == STD_OK) && (retval_check5 == STD_OK) &&
1111  (retval_check6 == STD_OK) && (retval_check7 == STD_OK) && (retval_check8 == STD_OK) &&
1112  (retval_check9 == STD_NOT_OK) && (retval_check10 == STD_NOT_OK) && (retval_check11 == STD_NOT_OK) &&
1113  (retval_check12 == STD_NOT_OK) && (retval_check13 == STD_NOT_OK) && (retval_check14 == STD_NOT_OK) &&
1114  (retval_check15 == STD_NOT_OK) && (retval_check16 == STD_NOT_OK) && (retval_check17 == STD_NOT_OK)) {
1115  retval = STD_OK;
1116  }
1117  return retval;
1118 }
1119 
1120 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1121 #ifdef UNITY_UNIT_TEST
1122 #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:281
@ 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:255
#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:785
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:847
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:893
@ 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:158
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 state machine 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