foxBMS  1.1.2
The foxBMS Battery Management System API Documentation
nxpfs85xx.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 nxpfs85xx.c
44  * @author foxBMS Team
45  * @date 2020-03-18 (date of creation)
46  * @updated 2021-07-14 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix SBC
49  *
50  * @brief Driver for the SBC module
51  *
52  * @details It must always be used when creating new c source files.
53  *
54  */
55 
56 /*========== Includes =======================================================*/
57 #include "nxpfs85xx.h"
58 
59 #include "HL_gio.h"
60 #include "HL_system.h"
61 
62 #include "diag.h"
63 #include "fram.h"
64 #include "fsystem.h"
65 #include "io.h"
66 #include "masterinfo.h"
67 #include "mcu.h"
68 
69 /*========== Macros and Definitions =========================================*/
70 
71 /*========== Static Constant and Variable Definitions =======================*/
72 typedef enum SBC_INIT_PHASE {
78 
79 /*========== Extern Constant and Variable Definitions =======================*/
82  .configValues.watchdogSeed = FS8x_WD_SEED_DEFAULT,
83  .configValues.communicationMode = fs8xSPI,
84  .configValues.i2cAddressOtp = 0, /* Not used as SPI is selected */
85  .fin.finUsed = true,
86  .fin.finState = STD_NOT_OK,
87  .fin.pGIOport = &(systemREG1->SYSPC4), /* FIN connected to ECLK1 (ball A12): PRIVILEGE MODE REQUIRED! */
88  .fin.pin = 0,
89  .mainRegister = {0},
90  .fsRegister = {0},
91  .nvram.entry = FRAM_BLOCK_ID_SBC_INIT_STATE,
92  .nvram.data = &fram_sbcInit,
93  .mode = SBC_NORMAL_MODE, /* default value */
94 };
95 
96 /*========== Static Function Prototypes =====================================*/
97 /**
98  * @brief Checks register value against expected value
99  * @details If actual register value equals expected value #STD_OK is
100  * returned if this is not the case this indicates an error and
101  * #STD_NOT_OK is returned.
102  * @param[in] registerValue actual register value of interest
103  * @param[in] expectedRegisterValue expected register value
104  * @return #STD_OK if register value equals expected, else #STD_NOT_OK
105  */
106 static STD_RETURN_TYPE_e SBC_CheckRegisterValues(uint32_t registerValue, uint32_t expectedRegisterValue);
107 
108 /**
109  * @brief Updates register values
110  * @details Updates register value of passed SBC instance with new
111  * values
112  * @param[in,out] pInstance SBC instance that is updated
113  * @param[in] isFailSafe true if fail-safe register, false if main register
114  * @param[in] registerAddress address of register that is updated
115  * @param[in] registerValue register value
116  */
117 static void SBC_UpdateRegister(
118  FS85xx_STATE_s *pInstance,
119  bool isFailSafe,
120  uint32_t registerAddress,
121  uint32_t registerValue);
122 
123 /**
124  * @brief Reads SBC register value
125  * @details Reads SBC register value from registerAddress and updates
126  * register in SBC state variable if reading was successful
127  * @param[in,out] pInstance SBC instance that is updated
128  * @param[in] isFailSafe true if fail-safe register, false if main
129  * register
130  * @param[in] registerAddress address of register that is read from
131  * @return #STD_OK if reading was successful, otherwise #STD_NOT_OK
132  */
133 static STD_RETURN_TYPE_e SBC_ReadBackRegister(FS85xx_STATE_s *pInstance, bool isFailSafe, uint8_t registerAddress);
134 
135 /**
136  * @brief Write to fail-safe register
137  * @details Writes to fail-safe register (can be done during FS_INIT phase
138  * only)
139  * @param[in] pInstance SBC instance that is updated
140  * @param[in] registerAddress address of register
141  * @param[in] registerValue value that is written into register
142  * @return #STD_OK if writting was successful, other #STD_NOT_OK
143  */
145  FS85xx_STATE_s *pInstance,
146  uint8_t registerAddress,
147  uint16_t registerValue);
148 
149 /**
150  * @brief Write to fail-safe register
151  * @details Writes to fail-safe register (can be done during FS_INIT
152  * phase only), reads back if write process was successful and
153  * afterwards updates register value of passed SBC instance
154  * @param[in,out] pInstance SBC instance that is updated
155  * @param[in] registerAddress address of register
156  * @param[in] registerValue value that is written into register
157  * @return #STD_OK if writting was successful, other #STD_NOT_OK
158  */
160  FS85xx_STATE_s *pInstance,
161  uint8_t registerAddress,
162  uint16_t registerValue);
163 
164 /**
165  * @brief Clears flags in register
166  * @details Writes to register, reads back if clear process was
167  * successful and afterwards updates register value of passed
168  * SBC instance
169  * @param[in,out] pInstance SBC instance that is updated
170  * @param[in] registerAddress address of register
171  * @param[in] isFailSafe true if fail-safe register, false if main register
172  * @param[in] registerValue value that is written into register
173  * @return #STD_OK if writting was successful, other #STD_NOT_OK
174  */
176  FS85xx_STATE_s *pInstance,
177  uint8_t registerAddress,
178  bool isFailSafe,
179  uint16_t registerValue);
180 
182 
183 /**
184  * @brief Perform RSTB safety path check
185  * @details This functions performs a safety path check to make sure
186  * external components connected to RSTB are available to
187  * bring the safety critical outputs to known levels during
188  * operation.
189  * @param[in,out] pInstance SBC instance for which the RSTB path is checked
190  * @return #STD_OK if path check was successful, other #STD_NOT_OK
191  */
193 
194 /**
195  * @brief Perform FS0B safety path check
196  * @details This functions performs a safety path check to make sure
197  * external components connected to FS0B are available to
198  * bring the safety critical outputs to known levels during
199  * operation.
200  * @param[in,out] pInstance SBC instance for which the FS0B path is checked
201  */
203 
204 /*========== Static Function Implementations ================================*/
205 static STD_RETURN_TYPE_e SBC_CheckRegisterValues(uint32_t registerValue, uint32_t expectedRegisterValue) {
206  STD_RETURN_TYPE_e retval = STD_OK;
207  if (registerValue != expectedRegisterValue) {
208  retval = STD_NOT_OK;
209  }
210  return retval;
211 }
212 
213 static void SBC_UpdateRegister(
214  FS85xx_STATE_s *pInstance,
215  bool isFailSafe,
216  uint32_t registerAddress,
217  uint32_t registerValue) {
218  FAS_ASSERT(pInstance != NULL_PTR);
219 
220  /* Check if fail-safe or main register needs to be updated */
221  if (isFailSafe == true) {
222  /* Update fail-safe register */
223  switch (registerAddress) {
225  pInstance->fsRegister.grl_flags = registerValue;
226  break;
227 
229  pInstance->fsRegister.iOvervoltageUndervolateSafeReaction1 = registerValue;
230  break;
231 
233  pInstance->fsRegister.iOvervoltageUndervolateSafeReaction2 = registerValue;
234  break;
235 
237  pInstance->fsRegister.iWatchdogConfiguration = registerValue;
238  break;
239 
241  pInstance->fsRegister.i_safe_inputs = registerValue;
242  break;
243 
244  case FS8X_FS_I_FSSM_ADDR:
245  pInstance->fsRegister.iFailSafeSateMachine = registerValue;
246  break;
247 
248  case FS8X_FS_I_SVS_ADDR:
249  pInstance->fsRegister.i_svs = registerValue;
250  break;
251 
253  pInstance->fsRegister.watchdogWindow = registerValue;
254  break;
255 
257  pInstance->fsRegister.watchdogSeed = registerValue;
258  break;
259 
261  pInstance->fsRegister.watchdogAnswer = registerValue;
262  break;
263 
265  pInstance->fsRegister.overvoltageUndervoltageRegisterStatus = registerValue;
266  break;
267 
269  pInstance->fsRegister.releaseFs0bPin = registerValue;
270  break;
271 
273  pInstance->fsRegister.safeIos = registerValue;
274  break;
275 
277  pInstance->fsRegister.diag_safety = registerValue;
278  break;
279 
281  pInstance->fsRegister.intb_mask = registerValue;
282  break;
283 
284  case FS8X_FS_STATES_ADDR:
285  pInstance->fsRegister.states = registerValue;
286  break;
287 
288  default:
289  FAS_ASSERT(FAS_TRAP); /* This case should never be reached */
290  break;
291  }
292  } else {
293  /* Update main register */
294  switch (registerAddress) {
295  case FS8X_M_FLAG_ADDR:
296  pInstance->mainRegister.flag = registerValue;
297  break;
298 
299  case FS8X_M_MODE_ADDR:
300  pInstance->mainRegister.mode = registerValue;
301  break;
302 
304  pInstance->mainRegister.registerControl1 = registerValue;
305  break;
306 
308  pInstance->mainRegister.registerControl2 = registerValue;
309  break;
310 
311  case FS8X_M_AMUX_ADDR:
312  pInstance->mainRegister.analogMultiplexer = registerValue;
313  break;
314 
315  case FS8X_M_CLOCK_ADDR:
316  pInstance->mainRegister.clock = registerValue;
317  break;
318 
320  pInstance->mainRegister.int_mask1 = registerValue;
321  break;
322 
324  pInstance->mainRegister.int_mask2 = registerValue;
325  break;
326 
327  case FS8X_M_FLAG1_ADDR:
328  pInstance->mainRegister.flag1 = registerValue;
329  break;
330 
331  case FS8X_M_FLAG2_ADDR:
332  pInstance->mainRegister.flag2 = registerValue;
333  break;
334 
336  pInstance->mainRegister.vmon_regx = registerValue;
337  break;
338 
340  pInstance->mainRegister.lvb1_svs = registerValue;
341  break;
342 
343  case FS8X_M_MEMORY0_ADDR:
344  pInstance->mainRegister.memory0 = registerValue;
345  break;
346 
347  case FS8X_M_MEMORY1_ADDR:
348  pInstance->mainRegister.memory1 = registerValue;
349  break;
350 
352  pInstance->mainRegister.deviceId = registerValue;
353  break;
354 
355  default:
356  FAS_ASSERT(FAS_TRAP); /* This case should never be reached */
357  break;
358  }
359  }
360 }
361 
362 static STD_RETURN_TYPE_e SBC_ReadBackRegister(FS85xx_STATE_s *pInstance, bool isFailSafe, uint8_t registerAddress) {
363  STD_RETURN_TYPE_e retval = STD_NOT_OK;
364  fs8x_rx_frame_t rxTemp = {0};
365 
366  FAS_ASSERT(pInstance != NULL_PTR);
367 
368  if (fs8xStatusOk !=
369  FS8x_ReadRegister(pInstance->pSpiInterface, &(pInstance->configValues), isFailSafe, registerAddress, &rxTemp)) {
370  retval = STD_NOT_OK;
371  } else {
372  SBC_UpdateRegister(pInstance, isFailSafe, registerAddress, rxTemp.readData);
373  retval = STD_OK;
374  }
375  return retval;
376 }
377 
379  FS85xx_STATE_s *pInstance,
380  uint8_t registerAddress,
381  uint16_t registerValue) {
382  STD_RETURN_TYPE_e retval = STD_OK;
383 
384  FAS_ASSERT(pInstance != NULL_PTR);
385 
386  /* Write to register */
387  if (fs8xStatusOk !=
388  FS8x_WriteRegisterInit(pInstance->pSpiInterface, &(pInstance->configValues), registerAddress, registerValue)) {
389  retval = STD_NOT_OK;
390  } else {
391  retval = STD_OK;
392  }
393  return retval;
394 }
395 
397  FS85xx_STATE_s *pInstance,
398  uint8_t registerAddress,
399  uint16_t registerValue) {
400  STD_RETURN_TYPE_e retval = STD_OK;
401  fs8x_rx_frame_t rxTemp = {0};
402 
403  FAS_ASSERT(pInstance != NULL_PTR);
404 
405  /* Write to register */
406  if (fs8xStatusOk !=
407  FS8x_WriteRegisterInit(pInstance->pSpiInterface, &(pInstance->configValues), registerAddress, registerValue)) {
408  retval |= STD_NOT_OK;
409  } else {
410  /* Read back register value and check if write process was successful */
411  if (fs8xStatusOk !=
412  FS8x_ReadRegister(pInstance->pSpiInterface, &(pInstance->configValues), true, registerAddress, &rxTemp)) {
413  retval |= STD_NOT_OK;
414  } else {
415  if (rxTemp.readData == registerValue) {
416  /* Written register value equals read value */
417  SBC_UpdateRegister(pInstance, true, registerAddress, rxTemp.readData);
418  } else {
419  retval |= STD_NOT_OK;
420  }
421  }
422  }
423  return retval;
424 }
425 
427  FS85xx_STATE_s *pInstance,
428  uint8_t registerAddress,
429  bool isFailSafe,
430  uint16_t registerValue) {
431  STD_RETURN_TYPE_e retval = STD_OK;
432  fs8x_rx_frame_t rxTemp = {0};
433 
434  FAS_ASSERT(pInstance != NULL_PTR);
435 
436  /* Write to register */
437  if (fs8xStatusOk !=
439  pInstance->pSpiInterface, &(pInstance->configValues), isFailSafe, registerAddress, registerValue)) {
440  retval |= STD_NOT_OK;
441  } else {
442  /* Read back register value and check if write process was successful */
443  if (fs8xStatusOk !=
445  pInstance->pSpiInterface, &(pInstance->configValues), isFailSafe, registerAddress, &rxTemp)) {
446  retval |= STD_NOT_OK;
447  } else {
448  /* Check if all flags have been cleared: '1' is written to registers to clear respective flags */
449  if ((rxTemp.readData & registerValue) == 0u) {
450  /* Written register value equals read value */
451  SBC_UpdateRegister(pInstance, isFailSafe, registerAddress, rxTemp.readData);
452  } else {
453  retval |= STD_NOT_OK;
454  }
455  }
456  }
457  return retval;
458 }
459 
460 /*========== Extern Function Implementations ================================*/
462  STD_RETURN_TYPE_e retval = STD_OK;
463  uint16_t registerMask = 0u;
464  uint16_t expRegisterValue = 0u;
465  uint16_t registerValue = 0u;
466 
467  FAS_ASSERT(pInstance != NULL_PTR);
468  /* Default init value: #STD_NOT_OK, will be set to #STD_OK later in init if
469  no short-circuit between FIN and RSTB detected. Do not apply external
470  clock on this pin until finState == #STD_OK */
471  FAS_ASSERT(pInstance->fin.finState == STD_NOT_OK);
472 
473  /** First: Verify following conditions:
474  1. Verify LBIST (logical-built-in-self-test) and ABIST1 (analog-built-in-self-test1) are pass
475  2. Verify Debug mode is not activated
476  3. Verify there is no OTP CRC error
477  4. Verify PGOOD was released: PGOOD is connected to power-on-reset of the MCU
478 
479  Second: Configure FS_I and FS_I_NOT registers
480 
481  - Write the desired data in the FS_I_Register_A (DATA)
482  - Write the opposite in the FS_I_NOT_Register_A (DATA_NOT)
483  - Only the utility bits must be inverted in the DATA_NOT content. The RESERVED bits are not considered and can be
484  written at '0'. If the comparison result is correct, then the REG_CORRUPT is set to '0'. If the comparison result
485  is wrong, then the REG_CORRUPT bit is set to '1'. The REG_CORRUPT monitoring is active as soon as the INIT_FS is
486  closed by the first good watchdog refresh. INIT_FS must be closed by the first good watchdog refresh before 256ms
487  timeout.
488 
489  1. Configure VCOREMON_OV_UV impact on RSTB and FS0B
490  2. Configure VDDIO_OV_UV impact on RSTB and FS0B
491  3. Configure VMONx_OV_UV impact on RSTB and FS0B
492  4. Configure ABIST2 assignment
493  5. Configure the WD window period, the WD window duty cycle, the WD counters limits,
494  and its impact on RSTB and FS0B. Ensure that the configuration does not violate the
495  FTTI requirement at system level.
496  6. Configure the Fault Error Counter limit and its impact on RSTB and FS0B at
497  intermediate value
498  7. Configure the RSTB pulse duration
499  8. Configure MCU FCCU error monitoring and its impact on RSTB and FS0B
500  9. Configure Ext. IC error monitoring and its impact on RSTB and FS0B
501  10.Configure FS0B short to high impact on RSTB
502 
503  Third: Execute
504 
505  1. Close INIT_FS by sending the first good WD refresh
506  2. Execute ABIST2 and verify it is pass
507  3. Clear all the flags by writing in FS_DIAG_SAFETY, FS_OVUVREG_STATUS
508  4. Clear the fault error counter to 0 with consecutive good WD refresh
509  5. Perform RSTB path check (repeat steps 1 to 4 after RSTB is released)
510  6. Release FS0B pin
511  7. Perform FS0B safety path check
512  8. Refresh the WD according to its configuration
513  9. Check FS_GRL_FLAGS register after each WD refresh
514 
515  The FS85 is now ready. If everything is OK for the MCU, it can release its own
516  safety path and the ECU starts.
517  */
518 
519  /* --------------------- First: Verify --------------------------------- */
520 
521  /** 1.: Verify LBIST and ABIST1 */
522  if (STD_OK != SBC_ReadBackRegister(pInstance, true, FS8X_FS_DIAG_SAFETY_ADDR)) {
523  retval = STD_NOT_OK;
524  }
526  expRegisterValue = (FS8X_FS_LBIST_OK_PASS | FS8X_FS_ABIST1_OK_PASS);
527  if (STD_OK != SBC_CheckRegisterValues((pInstance->fsRegister.diag_safety & registerMask), expRegisterValue)) {
528  retval = STD_NOT_OK;
529  }
530 
531  /** Read FS STATES register */
532  if (STD_OK != SBC_ReadBackRegister(pInstance, true, FS8X_FS_STATES_ADDR)) {
533  retval = STD_NOT_OK;
534  }
535 
536  /** 2.: Check if debug mode is active */
537  registerMask = FS8X_FS_DBG_MODE_MASK;
538  expRegisterValue = FS8X_FS_DBG_MODE_NO_DEBUG;
539  if (STD_OK != SBC_CheckRegisterValues((pInstance->fsRegister.states & registerMask), expRegisterValue)) {
540  /* Debug mode active: this can only be the case if debugger connected */
542  pInstance->mode = SBC_DEBUG_MODE;
543  } else {
544  /* Debug mode not active: no debugger connected */
546  pInstance->mode = SBC_NORMAL_MODE;
547  }
548 
549  /** 3.: Verify that no OPT CRC error */
550  registerMask = FS8X_FS_OTP_CORRUPT_MASK;
551  expRegisterValue = FS8X_FS_OTP_CORRUPT_NO_ERROR;
552  if (STD_OK != SBC_CheckRegisterValues((pInstance->fsRegister.states & registerMask), expRegisterValue)) {
553  retval = STD_NOT_OK;
554  }
555 
556  /** -------- Second: Configure fail-safe init registers ------------------*/
557  /** Check if SBC is in FS_INIT state, if not switch SBC in FS_INIT state.
558  * Specific configurations can only be done in FS_INIT state */
559  registerMask = FS8X_FS_FSM_STATE_MASK;
560  expRegisterValue = FS8X_FS_FSM_STATE_INIT_FS;
561  if (STD_OK != SBC_CheckRegisterValues((pInstance->fsRegister.states & registerMask), expRegisterValue)) {
562  /* SBC not in FS_INIT state -> request FS_INIT state */
563  /* Write FS_STATE request */
565  if (STD_OK != SBC_WriteRegisterFsInit(pInstance, FS8X_FS_SAFE_IOS_ADDR, registerValue)) {
566  retval = STD_NOT_OK;
567  } else {
568  /* Check if SBC now in FS_STATE */
569  if (STD_OK != SBC_ReadBackRegister(pInstance, true, FS8X_FS_STATES_ADDR)) {
570  retval = STD_NOT_OK;
571  } else {
572  /* Read register now check if SBC in FS_INIT state */
573  if (STD_OK !=
574  SBC_CheckRegisterValues((pInstance->fsRegister.states & registerMask), expRegisterValue)) {
575  /* SBC not in FS_INIT state -> error */
576  retval = STD_NOT_OK;
577  }
578  }
579  }
580  }
581 
582  /** 1.: Configure VCOREMON_OV_UV impact on RSTB and FS0B */
583  /** 2.: Configure VDDIO_OV_UV impact on RSTB and FS0B */
584  /** 4.: Configure ABIST2 assignment */
585  registerValue = 0;
586 
587  /** Select VCOREMON_OV options:
588  * - FS8X_FS_I_VCOREMON_OV_FS_IMPACT_NO_EFFECT
589  * - FS8X_FS_I_VCOREMON_OV_FS_IMPACT_FS0B
590  * - FS8X_FS_I_VCOREMON_OV_FS_IMPACT_FS0B_RSTB */
592 
593  /** Select VCOREMON_UV options:
594  * - FS8X_FS_I_VCOREMON_UV_FS_IMPACT_NO_EFFECT
595  * - FS8X_FS_I_VCOREMON_UV_FS_IMPACT_FS0B
596  * - FS8X_FS_I_VCOREMON_UV_FS_IMPACT_FS0B_RSTB */
598 
599  /** Select VDDIO_OV options:
600  * - FS8X_FS_I_VDDIO_OV_FS_IMPACT_NO_EFFECT
601  * - FS8X_FS_I_VDDIO_OV_FS_IMPACT_FS0B
602  * - FS8X_FS_I_VDDIO_OV_FS_IMPACT_FS0B_RSTB */
604 
605  /** Select VDDIO_UV options:
606  * - FS8X_FS_I_VDDIO_UV_FS_IMPACT_NO_EFFECT
607  * - FS8X_FS_I_VDDIO_UV_FS_IMPACT_FS0B
608  * - FS8X_FS_I_VDDIO_UV_FS_IMPACT_FS0B_RSTB */
610 
611  /** Select ABIST2 options:
612  * + VCOREMON
613  * - FS8X_FS_I_VCOREMON_ABIST2_NO_ABIST
614  * - FS8X_FS_I_VCOREMON_ABIST2_VCOREMON_BIST
615  * + VDDIO
616  * - FS8X_FS_I_VDDIO_ABIST2_NO_ABIST
617  * - FS8X_FS_I_VDDIO_ABIST2_VDDIO_BIST
618  * + VMONx (VMON1 - VMON4)
619  * - FS8X_FS_I_VMONx_ABIST2_NO_ABIST
620  * - FS8X_FS_I_VMONx_ABIST2_VMONx_BIST */
622  registerValue |= FS8X_FS_I_VDDIO_ABIST2_VDDIO_BIST;
623  registerValue |= FS8X_FS_I_VMON1_ABIST2_VMON1_BIST;
624  registerValue |= FS8X_FS_I_VMON2_ABIST2_VMON2_BIST;
625  registerValue |= FS8X_FS_I_VMON3_ABIST2_VMON3_BIST;
626  registerValue |= FS8X_FS_I_VMON4_ABIST2_VMON4_BIST;
627 
628  /* Write register */
629  if (STD_OK != SBC_WriteBackRegisterFsInit(pInstance, FS8X_FS_I_OVUV_SAFE_REACTION1_ADDR, registerValue)) {
630  retval = STD_NOT_OK;
631  }
632 
633  /** 3.: Configure VMONx_OV_UV impact on RSTB and FS0B */
634  registerValue = 0;
635  /** Select VMONx_OV options:
636  * - FS8X_FS_I_VMONx_OV_FS_IMPACT_NO_EFFECT
637  * - FS8X_FS_I_VMONx_OV_FS_IMPACT_FS0B
638  * - FS8X_FS_I_VMONx_OV_FS_IMPACT_FS0B_RSTB */
643 
644  /** Select VMONx_UV options:
645  * - FS8X_FS_I_VMONx_UV_FS_IMPACT_NO_EFFECT
646  * - FS8X_FS_I_VMONx_UV_FS_IMPACT_FS0B
647  * - FS8X_FS_I_VMONx_UV_FS_IMPACT_FS0B_RSTB */
652 
653  /* Write register */
654  if (STD_OK != SBC_WriteBackRegisterFsInit(pInstance, FS8X_FS_I_OVUV_SAFE_REACTION2_ADDR, registerValue)) {
655  retval = STD_NOT_OK;
656  }
657 
658  /** 5.: Configure the WD window period, the WD window duty cycle, the WD counters limits, and its impact on RSTB and
659  FS0B. Ensure that the configuration does not violate the FTTI requirement at system level. */
660  registerValue = 0;
661 
662  /** WD window period options:
663  * - FS8X_FS_WD_WINDOW_DISABLE
664  * - FS8X_FS_WD_WINDOW_xxxxMS */
665  registerValue |= FS8X_FS_WD_WINDOW_128MS;
666 
667  /** WD window duty cycle options:
668  * - FS8X_FS_WDW_DC_31_25
669  * - FS8X_FS_WDW_DC_37_5
670  * - FS8X_FS_WDW_DC_50
671  * - FS8X_FS_WDW_DC_62_5
672  * - FS8X_FS_WDW_DC_68_75 */
673  registerValue |= FS8X_FS_WDW_DC_50;
674 
675  /** WD fault recovery strategy
676  * - FS8X_FS_WDW_RECOVERY_DISABLE
677  * - FS8X_FS_WDW_RECOVERY_xxxxMS */
678  registerValue |= FS8X_FS_WDW_RECOVERY_128MS;
679 
680  /* Write register */
681  if (STD_OK != SBC_WriteBackRegisterFsInit(pInstance, FS8X_FS_WD_WINDOW_ADDR, registerValue)) {
682  retval = STD_NOT_OK;
683  }
684 
685  /** 6.: Configure the Fault Error Counter limit and its impact on RSTB and FS0B at intermediate value */
686  /** Configure the RSTB pulse duration */
687  /** Configure FS0B short to high impact on RSTB */
688  registerValue = 0;
689 
690  /** Fault Error Counter limit options:
691  * - FS8X_FS_I_FLT_ERR_CNT_LIMIT_2
692  * - FS8X_FS_I_FLT_ERR_CNT_LIMIT_4
693  * - FS8X_FS_I_FLT_ERR_CNT_LIMIT_6
694  * - FS8X_FS_I_FLT_ERR_CNT_LIMIT_8 */
695  registerValue |= FS8X_FS_I_FLT_ERR_CNT_LIMIT_8;
696 
697  /** Fault Error Counter impact options:
698  * - FS8X_FS_I_FLT_ERR_IMPACT_NO_EFFECT
699  * - FS8X_FS_I_FLT_ERR_IMPACT_FS0B
700  * - FS8X_FS_I_FLT_ERR_IMPACT_FS0B_RSTB */
701  registerValue |= FS8X_FS_I_FLT_ERR_IMPACT_FS0B_RSTB;
702 
703  /** 7.: RSTB pulse duration options:
704  * - FS8X_FS_I_RSTB_DUR_1MS
705  * - FS8X_FS_I_RSTB_DUR_10MS */
706  registerValue |= FS8X_FS_I_RSTB_DUR_10MS;
707 
708  /** 10.: FS0B short to high impact on RSTB options:
709  * - FS8X_FS_I_FS0B_SC_HIGH_CFG_NO_ASSERTION
710  * - FS8X_FS_I_FS0B_SC_HIGH_CFG_RESET_ASSERTED */
712 
713  /** After POR fault-error counter is set to 1 on default, it is reset after two consecutive good WD refreshes. This
714  part of the register is read-only so a write access has no influence. Set this bit for a successful comparison
715  between written and read register value */
716  registerValue |= FS8X_FS_I_FLT_ERR_CNT_1;
717 
718  /* Write register */
719  if (STD_OK != SBC_WriteRegisterFsInit(pInstance, FS8X_FS_I_FSSM_ADDR, registerValue)) {
720  retval = STD_NOT_OK;
721  }
722 
723  /** 8.: Configure MCU FCCU error monitoring and its impact on RSTB and FS0B */
724  /** 9.: Configure Ext. IC error monitoring and its impact on RSTB and FS0B */
725  registerValue = 0;
726 
727  /** MCU FCCU error monitoring options:
728  * + Input option:
729  * - FS8X_FS_I_FCCU_CFG_NO_MONITORING
730  * - FS8X_FS_I_FCCU_CFG_FCCU1_INPUT
731  * - FS8X_FS_I_FCCU_CFG_FCCU1_FCCU2_INPUT
732  * - FS8X_FS_I_FCCU_CFG_FCCU1_FCCU2_PAIR (bi-stable protocol)
733  * + Polarity option (independent):
734  * - FS8X_FS_I_FCCUx_FLT_POL_FCCUx_L
735  * - FS8X_FS_I_FCCUx_FLT_POL_FCCUx_H
736  * + Polarity option (bi-stable)
737  * - FS8X_FS_I_FCCU12_FLT_POL_FCCU1_L_FCCU2_H
738  * - FS8X_FS_I_FCCU12_FLT_POL_FCCU1_H_FCCU2_L
739  * + Impact option (independent)
740  * - FS8X_FS_I_FCCUx_FS_REACT_FS0B
741  * - FS8X_FS_I_FCCUx_FS_REACT_FS0B_RSTB
742  * + Impact option (bi-stable)
743  * - FS8X_FS_I_FCCU12_FS_IMPACT_FS0B
744  * - FS8X_FS_I_FCCU12_FS_IMPACT_FS0B_RSTB
745  */
746  registerValue |= FS8X_FS_I_FCCU_CFG_NO_MONITORING;
747  registerValue |= FS8X_FS_I_FCCU1_FLT_POL_FCCU1_L;
748  registerValue |= FS8X_FS_I_FCCU1_FS_REACT_FS0B;
749 
750  /** Ext. IC error monitoring options:
751  * + Polarity options:
752  * - FS8X_FS_I_ERRMON_FLT_POLARITY_NEGATIVE_EDGE
753  * - FS8X_FS_I_ERRMON_FLT_POLARITY_POSITIVE_EDGE
754  * + Error acknowledgment time options:
755  * - FS8X_FS_I_ERRMON_ACK_TIME_1MS
756  * - FS8X_FS_I_ERRMON_ACK_TIME_8MS
757  * - FS8X_FS_I_ERRMON_ACK_TIME_16MS
758  * - FS8X_FS_I_ERRMON_ACK_TIME_32MS
759  * + Error monitoring impact options:
760  * - FS8X_FS_I_ERRMON_FS_IMPACT_FS0B
761  * - FS8X_FS_I_ERRMON_FS_IMPACT_FS0B_RSTB */
763  registerValue |= FS8X_FS_I_ERRMON_ACK_TIME_32MS;
764  registerValue |= FS8X_FS_I_ERRMON_FS_IMPACT_FS0B;
765 
766  /* Write register */
767  if (STD_OK != SBC_WriteRegisterFsInit(pInstance, FS8X_FS_I_SAFE_INPUTS_ADDR, registerValue)) {
768  retval = STD_NOT_OK;
769  }
770 
771  /* -------------------- Third: Execute --------------------------------- */
772 
773  /** 1.: Close INIT_FS by sending the first good WD refresh */
774  if (STD_OK != SBC_TriggerWatchdog(pInstance)) {
775  retval = STD_NOT_OK;
776  }
777  /** 2.: Execute ABIST2 and verify it is pass */
778  /** ABIST2 is executed automatically after closing of INIT_FS, duration: 1.2ms max */
779  MCU_delay_us(1200u);
780 
781  if (STD_OK != SBC_ReadBackRegister(pInstance, true, FS8X_FS_DIAG_SAFETY_ADDR)) {
782  retval = STD_NOT_OK;
783  }
784  registerMask = FS8X_FS_ABIST2_OK_MASK;
785  expRegisterValue = FS8X_FS_ABIST2_OK_MASK;
786  if (STD_OK != SBC_CheckRegisterValues((pInstance->fsRegister.diag_safety & registerMask), expRegisterValue)) {
787  retval = STD_NOT_OK;
788  }
789 
790  /** 3.: Clear all the flags by writing in FS_DIAG_SAFETY */
791  registerValue = 0;
792  /** Flags are cleared by writting '1' to register */
794  registerValue |= FS8X_FS_ERRMON_ERROR_DETECTED;
796  registerValue |=
800  if (STD_OK != SBC_ClearRegisterFlags(pInstance, FS8X_FS_DIAG_SAFETY_ADDR, true, registerValue)) {
801  retval = STD_NOT_OK;
802  }
803 
804  /** Clear all the flags by writing in FS_OVUVREG_STATUS */
805  registerValue = 0;
806  /** Flags are cleared by writting '1' to register */
809  registerValue |=
815  registerValue |= FS8X_FS_FS_OSC_DRIFT_OSCILLATOR_DRIFT;
816  if (STD_OK != SBC_ClearRegisterFlags(pInstance, FS8X_FS_OVUVREG_STATUS_ADDR, true, registerValue)) {
817  retval = STD_NOT_OK;
818  }
819 
820  /** Clear flags FLAG1 register */
821  registerValue = FS8X_M_VBOSUVH_EVENT_OCCURRED;
822  registerValue |= FS8X_M_VBOOSTUVH_EVENT_OCCURRED;
823  if (STD_OK != SBC_ClearRegisterFlags(pInstance, FS8X_M_FLAG1_ADDR, false, registerValue)) {
824  retval = STD_NOT_OK;
825  }
826 
827  /** Clear flags FLAG2 register */
828  registerValue = FS8X_M_VSUPUV7_EVENT_OCCURRED;
829  registerValue |=
832  if (STD_OK != SBC_ClearRegisterFlags(pInstance, FS8X_M_FLAG2_ADDR, false, registerValue)) {
833  retval = STD_NOT_OK;
834  }
835 
836  /** Read out all registers for debug purpose */
837  if (STD_OK != SBC_ReadBackAllRegisters(pInstance)) {
838  retval = STD_OK;
839  }
840 
841  return retval;
842 }
843 
844 extern STD_RETURN_TYPE_e FS85X_Init_ReqWDGRefreshes(FS85xx_STATE_s *pInstance, uint8_t *requiredWatchdogRefreshes) {
845  STD_RETURN_TYPE_e retval = STD_OK;
846 
847  FAS_ASSERT(pInstance != NULL_PTR);
848 
849  /** Clear the fault error counter to 0 with consecutive good WD refreshes.
850  * The watchdog refresh counter is used to decrement the fault error counter. Each time the watchdog is properly
851  * refreshed, the watchdog refresh counter is incremented by '1'. Each time the watchdog refresh counter reaches
852  * its maximum value ('6' by default) and if next WD refresh is also good, the fault error counter is decremented
853  * by '1'. Whatever the position the watchdog refresh counter is in, each time there is a wrong refresh watchdog,
854  * the watchdog refresh counter is reset to '0'. */
855 
856  /** Read out FS_I_WD_CFG register to get watchdog refresh counter limit and value */
857  if (STD_OK != SBC_ReadBackRegister(pInstance, true, FS8X_FS_I_WD_CFG_ADDR)) {
858  retval = STD_NOT_OK;
859  }
860 
861  /** Get refresh counter value */
862  uint8_t watchdogRefreshLimit = 0;
863  uint8_t watchdogRefreshCounter = FS8x_BO_GET_REG_VALUE(
865 
866  /** Get refresh counter limit register value */
870  watchdogRefreshLimit = 6u;
871  } else if (
875  watchdogRefreshLimit = 4u;
876  } else if (
880  watchdogRefreshLimit = 2u;
881  } else {
882  watchdogRefreshLimit = 1u;
883  }
884 
885  /** Get fault error counter */
886  uint8_t faultCounter = 0u;
887  if (fs8xStatusOk !=
888  FS8x_GetFaultErrorCounterValue(pInstance->pSpiInterface, &(pInstance->configValues), &faultCounter)) {
889  retval = STD_NOT_OK;
890  }
891 
892  /** Get number of required watchdog refreshes to clear fault error counter to 0 */
893  *requiredWatchdogRefreshes = faultCounter + (watchdogRefreshLimit - watchdogRefreshCounter);
894 
895  return retval;
896 }
897 
899  STD_RETURN_TYPE_e retval = STD_OK;
900 
901  /* Check fault error counter */
902  uint8_t faultCounter = 0u;
903  retval |= FS8x_GetFaultErrorCounterValue(pInstance->pSpiInterface, &(pInstance->configValues), &faultCounter);
904  if (faultCounter != 0u) {
905  retval = STD_NOT_OK;
906  }
907  return retval;
908 }
909 
911  STD_RETURN_TYPE_e retval = STD_OK;
912 
913  FAS_ASSERT(pInstance != NULL_PTR);
914 
915  /* Perform RSTB path check (repeat steps 1 to 4 after RSTB is released) */
916  if (STD_OK != SBC_PerformPathCheckRSTB(pInstance)) {
917  retval = STD_NOT_OK;
918  }
919 
920  /* FS0B pin can not be released in debug mode */
921  if (pInstance->mode != SBC_DEBUG_MODE) {
922  /* Release FS0B pin */
923  if (fs8xStatusOk != FS8x_FS0B_Release(pInstance->pSpiInterface, &(pInstance->configValues))) {
924  retval = STD_NOT_OK;
925  }
926  }
927 
928  /* Perform FS0B safety path check */
929  if (STD_OK != SBC_PerformPathCheckFS0B(pInstance)) {
930  retval = STD_NOT_OK;
931  }
932 
933  /* Init finished successfully if retval still okay */
934  if (retval == STD_OK) {
935  pInstance->nvram.data->phase = (uint8_t)SBC_INITIALIZED;
936  FRAM_Write(pInstance->nvram.entry);
937  }
938  return retval;
939 }
940 
942  SPI_INTERFACE_CONFIG_s *pSpiInterface,
943  uint8_t *txFrame,
944  uint16_t frameLengthBytes,
945  uint8_t *rxFrame) {
946  uint16_t sbc_txBuffer[FS8x_COMM_FRAME_SIZE];
947  uint16_t sbc_rxBuffer[FS8x_COMM_FRAME_SIZE];
948  fs8x_status_t spiCommunicationState = fs8xStatusError;
949 
950  FAS_ASSERT(txFrame != NULL_PTR);
951  FAS_ASSERT(rxFrame != NULL_PTR);
952 
953  /* Copy TX data in TX array, reset RX array */
954  for (uint8_t i = 0u; i < FS8x_COMM_FRAME_SIZE; i++) {
955  sbc_txBuffer[FS8x_COMM_FRAME_SIZE - 1u - i] = (uint16_t)txFrame[i]; /* txFrame[0] will be sent last */
956  sbc_rxBuffer[i] = 0;
957  }
958 
959  STD_RETURN_TYPE_e spiRetval =
960  SPI_TransmitReceiveData(pSpiInterface, sbc_txBuffer, sbc_rxBuffer, FS8x_COMM_FRAME_SIZE);
961 
962  if (spiRetval == STD_OK) {
963  /* No error flag set - copy RX data in RX array */
964  for (uint8_t i = 0u; i < FS8x_COMM_FRAME_SIZE; i++) {
965  rxFrame[i] = (uint8_t)sbc_rxBuffer[FS8x_COMM_FRAME_SIZE - 1u - i];
966  }
967  spiCommunicationState = fs8xStatusOk;
968  }
969 
970  return spiCommunicationState;
971 }
972 
974  STD_RETURN_TYPE_e retval = STD_NOT_OK;
975  if (fs8xStatusOk == FS8x_WD_Refresh(pInstance->pSpiInterface, &(pInstance->configValues))) {
976  /* Check GRL_FLAGS register if watchdog refresh was valid */
977  if (STD_OK == SBC_ReadBackRegister(pInstance, true, FS8X_FS_GRL_FLAGS_ADDR)) {
978  uint16_t registerMask = FS8X_FS_FS_WD_G_MASK;
979  uint16_t expRegisterValue = FS8X_FS_FS_WD_G_GOOD_WD_REFRESH;
980  if (STD_OK == SBC_CheckRegisterValues((pInstance->fsRegister.grl_flags & registerMask), expRegisterValue)) {
981  /* GOOD watchdog refresh */
982  retval = STD_OK;
983  } else {
984  /* BAD watchdog refresh: get reason */
985  if (STD_OK == SBC_ReadBackRegister(pInstance, true, FS8X_FS_DIAG_SAFETY_ADDR)) {
986  registerMask = FS8X_FS_BAD_WD_TIMING_MASK;
987  expRegisterValue = FS8X_FS_BAD_WD_TIMING_BAD_WD_REFRESH;
988  if (STD_OK ==
989  SBC_CheckRegisterValues((pInstance->fsRegister.diag_safety & registerMask), expRegisterValue)) {
990  /* TODO: Notify someone: bad watchdog refresh was caused by wrong window or in timeout */
991  }
992  registerMask = FS8X_FS_BAD_WD_DATA_MASK;
993  expRegisterValue = FS8X_FS_BAD_WD_DATA_BAD_WD_REFRESH;
994  if (STD_OK ==
995  SBC_CheckRegisterValues((pInstance->fsRegister.diag_safety & registerMask), expRegisterValue)) {
996  /* TODO: Notify someone: bad watchdog refresh was caused by error in data */
997  }
998  }
999  }
1000  }
1001  }
1002  return retval;
1003 }
1004 
1006  STD_RETURN_TYPE_e retval = STD_OK;
1007 
1008  /* Read all fail-safe registers */
1009  SBC_ReadBackRegister(pInstance, true, FS8X_FS_GRL_FLAGS_ADDR);
1012  SBC_ReadBackRegister(pInstance, true, FS8X_FS_I_WD_CFG_ADDR);
1014  SBC_ReadBackRegister(pInstance, true, FS8X_FS_I_FSSM_ADDR);
1015  SBC_ReadBackRegister(pInstance, true, FS8X_FS_I_SVS_ADDR);
1016  SBC_ReadBackRegister(pInstance, true, FS8X_FS_WD_WINDOW_ADDR);
1017  SBC_ReadBackRegister(pInstance, true, FS8X_FS_WD_SEED_ADDR);
1018  SBC_ReadBackRegister(pInstance, true, FS8X_FS_WD_ANSWER_ADDR);
1021  SBC_ReadBackRegister(pInstance, true, FS8X_FS_SAFE_IOS_ADDR);
1023  SBC_ReadBackRegister(pInstance, true, FS8X_FS_INTB_MASK_ADDR);
1024  SBC_ReadBackRegister(pInstance, true, FS8X_FS_STATES_ADDR);
1025 
1026  /* Read main registers */
1027  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_FLAG_ADDR);
1028  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_MODE_ADDR);
1029  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_REG_CTRL1_ADDR);
1030  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_REG_CTRL2_ADDR);
1031  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_AMUX_ADDR);
1032  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_CLOCK_ADDR);
1033  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_INT_MASK1_ADDR);
1034  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_INT_MASK2_ADDR);
1035  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_FLAG1_ADDR);
1036  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_FLAG2_ADDR);
1037  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_VMON_REGX_ADDR);
1038  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_LVB1_SVS_ADDR);
1039  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_MEMORY0_ADDR);
1040  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_MEMORY1_ADDR);
1041  SBC_ReadBackRegister(pInstance, FALSE, FS8X_M_DEVICEID_ADDR);
1042  return retval;
1043 }
1044 
1046  STD_RETURN_TYPE_e retval = STD_OK;
1047  resetSource_t rstReason = MINFO_GetResetSource();
1048  bool test_assertionRSTB = false; /* Do not test RSTB assertion on default */
1049 
1050  /** Assertion of RSTB pin will trigger reset, check if reset reason was power-cycle.
1051  If so, check if short circuit between FIN and RSTB pin exists */
1052  if (rstReason == POWERON_RESET) {
1053  /** First check if FIN is used */
1054  if (pInstance->fin.finUsed == true) {
1055  /** Write to NVRAM to determine after reset and if short-circuit
1056  * between RSTB and FIN present what exactly caused the reset. */
1057  pInstance->nvram.data->phase = (uint8_t)SBC_FIN_TEST;
1058  FRAM_Write(pInstance->nvram.entry);
1059 
1060  /** MCU SBC is connected to ECLK1 -> privilege mode is required to access register */
1062 
1063  /** Last reset was caused by power-cycle */
1064  /** Set level of FIN pin low and check if this generates reset */
1065  IO_PinReset(pInstance->fin.pGIOport, pInstance->fin.pin);
1066 
1067  /** Pulses longer than 2000ns trigger reset -> wait 10us to check if
1068  reset is triggered by short between RSTB and FIN */
1069  MCU_delay_us(10u);
1070 
1071  /** If we reach this line of code, no reset has taken place.
1072  Everything okay. Set level of FIN pin back to high */
1073  IO_PinSet(pInstance->fin.pGIOport, pInstance->fin.pin);
1074 
1075  /** No further register access required -> leave privilege mode */
1077 
1078  /** FIN state okay, no short circuit. Update also in nvram struct */
1080  pInstance->fin.finState = STD_OK;
1081  pInstance->nvram.data->finState = STD_OK;
1082 
1083  /** Continue with RSTB assertion test */
1084  test_assertionRSTB = true;
1085  } else {
1086  /** Power-cycle but no FIN pin used -> continue with RSTB check */
1087  test_assertionRSTB = true;
1088  }
1089  } else if (rstReason == EXT_RESET) {
1090  /** Last reset reason was external reset via nRST pin (EXT_RESET)
1091  Readout FRAM to determine in which state the SBC was prior to reset */
1092  FRAM_Read(pInstance->nvram.entry);
1093  if ((SBC_INIT_PHASE_e)pInstance->nvram.data->phase == SBC_FIN_TEST) {
1094  /** Short-circuit between FIN and RSTB: Do not apply CLK on FIN */
1095  /** Update nvram FIN state */
1096  pInstance->nvram.data->finState = STD_NOT_OK;
1097  /** FIN state not okay, but still in SBC init phase after power-cycle
1098  * continue now with RSTB assertion */
1099  test_assertionRSTB = true;
1100  } else if ((SBC_INIT_PHASE_e)pInstance->nvram.data->phase == SBC_RSTB_ASSERTION_TEST) {
1101  /** Reset was triggered by SPI RSTB assertion test -> continue with SBC init phase */
1102  test_assertionRSTB = false;
1103 
1104  /** Diagnosis of the RSTB pin/event is available by reading the FS_SAFE_IOs register:
1105  * RSTB_EVENT bit reports an activation of RSTB pin. */
1106  SBC_ReadBackRegister(pInstance, true, FS8X_FS_SAFE_IOS_ADDR);
1107 
1108  /** Check RSTB_EVENT if RSTB has been activated */
1109  if (STD_OK ==
1112  /** RSTB pin should be sensed high and no RSTB short to high */
1114  uint16_t expRegisterValue =
1117  if (STD_OK != SBC_CheckRegisterValues((pInstance->fsRegister.safeIos & mask), expRegisterValue)) {
1118  retval = STD_NOT_OK;
1119  }
1120  /** Reset RSTB_EVENT flag */
1122  /** Update diag flag */
1124  } else {
1125  /** RSTB has not been activated but this should have been the case */
1126  retval = STD_NOT_OK;
1128  }
1129  } else {
1130  /** Reset was not caused by SBC initialization or power-cycle.
1131  * Continue with SBC init phase as RSTB assertion is only tested
1132  * after power-cycle occurred */
1133  test_assertionRSTB = false;
1134  }
1135  /** Copy FIN state info from nvram variable into local state variable. This restores lost data from rest or
1136  updates local FIN state if short-circuit between FIN and RSTB has been detected */
1137  pInstance->fin.finState = pInstance->nvram.data->finState;
1138  if (pInstance->fin.finState == STD_OK) {
1140  } else {
1142  }
1143  } else {
1144  /** Reset was not caused by power-cycle or SBC. SBC has already been initialized successfully after detected
1145  * power-cycle. Everything okay. Read FIN state from NVRAM and continue with normal operation */
1146  FRAM_Read(pInstance->nvram.entry);
1147  test_assertionRSTB = false;
1148  pInstance->fin.finState = pInstance->nvram.data->finState;
1149  if (pInstance->fin.finState == STD_OK) {
1151  } else {
1153  }
1154  }
1155 
1156  /** Verify the hardware connection between the MCU reset pin and the FS85 reset pin */
1157  if (test_assertionRSTB == true) {
1158  /** Write to NVRAM to determine after reset and if RSTB was asserted correctly */
1159  pInstance->nvram.data->phase = (uint8_t)SBC_RSTB_ASSERTION_TEST;
1160  FRAM_Write(pInstance->nvram.entry);
1161 
1162  SBC_ReadBackRegister(pInstance, true, FS8X_FS_STATES_ADDR);
1163 
1164  uint16_t registerValue = FS8X_FS_RSTB_REQ_RSTB_ASSERTION;
1165  SBC_WriteRegisterFsInit(pInstance, FS8X_FS_SAFE_IOS_ADDR, registerValue);
1166 
1167  while (1) {
1168  ;
1169  }
1170 
1171  /* Controller should never reach this point as reset via RSTB is requested */
1172  }
1173  return retval;
1174 }
1175 
1177  STD_RETURN_TYPE_e retval = STD_OK;
1178  /* TBD */
1179  return retval;
1180 }
1181 
1182 /*========== Externalized Static Function Implementations (Unit Test) =======*/
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diag_id, DIAG_EVENT_e event, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_Handler provides generic error handling, based on diagnosis group.
Definition: diag.c:226
Diagnosis driver header.
@ DIAG_SYSTEM
Definition: diag_cfg.h:247
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:235
@ DIAG_EVENT_OK
Definition: diag_cfg.h:234
@ DIAG_ID_SBC_RSTB_STATE
Definition: diag_cfg.h:215
@ DIAG_ID_SBC_FIN_STATE
Definition: diag_cfg.h:214
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:237
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:108
STD_RETURN_TYPE_e FRAM_Read(FRAM_BLOCK_ID_e blockId)
Reads a variable from the FRAM.
Definition: fram.c:160
STD_RETURN_TYPE_e FRAM_Write(FRAM_BLOCK_ID_e blockId)
Writes a variable to the FRAM.
Definition: fram.c:101
Header for the driver for the FRAM module.
FRAM_SBC_INIT_s fram_sbcInit
Definition: fram_cfg.c:72
@ FRAM_BLOCK_ID_SBC_INIT_STATE
Definition: fram_cfg.h:90
@ STD_NOT_OK
Definition: fstd_types.h:73
@ STD_OK
Definition: fstd_types.h:72
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:66
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
Function to switch between user mode and privilege mode.
#define FSYS_SwitchToUserMode()
Switch back to user mode.
Definition: fsystem.h:108
long FSYS_RaisePrivilege(void)
raise privilege
#define UNIT_TEST_WEAK_IMPL
Definition: general.h:104
fs8x_status_t FS8x_GetFaultErrorCounterValue(SPI_INTERFACE_CONFIG_s *spiInterface, fs8x_drv_data_t *drvData, uint8_t *faultErrorCounterValue)
Reads actual Fault Error Counter value.
Definition: sbc_fs8x.c:270
fs8x_status_t FS8x_WD_Refresh(SPI_INTERFACE_CONFIG_s *spiInterface, fs8x_drv_data_t *drvData)
Performs the watchdog refresh.
Definition: sbc_fs8x.c:160
fs8x_status_t FS8x_WriteRegisterInit(SPI_INTERFACE_CONFIG_s *pSpiInterface, fs8x_drv_data_t *drvData, uint8_t address, uint16_t writeData)
Performs a write to a single FS8x FS init register (during the INIT_FS phase only).
fs8x_status_t FS8x_WriteRegister(SPI_INTERFACE_CONFIG_s *pSpiInterface, fs8x_drv_data_t *drvData, bool isFailSafe, uint8_t address, uint16_t writeData)
Sends write command to the FS8x.
fs8x_status_t FS8x_FS0B_Release(SPI_INTERFACE_CONFIG_s *spiInterface, fs8x_drv_data_t *drvData)
FS0B release routine.
Definition: sbc_fs8x.c:184
fs8x_status_t FS8x_ReadRegister(SPI_INTERFACE_CONFIG_s *pSpiInterface, fs8x_drv_data_t *drvData, bool isFailSafe, uint8_t address, fs8x_rx_frame_t *rxData)
Performs a read from a single FS8x register.
fs8x_status_t
Status return codes.
@ fs8xSPI
@ fs8xStatusOk
@ fs8xStatusError
UNIT_TEST_WEAK_IMPL fs8x_status_t MCU_SPI_TransferData(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint8_t *txFrame, uint16_t frameLengthBytes, uint8_t *rxFrame)
This function transfers single frame through blocking SPI communication in both directions....
Definition: nxpfs85xx.c:941
void IO_PinSet(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:70
void IO_PinReset(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin by writing in pin output register.
Definition: io.c:77
Header for the driver for the IO module.
resetSource_t MINFO_GetResetSource(void)
Get reason for last reset.
Definition: masterinfo.c:83
void MINFO_SetDebugProbeConnectionState(MINFO_DEBUG_PROBE_CONNECTION_STATE_e state)
Check if debug probe is connected.
Definition: masterinfo.c:87
General foxBMS-master system information.
@ MINFO_DEBUG_PROBE_CONNECTED
Definition: masterinfo.h:67
@ MINFO_DEBUG_PROBE_NOT_CONNECTED
Definition: masterinfo.h:66
void MCU_delay_us(uint32_t delay_us)
Wait blocking a certain time in microseconds.
Definition: mcu.c:80
Headers for the driver for the MCU module.
static STD_RETURN_TYPE_e SBC_ReadBackAllRegisters(FS85xx_STATE_s *pInstance)
Definition: nxpfs85xx.c:1005
STD_RETURN_TYPE_e FS85X_InitFS(FS85xx_STATE_s *pInstance)
Configures SBC during INIT_FS phase.
Definition: nxpfs85xx.c:461
static STD_RETURN_TYPE_e SBC_WriteBackRegisterFsInit(FS85xx_STATE_s *pInstance, uint8_t registerAddress, uint16_t registerValue)
Write to fail-safe register.
Definition: nxpfs85xx.c:396
static STD_RETURN_TYPE_e SBC_CheckRegisterValues(uint32_t registerValue, uint32_t expectedRegisterValue)
Checks register value against expected value.
Definition: nxpfs85xx.c:205
static STD_RETURN_TYPE_e SBC_ReadBackRegister(FS85xx_STATE_s *pInstance, bool isFailSafe, uint8_t registerAddress)
Reads SBC register value.
Definition: nxpfs85xx.c:362
STD_RETURN_TYPE_e SBC_TriggerWatchdog(FS85xx_STATE_s *pInstance)
Trigger watchdog.
Definition: nxpfs85xx.c:973
static STD_RETURN_TYPE_e SBC_ClearRegisterFlags(FS85xx_STATE_s *pInstance, uint8_t registerAddress, bool isFailSafe, uint16_t registerValue)
Clears flags in register.
Definition: nxpfs85xx.c:426
STD_RETURN_TYPE_e FS85X_CheckFaultErrorCounter(FS85xx_STATE_s *pInstance)
Checks if fault error counter is zero.
Definition: nxpfs85xx.c:898
static STD_RETURN_TYPE_e SBC_PerformPathCheckFS0B(FS85xx_STATE_s *pInstance)
Perform FS0B safety path check.
Definition: nxpfs85xx.c:1176
STD_RETURN_TYPE_e FS85X_Init_ReqWDGRefreshes(FS85xx_STATE_s *pInstance, uint8_t *requiredWatchdogRefreshes)
Calculates the number of required watchdog refresh to reset fault error counter.
Definition: nxpfs85xx.c:844
static STD_RETURN_TYPE_e SBC_PerformPathCheckRSTB(FS85xx_STATE_s *pInstance)
Perform RSTB safety path check.
Definition: nxpfs85xx.c:1045
enum SBC_INIT_PHASE SBC_INIT_PHASE_e
STD_RETURN_TYPE_e FS85X_SafetyPathChecks(FS85xx_STATE_s *pInstance)
Performs SBC safety path checks.
Definition: nxpfs85xx.c:910
static STD_RETURN_TYPE_e SBC_WriteRegisterFsInit(FS85xx_STATE_s *pInstance, uint8_t registerAddress, uint16_t registerValue)
Write to fail-safe register.
Definition: nxpfs85xx.c:378
SBC_INIT_PHASE
Definition: nxpfs85xx.c:72
@ SBC_UNINITIALIZED
Definition: nxpfs85xx.c:73
@ SBC_FIN_TEST
Definition: nxpfs85xx.c:74
@ SBC_INITIALIZED
Definition: nxpfs85xx.c:76
@ SBC_RSTB_ASSERTION_TEST
Definition: nxpfs85xx.c:75
FS85xx_STATE_s fs85xx_mcuSupervisor
Definition: nxpfs85xx.c:80
static void SBC_UpdateRegister(FS85xx_STATE_s *pInstance, bool isFailSafe, uint32_t registerAddress, uint32_t registerValue)
Updates register values.
Definition: nxpfs85xx.c:213
Header for the driver for the FRAM module.
@ SBC_DEBUG_MODE
Definition: nxpfs85xx.h:111
@ SBC_NORMAL_MODE
Definition: nxpfs85xx.h:110
#define FS8x_WD_SEED_DEFAULT
Watchdog seed default value.
Definition: sbc_fs8x.h:59
#define FS8x_BO_GET_REG_VALUE(value, mask, shift)
Macro for getting value from register.
#define FS8x_COMM_FRAME_SIZE
#define FS8X_FS_I_FLT_ERR_IMPACT_FS0B_RSTB
#define FS8X_FS_VDDIO_UV_UNDERVOLTAGE_REPORTED
#define FS8X_FS_I_WD_RFR_CNT_MASK
#define FS8X_FS_BAD_WD_TIMING_MASK
#define FS8X_FS_VMON2_OV_OVERVOLTAGE_REPORTED
#define FS8X_M_VBOOSTUVH_EVENT_OCCURRED
#define FS8X_FS_I_ERRMON_FS_IMPACT_FS0B
#define FS8X_FS_VCOREMON_OV_OVERVOLTAGE_REPORTED
#define FS8X_FS_FCCU1_ERROR_DETECTED
#define FS8X_FS_RSTB_DIAG_MASK
#define FS8X_FS_I_FCCU_CFG_NO_MONITORING
#define FS8X_FS_RSTB_REQ_RSTB_ASSERTION
#define FS8X_M_WK2FLG_EVENT_OCCURRED
#define FS8X_FS_I_ERRMON_FLT_POLARITY_POSITIVE_EDGE
#define FS8X_M_INT_MASK2_ADDR
#define FS8X_FS_I_VMON2_UV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_I_ERRMON_ACK_TIME_32MS
#define FS8X_FS_WDW_DC_50
#define FS8X_FS_FSM_STATE_INIT_FS
#define FS8X_FS_I_FCCU1_FLT_POL_FCCU1_L
#define FS8X_FS_ABIST1_OK_PASS
#define FS8X_FS_I_VMON2_ABIST2_VMON2_BIST
#define FS8X_FS_I_VMON4_OV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_DBG_MODE_MASK
#define FS8X_M_MEMORY1_ADDR
#define FS8X_FS_ABIST2_OK_MASK
#define FS8X_FS_I_VMON3_ABIST2_VMON3_BIST
#define FS8X_FS_RSTB_EVENT_MASK
#define FS8X_FS_SPI_FS_CRC_ERROR_DETECTED
#define FS8X_FS_I_WD_RFR_LIMIT_2
#define FS8X_FS_SPI_FS_CLK_WRONG_NUMBER_OF_CLOCK_CYCLES
#define FS8X_FS_LBIST_OK_MASK
#define FS8X_FS_BAD_WD_DATA_BAD_WD_REFRESH
#define FS8X_FS_I2C_FS_CRC_ERROR_DETECTED
#define FS8X_FS_WD_ANSWER_ADDR
#define FS8X_FS_VMON3_UV_UNDERVOLTAGE_REPORTED
#define FS8X_FS_FSM_STATE_MASK
#define FS8X_M_REG_CTRL2_ADDR
Definition: sbc_fs8x_map.h:696
#define FS8X_M_VBOSUVH_EVENT_OCCURRED
#define FS8X_FS_I_VDDIO_OV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_RSTB_DIAG_NO_FAILURE
#define FS8X_FS_RSTB_EVENT_RESET_OCCURRED
#define FS8X_FS_RELEASE_FS0B_ADDR
#define FS8X_FS_WD_WINDOW_ADDR
#define FS8X_FS_VCOREMON_UV_UNDERVOLTAGE_REPORTED
#define FS8X_FS_I_VDDIO_UV_FS_IMPACT_NO_EFFECT
#define FS8X_M_DEVICEID_ADDR
#define FS8X_M_FLAG1_ADDR
#define FS8X_FS_BAD_WD_TIMING_BAD_WD_REFRESH
#define FS8X_FS_I_VMON2_OV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_I2C_FS_REQ_I2C_VIOLATION
#define FS8X_M_VMON_REGX_ADDR
#define FS8X_FS_I_RSTB_DUR_10MS
#define FS8X_FS_I_WD_RFR_LIMIT_SHIFT
#define FS8X_FS_I_VDDIO_ABIST2_VDDIO_BIST
#define FS8X_M_VSUPUVL_EVENT_OCCURRED
#define FS8X_FS_I_VMON4_ABIST2_VMON4_BIST
#define FS8X_FS_ERRMON_ERROR_DETECTED
#define FS8X_M_REG_CTRL1_ADDR
Definition: sbc_fs8x_map.h:432
#define FS8X_FS_I_VCOREMON_OV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_RSTB_SNS_PAD_SENSED_HIGH
#define FS8X_FS_VMON4_UV_UNDERVOLTAGE_REPORTED
#define FS8X_FS_I_VCOREMON_UV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_I_FLT_ERR_CNT_1
#define FS8X_M_FLAG_ADDR
Definition: sbc_fs8x_map.h:57
#define FS8X_FS_WD_SEED_ADDR
#define FS8X_FS_I_VMON3_OV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_I_WD_RFR_LIMIT_6
#define FS8X_M_MODE_ADDR
Definition: sbc_fs8x_map.h:304
#define FS8X_FS_VMON4_OV_OVERVOLTAGE_REPORTED
#define FS8X_FS_RSTB_DRV_COMMAND_SENSED_HIGH
#define FS8X_FS_I_WD_RFR_LIMIT_MASK
#define FS8X_FS_DBG_MODE_NO_DEBUG
#define FS8X_FS_I_VMON3_UV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_OTP_CORRUPT_MASK
#define FS8X_FS_I_FS0B_SC_HIGH_CFG_NO_ASSERTION
#define FS8X_FS_I_VMON1_ABIST2_VMON1_BIST
#define FS8X_FS_WD_WINDOW_128MS
#define FS8X_FS_I_SAFE_INPUTS_ADDR
#define FS8X_FS_INTB_MASK_ADDR
#define FS8X_FS_SAFE_IOS_ADDR
#define FS8X_M_CLOCK_ADDR
#define FS8X_FS_I_OVUV_SAFE_REACTION1_ADDR
#define FS8X_M_VSUPUVH_EVENT_OCCURRED
#define FS8X_FS_OVUVREG_STATUS_ADDR
#define FS8X_FS_I_FSSM_ADDR
#define FS8X_FS_FS_OSC_DRIFT_OSCILLATOR_DRIFT
#define FS8X_FS_I_WD_CFG_ADDR
#define FS8X_FS_VMON2_UV_UNDERVOLTAGE_REPORTED
#define FS8X_FS_FS_DIG_REF_OV_OVERVOLTAGE_REPORTED
#define FS8X_FS_FS_WD_G_MASK
#define FS8X_FS_DIAG_SAFETY_ADDR
#define FS8X_FS_I_VMON1_UV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_FCCU12_ERROR_DETECTED
#define FS8X_FS_VMON1_OV_OVERVOLTAGE_REPORTED
#define FS8X_FS_RSTB_DRV_MASK
#define FS8X_M_VPREUVH_EVENT_OCCURRED
#define FS8X_FS_VMON1_UV_UNDERVOLTAGE_REPORTED
#define FS8X_M_VSUPUV7_EVENT_OCCURRED
#define FS8X_M_INT_MASK1_ADDR
#define FS8X_FS_I_VMON1_OV_FS_IMPACT_NO_EFFECT
#define FS8X_FS_VMON3_OV_OVERVOLTAGE_REPORTED
#define FS8X_FS_WDW_RECOVERY_128MS
#define FS8X_FS_RSTB_SNS_MASK
#define FS8X_FS_I_SVS_ADDR
#define FS8X_FS_VDDIO_OV_OVERVOLTAGE_REPORTED
#define FS8X_M_LVB1_SVS_ADDR
#define FS8X_FS_I_FCCU1_FS_REACT_FS0B
#define FS8X_FS_SPI_FS_REQ_SPI_VIOLATION
#define FS8X_M_FLAG2_ADDR
#define FS8X_FS_I_WD_RFR_CNT_SHIFT
#define FS8X_FS_FS_WD_G_GOOD_WD_REFRESH
#define FS8X_FS_I_FLT_ERR_CNT_LIMIT_8
#define FS8X_FS_GO_TO_INITFS_GO_BACK_TO_INIT_FS
#define FS8X_FS_I_OVUV_SAFE_REACTION2_ADDR
#define FS8X_FS_I_VMON4_UV_FS_IMPACT_NO_EFFECT
#define FS8X_M_VPREUVL_EVENT_OCCURRED
#define FS8X_FS_OTP_CORRUPT_NO_ERROR
#define FS8X_FS_ABIST1_OK_MASK
#define FS8X_FS_LBIST_OK_PASS
#define FS8X_FS_BAD_WD_DATA_MASK
#define FS8X_FS_I_WD_RFR_LIMIT_4
#define FS8X_M_AMUX_ADDR
Definition: sbc_fs8x_map.h:882
#define FS8X_FS_STATES_ADDR
#define FS8X_M_MEMORY0_ADDR
#define FS8X_FS_I_VCOREMON_ABIST2_VCOREMON_BIST
#define FS8X_FS_GRL_FLAGS_ADDR
#define FS8X_FS_FCCU2_ERROR_DETECTED
STD_RETURN_TYPE_e SPI_TransmitReceiveData(SPI_INTERFACE_CONFIG_s *pSpiInterface, uint16 *pTxBuff, uint16 *pRxBuff, uint32 frameLength)
Transmits and receives data on SPI without DMA.
Definition: spi.c:142
SPI_INTERFACE_CONFIG_s spi_kSbcMcuInterface
Definition: spi_cfg.c:217
uint8_t phase
Definition: fram_cfg.h:110
STD_RETURN_TYPE_e finState
Definition: fram_cfg.h:111
STD_RETURN_TYPE_e finState
Definition: nxpfs85xx.h:117
volatile uint32_t * pGIOport
Definition: nxpfs85xx.h:118
uint16_t diag_safety
Definition: nxpfs85xx.h:84
uint16_t iOvervoltageUndervolateSafeReaction2
Definition: nxpfs85xx.h:73
uint16_t releaseFs0bPin
Definition: nxpfs85xx.h:82
uint16_t iWatchdogConfiguration
Definition: nxpfs85xx.h:74
uint16_t watchdogAnswer
Definition: nxpfs85xx.h:80
uint16_t grl_flags
Definition: nxpfs85xx.h:71
uint16_t intb_mask
Definition: nxpfs85xx.h:85
uint16_t iFailSafeSateMachine
Definition: nxpfs85xx.h:76
uint16_t i_svs
Definition: nxpfs85xx.h:77
uint16_t i_safe_inputs
Definition: nxpfs85xx.h:75
uint16_t states
Definition: nxpfs85xx.h:86
uint16_t watchdogWindow
Definition: nxpfs85xx.h:78
uint16_t safeIos
Definition: nxpfs85xx.h:83
uint16_t iOvervoltageUndervolateSafeReaction1
Definition: nxpfs85xx.h:72
uint16_t watchdogSeed
Definition: nxpfs85xx.h:79
uint16_t overvoltageUndervoltageRegisterStatus
Definition: nxpfs85xx.h:81
uint16_t int_mask2
Definition: nxpfs85xx.h:99
uint16_t int_mask1
Definition: nxpfs85xx.h:98
uint16_t registerControl1
Definition: nxpfs85xx.h:94
uint16_t analogMultiplexer
Definition: nxpfs85xx.h:96
uint16_t registerControl2
Definition: nxpfs85xx.h:95
FS85X_FS_REGISTER_s fsRegister
Definition: nxpfs85xx.h:134
FS85X_MAIN_REGISTERS_s mainRegister
Definition: nxpfs85xx.h:133
SPI_INTERFACE_CONFIG_s * pSpiInterface
Definition: nxpfs85xx.h:130
SBC_NVRAM_INFO_s nvram
Definition: nxpfs85xx.h:135
FS85X_OPERATION_MODE_e mode
Definition: nxpfs85xx.h:136
fs8x_drv_data_t configValues
Definition: nxpfs85xx.h:131
FS85X_FIN_CONFIGURATION_s fin
Definition: nxpfs85xx.h:132
FRAM_BLOCK_ID_e entry
Definition: nxpfs85xx.h:124
FRAM_SBC_INIT_s * data
Definition: nxpfs85xx.h:125
Structure representing received data frame.
uint16_t readData
Content of a read register.