foxBMS-UnitTests  1.0.0
The foxBMS Unit Tests API Documentation
interlock.c
Go to the documentation of this file.
1 /**
2  *
3  * @copyright © 2010 - 2021, Fraunhofer-Gesellschaft zur Foerderung der
4  * angewandten Forschung e.V. All rights reserved.
5  *
6  * BSD 3-Clause License
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * We kindly request you to use one or more of the following phrases to refer
31  * to foxBMS in your hardware, software, documentation or advertising
32  * materials:
33  *
34  * ″This product uses parts of foxBMS®″
35  *
36  * ″This product includes parts of foxBMS®″
37  *
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
433  ilck_state = state;
434  return;
435 }
436 #endif
437 
438 /*========== Externalized Static Function Implementations (Unit Test) =======*/
ILCK_SWITCH_ON
@ ILCK_SWITCH_ON
Definition: interlock_cfg.h:97
os.h
Implementation of the tasks used by the system, headers.
ILCK_CONFIG::feedback_pin
uint32_t feedback_pin
Definition: interlock_cfg.h:121
DATA_BLOCK_INTERLOCK_FEEDBACK::header
DATA_BLOCK_HEADER_s header
Definition: database_cfg.h:379
ILCK_SetInterlockState
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
ILCK_SWITCH_UNDEF
@ ILCK_SWITCH_UNDEF
Definition: interlock_cfg.h:98
ILCK_STATE_s::timer
uint16_t timer
Definition: interlock.h:114
ILCK_STATEMACH_OPEN
@ ILCK_STATEMACH_OPEN
Definition: interlock.h:71
ILCK_SwitchInterlockOn
static STD_RETURN_TYPE_e ILCK_SwitchInterlockOn(void)
Switches the interlock on and returns STD_OK on success.
Definition: interlock.c:274
ILCK_CheckFeedback
static void ILCK_CheckFeedback(void)
checks interlock feedback
Definition: interlock.c:206
STD_RETURN_TYPE_e
enum STD_RETURN_TYPE STD_RETURN_TYPE_e
ILCK_CheckStateRequest
static ILCK_RETURN_TYPE_e ILCK_CheckStateRequest(ILCK_STATE_REQUEST_e statereq)
checks the state requests that are made.
Definition: interlock.c:117
ILCK_STATE_s::ErrRequestCounter
uint32_t ErrRequestCounter
Definition: interlock.h:125
ILCK_STATE_s
Definition: interlock.h:113
diag.h
Diagnosis driver header.
ILCK_STATE_s::substate
ILCK_STATEMACH_SUB_e substate
Definition: interlock.h:120
DATA_WRITE_DATA
#define DATA_WRITE_DATA(...)
Definition: database.h:82
ILCK_STATEMACH_UNINITIALIZED
@ ILCK_STATEMACH_UNINITIALIZED
Definition: interlock.h:67
ILCK_STATE_ERROR_REQUEST
@ ILCK_STATE_ERROR_REQUEST
Definition: interlock.h:91
ILCK_ELECTRICAL_STATE::feedback
ILCK_ELECTRICAL_STATE_TYPE_e feedback
Definition: interlock_cfg.h:113
ILCK_SWITCH_OFF
@ ILCK_SWITCH_OFF
Definition: interlock_cfg.h:96
ILCK_STATE_s::state
ILCK_STATEMACH_e state
Definition: interlock.h:118
ILCK_STATE_INIT_REQUEST
@ ILCK_STATE_INIT_REQUEST
Definition: interlock.h:88
ILCK_STATEMACH_e
ILCK_STATEMACH_e
Definition: interlock.h:65
ILCK_STATEMACH_CLOSED
@ ILCK_STATEMACH_CLOSED
Definition: interlock.h:72
ILCK_CheckReEntrance
static uint8_t ILCK_CheckReEntrance(void)
re-entrance check of ILCK state machine trigger function
Definition: interlock.c:188
ILCK_INTERLOCK_FEEDBACK
#define ILCK_INTERLOCK_FEEDBACK
Definition: interlock_cfg.h:79
ILCK_GetInterlockSetValue
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
FAS_ASSERT
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:233
OS_ExitTaskCritical
void OS_ExitTaskCritical(void)
Exit Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:178
ILCK_OPENINTERLOCK
#define ILCK_OPENINTERLOCK()
Definition: interlock.c:74
ILCK_STATE_s::statereq
ILCK_STATE_REQUEST_e statereq
Definition: interlock.h:116
ILCK_ENTRY
@ ILCK_ENTRY
Definition: interlock.h:81
ILCK_TransferStateRequest
static ILCK_STATE_REQUEST_e ILCK_TransferStateRequest(void)
gets the current state request.
Definition: interlock.c:167
STD_OK
@ STD_OK
Definition: fstd_types.h:72
DIAG_SYSTEM
@ DIAG_SYSTEM
Definition: diag_cfg.h:214
ILCK_STATEMACH_WAIT_FIRST_REQUEST
@ ILCK_STATEMACH_WAIT_FIRST_REQUEST
Definition: interlock.h:70
ILCK_SwitchInterlockOff
static STD_RETURN_TYPE_e ILCK_SwitchInterlockOff(void)
Switches the interlock off and returns STD_NOT_OK on success.
Definition: interlock.c:264
OS_EnterTaskCritical
void OS_EnterTaskCritical(void)
Enter Critical interface function for use in FreeRTOS-Tasks and FreeRTOS-ISR.
Definition: os.c:174
DIAG_CheckEvent
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:326
STD_NOT_OK
@ STD_NOT_OK
Definition: fstd_types.h:73
ILCK_Trigger
void ILCK_Trigger(void)
trigger function for the ILCK driver state machine.
Definition: interlock.c:320
ilck_interlock_state
ILCK_ELECTRICAL_STATE_s ilck_interlock_state
Definition: interlock_cfg.c:64
ILCK_ELECTRICAL_STATE::set
ILCK_ELECTRICAL_STATE_TYPE_e set
Definition: interlock_cfg.h:112
ILCK_ELECTRICAL_STATE_TYPE_e
enum ILCK_ELECTRICAL_STATE_TYPE ILCK_ELECTRICAL_STATE_TYPE_e
ILCK_GetState
ILCK_STATEMACH_e ILCK_GetState(void)
gets the current state.
Definition: interlock.c:302
ILCK_SetStateRequest
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
DIAG_ID_INTERLOCK_FEEDBACK
@ DIAG_ID_INTERLOCK_FEEDBACK
Definition: diag_cfg.h:178
ILCK_Init_Pins
static void ILCK_Init_Pins(void)
Definition: interlock.c:281
DATA_BLOCK_INTERLOCK_FEEDBACK::interlockFeedback
uint8_t interlockFeedback
Definition: database_cfg.h:380
ILCK_SAVELASTSTATES
#define ILCK_SAVELASTSTATES()
Definition: interlock.c:67
ILCK_STATE_s::triggerentry
uint8_t triggerentry
Definition: interlock.h:126
ILCK_RETURN_TYPE_e
ILCK_RETURN_TYPE_e
Definition: interlock.h:98
ILCK_STATEMACH_INITIALIZED
@ ILCK_STATEMACH_INITIALIZED
Definition: interlock.h:69
ILCK_STATEMACH_SHORTTIME_MS
#define ILCK_STATEMACH_SHORTTIME_MS
Definition: interlock_cfg.h:92
DATA_BLOCK_INTERLOCK_FEEDBACK
Definition: database_cfg.h:375
database.h
Database module header.
DATA_BLOCK_ID_INTERLOCK_FEEDBACK
@ DATA_BLOCK_ID_INTERLOCK_FEEDBACK
Definition: database_cfg.h:85
ilck_state
static ILCK_STATE_s ilck_state
Definition: interlock.c:80
ILCK_REQUEST_PENDING
@ ILCK_REQUEST_PENDING
Definition: interlock.h:101
ILCK_CLOSEINTERLOCK
#define ILCK_CLOSEINTERLOCK()
Definition: interlock.c:72
ILCK_STATE_CLOSE_REQUEST
@ ILCK_STATE_CLOSE_REQUEST
Definition: interlock.h:90
ILCK_INTERLOCK_CONTROL
#define ILCK_INTERLOCK_CONTROL
Definition: interlock_cfg.h:76
ILCK_IO_REG
#define ILCK_IO_REG
Definition: interlock_cfg.h:65
ILCK_OK
@ ILCK_OK
Definition: interlock.h:99
ILCK_GetInterlockFeedback
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_STATE_NO_REQUEST
@ ILCK_STATE_NO_REQUEST
Definition: interlock.h:92
ILCK_STATE_OPEN_REQUEST
@ ILCK_STATE_OPEN_REQUEST
Definition: interlock.h:89
FAS_TRAP
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:108
TEST_ILCK_SetStateStruct
void TEST_ILCK_SetStateStruct(ILCK_STATE_s state)
Definition: interlock.c:432
interlock.h
Headers for the driver for the interlock.
ILCK_STATEMACH_INITIALIZATION
@ ILCK_STATEMACH_INITIALIZATION
Definition: interlock.h:68
ILCK_ALREADY_INITIALIZED
@ ILCK_ALREADY_INITIALIZED
Definition: interlock.h:105
ILCK_ILLEGAL_REQUEST
@ ILCK_ILLEGAL_REQUEST
Definition: interlock.h:102
ilck_interlock_config
ILCK_CONFIG_s ilck_interlock_config
Definition: interlock_cfg.c:62
ILCK_STATE_REQUEST_e
ILCK_STATE_REQUEST_e
Definition: interlock.h:87
DATA_BLOCKHEADER::uniqueId
DATA_BLOCK_ID_e uniqueId
Definition: database_cfg.h:109