foxBMS  1.5.0
The foxBMS Battery Management System API Documentation
bender_iso165c.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 bender_iso165c.c
44  * @author foxBMS Team
45  * @date 2019-04-07 (date of creation)
46  * @updated 2023-02-03 (date of last update)
47  * @version v1.5.0
48  * @ingroup DRIVERS
49  * @prefix I165C
50  *
51  * @brief Driver for the insulation monitoring
52  *
53  * @details main file of bender iso165C and iso165C-1 driver
54  *
55  */
56 
57 /*========== Includes =======================================================*/
58 #include "bender_iso165c.h"
59 
60 #include "database_cfg.h"
61 
62 #include "can.h"
65 #include "can_helper.h"
66 #include "database.h"
67 #include "ftask.h"
68 
69 #include <stdbool.h>
70 #include <stdint.h>
71 
72 /*========== Macros and Definitions =========================================*/
73 /** state machine short time definition in trigger calls until next state is processed */
74 #define I165C_FSM_SHORT_TIME (1u)
75 
76 /* -------------- State defines ---------------------------------------------*/
77 
78 /** States of the initialization state machine */
79 typedef enum {
80  I165C_FSM_STATE_INITIALIZATION_DUMMY, /*!< dummy state - always the first state */
81  I165C_FSM_STATE_INITIALIZATION_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
82  I165C_FSM_STATE_INITIALIZATION_UNLOCK_WAIT_ACK, /*!< wait acknowledge of unlocking */
83  I165C_FSM_STATE_INITIALIZATION_CHECK_MEASUREMENT_STATE, /*!< check if measurement is enabled. if not enable it */
84  I165C_FSM_STATE_INITIALIZATION_ENABLE_MEASUREMENT_WAIT_ACK, /*!< wait for acknowledge for enabling of measurement */
85  I165C_FSM_STATE_INITIALIZATION_REQUEST_HV_RELAY_OPENING, /*!< request HV relay state: open */
87  I165C_FSM_STATE_INITIALIZATION_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
88  I165C_FSM_STATE_INITIALIZATION_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
90  I165C_FSM_STATE_INITIALIZATION_SELF_TEST_WAIT_ACK, /*!< wait acknowledge of self-test */
91  I165C_FSM_STATE_INITIALIZATION_WAIT_SELF_TEST, /*!< wait until self-test is finished */
93  I165C_FSM_STATE_INITIALIZATION_AVERAGING_FACTOR_WAIT_ACK, /*!< wait acknowledge of averaging factor */
94  I165C_FSM_STATE_INITIALIZATION_SET_ERROR_THRESHOLD, /*!< configuration of error threshold */
95  I165C_FSM_STATE_INITIALIZATION_ERROR_THRESHOLD_WAIT_ACK, /*!< wait acknowledge of error threshold */
96  I165C_FSM_STATE_INITIALIZATION_SET_WARNING_THRESHOLD, /*!< configuration of warning threshold */
97  I165C_FSM_STATE_INITIALIZATION_WARNING_THRESHOLD_WAIT_ACK, /*!< wait acknowledge of warning threshold */
99  I165C_FSM_STATE_INITIALIZATION_DISABLE_MEASUREMENT_WAIT_ACK, /*!< wait acknowledge of disable measurement */
101 
102 /** States of the enable state machine */
103 typedef enum {
104  I165C_FSM_STATE_ENABLE_DUMMY, /*!< dummy state - always the first state */
105  I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
106  I165C_FSM_STATE_ENABLE_REQUEST_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
107  I165C_FSM_STATE_ENABLE_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
108  I165C_FSM_STATE_ENABLE_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
109  I165C_FSM_STATE_ENABLE_START_MEASUREMENT, /*!< start insulation measurement */
110  I165C_FSM_STATE_ENABLE_START_MEASUREMENT_WAIT_ACK, /*!< check for acknowledge of start measurement request */
112 
113 /** States of the running state machine */
114 typedef enum {
115  I165C_FSM_STATE_RUNNING_DUMMY, /*!< dummy state - always the first state */
116  I165C_FSM_STATE_RUNNING_HAS_NEVER_RUN, /*!< never run state - always the second state */
121 
122 /** States of the disable state machine */
123 typedef enum {
124  I165C_FSM_STATE_DISABLE_DUMMY, /*!< dummy state - always the first state */
125  I165C_FSM_STATE_DISABLE_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
126  I165C_FSM_STATE_MEASUREMENT_STOPPED_WAIT_ACK, /*!< wait for acknowledge of stop measurement request */
127  I165C_FSM_STATE_DISABLE_SET_HV_RELAY_STATE, /*!< request state of HV relays */
129  I165C_FSM_STATE_DISABLE_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
130  I165C_FSM_STATE_DISABLE_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
132 
133 /* -------------- State variables -------------------------------------------*/
134 
135 /** This struct describes the state of the initialization state machine */
136 typedef struct {
137  uint16_t timer; /*!< timer of the state */
138  uint8_t triggerEntry; /*!< trigger entry of the state */
139  I165C_FSM_INITIALIZATION_STATES_e currentState; /*!< current state of the FSM */
140  I165C_FSM_INITIALIZATION_STATES_e previousState; /*!< previous state of the FSM */
141  uint8_t receptionTries;
146 
147 typedef struct {
148  uint16_t timer; /*!< timer of the state */
149  uint8_t triggerEntry; /*!< trigger entry of the state */
150  I165C_FSM_ENABLE_STATES_e currentState; /*!< current state of the FSM */
151  I165C_FSM_ENABLE_STATES_e previousState; /*!< previous state of the FSM */
152  uint8_t receptionTries;
155 
156 typedef struct {
157  uint16_t timer; /*!< timer of the state */
158  uint8_t triggerEntry; /*!< trigger entry of the state */
159  I165C_FSM_RUNNING_STATES_e currentState; /*!< current state of the FSM */
160  I165C_FSM_RUNNING_STATES_e previousState; /*!< previous state of the FSM */
161  uint8_t receptionTries;
164 
165 typedef struct {
166  uint16_t timer; /*!< timer of the state */
167  uint8_t triggerEntry; /*!< trigger entry of the state */
168  I165C_FSM_DISABLE_STATES_e currentState; /*!< current state of the FSM */
169  I165C_FSM_DISABLE_STATES_e previousState; /*!< previous state of the FSM */
170  uint8_t receptionTries;
173 
174 /*========== Static Constant and Variable Definitions =======================*/
175 
177  .timer = 0u,
178  .triggerEntry = 0u,
180  .previousState = I165C_FSM_STATE_INITIALIZATION_DUMMY,
181  .receptionTries = 0u,
182  .receptionTriesMessage = 0u,
183 #if false == I165C_IS_165C_USED
184  /* Default state after startup is closed for iso165C-1 */
185  .negativeRelayClosed = true,
186  .positiveRelayClosed = true,
187 #else
188  /* Default state after startup is open for iso165C */
189  .negativeRelayClosed = false,
190  .positiveRelayClosed = false,
191 #endif
192 };
193 
195  .timer = 0u,
196  .triggerEntry = 0u,
197  .currentState = I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN,
198  .previousState = I165C_FSM_STATE_ENABLE_DUMMY,
199  .receptionTries = 0u,
200  .receptionTriesMessage = 0u,
201 };
202 
204  .timer = 0u,
205  .triggerEntry = 0u,
207  .previousState = I165C_FSM_STATE_RUNNING_DUMMY,
208  .receptionTries = 0u,
209  .receptionTriesMessage = 0u,
210 };
211 
213  .timer = 0u,
214  .triggerEntry = 0u,
216  .previousState = I165C_FSM_STATE_DISABLE_DUMMY,
217  .receptionTries = 0u,
218  .receptionTriesMessage = 0u,
219 };
220 
223 
224 /*========== Extern Constant and Variable Definitions =======================*/
225 
226 /*========== Static Function Prototypes =====================================*/
227 /**
228  * @brief Sets the next state the timer value
229  * of the initialization state variable.
230  * @param[in,out] pImdState state of the initialization state machine
231  * @param[in] nextState state to be transferred into
232  * @param[in] idleTime wait time for the state machine
233  */
234 static void I165C_SetInitializationState(
235  I165C_INITIALIZATION_STATE_s *pImdState,
237  uint16_t idleTime);
238 
239 /**
240  * @brief Sets the next state the timer value
241  * of the enable state variable.
242  * @param[in,out] pImdState state of the enable state machine
243  * @param[in] nextState state to be transferred into
244  * @param[in] idleTime wait time for the state machine
245  */
246 static void I165C_SetEnableState(
247  I165C_ENABLE_STATE_s *pImdState,
248  I165C_FSM_ENABLE_STATES_e nextState,
249  uint16_t idleTime);
250 
251 /**
252  * @brief Sets the next state the timer value
253  * of the running state variable.
254  * @param[in,out] pImdState state of the enable state machine
255  * @param[in] nextState state to be transferred into
256  * @param[in] idleTime wait time for the state machine
257  */
258 static void I165C_SetRunningState(
259  I165C_RUNNING_STATE_s *pImdState,
260  I165C_FSM_RUNNING_STATES_e nextState,
261  uint16_t idleTime);
262 
263 /**
264  * @brief Sets the next state the timer value
265  * of the disable state variable.
266  * @param[in,out] pImdState state of the enable state machine
267  * @param[in] nextState state to be transferred into
268  * @param[in] idleTime wait time for the state machine
269  */
270 static void I165C_SetDisableState(
271  I165C_DISABLE_STATE_s *pImdState,
272  I165C_FSM_DISABLE_STATES_e nextState,
273  uint16_t idleTime);
274 
275 /** Initialization state machine */
277 
278 /** Enable state machine */
279 static IMD_FSM_STATES_e I165C_Enable(void);
280 
281 /** Disable state machine */
282 static IMD_FSM_STATES_e I165C_Disable(void);
283 
284 /**
285  * @brief trigger function for the i165c driver state machine.
286  * @details This function contains the sequence of events in the i165c state
287  * machine.
288  * It must be called time-triggered, every 100ms.
289  * @param pTableInsulationMonitoring pointer to insulation database entry
290  */
291 static IMD_FSM_STATES_e I165C_Running(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring);
292 
293 /**
294  * @brief Reset CAN data.
295  * @details Used before starting a new transmission.
296  * @param[in,out] pCanMessage pointer to CAN data to be reset
297  */
298 static void I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *pCanMessage);
299 
300 /**
301  * @brief Write data in data word for CAN transmission.
302  * @param dataWord data word ("position") in CAN structure to be written
303  * to (see data sheet page 15)
304  * @param data data to be written in data word
305  * @param[in] pCanMessage CAN structure to be used for transmission
306  */
307 static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *pCanMessage);
308 
309 /**
310  * @brief Get data in data word from CAN transmission.
311  * @param dataWord data word ("position") in CAN structure to be read from
312  * (see data sheet page 15)
313  * @param[out] pData pointer where to put read data from data word
314  * @param canMessage CAN structure used for transmission
315  */
316 static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage);
317 
318 /**
319  * @brief Get data in data word from CAN transmission, for the specific
320  * IMD_Info message.
321  * @param dataWord data word ("position") in CAN structure to be read from
322  * (see data sheet page 15)
323  * @param[out] pData pointer where to put read data from data word
324  * @param canMessage CAN structure used for transmission
325  */
326 static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage);
327 
328 /**
329  * @brief Get data in data byte from CAN transmission.
330  * @param dataByte data byte ("position") in CAN structure to be read from
331  * (see data sheet page 15)
332  * @param[out] pData pointer where to put read data from data byte
333  * @param canMessage CAN structure used for transmission
334  */
335 static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFER_ELEMENT_s canMessage);
336 
337 /**
338  * @brief Compose CAN message for CAN transmission.
339  * @details Write CMD byte.
340  * @param id CAN ID to use
341  * @param command command to be used (see data page 15 section 6.3 and
342  * further)
343  * @param[out] pCanMessage pointer to CAN structure to be used for transmission
344  */
345 static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage);
346 
347 /**
348  * @brief Check if iso165c acknowledged reception of sent message
349  * and get corresponding data.
350  * @details Gets data from the CAN module through a queue.
351  * @param command check if this command is sent by iso165c to acknowledge
352  * reception
353  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
354  * @return true if transmission acknowledged, false otherwise
355  */
356 static bool I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage);
357 
358 /**
359  * @brief Get IMD Info from iso165c
360  * @details Gets data from the CAN module through a queue.
361  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
362  * @return true if IMD_Info message was received, false otherwise
363  */
364 static bool I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *pCanMessage);
365 
366 /**
367  * @brief Check if iso165c was initialized and is running
368  * @details Check is made using the CAN IMD_Info data sent by the iso165c.
369  * - the IMC is up and running with no errors:
370  * - insulation measurement deactivated
371  * - self-test executed
372  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
373  * @return true if IMD_Info was received, false otherwise
374  */
375 static bool I165C_IsSelfTestFinished(CAN_BUFFER_ELEMENT_s canMessage);
376 
377 /**
378  * @brief Check if iso165c has already been performed previously
379  * @details Check is made using the CAN IMD_Info data sent by the iso165c.
380  * - self-test executed
381  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
382  * @return true if self-test has already been executed, false otherwise
383  */
385 
386 /**
387  * @brief Set state of HV relay
388  * @param[in] relay set state of positive or negative relay
389  * @param[in] relayState open or close relay
390  */
391 static void I165C_SetRelayState(uint8_t relay, uint8_t relayState);
392 
393 /**
394  * @brief Request state of HV relay
395  * @param[in] relay positive or negative relay
396  */
397 static void I165C_RequestRelayState(uint8_t relay);
398 
399 /**
400  * @brief Check state of HV relay
401  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
402  * @param[in] relay positive or negative relay
403  * @param[in] relayState relay opened or closed
404  * @return true if state matches, otherwise false
405  */
406 static bool I165C_CheckRelayState(CAN_BUFFER_ELEMENT_s canMessage, uint8_t relay, uint8_t relayState);
407 
408 /**
409  * @brief Set measurement mode
410  * @param[in] mode set IMD measurement mode
411  */
412 static void I165C_SetMeasurementMode(uint8_t mode);
413 
414 /**
415  * @brief Check measurement mode
416  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
417  * @param[in] mode IMD measurement mode (activated or deactivated)
418  * @return true, if measurement mode matches, otherwise false
419  */
420 static bool I165C_CheckMeasurementMode(CAN_BUFFER_ELEMENT_s canMessage, uint8_t mode);
421 
422 /**
423  * @brief Set average factor of the insulation resistance averaging algorithm
424  * @param[in] averagingFactor set IMD averaging factor
425  */
426 static void I165C_SetAveragingFactor(uint8_t averagingFactor);
427 
428 /**
429  * @brief Check if iso165c acknowledged reception of command
430  * @param command command to be acknowledged
431  * @param[out] pTries pointer to variable counting the number of tries for reception
432  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
433  * @return true if Acknowledge has been received, otherwise false
434  */
435 static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFER_ELEMENT_s *pCanMessage);
436 
437 /*========== Static Function Implementations ================================*/
439  I165C_INITIALIZATION_STATE_s *pImdState,
441  uint16_t idleTime) {
442  FAS_ASSERT(pImdState != NULL_PTR);
443  /* Set time */
444  pImdState->timer = idleTime;
445  /* Set state */
446  if (nextState != pImdState->currentState) {
447  /* Next state is different: switch to it and set substate to entry value */
448  pImdState->previousState = pImdState->currentState;
449  pImdState->currentState = nextState;
450  } else {
451  /* Next state equal to current state: nothing to do */
452  }
453 }
454 
456  I165C_ENABLE_STATE_s *pImdState,
457  I165C_FSM_ENABLE_STATES_e nextState,
458  uint16_t idleTime) {
459  FAS_ASSERT(pImdState != NULL_PTR);
460  /* Set time */
461  pImdState->timer = idleTime;
462  /* Set state */
463  if (nextState != pImdState->currentState) {
464  /* Next state is different: switch to it and set substate to entry value */
465  pImdState->previousState = pImdState->currentState;
466  pImdState->currentState = nextState;
467  } else {
468  /* Next state equal to current state: nothing to do */
469  }
470 }
471 
473  I165C_RUNNING_STATE_s *pImdState,
474  I165C_FSM_RUNNING_STATES_e nextState,
475  uint16_t idleTime) {
476  FAS_ASSERT(pImdState != NULL_PTR);
477  /* Set time */
478  pImdState->timer = idleTime;
479  /* Set state */
480  if (nextState != pImdState->currentState) {
481  /* Next state is different: switch to it and set substate to entry value */
482  pImdState->previousState = pImdState->currentState;
483  pImdState->currentState = nextState;
484  } else {
485  /* Next state equal to current state: nothing to do */
486  }
487 }
488 
490  I165C_DISABLE_STATE_s *pImdState,
491  I165C_FSM_DISABLE_STATES_e nextState,
492  uint16_t idleTime) {
493  FAS_ASSERT(pImdState != NULL_PTR);
494  /* Set time */
495  pImdState->timer = idleTime;
496  /* Set state */
497  if (nextState != pImdState->currentState) {
498  /* Next state is different: switch to it and set substate to entry value */
499  pImdState->previousState = pImdState->currentState;
500  pImdState->currentState = nextState;
501  } else {
502  /* Next state equal to current state: nothing to do */
503  }
504 }
505 
506 static void I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *pCanMessage) {
507  FAS_ASSERT(pCanMessage != NULL_PTR);
508  for (uint8_t i = 0u; i < CAN_DEFAULT_DLC; i++) {
509  pCanMessage->data[i] = 0u;
510  }
511 }
512 
513 static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *pCanMessage) {
514  FAS_ASSERT(pCanMessage != NULL_PTR);
515  /* See data sheet section 6.1 page 15 */
516  if (dataWord == I165C_DW1) {
517  pCanMessage->data[CAN_BYTE_1_POSITION] = (uint8_t)(data & 0xFFu);
518  pCanMessage->data[CAN_BYTE_2_POSITION] = (uint8_t)((data >> 8u) & 0xFFu);
519  }
520  if (dataWord == I165C_DW2) {
521  pCanMessage->data[CAN_BYTE_3_POSITION] = (uint8_t)(data & 0xFFu);
522  pCanMessage->data[CAN_BYTE_4_POSITION] = (uint8_t)((data >> 8u) & 0xFFu);
523  }
524 }
525 
526 static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage) {
527  FAS_ASSERT(pData != NULL_PTR);
528  /* See data sheet section 6.1 page 15 */
529  if (dataWord == I165C_DW1) {
530  *pData = canMessage.data[CAN_BYTE_1_POSITION];
531  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_2_POSITION]) << 8u) & 0xFF00u;
532  }
533  if (dataWord == I165C_DW2) {
534  *pData = canMessage.data[CAN_BYTE_3_POSITION];
535  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_4_POSITION]) << 8u) & 0xFF00u;
536  }
537  if (dataWord == I165C_DW3) {
538  *pData = canMessage.data[CAN_BYTE_5_POSITION];
539  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_6_POSITION]) << 8u) & 0xFF00u;
540  }
541 }
542 
543 static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage) {
544  FAS_ASSERT(pData != NULL_PTR);
545  /* See data sheet section 6.1 page 15 */
546  if (dataWord == I165C_DW1) {
547  *pData = canMessage.data[CAN_BYTE_0_POSITION];
548  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_1_POSITION]) << 8u) & 0xFF00u;
549  }
550  if (dataWord == I165C_DW2) {
551  *pData = canMessage.data[CAN_BYTE_2_POSITION];
552  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_3_POSITION]) << 8u) & 0xFF00u;
553  }
554  if (dataWord == I165C_DW3) {
555  *pData = canMessage.data[CAN_BYTE_4_POSITION];
556  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_5_POSITION]) << 8u) & 0xFF00u;
557  }
558 }
559 
560 static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFER_ELEMENT_s canMessage) {
561  FAS_ASSERT(pData != NULL_PTR);
562  /* See data sheet section 6.1 page 15 */
563  switch (dataByte) {
564  case I165C_DB1:
565  *pData = canMessage.data[CAN_BYTE_1_POSITION];
566  break;
567  case I165C_DB2:
568  *pData = canMessage.data[CAN_BYTE_2_POSITION];
569  break;
570  case I165C_DB3:
571  *pData = canMessage.data[CAN_BYTE_3_POSITION];
572  break;
573  case I165C_DB4:
574  *pData = canMessage.data[CAN_BYTE_4_POSITION];
575  break;
576  default:
577  *pData = 0u;
578  break;
579  }
580 }
581 
582 static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage) {
583  FAS_ASSERT(pCanMessage != NULL_PTR);
584  /* CAN message is a request, set ID accordingly */
585  pCanMessage->id = id;
587  /* First byte contains the CMD field */
588  pCanMessage->data[CAN_BYTE_0_POSITION] = command;
589 }
590 
591 static bool I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage) {
592  FAS_ASSERT(pCanMessage != NULL_PTR);
593  bool messageReceived = false;
594  uint8_t numberItems = 0u;
595  uint8_t queueReadTries = I165C_MAX_QUEUE_READS;
596 
597  /* Use loop on queue because IMD_info message could come meanwhile */
598  do {
600  if (numberItems > 0u) {
601  if (OS_ReceiveFromQueue(ftsk_imdCanDataQueue, (void *)pCanMessage, 0u) == OS_SUCCESS) {
602  /* data queue was no empty */
603  if ((command == pCanMessage->data[CAN_BYTE_0_POSITION]) && (pCanMessage->id == CANRX_IMD_RESPONSE_ID) &&
604  (pCanMessage->idType == I165C_RX_MESSAGE_IDENTIFIER_TYPE)) {
605  messageReceived = true;
606  break;
607  }
608  }
609  }
610  queueReadTries--;
611  } while ((numberItems > 0u) && (queueReadTries > 0u));
612 
613  return messageReceived;
614 }
615 
616 static bool I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *pCanMessage) {
617  FAS_ASSERT(pCanMessage != NULL_PTR);
618  bool imdInfoReceived = false;
619  uint8_t numberItems = 0u;
620  uint8_t queueReadTries = I165C_MAX_QUEUE_READS;
621 
622  /* Use loop on queue because other messages could come meanwhile */
623  do {
625  if (numberItems > 0u) {
626  if (OS_ReceiveFromQueue(ftsk_imdCanDataQueue, (void *)pCanMessage, 0u) == OS_SUCCESS) {
627  /* data queue was no empty */
628  if (pCanMessage->id == I165C_MESSAGETYPE_IMD_INFO) {
629  imdInfoReceived = true;
630  break;
631  }
632  }
633  }
634  queueReadTries--;
635  } while ((numberItems > 0u) && (queueReadTries > 0u));
636 
637  return imdInfoReceived;
638 }
639 
641  bool initialized = true;
642  uint16_t data = 0u;
643 
644  /* Extract D_IMC_STATUS */
645  I165C_ReadDataWordImdInfo(I165C_DW2, &data, canMessage);
646  /* I165C_SELFTEST_RUNNING bit = 1 in IMD_Info DW2: self test running */
647  uint16_t selfTestState = (data & (1u << I165C_SELFTEST_RUNNING_SHIFT));
648  if (selfTestState != (1u << I165C_SELFTEST_RUNNING_SHIFT)) {
649  /* self test not running */
650  initialized = false;
651  }
652 
653  /* Extract D_VIFC_STATUS */
654  I165C_ReadDataWordImdInfo(I165C_DW3, &data, canMessage);
655  /* I165C_INSULATION_MEASUREMENT bit = 0 in IMD_Info DW3: insulation measurement active */
656  uint16_t insulationMeasurementState = (data & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT));
657  if (insulationMeasurementState != 0u) {
658  /* insulation measurement active */
659  initialized = false;
660  }
661 #ifdef I165C_SELF_TEST_LONG
662  /* I165C_IMC_SELFTEST_OVERALL_SCENARIO bit = 1 in IMD_Info DW3: selftest overall scenario not executed */
663  uint16_t selfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT));
664  if (selfTestExecuted != 0u) {
665  /* selftest overall scenario not executed */
666  initialized = false;
667  }
668 #else
669  /* I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO bit = 1 in IMD_Info DW3: selftest parameter config not executed */
670  uint16_t selfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT));
671  if (selfTestExecuted != 0u) {
672  /* selftest parameter scenario not executed */
673  initialized = false;
674  }
675 #endif
676  return initialized;
677 }
678 
680  bool anySelfTestExecuted = false;
681  uint16_t data = 0u;
682 
683  /* Extract D_VIFC_STATUS */
684  I165C_ReadDataWordImdInfo(I165C_DW3, &data, canMessage);
685 
686  /* I165C_IMC_SELFTEST_OVERALL_SCENARIO bit = 1 in IMD_Info DW3: selftest overall scenario not executed */
687  uint16_t overallSelfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT));
688  if (overallSelfTestExecuted == 0u) {
689  /* selftest overall scenario has been executed */
690  anySelfTestExecuted = true;
691  }
692  /* I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO bit = 1 in IMD_Info DW3: selftest parameter config not executed */
693  uint16_t parameterSelfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT));
694  if (parameterSelfTestExecuted == 0u) {
695  /* selftest parameter scenario has been executed */
696  anySelfTestExecuted = true;
697  }
698  return anySelfTestExecuted;
699 }
700 
701 static void I165C_SetRelayState(uint8_t relay, uint8_t relayState) {
703  FAS_ASSERT((relayState == I165C_RELAY_STATE_OPEN) || (relayState == I165C_RELAY_STATE_CLOSED));
704  /* Reset CAN message buffer */
706  /* Assemble CAN message */
710  /* Transmit CAN message */
712 }
713 
714 static void I165C_RequestRelayState(uint8_t relay) {
716  /* Reset CAN message buffer */
718  /* Assemble CAN message */
721  /* Transmit CAN message */
723 }
724 
725 static bool I165C_CheckRelayState(CAN_BUFFER_ELEMENT_s canMessage, uint8_t relay, uint8_t relayState) {
727  FAS_ASSERT((relayState == I165C_RELAY_STATE_OPEN) || (relayState == I165C_RELAY_STATE_CLOSED));
728  bool checkSuccess = true;
729  uint16_t data = 0u;
730 
732  /* IMD_Response DW1: relay */
733  if (relay != data) {
734  /* not request relay */
735  checkSuccess = false;
736  }
737 
739  /* IMD_Response DW2: relay state */
740  if (relayState != data) {
741  /* relay state does not match expected state */
742  checkSuccess = false;
743  }
744  return checkSuccess;
745 }
746 
747 static void I165C_SetMeasurementMode(uint8_t mode) {
749  /* Reset CAN message buffer */
751  /* Assemble CAN message */
754  /* Transmit CAN message */
756 }
757 
758 static bool I165C_CheckMeasurementMode(CAN_BUFFER_ELEMENT_s canMessage, uint8_t mode) {
760  bool measurementModeMatches = false;
761  uint16_t dVIFCStatus = 0u;
762 
763  /* Extract D_VIFC_STATUS word */
765  /* Extract measurement mode from D_VIFC_STATUS word */
766  uint8_t actualMeasurementMode = dVIFCStatus & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT);
767 
768  /* Check if actual measurement mode matches passed measurement mode */
769  if (actualMeasurementMode == mode) {
770  /* Insulation measurement deactivated*/
771  measurementModeMatches = true;
772  }
773  return measurementModeMatches;
774 }
775 
776 static void I165C_SetAveragingFactor(uint8_t averagingFactor) {
777  /* Averaging factor must be in the range 1...20 */
778  FAS_ASSERT(averagingFactor != 0u);
779  FAS_ASSERT(averagingFactor <= 20u);
780 
781  /* Reset CAN message buffer */
783  /* Assemble CAN message */
786  /* Transmit CAN message */
788 }
789 
790 static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFER_ELEMENT_s *pCanMessage) {
791  FAS_ASSERT(pTries != NULL_PTR);
792  FAS_ASSERT(pCanMessage != NULL_PTR);
793  /* AXIVION Routine Generic-MissingParameterAssert: command: parameter accepts whole range */
794 
795  bool acknowledgeReceived = false;
796  if (I165C_CheckResponse(command, pCanMessage) == false) {
797  (*pTries)++;
798  } else {
799  *pTries = 0u;
800  acknowledgeReceived = true;
801  }
802  return acknowledgeReceived;
803 }
804 
806  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_INITIALIZATION; /* stay in initialization state */
807  bool earlyExit = false;
808 
809  if (i165c_initializationState.timer > 0u) {
810  if ((--i165c_initializationState.timer) > 0u) {
812  earlyExit = true;
813  }
814  }
815 
816  if (earlyExit == false) {
819  /* Unlock device in case it was locked */
827  break;
828 
832  true) {
837  } else {
838  /* Issue: 621 */
839  }
840  break;
841 
843  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
845  /* Measurement is not enabled -> Enable measurement as otherwise the following
846  * initialization procedure would fail */
852  } else {
853  /* Measurement enabled -> continue with initialization procedure */
858  }
859  }
860  break;
861 
866  &i165c_canRxMessage) == true) {
867  /* Measurement enabled -> continue with initialization procedure */
872  } else {
873  /* Issue: 621 */
874  }
875  break;
876 
878  /* Open negative relay */
880  /* Open positive relay */
882  /* Switch to next state */
887  break;
888 
895  break;
896 
898  /* Check if HV relay is open and measurement has been stopped */
904 
905  /* Request state of positive HV relay */
907 
912  } else {
914  /* Issue: 621 */
915  }
916  } else {
918  /* Issue: 621 */
919  }
920  break;
921 
923  /* Check if HV relays are open and measurement has been stopped */
929 
934  } else {
936  /* Issue: 621 */
937  }
938  } else {
940  /* Issue: 621 */
941  }
942  break;
943 
945  /* A self test must be requested and can only be carried out
946  when the coupling relays are open. */
947 
948  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
953 #ifdef I165C_SELF_TEST_LONG
956 #else /* I165C_SELF_TEST_SHORT */
961 #endif
962  CAN_DataSend(
969  } else {
970  /* Self-test has already been performed -> skip following initialization steps as the device
971  has previously been successfully configured. */
976  }
977  }
978 
979  break;
980 
984  true) {
989  } else {
990  /* Issue: 621 */
992  /* Issue: 621 */
998  }
999  }
1000  break;
1002  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
1005  } else {
1012  }
1013  } else {
1014  /* Issue: 621 */
1017  /* Initialization not working: restart initialization procedure */
1018  /* Issue: 621 */
1019  }
1020  }
1021  break;
1022 
1029  break;
1030 
1035  &i165c_canRxMessage) == true) {
1040  } else {
1041  /* Issue: 621 */
1042  }
1043  break;
1044 
1055  break;
1060  &i165c_canRxMessage) == true) {
1065  } else {
1066  /* Issue: 621 */
1067  }
1068  break;
1079  break;
1084  &i165c_canRxMessage) == true) {
1089  } else {
1090  /* Issue: 621 */
1091  }
1092  break;
1093 
1100  break;
1101 
1106  &i165c_canRxMessage) == true) {
1107  /* Initialized -> switch to next state in IMD state machine */
1108  nextState = IMD_FSM_STATE_IMD_ENABLE;
1109  /* Reset state machine in case a re-initialization is necessary */
1112  } else {
1113  /* Issue: 621 */
1114  }
1115  break;
1116 
1117  default:
1119  break; /* LCOV_EXCL_LINE */
1120  }
1122  }
1123  return nextState;
1124 }
1125 
1127  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_IMD_ENABLE; /* stay in enable state */
1128  bool earlyExit = false;
1129 
1130  if (i165c_enableState.timer > 0u) {
1131  if ((--i165c_enableState.timer) > 0u) {
1133  earlyExit = true;
1134  }
1135  }
1136 
1137  if (earlyExit == false) {
1138  switch (i165c_enableState.currentState) {
1140  /* Close negative relay */
1142  /* Close positive relay */
1144  /* Switch to next state */
1147  break;
1148 
1153  break;
1154 
1161 
1162  /* Request state of positive HV relay */
1168  } else {
1170  /* Issue: 621 */
1171  }
1172  } else {
1174  /* Issue: 621 */
1181  }
1182  /* Issue: 621 */
1183  }
1184  break;
1185 
1192 
1195  } else {
1197  /* Issue: 621 */
1198  }
1199  } else {
1201  /* Issue: 621 */
1202  }
1203  break;
1204 
1209  break;
1210 
1214  true) {
1215  /* Enabled -> switch to next state in IMD state machine */
1216  nextState = IMD_FSM_STATE_RUNNING;
1217  /* Reset state machine in case a re-enabling is necessary */
1220  } else {
1221  /* Issue: 621 */
1222  }
1223  break;
1224  }
1225  }
1226  return nextState;
1227 }
1228 
1230  FAS_ASSERT(pTableInsulationMonitoring != NULL_PTR);
1231  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_RUNNING; /* stay in running state */
1232  bool earlyExit = false;
1233  uint16_t resistance_kOhm = 0u;
1234  uint16_t statusFlags = 0u;
1235  uint8_t data1 = 0u;
1236  uint8_t data2 = 0u;
1237 
1238  if (i165c_runningState.timer > 0u) {
1239  if ((--i165c_runningState.timer) > 0u) {
1241  earlyExit = true;
1242  }
1243  }
1244 
1245  if (earlyExit == false) {
1246  switch (i165c_runningState.currentState) {
1248  /* Switch to next state */
1251  break;
1252 
1260  break;
1261 
1265  /* Extract resistance value from response */
1266  I165C_ReadDataWord(I165C_DW1, &resistance_kOhm, i165c_canRxMessage);
1267  pTableInsulationMonitoring->insulationResistance_kOhm = resistance_kOhm;
1268 
1269  /* Extract bias/tendency to the location of the insulation fault (error), if detected */
1271  if (data1 == I165C_BIAS_TO_HV_PLUS) {
1272  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = true;
1273  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = false;
1274  } else if (data1 == I165C_BIAS_TO_HV_MINUS) {
1275  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = true;
1276  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = false;
1277  } else {
1278  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = false;
1279  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = false;
1280  }
1281 
1282  /* Extract counter value */
1284  /* TODO: What to do with this info? */
1285 
1288  } else {
1289  /* Issue: 621 */
1290  }
1291  break;
1292 
1294  if (I165C_GetImdInfo(&i165c_canRxMessage) == false) {
1296  /* Issue: 621 */
1297  /* IMD_Info not coming: restart initialization procedure?
1298  if (i165c_runningState.receptionTriesMessage >= I165C_IMD_INFO_RECEIVE_ATTEMPTS) {*/
1299  } else {
1301 
1302  /* Get measured resistance */
1304  pTableInsulationMonitoring->insulationResistance_kOhm = resistance_kOhm;
1305 
1306  /* Get IMC status */
1308  if (0u != (statusFlags & (1u << I165C_INSULATION_FAULT_SHIFT))) {
1309  /* Insulation fault */
1310  pTableInsulationMonitoring->dfIsCriticalResistanceDetected = true;
1311  } else {
1312  pTableInsulationMonitoring->dfIsCriticalResistanceDetected = false;
1313  }
1314  if (0u != (statusFlags & (1u << I165C_CHASSIS_FAULT_SHIFT))) {
1315  /* Chassis fault */
1316  pTableInsulationMonitoring->dfIsChassisFaultDetected = true;
1317  } else {
1318  pTableInsulationMonitoring->dfIsChassisFaultDetected = false;
1319  }
1320  if (0u != (statusFlags & (1u << I165C_SYSTEM_FAILURE_SHIFT))) {
1321  /* System failure */
1322  pTableInsulationMonitoring->dfIsDeviceErrorDetected = true;
1323  pTableInsulationMonitoring->areDeviceFlagsValid = false;
1324  } else {
1325  pTableInsulationMonitoring->dfIsDeviceErrorDetected = false;
1326  pTableInsulationMonitoring->areDeviceFlagsValid = true;
1327  }
1328  if (0u != (statusFlags & (1u << I165C_INSULATION_WARNING_SHIFT))) {
1329  /* Insulation warning */
1330  pTableInsulationMonitoring->dfIsWarnableResistanceDetected = true;
1331  } else {
1332  pTableInsulationMonitoring->dfIsWarnableResistanceDetected = false;
1333  }
1334 
1335  /* Get VIFC status */
1337  if (0u != (statusFlags & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT))) {
1338  /* Insulation measurement deactivated*/
1339  pTableInsulationMonitoring->isImdRunning = false;
1340  } else {
1341  pTableInsulationMonitoring->isImdRunning = true;
1342  }
1343  if (0u != (statusFlags & (1u << I165C_RESISTANCE_VALUE_OUTDATED_SHIFT))) {
1344  /* Insulation resistance value outdated */
1345  pTableInsulationMonitoring->dfIsMeasurementUpToDate = false;
1346  } else {
1347  pTableInsulationMonitoring->dfIsMeasurementUpToDate = true;
1348  }
1349  if ((pTableInsulationMonitoring->areDeviceFlagsValid == true) &&
1350  (pTableInsulationMonitoring->isImdRunning == true) &&
1351  (pTableInsulationMonitoring->dfIsMeasurementUpToDate == true)) {
1352  pTableInsulationMonitoring->isInsulationMeasurementValid = true;
1353  } else {
1354  pTableInsulationMonitoring->isInsulationMeasurementValid = false;
1355  }
1356  }
1357  /* Restart measurement cycle */
1360  break;
1361 
1362  default:
1363  /* invalid state */
1364  nextState = IMD_FSM_STATE_ERROR;
1366  break;
1367  }
1368  }
1369  return nextState;
1370 }
1371 
1372 /** Disable state machine */
1374  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_SHUTDOWN; /* stay in shutdown state */
1375  bool earlyExit = false;
1376 
1377  if (i165c_disableState.timer > 0u) {
1378  if ((--i165c_disableState.timer) > 0u) {
1380  earlyExit = true;
1381  }
1382  }
1383 
1384  if (earlyExit == false) {
1385  switch (i165c_disableState.currentState) {
1387  /* The I165C_Running state-machine, does not know when the
1388  * disable command is received by the superimposed IMD state
1389  * machine. Thus, the I165C_Running state machine needs to be
1390  * reset at this point to correctly call the running state
1391  * machine after re-enabling. */
1393 
1394  /* Request stop of measurement */
1398  break;
1399 
1403  true) {
1406  } else {
1407  /* Issue: 621 */
1408  }
1409  break;
1410 
1412  /* Open negative relay */
1414  /* Open positive relay */
1418  break;
1419 
1424  break;
1425 
1432 
1433  /* Request state of positive HV relay */
1439  } else {
1441  /* Issue: 621 */
1442  }
1443  } else {
1445  /* Issue: 621 */
1446  }
1447  break;
1448 
1455 
1456  /* Reset disable state machine in case a another disabling is necessary */
1459 
1460  /* IMD successfully disabled -> switch to next state in superimposed IMD state machine */
1461  nextState = IMD_FSM_STATE_IMD_ENABLE;
1462  } else {
1464  /* Issue: 621 */
1465  }
1466  } else {
1468  /* Issue: 621 */
1469  }
1470  break;
1471  }
1472  }
1473  return nextState;
1474 }
1475 
1476 /*========== Extern Function Implementations ================================*/
1477 
1479  return I165C_Initialize();
1480 }
1481 
1483  return I165C_Enable();
1484 }
1485 
1487  FAS_ASSERT(pTableInsulationMonitoring != NULL_PTR);
1488  return I165C_Running(pTableInsulationMonitoring);
1489 }
1490 
1492  return I165C_Disable();
1493 }
1494 
1495 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1496 #ifdef UNITY_UNIT_TEST
1497 extern void TEST_I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *canMessage) {
1498  I165C_ResetCanData(canMessage);
1499 }
1500 extern void TEST_I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *canMessage) {
1501  I165C_WriteDataWord(dataWord, data, canMessage);
1502 }
1503 extern void TEST_I165C_ReadDataWord(uint8_t dataWord, uint16_t *data, CAN_BUFFER_ELEMENT_s canMessage) {
1504  I165C_ReadDataWord(dataWord, data, canMessage);
1505 }
1506 extern void TEST_I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *data, CAN_BUFFER_ELEMENT_s canMessage) {
1507  I165C_ReadDataWordImdInfo(dataWord, data, canMessage);
1508 }
1509 extern void TEST_I165C_ReadDataByte(uint8_t dataByte, uint8_t *data, CAN_BUFFER_ELEMENT_s canMessage) {
1510  I165C_ReadDataByte(dataByte, data, canMessage);
1511 }
1512 extern void TEST_I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *canMessage) {
1513  I165C_WriteCmd(id, command, canMessage);
1514 }
1515 extern bool TEST_I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *canMessage) {
1516  return I165C_CheckResponse(command, canMessage);
1517 }
1518 extern bool TEST_I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *canMessage) {
1519  return I165C_GetImdInfo(canMessage);
1520 }
1521 extern bool TEST_I165C_IsSelfTestFinished(CAN_BUFFER_ELEMENT_s canMessage) {
1522  return I165C_IsSelfTestFinished(canMessage);
1523 }
1524 extern bool TEST_I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *tries, CAN_BUFFER_ELEMENT_s *canMessage) {
1525  return I165C_CheckAcknowledgeArrived(command, tries, canMessage);
1526 }
1527 
1528 #endif
static bool I165C_CheckRelayState(CAN_BUFFER_ELEMENT_s canMessage, uint8_t relay, uint8_t relayState)
Check state of HV relay.
static IMD_FSM_STATES_e I165C_Initialize(void)
static CAN_BUFFER_ELEMENT_s i165c_canTxMessage
static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage)
Compose CAN message for CAN transmission.
static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFER_ELEMENT_s canMessage)
Get data in data byte from CAN transmission.
static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage)
Get data in data word from CAN transmission, for the specific IMD_Info message.
IMD_FSM_STATES_e IMD_ProcessInitializationState(void)
Processes the initialization state.
static bool I165C_HasSelfTestBeenExecuted(CAN_BUFFER_ELEMENT_s canMessage)
Check if iso165c has already been performed previously.
static IMD_FSM_STATES_e I165C_Disable(void)
static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFER_ELEMENT_s *pCanMessage)
Check if iso165c acknowledged reception of command.
I165C_FSM_INITIALIZATION_STATES_e
@ I165C_FSM_STATE_INITIALIZATION_SET_ERROR_THRESHOLD
@ I165C_FSM_STATE_INITIALIZATION_UNLOCK_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_DUMMY
@ I165C_FSM_STATE_INITIALIZATION_ERROR_THRESHOLD_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_AVERAGING_FACTOR_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_SET_WARNING_THRESHOLD
@ I165C_FSM_STATE_INITIALIZATION_WARNING_THRESHOLD_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_CHECK_MEASUREMENT_STATE
@ I165C_FSM_STATE_INITIALIZATION_DISABLE_MEASUREMENT_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_DISABLE_MEASUREMENT
@ I165C_FSM_STATE_INITIALIZATION_REQUEST_HV_RELAY_OPENING
@ I165C_FSM_STATE_INITIALIZATION_SELF_TEST_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_ENABLE_MEASUREMENT_WAIT_ACK
@ I165C_FSM_STATE_INITIALIZATION_CHECK_NEGATIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_INITIALIZATION_SET_AVERAGING_FACTOR
@ I165C_FSM_STATE_INITIALIZATION_WAIT_SELF_TEST
@ I165C_FSM_STATE_INITIALIZATION_REQUEST_SELF_TEST
@ I165C_FSM_STATE_INITIALIZATION_CHECK_POSITIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_INITIALIZATION_REQUEST_NEGATIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_INITIALIZATION_HAS_NEVER_RUN
static void I165C_SetDisableState(I165C_DISABLE_STATE_s *pImdState, I165C_FSM_DISABLE_STATES_e nextState, uint16_t idleTime)
Sets the next state the timer value of the disable state variable.
static I165C_INITIALIZATION_STATE_s i165c_initializationState
static void I165C_SetMeasurementMode(uint8_t mode)
Set measurement mode.
IMD_FSM_STATES_e IMD_ProcessShutdownState(void)
Processes the shutdown state.
static void I165C_SetEnableState(I165C_ENABLE_STATE_s *pImdState, I165C_FSM_ENABLE_STATES_e nextState, uint16_t idleTime)
Sets the next state the timer value of the enable state variable.
I165C_FSM_DISABLE_STATES_e
@ I165C_FSM_STATE_DISABLE_SET_HV_RELAY_STATE
@ I165C_FSM_STATE_MEASUREMENT_STOPPED_WAIT_ACK
@ I165C_FSM_STATE_DISABLE_CHECK_NEGATIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_DISABLE_HAS_NEVER_RUN
@ I165C_FSM_STATE_DISABLE_DUMMY
@ I165C_FSM_STATE_DISABLE_REQUEST_NEGATIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_DISABLE_CHECK_POSITIVE_HV_RELAY_STATE
static void I165C_SetRunningState(I165C_RUNNING_STATE_s *pImdState, I165C_FSM_RUNNING_STATES_e nextState, uint16_t idleTime)
Sets the next state the timer value of the running state variable.
I165C_FSM_RUNNING_STATES_e
@ I165C_FSM_STATE_RUNNING_HAS_NEVER_RUN
@ I165C_FSM_STATE_RUNNING_GET_MEASUREMENT
@ I165C_FSM_STATE_RUNNING_READ_RESISTANCE_WAIT_ACK
@ I165C_FSM_STATE_RUNNING_DUMMY
@ I165C_FSM_STATE_RUNNING_READ_RESISTANCE
I165C_FSM_ENABLE_STATES_e
@ I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN
@ I165C_FSM_STATE_ENABLE_CHECK_NEGATIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_ENABLE_START_MEASUREMENT_WAIT_ACK
@ I165C_FSM_STATE_ENABLE_DUMMY
@ I165C_FSM_STATE_ENABLE_START_MEASUREMENT
@ I165C_FSM_STATE_ENABLE_REQUEST_NEGATIVE_HV_RELAY_STATE
@ I165C_FSM_STATE_ENABLE_CHECK_POSITIVE_HV_RELAY_STATE
IMD_FSM_STATES_e IMD_ProcessEnableState(void)
Processes the IMD enable state.
static IMD_FSM_STATES_e I165C_Running(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring)
trigger function for the i165c driver state machine.
static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *pCanMessage)
Write data in data word for CAN transmission.
static void I165C_SetInitializationState(I165C_INITIALIZATION_STATE_s *pImdState, I165C_FSM_INITIALIZATION_STATES_e nextState, uint16_t idleTime)
Sets the next state the timer value of the initialization state variable.
static I165C_RUNNING_STATE_s i165c_runningState
static I165C_DISABLE_STATE_s i165c_disableState
static void I165C_SetRelayState(uint8_t relay, uint8_t relayState)
Set state of HV relay.
#define I165C_FSM_SHORT_TIME
static void I165C_RequestRelayState(uint8_t relay)
Request state of HV relay.
static bool I165C_IsSelfTestFinished(CAN_BUFFER_ELEMENT_s canMessage)
Check if iso165c was initialized and is running.
static bool I165C_CheckMeasurementMode(CAN_BUFFER_ELEMENT_s canMessage, uint8_t mode)
Check measurement mode.
static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage)
Get data in data word from CAN transmission.
static void I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *pCanMessage)
Reset CAN data.
static IMD_FSM_STATES_e I165C_Enable(void)
static void I165C_SetAveragingFactor(uint8_t averagingFactor)
Set average factor of the insulation resistance averaging algorithm.
static bool I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage)
Check if iso165c acknowledged reception of sent message and get corresponding data.
static CAN_BUFFER_ELEMENT_s i165c_canRxMessage
static bool I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *pCanMessage)
Get IMD Info from iso165c.
static I165C_ENABLE_STATE_s i165c_enableState
IMD_FSM_STATES_e IMD_ProcessRunningState(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring)
Processes the running state.
Headers for the driver for the insulation monitoring.
#define I165C_D_VIFC_HV_RELAIS_STATE_GET_RESPONSE
#define I165C_INSULATION_FAULT_SHIFT
#define I165C_D_VIFC_HV_RELAIS_SET_REQUEST
#define I165C_D_IMC_MEAN_FACTOR_SET_REQUEST
#define I165C_D_VIFC_HV_RELAIS_POSITIVE
#define I165C_BIAS_TO_HV_PLUS
#define I165C_UNLOCK_PASSWORD
#define I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT
#define I165C_CMD_S_IMC_SET_R_ISO_ERR_THR
#define I165C_RELAY_STATE_CLOSED
#define I165C_D_VIFC_HV_RELAIS_GET_REQUEST
#define I165C_INSULATION_MEASUREMENT_STATUS_SHIFT
#define I165C_LOCKMODE_UNLOCKED
#define I165C_DW_VIFC_CTL_MEASUREMENT_REQUEST
#define I165C_CMD_S_VIFC_CTL_MEASUREMENT
#define I165C_CMD_S_IMC_SET_R_ISO_ERR_WRN
#define I165C_CMD_S_IMC_SET_MEAN_FACTOR
#define I165C_D_IMC_R_ISO_CNT_GET_RESPONSE
#define I165C_DB2
#define I165C_CMD_S_IMC_CTL_SELFTEST
#define I165C_MAX_QUEUE_READS
#define I165C_SELFTEST_SCENARIO_PARAMETERCONFIG
#define I165C_SELFTEST_SCENARIO_OVERALL
#define I165C_CMD_S_IMC_GET_R_ISO
#define I165C_D_VIFC_HV_RELAIS_GET_RESPONSE
#define I165C_D_IMC_SELFTEST_SCR_CTL_REQUEST
#define I165C_SYSTEM_FAILURE_SHIFT
#define I165C_D_VIFC_LOCK_MODE_CTL_REQUEST
#define I165C_TRANSMISSION_ATTEMPTS
#define I165C_RX_MESSAGE_IDENTIFIER_TYPE
#define I165C_MESSAGETYPE_IMD_INFO
#define I165C_CAN_NODE
#define I165C_CMD_S_VIFC_SET_HV_RELAIS
#define I165C_WARNING_THRESHOLD_kOhm
#define I165C_BIAS_TO_HV_MINUS
#define I165C_DW2
#define I165C_MESSAGETYPE_IMD_REQUEST
#define I165C_D_IMC_R_ISO_ERR_WRN_SET_REQUEST
#define I165C_TX_MESSAGE_IDENTIFIER_TYPE
#define I165C_DISABLE_MEASUREMENT
#define I165C_SELFTEST_RUNNING_SHIFT
#define I165C_DB3
#define I165C_DW1
#define I165C_IMD_INFO_RECEIVE_ATTEMPTS
#define I165C_DB1
#define I165C_RELAY_STATE_OPEN
#define I165C_CHASSIS_FAULT_SHIFT
#define I165C_D_VIFC_HV_RELAIS_STATE_SET_REQUEST
#define I165C_ERROR_THRESHOLD_kOhm
#define I165C_INSULATION_WARNING_SHIFT
#define I165C_D_VIFC_LOCK_PWD_CTL_REQUEST
#define I165C_D_IMC_R_ISO_BIAS_GET_RESPONSE
#define I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT
#define I165C_CMD_S_VIFC_GET_HV_RELAIS
#define I165C_ENABLE_MEASUREMENT
#define I165C_DW3
#define I165C_D_VIFC_HV_RELAIS_NEGATIVE
#define I165C_RESISTANCE_VALUE_OUTDATED_SHIFT
#define I165C_DB4
#define I165C_CMD_S_VIFC_CTL_LOCK
#define I165C_MEASUREMENT_AVERAGING_FACTOR
#define I165C_D_IMC_R_ISO_ERR_THR_SET_REQUEST
STD_RETURN_TYPE_e CAN_DataSend(CAN_NODE_s *pNode, uint32_t id, CAN_IDENTIFIER_TYPE_e idType, uint8 *pData)
Sends over CAN the data passed in parameters. This function goes over the message boxes and marks the...
Definition: can.c:781
Header for the driver for the CAN module.
#define CAN_DEFAULT_DLC
Definition: can_cfg.h:103
Header for the driver for the CAN module.
#define CANRX_IMD_RESPONSE_ID
Header for the driver for the CAN module.
Headers for the helper functions for the CAN module.
#define CAN_BYTE_2_POSITION
Definition: can_helper.h:73
#define CAN_BYTE_4_POSITION
Definition: can_helper.h:75
#define CAN_BYTE_0_POSITION
Definition: can_helper.h:71
#define CAN_BYTE_6_POSITION
Definition: can_helper.h:77
#define CAN_BYTE_3_POSITION
Definition: can_helper.h:74
#define CAN_BYTE_5_POSITION
Definition: can_helper.h:76
#define CAN_BYTE_1_POSITION
Definition: can_helper.h:72
Database module header.
Database configuration header.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:254
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
Header of task driver implementation.
OS_QUEUE ftsk_imdCanDataQueue
IMD_FSM_STATES_e
Definition: imd.h:93
@ IMD_FSM_STATE_RUNNING
Definition: imd.h:100
@ IMD_FSM_STATE_SHUTDOWN
Definition: imd.h:99
@ IMD_FSM_STATE_INITIALIZATION
Definition: imd.h:97
@ IMD_FSM_STATE_IMD_ENABLE
Definition: imd.h:98
@ IMD_FSM_STATE_ERROR
Definition: imd.h:101
@ OS_SUCCESS
Definition: os.h:83
OS_STD_RETURN_e OS_ReceiveFromQueue(OS_QUEUE xQueue, void *const pvBuffer, uint32_t ticksToWait)
Receive an item from a queue.
Definition: os_freertos.c:248
uint32_t OS_GetNumberOfStoredMessagesInQueue(OS_QUEUE xQueue)
Check if messages are waiting for queue.
Definition: os_freertos.c:289
uint8_t data[CAN_MAX_DLC]
Definition: can_cfg.h:173
CAN_IDENTIFIER_TYPE_e idType
Definition: can_cfg.h:172
I165C_FSM_DISABLE_STATES_e previousState
I165C_FSM_DISABLE_STATES_e currentState
I165C_FSM_ENABLE_STATES_e previousState
I165C_FSM_ENABLE_STATES_e currentState
I165C_FSM_INITIALIZATION_STATES_e currentState
I165C_FSM_INITIALIZATION_STATES_e previousState
I165C_FSM_RUNNING_STATES_e currentState
I165C_FSM_RUNNING_STATES_e previousState