foxBMS  1.1.2
The foxBMS Battery Management System API Documentation
interlock.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  *
18  * 3. Neither the name of the copyright holder nor the names of its
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * We kindly request you to use one or more of the following phrases to refer to
34  * foxBMS in your hardware, software, documentation or advertising materials:
35  *
36  * - ″This product uses parts of foxBMS®″
37  * - ″This product includes parts of foxBMS®″
38  * - ″This product is derived from foxBMS®″
39  *
40  */
41 
42 /**
43  * @file interlock.c
44  * @author foxBMS Team
45  * @date 2020-02-24 (date of creation)
46  * @updated 2020-02-24 (date of last update)
47  * @ingroup DRIVERS
48  * @prefix ILCK
49  *
50  * @brief Driver for the interlock.
51  *
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "interlock.h"
56 
57 #include "HL_gio.h"
58 
59 #include "database.h"
60 #include "diag.h"
61 #include "os.h"
62 
63 /*========== Macros and Definitions =========================================*/
64 /**
65  * Saves the last state and the last substate
66  */
67 #define ILCK_SAVELASTSTATES() \
68  ilck_state.laststate = ilck_state.state; \
69  ilck_state.lastsubstate = ilck_state.substate
70 
71 /** provides more clear name for #ILCK_SwitchInterlockOn() */
72 #define ILCK_CLOSEINTERLOCK() ILCK_SwitchInterlockOn()
73 /** provides more clear name for #ILCK_SwitchInterlockOff() */
74 #define ILCK_OPENINTERLOCK() ILCK_SwitchInterlockOff()
75 
76 /*========== Static Constant and Variable Definitions =======================*/
77 /**
78  * contains the state of the contactor state machine
79  */
81  .timer = 0,
82  .statereq = ILCK_STATE_NO_REQUEST,
84  .substate = ILCK_ENTRY,
85  .laststate = ILCK_STATEMACH_UNINITIALIZED,
86  .lastsubstate = ILCK_ENTRY,
87  .triggerentry = 0,
88  .ErrRequestCounter = 0,
89  .counter = 0,
90 };
91 
92 /*========== Extern Constant and Variable Definitions =======================*/
93 
94 /*========== Static Function Prototypes =====================================*/
96 /* static ILCK_STATE_REQUEST_e ILCK_GetStateRequest(void); */ /* Kept for compatibility */
98 static uint8_t ILCK_CheckReEntrance(void);
99 static void ILCK_CheckFeedback(void);
104 static void ILCK_Init_Pins(void);
105 
106 /*========== Static Function Implementations ================================*/
107 /**
108  * @brief checks the state requests that are made.
109  *
110  * This function checks the validity of the state requests.
111  * The results of the checked is returned immediately.
112  *
113  * @param statereq state request to be checked
114  *
115  * @return result of the state request that was made, taken from ILCK_RETURN_TYPE_e
116  */
118  if (statereq == ILCK_STATE_ERROR_REQUEST) {
119  return ILCK_OK;
120  }
121 
123  /* init only allowed from the uninitialized state */
124  if (statereq == ILCK_STATE_INIT_REQUEST) {
126  return ILCK_OK;
127  } else {
129  }
130  }
131 
132  if ((statereq == ILCK_STATE_OPEN_REQUEST) || (statereq == ILCK_STATE_CLOSE_REQUEST)) {
133  return ILCK_OK;
134  } else {
135  return ILCK_ILLEGAL_REQUEST;
136  }
137  } else {
138  return ILCK_REQUEST_PENDING;
139  }
140 }
141 
142 /* TODO: check if code still necessary */
143 /**
144  * @brief gets the current state request.
145  * @details This function is used in the functioning of the ILCK state machine.
146  * It is kept as comment for compatibility.
147  * @return retval current state request, taken from #ILCK_STATE_REQUEST_e
148  */
149 /* static ILCK_STATE_REQUEST_e ILCK_GetStateRequest(void) {
150  ILCK_STATE_REQUEST_e retval = ILCK_STATE_NO_REQUEST;
151 
152  OS_EnterTaskCritical();
153  retval = ilck_state.statereq;
154  OS_ExitTaskCritical();
155 
156  return retval;
157 } */
158 
159 /**
160  * @brief transfers the current state request to the state machine.
161  *
162  * This function takes the current state request from ilck_state and transfers it to the state machine.
163  * It resets the value from ilck_state to ILCK_STATE_NO_REQUEST
164  *
165  * @return retVal current state request, taken from ILCK_STATE_REQUEST_e
166  */
169 
171  retval = ilck_state.statereq;
174 
175  return retval;
176 }
177 
178 /**
179  * @brief re-entrance check of ILCK state machine trigger function
180  *
181  * This function is not re-entrant and should only be called time- or event-triggered.
182  * It increments the triggerentry counter from the state variable ilck_state.
183  * It should never be called by two different processes, so if it is the case, triggerentry
184  * should never be higher than 0 when this function is called.
185  *
186  * @return retval 0 if no further instance of the function is active, 0xff else
187  */
188 static uint8_t ILCK_CheckReEntrance(void) {
189  uint8_t retval = 0;
190 
192  if (!ilck_state.triggerentry) {
194  } else {
195  retval = 0xFF; /* multiple calls of function */
196  }
198 
199  return retval;
200 }
201 
202 /**
203  * @brief checks interlock feedback
204  * @details This function is used to check interlock feedback.
205  */
206 static void ILCK_CheckFeedback(void) {
207  STD_RETURN_TYPE_e result = STD_NOT_OK;
209 
211  ilckfeedback_tab.interlockFeedback = interlockFeedback;
212 
213  DATA_WRITE_DATA(&ilckfeedback_tab);
214 
215  if (interlockFeedback == ILCK_GetInterlockSetValue()) {
216  result = STD_OK;
217  }
219 }
220 
221 /**
222  * @brief Gets the latest value (#ILCK_SWITCH_ON, #ILCK_SWITCH_OFF) the interlock was set to.
223  *
224  * Meaning of the return value:
225  * - #ILCK_SWITCH_OFF means interlock was set to be opened
226  * - #ILCK_SWITCH_ON means interlock was set to be closed
227  *
228  * @return setInformation (type: #ILCK_ELECTRICAL_STATE_TYPE_e)
229  */
231  ILCK_ELECTRICAL_STATE_TYPE_e interlockSetInformation = ILCK_SWITCH_UNDEF;
233  interlockSetInformation = ilck_interlock_state.set;
235  return interlockSetInformation;
236 }
237 
238 /**
239  * @brief Sets the interlock state to its requested state, if the interlock is at that time not in the requested state.
240  * It returns #STD_OK if the requested state was successfully set or if the interlock was at the requested state before.
241  * @param requestedInterlockState open or close interlock
242  * @return retVal #STD_OK if no error, #STD_NOT_OK otherwise
243  */
245  STD_RETURN_TYPE_e retVal = STD_OK;
246 
247  if (requestedInterlockState == ILCK_SWITCH_ON) {
249  /* gioSetBit(ILCK_IO_REG, ilck_interlock_config.control_pin, 1); */ /* TODO: activate if pin wired correctly on HW */
250  } else if (requestedInterlockState == ILCK_SWITCH_OFF) {
252  /* gioSetBit(ILCK_IO_REG, ilck_interlock_config.control_pin, 0); */ /* TODO: activate if pin wired correctly on HW */
253  } else {
254  retVal = STD_NOT_OK;
255  }
256 
257  return retVal;
258 }
259 
260 /**
261  * @brief Switches the interlock off and returns #STD_NOT_OK on success.
262  * @return retVal (type: #STD_RETURN_TYPE_e)
263  */
265  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
267  return retVal;
268 }
269 
270 /**
271  * @brief Switches the interlock on and returns STD_OK on success.
272  * @return retVal (type: #STD_RETURN_TYPE_e)
273  */
275  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
277  return retVal;
278 }
279 
280 /** initializes the pins of the interlock to default state */
281 static void ILCK_Init_Pins(void) {
282  gioSetBit(ILCK_IO_REG, ILCK_INTERLOCK_CONTROL, 1u);
283  gioSetBit(ILCK_IO_REG, ILCK_INTERLOCK_FEEDBACK, 0u);
284 }
285 
286 /*========== Extern Function Implementations ================================*/
288  ILCK_ELECTRICAL_STATE_TYPE_e measuredInterlockState = ILCK_SWITCH_UNDEF;
289  uint8_t pinstate = 0U;
291  pinstate = gioGetBit(ILCK_IO_REG, ilck_interlock_config.feedback_pin);
293  if (pinstate == 1U) {
294  measuredInterlockState = ILCK_SWITCH_ON;
295  } else if (pinstate == 0U) {
296  measuredInterlockState = ILCK_SWITCH_OFF;
297  }
298  ilck_interlock_state.feedback = measuredInterlockState;
299  return measuredInterlockState;
300 }
301 
303  return ilck_state.state;
304 }
305 
307  ILCK_RETURN_TYPE_e retVal = ILCK_OK;
308 
310  retVal = ILCK_CheckStateRequest(statereq);
311 
312  if (retVal == ILCK_OK) {
313  ilck_state.statereq = statereq;
314  }
316 
317  return retVal;
318 }
319 
320 void ILCK_Trigger(void) {
322 
323  /* Check re-entrance of function */
324  if (ILCK_CheckReEntrance() > 0u) {
325  return;
326  }
327 
328  /****Happens every time the state machine is triggered**************/
331  }
332 
333  if (ilck_state.timer > 0u) {
334  if ((--ilck_state.timer) > 0u) {
336  return; /* handle state machine only if timer has elapsed */
337  }
338  }
339 
340  switch (ilck_state.state) {
341  /****************************UNINITIALIZED***********************************/
343  /* waiting for Initialization Request */
344  statereq = ILCK_TransferStateRequest();
345  if (statereq == ILCK_STATE_INIT_REQUEST) {
347  ILCK_Init_Pins();
351  } else if (statereq == ILCK_STATE_NO_REQUEST) {
352  /* no actual request pending */
353  } else {
354  ilck_state.ErrRequestCounter++; /* illegal request pending */
355  }
356  break;
357 
358  /****************************INITIALIZATION**********************************/
362 
366  break;
367 
368  /****************************INITIALIZED*************************************/
374  break;
375 
376  /****************************INITIALIZED*************************************/
379  statereq = ILCK_TransferStateRequest();
380  if (statereq == ILCK_STATE_OPEN_REQUEST) {
384  } else if (statereq == ILCK_STATE_CLOSE_REQUEST) {
388  } else {
390  }
391  break;
392 
393  /****************************OPEN*************************************/
394  case ILCK_STATEMACH_OPEN:
398  statereq = ILCK_TransferStateRequest();
399  if (statereq == ILCK_STATE_CLOSE_REQUEST) {
403  break;
404  }
405  break;
406 
407  /****************************CLOSED*************************************/
412  statereq = ILCK_TransferStateRequest();
413  if (statereq == ILCK_STATE_OPEN_REQUEST) {
417  break;
418  }
419  break;
420 
421  default:
422  /* this is an undefined state that should never be reached */
424  break;
425  } /* end switch (ilck_state.state) */
426 
428 }
429 
430 /*================== Setter for static Variables (Unit Test) ==============*/
431 #ifdef UNITY_UNIT_TEST
432 extern void TEST_ILCK_SetStateStruct(ILCK_STATE_s state) {
433  ilck_state = state;
434 }
435 #endif
436 
437 /*========== Externalized Static Function Implementations (Unit Test) =======*/
Database module header.
#define DATA_WRITE_DATA(...)
Definition: database.h:86
@ DATA_BLOCK_ID_INTERLOCK_FEEDBACK
Definition: database_cfg.h:85
STD_RETURN_TYPE_e DIAG_CheckEvent(STD_RETURN_TYPE_e cond, DIAG_ID_e diag_id, DIAG_IMPACT_LEVEL_e impact, uint32_t data)
DIAG_CheckEvent provides a simple interface to check an event for STD_OK.
Definition: diag.c:353
Diagnosis driver header.
@ DIAG_SYSTEM
Definition: diag_cfg.h:247
@ DIAG_ID_INTERLOCK_FEEDBACK
Definition: diag_cfg.h:211
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:237
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:108
@ STD_NOT_OK
Definition: fstd_types.h:73
@ STD_OK
Definition: fstd_types.h:72
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
static STD_RETURN_TYPE_e ILCK_SetInterlockState(ILCK_ELECTRICAL_STATE_TYPE_e requestedInterlockState)
Sets the interlock state to its requested state, if the interlock is at that time not in the requeste...
Definition: interlock.c:244
static ILCK_ELECTRICAL_STATE_TYPE_e ILCK_GetInterlockSetValue(void)
Gets the latest value (ILCK_SWITCH_ON, ILCK_SWITCH_OFF) the interlock was set to.
Definition: interlock.c:230
#define ILCK_SAVELASTSTATES()
Definition: interlock.c:67
static void ILCK_Init_Pins(void)
Definition: interlock.c:281
static void ILCK_CheckFeedback(void)
checks interlock feedback
Definition: interlock.c:206
#define ILCK_OPENINTERLOCK()
Definition: interlock.c:74
static ILCK_STATE_s ilck_state
Definition: interlock.c:80
static STD_RETURN_TYPE_e ILCK_SwitchInterlockOff(void)
Switches the interlock off and returns STD_NOT_OK on success.
Definition: interlock.c:264
static uint8_t ILCK_CheckReEntrance(void)
re-entrance check of ILCK state machine trigger function
Definition: interlock.c:188
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:306
void ILCK_Trigger(void)
trigger function for the ILCK driver state machine.
Definition: interlock.c:320
static ILCK_STATE_REQUEST_e ILCK_TransferStateRequest(void)
gets the current state request.
Definition: interlock.c:167
#define ILCK_CLOSEINTERLOCK()
Definition: interlock.c:72
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:287
ILCK_STATEMACH_e ILCK_GetState(void)
gets the current state.
Definition: interlock.c:302
static ILCK_RETURN_TYPE_e ILCK_CheckStateRequest(ILCK_STATE_REQUEST_e statereq)
checks the state requests that are made.
Definition: interlock.c:117
static STD_RETURN_TYPE_e ILCK_SwitchInterlockOn(void)
Switches the interlock on and returns STD_OK on success.
Definition: interlock.c:274
Headers for the driver for the interlock.
ILCK_STATEMACH_e
Definition: interlock.h:65
@ ILCK_STATEMACH_UNINITIALIZED
Definition: interlock.h:67
@ ILCK_STATEMACH_OPEN
Definition: interlock.h:71
@ ILCK_STATEMACH_CLOSED
Definition: interlock.h:72
@ ILCK_STATEMACH_INITIALIZED
Definition: interlock.h:69
@ ILCK_STATEMACH_WAIT_FIRST_REQUEST
Definition: interlock.h:70
@ ILCK_STATEMACH_INITIALIZATION
Definition: interlock.h:68
ILCK_RETURN_TYPE_e
Definition: interlock.h:98
@ ILCK_ALREADY_INITIALIZED
Definition: interlock.h:105
@ ILCK_ILLEGAL_REQUEST
Definition: interlock.h:102
@ ILCK_OK
Definition: interlock.h:99
@ ILCK_REQUEST_PENDING
Definition: interlock.h:101
@ ILCK_ENTRY
Definition: interlock.h:81
ILCK_STATE_REQUEST_e
Definition: interlock.h:87
@ ILCK_STATE_NO_REQUEST
Definition: interlock.h:92
@ ILCK_STATE_OPEN_REQUEST
Definition: interlock.h:89
@ ILCK_STATE_INIT_REQUEST
Definition: interlock.h:88
@ ILCK_STATE_ERROR_REQUEST
Definition: interlock.h:91
@ ILCK_STATE_CLOSE_REQUEST
Definition: interlock.h:90
ILCK_ELECTRICAL_STATE_s ilck_interlock_state
Definition: interlock_cfg.c:64
ILCK_CONFIG_s ilck_interlock_config
Definition: interlock_cfg.c:62
#define ILCK_INTERLOCK_FEEDBACK
Definition: interlock_cfg.h:79
@ ILCK_SWITCH_ON
Definition: interlock_cfg.h:97
@ ILCK_SWITCH_UNDEF
Definition: interlock_cfg.h:98
@ ILCK_SWITCH_OFF
Definition: interlock_cfg.h:96
#define ILCK_INTERLOCK_CONTROL
Definition: interlock_cfg.h:76
enum ILCK_ELECTRICAL_STATE_TYPE ILCK_ELECTRICAL_STATE_TYPE_e
#define ILCK_IO_REG
Definition: interlock_cfg.h:65
#define ILCK_STATEMACH_SHORTTIME_MS
Definition: interlock_cfg.h:92
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:178
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:174
Implementation of the tasks used by the system, headers.
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:110
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:383
uint32_t feedback_pin
ILCK_ELECTRICAL_STATE_TYPE_e feedback
ILCK_ELECTRICAL_STATE_TYPE_e set
uint32_t ErrRequestCounter
Definition: interlock.h:125
uint8_t triggerentry
Definition: interlock.h:126
ILCK_STATE_REQUEST_e statereq
Definition: interlock.h:116
ILCK_STATEMACH_e state
Definition: interlock.h:118
uint16_t timer
Definition: interlock.h:114
ILCK_STATEMACH_SUB_e substate
Definition: interlock.h:120