foxBMS  1.3.0
The foxBMS Battery Management System 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-05-30 (date of last update)
47  * @version v1.3.0
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"
63 #include "can_helper.h"
64 #include "database.h"
65 #include "ftask.h"
66 
67 /*========== Macros and Definitions =========================================*/
68 /** statemachine short time definition in trigger calls until next state is processed */
69 #define I165C_FSM_SHORT_TIME (1u)
70 
71 /* -------------- State defines ---------------------------------------------*/
72 
73 /** States of the initialization state machine */
74 typedef enum {
75  I165C_FSM_STATE_INITIALIZATION_DUMMY, /*!< dummy state - always the first state */
76  I165C_FSM_STATE_INITIALIZATION_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
77  I165C_FSM_STATE_INITIALIZATION_UNLOCK_WAIT_ACK, /*!< wait acknowledge of unlocking */
78  I165C_FSM_STATE_INITIALIZATION_CHECK_MEASUREMENT_STATE, /*!< check if measurement is enabled. if not enable it */
79  I165C_FSM_STATE_INITIALIZATION_ENABLE_MEASUREMENT_WAIT_ACK, /*!< wait for acknowledge for enabling of measurement */
80  I165C_FSM_STATE_INITIALIZATION_REQUEST_HV_RELAY_OPENING, /*!< request HV relay state: open */
82  I165C_FSM_STATE_INITIALIZATION_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
83  I165C_FSM_STATE_INITIALIZATION_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
85  I165C_FSM_STATE_INITIALIZATION_SELF_TEST_WAIT_ACK, /*!< wait acknowledge of self-test */
86  I165C_FSM_STATE_INITIALIZATION_WAIT_SELF_TEST, /*!< wait until self-test is finished */
88  I165C_FSM_STATE_INITIALIZATION_AVERAGING_FACTOR_WAIT_ACK, /*!< wait acknowledge of averaging factor */
89  I165C_FSM_STATE_INITIALIZATION_SET_ERROR_THRESHOLD, /*!< configuration of error threshold */
90  I165C_FSM_STATE_INITIALIZATION_ERROR_THRESHOLD_WAIT_ACK, /*!< wait acknowledge of error threshold */
91  I165C_FSM_STATE_INITIALIZATION_SET_WARNING_THRESHOLD, /*!< configuration of warning threshold */
92  I165C_FSM_STATE_INITIALIZATION_WARNING_THRESHOLD_WAIT_ACK, /*!< wait acknowledge of warning threshold */
94  I165C_FSM_STATE_INITIALIZATION_DISABLE_MEASUREMENT_WAIT_ACK, /*!< wait acknowledge of disable measurement */
96 
97 /** States of the enable state machine */
98 typedef enum {
99  I165C_FSM_STATE_ENABLE_DUMMY, /*!< dummy state - always the first state */
100  I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
101  I165C_FSM_STATE_ENABLE_REQUEST_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
102  I165C_FSM_STATE_ENABLE_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
103  I165C_FSM_STATE_ENABLE_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
104  I165C_FSM_STATE_ENABLE_START_MEASUREMENT, /*!< start insulation measurement */
105  I165C_FSM_STATE_ENABLE_START_MEASUREMENT_WAIT_ACK, /*!< check for acknowledge of start measurement request */
107 
108 /** States of the running state machine */
109 typedef enum {
110  I165C_FSM_STATE_RUNNING_DUMMY, /*!< dummy state - always the first state */
111  I165C_FSM_STATE_RUNNING_HAS_NEVER_RUN, /*!< never run state - always the second state */
116 
117 /** States of the disable state machine */
118 typedef enum {
119  I165C_FSM_STATE_DISABLE_DUMMY, /*!< dummy state - always the first state */
120  I165C_FSM_STATE_DISABLE_HAS_NEVER_RUN, /*!< never run state - always the second state - unlock device */
121  I165C_FSM_STATE_MEASUREMENT_STOPPED_WAIT_ACK, /*!< wait for acknowledge of stop measurement request */
122  I165C_FSM_STATE_DISABLE_SET_HV_RELAY_STATE, /*!< request state of HV relays */
124  I165C_FSM_STATE_DISABLE_CHECK_NEGATIVE_HV_RELAY_STATE, /*!< check negative HV relay state */
125  I165C_FSM_STATE_DISABLE_CHECK_POSITIVE_HV_RELAY_STATE, /*!< check positive HV relay state */
127 
128 /* -------------- State variables -------------------------------------------*/
129 
130 /** This struct describes the state of the initialization state machine */
131 typedef struct {
132  uint16_t timer; /*!< timer of the state */
133  uint8_t triggerEntry; /*!< trigger entry of the state */
134  I165C_FSM_INITIALIZATION_STATES_e currentState; /*!< current state of the FSM */
135  I165C_FSM_INITIALIZATION_STATES_e previousState; /*!< previous state of the FSM */
136  uint8_t receptionTries;
141 
142 typedef struct {
143  uint16_t timer; /*!< timer of the state */
144  uint8_t triggerEntry; /*!< trigger entry of the state */
145  I165C_FSM_ENABLE_STATES_e currentState; /*!< current state of the FSM */
146  I165C_FSM_ENABLE_STATES_e previousState; /*!< previous state of the FSM */
147  uint8_t receptionTries;
150 
151 typedef struct {
152  uint16_t timer; /*!< timer of the state */
153  uint8_t triggerEntry; /*!< trigger entry of the state */
154  I165C_FSM_RUNNING_STATES_e currentState; /*!< current state of the FSM */
155  I165C_FSM_RUNNING_STATES_e previousState; /*!< previous state of the FSM */
156  uint8_t receptionTries;
159 
160 typedef struct {
161  uint16_t timer; /*!< timer of the state */
162  uint8_t triggerEntry; /*!< trigger entry of the state */
163  I165C_FSM_DISABLE_STATES_e currentState; /*!< current state of the FSM */
164  I165C_FSM_DISABLE_STATES_e previousState; /*!< previous state of the FSM */
165  uint8_t receptionTries;
168 
169 /*========== Static Constant and Variable Definitions =======================*/
170 
172  .timer = 0u,
173  .triggerEntry = 0u,
175  .previousState = I165C_FSM_STATE_INITIALIZATION_DUMMY,
176  .receptionTries = 0u,
177  .receptionTriesMessage = 0u,
178 #if false == I165C_IS_165C_USED
179  /* Default state after startup is closed for iso165C-1 */
180  .negativeRelayClosed = true,
181  .positiveRelayClosed = true,
182 #else
183  /* Default state after startup is open for iso165C */
184  .negativeRelayClosed = false,
185  .positiveRelayClosed = false,
186 #endif
187 };
188 
190  .timer = 0u,
191  .triggerEntry = 0u,
192  .currentState = I165C_FSM_STATE_ENABLE_HAS_NEVER_RUN,
193  .previousState = I165C_FSM_STATE_ENABLE_DUMMY,
194  .receptionTries = 0u,
195  .receptionTriesMessage = 0u,
196 };
197 
199  .timer = 0u,
200  .triggerEntry = 0u,
202  .previousState = I165C_FSM_STATE_RUNNING_DUMMY,
203  .receptionTries = 0u,
204  .receptionTriesMessage = 0u,
205 
206 };
207 
209  .timer = 0u,
210  .triggerEntry = 0u,
212  .previousState = I165C_FSM_STATE_DISABLE_DUMMY,
213  .receptionTries = 0u,
214  .receptionTriesMessage = 0u,
215 
216 };
217 
220 
221 /*========== Extern Constant and Variable Definitions =======================*/
222 
223 /*========== Static Function Prototypes =====================================*/
224 /**
225  * @brief Sets the next state the timer value
226  * of the initialization state variable.
227  * @param[in,out] pImdState state of the initialization state machine
228  * @param[in] nextState state to be transferred into
229  * @param[in] idleTime wait time for the state machine
230  */
231 static void I165C_SetInitializationState(
232  I165C_INITIALIZATION_STATE_s *pImdState,
234  uint16_t idleTime);
235 
236 /**
237  * @brief Sets the next state the timer value
238  * of the enable state variable.
239  * @param[in,out] pImdState state of the enable state machine
240  * @param[in] nextState state to be transferred into
241  * @param[in] idleTime wait time for the state machine
242  */
243 static void I165C_SetEnableState(
244  I165C_ENABLE_STATE_s *pImdState,
245  I165C_FSM_ENABLE_STATES_e nextState,
246  uint16_t idleTime);
247 
248 /**
249  * @brief Sets the next state the timer value
250  * of the running state variable.
251  * @param[in,out] pImdState state of the enable state machine
252  * @param[in] nextState state to be transferred into
253  * @param[in] idleTime wait time for the state machine
254  */
255 static void I165C_SetRunningState(
256  I165C_RUNNING_STATE_s *pImdState,
257  I165C_FSM_RUNNING_STATES_e nextState,
258  uint16_t idleTime);
259 
260 /**
261  * @brief Sets the next state the timer value
262  * of the disable state variable.
263  * @param[in,out] pImdState state of the enable state machine
264  * @param[in] nextState state to be transferred into
265  * @param[in] idleTime wait time for the state machine
266  */
267 static void I165C_SetDisableState(
268  I165C_DISABLE_STATE_s *pImdState,
269  I165C_FSM_DISABLE_STATES_e nextState,
270  uint16_t idleTime);
271 
272 /** Initialization state machine */
274 
275 /** Enable state machine */
276 static IMD_FSM_STATES_e I165C_Enable(void);
277 
278 /** Disable state machine */
279 static IMD_FSM_STATES_e I165C_Disable(void);
280 
281 /**
282  * @brief trigger function for the i165c driver state machine.
283  * @details This function contains the sequence of events in the i165c state
284  * machine.
285  * It must be called time-triggered, every 100ms.
286  * @param pTableInsulationMonitoring pointer to insulation database entry
287  */
288 static IMD_FSM_STATES_e I165C_Running(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring);
289 
290 /**
291  * @brief Reset CAN data.
292  * @details Used before starting a new transmission.
293  * @param[in,out] pCanMessage pointer to CAN data to be reset
294  */
295 static void I165C_ResetCanData(CAN_BUFFERELEMENT_s *pCanMessage);
296 
297 /**
298  * @brief Write data in data word for CAN transmission.
299  * @param dataWord data word ("position") in CAN structure to be written
300  * to (see data sheet page 15)
301  * @param data data to be written in data word
302  * @param[in] pCanMessage CAN structure to be used for transmission
303  */
304 static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFERELEMENT_s *pCanMessage);
305 
306 /**
307  * @brief Get data in data word from CAN transmission.
308  * @param dataWord data word ("position") in CAN structure to be read from
309  * (see data sheet page 15)
310  * @param[out] pData pointer where to put read data from data word
311  * @param canMessage CAN structure used for transmission
312  */
313 static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFERELEMENT_s canMessage);
314 
315 /**
316  * @brief Get data in data word from CAN transmission, for the specific
317  * IMD_Info message.
318  * @param dataWord data word ("position") in CAN structure to be read from
319  * (see data sheet page 15)
320  * @param[out] pData pointer where to put read data from data word
321  * @param canMessage CAN structure used for transmission
322  */
323 static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFERELEMENT_s canMessage);
324 
325 /**
326  * @brief Get data in data byte from CAN transmission.
327  * @param dataByte data byte ("position") in CAN structure to be read from
328  * (see data sheet page 15)
329  * @param[out] pData pointer where to put read data from data byte
330  * @param canMessage CAN structure used for transmission
331  */
332 static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFERELEMENT_s canMessage);
333 
334 /**
335  * @brief Compose CAN message for CAN transmission.
336  * @details Write CMD byte.
337  * @param id CAN ID to use
338  * @param command command to be used (see data page 15 section 6.3 and
339  * further)
340  * @param[out] pCanMessage pointer to CAN structure to be used for transmission
341  */
342 static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFERELEMENT_s *pCanMessage);
343 
344 /**
345  * @brief Check if iso165c acknowledged reception of sent message
346  * and get corresponding data.
347  * @details Gets data from the CAN module through a queue.
348  * @param command check if this command is sent by iso165c to acknowledge
349  * reception
350  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
351  * @return true if transmission acknowledged, false otherwise
352  */
353 static bool I165C_CheckResponse(uint8_t command, CAN_BUFFERELEMENT_s *pCanMessage);
354 
355 /**
356  * @brief Get IMD Info from iso165c
357  * @details Gets data from the CAN module through a queue.
358  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
359  * @return true if IMD_Info message was received, false otherwise
360  */
361 static bool I165C_GetImdInfo(CAN_BUFFERELEMENT_s *pCanMessage);
362 
363 /**
364  * @brief Check if iso165c was initialized and is running
365  * @details Check is made using the CAN IMD_Info data sent by the iso165c.
366  * - the IMC is up and running with no errors:
367  * - insulation measurement deactivated
368  * - self-test executed
369  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
370  * @return true if IMD_Info was received, false otherwise
371  */
372 static bool I165C_IsSelfTestFinished(CAN_BUFFERELEMENT_s canMessage);
373 
374 /**
375  * @brief Check if iso165c has already been performed previously
376  * @details Check is made using the CAN IMD_Info data sent by the iso165c.
377  * - self-test executed
378  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
379  * @return true if self-test has already been executed, false otherwise
380  */
381 static bool I165C_HasSelfTestBeenExecuted(CAN_BUFFERELEMENT_s canMessage);
382 
383 /**
384  * @brief Set state of HV relay
385  * @param[in] relay set state of positive or negative relay
386  * @param[in] relayState open or close relay
387  */
388 static void I165C_SetRelayState(uint8_t relay, uint8_t relayState);
389 
390 /**
391  * @brief Request state of HV relay
392  * @param[in] relay positive or negative relay
393  */
394 static void I165C_RequestRelayState(uint8_t relay);
395 
396 /**
397  * @brief Check state of HV relay
398  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
399  * @param[in] relay positive or negative relay
400  * @param[in] relayState relay opened or closed
401  * @return true if state matches, otherwise false
402  */
403 static bool I165C_CheckRelayState(CAN_BUFFERELEMENT_s canMessage, uint8_t relay, uint8_t relayState);
404 
405 /**
406  * @brief Set measurement mode
407  * @param[in] mode set IMD measurement mode
408  */
409 static void I165C_SetMeasurementMode(uint8_t mode);
410 
411 /**
412  * @brief Check measurement mode
413  * @param[in] canMessage IMD_Info to be checked, sent by the iso165c
414  * @param[in] mode IMD measurement mode (activated or deactivated)
415  * @return true, if measurement mode matches, otherwise false
416  */
417 static bool I165C_CheckMeasurementMode(CAN_BUFFERELEMENT_s canMessage, uint8_t mode);
418 
419 /**
420  * @brief Set average factor of the insulation resistance averaging algorithm
421  * @param[in] averagingFactor set IMD averaging factor
422  */
423 static void I165C_SetAveragingFactor(uint8_t averagingFactor);
424 
425 /**
426  * @brief Check if iso165c acknowledged reception of command
427  * @param command command to be acknowledged
428  * @param[out] pTries pointer to variable counting the number of tries for reception
429  * @param[in] pCanMessage pointer to CAN data sent by the iso165c
430  * @return true if Acknowledge has been received, otherwise false
431  */
432 static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFERELEMENT_s *pCanMessage);
433 
434 /*========== Static Function Implementations ================================*/
436  I165C_INITIALIZATION_STATE_s *pImdState,
438  uint16_t idleTime) {
439  FAS_ASSERT(pImdState != NULL_PTR);
440  /* Set time */
441  pImdState->timer = idleTime;
442  /* Set state */
443  if (nextState != pImdState->currentState) {
444  /* Next state is different: switch to it and set substate to entry value */
445  pImdState->previousState = pImdState->currentState;
446  pImdState->currentState = nextState;
447  } else {
448  /* Next state equal to current state: nothing to do */
449  }
450 }
451 
453  I165C_ENABLE_STATE_s *pImdState,
454  I165C_FSM_ENABLE_STATES_e nextState,
455  uint16_t idleTime) {
456  FAS_ASSERT(pImdState != NULL_PTR);
457  /* Set time */
458  pImdState->timer = idleTime;
459  /* Set state */
460  if (nextState != pImdState->currentState) {
461  /* Next state is different: switch to it and set substate to entry value */
462  pImdState->previousState = pImdState->currentState;
463  pImdState->currentState = nextState;
464  } else {
465  /* Next state equal to current state: nothing to do */
466  }
467 }
468 
470  I165C_RUNNING_STATE_s *pImdState,
471  I165C_FSM_RUNNING_STATES_e nextState,
472  uint16_t idleTime) {
473  FAS_ASSERT(pImdState != NULL_PTR);
474  /* Set time */
475  pImdState->timer = idleTime;
476  /* Set state */
477  if (nextState != pImdState->currentState) {
478  /* Next state is different: switch to it and set substate to entry value */
479  pImdState->previousState = pImdState->currentState;
480  pImdState->currentState = nextState;
481  } else {
482  /* Next state equal to current state: nothing to do */
483  }
484 }
485 
487  I165C_DISABLE_STATE_s *pImdState,
488  I165C_FSM_DISABLE_STATES_e nextState,
489  uint16_t idleTime) {
490  FAS_ASSERT(pImdState != NULL_PTR);
491  /* Set time */
492  pImdState->timer = idleTime;
493  /* Set state */
494  if (nextState != pImdState->currentState) {
495  /* Next state is different: switch to it and set substate to entry value */
496  pImdState->previousState = pImdState->currentState;
497  pImdState->currentState = nextState;
498  } else {
499  /* Next state equal to current state: nothing to do */
500  }
501 }
502 
503 static void I165C_ResetCanData(CAN_BUFFERELEMENT_s *pCanMessage) {
504  FAS_ASSERT(pCanMessage != NULL_PTR);
505  for (uint8_t i = 0u; i < CAN_DLC; i++) {
506  pCanMessage->data[i] = 0u;
507  }
508 }
509 
510 static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFERELEMENT_s *pCanMessage) {
511  FAS_ASSERT(pCanMessage != NULL_PTR);
512  /* See data sheet section 6.1 page 15 */
513  if (dataWord == I165C_DW1) {
514  pCanMessage->data[CAN_BYTE_1_POSITION] = (uint8_t)(data & 0xFFu);
515  pCanMessage->data[CAN_BYTE_2_POSITION] = (uint8_t)((data >> 8u) & 0xFFu);
516  }
517  if (dataWord == I165C_DW2) {
518  pCanMessage->data[CAN_BYTE_3_POSITION] = (uint8_t)(data & 0xFFu);
519  pCanMessage->data[CAN_BYTE_4_POSITION] = (uint8_t)((data >> 8u) & 0xFFu);
520  }
521 }
522 
523 static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFERELEMENT_s canMessage) {
524  FAS_ASSERT(pData != NULL_PTR);
525  /* See data sheet section 6.1 page 15 */
526  if (dataWord == I165C_DW1) {
527  *pData = canMessage.data[CAN_BYTE_1_POSITION];
528  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_2_POSITION]) << 8u) & 0xFF00u;
529  }
530  if (dataWord == I165C_DW2) {
531  *pData = canMessage.data[CAN_BYTE_3_POSITION];
532  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_4_POSITION]) << 8u) & 0xFF00u;
533  }
534  if (dataWord == I165C_DW3) {
535  *pData = canMessage.data[CAN_BYTE_5_POSITION];
536  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_6_POSITION]) << 8u) & 0xFF00u;
537  }
538 }
539 
540 static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFERELEMENT_s canMessage) {
541  FAS_ASSERT(pData != NULL_PTR);
542  /* See data sheet section 6.1 page 15 */
543  if (dataWord == I165C_DW1) {
544  *pData = canMessage.data[CAN_BYTE_0_POSITION];
545  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_1_POSITION]) << 8u) & 0xFF00u;
546  }
547  if (dataWord == I165C_DW2) {
548  *pData = canMessage.data[CAN_BYTE_2_POSITION];
549  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_3_POSITION]) << 8u) & 0xFF00u;
550  }
551  if (dataWord == I165C_DW3) {
552  *pData = canMessage.data[CAN_BYTE_4_POSITION];
553  *pData |= (((uint16_t)canMessage.data[CAN_BYTE_5_POSITION]) << 8u) & 0xFF00u;
554  }
555 }
556 
557 static void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFERELEMENT_s canMessage) {
558  FAS_ASSERT(pData != NULL_PTR);
559  /* See data sheet section 6.1 page 15 */
560  switch (dataByte) {
561  case I165C_DB1:
562  *pData = canMessage.data[CAN_BYTE_1_POSITION];
563  break;
564  case I165C_DB2:
565  *pData = canMessage.data[CAN_BYTE_2_POSITION];
566  break;
567  case I165C_DB3:
568  *pData = canMessage.data[CAN_BYTE_3_POSITION];
569  break;
570  case I165C_DB4:
571  *pData = canMessage.data[CAN_BYTE_4_POSITION];
572  break;
573  default:
574  *pData = 0u;
575  break;
576  }
577 }
578 
579 static void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFERELEMENT_s *pCanMessage) {
580  FAS_ASSERT(pCanMessage != NULL_PTR);
581  /* CAN message is a request, set ID accordingly */
582  pCanMessage->id = id;
583  /* First byte contains the CMD field */
584  pCanMessage->data[CAN_BYTE_0_POSITION] = command;
585 }
586 
587 static bool I165C_CheckResponse(uint8_t command, CAN_BUFFERELEMENT_s *pCanMessage) {
588  FAS_ASSERT(pCanMessage != NULL_PTR);
589  bool messageReceived = false;
590  uint8_t numberItems = 0u;
591  uint8_t queueReadTries = I165C_MAX_QUEUE_READS;
592 
593  /* Use loop on queue because IMD_info message could come meanwhile */
594  do {
596  if (numberItems > 0u) {
597  if (OS_ReceiveFromQueue(ftsk_imdCanDataQueue, (void *)pCanMessage, 0u) == OS_SUCCESS) {
598  /* data queue was no empty */
599  if ((command == pCanMessage->data[CAN_BYTE_0_POSITION]) && (pCanMessage->id == CAN_ID_IMD_RESPONSE)) {
600  messageReceived = true;
601  break;
602  }
603  }
604  }
605  queueReadTries--;
606  } while ((numberItems > 0u) && (queueReadTries > 0u));
607 
608  return messageReceived;
609 }
610 
611 static bool I165C_GetImdInfo(CAN_BUFFERELEMENT_s *pCanMessage) {
612  FAS_ASSERT(pCanMessage != NULL_PTR);
613  bool imdInfoReceived = false;
614  uint8_t numberItems = 0u;
615  uint8_t queueReadTries = I165C_MAX_QUEUE_READS;
616 
617  /* Use loop on queue because other messages could come meanwhile */
618  do {
620  if (numberItems > 0u) {
621  if (OS_ReceiveFromQueue(ftsk_imdCanDataQueue, (void *)pCanMessage, 0u) == OS_SUCCESS) {
622  /* data queue was no empty */
623  if (pCanMessage->id == I165C_MESSAGETYPE_IMD_INFO) {
624  imdInfoReceived = true;
625  break;
626  }
627  }
628  }
629  queueReadTries--;
630  } while ((numberItems > 0u) && (queueReadTries > 0u));
631 
632  return imdInfoReceived;
633 }
634 
636  bool initialized = true;
637  uint16_t data = 0u;
638 
639  /* Extract D_IMC_STATUS */
640  I165C_ReadDataWordImdInfo(I165C_DW2, &data, canMessage);
641  /* I165C_SELFTEST_RUNNING bit = 1 in IMD_Info DW2: self test running */
642  uint16_t selfTestState = (data & (1u << I165C_SELFTEST_RUNNING_SHIFT));
643  if (selfTestState != (1u << I165C_SELFTEST_RUNNING_SHIFT)) {
644  /* self test not running */
645  initialized = false;
646  }
647 
648  /* Extract D_VIFC_STATUS */
649  I165C_ReadDataWordImdInfo(I165C_DW3, &data, canMessage);
650  /* I165C_INSULATION_MEASUREMENT bit = 0 in IMD_Info DW3: insulation measurement active */
651  uint16_t insulationMeasurementState = (data & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT));
652  if (insulationMeasurementState != 0u) {
653  /* insulation measurement active */
654  initialized = false;
655  }
656 #ifdef I165C_SELF_TEST_LONG
657  /* I165C_IMC_SELFTEST_OVERALL_SCENARIO bit = 1 in IMD_Info DW3: selftest overall scenario not executed */
658  uint16_t selfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT));
659  if (selfTestExecuted != 0u) {
660  /* selftest overall scenario not executed */
661  initialized = false;
662  }
663 #else
664  /* I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO bit = 1 in IMD_Info DW3: selftest parameter config not executed */
665  uint16_t selfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT));
666  if (selfTestExecuted != 0u) {
667  /* selftest parameter scenario not executed */
668  initialized = false;
669  }
670 #endif
671  return initialized;
672 }
673 
675  bool anySelfTestExecuted = false;
676  uint16_t data = 0u;
677 
678  /* Extract D_VIFC_STATUS */
679  I165C_ReadDataWordImdInfo(I165C_DW3, &data, canMessage);
680 
681  /* I165C_IMC_SELFTEST_OVERALL_SCENARIO bit = 1 in IMD_Info DW3: selftest overall scenario not executed */
682  uint16_t overallSelfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_OVERALL_SCENARIO_SHIFT));
683  if (overallSelfTestExecuted == 0u) {
684  /* selftest overall scenario has been executed */
685  anySelfTestExecuted = true;
686  }
687  /* I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO bit = 1 in IMD_Info DW3: selftest parameter config not executed */
688  uint16_t parameterSelfTestExecuted = (data & (1u << I165C_IMC_SELFTEST_PARAMETERCONFIG_SCENARIO_SHIFT));
689  if (parameterSelfTestExecuted == 0u) {
690  /* selftest parameter scenario has been executed */
691  anySelfTestExecuted = true;
692  }
693  return anySelfTestExecuted;
694 }
695 
696 static void I165C_SetRelayState(uint8_t relay, uint8_t relayState) {
698  FAS_ASSERT((relayState == I165C_RELAY_STATE_OPEN) || (relayState == I165C_RELAY_STATE_CLOSED));
699  /* Reset CAN message buffer */
701  /* Assemble CAN message */
705  /* Transmit CAN message */
707 }
708 
709 static void I165C_RequestRelayState(uint8_t relay) {
711  /* Reset CAN message buffer */
713  /* Assemble CAN message */
716  /* Transmit CAN message */
718 }
719 
720 static bool I165C_CheckRelayState(CAN_BUFFERELEMENT_s canMessage, uint8_t relay, uint8_t relayState) {
722  FAS_ASSERT((relayState == I165C_RELAY_STATE_OPEN) || (relayState == I165C_RELAY_STATE_CLOSED));
723  bool checkSuccess = true;
724  uint16_t data = 0u;
725 
727  /* IMD_Response DW1: relay */
728  if (relay != data) {
729  /* not request relay */
730  checkSuccess = false;
731  }
732 
734  /* IMD_Response DW2: relay state */
735  if (relayState != data) {
736  /* relay state does not match expected state */
737  checkSuccess = false;
738  }
739  return checkSuccess;
740 }
741 
742 static void I165C_SetMeasurementMode(uint8_t mode) {
744  /* Reset CAN message buffer */
746  /* Assemble CAN message */
749  /* Transmit CAN message */
751 }
752 
753 static bool I165C_CheckMeasurementMode(CAN_BUFFERELEMENT_s canMessage, uint8_t mode) {
755  bool measurementModeMatches = false;
756  uint16_t dVIFCStatus = 0u;
757 
758  /* Extract D_VIFC_STATUS word */
760  /* Extract measurement mode from D_VIFC_STATUS word */
761  uint8_t actualMeasurementMode = dVIFCStatus & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT);
762 
763  /* Check if actual measurement mode matches passed measurement mode */
764  if (actualMeasurementMode == mode) {
765  /* Insulation measurement deactivated*/
766  measurementModeMatches = true;
767  }
768  return measurementModeMatches;
769 }
770 
771 static void I165C_SetAveragingFactor(uint8_t averagingFactor) {
772  /* Averaging factor must be in the range 1...20 */
773  FAS_ASSERT(averagingFactor != 0u);
774  FAS_ASSERT(averagingFactor <= 20u);
775 
776  /* Reset CAN message buffer */
778  /* Assemble CAN message */
781  /* Transmit CAN message */
783 }
784 
785 static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFERELEMENT_s *pCanMessage) {
786  FAS_ASSERT(pTries != NULL_PTR);
787  FAS_ASSERT(pCanMessage != NULL_PTR);
788  /* AXIVION Routine Generic-MissingParameterAssert: command: parameter accepts whole range */
789 
790  bool acknowledgeReceived = false;
791  if (I165C_CheckResponse(command, pCanMessage) == false) {
792  (*pTries)++;
793  } else {
794  *pTries = 0u;
795  acknowledgeReceived = true;
796  }
797  return acknowledgeReceived;
798 }
799 
801  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_INITIALIZATION; /* stay in initialization state */
802  bool earlyExit = false;
803 
804  if (i165c_initializationState.timer > 0u) {
805  if ((--i165c_initializationState.timer) > 0u) {
807  earlyExit = true;
808  }
809  }
810 
811  if (earlyExit == false) {
814  /* Unlock device in case it was locked */
822  break;
823 
827  true) {
832  } else {
833  /* Issue: 621 */
834  }
835  break;
836 
838  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
840  /* Measurement is not enabled -> Enable measurement as otherwise the following
841  * initialization procedure would fail */
847  } else {
848  /* Measurement enabled -> continue with initialization procedure */
853  }
854  }
855  break;
856 
861  &i165c_canRxMessage) == true) {
862  /* Measurement enabled -> continue with initialization procedure */
867  } else {
868  /* Issue: 621 */
869  }
870  break;
871 
873  /* Open negative relay */
875  /* Open positive relay */
877  /* Switch to next state */
882  break;
883 
890  break;
891 
893  /* Check if HV relay is open and measurement has been stopped */
899 
900  /* Request state of positive HV relay */
902 
907  } else {
909  /* Issue: 621 */
910  }
911  } else {
913  /* Issue: 621 */
914  }
915  break;
916 
918  /* Check if HV relays are open and measurement has been stopped */
924 
929  } else {
931  /* Issue: 621 */
932  }
933  } else {
935  /* Issue: 621 */
936  }
937  break;
938 
940  /* A self test must be requested and can only be carried out
941  when the coupling relays are open. */
942 
943  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
948 #ifdef I165C_SELF_TEST_LONG
951 #else /* I165C_SELF_TEST_SHORT */
956 #endif
963  } else {
964  /* Self-test has already been performed -> skip following initialization steps as the device
965  has previously been successfully configured. */
970  }
971  }
972 
973  break;
974 
978  true) {
983  } else {
984  /* Issue: 621 */
986  /* Issue: 621 */
992  }
993  }
994  break;
996  if (I165C_GetImdInfo(&i165c_canRxMessage) == true) {
999  } else {
1006  }
1007  } else {
1008  /* Issue: 621 */
1011  /* Initialization not working: restart initialization procedure */
1012  /* Issue: 621 */
1013  }
1014  }
1015  break;
1016 
1023  break;
1024 
1029  &i165c_canRxMessage) == true) {
1034  } else {
1035  /* Issue: 621 */
1036  }
1037  break;
1038 
1049  break;
1054  &i165c_canRxMessage) == true) {
1059  } else {
1060  /* Issue: 621 */
1061  }
1062  break;
1073  break;
1078  &i165c_canRxMessage) == true) {
1083  } else {
1084  /* Issue: 621 */
1085  }
1086  break;
1087 
1094  break;
1095 
1100  &i165c_canRxMessage) == true) {
1101  /* Initialized -> switch to next state in IMD state machine */
1102  nextState = IMD_FSM_STATE_IMD_ENABLE;
1103  /* Reset state machine in case a re-initialization is necessary */
1106 
1107  } else {
1108  /* Issue: 621 */
1109  }
1110  break;
1111 
1112  default:
1114  break;
1115  }
1117  }
1118  return nextState;
1119 }
1120 
1122  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_IMD_ENABLE; /* stay in enable state */
1123  bool earlyExit = false;
1124 
1125  if (i165c_enableState.timer > 0u) {
1126  if ((--i165c_enableState.timer) > 0u) {
1128  earlyExit = true;
1129  }
1130  }
1131 
1132  if (earlyExit == false) {
1133  switch (i165c_enableState.currentState) {
1135  /* Close negative relay */
1137  /* Close positive relay */
1139  /* Switch to next state */
1142  break;
1143 
1148  break;
1149 
1156 
1157  /* Request state of positive HV relay */
1163  } else {
1165  /* Issue: 621 */
1166  }
1167  } else {
1169  /* Issue: 621 */
1176  }
1177  /* Issue: 621 */
1178  }
1179  break;
1180 
1187 
1190  } else {
1192  /* Issue: 621 */
1193  }
1194  } else {
1196  /* Issue: 621 */
1197  }
1198  break;
1199 
1204  break;
1205 
1209  true) {
1210  /* Enabled -> switch to next state in IMD state machine */
1211  nextState = IMD_FSM_STATE_RUNNING;
1212  /* Reset state machine in case a re-enabling is necessary */
1215  } else {
1216  /* Issue: 621 */
1217  }
1218  break;
1219  }
1220  }
1221  return nextState;
1222 }
1223 
1225  FAS_ASSERT(pTableInsulationMonitoring != NULL_PTR);
1226  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_RUNNING; /* stay in running state */
1227  bool earlyExit = false;
1228  uint16_t resistance_kOhm = 0u;
1229  uint16_t statusFlags = 0u;
1230  uint8_t data1 = 0u;
1231  uint8_t data2 = 0u;
1232 
1233  if (i165c_runningState.timer > 0u) {
1234  if ((--i165c_runningState.timer) > 0u) {
1236  earlyExit = true;
1237  }
1238  }
1239 
1240  if (earlyExit == false) {
1241  switch (i165c_runningState.currentState) {
1243  /* Switch to next state */
1246  break;
1247 
1255  break;
1256 
1260  /* Extract resistance value from response */
1261  I165C_ReadDataWord(I165C_DW1, &resistance_kOhm, i165c_canRxMessage);
1262  pTableInsulationMonitoring->insulationResistance_kOhm = resistance_kOhm;
1263 
1264  /* Extract bias/tendency to the location of the insulation fault (error), if detected */
1266  if (data1 == I165C_BIAS_TO_HV_PLUS) {
1267  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = true;
1268  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = false;
1269  } else if (data1 == I165C_BIAS_TO_HV_MINUS) {
1270  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = true;
1271  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = false;
1272  } else {
1273  pTableInsulationMonitoring->dfIsChassisShortToHvPlus = false;
1274  pTableInsulationMonitoring->dfIsChassisShortToHvMinus = false;
1275  }
1276 
1277  /* Extract counter value */
1279  /* TODO: What to do with this info? */
1280 
1283  } else {
1284  /* Issue: 621 */
1285  }
1286  break;
1287 
1289  if (I165C_GetImdInfo(&i165c_canRxMessage) == false) {
1291  /* Issue: 621 */
1292  /* IMD_Info not comming: restart initialization procedure?
1293  if (i165c_runningState.receptionTriesMessage >= I165C_IMD_INFO_RECEIVE_ATTEMPTS) {*/
1294  } else {
1296 
1297  /* Get measured resistance */
1299  pTableInsulationMonitoring->insulationResistance_kOhm = resistance_kOhm;
1300 
1301  /* Get IMC status */
1303  if (0u != (statusFlags & (1u << I165C_INSULATION_FAULT_SHIFT))) {
1304  /* Insulation fault */
1305  pTableInsulationMonitoring->dfIsCriticalResistanceDetected = true;
1306  } else {
1307  pTableInsulationMonitoring->dfIsCriticalResistanceDetected = false;
1308  }
1309  if (0u != (statusFlags & (1u << I165C_CHASSIS_FAULT_SHIFT))) {
1310  /* Chassis fault */
1311  pTableInsulationMonitoring->dfIsChassisFaultDetected = true;
1312  } else {
1313  pTableInsulationMonitoring->dfIsChassisFaultDetected = false;
1314  }
1315  if (0u != (statusFlags & (1u << I165C_SYSTEM_FAILURE_SHIFT))) {
1316  /* System failure */
1317  pTableInsulationMonitoring->dfIsDeviceErrorDetected = true;
1318  pTableInsulationMonitoring->areDeviceFlagsValid = false;
1319  } else {
1320  pTableInsulationMonitoring->dfIsDeviceErrorDetected = false;
1321  pTableInsulationMonitoring->areDeviceFlagsValid = true;
1322  }
1323  if (0u != (statusFlags & (1u << I165C_INSULATION_WARNING_SHIFT))) {
1324  /* Insulation warning */
1325  pTableInsulationMonitoring->dfIsWarnableResistanceDetected = true;
1326  } else {
1327  pTableInsulationMonitoring->dfIsWarnableResistanceDetected = false;
1328  }
1329 
1330  /* Get VIFC status */
1332  if (0u != (statusFlags & (1u << I165C_INSULATION_MEASUREMENT_STATUS_SHIFT))) {
1333  /* Insulation measurement deactivated*/
1334  pTableInsulationMonitoring->isImdRunning = false;
1335  } else {
1336  pTableInsulationMonitoring->isImdRunning = true;
1337  }
1338  if (0u != (statusFlags & (1u << I165C_RESISTANCE_VALUE_OUTDATED_SHIFT))) {
1339  /* Insulation resistance value outdated */
1340  pTableInsulationMonitoring->dfIsMeasurmentedUpToDate = false;
1341  } else {
1342  pTableInsulationMonitoring->dfIsMeasurmentedUpToDate = true;
1343  }
1344  if ((pTableInsulationMonitoring->areDeviceFlagsValid == true) &&
1345  (pTableInsulationMonitoring->isImdRunning == true) &&
1346  (pTableInsulationMonitoring->dfIsMeasurmentedUpToDate == true)) {
1347  pTableInsulationMonitoring->isInsulationMeasurementValid = true;
1348  } else {
1349  pTableInsulationMonitoring->isInsulationMeasurementValid = false;
1350  }
1351  }
1352  /* Restart measurement cycle */
1355  break;
1356 
1357  default:
1358  /* invalid state */
1359  nextState = IMD_FSM_STATE_ERROR;
1361  break;
1362  }
1363  }
1364  return nextState;
1365 }
1366 
1367 /** Disable state machine */
1369  IMD_FSM_STATES_e nextState = IMD_FSM_STATE_SHUTDOWN; /* stay in shutdown state */
1370  bool earlyExit = false;
1371 
1372  if (i165c_disableState.timer > 0u) {
1373  if ((--i165c_disableState.timer) > 0u) {
1375  earlyExit = true;
1376  }
1377  }
1378 
1379  if (earlyExit == false) {
1380  switch (i165c_disableState.currentState) {
1382  /* The I165C_Running state-machine, does not know when the
1383  * disable command is received by the superimposed IMD state
1384  * machine. Thus, the I165C_Running state machine needs to be
1385  * reset at this point to correctly call the running state
1386  * machine after re-enabling. */
1388 
1389  /* Request stop of measurement */
1393  break;
1394 
1398  true) {
1401  } else {
1402  /* Issue: 621 */
1403  }
1404  break;
1405 
1407  /* Open negative relay */
1409  /* Open positive relay */
1413  break;
1414 
1419  break;
1420 
1427 
1428  /* Request state of positive HV relay */
1434  } else {
1436  /* Issue: 621 */
1437  }
1438  } else {
1440  /* Issue: 621 */
1441  }
1442  break;
1443 
1450 
1451  /* Reset disable state machine in case a another disabling is necessary */
1454 
1455  /* IMD successfully disabled -> switch to next state in superimposed IMD state machine */
1456  nextState = IMD_FSM_STATE_IMD_ENABLE;
1457  } else {
1459  /* Issue: 621 */
1460  }
1461  } else {
1463  /* Issue: 621 */
1464  }
1465  break;
1466  }
1467  }
1468  return nextState;
1469 }
1470 
1471 /*========== Extern Function Implementations ================================*/
1472 
1474  return I165C_Initialize();
1475 }
1476 
1478  return I165C_Enable();
1479 }
1480 
1482  FAS_ASSERT(pTableInsulationMonitoring != NULL_PTR);
1483  return I165C_Running(pTableInsulationMonitoring);
1484 }
1485 
1487  return I165C_Disable();
1488 }
1489 
1490 /*========== Externalized Static Function Implementations (Unit Test) =======*/
1491 #ifdef UNITY_UNIT_TEST
1492 extern void TEST_I165C_ResetCanData(CAN_BUFFERELEMENT_s *canMessage) {
1493  I165C_ResetCanData(canMessage);
1494 }
1495 extern void TEST_I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFERELEMENT_s *canMessage) {
1496  I165C_WriteDataWord(dataWord, data, canMessage);
1497 }
1498 extern void TEST_I165C_ReadDataWord(uint8_t dataWord, uint16_t *data, CAN_BUFFERELEMENT_s canMessage) {
1499  I165C_ReadDataWord(dataWord, data, canMessage);
1500 }
1501 extern void TEST_I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *data, CAN_BUFFERELEMENT_s canMessage) {
1502  I165C_ReadDataWordImdInfo(dataWord, data, canMessage);
1503 }
1504 extern void TEST_I165C_ReadDataByte(uint8_t dataByte, uint8_t *data, CAN_BUFFERELEMENT_s canMessage) {
1505  I165C_ReadDataByte(dataByte, data, canMessage);
1506 }
1507 extern void TEST_I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFERELEMENT_s *canMessage) {
1508  I165C_WriteCmd(id, command, canMessage);
1509 }
1510 extern bool TEST_I165C_CheckResponse(uint8_t command, CAN_BUFFERELEMENT_s *canMessage) {
1511  return I165C_CheckResponse(command, canMessage);
1512 }
1513 extern bool TEST_I165C_GetImdInfo(CAN_BUFFERELEMENT_s *canMessage) {
1514  return I165C_GetImdInfo(canMessage);
1515 }
1516 extern bool TEST_I165C_IsSelfTestFinished(CAN_BUFFERELEMENT_s canMessage) {
1517  return I165C_IsSelfTestFinished(canMessage);
1518 }
1519 extern bool TEST_I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *tries, CAN_BUFFERELEMENT_s *canMessage) {
1520  return I165C_CheckAcknowledgeArrived(command, tries, canMessage);
1521 }
1522 
1523 #endif
static void I165C_ReadDataWordImdInfo(uint8_t dataWord, uint16_t *pData, CAN_BUFFERELEMENT_s canMessage)
Get data in data word from CAN transmission, for the specific IMD_Info message.
static IMD_FSM_STATES_e I165C_Initialize(void)
static CAN_BUFFERELEMENT_s i165c_canTxMessage
IMD_FSM_STATES_e IMD_ProcessInitializationState(void)
Processes the initialization state.
static CAN_BUFFERELEMENT_s i165c_canRxMessage
static IMD_FSM_STATES_e I165C_Disable(void)
static bool I165C_IsSelfTestFinished(CAN_BUFFERELEMENT_s canMessage)
Check if iso165c was initialized and is running.
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 void I165C_WriteCmd(uint8_t id, uint8_t command, CAN_BUFFERELEMENT_s *pCanMessage)
Compose CAN message for CAN transmission.
static IMD_FSM_STATES_e I165C_Running(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring)
trigger function for the i165c driver state machine.
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.
static bool I165C_CheckRelayState(CAN_BUFFERELEMENT_s canMessage, uint8_t relay, uint8_t relayState)
Check state of HV relay.
#define I165C_FSM_SHORT_TIME
static bool I165C_CheckMeasurementMode(CAN_BUFFERELEMENT_s canMessage, uint8_t mode)
Check measurement mode.
static void I165C_RequestRelayState(uint8_t relay)
Request state of HV relay.
static bool I165C_GetImdInfo(CAN_BUFFERELEMENT_s *pCanMessage)
Get IMD Info from iso165c.
static bool I165C_HasSelfTestBeenExecuted(CAN_BUFFERELEMENT_s canMessage)
Check if iso165c has already been performed previously.
static void I165C_ReadDataWord(uint8_t dataWord, uint16_t *pData, CAN_BUFFERELEMENT_s canMessage)
Get data in data word from CAN transmission.
static void I165C_WriteDataWord(uint8_t dataWord, uint16_t data, CAN_BUFFERELEMENT_s *pCanMessage)
Write data in data word for CAN transmission.
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 void I165C_ReadDataByte(uint8_t dataByte, uint8_t *pData, CAN_BUFFERELEMENT_s canMessage)
Get data in data byte from CAN transmission.
static void I165C_ResetCanData(CAN_BUFFERELEMENT_s *pCanMessage)
Reset CAN data.
static bool I165C_CheckAcknowledgeArrived(uint8_t command, uint8_t *pTries, CAN_BUFFERELEMENT_s *pCanMessage)
Check if iso165c acknowledged reception of command.
static I165C_ENABLE_STATE_s i165c_enableState
IMD_FSM_STATES_e IMD_ProcessRunningState(DATA_BLOCK_INSULATION_MONITORING_s *pTableInsulationMonitoring)
Processes the running state.
static bool I165C_CheckResponse(uint8_t command, CAN_BUFFERELEMENT_s *pCanMessage)
Check if iso165c acknowledged reception of sent message and get corresponding data.
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 messageboxes and marks the ...
Definition: can.c:206
Header for the driver for the CAN module.
#define CAN_ID_IMD_RESPONSE
Definition: can_cfg.h:216
#define CAN_DLC
Definition: can_cfg.h:91
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:241
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:115
#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:307
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