foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
mxm_17841b.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file mxm_17841b.c
44  * @author foxBMS Team
45  * @date 2018-12-14 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix MXM
50  *
51  * @brief Driver for the MAX17841B ASCI and MAX1785x analog front-end
52  *
53  * @details def
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "mxm_17841b.h"
59 
60 #include "fassert.h"
61 #include "fstd_types.h"
62 #include "mxm_41b_register_map.h"
63 #include "mxm_bitextract.h"
64 #include "os.h"
65 
66 #include <stdint.h>
67 
68 /*========== Macros and Definitions =========================================*/
69 /** bit shift half byte length */
70 #define MXM_41B_BIT_SHIFT_HALF_BYTE (4u)
71 
72 /** low nibble (of uint8_t) bit mask */
73 #define MXM_41B_BIT_MASK_LOW_NIBBLE (0xFu)
74 
75 /** high nibble (of uint8_t) bit mask */
76 #define MXM_41B_BIT_MASK_HIGH_NIBBLE (0xF0u)
77 
78 /** (uint8_t) one byte bit mask */
79 #define MXM_41B_BIT_MASK_ONE_BYTE (0xFFu)
80 
81 /** threshold above which a reset in this driver occurs in case of hangup */
82 #define MXM_41B_WAIT_COUNTER_THRESHOLD (75u)
83 #if MXM_41B_WAIT_COUNTER_THRESHOLD > (UINT8_MAX - 1)
84 #error "invalid wait counter threshold (counter is implemented in uint8_t)"
85 #endif
86 
87 /**
88  * time interval that shall ensure that the bridge IC is completely reset in ms
89  */
90 #define MXM_41B_BRIDGE_RESET_TIME_MS (100u)
91 
92 /** default config register bank length
93  *
94  * Length of the array that writes the registers referenced in
95  * mxm_41B_reg_default_values in #MXM_41BStateHandlerInit().
96  */
97 #define MXM_41B_CONFIG_REGISTER_LENGTH (7u)
98 
99 /*========== Static Constant and Variable Definitions =======================*/
100 
101 /*========== Extern Constant and Variable Definitions =======================*/
102 
103 /*========== Static Function Prototypes =====================================*/
104 /* static MXM_SPI_STATE_s mxm_proto_enable_keep_alive(void); */
105 /**
106  * @brief Write one or multiple registers of MAX17841B.
107  *
108  * This function puts together a SPI message consisting of command
109  * and payload and writes it to the assigned SPI interface.
110  *
111  * The command should be one of the #MXM_41B_REG_ADD_t commands.
112  * The function checks whether the chosen command is a write command.
113  *
114  * The payload-length has to be consistent with the payload.
115  * Payload-lengths of one will write to one register only. Longer payloads
116  * will write to adjacent registers. Please see the MAX17841B data sheet
117  * for reference.
118  *
119  * @param[in,out] pInstance pointer to the state of the MAX17841B-state-machine
120  * @param[in] command register command of #MXM_41B_REG_ADD_t
121  * @param[in] kpkPayload pointer to an array of data to be written
122  * @param[in] lengthPayload length of the payload array
123  * @return #STD_NOT_OK for inconsistent input or a blocked SPI interface,
124  * otherwise #STD_OK
125  */
127  MXM_41B_INSTANCE_s *pInstance,
128  MXM_41B_REG_ADD_t command,
129  const uint8_t *const kpkPayload,
130  uint8_t lengthPayload);
131 
132 /**
133  * @brief Read one or multiple registers of MAX17841B.
134  *
135  * This function puts together a SPI message consisting of command
136  * and bit-stuffing and writes it to the assigned SPI-interface.
137  *
138  * The command should be one of the #MXM_41B_REG_ADD_t commands.
139  * The function checks whether the chosen command is a read command.
140  *
141  * The RX buffer length has to be consistent with the RX buffer.
142  * RX buffer lengths of one will read one register only. Longer RX buffers
143  * will read also from adjacent registers. Please see the MAX17841B data sheet
144  * for reference.
145  *
146  * @param[in,out] pInstance pointer to the state of the MAX17841B-state-machine
147  * @param[in] command register command of #MXM_41B_REG_ADD_t
148  * @param[out] pRxBuffer pointer to an array into which read data will be written
149  * @param[in] length length of the RX buffer array
150  * @return #STD_NOT_OK for inconsistent input or a blocked SPI interface,
151  * otherwise #STD_OK
152  */
154  MXM_41B_INSTANCE_s *pInstance,
155  MXM_41B_REG_ADD_t command,
156  uint16_t *pRxBuffer,
157  uint8_t length);
158 
159 /**
160  * @brief Write the config register of MAX17841B.
161  *
162  * This functions writes the config registers with the values
163  * from the local register copies. It puts together a
164  * buffer from these register values and calls MXM_41BRegisterWrite()
165  * with this data.
166  * Calling this function will clear the interrupt registers and reset them
167  * to their default values (which is #MXM_41B_RX_INT_FLAG_DEFAULT_VALUE and
168  * #MXM_41B_TX_INT_FLAG_DEFAULT_VALUE).
169  *
170  * @param[in,out] pInstance state pointer
171  * @return returnvalue of #MXM_41BRegisterWrite()
172  */
174 
175 /**
176  * @brief Write a buffer transaction to MAX17841B.
177  *
178  * Writes into the load-queue-buffer.
179  * The supplied-message-length marks the length of the Battery Management
180  * Protocol message without any stuffing-bytes for read-commands.
181  * The extendMessage parameter describes with how much bytes the
182  * command shall be stretched. This number will be added to the
183  * length of the command and written into the length field of the
184  * buffer.
185  * After this action the user has to select the next load queue with
186  * the appropriate command in order to mark the load queue as sendable.
187  *
188  * @param[in,out] pInstance pointer to the state of the MAX17841B-state-machine
189  * @param[in] kpkMessage pointer to an array containing the message
190  * @param[in] messageLength length of the supplied array
191  * @param[in] extendMessage stretch the message by number of bytes
192  * @return #STD_NOT_OK for inconsistent input or a blocked SPI interface,
193  * otherwise #STD_OK
194  */
196  MXM_41B_INSTANCE_s *pInstance,
197  const uint16_t *const kpkMessage,
198  uint8_t messageLength,
199  uint8_t extendMessage);
200 
201 /**
202  * @brief Transition into idle, mark as successful
203  * @param[out] pInstance pointer to the state-struct
204  */
205 static void MXM_41BTransitionToIdleSuccess(MXM_41B_INSTANCE_s *pInstance);
206 
207 /**
208  * @brief Transition into idle, mark as an error occurred
209  * @param[out] pInstance pointer to the state-struct
210  */
211 static void MXM_41BTransitionToIdleError(MXM_41B_INSTANCE_s *pInstance);
212 
213 /**
214  * @brief Reset register copies to default
215  * @param[out] pInstance pointer to the state-struct
216  */
218 
219 /**
220  * \defgroup mxm-41b-state-handlers State handler functions for #MXM_41BStateMachine()
221  * @{
222  */
223 
224 /**
225  * @brief init state handler
226  * @details This function contains all states for #MXM_STATEMACH_41B_INIT.
227  * @param[in,out] pInstance pointer to the state-struct
228  */
229 static void MXM_41BStateHandlerInit(MXM_41B_INSTANCE_s *pInstance);
230 
231 /**
232  * @brief state handler for "get version"
233  * @details This function contains all states for #MXM_STATEMACH_41B_GET_VERSION.
234  * @param[in,out] pInstance pointer to the state-struct
235  */
236 static void MXM_41BStateHandlerGetVersion(MXM_41B_INSTANCE_s *pInstance);
237 
238 /**
239  * @brief state handler for "idle"
240  * @details This function contains all states for #MXM_STATEMACH_41B_IDLE.
241  * @param[in,out] pInstance pointer to the state-struct
242  */
243 static void MXM_41BStateHandlerIdle(MXM_41B_INSTANCE_s *pInstance);
244 
245 /**
246  * @brief state handler for "write conf and int register"
247  * @details This functions contains all states for #MXM_STATEMACH_41B_WRITE_CONF_AND_INT_REGISTER.
248  * @param[in,out] pInstance pointer to the state-struct
249  */
251 
252 /**
253  * @brief state handler for "read status register"
254  * @details This functions contains all states for #MXM_STATEMACH_41B_READ_STATUS_REGISTER.
255  * @param[in,out] pInstance pointer to the state-struct
256  */
258 
259 /**
260  * @brief state handler for "uart transaction"
261  * @details This functions contains all states for #MXM_STATEMACH_41B_UART_TRANSACTION.
262  * @param[in,out] pInstance pointer to the state-struct
263  */
265 
266 /**
267  * @brief state handler for "check fmea"
268  * @details This functions contains all states for #MXM_STATEMACH_41B_CHECK_FMEA.
269  * @param[in,out] pInstance pointer to the state-struct
270  */
271 static void MXM_41BStateHandlerCheckFmea(MXM_41B_INSTANCE_s *pInstance);
272 
273 /**
274  * @brief state handler for "clear receive buffer"
275  * @details This functions contains all states for #MXM_STATEMACH_41B_CLEAR_RECEIVE_BUFFER.
276  * @param[in,out] pInstance pointer to the state-struct
277  */
279 
280 /**
281  * @brief state handler for "clear transmit buffer"
282  * @details This functions contains all states for #MXM_STATEMACH_41B_CLEAR_TRANSMIT_BUFFER.
283  * @param[in,out] pInstance pointer to the state-struct
284  */
286 
287 /** @} */
288 
289 /*========== Static Function Implementations ================================*/
291  MXM_41B_INSTANCE_s *pInstance,
292  MXM_41B_REG_ADD_t command,
293  const uint8_t *const kpkPayload,
294  uint8_t lengthPayload) {
295  /* sanity check: state-pointer may not be null */
296  FAS_ASSERT(pInstance != NULL_PTR);
297  FAS_ASSERT(lengthPayload < (MXM_SPI_TX_BUFFER_LENGTH - 1u));
298  /* AXIVION Routine Generic-MissingParameterAssert: command: parameter accepts whole range */
299  /* AXIVION Routine Generic-MissingParameterAssert: kpkPayload: pointer may be NULL */
300 
301  STD_RETURN_TYPE_e retval = STD_NOT_OK;
302  /* check if command is a write command (write addresses in MAX17841B are even) */
303  if ((command % 2u) == 0u) {
304  /* construct tx buffer */
305  pInstance->spiTxBuffer[0] = command;
306  /* message has payload --> copy into buffer */
307  if ((kpkPayload != NULL_PTR) && (lengthPayload != 0u)) {
308  for (uint8_t i = 0u; i < lengthPayload; i++) {
309  pInstance->spiTxBuffer[i + 1u] = kpkPayload[i];
310  }
311  /* null rest of tx buffer */
312  for (uint8_t i = lengthPayload + 1u; i < MXM_SPI_TX_BUFFER_LENGTH; i++) {
313  pInstance->spiTxBuffer[i] = 0u;
314  }
315  /* send command with payload */
316  retval = MXM_SendData(pInstance->spiTxBuffer, (uint16_t)lengthPayload + 1u);
317  } else if ((kpkPayload == NULL_PTR) && (lengthPayload == 0u)) {
318  /* send command without payload */
319  retval = MXM_SendData(pInstance->spiTxBuffer, 1);
320  } else {
321  /* invalid configuration */
322  }
323  }
324  return retval;
325 }
326 
328  MXM_41B_INSTANCE_s *pInstance,
329  MXM_41B_REG_ADD_t command,
330  uint16_t *pRxBuffer,
331  uint8_t length) {
332  /* sanity check: state-pointer may not be null */
333  FAS_ASSERT(pInstance != NULL_PTR);
334  /* RX Buffer may not be NULL pointer for this function */
335  FAS_ASSERT(pRxBuffer != NULL_PTR);
337  /* AXIVION Routine Generic-MissingParameterAssert: command: parameter accepts whole range */
338 
339  STD_RETURN_TYPE_e retval = STD_NOT_OK;
340  /* check if command is a read command (read addresses in MAX17841B are odd) */
341  if ((command % 2u) != 0u) {
342  /* construct tx buffer */
343  pInstance->spiTxBuffer[0] = command;
344  /* null rest of tx buffer */
345  for (uint16_t i = 1u; i < MXM_SPI_TX_BUFFER_LENGTH; i++) {
346  pInstance->spiTxBuffer[i] = 0u;
347  }
348  /* send command with payload */
349  retval = MXM_ReceiveData(pInstance->spiTxBuffer, pRxBuffer, ((uint16_t)length + 1u));
350  }
351  return retval;
352 }
353 
355  /* sanity check: state-pointer may not be null */
356  FAS_ASSERT(pInstance != NULL_PTR);
357  uint8_t mxm_spi_temp_buffer[MXM_41B_CONFIG_REGISTER_LENGTH] = {0};
358 
359  /* AXIVION Disable Style Generic-NoMagicNumbers: Magic numbers for index value of array is clear in usage */
360  mxm_spi_temp_buffer[0u] = pInstance->regRxIntEnable;
361  mxm_spi_temp_buffer[1u] = pInstance->regTxIntEnable;
362  mxm_spi_temp_buffer[2u] = MXM_41B_RX_INT_FLAG_DEFAULT_VALUE;
363  mxm_spi_temp_buffer[3u] = MXM_41B_TX_INT_FLAG_DEFAULT_VALUE;
364  mxm_spi_temp_buffer[4u] = pInstance->regConfig1;
365  mxm_spi_temp_buffer[5u] = pInstance->regConfig2;
366  mxm_spi_temp_buffer[6u] = pInstance->regConfig3;
367  /* AXIVION Enable Style Generic-NoMagicNumbers: */
368  FAS_STATIC_ASSERT((6u < MXM_41B_CONFIG_REGISTER_LENGTH), "Revise this function and config register length!");
369 
370  return MXM_41BRegisterWrite(
371  pInstance, MXM_REG_RX_INTERRUPT_ENABLE_W, mxm_spi_temp_buffer, MXM_41B_CONFIG_REGISTER_LENGTH);
372 }
373 
375  MXM_41B_INSTANCE_s *pInstance,
376  const uint16_t *const kpkMessage,
377  uint8_t messageLength,
378  uint8_t extendMessage) {
379  /* sanity check: state-pointer may not be null */
380  FAS_ASSERT(pInstance != NULL_PTR);
381  /* check if message-pointer is valid */
382  FAS_ASSERT(kpkMessage != NULL_PTR);
383  FAS_ASSERT(messageLength >= 1u);
384  FAS_ASSERT(messageLength <= 6u);
385  /* AXIVION Routine Generic-MissingParameterAssert: extendMessage: parameter accepts whole range */
386 
387  /* write address and length to buffer */
388  pInstance->spiTxBuffer[0] = (uint16_t)MXM_BUF_WR_LD_Q_0;
389  pInstance->spiTxBuffer[1] = (uint16_t)messageLength + extendMessage;
390  /* iterate of complete TX buffer and
391  * write into proper fields, null rest
392  */
393  for (uint8_t i = 0; i < (MXM_SPI_TX_BUFFER_LENGTH - 2u); i++) {
394  if (i < messageLength) {
395  pInstance->spiTxBuffer[i + 2u] = kpkMessage[i];
396  } else {
397  pInstance->spiTxBuffer[i + 2u] = 0x00u;
398  }
399  }
400 
401  /* send data */
402  return MXM_SendData(pInstance->spiTxBuffer, ((uint16_t)messageLength + 2u));
403 }
404 
406  FAS_ASSERT(pInstance != NULL_PTR);
407  FAS_ASSERT(pInstance->processed != NULL_PTR);
408  pInstance->state = MXM_STATEMACH_41B_IDLE;
409  pInstance->substate = MXM_41B_ENTRY_SUBSTATE;
410  *pInstance->processed = MXM_41B_STATE_PROCESSED;
411 }
412 
414  FAS_ASSERT(pInstance != NULL_PTR);
415  FAS_ASSERT(pInstance->processed != NULL_PTR);
416  pInstance->state = MXM_STATEMACH_41B_IDLE;
417  pInstance->substate = MXM_41B_ENTRY_SUBSTATE;
418  *pInstance->processed = MXM_41B_STATE_ERROR;
419 }
420 
422  FAS_ASSERT(pInstance != NULL_PTR);
423  pInstance->regRxStatus = 0u;
424  pInstance->regTxStatus = 0u;
430 }
431 
433  FAS_ASSERT(pInstance != NULL_PTR);
434 
435  if (pInstance->substate == MXM_41B_ENTRY_SUBSTATE) {
436  /* entry of state --> set to first substate */
438  }
439 
440  if (pInstance->substate == MXM_41B_INIT_RESET_BRIDGE_IC) {
442  pInstance->shutdownTimeStamp = OS_GetTickCount();
444  } else if (pInstance->substate == MXM_41B_INIT_START_BRIDGE_IC) {
445  const bool resetTimeHasPassed =
447  if (resetTimeHasPassed) {
450  }
451  } else if (pInstance->substate == MXM_41B_INIT_WRITE_DEFAULT_VALUES) {
452  /* set default register values according to data sheet */
454  const STD_RETURN_TYPE_e retval = MXM_41BConfigRegisterWrite(pInstance);
455  if (retval == STD_OK) {
457  }
458  } else if (pInstance->substate == MXM_41B_INIT_READ_CONFIG_REGISTERS) {
459  const STD_RETURN_TYPE_e retval = MXM_41BRegisterRead(
461 
462  if (retval == STD_OK) {
464  }
465  } else if (pInstance->substate == MXM_41B_INIT_CHECK_INITIALIZATION) {
466  STD_RETURN_TYPE_e retval = STD_OK;
467 
468  if (MXM_GetSPIStateReady() == STD_OK) {
469  /**
470  * @brief Default values for the configuration and interrupt registers
471  * @details This constant array contains the default values to which the
472  * configuration is compared when resetting it.
473  * The array is 7 entries long in order to fit onto the following
474  * registers which are placed in succession in the memory of
475  * MAX17841B:
476  * - RX_Interrupt_Enable
477  * - TX_Interrupt_Enable
478  * - RX_Interrupt_Flags
479  * - TX_Interrupt_Flags
480  * - Configuration_1
481  * - Configuration_2
482  * - Configuration_3
483  */
484  const uint8_t mxm_41B_reg_default_values[MXM_41B_CONFIG_REGISTER_LENGTH] = {
492 
493  for (uint8_t i = 0; i < MXM_41B_CONFIG_REGISTER_LENGTH; i++) {
494  if (pInstance->spiRxBuffer[i + 1u] != mxm_41B_reg_default_values[i]) {
495  retval = STD_NOT_OK;
496  }
497  }
498  } else {
499  retval = STD_NOT_OK;
500  }
501 
502  if (retval == STD_NOT_OK) {
503  MXM_41BTransitionToIdleError(pInstance);
504  } else {
506  }
507  } else {
508  MXM_41BTransitionToIdleError(pInstance);
509  }
510 }
511 
513  FAS_ASSERT(pInstance != NULL_PTR);
514  if (pInstance->substate == MXM_41B_ENTRY_SUBSTATE) {
516  }
517 
518  if (pInstance->substate == MXM_41B_VERSION_REQUEST_REGISTER) {
519  /* read two byte in order to read also the adjacent version register */
520  const STD_RETURN_TYPE_e retval = MXM_41BRegisterRead(pInstance, MXM_REG_MODEL_R, pInstance->spiRxBuffer, 2);
521 
522  if (retval == STD_OK) {
523  pInstance->substate = MXM_41B_VERSION_VERIFY;
524  }
525  } else if (pInstance->substate == MXM_41B_VERSION_VERIFY) {
526  if (MXM_GetSPIStateReady() == STD_OK) {
527  /* get model from model register and high nibble of mask revision (should be 0x8410) */
528  pInstance->hardwareModel =
529  (uint16_t)((pInstance->spiRxBuffer[1] & MXM_41B_BIT_MASK_ONE_BYTE) << MXM_41B_BIT_SHIFT_HALF_BYTE);
530  pInstance->hardwareModel |=
532  /* extract mask revision from low nibble */
533  pInstance->hardwareMaskRevision = (uint8_t)(pInstance->spiRxBuffer[2] & MXM_41B_BIT_MASK_LOW_NIBBLE);
534 
536  }
537  } else {
538  /* something is very broken */
539  MXM_41BTransitionToIdleError(pInstance);
540  }
541 }
542 
544  FAS_ASSERT(pInstance != NULL_PTR);
545  /* do nothing in idle state
546  just clean up substate */
547  pInstance->substate = MXM_41B_ENTRY_SUBSTATE;
548 }
549 
551  FAS_ASSERT(pInstance != NULL_PTR);
552  const STD_RETURN_TYPE_e retval = MXM_41BConfigRegisterWrite(pInstance);
553 
554  if (retval == STD_NOT_OK) {
555  MXM_41BTransitionToIdleError(pInstance);
556  } else {
558  }
559 }
560 
562  FAS_ASSERT(pInstance != NULL_PTR);
563  /* TODO read status register and parse into static variables */
564  if (pInstance->substate == MXM_41B_ENTRY_SUBSTATE) {
565  /* entry of state --> set to first substate */
567  }
568 
569  if (pInstance->substate == MXM_41B_READ_STATUS_REGISTER_SEND) {
570  /* read rx and tx status register */
571  const STD_RETURN_TYPE_e retval = MXM_41BRegisterRead(pInstance, MXM_REG_RX_STATUS_R, pInstance->spiRxBuffer, 2);
572  if (retval == STD_NOT_OK) {
573  MXM_41BTransitionToIdleError(pInstance);
574  } else {
576  }
577  } else if (pInstance->substate == MXM_41B_READ_STATUS_REGISTER_PROCESS) {
578  pInstance->regRxStatus = (uint8_t)(pInstance->spiRxBuffer[1] & 0xFFu);
579  pInstance->regTxStatus = (uint8_t)(pInstance->spiRxBuffer[2] & 0xFFu);
581  } else {
582  /* something is very broken */
583  MXM_41BTransitionToIdleError(pInstance);
584  }
585 }
586 
588  FAS_ASSERT(pInstance != NULL_PTR);
589  if (pInstance->substate == MXM_41B_ENTRY_SUBSTATE) {
590  /* entry of state --> set to first substate */
592  }
593 
594  if (pInstance->substate == MXM_41B_UART_READ_RX_SPACE) {
595  const STD_RETURN_TYPE_e retval = MXM_41BRegisterRead(pInstance, MXM_REG_RX_SPACE_R, pInstance->spiRxBuffer, 1u);
596  if (retval == STD_NOT_OK) {
597  MXM_41BTransitionToIdleError(pInstance);
598  } else {
600  }
601  } else if (pInstance->substate == MXM_41B_UART_READ_RX_SPACE_PARSE) {
602  pInstance->regRxSpace = (uint8_t)(pInstance->spiRxBuffer[1] & MXM_41B_BIT_MASK_ONE_BYTE);
604 
605  } else if (pInstance->substate == MXM_41B_UART_WRITE_LOAD_QUEUE) {
606  /* load queue with message */
607  const STD_RETURN_TYPE_e retval =
608  MXM_41BBufferWrite(pInstance, pInstance->pPayload, pInstance->payloadLength, pInstance->extendMessageBytes);
609 
610  if (retval == STD_NOT_OK) {
611  MXM_41BTransitionToIdleError(pInstance);
612  } else {
614  }
615  } else if (pInstance->substate == MXM_41B_UART_READ_LOAD_QUEUE) {
616  /* check assumption that incremented payloadlength fits into uint8_t */
617  FAS_ASSERT(pInstance->payloadLength < (uint8_t)UINT8_MAX);
618  const uint8_t payloadLength = pInstance->payloadLength + 1u;
619  /* send read load queue */
620  const STD_RETURN_TYPE_e retval =
621  MXM_41BRegisterRead(pInstance, MXM_BUF_RD_LD_Q_0, pInstance->spiRxBuffer, payloadLength);
622 
623  if (retval == STD_NOT_OK) {
624  MXM_41BTransitionToIdleError(pInstance);
625  } else {
627  }
628  } else if (pInstance->substate == MXM_41B_UART_VERIFY_LOAD_QUEUE_AND_TRANSMIT) {
629  /* verify load queue */
630  STD_RETURN_TYPE_e retval = STD_OK;
631  /* check message length */
632  if (pInstance->spiRxBuffer[1] != (pInstance->payloadLength + (uint16_t)pInstance->extendMessageBytes)) {
633  retval = STD_NOT_OK;
634  }
635  for (uint8_t i = 0; i < pInstance->payloadLength; i++) {
636  FAS_ASSERT(pInstance->pPayload != NULL_PTR);
637  if (pInstance->spiRxBuffer[i + 2u] != pInstance->pPayload[i]) {
638  /* message corrupted during SPI transfer */
639  retval = STD_NOT_OK;
640  }
641  }
642  if (retval == STD_NOT_OK) {
643  MXM_41BTransitionToIdleError(pInstance);
644  } else {
645  /* transmit queue */
646  retval = MXM_41BRegisterWrite(pInstance, MXM_BUF_WR_NXT_LD_Q_0, NULL_PTR, 0);
647 
648  if (retval == STD_NOT_OK) {
649  MXM_41BTransitionToIdleError(pInstance);
650  } else {
652  }
653  }
654  } else if (pInstance->substate == MXM_41B_UART_WAIT_FOR_RX_STATUS_CHANGE_WRITE) {
655  /* poll RX status change */
656  const STD_RETURN_TYPE_e retval = MXM_41BRegisterRead(pInstance, MXM_REG_RX_STATUS_R, pInstance->spiRxBuffer, 1);
657 
658  if (retval == STD_NOT_OK) {
659  MXM_41BTransitionToIdleError(pInstance);
660  } else {
662  }
664  /* update RX status register copy with received buffer */
665  pInstance->regRxStatus = (uint8_t)(pInstance->spiRxBuffer[1] & MXM_41B_BIT_MASK_ONE_BYTE);
666  /* check if RX_OVERFLOW_Status is 1 */
667  MXM_41B_REG_BIT_VALUE rx_overflow_status_value = MXM_41B_REG_FALSE;
668  const STD_RETURN_TYPE_e resultWrongRegisterOverflow =
669  MXM_41BReadRegisterFunction(pInstance, MXM_41B_REG_FUNCTION_RX_OVERFLOW_STATUS, &rx_overflow_status_value);
670  FAS_ASSERT(resultWrongRegisterOverflow == STD_OK);
671  /* check if RX_STOP_Status is 1 */
672  MXM_41B_REG_BIT_VALUE rx_stop_status_value = MXM_41B_REG_FALSE;
673  const STD_RETURN_TYPE_e resultWrongRegisterStop =
674  MXM_41BReadRegisterFunction(pInstance, MXM_41B_REG_FUNCTION_RX_STOP_STATUS, &rx_stop_status_value);
675  FAS_ASSERT(resultWrongRegisterStop == STD_OK);
676  if (rx_overflow_status_value == MXM_41B_REG_TRUE) {
677  /* overflow, we have to discard the rx buffer */
678  const STD_RETURN_TYPE_e retval = MXM_41BRegisterWrite(pInstance, MXM_BUF_CLR_RX_BUF, NULL_PTR, 0);
679  if (retval == STD_NOT_OK) {
680  MXM_41BTransitionToIdleError(pInstance);
681  } else {
682  MXM_41BTransitionToIdleError(pInstance);
683  }
684  } else if (rx_stop_status_value == MXM_41B_REG_TRUE) {
685  /* received full UART frame --> continue */
686  /* check assumption that payload length fits into uint8_t */
687  FAS_ASSERT((pInstance->payloadLength + (uint16_t)1u + pInstance->extendMessageBytes) <= (uint8_t)UINT8_MAX);
688  const uint8_t payloadLength = pInstance->payloadLength + 1u + pInstance->extendMessageBytes;
689  /* read back receive buffer */
690  const STD_RETURN_TYPE_e retval =
691  MXM_41BRegisterRead(pInstance, MXM_BUF_RD_NXT_MSG, pInstance->spiRxBuffer, payloadLength);
692 
693  if (retval == STD_NOT_OK) {
694  MXM_41BTransitionToIdleError(pInstance);
695  } else {
697  pInstance->waitCounter = 0u;
698  }
699  } else {
700  /* no UART frame received yet --> check again */
702  /* increment wait counter (only to 1 above MXM_41B_WAIT_COUNTER_THRESHOLD,
703  then other parts of the code will reset). */
704  if (pInstance->waitCounter <= MXM_41B_WAIT_COUNTER_THRESHOLD) {
705  pInstance->waitCounter++;
706  }
707  }
708  } else if (pInstance->substate == MXM_41B_UART_READ_BACK_RECEIVE_BUFFER_SAVE) {
709  if ((pInstance->spiRxBuffer != NULL_PTR) && (pInstance->pRxBuffer != NULL_PTR)) {
710  for (uint16_t i = 0; i < ((uint16_t)pInstance->payloadLength + pInstance->extendMessageBytes); i++) {
711  if (i < pInstance->rxBufferLength) {
712  pInstance->pRxBuffer[i] = pInstance->spiRxBuffer[i + 1u];
713  }
714  }
715  }
717  } else {
718  /* we should not be here */
720  }
721 }
722 
724  FAS_ASSERT(pInstance != NULL_PTR);
725  if (pInstance->substate == MXM_41B_ENTRY_SUBSTATE) {
727  }
728 
729  if (pInstance->substate == MXM_41B_FMEA_REQUEST_REGISTER) {
730  const STD_RETURN_TYPE_e retval = MXM_41BRegisterRead(pInstance, MXM_REG_FMEA_R, pInstance->spiRxBuffer, 1);
731 
732  if (retval == STD_OK) {
733  pInstance->substate = MXM_41B_FMEA_VERIFY;
734  }
735  } else if (pInstance->substate == MXM_41B_FMEA_VERIFY) {
736  STD_RETURN_TYPE_e retval = STD_NOT_OK;
737  if (MXM_GetSPIStateReady() == STD_OK) {
738  pInstance->regFmea = pInstance->spiRxBuffer[1u];
739  if (pInstance->regFmea == 0u) {
740  retval = STD_OK;
741  }
742  }
743 
744  if (retval == STD_NOT_OK) {
745  /* FMEA check went bad */
746  MXM_41BTransitionToIdleError(pInstance);
747  } else {
749  }
750  } else {
751  /* something is very broken */
752  MXM_41BTransitionToIdleError(pInstance);
753  }
754 }
755 
757  FAS_ASSERT(pInstance != NULL_PTR);
758  /* clear receive buffer --> reset UART RX into defined state */
759  const STD_RETURN_TYPE_e retval = MXM_41BRegisterWrite(pInstance, MXM_BUF_CLR_RX_BUF, NULL_PTR, 0);
760 
761  if (retval == STD_OK) {
762  /* writing successful, return to idle */
764  } else {
765  /* an error has occurred, retry and set error */
766  MXM_41BTransitionToIdleError(pInstance);
767  }
768 }
769 
771  FAS_ASSERT(pInstance != NULL_PTR);
772  /* clear receive buffer --> reset UART RX into defined state */
773  const STD_RETURN_TYPE_e retval = MXM_41BRegisterWrite(pInstance, MXM_BUF_CLR_TX_BUF, NULL_PTR, 0);
774 
775  if (retval == STD_OK) {
776  /* writing successful, return to idle */
778  } else {
779  /* an error has occurred, retry and set error */
780  MXM_41BTransitionToIdleError(pInstance);
781  }
782 }
783 
784 /*========== Extern Function Implementations ================================*/
786  MXM_41B_INSTANCE_s *pInstance,
787  MXM_STATEMACH_41B_e state,
788  uint16_t *pPayload,
789  uint8_t payloadLength,
790  uint8_t extendMessageBytes,
791  uint16_t *pRxBuffer,
792  uint16_t rxBufferLength,
793  MXM_41B_STATE_REQUEST_STATUS_e *processed) {
794  /* sanity check: state-pointer may not be null */
795  FAS_ASSERT(pInstance != NULL_PTR);
796  /* AXIVION Routine Generic-MissingParameterAssert: state: parameter accepts whole range */
797  /* AXIVION Routine Generic-MissingParameterAssert: pPayload: pointer may be NULL */
798  /* AXIVION Routine Generic-MissingParameterAssert: payloadLength: parameter accepts whole range */
799  /* AXIVION Routine Generic-MissingParameterAssert: extendMessageBytes: parameter accepts whole range */
800  /* AXIVION Routine Generic-MissingParameterAssert: pRxBuffer: pointer may be NULL */
801  /* AXIVION Routine Generic-MissingParameterAssert: rxBufferLength: parameter accepts whole range */
802 
803  STD_RETURN_TYPE_e retval = STD_OK;
804  /* start by checking for input inconsistency */
805  if (state >= MXM_STATEMACH_41B_MAXSTATE) {
806  retval = STD_NOT_OK;
807  } else if ((pPayload == NULL_PTR) && (payloadLength != 0u)) {
808  retval = STD_NOT_OK;
809  } else if ((payloadLength == 0u) && (pPayload != NULL_PTR)) {
810  retval = STD_NOT_OK;
811  } else if ((pRxBuffer == NULL_PTR) && (rxBufferLength != 0u)) {
812  retval = STD_NOT_OK;
813  } else if ((rxBufferLength == 0u) && (pRxBuffer != NULL_PTR)) {
814  retval = STD_NOT_OK;
815  } else if (processed == NULL_PTR) {
816  retval = STD_NOT_OK;
817  } else if (pInstance->state == MXM_STATEMACH_41B_UNINITIALIZED) {
818  if (state == MXM_STATEMACH_41B_INIT) {
819  pInstance->state = state;
820  pInstance->substate = MXM_41B_ENTRY_SUBSTATE;
821  pInstance->pPayload = pPayload;
822  pInstance->payloadLength = payloadLength;
823  pInstance->extendMessageBytes = extendMessageBytes;
824  pInstance->pRxBuffer = pRxBuffer;
825  pInstance->rxBufferLength = rxBufferLength;
826  pInstance->processed = processed;
827  *pInstance->processed = MXM_41B_STATE_UNPROCESSED;
828  } else {
829  retval = STD_NOT_OK;
830  }
831  } else if (pInstance->state == MXM_STATEMACH_41B_IDLE) {
832  pInstance->state = state;
833  pInstance->substate = MXM_41B_ENTRY_SUBSTATE;
834  pInstance->pPayload = pPayload;
835  pInstance->payloadLength = payloadLength;
836  pInstance->extendMessageBytes = extendMessageBytes;
837  pInstance->pRxBuffer = pRxBuffer;
838  pInstance->rxBufferLength = rxBufferLength;
839  pInstance->processed = processed;
840  *pInstance->processed = MXM_41B_STATE_UNPROCESSED;
841  } else {
842  retval = STD_NOT_OK;
843  }
844  return retval;
845 }
846 
848  MXM_41B_INSTANCE_s *pInstance,
849  MXM_41B_REG_FUNCTION_e registerFunction,
850  MXM_41B_REG_BIT_VALUE value) {
851  /* sanity check: state-pointer may not be null */
852  FAS_ASSERT(pInstance != NULL_PTR);
853  /* AXIVION Routine Generic-MissingParameterAssert: registerFunction: parameter accepts whole range */
854  /* AXIVION Routine Generic-MissingParameterAssert: value: parameter accepts whole range */
855 
856  STD_RETURN_TYPE_e retval = STD_OK;
857  /* TODO sanitize value */
858 
859  switch (registerFunction) {
861  pInstance->regConfig2 = mxm_41bWriteValue(
862  value,
863  1,
865  pInstance->regConfig2); /* MXM_41B_TX_PREAMBLES is 5th bit of regConfig2 */
866  break;
868  pInstance->regConfig3 = mxm_41bWriteValue(
869  value, 4, MXM_41B_KEEP_ALIVE, pInstance->regConfig3); /* MXM_41B_KEEP_ALIVE is 0st bit of regConfig3 */
870  break;
872  pInstance->regRxIntEnable = mxm_41bWriteValue(
873  value,
874  1,
876  pInstance->regRxIntEnable); /* MXM_41B_RX_ERROR is 7th bit of regRxIntEnable */
877  break;
879  pInstance->regRxIntEnable = mxm_41bWriteValue(
880  value,
881  1,
883  pInstance->regRxIntEnable); /* MXM_41B_RX_OVERFLOW is 2nd bit of regRxIntEnable */
884  break;
885  default:
886  retval = STD_NOT_OK;
887  break;
888  }
889 
890  return retval;
891 }
892 
894  const MXM_41B_INSTANCE_s *const kpkInstance,
895  MXM_41B_REG_FUNCTION_e registerFunction,
896  MXM_41B_REG_BIT_VALUE *pValue) {
897  /* sanity check: state-pointer may not be null */
898  FAS_ASSERT(kpkInstance != NULL_PTR);
899  /* sanity check: pValue may not be null */
900  FAS_ASSERT(pValue != NULL_PTR);
901  STD_RETURN_TYPE_e retval = STD_OK;
902 
903  switch (registerFunction) {
905  *pValue = mxm_41bReadValue(kpkInstance->regRxStatus, 1, MXM_41B_RX_BUSY_STATUS); /* 5th bit */
906  break;
908  *pValue = mxm_41bReadValue(kpkInstance->regRxStatus, 1, MXM_41B_RX_STOP_STATUS); /* 1st bit */
909  break;
911  *pValue = mxm_41bReadValue(kpkInstance->regRxStatus, 1, MXM_41B_RX_OVERFLOW_STATUS); /* 3rd bit */
912  break;
914  *pValue = mxm_41bReadValue(kpkInstance->regRxStatus, 1, MXM_41B_RX_EMPTY_STATUS); /* 0th bit */
915  break;
917  *pValue = mxm_41bReadValue(kpkInstance->regConfig2, 1, MXM_41B_TX_PREAMBLES); /* 5th bit */
918  break;
919  default:
920  *pValue = MXM_41B_REG_FALSE;
921  retval = STD_NOT_OK;
922  break;
923  }
924 
925  return retval;
926 }
927 
929  /* sanity check: state-pointer may not be null */
930  FAS_ASSERT(pInstance != NULL_PTR);
931 
932  if (pInstance->waitCounter > MXM_41B_WAIT_COUNTER_THRESHOLD) {
933  /* error, reset to idle state */
934  MXM_41BTransitionToIdleError(pInstance);
935  pInstance->waitCounter = 0u;
936  }
937  switch (pInstance->state) {
939  break;
941  MXM_41BStateHandlerInit(pInstance);
942  break;
945  break;
947  MXM_41BStateHandlerIdle(pInstance);
948  break;
951  break;
954  break;
957  break;
959  MXM_41BStateHandlerCheckFmea(pInstance);
960  break;
963  break;
966  break;
967  default:
968  /* this default case should never be reached */
970  break;
971  }
972 }
973 
975  FAS_ASSERT(pInstance != NULL_PTR);
976 
978 
980  pInstance->substate = MXM_41B_ENTRY_SUBSTATE;
981  pInstance->pPayload = NULL_PTR;
982  pInstance->payloadLength = 0u;
983  pInstance->pRxBuffer = NULL_PTR;
984  pInstance->rxBufferLength = 0u;
985  pInstance->processed = NULL_PTR;
986  pInstance->extendMessageBytes = 0u;
987  pInstance->waitCounter = 0u;
988  pInstance->regRxSpace = 0u;
989  pInstance->regFmea = 0u;
990  pInstance->hardwareModel = 0u;
991  pInstance->hardwareMaskRevision = 0u;
992  pInstance->shutdownTimeStamp = 0u;
993 
994  for (uint32_t i = 0u; i < MXM_SPI_RX_BUFFER_LENGTH; i++) {
995  pInstance->spiRxBuffer[i] = 0u;
996  }
997 
998  for (uint32_t i = 0u; i < MXM_SPI_TX_BUFFER_LENGTH; i++) {
999  pInstance->spiTxBuffer[i] = 0u;
1000  }
1001 }
1002 
1003 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1004 #ifdef UNITY_UNIT_TEST
1005 #endif
Assert macro implementation.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
#define FAS_STATIC_ASSERT(cond, msg)
Definition: fassert.h:285
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
static void MXM_41BStateHandlerClearTransmitBuffer(MXM_41B_INSTANCE_s *pInstance)
state handler for "clear transmit buffer"
Definition: mxm_17841b.c:770
static void MXM_41BStateHandlerIdle(MXM_41B_INSTANCE_s *pInstance)
state handler for "idle"
Definition: mxm_17841b.c:543
static void MXM_41BStateHandlerClearReceiveBuffer(MXM_41B_INSTANCE_s *pInstance)
state handler for "clear receive buffer"
Definition: mxm_17841b.c:756
static void MXM_41BStateHandlerUartTransaction(MXM_41B_INSTANCE_s *pInstance)
state handler for "uart transaction"
Definition: mxm_17841b.c:587
static void MXM_41BStateHandlerWriteConfAndIntRegister(MXM_41B_INSTANCE_s *pInstance)
state handler for "write conf and int register"
Definition: mxm_17841b.c:550
static void MXM_41BStateHandlerReadStatusRegister(MXM_41B_INSTANCE_s *pInstance)
state handler for "read status register"
Definition: mxm_17841b.c:561
static void MXM_41BStateHandlerGetVersion(MXM_41B_INSTANCE_s *pInstance)
state handler for "get version"
Definition: mxm_17841b.c:512
static void MXM_41BStateHandlerCheckFmea(MXM_41B_INSTANCE_s *pInstance)
state handler for "check fmea"
Definition: mxm_17841b.c:723
static void MXM_41BStateHandlerInit(MXM_41B_INSTANCE_s *pInstance)
init state handler
Definition: mxm_17841b.c:432
STD_RETURN_TYPE_e MXM_41BSetStateRequest(MXM_41B_INSTANCE_s *pInstance, MXM_STATEMACH_41B_e state, uint16_t *pPayload, uint8_t payloadLength, uint8_t extendMessageBytes, uint16_t *pRxBuffer, uint16_t rxBufferLength, MXM_41B_STATE_REQUEST_STATUS_e *processed)
Set state transition for MAX17841B-state-machine.
Definition: mxm_17841b.c:785
void MXM_41BStateMachine(MXM_41B_INSTANCE_s *pInstance)
Execute state-machine for the MAX17841B.
Definition: mxm_17841b.c:928
static STD_RETURN_TYPE_e MXM_41BRegisterWrite(MXM_41B_INSTANCE_s *pInstance, MXM_41B_REG_ADD_t command, const uint8_t *const kpkPayload, uint8_t lengthPayload)
Write one or multiple registers of MAX17841B.
Definition: mxm_17841b.c:290
STD_RETURN_TYPE_e MXM_41BWriteRegisterFunction(MXM_41B_INSTANCE_s *pInstance, MXM_41B_REG_FUNCTION_e registerFunction, MXM_41B_REG_BIT_VALUE value)
Write a register function.
Definition: mxm_17841b.c:847
static STD_RETURN_TYPE_e MXM_41BConfigRegisterWrite(MXM_41B_INSTANCE_s *pInstance)
Write the config register of MAX17841B.
Definition: mxm_17841b.c:354
static void MXM_41BTransitionToIdleError(MXM_41B_INSTANCE_s *pInstance)
Transition into idle, mark as an error occurred.
Definition: mxm_17841b.c:413
static void MXM_41BInitializeRegisterCopies(MXM_41B_INSTANCE_s *pInstance)
Reset register copies to default.
Definition: mxm_17841b.c:421
static STD_RETURN_TYPE_e MXM_41BRegisterRead(MXM_41B_INSTANCE_s *pInstance, MXM_41B_REG_ADD_t command, uint16_t *pRxBuffer, uint8_t length)
Read one or multiple registers of MAX17841B.
Definition: mxm_17841b.c:327
#define MXM_41B_CONFIG_REGISTER_LENGTH
Definition: mxm_17841b.c:97
#define MXM_41B_BIT_MASK_HIGH_NIBBLE
Definition: mxm_17841b.c:76
#define MXM_41B_BIT_MASK_ONE_BYTE
Definition: mxm_17841b.c:79
void MXM_41BInitializeStateStruct(MXM_41B_INSTANCE_s *pInstance)
Initializes the state struct with default values.
Definition: mxm_17841b.c:974
static void MXM_41BTransitionToIdleSuccess(MXM_41B_INSTANCE_s *pInstance)
Transition into idle, mark as successful.
Definition: mxm_17841b.c:405
STD_RETURN_TYPE_e MXM_41BReadRegisterFunction(const MXM_41B_INSTANCE_s *const kpkInstance, MXM_41B_REG_FUNCTION_e registerFunction, MXM_41B_REG_BIT_VALUE *pValue)
Read the value of a register function.
Definition: mxm_17841b.c:893
static STD_RETURN_TYPE_e MXM_41BBufferWrite(MXM_41B_INSTANCE_s *pInstance, const uint16_t *const kpkMessage, uint8_t messageLength, uint8_t extendMessage)
Write a buffer transaction to MAX17841B.
Definition: mxm_17841b.c:374
#define MXM_41B_BIT_SHIFT_HALF_BYTE
Definition: mxm_17841b.c:70
#define MXM_41B_BRIDGE_RESET_TIME_MS
Definition: mxm_17841b.c:90
#define MXM_41B_WAIT_COUNTER_THRESHOLD
Definition: mxm_17841b.c:82
#define MXM_41B_BIT_MASK_LOW_NIBBLE
Definition: mxm_17841b.c:73
Headers for the driver for the MAX17841B ASCI and MAX1785x analog front-end.
#define MXM_SPI_TX_BUFFER_LENGTH
SPI TX buffer length.
Definition: mxm_17841b.h:79
MXM_STATEMACH_41B_e
States of the MAX17841B state-machine.
Definition: mxm_17841b.h:87
@ MXM_STATEMACH_41B_MAXSTATE
Definition: mxm_17841b.h:98
@ MXM_STATEMACH_41B_GET_VERSION
Definition: mxm_17841b.h:92
@ MXM_STATEMACH_41B_CLEAR_RECEIVE_BUFFER
Definition: mxm_17841b.h:96
@ MXM_STATEMACH_41B_CLEAR_TRANSMIT_BUFFER
Definition: mxm_17841b.h:97
@ MXM_STATEMACH_41B_UNINITIALIZED
Definition: mxm_17841b.h:88
@ MXM_STATEMACH_41B_INIT
Definition: mxm_17841b.h:89
@ MXM_STATEMACH_41B_WRITE_CONF_AND_INT_REGISTER
Definition: mxm_17841b.h:93
@ MXM_STATEMACH_41B_CHECK_FMEA
Definition: mxm_17841b.h:91
@ MXM_STATEMACH_41B_READ_STATUS_REGISTER
Definition: mxm_17841b.h:94
@ MXM_STATEMACH_41B_IDLE
Definition: mxm_17841b.h:90
@ MXM_STATEMACH_41B_UART_TRANSACTION
Definition: mxm_17841b.h:95
@ MXM_41B_FMEA_REQUEST_REGISTER
Definition: mxm_17841b.h:111
@ MXM_41B_INIT_RESET_BRIDGE_IC
Definition: mxm_17841b.h:106
@ MXM_41B_UART_WAIT_FOR_RX_STATUS_CHANGE_WRITE
Definition: mxm_17841b.h:121
@ MXM_41B_VERSION_VERIFY
Definition: mxm_17841b.h:114
@ MXM_41B_UART_READ_RX_SPACE
Definition: mxm_17841b.h:116
@ MXM_41B_INIT_CHECK_INITIALIZATION
Definition: mxm_17841b.h:110
@ MXM_41B_FMEA_VERIFY
Definition: mxm_17841b.h:112
@ MXM_41B_UART_READ_BACK_RECEIVE_BUFFER_SAVE
Definition: mxm_17841b.h:123
@ MXM_41B_VERSION_REQUEST_REGISTER
Definition: mxm_17841b.h:113
@ MXM_41B_ENTRY_SUBSTATE
Definition: mxm_17841b.h:105
@ MXM_41B_UART_WRITE_LOAD_QUEUE
Definition: mxm_17841b.h:118
@ MXM_41B_UART_READ_LOAD_QUEUE
Definition: mxm_17841b.h:119
@ MXM_41B_INIT_START_BRIDGE_IC
Definition: mxm_17841b.h:107
@ MXM_41B_UART_READ_RX_SPACE_PARSE
Definition: mxm_17841b.h:117
@ MXM_41B_INIT_READ_CONFIG_REGISTERS
Definition: mxm_17841b.h:109
@ MXM_41B_UART_VERIFY_LOAD_QUEUE_AND_TRANSMIT
Definition: mxm_17841b.h:120
@ MXM_41B_READ_STATUS_REGISTER_SEND
Definition: mxm_17841b.h:124
@ MXM_41B_READ_STATUS_REGISTER_PROCESS
Definition: mxm_17841b.h:125
@ MXM_41B_INIT_WRITE_DEFAULT_VALUES
Definition: mxm_17841b.h:108
@ MXM_41B_UART_WAIT_FOR_RX_STATUS_CHANGE_READ_AND_READ_BACK_RCV_BUF
Definition: mxm_17841b.h:122
#define MXM_SPI_RX_BUFFER_LENGTH
Definition: mxm_17841b.h:82
MXM_41B_REG_FUNCTION_e
Register functions.
Definition: mxm_17841b.h:144
@ MXM_41B_REG_FUNCTION_RX_BUSY_STATUS
Definition: mxm_17841b.h:145
@ MXM_41B_REG_FUNCTION_RX_EMPTY_STATUS
Definition: mxm_17841b.h:148
@ MXM_41B_REG_FUNCTION_RX_STOP_STATUS
Definition: mxm_17841b.h:147
@ MXM_41B_REG_FUNCTION_RX_OVERFLOW_STATUS
Definition: mxm_17841b.h:146
@ MXM_41B_REG_FUNCTION_TX_PREAMBLES
Definition: mxm_17841b.h:149
@ MXM_41B_REG_FUNCTION_RX_ERROR_INT
Definition: mxm_17841b.h:151
@ MXM_41B_REG_FUNCTION_KEEP_ALIVE
Definition: mxm_17841b.h:150
@ MXM_41B_REG_FUNCTION_RX_OVERFLOW_INT
Definition: mxm_17841b.h:152
MXM_41B_STATE_REQUEST_STATUS_e
Request status of MAX17841B states.
Definition: mxm_17841b.h:134
@ MXM_41B_STATE_ERROR
Definition: mxm_17841b.h:138
@ MXM_41B_STATE_UNPROCESSED
Definition: mxm_17841b.h:136
@ MXM_41B_STATE_PROCESSED
Definition: mxm_17841b.h:137
Register map of the MAX17841 bridge IC.
#define MXM_REG_RX_INTERRUPT_ENABLE_W
RX interrupt enable register write address.
#define MXM_BUF_RD_LD_Q_0
Read load queue starting from location 0.
#define MXM_REG_RX_SPACE_R
RX space register read address.
#define MXM_BUF_CLR_RX_BUF
Reset receive buffer and pointers to default state.
#define MXM_REG_FMEA_R
FMEA register read address.
#define MXM_REG_RX_INTERRUPT_ENABLE_R
RX interrupt enable register read address.
#define MXM_BUF_RD_NXT_MSG
Read receive buffer starting at the oldest unread message.
#define MXM_REG_RX_STATUS_R
RX status register read address.
#define MXM_REG_MODEL_R
Model register read address.
#define MXM_BUF_WR_LD_Q_0
Write load queue starting from location 0.
#define MXM_BUF_CLR_TX_BUF
Reset transmit buffer to default state and clear TX_Q and LD_Q.
#define MXM_BUF_WR_NXT_LD_Q_0
Select next load queue and write starting from location 0.
uint8_t MXM_41B_REG_ADD_t
MAX17841B register addresses.
MXM_41B_REG_BIT_VALUE mxm_41bWriteValue(MXM_41B_REG_BIT_VALUE value, uint8_t numberOfBits, MXM_41B_REG_BITS shift, uint8_t reg)
write a value to a register supplied as variable
MXM_41B_REG_BIT_VALUE mxm_41bReadValue(uint8_t reg, uint8_t numberOfBits, MXM_41B_REG_BITS position)
read a value from a register supplied as variable
Bit extraction function for MXM_17841b.
#define MXM_41B_KEEP_ALIVE
#define MXM_41B_RX_BUSY_STATUS
#define MXM_41B_REG_FALSE
#define MXM_41B_RX_EMPTY_STATUS
#define MXM_41B_RX_OVERFLOW_STATUS
uint8_t MXM_41B_REG_BIT_VALUE
Bit-values for registers.
#define MXM_41B_RX_STOP_STATUS
#define MXM_41B_RX_OVERFLOW_INT_ENABLE
#define MXM_41B_RX_ERROR
#define MXM_41B_TX_PREAMBLES
#define MXM_41B_REG_TRUE
STD_RETURN_TYPE_e MXM_ReceiveData(uint16_t *txBuffer, uint16_t *rxBuffer, uint16_t length)
Send and Receive data over SPI.
Definition: mxm_cfg.c:99
STD_RETURN_TYPE_e MXM_GetSPIStateReady(void)
Return whether SPI interface is ready.
Definition: mxm_cfg.c:86
void MXM_ShutDownBridgeIc(void)
Pulls the shutdown of the bridge IC low.
Definition: mxm_cfg.c:109
void MXM_EnableBridgeIc(void)
Pulls the shutdown of the bridge IC high.
Definition: mxm_cfg.c:113
STD_RETURN_TYPE_e MXM_SendData(uint16_t *txBuffer, uint16_t length)
Transmit data over SPI.
Definition: mxm_cfg.c:90
#define MXM_41B_CONFIG_3_DEFAULT_VALUE
Definition: mxm_cfg.h:111
#define MXM_41B_CONFIG_1_DEFAULT_VALUE
Definition: mxm_cfg.h:99
#define MXM_41B_CONFIG_2_DEFAULT_VALUE
Definition: mxm_cfg.h:105
#define MXM_41B_RX_INT_ENABLE_DEFAULT_VALUE
Definition: mxm_cfg.h:88
#define MXM_41B_RX_INT_FLAG_DEFAULT_VALUE
Definition: mxm_cfg.h:90
#define MXM_41B_TX_INT_ENABLE_DEFAULT_VALUE
Definition: mxm_cfg.h:89
#define MXM_41B_TX_INT_FLAG_DEFAULT_VALUE
Definition: mxm_cfg.h:91
bool OS_CheckTimeHasPassed(uint32_t oldTimeStamp_ms, uint32_t timeToPass_ms)
This function checks if timeToPass has passed since the last timestamp to now.
Definition: os.c:150
Declaration of the OS wrapper interface.
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:158
Struct for the state-variable of state-machine.
Definition: mxm_17841b.h:161
uint8_t regRxIntEnable
Definition: mxm_17841b.h:171
uint16_t * pRxBuffer
Definition: mxm_17841b.h:166
uint16_t * pPayload
Definition: mxm_17841b.h:164
uint8_t regTxIntEnable
Definition: mxm_17841b.h:172
uint16_t spiTxBuffer[MXM_SPI_TX_BUFFER_LENGTH]
Definition: mxm_17841b.h:184
uint16_t rxBufferLength
Definition: mxm_17841b.h:167
MXM_41B_STATE_REQUEST_STATUS_e * processed
Definition: mxm_17841b.h:168
uint16_t spiRxBuffer[MXM_SPI_RX_BUFFER_LENGTH]
Definition: mxm_17841b.h:183
uint32_t shutdownTimeStamp
Definition: mxm_17841b.h:182
MXM_41B_SUBSTATES_e substate
Definition: mxm_17841b.h:163
uint16_t hardwareModel
Definition: mxm_17841b.h:180
MXM_STATEMACH_41B_e state
Definition: mxm_17841b.h:162
uint8_t extendMessageBytes
Definition: mxm_17841b.h:169
uint8_t hardwareMaskRevision
Definition: mxm_17841b.h:181
uint8_t payloadLength
Definition: mxm_17841b.h:165