foxBMS  1.4.1
The foxBMS Battery Management System API Documentation
mxm_battery_management.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, 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 2022-10-27 (date of last update)
47  * @version v1.4.1
48  * @ingroup DRIVERS
49  * @prefix MXM
50  *
51  * @brief Driver for the MAX17841B ASCI and MAX1785x monitoring chip
52  *
53  * @details def
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "mxm_battery_management.h"
59 
60 #include "diag.h"
61 #include "os.h"
62 
63 /*========== Macros and Definitions =========================================*/
64 
65 /** length of the helloall command @{*/
66 #define HELLOALL_TX_LENGTH (3u)
67 #define HELLOALL_RX_LENGTH HELLOALL_TX_LENGTH
68 /**@}*/
69 
70 /** threshold above which an error handling procedure is triggered */
71 #define MXM_5X_ERROR_THRESHOLD (3u)
72 
73 /** time in milliseconds that should be waited in order to ensure that the slaves shut off */
74 #define MXM_5X_SLAVE_SHUTDOWN_TIMEOUT_MS (400u)
75 
76 /** (uint8_t) one byte bit mask */
77 #define MXM_5X_BIT_MASK_ONE_BYTE (0xFFu)
78 
79 /**
80  * @brief bit masks for writing the device address in write device command
81  */
82 #define MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS ((uint16_t)0xF8u)
83 
84 /*========== Static Constant and Variable Definitions =======================*/
85 
86 /*========== Extern Constant and Variable Definitions =======================*/
87 
88 /*========== Static Function Prototypes =====================================*/
89 
90 /**
91  * @brief Clear the command-buffer.
92  * @details Clears #MXM_5X_INSTANCE_s::commandBuffer by writing 0x00 to every entry.
93  * @param[in,out] pInstance pointer to the state-struct
94  * @return always return #STD_OK
95  */
96 static void MXM_5XClearCommandBuffer(MXM_5X_INSTANCE_s *pInstance);
97 
98 /**
99  * @brief Check if a register address is user accessible
100  * @details Checks if a register address is inside the user accessible memory
101  * range. This range is specified in the data sheet of the monitoring
102  * IC as following:
103  * - user memory is contained in the range 0x00 to 0x98
104  * - reserved addresses in the user address space are:
105  * - 0x2C, 0x2D, 0x2E, 0x2F
106  * - 0x46
107  * - 0x84 through 0x8B
108  * @param[in] regAddress register address to be checked
109  * @param[in] model model id of the IC that shall be addressed
110  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
111  */
112 static STD_RETURN_TYPE_e MXM_5XIsUserAccessibleRegister(uint8_t regAddress, MXM_MODEL_ID_e model);
113 
114 /**
115  * @brief Check if a register address is user accessible in MAX17852
116  * @details Checks if a register address is inside the user accessible memory
117  * range.
118  * This range is specified in the data sheet of the monitoring IC.
119  * @param[in] regAddress register address to be checked
120  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
121  */
122 static STD_RETURN_TYPE_e MXM_52IsUserAccessibleRegister(uint8_t regAddress);
123 
124 /**
125  * @brief Check if a register address is user accessible in MAX17853
126  * @details Checks if a register address is inside the user accessible memory
127  * range.
128  * This range is specified in the data sheet of the monitoring IC as
129  * the following:
130  * - user memory is contained in the range 0x00 to 0x98
131  * - reserved addresses in the user address space are:
132  * - 0x2C, 0x2D, 0x2E, 0x2F
133  * - 0x46
134  * - 0x84 through 0x8B
135  * @param[in] regAddress register address to be checked
136  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
137  */
138 static STD_RETURN_TYPE_e MXM_53IsUserAccessibleRegister(uint8_t regAddress);
139 
140 /**
141  * @brief clears the command buffer and writes HELLOALL into the buffer
142  * @details Fills the command buffer with a HELLOALL message after having it
143  * cleaned.
144  * @param[in,out] pInstance pointer to the state-struct
145  */
147 
148 /**
149  * @brief clears the command buffer and writes WRITEALL into the buffer
150  * @details Fills the command buffer with a WRITEALL command. This command
151  * writes the same lsb and msb to every satellite in the daisy-chain
152  * in the same register. The data to be written has to be set before
153  * calling this function in #MXM_5X_INSTANCE_s::commandPayload.
154  * @param[in,out] pInstance pointer to the state-struct
155  * @return #STD_OK if an accessible register address has been selected,
156  * #STD_NOT_OK if not.
157  */
159 
160 /**
161  * @brief clears the command buffer and writes a WRITEDEVICE message
162  * @details Fills the command buffer with a WRITEDEVICE message. This message
163  * is addressed to one specific device in the daisy-chain. Therefore
164  * the address of the device has to be supplied together with the
165  * register and the data that should be written. The data to be
166  * written has to be set before calling this function in
167  * #MXM_5X_INSTANCE_s::commandPayload.
168  * @param[in,out] pInstance pointer to the state-struct
169  * @return #STD_OK if an accessible register address has been selected,
170  * #STD_NOT_OK if not.
171  */
173 
174 /**
175  * @brief clears the command buffer and writes READALL into the buffer
176  * @details Fills the command buffer with a READALL command. This command
177  * retrieves the LSB and MSB of exactly one register of every device
178  * in the daisy-chain. The data to be written has to be set before
179  * calling this function in #MXM_5X_INSTANCE_s::commandPayload.
180  * @param[in,out] pInstance pointer to the state-struct
181  * @return #STD_OK if an accessible register address has been selected,
182  * #STD_NOT_OK if not.
183  */
185 
186 /**
187  * @brief handles the error of the underlying state-machine (by resetting it and counting the error)
188  * @param[in,out] pInstance pointer to the state-struct
189  */
190 static void MXM_5XHandle41BErrorState(MXM_5X_INSTANCE_s *pInstance);
191 
192 /**
193  * @brief sets all internal state variables so that upon next execution the next substate is entered
194  * @param[out] pInstance pointer to the state-struct
195  * @param[in] substate identifier of the next substate
196  */
197 static void MXM_5XTransitionToSubstate(MXM_5X_INSTANCE_s *pInstance, MXM_5X_SUBSTATES_e substate);
198 
199 /**
200  * @brief repeat the current substate (by resetting to the entry state)
201  * @param[out] pInstance pointer to the state-struct
202  */
203 static void MXM_5XRepeatCurrentSubstate(MXM_5X_INSTANCE_s *pInstance);
204 
205 /**
206  * @brief Signal that a chain of substates has been successfully handled
207  * @param[out] pInstance pointer to the state-struct
208  */
209 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance);
210 
211 /**
212  * @brief Signal that an error has occurred in a chain of substates
213  * @param[out] pInstance pointer to the state-struct
214  */
215 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance);
216 
217 /**
218  * @brief Handle the state #MXM_STATEMACH_5X_41B_FMEA_CHECK
219  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
220  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
221  */
222 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
223 
224 /**
225  * @brief Handle the state #MXM_STATEMACH_5X_INIT
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_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
230 
231 /**
232  * @brief Handle the states #MXM_STATEMACH_5X_WRITEALL and #MXM_STATEMACH_5X_WRITE_DEVICE
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  * @param[in] writeDevice true: write device, false: write all
236  */
237 static void MXM_5XStateHandlerWrite(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b, bool writeDevice);
238 
239 /**
240  * @brief Handle the state #MXM_STATEMACH_5X_READALL
241  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
242  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
243  */
244 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
245 
246 /*========== Static Function Implementations ================================*/
248  FAS_ASSERT(pInstance != NULL_PTR);
249  for (uint8_t i = 0; i < COMMAND_BUFFER_LENGTH; i++) {
250  pInstance->commandBuffer[i] = 0x00U;
251  }
253 }
254 
257  /* AXIVION Routine Generic-MissingParameterAssert: regAddress: parameter accepts whole range */
258 
259  STD_RETURN_TYPE_e retval = STD_NOT_OK;
260 
261  switch (model) {
263  retval = MXM_52IsUserAccessibleRegister(regAddress);
264  break;
266  retval = MXM_53IsUserAccessibleRegister(regAddress);
267  break;
269  case MXM_MODEL_ID_NONE:
271  /* not implemented or invalid model id */
272  break;
273  default:
274  /* invalid state, should not happen */
276  break;
277  }
278  return retval;
279 }
280 
282  /* AXIVION Routine Generic-MissingParameterAssert: regAddress: parameter accepts whole range */
283 
284  STD_RETURN_TYPE_e retval = STD_NOT_OK;
285  /* check if regAddress is outside user-accessible area */
286  /* AXIVION Disable Style Generic-NoMagicNumbers: memory limits of ICs are specific and unchangeable, therefore hardcoded */
287  bool registerAddressIsInvalid = (regAddress == 0x5Du);
288  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress == 0x5Eu);
289  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress > 0x98u);
290  /* AXIVION Enable Style Generic-NoMagicNumbers: */
291 
292  if (registerAddressIsInvalid == false) {
293  /* valid MAX17852 register address */
294  retval = STD_OK;
295  }
296  return retval;
297 }
298 
300  STD_RETURN_TYPE_e retval = STD_NOT_OK;
301  /* check if regAddress is outside user-accessible area */
302  /* AXIVION Disable Style Generic-NoMagicNumbers: memory limits of ICs are specific and unchangeable, therefore hardcoded */
303  bool registerAddressIsInvalid = (regAddress == 0x46u);
304  registerAddressIsInvalid = registerAddressIsInvalid || ((0x2Cu <= regAddress) && (regAddress <= 0x2Fu));
305  registerAddressIsInvalid = registerAddressIsInvalid || ((0x84u <= regAddress) && (regAddress <= 0x8Bu));
306  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress > 0x98u);
307  /* AXIVION Enable Style Generic-NoMagicNumbers: */
308 
309  if (registerAddressIsInvalid == false) {
310  /* valid MAX17853 register address */
311  retval = STD_OK;
312  }
313  return retval;
314 }
315 
317  FAS_ASSERT(pInstance != NULL_PTR);
318  MXM_5XClearCommandBuffer(pInstance);
320  pInstance->commandBuffer[1] = 0x00;
321  pInstance->commandBuffer[2] = HELLOALL_START_SEED;
322  pInstance->commandBufferCurrentLength = 3;
323 }
324 
326  FAS_ASSERT(pInstance != NULL_PTR);
327  STD_RETURN_TYPE_e retval = STD_NOT_OK;
328 
329  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
330  FAS_ASSERT(pPayload != NULL_PTR);
331 
332  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
333  /* clear command buffer */
334  MXM_5XClearCommandBuffer(pInstance);
335 
336  /* construct command buffer */
338  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
339  pInstance->commandBuffer[2] = pPayload->lsb;
340  pInstance->commandBuffer[3] = pPayload->msb;
341  /* PEC byte */
342  pInstance->commandBuffer[4] = MXM_CRC8(pInstance->commandBuffer, 4);
343  /* TODO alive-counter? */
344  pInstance->commandBufferCurrentLength = 5;
345  retval = STD_OK;
346  }
347 
348  return retval;
349 }
350 
352  FAS_ASSERT(pInstance != NULL_PTR);
353  STD_RETURN_TYPE_e retval = STD_NOT_OK;
354 
355  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
356  FAS_ASSERT(pPayload != NULL_PTR);
357 
358  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
359  /* clear command buffer */
360  MXM_5XClearCommandBuffer(pInstance);
361 
362  /* construct command buffer */
363 
364  /* commandBuffer[0] = Device address in a daisy chain + 0b100
365  * DA = deviceAddress
366  * Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
367  * Content | DA[4] | DA[3] | DA[2] | DA[1] | DA[0] | 1 | 0 | 0
368  */
369  pInstance->commandBuffer[0] =
370  ((((uint16_t)pPayload->deviceAddress << 3u) & MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS) |
372  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
373  pInstance->commandBuffer[2] = pPayload->lsb;
374  pInstance->commandBuffer[3] = pPayload->msb;
375  /* PEC byte */
376  pInstance->commandBuffer[4] = MXM_CRC8(pInstance->commandBuffer, 4);
377  /* TODO alive-counter? */
378  pInstance->commandBufferCurrentLength = 5;
379  retval = STD_OK;
380  }
381 
382  return retval;
383 }
384 
386  FAS_ASSERT(pInstance != NULL_PTR);
387  STD_RETURN_TYPE_e retval = STD_NOT_OK;
388  /* TODO test these functions */
389 
390  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
391  FAS_ASSERT(pPayload != NULL_PTR);
392 
393  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
394  /* clear command buffer */
395  MXM_5XClearCommandBuffer(pInstance);
396 
397  /* construct command buffer */
399  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
400  pInstance->commandBuffer[2] = DATA_CHECK_BYTE_SEED;
401  /* PEC byte */
402  pInstance->commandBuffer[3] = MXM_CRC8(pInstance->commandBuffer, 3);
403  /* TODO alive-counter? */
404  pInstance->commandBufferCurrentLength = 4;
405  retval = STD_OK;
406  }
407 
409  /* define containing command buffer length does
410  * not match actual buffer */
411  retval = STD_NOT_OK;
412  }
413 
414  return retval;
415 }
416 
418  FAS_ASSERT(pInstance != NULL_PTR);
419  pInstance->status41b = MXM_41B_STATE_UNSENT;
420  if (pInstance->errorCounter < (uint8_t)UINT8_MAX) {
421  pInstance->errorCounter++;
422  }
423  return;
424 }
425 
427  FAS_ASSERT(pInstance != NULL_PTR);
428  FAS_ASSERT(substate <= MXM_5X_ENTRY_SUBSTATE);
429  pInstance->substate = substate;
430  if ((pInstance->status41b == MXM_41B_STATE_PROCESSED) || (pInstance->status41b == MXM_41B_STATE_ERROR)) {
431  pInstance->status41b = MXM_41B_STATE_UNSENT;
432  }
433  return;
434 }
435 
437  FAS_ASSERT(pInstance != NULL_PTR);
438  pInstance->status41b = MXM_41B_STATE_UNSENT;
439  return;
440 }
441 
442 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance) {
443  FAS_ASSERT(pInstance != NULL_PTR);
445  FAS_ASSERT(pInstance->processed != NULL_PTR);
446  *pInstance->processed = MXM_5X_STATE_PROCESSED;
447  pInstance->state = MXM_STATEMACH_5X_IDLE;
448  return;
449 }
450 
451 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance) {
452  FAS_ASSERT(pInstance != NULL_PTR);
454  FAS_ASSERT(pInstance->processed != NULL_PTR);
455  *pInstance->processed = MXM_5X_STATE_ERROR;
456  pInstance->state = MXM_STATEMACH_5X_IDLE;
457  return;
458 }
459 
460 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
461  FAS_ASSERT(pInstance5x != NULL_PTR);
462  FAS_ASSERT(pInstance41b != NULL_PTR);
463  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
464  /* entry of state --> set to first substate */
466  }
467 
468  if (pInstance5x->substate == MXM_5X_41B_FMEA_REQUEST) {
469  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
470  pInstance41b, MXM_STATEMACH_41B_CHECK_FMEA, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
471  FAS_ASSERT(stateRequestReturn == STD_OK);
473  } else if (pInstance5x->substate == MXM_5X_41B_FMEA_CHECK) {
474  if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
475  /* wait for processing */
476  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
477  /* failure in FMEA; signal error */
478  MXM_5XSignalError(pInstance5x);
479  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
480  MXM_5XSignalSuccess(pInstance5x);
481  } else {
483  }
484  } else {
486  }
487 }
488 
489 static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
490  FAS_ASSERT(pInstance5x != NULL_PTR);
491  FAS_ASSERT(pInstance41b != NULL_PTR);
492  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
493  /* entry of state --> set to first substate */
495  }
496 
497  if (pInstance5x->substate == MXM_5X_INIT_41B_INIT) {
498  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
499  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
500  pInstance41b, MXM_STATEMACH_41B_INIT, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
501  FAS_ASSERT(stateRequestReturn == STD_OK);
502  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
503  /* wait for processing */
504  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
505  MXM_5XHandle41BErrorState(pInstance5x);
506  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
508  pInstance5x->resetWaitTimestamp = OS_GetTickCount();
509  } else {
511  }
512  } else if (pInstance5x->substate == MXM_5X_INIT_41B_GET_VERSION) {
513  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
514  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
515  pInstance41b, MXM_STATEMACH_41B_GET_VERSION, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
516  FAS_ASSERT(stateRequestReturn == STD_OK);
517  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
518  /* wait for processing */
519  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
520  MXM_5XHandle41BErrorState(pInstance5x);
521  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
523  } else {
525  }
526  } else if (pInstance5x->substate == MXM_5X_INIT_WAIT_FOR_RESET) {
527  /* wait so that shutdown low of the satellites discharges and they switch off */
528  const bool shutdownTimeoutHasPassed =
530  if (shutdownTimeoutHasPassed) {
532  }
533  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_RX_INTERRUPT_FLAGS) {
534  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
535  const STD_RETURN_TYPE_e writeRegisterRxErrorReturn =
537  FAS_ASSERT(writeRegisterRxErrorReturn == STD_OK);
538  const STD_RETURN_TYPE_e writeRegisterRxOverflowReturn =
540  FAS_ASSERT(writeRegisterRxOverflowReturn == STD_OK);
541 
542  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
543  pInstance41b,
545  NULL_PTR,
546  0,
547  0,
548  NULL_PTR,
549  0,
550  &pInstance5x->status41b);
551  FAS_ASSERT(stateRequestReturn == STD_OK);
552  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
553  /* wait for processing */
554  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
555  MXM_5XHandle41BErrorState(pInstance5x);
556  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
558  } else {
560  }
562  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
563  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
564  pInstance41b,
566  NULL_PTR,
567  0,
568  0,
569  NULL_PTR,
570  0,
571  &pInstance5x->status41b);
572  FAS_ASSERT(stateRequestReturn == STD_OK);
573  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
574  /* wait for processing */
575  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
576  MXM_5XHandle41BErrorState(pInstance5x);
577  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
579  } else {
581  }
583  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
584  const STD_RETURN_TYPE_e writeRegisterReturn =
586  FAS_ASSERT(writeRegisterReturn == STD_OK);
587 
588  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
589  pInstance41b,
591  NULL_PTR,
592  0,
593  0,
594  NULL_PTR,
595  0,
596  &pInstance5x->status41b);
597  FAS_ASSERT(stateRequestReturn == STD_OK);
598  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
599  /* wait for processing */
600  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
601  MXM_5XHandle41BErrorState(pInstance5x);
602  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
604  } else {
606  }
607  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_KEEP_ALIVE) {
608  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
609  const uint8_t mxm_kConfig3KeepAlive160us41BRegister = 0x05;
610  const STD_RETURN_TYPE_e writeRegisterReturn = MXM_41BWriteRegisterFunction(
611  pInstance41b, MXM_41B_REG_FUNCTION_KEEP_ALIVE, mxm_kConfig3KeepAlive160us41BRegister);
612  FAS_ASSERT(writeRegisterReturn == STD_OK);
613 
614  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
615  pInstance41b,
617  NULL_PTR,
618  0,
619  0,
620  NULL_PTR,
621  0,
622  &pInstance5x->status41b);
623  FAS_ASSERT(stateRequestReturn == STD_OK);
624  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
625  /* wait for processing */
626  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
627  MXM_5XHandle41BErrorState(pInstance5x);
628  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
630  } else {
632  }
634  /* wait for rx status change busy */
635  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
636  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
637  pInstance41b,
639  NULL_PTR,
640  0,
641  0,
642  NULL_PTR,
643  0,
644  &pInstance5x->status41b);
645  FAS_ASSERT(stateRequestReturn == STD_OK);
646  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
647  /* wait for processing */
648  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
649  MXM_5XHandle41BErrorState(pInstance5x);
650  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
651  MXM_41B_REG_BIT_VALUE functionValue;
652  const STD_RETURN_TYPE_e readRegisterReturn =
654  FAS_ASSERT(readRegisterReturn == STD_OK);
655  if (functionValue == MXM_41B_REG_FALSE) {
656  MXM_5XRepeatCurrentSubstate(pInstance5x);
657  } else if (functionValue == MXM_41B_REG_TRUE) {
659  } else {
661  }
662  } else {
664  }
666  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
667  const STD_RETURN_TYPE_e writeRegisterReturn =
669  FAS_ASSERT(writeRegisterReturn == STD_OK);
670 
671  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
672  pInstance41b,
674  NULL_PTR,
675  0,
676  0,
677  NULL_PTR,
678  0,
679  &pInstance5x->status41b);
680  FAS_ASSERT(stateRequestReturn == STD_OK);
681  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
682  /* wait for processing */
683  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
684  MXM_5XHandle41BErrorState(pInstance5x);
685  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
687  } else {
689  }
691  /* wait for rx status change busy */
692  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
693  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
694  pInstance41b,
696  NULL_PTR,
697  0,
698  0,
699  NULL_PTR,
700  0,
701  &pInstance5x->status41b);
702  FAS_ASSERT(stateRequestReturn == STD_OK);
703  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
704  /* wait for processing */
705  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
706  MXM_5XHandle41BErrorState(pInstance5x);
707  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
708  MXM_41B_REG_BIT_VALUE functionValue;
709  const STD_RETURN_TYPE_e readRegisterReturn =
711  FAS_ASSERT(readRegisterReturn == STD_OK);
712 
713  if (functionValue == MXM_41B_REG_TRUE) {
714  MXM_5XRepeatCurrentSubstate(pInstance5x);
715  } else if (functionValue == MXM_41B_REG_FALSE) {
717  } else {
719  }
720  } else {
722  }
724  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
725  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
726  pInstance41b,
728  NULL_PTR,
729  0,
730  0,
731  NULL_PTR,
732  0,
733  &pInstance5x->status41b);
734  FAS_ASSERT(stateRequestReturn == STD_OK);
735  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
736  /* wait for processing */
737  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
738  MXM_5XHandle41BErrorState(pInstance5x);
739  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
741  } else {
743  }
745  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
746  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
747  pInstance41b,
749  NULL_PTR,
750  0,
751  0,
752  NULL_PTR,
753  0,
754  &pInstance5x->status41b);
755  FAS_ASSERT(stateRequestReturn == STD_OK);
756  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
757  /* wait for processing */
758  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
759  MXM_5XHandle41BErrorState(pInstance5x);
760  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
762  } else {
764  }
765  } else if (pInstance5x->substate == MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_HELLOALL) {
766  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
768  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
769  pInstance41b,
771  pInstance5x->commandBuffer,
772  pInstance5x->commandBufferCurrentLength,
773  0,
774  pInstance5x->rxBuffer,
776  &pInstance5x->status41b);
777  FAS_ASSERT(stateRequestReturn == STD_OK);
778  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
779  /* wait for processing */
780  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
781  MXM_5XHandle41BErrorState(pInstance5x);
782  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
784  } else {
786  }
787  /* TODO check for receive buffer errors and handle */
789  /* check if the commandBuffer matches with the receive buffer */
790  STD_RETURN_TYPE_e commandBufferMatchesReceiveBuffer = STD_OK;
791  for (uint8_t i = 0u; i < (pInstance5x->commandBufferCurrentLength - 1u); i++) {
792  if (pInstance5x->commandBuffer[i] != pInstance5x->rxBuffer[i]) {
793  commandBufferMatchesReceiveBuffer = STD_NOT_OK;
794  }
795  }
796  /* update number of satellites */
797  pInstance5x->numberOfSatellites =
798  (uint8_t)((pInstance5x->rxBuffer[HELLOALL_RX_LENGTH - 1u] - HELLOALL_START_SEED) & MXM_5X_BIT_MASK_ONE_BYTE);
799 
800  /* Plausibility check, compare with preset number of satellites */
802  pInstance5x->numberOfSatellitesIsGood = STD_OK;
803  }
804 
805  if (commandBufferMatchesReceiveBuffer == STD_NOT_OK) {
806  /* TODO error handling */
807  } else {
808  MXM_5XSignalSuccess(pInstance5x);
809  }
810  } else {
811  /* something is very broken */
813  }
814 }
815 
817  MXM_5X_INSTANCE_s *pInstance5x,
818  MXM_41B_INSTANCE_s *pInstance41b,
819  bool writeDevice) {
820  FAS_ASSERT(pInstance5x != NULL_PTR);
821  FAS_ASSERT(pInstance41b != NULL_PTR);
822  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
823  /* entry of state --> set to first substate */
825  }
826 
827  if (pInstance5x->substate == MXM_5X_WRITE_UART_TRANSACTION) {
828  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
829  if (writeDevice == true) {
830  /* write device: call function for write device buffer */
831  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteDevice(pInstance5x);
832  FAS_ASSERT(resultAddressCorrect == STD_OK);
833  } else {
834  /* write all: call function for write all buffer */
835  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteall(pInstance5x);
836  FAS_ASSERT(resultAddressCorrect == STD_OK);
837  }
838 
839  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
840  pInstance41b,
842  pInstance5x->commandBuffer,
843  pInstance5x->commandBufferCurrentLength,
844  0,
845  pInstance5x->rxBuffer,
846  pInstance5x->commandBufferCurrentLength,
847  &pInstance5x->status41b);
848  FAS_ASSERT(stateRequestReturn == STD_OK);
849  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
850  /* wait for processing */
851  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
852  MXM_5XHandle41BErrorState(pInstance5x);
853  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
854  MXM_5XSignalSuccess(pInstance5x); /* TODO continue and check CRC */
855  } else {
857  }
858  }
859 }
860 
861 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
862  FAS_ASSERT(pInstance5x != NULL_PTR);
863  FAS_ASSERT(pInstance41b != NULL_PTR);
864  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
865  /* entry of state --> set to first substate */
867  }
868 
869  if (pInstance5x->substate == MXM_5X_READALL_UART_TRANSACTION) {
870  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
871  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferReadall(pInstance5x);
872  FAS_ASSERT(resultAddressCorrect == STD_OK);
873  /* TODO parse rx buffer here into values and parse CRC before passing on*/
874  /* stretch message length in order to accommodate 2 bytes per satellite */
875  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
876  pInstance41b,
878  pInstance5x->commandBuffer,
879  pInstance5x->commandBufferCurrentLength,
880  2u * pInstance5x->numberOfSatellites,
881  pInstance5x->rxBuffer,
883  &pInstance5x->status41b);
884  FAS_ASSERT(stateRequestReturn == STD_OK);
885  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
886  /* wait for processing */
887  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
888  MXM_5XHandle41BErrorState(pInstance5x);
889  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
891  } else {
893  }
894  } else if (pInstance5x->substate == MXM_5X_READALL_CHECK_CRC) {
895  /* check CRC */
896  if (MXM_CRC8(
897  pInstance5x->rxBuffer,
898  ((int32_t)pInstance5x->commandBufferCurrentLength + (2 * (int32_t)pInstance5x->numberOfSatellites))) ==
899  0x00u) {
900  /* currently only one physical string is supported, therefore reporting always to string 0 */
903  } else {
904  /* currently only one physical string is supported, therefore reporting always to string 0 */
906  MXM_5XSignalError(pInstance5x);
907  }
908  } else if (pInstance5x->substate == MXM_5X_READALL_GET_DC) {
909  /* get DC */ /* TODO check DC in this state */
910  /* dc byte position is after data */
911  FAS_ASSERT(((uint16_t)2u + ((uint16_t)2u * pInstance5x->numberOfSatellites)) <= (uint16_t)UINT8_MAX);
912  uint8_t dc_byte_position = 2u + (2u * pInstance5x->numberOfSatellites);
913 
914  pInstance5x->lastDCByte = (uint8_t)(pInstance5x->rxBuffer[dc_byte_position] & MXM_5X_BIT_MASK_ONE_BYTE);
915 
916  MXM_5XSignalSuccess(pInstance5x);
917  } else {
919  }
920 }
921 
922 /*========== Extern Function Implementations ================================*/
923 
925  FAS_ASSERT(pInstance != NULL_PTR);
926 
928  pInstance->substate = MXM_5X_ENTRY_SUBSTATE;
930  pInstance->commandPayload.lsb = 0u;
931  pInstance->commandPayload.msb = 0u;
932  pInstance->commandPayload.blocksize = 0u;
933  pInstance->commandPayload.deviceAddress = 0u;
934  pInstance->processed = NULL_PTR;
935  pInstance->status41b = MXM_41B_STATE_UNSENT;
936  pInstance->numberOfSatellites = 0u;
938  pInstance->lastDCByte = 0u;
939  pInstance->errorCounter = 0u;
940  pInstance->resetWaitTimestamp = 0u;
941  pInstance->commandBufferCurrentLength = 0u;
942 
943  for (uint32_t i = 0u; i < COMMAND_BUFFER_LENGTH; i++) {
944  pInstance->commandBuffer[i] = 0u;
945  }
946 
947  for (uint32_t i = 0u; i < MXM_5X_RX_BUFFER_LEN; i++) {
948  pInstance->rxBuffer[i] = 0u;
949  }
950 }
951 
953  const MXM_5X_INSTANCE_s *const kpkInstance,
954  uint8_t *rxBuffer,
955  uint16_t rxBufferLength) {
956  FAS_ASSERT(kpkInstance != NULL_PTR);
957  FAS_ASSERT(rxBufferLength <= MXM_5X_RX_BUFFER_LEN);
958  /* AXIVION Routine Generic-MissingParameterAssert: rxBuffer: pointer may be NULL */
959 
960  STD_RETURN_TYPE_e retval = STD_OK;
961 
962  if ((rxBuffer != NULL_PTR) && (rxBufferLength != 0u)) {
963  for (uint16_t i = 0; i < rxBufferLength; i++) {
964  if (i < MXM_5X_RX_BUFFER_LEN) {
965  rxBuffer[i] = (uint8_t)(kpkInstance->rxBuffer[i] & MXM_5X_BIT_MASK_ONE_BYTE);
966  }
967  }
968  } else {
969  retval = STD_NOT_OK;
970  }
971 
972  return retval;
973 }
974 
975 extern MXM_DC_BYTE_e MXM_5XGetLastDCByte(const MXM_5X_INSTANCE_s *const kpkInstance) {
976  FAS_ASSERT(kpkInstance != NULL_PTR);
977  return (MXM_DC_BYTE_e)kpkInstance->lastDCByte;
978 }
979 
980 extern uint8_t MXM_5XGetNumberOfSatellites(const MXM_5X_INSTANCE_s *const kpkInstance) {
981  FAS_ASSERT(kpkInstance != NULL_PTR);
982  const uint8_t numberOfSatellites = kpkInstance->numberOfSatellites;
983  FAS_ASSERT(numberOfSatellites <= MXM_MAXIMUM_NR_OF_MODULES);
984  return numberOfSatellites;
985 }
986 
988  FAS_ASSERT(kpkInstance != NULL_PTR);
989  return kpkInstance->numberOfSatellitesIsGood;
990 }
991 
993  MXM_5X_INSTANCE_s *pInstance5x,
994  MXM_STATEMACHINE_5X_e state,
995  MXM_5X_COMMAND_PAYLOAD_s commandPayload,
996  MXM_5X_STATE_REQUEST_STATUS_e *processed) {
997  FAS_ASSERT(pInstance5x != NULL_PTR);
998  /* AXIVION Routine Generic-MissingParameterAssert: state: parameter accepts whole range */
999  /* AXIVION Routine Generic-MissingParameterAssert: commandPayload: parameter accepts whole range */
1000  /* AXIVION Routine Generic-MissingParameterAssert: processed: pointer may be NULL */
1001 
1002  STD_RETURN_TYPE_e retval = STD_OK;
1003  if (state >= MXM_STATEMACH_5X_MAXSTATE) {
1004  retval = STD_NOT_OK;
1005  } else if (processed == NULL_PTR) {
1006  retval = STD_NOT_OK;
1007  } else if (pInstance5x->state == MXM_STATEMACH_5X_UNINITIALIZED) {
1008  if (state == MXM_STATEMACH_5X_INIT) {
1009  pInstance5x->state = state;
1010  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1011  pInstance5x->commandPayload = commandPayload;
1012  pInstance5x->processed = processed;
1013  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1014  } else {
1015  retval = STD_NOT_OK;
1016  }
1017  } else if (pInstance5x->state == MXM_STATEMACH_5X_IDLE) {
1018  pInstance5x->state = state;
1019  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1020  pInstance5x->commandPayload = commandPayload;
1021  pInstance5x->processed = processed;
1022  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1023  } else {
1024  retval = STD_NOT_OK;
1025  }
1026  return retval;
1027 }
1028 
1029 void MXM_5XStateMachine(MXM_41B_INSTANCE_s *pInstance41b, MXM_5X_INSTANCE_s *pInstance5x) {
1030  FAS_ASSERT(pInstance41b != NULL_PTR);
1031  FAS_ASSERT(pInstance5x != NULL_PTR);
1032 
1033  /* failure handling */
1034  if (pInstance5x->errorCounter > MXM_5X_ERROR_THRESHOLD) {
1035  /* error, reset both this state-machine and the underlying */
1036  pInstance41b->state = MXM_STATEMACH_41B_IDLE;
1037  pInstance41b->substate = MXM_41B_ENTRY_SUBSTATE;
1038  pInstance41b->waitCounter = 0u;
1039  MXM_5XSignalError(pInstance5x);
1040  pInstance5x->errorCounter = 0u;
1041  }
1042 
1043  switch (pInstance5x->state) {
1045  /* statemachine waits here for initialization */
1046  break;
1047  case MXM_STATEMACH_5X_IDLE:
1048  /* idle state currently does nothing */
1049  break;
1051  MXM_5XStateHandler41BFmeaCheck(pInstance5x, pInstance41b);
1052  break;
1053  case MXM_STATEMACH_5X_INIT:
1054  MXM_5XStateHandlerInit(pInstance5x, pInstance41b);
1055  break;
1057  MXM_5XStateHandlerWrite(pInstance5x, pInstance41b, false);
1058  break;
1060  MXM_5XStateHandlerWrite(pInstance5x, pInstance41b, true);
1061  break;
1063  MXM_5XStateHandlerReadAll(pInstance5x, pInstance41b);
1064  break;
1065  default:
1067  break;
1068  }
1069 }
1070 
1072  /* check:
1073  * - user memory is contained in range 0x00 to 0x98
1074  * - reserved addresses in user address space:
1075  * 0x2C, 0x2D, 0x2E, 0x2F, 0x46 and 0x84 through 0x8B */
1076 
1077  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
1078  /* expected #STD_OK */
1082 
1086 
1090 
1091  /* expected #STD_NOT_OK */
1098 
1102 
1103  /* AXIVION Enable Style Generic-NoMagicNumbers: */
1104 
1105  STD_RETURN_TYPE_e retval = STD_NOT_OK;
1106 
1107  if ((retval_check0 == STD_OK) && (retval_check1 == STD_OK) && (retval_check2 == STD_OK) &&
1108  (retval_check3 == STD_OK) && (retval_check4 == STD_OK) && (retval_check5 == STD_OK) &&
1109  (retval_check6 == STD_OK) && (retval_check7 == STD_OK) && (retval_check8 == STD_OK) &&
1110  (retval_check9 == STD_NOT_OK) && (retval_check10 == STD_NOT_OK) && (retval_check11 == STD_NOT_OK) &&
1111  (retval_check12 == STD_NOT_OK) && (retval_check13 == STD_NOT_OK) && (retval_check14 == STD_NOT_OK) &&
1112  (retval_check15 == STD_NOT_OK) && (retval_check16 == STD_NOT_OK) && (retval_check17 == STD_NOT_OK)) {
1113  retval = STD_OK;
1114  }
1115  return retval;
1116 }
1117 
1118 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#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:371
Diagnosis driver header.
@ DIAG_STRING
Definition: diag_cfg.h:271
@ DIAG_ID_AFE_COM_INTEGRITY
Definition: diag_cfg.h:179
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:126
STD_RETURN_TYPE_e
Definition: fstd_types.h:81
@ STD_NOT_OK
Definition: fstd_types.h:83
@ STD_OK
Definition: fstd_types.h:82
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
#define GEN_MUST_CHECK_RETURN
Allows functions to generate warnings in GCC for unused returns.
Definition: general.h:88
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:784
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:846
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:892
@ MXM_STATEMACH_41B_GET_VERSION
Definition: mxm_17841b.h:89
@ MXM_STATEMACH_41B_CLEAR_RECEIVE_BUFFER
Definition: mxm_17841b.h:93
@ MXM_STATEMACH_41B_CLEAR_TRANSMIT_BUFFER
Definition: mxm_17841b.h:94
@ MXM_STATEMACH_41B_INIT
Definition: mxm_17841b.h:86
@ MXM_STATEMACH_41B_WRITE_CONF_AND_INT_REGISTER
Definition: mxm_17841b.h:90
@ MXM_STATEMACH_41B_CHECK_FMEA
Definition: mxm_17841b.h:88
@ MXM_STATEMACH_41B_READ_STATUS_REGISTER
Definition: mxm_17841b.h:91
@ MXM_STATEMACH_41B_IDLE
Definition: mxm_17841b.h:87
@ MXM_STATEMACH_41B_UART_TRANSACTION
Definition: mxm_17841b.h:92
@ MXM_41B_ENTRY_SUBSTATE
Definition: mxm_17841b.h:102
@ MXM_41B_REG_FUNCTION_RX_BUSY_STATUS
Definition: mxm_17841b.h:142
@ MXM_41B_REG_FUNCTION_RX_EMPTY_STATUS
Definition: mxm_17841b.h:145
@ MXM_41B_REG_FUNCTION_TX_PREAMBLES
Definition: mxm_17841b.h:146
@ MXM_41B_REG_FUNCTION_RX_ERROR_INT
Definition: mxm_17841b.h:148
@ MXM_41B_REG_FUNCTION_KEEP_ALIVE
Definition: mxm_17841b.h:147
@ MXM_41B_REG_FUNCTION_RX_OVERFLOW_INT
Definition: mxm_17841b.h:149
@ MXM_41B_STATE_UNSENT
Definition: mxm_17841b.h:132
@ MXM_41B_STATE_ERROR
Definition: mxm_17841b.h:135
@ MXM_41B_STATE_UNPROCESSED
Definition: mxm_17841b.h:133
@ MXM_41B_STATE_PROCESSED
Definition: mxm_17841b.h:134
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 monitoring chip.
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:133
@ 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:144
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:139
Struct for the state-variable of state-machine.
Definition: mxm_17841b.h:158
MXM_41B_SUBSTATES_e substate
Definition: mxm_17841b.h:160
MXM_STATEMACH_41B_e state
Definition: mxm_17841b.h:159
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