foxBMS - Unit Tests  1.2.1
The foxBMS Unit Tests API Documentation
mxm_battery_management.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file mxm_battery_management.c
44  * @author foxBMS Team
45  * @date 2019-01-14 (date of creation)
46  * @updated 2021-12-06 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix MXM
49  *
50  * @brief Driver for the MAX17841B ASCI and MAX1785x monitoring chip
51  *
52  * @details def
53  *
54  */
55 
56 /*========== Includes =======================================================*/
57 #include "mxm_battery_management.h"
58 
59 #include "os.h"
60 
61 /*========== Macros and Definitions =========================================*/
62 
63 /** length of the helloall command @{*/
64 #define HELLOALL_TX_LENGTH (3u)
65 #define HELLOALL_RX_LENGTH HELLOALL_TX_LENGTH
66 /**@}*/
67 
68 /** threshold above which an error handling procedure is triggered */
69 #define MXM_5X_ERROR_THRESHOLD (3u)
70 
71 /** time in milliseconds that should be waited in order to ensure that the slaves shut off */
72 #define MXM_5X_SLAVE_SHUTDOWN_TIMEOUT_MS (400u)
73 
74 /** (uint8_t) one byte bit mask */
75 #define MXM_5X_BIT_MASK_ONE_BYTE (0xFFu)
76 
77 /**
78  * @brief bit masks for writing the device address in write device command
79  */
80 #define MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS ((uint16_t)0xF8u)
81 
82 /*========== Static Constant and Variable Definitions =======================*/
83 
84 /*========== Extern Constant and Variable Definitions =======================*/
85 
86 /*========== Static Function Prototypes =====================================*/
87 
88 /**
89  * @brief Clear the command-buffer.
90  * @details Clears #MXM_5X_INSTANCE_s::commandBuffer by writing 0x00 to every entry.
91  * @param[in,out] pInstance pointer to the state-struct
92  * @return always return #STD_OK
93  */
94 static void MXM_5XClearCommandBuffer(MXM_5X_INSTANCE_s *pInstance);
95 
96 /**
97  * @brief Check if a register address is user accessible
98  * @details Checks if a register address is inside the user accessible memory
99  * range. This range is specified in the data sheet of the monitoring
100  * IC as following:
101  * - user memory is contained in the range 0x00 to 0x98
102  * - reserved addresses in the user address space are:
103  * - 0x2C, 0x2D, 0x2E, 0x2F
104  * - 0x46
105  * - 0x84 through 0x8B
106  * @param[in] regAddress register address to be checked
107  * @param[in] model model id of the IC that shall be addressed
108  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
109  */
110 static STD_RETURN_TYPE_e MXM_5XIsUserAccessibleRegister(uint8_t regAddress, MXM_MODEL_ID_e model);
111 
112 /**
113  * @brief Check if a register address is user accessible in MAX17852
114  * @details Checks if a register address is inside the user accessible memory
115  * range.
116  * This range is specified in the data sheet of the monitoring IC.
117  * @param[in] regAddress register address to be checked
118  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
119  */
120 static STD_RETURN_TYPE_e MXM_52IsUserAccessibleRegister(uint8_t regAddress);
121 
122 /**
123  * @brief Check if a register address is user accessible in MAX17853
124  * @details Checks if a register address is inside the user accessible memory
125  * range.
126  * This range is specified in the data sheet of the monitoring IC as
127  * the following:
128  * - user memory is contained in the range 0x00 to 0x98
129  * - reserved addresses in the user address space are:
130  * - 0x2C, 0x2D, 0x2E, 0x2F
131  * - 0x46
132  * - 0x84 through 0x8B
133  * @param[in] regAddress register address to be checked
134  * @return #STD_OK if the register address is good, otherwise #STD_NOT_OK
135  */
136 static STD_RETURN_TYPE_e MXM_53IsUserAccessibleRegister(uint8_t regAddress);
137 
138 /**
139  * @brief clears the command buffer and writes HELLOALL into the buffer
140  * @details Fills the command buffer with a HELLOALL message after having it
141  * cleaned.
142  * @param[in,out] pInstance pointer to the state-struct
143  */
145 
146 /**
147  * @brief clears the command buffer and writes WRITEALL into the buffer
148  * @details Fills the command buffer with a WRITEALL command. This command
149  * writes the same lsb and msb to every satellite in the daisy-chain
150  * in the same register. The data to be written has to be set before
151  * calling this function in #MXM_5X_INSTANCE_s::commandPayload.
152  * @param[in,out] pInstance pointer to the state-struct
153  * @return #STD_OK if an accessible register address has been selected,
154  * #STD_NOT_OK if not.
155  */
157 
158 /**
159  * @brief clears the command buffer and writes a WRITEDEVICE message
160  * @details Fills the command buffer with a WRITEDEVICE message. This message
161  * is addressed to one specific device in the daisy-chain. Therefore
162  * the address of the device has to be supplied together with the
163  * register and the data that should be written. The data to be
164  * written has to be set before calling this function in
165  * #MXM_5X_INSTANCE_s::commandPayload.
166  * @param[in,out] pInstance pointer to the state-struct
167  * @return #STD_OK if an accessible register address has been selected,
168  * #STD_NOT_OK if not.
169  */
171 
172 /**
173  * @brief clears the command buffer and writes READALL into the buffer
174  * @details Fills the command buffer with a READALL command. This command
175  * retrieves the LSB and MSB of exactly one register of every device
176  * in the daisy-chain. The data to be written has to be set before
177  * calling this function in #MXM_5X_INSTANCE_s::commandPayload.
178  * @param[in,out] pInstance pointer to the state-struct
179  * @return #STD_OK if an accessible register address has been selected,
180  * #STD_NOT_OK if not.
181  */
183 
184 /**
185  * @brief handles the error of the underlying state-machine (by resetting it and counting the error)
186  * @param[in,out] pInstance pointer to the state-struct
187  */
188 static void MXM_5XHandle41BErrorState(MXM_5X_INSTANCE_s *pInstance);
189 
190 /**
191  * @brief sets all internal state variables so that upon next execution the next substate is entered
192  * @param[out] pInstance pointer to the state-struct
193  * @param[in] substate identifier of the next substate
194  */
195 static void MXM_5XTransitionToSubstate(MXM_5X_INSTANCE_s *pInstance, MXM_5X_SUBSTATES_e substate);
196 
197 /**
198  * @brief repeat the current substate (by resetting to the entry state)
199  * @param[out] pInstance pointer to the state-struct
200  */
201 static void MXM_5XRepeatCurrentSubstate(MXM_5X_INSTANCE_s *pInstance);
202 
203 /**
204  * @brief Signal that a chain of substates has been successfully handled
205  * @param[out] pInstance pointer to the state-struct
206  */
207 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance);
208 
209 /**
210  * @brief Signal that an error has occurred in a chain of substates
211  * @param[out] pInstance pointer to the state-struct
212  */
213 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance);
214 
215 /**
216  * @brief Handle the state #MXM_STATEMACH_5X_41B_FMEA_CHECK
217  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
218  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
219  */
220 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
221 
222 /**
223  * @brief Handle the state #MXM_STATEMACH_5X_INIT
224  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
225  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
226  */
227 static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
228 
229 /**
230  * @brief Handle the state #MXM_STATEMACH_5X_WRITEALL
231  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
232  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
233  */
234 static void MXM_5XStateHandlerWriteAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
235 
236 /**
237  * @brief Handle the state #MXM_STATEMACH_5X_WRITE_DEVICE
238  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
239  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
240  */
241 static void MXM_5XStateHandlerWriteDevice(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
242 
243 /**
244  * @brief Handle the state #MXM_STATEMACH_5X_READALL
245  * @param[in,out] pInstance5x pointer to the state-struct of the battery management state machine
246  * @param[in,out] pInstance41b pointer to the state-struct of the bridge IC
247  */
248 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b);
249 
250 /*========== Static Function Implementations ================================*/
252  FAS_ASSERT(pInstance != NULL_PTR);
253  for (uint8_t i = 0; i < COMMAND_BUFFER_LENGTH; i++) {
254  pInstance->commandBuffer[i] = 0x00U;
255  }
257 }
258 
261 
262  STD_RETURN_TYPE_e retval = STD_NOT_OK;
263 
264  switch (model) {
266  retval = MXM_52IsUserAccessibleRegister(regAddress);
267  break;
269  retval = MXM_53IsUserAccessibleRegister(regAddress);
270  break;
272  case MXM_MODEL_ID_NONE:
274  /* not implemented or invalid model id */
275  break;
276  default:
277  /* invalid state, should not happen */
279  break;
280  }
281  return retval;
282 }
283 
285  STD_RETURN_TYPE_e retval = STD_NOT_OK;
286  /* check if regAddress is outside user-accessible area */
287  /* AXIVION Disable Style Generic-NoMagicNumbers: memory limits of ICs are specific and unchangeable, therefore hardcoded */
288  bool registerAddressIsInvalid = (regAddress == 0x5Du);
289  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress == 0x5Eu);
290  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress > 0x98u);
291  /* AXIVION Enable Style Generic-NoMagicNumbers: */
292 
293  if (registerAddressIsInvalid == false) {
294  /* valid MAX17852 register address */
295  retval = STD_OK;
296  }
297  return retval;
298 }
299 
301  STD_RETURN_TYPE_e retval = STD_NOT_OK;
302  /* check if regAddress is outside user-accessible area */
303  /* AXIVION Disable Style Generic-NoMagicNumbers: memory limits of ICs are specific and unchangeable, therefore hardcoded */
304  bool registerAddressIsInvalid = (regAddress == 0x46u);
305  registerAddressIsInvalid = registerAddressIsInvalid || ((0x2Cu <= regAddress) && (regAddress <= 0x2Fu));
306  registerAddressIsInvalid = registerAddressIsInvalid || ((0x84u <= regAddress) && (regAddress <= 0x8Bu));
307  registerAddressIsInvalid = registerAddressIsInvalid || (regAddress > 0x98u);
308  /* AXIVION Enable Style Generic-NoMagicNumbers: */
309 
310  if (registerAddressIsInvalid == false) {
311  /* valid MAX17853 register address */
312  retval = STD_OK;
313  }
314  return retval;
315 }
316 
318  FAS_ASSERT(pInstance != NULL_PTR);
319  MXM_5XClearCommandBuffer(pInstance);
321  pInstance->commandBuffer[1] = 0x00;
322  pInstance->commandBuffer[2] = HELLOALL_START_SEED;
323  pInstance->commandBufferCurrentLength = 3;
324 }
325 
327  FAS_ASSERT(pInstance != NULL_PTR);
328  STD_RETURN_TYPE_e retval = STD_NOT_OK;
329 
330  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
331  FAS_ASSERT(pPayload != NULL_PTR);
332 
333  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
334  /* clear command buffer */
335  MXM_5XClearCommandBuffer(pInstance);
336 
337  /* construct command buffer */
339  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
340  pInstance->commandBuffer[2] = pPayload->lsb;
341  pInstance->commandBuffer[3] = pPayload->msb;
342  /* PEC byte */
343  pInstance->commandBuffer[4] = MXM_CRC8(pInstance->commandBuffer, 4);
344  /* TODO alive-counter? */
345  pInstance->commandBufferCurrentLength = 5;
346  retval = STD_OK;
347  }
348 
349  return retval;
350 }
351 
353  FAS_ASSERT(pInstance != NULL_PTR);
354  STD_RETURN_TYPE_e retval = STD_NOT_OK;
355 
356  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
357  FAS_ASSERT(pPayload != NULL_PTR);
358 
359  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
360  /* clear command buffer */
361  MXM_5XClearCommandBuffer(pInstance);
362 
363  /* construct command buffer */
364 
365  /* commandBuffer[0] = Device address in a daisy chain + 0b100
366  * DA = deviceAddress
367  * Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
368  * Content | DA[4] | DA[3] | DA[2] | DA[1] | DA[0] | 1 | 0 | 0
369  */
370  pInstance->commandBuffer[0] =
371  ((((uint16_t)pPayload->deviceAddress << 3u) & MXM_5X_BIT_MASK_WRITE_DEVICE_ADDRESS) |
373  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
374  pInstance->commandBuffer[2] = pPayload->lsb;
375  pInstance->commandBuffer[3] = pPayload->msb;
376  /* PEC byte */
377  pInstance->commandBuffer[4] = MXM_CRC8(pInstance->commandBuffer, 4);
378  /* TODO alive-counter? */
379  pInstance->commandBufferCurrentLength = 5;
380  retval = STD_OK;
381  }
382 
383  return retval;
384 }
385 
387  FAS_ASSERT(pInstance != NULL_PTR);
388  STD_RETURN_TYPE_e retval = STD_NOT_OK;
389  /* TODO test these functions */
390 
391  const MXM_5X_COMMAND_PAYLOAD_s *const pPayload = &pInstance->commandPayload;
392  FAS_ASSERT(pPayload != NULL_PTR);
393 
394  if (MXM_5XIsUserAccessibleRegister((uint8_t)pPayload->regAddress, pPayload->model) == STD_OK) {
395  /* clear command buffer */
396  MXM_5XClearCommandBuffer(pInstance);
397 
398  /* construct command buffer */
400  pInstance->commandBuffer[1] = (uint8_t)pPayload->regAddress;
401  pInstance->commandBuffer[2] = DATA_CHECK_BYTE_SEED;
402  /* PEC byte */
403  pInstance->commandBuffer[3] = MXM_CRC8(pInstance->commandBuffer, 3);
404  /* TODO alive-counter? */
405  pInstance->commandBufferCurrentLength = 4;
406  retval = STD_OK;
407  }
408 
410  /* define containing command buffer length does
411  * not match actual buffer */
412  retval = STD_NOT_OK;
413  }
414 
415  return retval;
416 }
417 
419  FAS_ASSERT(pInstance != NULL_PTR);
420  pInstance->status41b = MXM_41B_STATE_UNSENT;
421  if (pInstance->errorCounter < (uint8_t)UINT8_MAX) {
422  pInstance->errorCounter++;
423  }
424  return;
425 }
426 
428  FAS_ASSERT(pInstance != NULL_PTR);
429  FAS_ASSERT(substate <= MXM_5X_ENTRY_SUBSTATE);
430  pInstance->substate = substate;
431  if ((pInstance->status41b == MXM_41B_STATE_PROCESSED) || (pInstance->status41b == MXM_41B_STATE_ERROR)) {
432  pInstance->status41b = MXM_41B_STATE_UNSENT;
433  }
434  return;
435 }
436 
438  FAS_ASSERT(pInstance != NULL_PTR);
439  pInstance->status41b = MXM_41B_STATE_UNSENT;
440  return;
441 }
442 
443 static void MXM_5XSignalSuccess(MXM_5X_INSTANCE_s *pInstance) {
444  FAS_ASSERT(pInstance != NULL_PTR);
446  FAS_ASSERT(pInstance->processed != NULL_PTR);
447  *pInstance->processed = MXM_5X_STATE_PROCESSED;
448  pInstance->state = MXM_STATEMACH_5X_IDLE;
449  return;
450 }
451 
452 static void MXM_5XSignalError(MXM_5X_INSTANCE_s *pInstance) {
453  FAS_ASSERT(pInstance != NULL_PTR);
455  FAS_ASSERT(pInstance->processed != NULL_PTR);
456  *pInstance->processed = MXM_5X_STATE_ERROR;
457  pInstance->state = MXM_STATEMACH_5X_IDLE;
458  return;
459 }
460 
461 static void MXM_5XStateHandler41BFmeaCheck(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
462  FAS_ASSERT(pInstance5x != NULL_PTR);
463  FAS_ASSERT(pInstance41b != NULL_PTR);
464  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
465  /* entry of state --> set to first substate */
467  }
468 
469  if (pInstance5x->substate == MXM_5X_41B_FMEA_REQUEST) {
470  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
471  pInstance41b, MXM_STATEMACH_41B_CHECK_FMEA, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
472  FAS_ASSERT(stateRequestReturn == STD_OK);
474  } else if (pInstance5x->substate == MXM_5X_41B_FMEA_CHECK) {
475  if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
476  /* wait for processing */
477  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
478  /* failure in FMEA; signal error */
479  MXM_5XSignalError(pInstance5x);
480  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
481  MXM_5XSignalSuccess(pInstance5x);
482  } else {
484  }
485  } else {
487  }
488 }
489 
490 static void MXM_5XStateHandlerInit(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
491  FAS_ASSERT(pInstance5x != NULL_PTR);
492  FAS_ASSERT(pInstance41b != NULL_PTR);
493  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
494  /* entry of state --> set to first substate */
496  }
497 
498  if (pInstance5x->substate == MXM_5X_INIT_41B_INIT) {
499  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
500  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
501  pInstance41b, MXM_STATEMACH_41B_INIT, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
502  FAS_ASSERT(stateRequestReturn == STD_OK);
503  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
504  /* wait for processing */
505  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
506  MXM_5XHandle41BErrorState(pInstance5x);
507  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
509  pInstance5x->resetWaitTimestamp = OS_GetTickCount();
510  } else {
512  }
513  } else if (pInstance5x->substate == MXM_5X_INIT_41B_GET_VERSION) {
514  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
515  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
516  pInstance41b, MXM_STATEMACH_41B_GET_VERSION, NULL_PTR, 0, 0, NULL_PTR, 0, &pInstance5x->status41b);
517  FAS_ASSERT(stateRequestReturn == STD_OK);
518  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
519  /* wait for processing */
520  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
521  MXM_5XHandle41BErrorState(pInstance5x);
522  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
524  } else {
526  }
527  } else if (pInstance5x->substate == MXM_5X_INIT_WAIT_FOR_RESET) {
528  /* wait so that shutdown low of the satellites discharges and they switch off */
529  const bool shutdownTimeoutHasPassed =
531  if (shutdownTimeoutHasPassed) {
533  }
534  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_RX_INTERRUPT_FLAGS) {
535  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
536  const STD_RETURN_TYPE_e writeRegisterRxErrorReturn =
538  FAS_ASSERT(writeRegisterRxErrorReturn == STD_OK);
539  const STD_RETURN_TYPE_e writeRegisterRxOverflowReturn =
541  FAS_ASSERT(writeRegisterRxOverflowReturn == STD_OK);
542 
543  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
544  pInstance41b,
546  NULL_PTR,
547  0,
548  0,
549  NULL_PTR,
550  0,
551  &pInstance5x->status41b);
552  FAS_ASSERT(stateRequestReturn == STD_OK);
553  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
554  /* wait for processing */
555  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
556  MXM_5XHandle41BErrorState(pInstance5x);
557  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
559  } else {
561  }
563  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
564  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
565  pInstance41b,
567  NULL_PTR,
568  0,
569  0,
570  NULL_PTR,
571  0,
572  &pInstance5x->status41b);
573  FAS_ASSERT(stateRequestReturn == STD_OK);
574  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
575  /* wait for processing */
576  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
577  MXM_5XHandle41BErrorState(pInstance5x);
578  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
580  } else {
582  }
584  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
585  const STD_RETURN_TYPE_e writeRegisterReturn =
587  FAS_ASSERT(writeRegisterReturn == STD_OK);
588 
589  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
590  pInstance41b,
592  NULL_PTR,
593  0,
594  0,
595  NULL_PTR,
596  0,
597  &pInstance5x->status41b);
598  FAS_ASSERT(stateRequestReturn == STD_OK);
599  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
600  /* wait for processing */
601  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
602  MXM_5XHandle41BErrorState(pInstance5x);
603  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
605  } else {
607  }
608  } else if (pInstance5x->substate == MXM_5X_INIT_ENABLE_KEEP_ALIVE) {
609  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
610  const uint8_t mxm_kConfig3KeepAlive160us41BRegister = 0x05;
611  const STD_RETURN_TYPE_e writeRegisterReturn = MXM_41BWriteRegisterFunction(
612  pInstance41b, MXM_41B_REG_FUNCTION_KEEP_ALIVE, mxm_kConfig3KeepAlive160us41BRegister);
613  FAS_ASSERT(writeRegisterReturn == STD_OK);
614 
615  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
616  pInstance41b,
618  NULL_PTR,
619  0,
620  0,
621  NULL_PTR,
622  0,
623  &pInstance5x->status41b);
624  FAS_ASSERT(stateRequestReturn == STD_OK);
625  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
626  /* wait for processing */
627  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
628  MXM_5XHandle41BErrorState(pInstance5x);
629  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
631  } else {
633  }
635  /* wait for rx status change busy */
636  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
637  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
638  pInstance41b,
640  NULL_PTR,
641  0,
642  0,
643  NULL_PTR,
644  0,
645  &pInstance5x->status41b);
646  FAS_ASSERT(stateRequestReturn == STD_OK);
647  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
648  /* wait for processing */
649  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
650  MXM_5XHandle41BErrorState(pInstance5x);
651  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
652  MXM_41B_REG_BIT_VALUE functionValue;
653  const STD_RETURN_TYPE_e readRegisterReturn =
655  FAS_ASSERT(readRegisterReturn == STD_OK);
656  if (functionValue == MXM_41B_REG_FALSE) {
657  MXM_5XRepeatCurrentSubstate(pInstance5x);
658  } else if (functionValue == MXM_41B_REG_TRUE) {
660  } else {
662  }
663  } else {
665  }
667  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
668  const STD_RETURN_TYPE_e writeRegisterReturn =
670  FAS_ASSERT(writeRegisterReturn == STD_OK);
671 
672  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
673  pInstance41b,
675  NULL_PTR,
676  0,
677  0,
678  NULL_PTR,
679  0,
680  &pInstance5x->status41b);
681  FAS_ASSERT(stateRequestReturn == STD_OK);
682  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
683  /* wait for processing */
684  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
685  MXM_5XHandle41BErrorState(pInstance5x);
686  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
688  } else {
690  }
692  /* wait for rx status change busy */
693  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
694  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
695  pInstance41b,
697  NULL_PTR,
698  0,
699  0,
700  NULL_PTR,
701  0,
702  &pInstance5x->status41b);
703  FAS_ASSERT(stateRequestReturn == STD_OK);
704  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
705  /* wait for processing */
706  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
707  MXM_5XHandle41BErrorState(pInstance5x);
708  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
709  MXM_41B_REG_BIT_VALUE functionValue;
710  const STD_RETURN_TYPE_e readRegisterReturn =
712  FAS_ASSERT(readRegisterReturn == STD_OK);
713 
714  if (functionValue == MXM_41B_REG_TRUE) {
715  MXM_5XRepeatCurrentSubstate(pInstance5x);
716  } else if (functionValue == MXM_41B_REG_FALSE) {
718  } else {
720  }
721  } else {
723  }
725  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
726  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
727  pInstance41b,
729  NULL_PTR,
730  0,
731  0,
732  NULL_PTR,
733  0,
734  &pInstance5x->status41b);
735  FAS_ASSERT(stateRequestReturn == STD_OK);
736  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
737  /* wait for processing */
738  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
739  MXM_5XHandle41BErrorState(pInstance5x);
740  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
742  } else {
744  }
746  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
747  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
748  pInstance41b,
750  NULL_PTR,
751  0,
752  0,
753  NULL_PTR,
754  0,
755  &pInstance5x->status41b);
756  FAS_ASSERT(stateRequestReturn == STD_OK);
757  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
758  /* wait for processing */
759  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
760  MXM_5XHandle41BErrorState(pInstance5x);
761  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
763  } else {
765  }
766  } else if (pInstance5x->substate == MXM_5X_INIT_WAKE_UP_SATELLITE_DEVICES_HELLOALL) {
767  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
769  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
770  pInstance41b,
772  pInstance5x->commandBuffer,
773  pInstance5x->commandBufferCurrentLength,
774  0,
775  pInstance5x->rxBuffer,
777  &pInstance5x->status41b);
778  FAS_ASSERT(stateRequestReturn == STD_OK);
779  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
780  /* wait for processing */
781  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
782  MXM_5XHandle41BErrorState(pInstance5x);
783  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
785  } else {
787  }
788  /* TODO check for receive buffer errors and handle */
790  /* check if the commandBuffer matches with the receive buffer */
791  STD_RETURN_TYPE_e commandBufferMatchesReceiveBuffer = STD_OK;
792  for (uint8_t i = 0u; i < (pInstance5x->commandBufferCurrentLength - 1u); i++) {
793  if (pInstance5x->commandBuffer[i] != pInstance5x->rxBuffer[i]) {
794  commandBufferMatchesReceiveBuffer = STD_NOT_OK;
795  }
796  }
797  /* update number of satellites */
798  pInstance5x->numberOfSatellites = (uint8_t)(
800 
801  /* Plausibility check, compare with preset number of satellites */
802  if (pInstance5x->numberOfSatellites == (BS_NR_OF_MODULES * BS_NR_OF_STRINGS)) {
803  pInstance5x->numberOfSatellitesIsGood = STD_OK;
804  }
805 
806  if (commandBufferMatchesReceiveBuffer == STD_NOT_OK) {
807  /* TODO error handling */
808  } else {
809  MXM_5XSignalSuccess(pInstance5x);
810  }
811  } else {
812  /* something is very broken */
814  }
815 }
816 
817 static void MXM_5XStateHandlerWriteAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
818  FAS_ASSERT(pInstance5x != NULL_PTR);
819  FAS_ASSERT(pInstance41b != NULL_PTR);
820  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
821  /* entry of state --> set to first substate */
823  }
824 
825  if (pInstance5x->substate == MXM_5X_WRITEALL_UART_TRANSACTION) {
826  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
827  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteall(pInstance5x);
828  FAS_ASSERT(resultAddressCorrect == STD_OK);
829  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
830  pInstance41b,
832  pInstance5x->commandBuffer,
833  pInstance5x->commandBufferCurrentLength,
834  0,
835  pInstance5x->rxBuffer,
836  pInstance5x->commandBufferCurrentLength,
837  &pInstance5x->status41b);
838  /* TODO check CRC */
839  FAS_ASSERT(stateRequestReturn == STD_OK);
840  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
841  /* wait for processing */
842  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
843  MXM_5XHandle41BErrorState(pInstance5x);
844  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
845  MXM_5XSignalSuccess(pInstance5x);
846  } else {
848  }
849  }
850 }
851 
852 static void MXM_5XStateHandlerWriteDevice(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
853  FAS_ASSERT(pInstance5x != NULL_PTR);
854  FAS_ASSERT(pInstance41b != NULL_PTR);
855  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
856  /* entry of state --> set to first substate */
858  }
859 
860  if (pInstance5x->substate == MXM_5X_WRITE_DEVICE_UART_TRANSACTION) {
861  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
862  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferWriteDevice(pInstance5x);
863  FAS_ASSERT(resultAddressCorrect == STD_OK);
864  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
865  pInstance41b,
867  pInstance5x->commandBuffer,
868  pInstance5x->commandBufferCurrentLength,
869  0,
870  pInstance5x->rxBuffer,
871  pInstance5x->commandBufferCurrentLength,
872  &pInstance5x->status41b);
873  FAS_ASSERT(stateRequestReturn == STD_OK);
874  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
875  /* wait for processing */
876  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
877  MXM_5XHandle41BErrorState(pInstance5x);
878  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
879  MXM_5XSignalSuccess(pInstance5x); /* TODO continue and check CRC */
880  } else {
882  }
883  }
884 }
885 
886 static void MXM_5XStateHandlerReadAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b) {
887  FAS_ASSERT(pInstance5x != NULL_PTR);
888  FAS_ASSERT(pInstance41b != NULL_PTR);
889  if (pInstance5x->substate == MXM_5X_ENTRY_SUBSTATE) {
890  /* entry of state --> set to first substate */
892  }
893 
894  if (pInstance5x->substate == MXM_5X_READALL_UART_TRANSACTION) {
895  if (pInstance5x->status41b == MXM_41B_STATE_UNSENT) {
896  const STD_RETURN_TYPE_e resultAddressCorrect = MXM_5XConstructCommandBufferReadall(pInstance5x);
897  FAS_ASSERT(resultAddressCorrect == STD_OK);
898  /* TODO parse rx buffer here into values and parse CRC before passing on*/
899  /* stretch message length in order to accommodate 2 bytes per satellite */
900  const STD_RETURN_TYPE_e stateRequestReturn = MXM_41BSetStateRequest(
901  pInstance41b,
903  pInstance5x->commandBuffer,
904  pInstance5x->commandBufferCurrentLength,
905  2u * pInstance5x->numberOfSatellites,
906  pInstance5x->rxBuffer,
908  &pInstance5x->status41b);
909  FAS_ASSERT(stateRequestReturn == STD_OK);
910  } else if (pInstance5x->status41b == MXM_41B_STATE_UNPROCESSED) {
911  /* wait for processing */
912  } else if (pInstance5x->status41b == MXM_41B_STATE_ERROR) {
913  MXM_5XHandle41BErrorState(pInstance5x);
914  } else if (pInstance5x->status41b == MXM_41B_STATE_PROCESSED) {
916  } else {
918  }
919  } else if (pInstance5x->substate == MXM_5X_READALL_CHECK_CRC) {
920  /* check CRC */
921  if (MXM_CRC8(
922  pInstance5x->rxBuffer,
923  ((int32_t)pInstance5x->commandBufferCurrentLength + (2 * (int32_t)pInstance5x->numberOfSatellites))) ==
924  0x00u) {
926  } else {
927  MXM_5XSignalError(pInstance5x);
928  }
929  } else if (pInstance5x->substate == MXM_5X_READALL_GET_DC) {
930  /* get DC */ /* TODO check DC in this state */
931  /* dc byte position is after data */
932  FAS_ASSERT(((uint16_t)2u + ((uint16_t)2u * pInstance5x->numberOfSatellites)) <= (uint16_t)UINT8_MAX);
933  uint8_t dc_byte_position = 2u + (2u * pInstance5x->numberOfSatellites);
934 
935  pInstance5x->lastDCByte = (uint8_t)(pInstance5x->rxBuffer[dc_byte_position] & MXM_5X_BIT_MASK_ONE_BYTE);
936 
937  MXM_5XSignalSuccess(pInstance5x);
938  } else {
940  }
941 }
942 
943 /*========== Extern Function Implementations ================================*/
944 
946  FAS_ASSERT(pInstance != NULL_PTR);
947 
949  pInstance->substate = MXM_5X_ENTRY_SUBSTATE;
951  pInstance->commandPayload.lsb = 0u;
952  pInstance->commandPayload.msb = 0u;
953  pInstance->commandPayload.blocksize = 0u;
954  pInstance->commandPayload.deviceAddress = 0u;
955  pInstance->processed = NULL_PTR;
956  pInstance->status41b = MXM_41B_STATE_UNSENT;
957  pInstance->numberOfSatellites = 0u;
959  pInstance->lastDCByte = 0u;
960  pInstance->errorCounter = 0u;
961  pInstance->resetWaitTimestamp = 0u;
962  pInstance->commandBufferCurrentLength = 0u;
963 
964  for (uint32_t i = 0u; i < COMMAND_BUFFER_LENGTH; i++) {
965  pInstance->commandBuffer[i] = 0u;
966  }
967 
968  for (uint32_t i = 0u; i < MXM_5X_RX_BUFFER_LEN; i++) {
969  pInstance->rxBuffer[i] = 0u;
970  }
971 }
972 
974  const MXM_5X_INSTANCE_s *const kpkInstance,
975  uint8_t *rxBuffer,
976  uint16_t rxBufferLength) {
977  FAS_ASSERT(kpkInstance != NULL_PTR);
978  FAS_ASSERT(rxBufferLength <= MXM_5X_RX_BUFFER_LEN);
979  STD_RETURN_TYPE_e retval = STD_OK;
980 
981  if ((rxBuffer != NULL_PTR) && (rxBufferLength != 0u)) {
982  for (uint16_t i = 0; i < rxBufferLength; i++) {
983  if (i < MXM_5X_RX_BUFFER_LEN) {
984  rxBuffer[i] = (uint8_t)(kpkInstance->rxBuffer[i] & MXM_5X_BIT_MASK_ONE_BYTE);
985  }
986  }
987  } else {
988  retval = STD_NOT_OK;
989  }
990 
991  return retval;
992 }
993 
994 extern MXM_DC_BYTE_e MXM_5XGetLastDCByte(const MXM_5X_INSTANCE_s *const kpkInstance) {
995  FAS_ASSERT(kpkInstance != NULL_PTR);
996  return (MXM_DC_BYTE_e)kpkInstance->lastDCByte;
997 }
998 
999 extern uint8_t MXM_5XGetNumberOfSatellites(const MXM_5X_INSTANCE_s *const kpkInstance) {
1000  FAS_ASSERT(kpkInstance != NULL_PTR);
1001  const uint8_t numberOfSatellites = kpkInstance->numberOfSatellites;
1002  FAS_ASSERT(numberOfSatellites <= MXM_MAXIMUM_NR_OF_MODULES);
1003  return numberOfSatellites;
1004 }
1005 
1007  FAS_ASSERT(kpkInstance != NULL_PTR);
1008  return kpkInstance->numberOfSatellitesIsGood;
1009 }
1010 
1012  MXM_5X_INSTANCE_s *pInstance5x,
1013  MXM_STATEMACHINE_5X_e state,
1014  MXM_5X_COMMAND_PAYLOAD_s commandPayload,
1015  MXM_5X_STATE_REQUEST_STATUS_e *processed) {
1016  FAS_ASSERT(pInstance5x != NULL_PTR);
1017  STD_RETURN_TYPE_e retval = STD_OK;
1018  if (state >= MXM_STATEMACH_5X_MAXSTATE) {
1019  retval = STD_NOT_OK;
1020  } else if (processed == NULL_PTR) {
1021  retval = STD_NOT_OK;
1022  } else if (pInstance5x->state == MXM_STATEMACH_5X_UNINITIALIZED) {
1023  if (state == MXM_STATEMACH_5X_INIT) {
1024  pInstance5x->state = state;
1025  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1026  pInstance5x->commandPayload = commandPayload;
1027  pInstance5x->processed = processed;
1028  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1029  } else {
1030  retval = STD_NOT_OK;
1031  }
1032  } else if (pInstance5x->state == MXM_STATEMACH_5X_IDLE) {
1033  pInstance5x->state = state;
1034  pInstance5x->substate = MXM_5X_ENTRY_SUBSTATE;
1035  pInstance5x->commandPayload = commandPayload;
1036  pInstance5x->processed = processed;
1037  *pInstance5x->processed = MXM_5X_STATE_UNPROCESSED;
1038  } else {
1039  retval = STD_NOT_OK;
1040  }
1041  return retval;
1042 }
1043 
1044 void MXM_5XStateMachine(MXM_41B_INSTANCE_s *pInstance41b, MXM_5X_INSTANCE_s *pInstance5x) {
1045  FAS_ASSERT(pInstance41b != NULL_PTR);
1046  FAS_ASSERT(pInstance5x != NULL_PTR);
1047 
1048  /* failure handling */
1049  if (pInstance5x->errorCounter > MXM_5X_ERROR_THRESHOLD) {
1050  /* error, reset both this state-machine and the underlying */
1051  pInstance41b->state = MXM_STATEMACH_41B_IDLE;
1052  pInstance41b->substate = MXM_41B_ENTRY_SUBSTATE;
1053  pInstance41b->waitCounter = 0u;
1054  MXM_5XSignalError(pInstance5x);
1055  pInstance5x->errorCounter = 0u;
1056  }
1057 
1058  switch (pInstance5x->state) {
1060  /* statemachine waits here for initialization */
1061  break;
1062  case MXM_STATEMACH_5X_IDLE:
1063  /* idle state currently does nothing */
1064  break;
1066  MXM_5XStateHandler41BFmeaCheck(pInstance5x, pInstance41b);
1067  break;
1068  case MXM_STATEMACH_5X_INIT:
1069  MXM_5XStateHandlerInit(pInstance5x, pInstance41b);
1070  break;
1072  MXM_5XStateHandlerWriteAll(pInstance5x, pInstance41b);
1073  break;
1075  MXM_5XStateHandlerWriteDevice(pInstance5x, pInstance41b);
1076  break;
1078  MXM_5XStateHandlerReadAll(pInstance5x, pInstance41b);
1079  break;
1080  default:
1082  break;
1083  }
1084 }
1085 
1087  /* check:
1088  * - user memory is contained in range 0x00 to 0x98
1089  * - reserved addresses in user address space:
1090  * 0x2C, 0x2D, 0x2E, 0x2F, 0x46 and 0x84 through 0x8B */
1091 
1092  /* AXIVION Disable Style Generic-NoMagicNumbers: This test function uses magic numbers to test predefined values. */
1093  /* expected #STD_OK */
1097 
1101 
1105 
1106  /* expected #STD_NOT_OK */
1113 
1117 
1118  /* AXIVION Enable Style Generic-NoMagicNumbers: */
1119 
1120  STD_RETURN_TYPE_e retval = STD_NOT_OK;
1121 
1122  if ((retval_check0 == STD_OK) && (retval_check1 == STD_OK) && (retval_check2 == STD_OK) &&
1123  (retval_check3 == STD_OK) && (retval_check4 == STD_OK) && (retval_check5 == STD_OK) &&
1124  (retval_check6 == STD_OK) && (retval_check7 == STD_OK) && (retval_check8 == STD_OK) &&
1125  (retval_check9 == STD_NOT_OK) && (retval_check10 == STD_NOT_OK) && (retval_check11 == STD_NOT_OK) &&
1126  (retval_check12 == STD_NOT_OK) && (retval_check13 == STD_NOT_OK) && (retval_check14 == STD_NOT_OK) &&
1127  (retval_check15 == STD_NOT_OK) && (retval_check16 == STD_NOT_OK) && (retval_check17 == STD_NOT_OK)) {
1128  retval = STD_OK;
1129  }
1130  return retval;
1131 }
1132 
1133 /*========== Externalized Static Function Implementations (Unit Test) =======*/
#define BS_NR_OF_STRINGS
#define BS_NR_OF_MODULES
number of modules in battery pack
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:235
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:110
@ STD_NOT_OK
Definition: fstd_types.h:82
@ STD_OK
Definition: fstd_types.h:81
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:75
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
#define must_check_return
Allows functions to generate warnings in GCC for unused returns.
Definition: general.h:101
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:775
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:831
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:875
@ MXM_STATEMACH_41B_GET_VERSION
Definition: mxm_17841b.h:88
@ MXM_STATEMACH_41B_CLEAR_RECEIVE_BUFFER
Definition: mxm_17841b.h:92
@ MXM_STATEMACH_41B_CLEAR_TRANSMIT_BUFFER
Definition: mxm_17841b.h:93
@ MXM_STATEMACH_41B_INIT
Definition: mxm_17841b.h:85
@ MXM_STATEMACH_41B_WRITE_CONF_AND_INT_REGISTER
Definition: mxm_17841b.h:89
@ MXM_STATEMACH_41B_CHECK_FMEA
Definition: mxm_17841b.h:87
@ MXM_STATEMACH_41B_READ_STATUS_REGISTER
Definition: mxm_17841b.h:90
@ MXM_STATEMACH_41B_IDLE
Definition: mxm_17841b.h:86
@ MXM_STATEMACH_41B_UART_TRANSACTION
Definition: mxm_17841b.h:91
@ MXM_41B_ENTRY_SUBSTATE
Definition: mxm_17841b.h:101
@ MXM_41B_REG_FUNCTION_RX_BUSY_STATUS
Definition: mxm_17841b.h:141
@ MXM_41B_REG_FUNCTION_RX_EMPTY_STATUS
Definition: mxm_17841b.h:144
@ MXM_41B_REG_FUNCTION_TX_PREAMBLES
Definition: mxm_17841b.h:145
@ MXM_41B_REG_FUNCTION_RX_ERROR_INT
Definition: mxm_17841b.h:147
@ MXM_41B_REG_FUNCTION_KEEP_ALIVE
Definition: mxm_17841b.h:146
@ MXM_41B_REG_FUNCTION_RX_OVERFLOW_INT
Definition: mxm_17841b.h:148
@ MXM_41B_STATE_UNSENT
Definition: mxm_17841b.h:131
@ MXM_41B_STATE_ERROR
Definition: mxm_17841b.h:134
@ MXM_41B_STATE_UNPROCESSED
Definition: mxm_17841b.h:132
@ MXM_41B_STATE_PROCESSED
Definition: mxm_17841b.h:133
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.
STD_RETURN_TYPE_e must_check_return MXM_5XUserAccessibleAddressSpaceCheckerSelfCheck(void)
runs a selfcheck for the address space check
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
static void MXM_5XStateHandlerWriteAll(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b)
Handle the state MXM_STATEMACH_5X_WRITEALL.
#define MXM_5X_BIT_MASK_ONE_BYTE
static void MXM_5XClearCommandBuffer(MXM_5X_INSTANCE_s *pInstance)
Clear the command-buffer.
static void MXM_5XStateHandlerWriteDevice(MXM_5X_INSTANCE_s *pInstance5x, MXM_41B_INSTANCE_s *pInstance41b)
Handle the state MXM_STATEMACH_5X_WRITE_DEVICE.
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_WRITEALL_UART_TRANSACTION
@ 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_WRITE_DEVICE_UART_TRANSACTION
@ 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_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:130
@ 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:140
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:129
Struct for the state-variable of state-machine.
Definition: mxm_17841b.h:157
MXM_41B_SUBSTATES_e substate
Definition: mxm_17841b.h:159
MXM_STATEMACH_41B_e state
Definition: mxm_17841b.h:158
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
uint16_t rxBuffer[100]