foxBMS  1.6.0
The foxBMS Battery Management System API Documentation
contactor.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 contactor.c
44  * @author foxBMS Team
45  * @date 2020-02-11 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVERS
49  * @prefix CONT
50  *
51  * @brief Driver for the contactors.
52  *
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "contactor.h"
57 
58 #include "diag.h"
59 #include "fassert.h"
60 #include "fstd_types.h"
61 #include "mcu.h"
62 #include "sps.h"
63 
64 #include <stdint.h>
65 
66 /*========== Macros and Definitions =========================================*/
67 
68 /*========== Static Constant and Variable Definitions =======================*/
69 
70 /*========== Extern Constant and Variable Definitions =======================*/
71 
72 /*========== Static Function Prototypes =====================================*/
73 /**
74  * @brief Reads the feedback of all contactors
75  * @details Gathers the feedback of all contactors from the configured feedback
76  * source (#CONT_FEEDBACK_TYPE_e). If #CONT_HAS_NO_FEEDBACK is
77  * configured,it is assumed that the contactor has reached the
78  * requested state.
79  */
80 static void CONT_GetFeedbackOfAllContactors(void);
81 
82 /** conducts an initialization test of the contactor registry and asserts at failure */
84 
85 /*========== Static Function Implementations ================================*/
87  /* Iterate over all contactors */
88  for (CONT_CONTACTOR_INDEX contactor = 0; contactor < BS_NR_OF_CONTACTORS; contactor++) {
89  /* Use different feedback sources depending on the individual contactor configuration */
90  if (cont_contactorStates[contactor].feedbackPinType == CONT_HAS_NO_FEEDBACK) {
91  /* no feedback: assume set value is true */
93  } else if (cont_contactorStates[contactor].feedbackPinType == CONT_FEEDBACK_THROUGH_CURRENT) {
94  /* feedback from current: ask SPS driver for feedback */
95  cont_contactorStates[contactor].feedback =
97  } else if (CONT_FEEDBACK_NORMALLY_OPEN == cont_contactorStates[contactor].feedbackPinType) {
98  cont_contactorStates[contactor].feedback =
99  SPS_GetChannelPexFeedback(cont_contactorStates[contactor].spsChannel, true);
100  } else {
101  /* CONT_FEEDBACK_NORMALLY_CLOSED */
102  cont_contactorStates[contactor].feedback =
103  SPS_GetChannelPexFeedback(cont_contactorStates[contactor].spsChannel, false);
104  }
105  }
106 }
107 
109  /* Iterate over each contactor and compare found name with resolved name (if a name is used double this would
110  always return the first entry and we would have the second entry from iterating here) */
111  for (CONT_CONTACTOR_INDEX contactor = 0u; contactor < BS_NR_OF_CONTACTORS; contactor++) {
112  /* TODO: add check that only one contactor of each type is configured for each string */
113 
114  /* Check that a configured SPS channel number is not higher than the number of available SPS channels */
116 
117  /* every contactor channel has to be affiliated with contactor */
118  const SPS_CHANNEL_AFFILIATION_e channelAffiliation =
119  SPS_GetChannelAffiliation(cont_contactorStates[contactor].spsChannel);
120  FAS_ASSERT(SPS_AFF_CONTACTOR == channelAffiliation);
121  }
122 }
123 
124 /*========== Extern Function Implementations ================================*/
125 extern void CONT_CheckFeedback(void) {
126  /* Get the feedback from all contactors from the configured feedback sources */
128  /* Check the contactor feedback */
129  for (CONT_CONTACTOR_INDEX contactor = 0u; contactor < BS_NR_OF_CONTACTORS; contactor++) {
130  /* TODO: add check that only one contactor of each type is configured for each string */
131  DIAG_EVENT_e feedbackStatus = DIAG_EVENT_NOT_OK;
132  if (cont_contactorStates[contactor].currentSet == cont_contactorStates[contactor].feedback) {
133  /* Set feedback status to okay, if expected and actual contactor state match */
134  feedbackStatus = DIAG_EVENT_OK;
135  }
136  switch (cont_contactorStates[contactor].type) {
137  case CONT_PLUS:
138  DIAG_Handler(
140  feedbackStatus,
141  DIAG_STRING,
142  (uint8_t)cont_contactorStates[contactor].stringIndex);
143  break;
144  case CONT_MINUS:
145  DIAG_Handler(
147  feedbackStatus,
148  DIAG_STRING,
149  (uint8_t)cont_contactorStates[contactor].stringIndex);
150  break;
151  case CONT_PRECHARGE:
152  DIAG_Handler(
154  feedbackStatus,
155  DIAG_STRING,
156  (uint8_t)cont_contactorStates[contactor].stringIndex);
157  break;
158  default:
159  /* Type: CONT_UNDEFINED -> trap */
161  }
162  }
163 }
164 
165 extern STD_RETURN_TYPE_e CONT_OpenContactor(uint8_t stringNumber, CONT_TYPE_e contactor) {
166  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
167  FAS_ASSERT(contactor != CONT_UNDEFINED);
168  STD_RETURN_TYPE_e retval = STD_NOT_OK;
169  /* Iterate over contactor array, find the correct one and request state change via SPS module */
170  for (uint8_t contactorIndex = 0u; contactorIndex < BS_NR_OF_CONTACTORS; contactorIndex++) {
171  if (((BS_STRING_ID_e)stringNumber == cont_contactorStates[contactorIndex].stringIndex) &&
172  (contactor == cont_contactorStates[contactorIndex].type)) {
173  /* Set set state in cont_contactorStates array */
175  /* Request contactor state via SPS module */
177  retval = STD_OK;
178  break;
179  }
180  }
181  return retval;
182 }
183 
184 extern STD_RETURN_TYPE_e CONT_CloseContactor(uint8_t stringNumber, CONT_TYPE_e contactor) {
185  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
186  FAS_ASSERT(contactor != CONT_UNDEFINED);
187  STD_RETURN_TYPE_e retval = STD_NOT_OK;
188  /* Iterate over contactor array, find the correct one and request state change via SPS module */
189  for (uint8_t contactorIndex = 0u; contactorIndex < BS_NR_OF_CONTACTORS; contactorIndex++) {
190  if (((BS_STRING_ID_e)stringNumber == cont_contactorStates[contactorIndex].stringIndex) &&
191  (contactor == cont_contactorStates[contactorIndex].type)) {
192  /* Set set state in cont_contactorStates array */
194  /* Request contactor state via SPS module */
196  retval = STD_OK;
197  break;
198  }
199  }
200  return retval;
201 }
202 
203 extern STD_RETURN_TYPE_e CONT_ClosePrecharge(uint8_t stringNumber) {
204  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
205  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
206  /* Check if passed string has configured a precharge contactor */
207  if (bs_stringsWithPrecharge[stringNumber] == BS_STRING_WITH_PRECHARGE) {
208  retVal = CONT_CloseContactor(stringNumber, CONT_PRECHARGE);
209  }
210  return retVal;
211 }
212 
213 extern STD_RETURN_TYPE_e CONT_OpenPrecharge(uint8_t stringNumber) {
214  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
215  STD_RETURN_TYPE_e retVal = STD_NOT_OK;
216  /* Check if passed string has configured a precharge contactor */
217  if (bs_stringsWithPrecharge[stringNumber] == BS_STRING_WITH_PRECHARGE) {
218  retVal = CONT_OpenContactor(stringNumber, CONT_PRECHARGE);
219  }
220  return retVal;
221 }
222 
224  /* Iterate over all contactors and open all precharge contactors */
225  for (uint8_t contactorIndex = 0u; contactorIndex < BS_NR_OF_CONTACTORS; contactorIndex++) {
226  /* Set off a request to open all precharge contactors regardless of
227  * their current state as we want to reach a safe state */
228  if (cont_contactorStates[contactorIndex].type == CONT_PRECHARGE) {
229  /* Request opening via SPS module */
232  }
233  }
234 }
235 
236 extern CONT_ELECTRICAL_STATE_TYPE_e CONT_GetContactorState(uint8_t stringNumber, CONT_TYPE_e contactorType) {
237  FAS_ASSERT(stringNumber < BS_NR_OF_STRINGS);
238  FAS_ASSERT(contactorType != CONT_UNDEFINED);
240  /* Iterate over all contactors and return the requested feedback */
241  for (uint8_t contactorIndex = 0u; contactorIndex < BS_NR_OF_CONTACTORS; contactorIndex++) {
242  if ((cont_contactorStates[contactorIndex].stringIndex == (BS_STRING_ID_e)stringNumber) &&
243  (contactorType == cont_contactorStates[contactorIndex].type)) {
244  feedback = cont_contactorStates[contactorIndex].feedback;
245  break;
246  }
247  }
248  return feedback;
249 }
250 
251 extern void CONT_Initialize(void) {
253 }
254 
255 /*========== Externalized Static Function Implementations (Unit Test) =======*/
256 #ifdef UNITY_UNIT_TEST
257 extern void TEST_CONT_InitializationCheckOfContactorRegistry() {
259 }
260 #endif
BS_STRING_PRECHARGE_PRESENT_e bs_stringsWithPrecharge[BS_NR_OF_STRINGS]
#define BS_NR_OF_STRINGS
Number of parallel strings in the battery pack.
@ BS_STRING_WITH_PRECHARGE
BS_STRING_ID_e
#define BS_NR_OF_CONTACTORS
void CONT_CheckFeedback(void)
checks the feedback of all contactors
Definition: contactor.c:125
STD_RETURN_TYPE_e CONT_CloseContactor(uint8_t stringNumber, CONT_TYPE_e contactor)
Closes the contactor.
Definition: contactor.c:184
static void CONT_InitializationCheckOfContactorRegistry(void)
Definition: contactor.c:108
static void CONT_GetFeedbackOfAllContactors(void)
Reads the feedback of all contactors.
Definition: contactor.c:86
STD_RETURN_TYPE_e CONT_OpenPrecharge(uint8_t stringNumber)
Opens precharge.
Definition: contactor.c:213
STD_RETURN_TYPE_e CONT_OpenContactor(uint8_t stringNumber, CONT_TYPE_e contactor)
Opens the contactor.
Definition: contactor.c:165
CONT_ELECTRICAL_STATE_TYPE_e CONT_GetContactorState(uint8_t stringNumber, CONT_TYPE_e contactorType)
Returns the current contactor state.
Definition: contactor.c:236
void CONT_OpenAllPrechargeContactors(void)
Open all currently closed precharge contactors.
Definition: contactor.c:223
STD_RETURN_TYPE_e CONT_ClosePrecharge(uint8_t stringNumber)
Closes precharge.
Definition: contactor.c:203
void CONT_Initialize(void)
initializes the contactor module
Definition: contactor.c:251
Headers for the driver for the contactors.
CONT_CONTACTOR_STATE_s cont_contactorStates[BS_NR_OF_CONTACTORS]
Definition: contactor_cfg.c:67
@ CONT_HAS_NO_FEEDBACK
Definition: contactor_cfg.h:81
@ CONT_FEEDBACK_THROUGH_CURRENT
Definition: contactor_cfg.h:80
@ CONT_FEEDBACK_NORMALLY_OPEN
Definition: contactor_cfg.h:78
CONT_TYPE_e
Definition: contactor_cfg.h:85
@ CONT_UNDEFINED
Definition: contactor_cfg.h:89
@ CONT_PRECHARGE
Definition: contactor_cfg.h:88
@ CONT_MINUS
Definition: contactor_cfg.h:87
@ CONT_PLUS
Definition: contactor_cfg.h:86
uint8_t CONT_CONTACTOR_INDEX
CONT_ELECTRICAL_STATE_TYPE_e
Definition: contactor_cfg.h:70
@ CONT_SWITCH_UNDEFINED
Definition: contactor_cfg.h:73
@ CONT_SWITCH_ON
Definition: contactor_cfg.h:72
@ CONT_SWITCH_OFF
Definition: contactor_cfg.h:71
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_e
Definition: diag_cfg.h:266
@ DIAG_EVENT_NOT_OK
Definition: diag_cfg.h:268
@ DIAG_EVENT_OK
Definition: diag_cfg.h:267
@ DIAG_STRING
Definition: diag_cfg.h:281
@ DIAG_ID_STRING_PLUS_CONTACTOR_FEEDBACK
Definition: diag_cfg.h:234
@ DIAG_ID_STRING_MINUS_CONTACTOR_FEEDBACK
Definition: diag_cfg.h:233
@ DIAG_ID_PRECHARGE_CONTACTOR_FEEDBACK
Definition: diag_cfg.h:235
Assert macro implementation.
#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
Definition of foxBMS standard types.
STD_RETURN_TYPE_e
Definition: fstd_types.h:82
@ STD_NOT_OK
Definition: fstd_types.h:84
@ STD_OK
Definition: fstd_types.h:83
Headers for the driver for the MCU module.
CONT_ELECTRICAL_STATE_TYPE_e SPS_GetChannelPexFeedback(const SPS_CHANNEL_INDEX channelIndex, bool normallyOpen)
Get the feedback state of a channel.
Definition: sps.c:636
SPS_CHANNEL_AFFILIATION_e SPS_GetChannelAffiliation(SPS_CHANNEL_INDEX channelIndex)
Returns the channel affiliation.
Definition: sps.c:659
CONT_ELECTRICAL_STATE_TYPE_e SPS_GetChannelCurrentFeedback(const SPS_CHANNEL_INDEX channelIndex)
Get feedback value.
Definition: sps.c:620
void SPS_RequestContactorState(SPS_CHANNEL_INDEX channelIndex, SPS_CHANNEL_FUNCTION_e channelFunction)
Request state of a contactor.
Definition: sps.c:602
Headers for the driver for the smart power switches.
#define SPS_NR_OF_AVAILABLE_SPS_CHANNELS
Definition: sps_cfg.h:102
@ SPS_CHANNEL_ON
Definition: sps_cfg.h:188
@ SPS_CHANNEL_OFF
Definition: sps_cfg.h:187
SPS_CHANNEL_AFFILIATION_e
affiliation type of a sps channel
Definition: sps_types.h:73
@ SPS_AFF_CONTACTOR
Definition: sps_types.h:74
CONT_ELECTRICAL_STATE_TYPE_e currentSet
CONT_ELECTRICAL_STATE_TYPE_e feedback