foxBMS - Unit Tests  1.4.1
The foxBMS Unit Tests API Documentation
bender_iso165c.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2022, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file bender_iso165c.c
44  * @author foxBMS Team
45  * @date 2019-04-07 (date of creation)
46  * @updated 2022-10-27 (date of last update)
47  * @version v1.4.1
48  * @ingroup DRIVERS
49  * @prefix I165C
50  *
51  * @brief Driver for the insulation monitoring
52  *
53  * 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"
64 #include "can_helper.h"
65 #include "database.h"
66 #include "ftask.h"
67 
68 /*========== Macros and Definitions =========================================*/
69 /** state machine short time definition in trigger calls until next state is processed */
70 #define I165C_FSM_SHORT_TIME (1u)
71 
72 /* -------------- State defines ---------------------------------------------*/
73 
74 /** States of the initialization state machine */
75 typedef enum {
76  I165C_FSM_STATE_INITIALIZATION_DUMMY, /*!< dummy state - always the first state */
77  I165C_FSM_STATE_INITIALIZATION_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
78  I165C_FSM_STATE_INITIALIZATION_UNLOCK_WAIT_ACK, /*!< wait acknowledge of unlocking */
79  I165C_FSM_STATE_INITIALIZATION_CHECK_MEASUREMENT_STATE, /*!< check if measurement is enabled. if not enable it */
80  I165C_FSM_STATE_INITIALIZATION_ENABLE_MEASUREMENT_WAIT_ACK, /*!< wait for acknowledge for enabling of measurement */
81  I165C_FSM_STATE_INITIALIZATION_REQUEST_HV_RELAY_OPENING, /*!< request HV relay state: open */
83  I165C_FSM_STATE_INITIALIZATION_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
84  I165C_FSM_STATE_INITIALIZATION_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
86  I165C_FSM_STATE_INITIALIZATION_SELF_TEST_WAIT_ACK, /*!< wait acknowledge of self-test */
87  I165C_FSM_STATE_INITIALIZATION_WAIT_SELF_TEST, /*!< wait until self-test is finished */
89  I165C_FSM_STATE_INITIALIZATION_AVERAGING_FACTOR_WAIT_ACK, /*!< wait acknowledge of averaging factor */
90  I165C_FSM_STATE_INITIALIZATION_SET_ERROR_THRESHOLD, /*!< configuration of error threshold */
91  I165C_FSM_STATE_INITIALIZATION_ERROR_THRESHOLD_WAIT_ACK, /*!< wait acknowledge of error threshold */
92  I165C_FSM_STATE_INITIALIZATION_SET_WARNING_THRESHOLD, /*!< configuration of warning threshold */
93  I165C_FSM_STATE_INITIALIZATION_WARNING_THRESHOLD_WAIT_ACK, /*!< wait acknowledge of warning threshold */
95  I165C_FSM_STATE_INITIALIZATION_DISABLE_MEASUREMENT_WAIT_ACK, /*!< wait acknowledge of disable measurement */
97 
98 /** States of the enable state machine */
99 typedef enum {
100  I165C_FSM_STATE_ENABLE_DUMMY, /*!< dummy state - always the first state */
101  I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
102  I165C_FSM_STATE_ENABLE_REQUEST_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
103  I165C_FSM_STATE_ENABLE_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
104  I165C_FSM_STATE_ENABLE_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
105  I165C_FSM_STATE_ENABLE_START_MEASUREMENT, /*!< start insulation measurement */
106  I165C_FSM_STATE_ENABLE_START_MEASUREMENT_WAIT_ACK, /*!< check for acknowledge of start measurement request */
108 
109 /** States of the running state machine */
110 typedef enum {
111  I165C_FSM_STATE_RUNNING_DUMMY, /*!< dummy state - always the first state */
112  I165C_FSM_STATE_RUNNING_HAS_NEVER_RUN, /*!< never run state - always the second state */
117 
118 /** States of the disable state machine */
119 typedef enum {
120  I165C_FSM_STATE_DISABLE_DUMMY, /*!< dummy state - always the first state */
121  I165C_FSM_STATE_DISABLE_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
122  I165C_FSM_STATE_MEASUREMENT_STOPPED_WAIT_ACK, /*!< wait for acknowledge of stop measurement request */
123  I165C_FSM_STATE_DISABLE_SET_HV_RELAY_STATE, /*!< request state of HV relays */
125  I165C_FSM_STATE_DISABLE_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
126  I165C_FSM_STATE_DISABLE_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
128 
129 /* -------------- State variables -------------------------------------------*/
130 
131 /** This struct describes the state of the initialization state machine */
132 typedef struct {
133  uint16_t timer; /*!< timer of the state */
134  uint8_t triggerEntry; /*!< trigger entry of the state */
135  I165C_FSM_INITIALIZATION_STATES_e currentState; /*!< current state of the FSM */
136  I165C_FSM_INITIALIZATION_STATES_e previousState; /*!< previous state of the FSM */
137  uint8_t receptionTries;
142 
143 typedef struct {
144  uint16_t timer; /*!< timer of the state */
145  uint8_t triggerEntry; /*!< trigger entry of the state */
146  I165C_FSM_ENABLE_STATES_e currentState; /*!< current state of the FSM */
147  I165C_FSM_ENABLE_STATES_e previousState; /*!< previous state of the FSM */
148  uint8_t receptionTries;
151 
152 typedef struct {
153  uint16_t timer; /*!< timer of the state */
154  uint8_t triggerEntry; /*!< trigger entry of the state */
155  I165C_FSM_RUNNING_STATES_e currentState; /*!< current state of the FSM */
156  I165C_FSM_RUNNING_STATES_e previousState; /*!< previous state of the FSM */
157  uint8_t receptionTries;
160 
161 typedef struct {
162  uint16_t timer; /*!< timer of the state */
163  uint8_t triggerEntry; /*!< trigger entry of the state */
164  I165C_FSM_DISABLE_STATES_e currentState; /*!< current state of the FSM */
165  I165C_FSM_DISABLE_STATES_e previousState; /*!< previous state of the FSM */
166  uint8_t receptionTries;
169 
170 /*========== Static Constant and Variable Definitions =======================*/
171 
173  .timer = 0u,
174  .triggerEntry = 0u,
176  .previousState = I165C_FSM_STATE_INITIALIZATION_DUMMY,
177  .receptionTries = 0u,
178  .receptionTriesMessage = 0u,
179 #if false == I165C_IS_165C_USED
180  /* Default state after startup is closed for iso165C-1 */
181  .negativeRelayClosed = true,
182  .positiveRelayClosed = true,
183 #else
184  /* Default state after startup is open for iso165C */
185  .negativeRelayClosed = false,
186  .positiveRelayClosed = false,
187 #endif
188 };
189 
191  .timer = 0u,
192  .triggerEntry = 0u,
193  .currentState = I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN,
194  .previousState = I165C_FSM_STATE_ENABLE_DUMMY,
195  .receptionTries = 0u,
196  .receptionTriesMessage = 0u,
197 };
198 
200  .timer = 0u,
201  .triggerEntry = 0u,
203  .previousState = I165C_FSM_STATE_RUNNING_DUMMY,
204  .receptionTries = 0u,
205  .receptionTriesMessage = 0u,
206 };
207 
209  .timer = 0u,
210  .triggerEntry = 0u,
212  .previousState = I165C_FSM_STATE_DISABLE_DUMMY,
213  .receptionTries = 0u,
214  .receptionTriesMessage = 0u,
215 };
216 
219 
220 /*========== Extern Constant and Variable Definitions =======================*/
221 
222 /*========== Static Function Prototypes =====================================*/
223 /**
224  * @brief Sets the next state the timer value
225  * of the initialization state variable.
226  * @param[in,out] pImdState state of the initialization state machine
227  * @param[in] nextState state to be transferred into
228  * @param[in] idleTime wait time for the state machine
229  */
230 static void I165C_SetInitializationState(
231  I165C_INITIALIZATION_STATE_s *pImdState,
233  uint16_t idleTime);
234 
235 /**
236  * @brief Sets the next state the timer value
237  * of the enable state variable.
238  * @param[in,out] pImdState state of the enable state machine
239  * @param[in] nextState state to be transferred into
240  * @param[in] idleTime wait time for the state machine
241  */
242 static void I165C_SetEnableState(
243  I165C_ENABLE_STATE_s *pImdState,
244  I165C_FSM_ENABLE_STATES_e nextState,
245  uint16_t idleTime);
246 
247 /**
248  * @brief Sets the next state the timer value
249  * of the running state variable.
250  * @param[in,out] pImdState state of the enable state machine
251  * @param[in] nextState state to be transferred into
252  * @param[in] idleTime wait time for the state machine
253  */
254 static void I165C_SetRunningState(
255  I165C_RUNNING_STATE_s *pImdState,
256  I165C_FSM_RUNNING_STATES_e nextState,
257  uint16_t idleTime);
258 
259 /**
260  * @brief Sets the next state the timer value
261  * of the disable state variable.
262  * @param[in,out] pImdState state of the enable state machine
263  * @param[in] nextState state to be transferred into
264  * @param[in] idleTime wait time for the state machine
265  */
266 static void I165C_SetDisableState(
267  I165C_DISABLE_STATE_s *pImdState,
268  I165C_FSM_DISABLE_STATES_e nextState,
269  uint16_t idleTime);
270 
271 /** Initialization state machine */
273 
274 /** Enable state machine */
275 static IMD_FSM_STATES_e I165C_Enable(void);
276 
277 /** Disable state machine */
278 static IMD_FSM_STATES_e I165C_Disable(void);
279 
280 /**
281  * @brief trigger function for the i165c driver state machine.
282  * @details This function contains the sequence of events in the i165c state
283  * machine.
284  * It must be called time-triggered, every 100ms.
285  * @param pTableInsulationMonitoring pointer to insulation database entry
286  */
287 static IMD_FSM_STATES_e I165C_Running(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring);
288 
289 /**
290  * @brief Reset CAN data.
291  * @details Used before starting a new transmission.
292  * @param[in,out] pCanMessage pointer to CAN data to be reset
293  */
294 static void I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *pCanMessage);
295 
296 /**
297  * @brief Write data in data word for CAN transmission.
298  * @param dataWord data word ("position") in CAN structure to be written
299  * to (see data sheet page 15)
300  * @param data data to be written in data word
301  * @param[in] pCanMessage CAN structure to be used for transmission
302  */
303 static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *pCanMessage);
304 
305 /**
306  * @brief Get data in data word from CAN transmission.
307  * @param dataWord data word ("position") in CAN structure to be read from
308  * (see data sheet page 15)
309  * @param[out] pData pointer where to put read data from data word
310  * @param canMessage CAN structure used for transmission
311  */
312 static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage);
313 
314 /**
315  * @brief Get data in data word from CAN transmission, for the specific
316  * IMD_Info message.
317  * @param dataWord data word ("position") in CAN structure to be read from
318  * (see data sheet page 15)
319  * @param[out] pData pointer where to put read data from data word
320  * @param canMessage CAN structure used for transmission
321  */
322 static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage);
323 
324 /**
325  * @brief Get data in data byte from CAN transmission.
326  * @param dataByte data byte ("position") in CAN structure to be read from
327  * (see data sheet page 15)
328  * @param[out] pData pointer where to put read data from data byte
329  * @param canMessage CAN structure used for transmission
330  */
331 static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFER_ELEMENT_s canMessage);
332 
333 /**
334  * @brief Compose CAN message for CAN transmission.
335  * @details Write CMD byte.
336  * @param id CAN ID to use
337  * @param command command to be used (see data page 15 section 6.3 and
338  * further)
339  * @param[out] pCanMessage pointer to CAN structure to be used for transmission
340  */
341 static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage);
342 
343 /**
344  * @brief Check if iso165c acknowledged reception of sent message
345  * and get corresponding data.
346  * @details Gets data from the CAN module through a queue.
347  * @param command check if this command is sent by iso165c to acknowledge
348  * reception
349  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
350  * @return true if transmission acknowledged, false otherwise
351  */
352 static bool I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage);
353 
354 /**
355  * @brief Get IMD Info from iso165c
356  * @details Gets data from the CAN module through a queue.
357  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
358  * @return true if IMD_Info message was received, false otherwise
359  */
360 static bool I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *pCanMessage);
361 
362 /**
363  * @brief Check if iso165c was initialized and is running
364  * @details Check is made using the CAN IMD_Info data sent by the iso165c.
365  * - the IMC is up and running with no errors:
366  * - insulation measurement deactivated
367  * - self-test executed
368  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
369  * @return true if IMD_Info was received, false otherwise
370  */
371 static bool I165C_IsSelfTestFinished(CAN_BUFFER_ELEMENT_s canMessage);
372 
373 /**
374  * @brief Check if iso165c has already been performed previously
375  * @details Check is made using the CAN IMD_Info data sent by the iso165c.
376  * - self-test executed
377  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
378  * @return true if self-test has already been executed, false otherwise
379  */
381 
382 /**
383  * @brief Set state of HV relay
384  * @param[in] relay set state of positive or negative relay
385  * @param[in] relayState open or close relay
386  */
387 static void I165C_SetRelayState(uint8_t relay, uint8_t relayState);
388 
389 /**
390  * @brief Request state of HV relay
391  * @param[in] relay positive or negative relay
392  */
393 static void I165C_RequestRelayState(uint8_t relay);
394 
395 /**
396  * @brief Check state of HV relay
397  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
398  * @param[in] relay positive or negative relay
399  * @param[in] relayState relay opened or closed
400  * @return true if state matches, otherwise false
401  */
402 static bool I165C_CheckRelayState(CAN_BUFFER_ELEMENT_s canMessage, uint8_t relay, uint8_t relayState);
403 
404 /**
405  * @brief Set measurement mode
406  * @param[in] mode set IMD measurement mode
407  */
408 static void I165C_SetMeasurementMode(uint8_t mode);
409 
410 /**
411  * @brief Check measurement mode
412  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
413  * @param[in] mode IMD measurement mode (activated or deactivated)
414  * @return true, if measurement mode matches, otherwise false
415  */
416 static bool I165C_CheckMeasurementMode(CAN_BUFFER_ELEMENT_s canMessage, uint8_t mode);
417 
418 /**
419  * @brief Set average factor of the insulation resistance averaging algorithm
420  * @param[in] averagingFactor set IMD averaging factor
421  */
422 static void I165C_SetAveragingFactor(uint8_t averagingFactor);
423 
424 /**
425  * @brief Check if iso165c acknowledged reception of command
426  * @param command command to be acknowledged
427  * @param[out] pTries pointer to variable counting the number of tries for reception
428  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
429  * @return true if Acknowledge has been received, otherwise false
430  */
431 static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFER_ELEMENT_s *pCanMessage);
432 
433 /*========== Static Function Implementations ================================*/
435  I165C_INITIALIZATION_STATE_s *pImdState,
437  uint16_t idleTime) {
438  FAS_ASSERT(pImdState != NULL_PTR);
439  /* Set time */
440  pImdState->timer = idleTime;
441  /* Set state */
442  if (nextState != pImdState->currentState) {
443  /* Next state is different: switch to it and set substate to entry value */
444  pImdState->previousState = pImdState->currentState;
445  pImdState->currentState = nextState;
446  } else {
447  /* Next state equal to current state: nothing to do */
448  }
449 }
450 
452  I165C_ENABLE_STATE_s *pImdState,
453  I165C_FSM_ENABLE_STATES_e nextState,
454  uint16_t idleTime) {
455  FAS_ASSERT(pImdState != NULL_PTR);
456  /* Set time */
457  pImdState->timer = idleTime;
458  /* Set state */
459  if (nextState != pImdState->currentState) {
460  /* Next state is different: switch to it and set substate to entry value */
461  pImdState->previousState = pImdState->currentState;
462  pImdState->currentState = nextState;
463  } else {
464  /* Next state equal to current state: nothing to do */
465  }
466 }
467 
469  I165C_RUNNING_STATE_s *pImdState,
470  I165C_FSM_RUNNING_STATES_e nextState,
471  uint16_t idleTime) {
472  FAS_ASSERT(pImdState != NULL_PTR);
473  /* Set time */
474  pImdState->timer = idleTime;
475  /* Set state */
476  if (nextState != pImdState->currentState) {
477  /* Next state is different: switch to it and set substate to entry value */
478  pImdState->previousState = pImdState->currentState;
479  pImdState->currentState = nextState;
480  } else {
481  /* Next state equal to current state: nothing to do */
482  }
483 }
484 
486  I165C_DISABLE_STATE_s *pImdState,
487  I165C_FSM_DISABLE_STATES_e nextState,
488  uint16_t idleTime) {
489  FAS_ASSERT(pImdState != NULL_PTR);
490  /* Set time */
491  pImdState->timer = idleTime;
492  /* Set state */
493  if (nextState != pImdState->currentState) {
494  /* Next state is different: switch to it and set substate to entry value */
495  pImdState->previousState = pImdState->currentState;
496  pImdState->currentState = nextState;
497  } else {
498  /* Next state equal to current state: nothing to do */
499  }
500 }
501 
502 static void I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *pCanMessage) {
503  FAS_ASSERT(pCanMessage != NULL_PTR);
504  for (uint8_t i = 0u; i < CAN_DEFAULT_DLC; i++) {
505  pCanMessage->data[i] = 0u;
506  }
507 }
508 
509 static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *pCanMessage) {
510  FAS_ASSERT(pCanMessage != NULL_PTR);
511  /* See data sheet section 6.1 page 15 */
512  if (dataWord == I165C_DW1) {
513  pCanMessage->data[CAN_BYTE_1_POSITION] = (uint8_t)(data & 0xFFu);
514  pCanMessage->data[CAN_BYTE_2_POSITION] = (uint8_t)((data >> 8u) & 0xFFu);
515  }
516  if (dataWord == I165C_DW2) {
517  pCanMessage->data[CAN_BYTE_3_POSITION] = (uint8_t)(data & 0xFFu);
518  pCanMessage->data[CAN_BYTE_4_POSITION] = (uint8_t)((data >> 8u) & 0xFFu);
519  }
520 }
521 
522 static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage) {
523  FAS_ASSERT(pData != NULL_PTR);
524  /* See data sheet section 6.1 page 15 */
525  if (dataWord == I165C_DW1) {
526  *pData = canMessage.data[CAN_BYTE_1_POSITION];
527  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_2_POSITION]) << 8u) & 0xFF00u;
528  }
529  if (dataWord == I165C_DW2) {
530  *pData = canMessage.data[CAN_BYTE_3_POSITION];
531  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_4_POSITION]) << 8u) & 0xFF00u;
532  }
533  if (dataWord == I165C_DW3) {
534  *pData = canMessage.data[CAN_BYTE_5_POSITION];
535  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_6_POSITION]) << 8u) & 0xFF00u;
536  }
537 }
538 
539 static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage) {
540  FAS_ASSERT(pData != NULL_PTR);
541  /* See data sheet section 6.1 page 15 */
542  if (dataWord == I165C_DW1) {
543  *pData = canMessage.data[CAN_BYTE_0_POSITION];
544  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_1_POSITION]) << 8u) & 0xFF00u;
545  }
546  if (dataWord == I165C_DW2) {
547  *pData = canMessage.data[CAN_BYTE_2_POSITION];
548  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_3_POSITION]) << 8u) & 0xFF00u;
549  }
550  if (dataWord == I165C_DW3) {
551  *pData = canMessage.data[CAN_BYTE_4_POSITION];
552  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_5_POSITION]) << 8u) & 0xFF00u;
553  }
554 }
555 
556 static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFER_ELEMENT_s canMessage) {
557  FAS_ASSERT(pData != NULL_PTR);
558  /* See data sheet section 6.1 page 15 */
559  switch (dataByte) {
560  case I165C_DB1:
561  *pData = canMessage.data[CAN_BYTE_1_POSITION];
562  break;
563  case I165C_DB2:
564  *pData = canMessage.data[CAN_BYTE_2_POSITION];
565  break;
566  case I165C_DB3:
567  *pData = canMessage.data[CAN_BYTE_3_POSITION];
568  break;
569  case I165C_DB4:
570  *pData = canMessage.data[CAN_BYTE_4_POSITION];
571  break;
572  default:
573  *pData = 0u;
574  break;
575  }
576 }
577 
578 static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage) {
579  FAS_ASSERT(pCanMessage != NULL_PTR);
580  /* CAN message is a request, set ID accordingly */
581  pCanMessage->id = id;
582  /* First byte contains the CMD field */
583  pCanMessage->data[CAN_BYTE_0_POSITION] = command;
584 }
585 
586 static bool I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *pCanMessage) {
587  FAS_ASSERT(pCanMessage != NULL_PTR);
588  bool messageReceived = false;
589  uint8_t numberItems = 0u;
590  uint8_t queueReadTries = I165C_MAX_QUEUE_READS;
591 
592  /* Use loop on queue because IMD_info message could come meanwhile */
593  do {
595  if (numberItems > 0u) {
596  if (OS_ReceiveFromQueue(ftsk_imdCanDataQueue, (void *)pCanMessage, 0u) == OS_SUCCESS) {
597  /* data queue was no empty */
598  if ((command == pCanMessage->data[CAN_BYTE_0_POSITION]) && (pCanMessage->id == CANRX_IMD_RESPONSE_ID)) {
599  messageReceived = true;
600  break;
601  }
602  }
603  }
604  queueReadTries--;
605  } while ((numberItems > 0u) && (queueReadTries > 0u));
606 
607  return messageReceived;
608 }
609 
610 static bool I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *pCanMessage) {
611  FAS_ASSERT(pCanMessage != NULL_PTR);
612  bool imdInfoReceived = false;
613  uint8_t numberItems = 0u;
614  uint8_t queueReadTries = I165C_MAX_QUEUE_READS;
615 
616  /* Use loop on queue because other messages could come meanwhile */
617  do {
619  if (numberItems > 0u) {
620  if (OS_ReceiveFromQueue(ftsk_imdCanDataQueue, (void *)pCanMessage, 0u) == OS_SUCCESS) {
621  /* data queue was no empty */
622  if (pCanMessage->id == I165C_MESSAGETYPE_IMD_INFO) {
623  imdInfoReceived = true;
624  break;
625  }
626  }
627  }
628  queueReadTries--;
629  } while ((numberItems > 0u) && (queueReadTries > 0u));
630 
631  return imdInfoReceived;
632 }
633 
635  bool initialized = true;
636  uint16_t data = 0u;
637 
638  /* Extract D_IMC_STATUS */
639  I165C_ReadDataWordImdInfo(I165C_DW2, &data, canMessage);
640  /* I165C_SELFTEST_RUNNING bit = 1 in IMD_Info DW2: self test running */
641  uint16_t selfTestState = (data & (1u << I165C_SELFTEST_RUNNING_SHIFT));
642  if (selfTestState != (1u << I165C_SELFTEST_RUNNING_SHIFT)) {
643  /* self test not running */
644  initialized = false;
645  }
646 
647  /* Extract D_VIFC_STATUS */
648  I165C_ReadDataWordImdInfo(I165C_DW3, &data, canMessage);
649  /* I165C_INSULATION_MEASUREMENT bit = 0 in IMD_Info DW3: insulation measurement active */
650  uint16_t insulationMeasurementState = (data & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT));
651  if (insulationMeasurementState != 0u) {
652  /* insulation measurement active */
653  initialized = false;
654  }
655 #ifdef I165C_SELF_TEST_LONG
656  /* I165C_IMC_SELFTEST_OVERALL_SCENARIO bit = 1 in IMD_Info DW3: selftest overall scenario not executed */
657  uint16_t selfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT));
658  if (selfTestExecuted != 0u) {
659  /* selftest overall scenario not executed */
660  initialized = false;
661  }
662 #else
663  /* I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO bit = 1 in IMD_Info DW3: selftest parameter config not executed */
664  uint16_t selfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT));
665  if (selfTestExecuted != 0u) {
666  /* selftest parameter scenario not executed */
667  initialized = false;
668  }
669 #endif
670  return initialized;
671 }
672 
674  bool anySelfTestExecuted = false;
675  uint16_t data = 0u;
676 
677  /* Extract D_VIFC_STATUS */
678  I165C_ReadDataWordImdInfo(I165C_DW3, &data, canMessage);
679 
680  /* I165C_IMC_SELFTEST_OVERALL_SCENARIO bit = 1 in IMD_Info DW3: selftest overall scenario not executed */
681  uint16_t overallSelfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT));
682  if (overallSelfTestExecuted == 0u) {
683  /* selftest overall scenario has been executed */
684  anySelfTestExecuted = true;
685  }
686  /* I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO bit = 1 in IMD_Info DW3: selftest parameter config not executed */
687  uint16_t parameterSelfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT));
688  if (parameterSelfTestExecuted == 0u) {
689  /* selftest parameter scenario has been executed */
690  anySelfTestExecuted = true;
691  }
692  return anySelfTestExecuted;
693 }
694 
695 static void I165C_SetRelayState(uint8_t relay, uint8_t relayState) {
697  FAS_ASSERT((relayState == I165C_RELAY_STATE_OPEN) || (relayState == I165C_RELAY_STATE_CLOSED));
698  /* Reset CAN message buffer */
700  /* Assemble CAN message */
704  /* Transmit CAN message */
706 }
707 
708 static void I165C_RequestRelayState(uint8_t relay) {
710  /* Reset CAN message buffer */
712  /* Assemble CAN message */
715  /* Transmit CAN message */
717 }
718 
719 static bool I165C_CheckRelayState(CAN_BUFFER_ELEMENT_s canMessage, uint8_t relay, uint8_t relayState) {
721  FAS_ASSERT((relayState == I165C_RELAY_STATE_OPEN) || (relayState == I165C_RELAY_STATE_CLOSED));
722  bool checkSuccess = true;
723  uint16_t data = 0u;
724 
726  /* IMD_Response DW1: relay */
727  if (relay != data) {
728  /* not request relay */
729  checkSuccess = false;
730  }
731 
733  /* IMD_Response DW2: relay state */
734  if (relayState != data) {
735  /* relay state does not match expected state */
736  checkSuccess = false;
737  }
738  return checkSuccess;
739 }
740 
741 static void I165C_SetMeasurementMode(uint8_t mode) {
743  /* Reset CAN message buffer */
745  /* Assemble CAN message */
748  /* Transmit CAN message */
750 }
751 
752 static bool I165C_CheckMeasurementMode(CAN_BUFFER_ELEMENT_s canMessage, uint8_t mode) {
754  bool measurementModeMatches = false;
755  uint16_t dVIFCStatus = 0u;
756 
757  /* Extract D_VIFC_STATUS word */
759  /* Extract measurement mode from D_VIFC_STATUS word */
760  uint8_t actualMeasurementMode = dVIFCStatus & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT);
761 
762  /* Check if actual measurement mode matches passed measurement mode */
763  if (actualMeasurementMode == mode) {
764  /* Insulation measurement deactivated*/
765  measurementModeMatches = true;
766  }
767  return measurementModeMatches;
768 }
769 
770 static void I165C_SetAveragingFactor(uint8_t averagingFactor) {
771  /* Averaging factor must be in the range 1...20 */
772  FAS_ASSERT(averagingFactor != 0u);
773  FAS_ASSERT(averagingFactor <= 20u);
774 
775  /* Reset CAN message buffer */
777  /* Assemble CAN message */
780  /* Transmit CAN message */
782 }
783 
784 static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFER_ELEMENT_s *pCanMessage) {
785  FAS_ASSERT(pTries != NULL_PTR);
786  FAS_ASSERT(pCanMessage != NULL_PTR);
787  /* AXIVION Routine Generic-MissingParameterAssert: command: parameter accepts whole range */
788 
789  bool acknowledgeReceived = false;
790  if (I165C_CheckResponse(command, pCanMessage) == false) {
791  (*pTries)++;
792  } else {
793  *pTries = 0u;
794  acknowledgeReceived = true;
795  }
796  return acknowledgeReceived;
797 }
798 
800  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_INITIALIZATION; /* stay in initialization state */
801  bool earlyExit = false;
802 
803  if (i165c_initializationState.timer > 0u) {
804  if ((--i165c_initializationState.timer) > 0u) {
806  earlyExit = true;
807  }
808  }
809 
810  if (earlyExit == false) {
813  /* Unlock device in case it was locked */
821  break;
822 
826  true) {
831  } else {
832  /* Issue: 621 */
833  }
834  break;
835 
837  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
839  /* Measurement is not enabled -> Enable measurement as otherwise the following
840  * initialization procedure would fail */
846  } else {
847  /* Measurement enabled -> continue with initialization procedure */
852  }
853  }
854  break;
855 
860  &i165c_canRxMessage) == true) {
861  /* Measurement enabled -> continue with initialization procedure */
866  } else {
867  /* Issue: 621 */
868  }
869  break;
870 
872  /* Open negative relay */
874  /* Open positive relay */
876  /* Switch to next state */
881  break;
882 
889  break;
890 
892  /* Check if HV relay is open and measurement has been stopped */
898 
899  /* Request state of positive HV relay */
901 
906  } else {
908  /* Issue: 621 */
909  }
910  } else {
912  /* Issue: 621 */
913  }
914  break;
915 
917  /* Check if HV relays are open and measurement has been stopped */
923 
928  } else {
930  /* Issue: 621 */
931  }
932  } else {
934  /* Issue: 621 */
935  }
936  break;
937 
939  /* A self test must be requested and can only be carried out
940  when the coupling relays are open. */
941 
942  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
947 #ifdef I165C_SELF_TEST_LONG
950 #else /* I165C_SELF_TEST_SHORT */
955 #endif
962  } else {
963  /* Self-test has already been performed -> skip following initialization steps as the device
964  has previously been successfully configured. */
969  }
970  }
971 
972  break;
973 
977  true) {
982  } else {
983  /* Issue: 621 */
985  /* Issue: 621 */
991  }
992  }
993  break;
995  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
998  } else {
1005  }
1006  } else {
1007  /* Issue: 621 */
1010  /* Initialization not working: restart initialization procedure */
1011  /* Issue: 621 */
1012  }
1013  }
1014  break;
1015 
1022  break;
1023 
1028  &i165c_canRxMessage) == true) {
1033  } else {
1034  /* Issue: 621 */
1035  }
1036  break;
1037 
1048  break;
1053  &i165c_canRxMessage) == true) {
1058  } else {
1059  /* Issue: 621 */
1060  }
1061  break;
1072  break;
1077  &i165c_canRxMessage) == true) {
1082  } else {
1083  /* Issue: 621 */
1084  }
1085  break;
1086 
1093  break;
1094 
1099  &i165c_canRxMessage) == true) {
1100  /* Initialized -> switch to next state in IMD state machine */
1101  nextState = IMD_FSM_STATE_IMD_ENABLE;
1102  /* Reset state machine in case a re-initialization is necessary */
1105  } else {
1106  /* Issue: 621 */
1107  }
1108  break;
1109 
1110  default:
1112  break;
1113  }
1115  }
1116  return nextState;
1117 }
1118 
1120  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_IMD_ENABLE; /* stay in enable state */
1121  bool earlyExit = false;
1122 
1123  if (i165c_enableState.timer > 0u) {
1124  if ((--i165c_enableState.timer) > 0u) {
1126  earlyExit = true;
1127  }
1128  }
1129 
1130  if (earlyExit == false) {
1131  switch (i165c_enableState.currentState) {
1133  /* Close negative relay */
1135  /* Close positive relay */
1137  /* Switch to next state */
1140  break;
1141 
1146  break;
1147 
1154 
1155  /* Request state of positive HV relay */
1161  } else {
1163  /* Issue: 621 */
1164  }
1165  } else {
1167  /* Issue: 621 */
1174  }
1175  /* Issue: 621 */
1176  }
1177  break;
1178 
1185 
1188  } else {
1190  /* Issue: 621 */
1191  }
1192  } else {
1194  /* Issue: 621 */
1195  }
1196  break;
1197 
1202  break;
1203 
1207  true) {
1208  /* Enabled -> switch to next state in IMD state machine */
1209  nextState = IMD_FSM_STATE_RUNNING;
1210  /* Reset state machine in case a re-enabling is necessary */
1213  } else {
1214  /* Issue: 621 */
1215  }
1216  break;
1217  }
1218  }
1219  return nextState;
1220 }
1221 
1223  FAS_ASSERT(pTableInsulationMonitoring != NULL_PTR);
1224  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_RUNNING; /* stay in running state */
1225  bool earlyExit = false;
1226  uint16_t resistance_kOhm = 0u;
1227  uint16_t statusFlags = 0u;
1228  uint8_t data1 = 0u;
1229  uint8_t data2 = 0u;
1230 
1231  if (i165c_runningState.timer > 0u) {
1232  if ((--i165c_runningState.timer) > 0u) {
1234  earlyExit = true;
1235  }
1236  }
1237 
1238  if (earlyExit == false) {
1239  switch (i165c_runningState.currentState) {
1241  /* Switch to next state */
1244  break;
1245 
1253  break;
1254 
1258  /* Extract resistance value from response */
1259  I165C_ReadDataWord(I165C_DW1, &resistance_kOhm, i165c_canRxMessage);
1260  pTableInsulationMonitoring->insulationResistance_kOhm = resistance_kOhm;
1261 
1262  /* Extract bias/tendency to the location of the insulation fault (error), if detected */
1264  if (data1 == I165C_BIAS_TO_HV_PLUS) {
1265  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = true;
1266  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = false;
1267  } else if (data1 == I165C_BIAS_TO_HV_MINUS) {
1268  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = true;
1269  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = false;
1270  } else {
1271  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = false;
1272  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = false;
1273  }
1274 
1275  /* Extract counter value */
1277  /* TODO: What to do with this info? */
1278 
1281  } else {
1282  /* Issue: 621 */
1283  }
1284  break;
1285 
1287  if (I165C_GetImdInfo(&i165c_canRxMessage) == false) {
1289  /* Issue: 621 */
1290  /* IMD_Info not coming: restart initialization procedure?
1291  if (i165c_runningState.receptionTriesMessage >= I165C_IMD_INFO_RECEIVE_ATTEMPTS) {*/
1292  } else {
1294 
1295  /* Get measured resistance */
1297  pTableInsulationMonitoring->insulationResistance_kOhm = resistance_kOhm;
1298 
1299  /* Get IMC status */
1301  if (0u != (statusFlags & (1u << I165C_INSULATION_FAULT_SHIFT))) {
1302  /* Insulation fault */
1303  pTableInsulationMonitoring->dfIsCriticalResistanceDetected = true;
1304  } else {
1305  pTableInsulationMonitoring->dfIsCriticalResistanceDetected = false;
1306  }
1307  if (0u != (statusFlags & (1u << I165C_CHASSIS_FAULT_SHIFT))) {
1308  /* Chassis fault */
1309  pTableInsulationMonitoring->dfIsChassisFaultDetected = true;
1310  } else {
1311  pTableInsulationMonitoring->dfIsChassisFaultDetected = false;
1312  }
1313  if (0u != (statusFlags & (1u << I165C_SYSTEM_FAILURE_SHIFT))) {
1314  /* System failure */
1315  pTableInsulationMonitoring->dfIsDeviceErrorDetected = true;
1316  pTableInsulationMonitoring->areDeviceFlagsValid = false;
1317  } else {
1318  pTableInsulationMonitoring->dfIsDeviceErrorDetected = false;
1319  pTableInsulationMonitoring->areDeviceFlagsValid = true;
1320  }
1321  if (0u != (statusFlags & (1u << I165C_INSULATION_WARNING_SHIFT))) {
1322  /* Insulation warning */
1323  pTableInsulationMonitoring->dfIsWarnableResistanceDetected = true;
1324  } else {
1325  pTableInsulationMonitoring->dfIsWarnableResistanceDetected = false;
1326  }
1327 
1328  /* Get VIFC status */
1330  if (0u != (statusFlags & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT))) {
1331  /* Insulation measurement deactivated*/
1332  pTableInsulationMonitoring->isImdRunning = false;
1333  } else {
1334  pTableInsulationMonitoring->isImdRunning = true;
1335  }
1336  if (0u != (statusFlags & (1u << I165C_RESISTANCE_VALUE_OUTDATED_SHIFT))) {
1337  /* Insulation resistance value outdated */
1338  pTableInsulationMonitoring->dfIsMeasurmentedUpToDate = false;
1339  } else {
1340  pTableInsulationMonitoring->dfIsMeasurmentedUpToDate = true;
1341  }
1342  if ((pTableInsulationMonitoring->areDeviceFlagsValid == true) &&
1343  (pTableInsulationMonitoring->isImdRunning == true) &&
1344  (pTableInsulationMonitoring->dfIsMeasurmentedUpToDate == true)) {
1345  pTableInsulationMonitoring->isInsulationMeasurementValid = true;
1346  } else {
1347  pTableInsulationMonitoring->isInsulationMeasurementValid = false;
1348  }
1349  }
1350  /* Restart measurement cycle */
1353  break;
1354 
1355  default:
1356  /* invalid state */
1357  nextState = IMD_FSM_STATE_ERROR;
1359  break;
1360  }
1361  }
1362  return nextState;
1363 }
1364 
1365 /** Disable state machine */
1367  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_SHUTDOWN; /* stay in shutdown state */
1368  bool earlyExit = false;
1369 
1370  if (i165c_disableState.timer > 0u) {
1371  if ((--i165c_disableState.timer) > 0u) {
1373  earlyExit = true;
1374  }
1375  }
1376 
1377  if (earlyExit == false) {
1378  switch (i165c_disableState.currentState) {
1380  /* The I165C_Running state-machine, does not know when the
1381  * disable command is received by the superimposed IMD state
1382  * machine. Thus, the I165C_Running state machine needs to be
1383  * reset at this point to correctly call the running state
1384  * machine after re-enabling. */
1386 
1387  /* Request stop of measurement */
1391  break;
1392 
1396  true) {
1399  } else {
1400  /* Issue: 621 */
1401  }
1402  break;
1403 
1405  /* Open negative relay */
1407  /* Open positive relay */
1411  break;
1412 
1417  break;
1418 
1425 
1426  /* Request state of positive HV relay */
1432  } else {
1434  /* Issue: 621 */
1435  }
1436  } else {
1438  /* Issue: 621 */
1439  }
1440  break;
1441 
1448 
1449  /* Reset disable state machine in case a another disabling is necessary */
1452 
1453  /* IMD successfully disabled -> switch to next state in superimposed IMD state machine */
1454  nextState = IMD_FSM_STATE_IMD_ENABLE;
1455  } else {
1457  /* Issue: 621 */
1458  }
1459  } else {
1461  /* Issue: 621 */
1462  }
1463  break;
1464  }
1465  }
1466  return nextState;
1467 }
1468 
1469 /*========== Extern Function Implementations ================================*/
1470 
1472  return I165C_Initialize();
1473 }
1474 
1476  return I165C_Enable();
1477 }
1478 
1480  FAS_ASSERT(pTableInsulationMonitoring != NULL_PTR);
1481  return I165C_Running(pTableInsulationMonitoring);
1482 }
1483 
1485  return I165C_Disable();
1486 }
1487 
1488 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1489 #ifdef UNITY_UNIT_TEST
1491  I165C_ResetCanData(canMessage);
1492 }
1493 extern void TEST_I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *canMessage) {
1494  I165C_WriteDataWord(dataWord, data, canMessage);
1495 }
1496 extern void TEST_I165C_ReadDataWord(uint8_t dataWord, uint16_t *data, CAN_BUFFER_ELEMENT_s canMessage) {
1497  I165C_ReadDataWord(dataWord, data, canMessage);
1498 }
1499 extern void TEST_I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *data, CAN_BUFFER_ELEMENT_s canMessage) {
1500  I165C_ReadDataWordImdInfo(dataWord, data, canMessage);
1501 }
1502 extern void TEST_I165C_ReadDataByte(uint8_t dataByte, uint8_t *data, CAN_BUFFER_ELEMENT_s canMessage) {
1503  I165C_ReadDataByte(dataByte, data, canMessage);
1504 }
1505 extern void TEST_I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *canMessage) {
1506  I165C_WriteCmd(id, command, canMessage);
1507 }
1508 extern bool TEST_I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *canMessage) {
1509  return I165C_CheckResponse(command, canMessage);
1510 }
1512  return I165C_GetImdInfo(canMessage);
1513 }
1515  return I165C_IsSelfTestFinished(canMessage);
1516 }
1517 extern bool TEST_I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *tries, CAN_BUFFER_ELEMENT_s *canMessage) {
1518  return I165C_CheckAcknowledgeArrived(command, tries, canMessage);
1519 }
1520 
1521 #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
void TEST_I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFER_ELEMENT_s *canMessage)
void TEST_I165C_ReadDataByte(uint8_t dataByte, uint8_t *data, CAN_BUFFER_ELEMENT_s canMessage)
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.
bool TEST_I165C_GetImdInfo(CAN_BUFFER_ELEMENT_s *canMessage)
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
bool TEST_I165C_IsSelfTestFinished(CAN_BUFFER_ELEMENT_s canMessage)
IMD_FSM_STATES_e IMD_ProcessEnableState(void)
Processes the IMD enable state.
void TEST_I165C_ResetCanData(CAN_BUFFER_ELEMENT_s *canMessage)
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.
void TEST_I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *data, CAN_BUFFER_ELEMENT_s canMessage)
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
bool TEST_I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *tries, CAN_BUFFER_ELEMENT_s *canMessage)
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.
void TEST_I165C_ReadDataWord(uint8_t dataWord, uint16_t *data, CAN_BUFFER_ELEMENT_s canMessage)
static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFER_ELEMENT_s canMessage)
Get data in data word from CAN transmission.
bool TEST_I165C_CheckResponse(uint8_t command, CAN_BUFFER_ELEMENT_s *canMessage)
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.
void TEST_I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFER_ELEMENT_s *canMessage)
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_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_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(canBASE_t *pNode, uint32_t id, uint8 *pData)
Sends over CAN the data passed in parameters. This function goes over the message boxes and marks the...
Definition: can.c:200
Header for the driver for the CAN module.
#define CAN_DEFAULT_DLC
Definition: can_cfg.h:93
Header for the driver for the CAN module.
#define CANRX_IMD_RESPONSE_ID
Headers for the helper functions for the CAN module.
#define CAN_BYTE_2_POSITION
Definition: can_helper.h:71
#define CAN_BYTE_4_POSITION
Definition: can_helper.h:73
#define CAN_BYTE_0_POSITION
Definition: can_helper.h:69
#define CAN_BYTE_6_POSITION
Definition: can_helper.h:75
#define CAN_BYTE_3_POSITION
Definition: can_helper.h:72
#define CAN_BYTE_5_POSITION
Definition: can_helper.h:74
#define CAN_BYTE_1_POSITION
Definition: can_helper.h:70
Database module header.
Database configuration header.
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:248
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:126
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
Header of task driver implementation.
QueueHandle_t ftsk_imdCanDataQueue
IMD_FSM_STATES_e
Definition: imd.h:92
@ IMD_FSM_STATE_RUNNING
Definition: imd.h:99
@ IMD_FSM_STATE_SHUTDOWN
Definition: imd.h:98
@ IMD_FSM_STATE_INITIALIZATION
Definition: imd.h:96
@ IMD_FSM_STATE_IMD_ENABLE
Definition: imd.h:97
@ IMD_FSM_STATE_ERROR
Definition: imd.h:100
@ OS_SUCCESS
Definition: os.h:78
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:157
uint32_t OS_GetNumberOfStoredMessagesInQueue(OS_QUEUE xQueue)
Check if messages are waiting for queue.
Definition: os_freertos.c:198
uint8_t data[CAN_MAX_DLC]
Definition: can_cfg.h:155
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