foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
interlock.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2023, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file interlock.c
44  * @author foxBMS Team
45  * @date 2020-02-24 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix ILCK
50  *
51  * @brief Driver for the interlock.
52  * @details The interlock driver measures the relevant hardware signals from
53  * the interlock circuit. For details on available hardware signals
54  * please refer to the section on this module in the foxBMS
55  * documentation.
56  *
57  * In reference to the names in the foxBMS schematic, this module uses
58  * the following names:
59  *
60  * shorthand | meaning
61  * --------- | ---------
62  * IL | interlock
63  * HS | high-side
64  * LS | low-side
65  * VS | voltage sense
66  * CS | current sense
67  *
68  */
69 
70 /*========== Includes =======================================================*/
71 #include "interlock.h"
72 
73 #include "database.h"
74 #include "diag.h"
75 #include "io.h"
76 #include "os.h"
77 
78 #include <stdbool.h>
79 #include <stdint.h>
80 
81 /*========== Macros and Definitions =========================================*/
82 /**
83  * Saves the last state and the last substate
84  */
85 #define ILCK_SAVELASTSTATES() \
86  ilck_state.laststate = ilck_state.state; \
87  ilck_state.lastsubstate = ilck_state.substate
88 
89 /*========== Static Constant and Variable Definitions =======================*/
90 /**
91  * contains the state of the contactor state machine
92  */
94  .timer = 0,
95  .statereq = ILCK_STATE_NO_REQUEST,
97  .substate = ILCK_ENTRY,
99  .lastsubstate = ILCK_ENTRY,
100  .triggerentry = 0,
101  .ErrRequestCounter = 0,
102  .counter = 0,
103 };
104 
105 /** Local variable containing interlock feedback */
107 
108 /*========== Extern Constant and Variable Definitions =======================*/
109 
110 /*========== Static Function Prototypes =====================================*/
111 /**
112  * @brief checks the state requests that are made.
113  * @details This function checks the validity of the state requests. The
114  * results of the checked is returned immediately.
115  * @param statereq state request to be checked
116  * @return result of the state request that was made, taken from
117  * #ILCK_RETURN_TYPE_e
118  */
120 
121 /**
122  * @brief transfers the current state request to the state machine.
123  * @details This function takes the current state request from ilck_state and
124  * transfers it to the state machine. It resets the value from
125  * ilck_state to ILCK_STATE_NO_REQUEST
126  * @return current state request, taken from ILCK_STATE_REQUEST_e
127  */
129 
130 /**
131  * @brief re-entrance check of ILCK state machine trigger function
132  * @details This function is not re-entrant and should only be called time- or
133  * event-triggered. It increments the triggerentry counter from the
134  * state variable ilck_state. It should never be called by two
135  * different processes, so if it is the case, triggerentry should
136  * never be higher than 0 when this function is called.
137  * @return 0 if no further instance of the function is active, 0xFF else
138  */
139 static uint8_t ILCK_CheckReEntrance(void);
140 
141 /**
142  * @brief Initializes required pins for interlock evaluation
143  */
144 static void ILCK_InitializePins(void);
145 
146 /**
147  * @brief Reads the feedback pin of the interlock and returns its current value
148  * (ILCK_SWITCH_OFF/ILCK_SWITCH_ON)
149  * @return measuredInterlockState (type: ILCK_ELECTRICAL_STATE_TYPE_e)
150  */
152 
153 /*========== Static Function Implementations ================================*/
155  ILCK_RETURN_TYPE_e stateRequestCheck = ILCK_ILLEGAL_REQUEST;
156  if (!((statereq == ILCK_STATE_INITIALIZATION_REQUEST) || (statereq == ILCK_STATE_NO_REQUEST))) {
157  stateRequestCheck = ILCK_ILLEGAL_REQUEST;
158  } else if (ilck_state.statereq == ILCK_STATE_NO_REQUEST) {
159  /* init only allowed from the uninitialized state */
160  if (statereq == ILCK_STATE_INITIALIZATION_REQUEST) {
162  stateRequestCheck = ILCK_OK;
163  } else {
164  stateRequestCheck = ILCK_ALREADY_INITIALIZED;
165  }
166  }
167  } else {
168  stateRequestCheck = ILCK_REQUEST_PENDING;
169  }
170  return stateRequestCheck;
171 }
172 
175 
177  retval = ilck_state.statereq;
180 
181  return retval;
182 }
183 
184 static uint8_t ILCK_CheckReEntrance(void) {
185  uint8_t retval = 0;
186 
188  if (!ilck_state.triggerentry) {
190  } else {
191  retval = 0xFF; /* multiple calls of function */
192  }
194 
195  return retval;
196 }
197 
198 static void ILCK_InitializePins(void) {
199  /* Configure diagnostic supply enable pin as output */
201  /* Disable diagnostic power supply as component is currently NOT available */
203  /* Configure interlock feedback pin as input */
205 }
206 
208  ILCK_ELECTRICAL_STATE_TYPE_e measuredInterlockState = ILCK_SWITCH_UNDEF;
209 
213 
214  /** Local variable containing voltages measured on TMS570 ADC1 inputs */
216  DATA_READ_DATA(&ilck_tableAdcVoltages);
217 
218  /** Pin low: interlock closed, pin high: interlock open */
219  if (pinState == STD_PIN_HIGH) {
220  measuredInterlockState = ILCK_SWITCH_OFF;
221  } else if (pinState == STD_PIN_LOW) {
222  measuredInterlockState = ILCK_SWITCH_ON;
223  }
224 
237 
238  ilck_tableFeedback.interlockFeedback_IL_STATE = measuredInterlockState;
239 
241 
242 #if (BS_IGNORE_INTERLOCK_FEEDBACK == true)
243  measuredInterlockState = ILCK_SWITCH_ON;
244 #endif
245 
246  return measuredInterlockState;
247 }
248 
249 /*========== Extern Function Implementations ================================*/
251  return ilck_state.state;
252 }
253 
256 
258  retVal = ILCK_CheckStateRequest(statereq);
259 
260  if (retVal != ILCK_ILLEGAL_REQUEST) {
261  ilck_state.statereq = statereq;
262  }
264 
265  return retVal;
266 }
267 
268 void ILCK_Trigger(void) {
271 
272  /* Check re-entrance of function */
273  if (ILCK_CheckReEntrance() > 0u) {
274  return;
275  }
276 
277  if (ilck_state.timer > 0u) {
278  if ((--ilck_state.timer) > 0u) {
280  return; /* handle state machine only if timer has elapsed */
281  }
282  }
283 
284  switch (ilck_state.state) {
285  /****************************UNINITIALIZED***********************************/
287  /* waiting for Initialization Request */
288  statereq = ILCK_TransferStateRequest();
289  if (statereq == ILCK_STATE_INITIALIZATION_REQUEST) {
295  } else if (statereq == ILCK_STATE_NO_REQUEST) {
296  /* no actual request pending */
297  } else {
298  ilck_state.ErrRequestCounter++; /* illegal request pending */
299  }
300  break;
301 
302  /****************************INITIALIZED*************************************/
306  interlockState = ILCK_GetInterlockFeedback();
307  if (interlockState == ILCK_SWITCH_ON) {
309  } else {
311  }
312  break;
313 
314  default:
315  /* this is an undefined state that should never be reached */
317  break;
318  } /* end switch (ilck_state.state) */
319 
321 }
322 
323 /*================== Setter for static Variables (Unit Test) ==============*/
324 #ifdef UNITY_UNIT_TEST
325 extern void TEST_ILCK_SetStateStruct(ILCK_STATE_s state) {
326  ilck_state = state;
327 }
328 #endif
329 
330 /*========== Externalized Static Function Implementations (Unit Test) =======*/
331 #ifdef UNITY_UNIT_TEST
332 extern ILCK_ELECTRICAL_STATE_TYPE_e TEST_ILCK_GetInterlockFeedback(void) {
333  return ILCK_GetInterlockFeedback();
334 }
335 #endif
Database module header.
#define DATA_READ_DATA(...)
Definition: database.h:86
#define DATA_WRITE_DATA(...)
Definition: database.h:96
@ DATA_BLOCK_ID_INTERLOCK_FEEDBACK
Definition: database_cfg.h:98
@ DATA_BLOCK_ID_ADC_VOLTAGE
Definition: database_cfg.h:79
DIAG_RETURNTYPE_e DIAG_Handler(DIAG_ID_e diagId, DIAG_EVENT_e event, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_Handler provides generic error handling, based on diagnosis group.
Definition: diag.c:246
Diagnosis driver header.
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:268
@ DIAG_EVENT_OK
Definition: diag_cfg.h:267
@ DIAG_SYSTEM
Definition: diag_cfg.h:280
@ DIAG_ID_INTERLOCK_FEEDBACK
Definition: diag_cfg.h:232
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:255
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:129
STD_PIN_STATE_e
Definition: fstd_types.h:88
@ STD_PIN_LOW
Definition: fstd_types.h:89
@ STD_PIN_HIGH
Definition: fstd_types.h:90
static void ILCK_InitializePins(void)
Initializes required pins for interlock evaluation.
Definition: interlock.c:198
#define ILCK_SAVELASTSTATES()
Definition: interlock.c:85
static ILCK_STATE_s ilck_state
Definition: interlock.c:93
static uint8_t ILCK_CheckReEntrance(void)
re-entrance check of ILCK state machine trigger function
Definition: interlock.c:184
ILCK_RETURN_TYPE_e ILCK_SetStateRequest(ILCK_STATE_REQUEST_e statereq)
sets the current state request of the state variable ilck_state.
Definition: interlock.c:254
void ILCK_Trigger(void)
trigger function for the ILCK driver state machine.
Definition: interlock.c:268
static ILCK_STATE_REQUEST_e ILCK_TransferStateRequest(void)
transfers the current state request to the state machine.
Definition: interlock.c:173
static ILCK_ELECTRICAL_STATE_TYPE_e ILCK_GetInterlockFeedback(void)
Reads the feedback pin of the interlock and returns its current value (ILCK_SWITCH_OFF/ILCK_SWITCH_ON...
Definition: interlock.c:207
static DATA_BLOCK_INTERLOCK_FEEDBACK_s ilck_tableFeedback
Definition: interlock.c:106
ILCK_STATEMACH_e ILCK_GetState(void)
gets the current state.
Definition: interlock.c:250
static ILCK_RETURN_TYPE_e ILCK_CheckStateRequest(ILCK_STATE_REQUEST_e statereq)
checks the state requests that are made.
Definition: interlock.c:154
Headers for the driver for the interlock.
ILCK_STATEMACH_e
Definition: interlock.h:68
@ ILCK_STATEMACHINE_UNINITIALIZED
Definition: interlock.h:70
@ ILCK_STATEMACHINE_INITIALIZED
Definition: interlock.h:71
ILCK_RETURN_TYPE_e
Definition: interlock.h:93
@ ILCK_ALREADY_INITIALIZED
Definition: interlock.h:96
@ ILCK_ILLEGAL_REQUEST
Definition: interlock.h:97
@ ILCK_OK
Definition: interlock.h:94
@ ILCK_REQUEST_PENDING
Definition: interlock.h:95
@ ILCK_ENTRY
Definition: interlock.h:79
ILCK_STATE_REQUEST_e
Definition: interlock.h:85
@ ILCK_STATE_NO_REQUEST
Definition: interlock.h:87
@ ILCK_STATE_INITIALIZATION_REQUEST
Definition: interlock.h:86
#define ILCK_ADC_INPUT_HIGH_SIDE_VOLTAGE_SENSE
Definition: interlock_cfg.h:79
#define ILCK_VOLTAGE_DIVIDER_FACTOR
Definition: interlock_cfg.h:89
ILCK_ELECTRICAL_STATE_TYPE_e
@ ILCK_SWITCH_ON
@ ILCK_SWITCH_UNDEF
@ ILCK_SWITCH_OFF
#define ILCK_ADC_INPUT_LOW_SIDE_VOLTAGE_SENSE
Definition: interlock_cfg.h:81
#define ILCK_IO_REG_PORT
Definition: interlock_cfg.h:69
#define ILCK_STATEMACH_SHORTTIME
ILCK state machine short time definition in ILCK_Trigger() calls until next state/substate is process...
#define ILCK_INTERLOCK_CONTROL_PIN_IL_HS_ENABLE
Definition: interlock_cfg.h:72
#define ILCK_INTERLOCK_FEEDBACK_PIN_IL_STATE
Definition: interlock_cfg.h:75
#define ILCK_FACTOR_IL_LS_CS_1_ohm
#define ILCK_ADC_INPUT_LOW_SIDE_CURRENT_SENSE
Definition: interlock_cfg.h:85
#define ILCK_ADC_INPUT_HIGH_SIDE_CURRENT_SENSE
Definition: interlock_cfg.h:83
#define ILCK_IO_REG_DIR
Definition: interlock_cfg.h:67
#define ILCK_FACTOR_IL_HS_CS_1_ohm
Definition: interlock_cfg.h:97
void IO_SetPinDirectionToOutput(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin to output by writing in pin direction register.
Definition: io.c:77
void IO_SetPinDirectionToInput(volatile uint32_t *pRegisterAddress, uint32_t pin)
Set pin to input by writing in pin direction register.
Definition: io.c:84
void IO_PinReset(volatile uint32_t *pRegisterAddress, uint32_t pin)
Reset pin by writing in pin output register.
Definition: io.c:98
STD_PIN_STATE_e IO_PinGet(const volatile uint32_t *pRegisterAddress, uint32_t pin)
Get pin state.
Definition: io.c:105
Header for the driver for the IO module.
Declaration of the OS wrapper interface.
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:154
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os_freertos.c:150
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:616
float_t adc1ConvertedVoltages_mV[MCU_ADC1_MAX_NR_CHANNELS]
Definition: database_cfg.h:617
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:125
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:414
uint32_t ErrRequestCounter
Definition: interlock.h:111
uint8_t triggerentry
Definition: interlock.h:112
ILCK_STATE_REQUEST_e statereq
Definition: interlock.h:106
ILCK_STATEMACH_e state
Definition: interlock.h:107
uint16_t timer
Definition: interlock.h:105
ILCK_STATEMACH_SUB_e substate
Definition: interlock.h:108