foxBMS  1.4.0
The foxBMS Battery Management System API Documentation
can_cbs_rx_current_sensor.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 can_cbs_rx_current_sensor.c
44  * @author foxBMS Team
45  * @date 2021-04-20 (date of creation)
46  * @updated 2022-07-28 (date of last update)
47  * @version v1.4.0
48  * @ingroup DRIVER
49  * @prefix CAN
50  *
51  * @brief CAN driver Rx callback implementation
52  * @details CAN Rx callback for current sensor measurements
53  */
54 
55 /*========== Includes =======================================================*/
56 #include "can_cbs.h"
57 #include "can_helper.h"
58 
59 /*========== Macros and Definitions =========================================*/
60 
61 /** Overcurrent flag */
62 #define CAN_CURRENT_SENSOR_DIAGNOSIS_OVERCURRENT (0x1u)
63 /** Actual measurement error flag */
64 #define CAN_CURRENT_SENSOR_DIAGNOSIS_ACTUAL_MEASUREMENT_ERROR (0x2u)
65 /** Any measurement error flag */
66 #define CAN_CURRENT_SENSOR_DIAGNOSIS_ANY_MEASUREMENT_ERROR (0x4u)
67 /** System error flag */
68 #define CAN_CURRENT_SENSOR_DIAGNOSIS_SYSTEM_ERROR (0x8u)
69 
70 /*========== Static Constant and Variable Definitions =======================*/
71 
72 /*========== Extern Constant and Variable Definitions =======================*/
73 
74 /*========== Static Function Prototypes =====================================*/
75 
76 /*========== Static Function Implementations ================================*/
77 
78 /*========== Extern Function Implementations ================================*/
79 extern uint32_t CAN_RxCurrentSensor(
80  uint32_t id,
81  uint8_t dlc,
82  CAN_ENDIANNESS_e endianness,
83  const uint8_t *const kpkCanData,
84  const CAN_SHIM_s *const kpkCanShim) {
85  FAS_ASSERT(id < CAN_MAX_11BIT_ID); /* Currently standard ID, 11 bit */
86  FAS_ASSERT(dlc <= CAN_MAX_DLC); /* Currently max 8 bytes in a CAN frame */
87  FAS_ASSERT(kpkCanData != NULL_PTR);
88  FAS_ASSERT(kpkCanShim != NULL_PTR);
89 
90  /**
91  * CAN signals used in this message
92  * Parameters:
93  * bit start, bit length, factor, offset, minimum value, maximum value
94  */
95  const CAN_SIGNAL_TYPE_s currentSensorStatus = {7u, 8u, 1.0f, 0.0f, 0.0f, 255.0f};
96  const CAN_SIGNAL_TYPE_s currentSensorData = {23u, 32u, 1.0f, 0.0f, -2147483648.0f, 2147483648.0f};
97 
98  uint64_t message = 0u;
99  uint64_t canSignal = 0u;
100 
101  int32_t sensorSignalValue = 0;
102  uint8_t diagInfo = 0u;
103  uint8_t stringNumber = 0u;
104 
105  if (id <= CAN_ID_STRING0_ENERGY_COUNTER) {
106  stringNumber = 0u;
107  } else if (id <= CAN_ID_STRING1_ENERGY_COUNTER) {
108  stringNumber = 1u;
109  } else {
110  stringNumber = 2u;
111  }
112 
113  CAN_RxGetMessageDataFromCanData(&message, kpkCanData, endianness);
114 
115  /* Get status*/
117  message, currentSensorStatus.bitStart, currentSensorStatus.bitLength, &canSignal, endianness);
118 
119  /* only high nibble contains diag info */
120  diagInfo = canSignal & 0xF0u;
121  diagInfo >>= 4u;
122 
123  if ((diagInfo & CAN_CURRENT_SENSOR_DIAGNOSIS_OVERCURRENT) != 0u) {
124  /* Overcurrent detected. This feature is currently not supported. */
125  }
127  switch (id) {
128  case CAN_ID_STRING0_CURRENT: /* Current status */
131  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 1;
132  break;
133  case CAN_ID_STRING0_VOLTAGE1: /* Voltage status */
136  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 1;
137  break;
141  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 1;
142  break;
146  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 1;
147  break;
148  case CAN_ID_STRING0_TEMPERATURE: /* Temperature status */
151  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 1;
152  break;
153  case CAN_ID_STRING0_POWER: /* Power status */
156  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 1;
157  break;
158  case CAN_ID_STRING0_CURRENT_COUNTER: /* CC status */
161  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 1;
162  break;
163  case CAN_ID_STRING0_ENERGY_COUNTER: /* EC status */
166  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 1;
167  break;
168  default:
169  /* No error detected */
170  break;
171  }
172  } else {
173  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 0;
174  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 0;
175  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 0;
176  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 0;
177  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 0;
178  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 0;
179  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 0;
180  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 0;
181  }
182 
183  if (((diagInfo & CAN_CURRENT_SENSOR_DIAGNOSIS_ANY_MEASUREMENT_ERROR) != 0u) ||
184  ((diagInfo & CAN_CURRENT_SENSOR_DIAGNOSIS_SYSTEM_ERROR) != 0u)) {
185  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 1;
186  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 1;
187  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 1;
188  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 1;
189  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 1;
190  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 1;
191  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 1;
192  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 1;
193  }
194 
195  /* Get measurement */
197  message, currentSensorData.bitStart, currentSensorData.bitLength, &canSignal, endianness);
198  switch (id) {
199  /* Current measurement */
203  sensorSignalValue = (int32_t)canSignal;
204  kpkCanShim->pTableCurrentSensor->current_mA[stringNumber] = sensorSignalValue;
205  kpkCanShim->pTableCurrentSensor->newCurrent++;
206  kpkCanShim->pTableCurrentSensor->previousTimestampCurrent[stringNumber] =
207  kpkCanShim->pTableCurrentSensor->timestampCurrent[stringNumber];
208  kpkCanShim->pTableCurrentSensor->timestampCurrent[stringNumber] = OS_GetTickCount();
209  break;
210  /* Voltage measurement U1 */
214  sensorSignalValue = (int32_t)canSignal;
215  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][0] = sensorSignalValue;
216  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][0] =
217  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][0];
218  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][0] = OS_GetTickCount();
219  break;
220  /* Voltage measurement U2 */
224  sensorSignalValue = (int32_t)canSignal;
225  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][1] = sensorSignalValue;
226  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][1] =
227  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][1];
228  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][1] = OS_GetTickCount();
229  break;
230  /* Voltage measurement U3 */
234  sensorSignalValue = (int32_t)canSignal;
235  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][2] = sensorSignalValue;
236  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][2] =
237  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][2];
238  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][2] = OS_GetTickCount();
239  break;
240  /* Temperature measurement */
244  sensorSignalValue = (int32_t)canSignal;
245  kpkCanShim->pTableCurrentSensor->sensorTemperature_ddegC[stringNumber] = sensorSignalValue;
246  break;
247  /* Power measurement */
251  sensorSignalValue = (int32_t)canSignal;
252  kpkCanShim->pTableCurrentSensor->power_W[stringNumber] = sensorSignalValue;
253  kpkCanShim->pTableCurrentSensor->newPower++;
254  kpkCanShim->pTableCurrentSensor->previousTimestampPower[stringNumber] =
255  kpkCanShim->pTableCurrentSensor->timestampPower[stringNumber];
256  kpkCanShim->pTableCurrentSensor->timestampPower[stringNumber] = OS_GetTickCount();
257  break;
258  /* CC measurement */
262  sensorSignalValue = (int32_t)canSignal;
263  kpkCanShim->pTableCurrentSensor->previousTimestampCurrentCounting[stringNumber] =
264  kpkCanShim->pTableCurrentSensor->timestampCurrentCounting[stringNumber];
265  kpkCanShim->pTableCurrentSensor->timestampCurrentCounting[stringNumber] = OS_GetTickCount();
266  kpkCanShim->pTableCurrentSensor->currentCounter_As[stringNumber] = sensorSignalValue;
267  break;
268  /* EC measurement */
272  sensorSignalValue = (int32_t)canSignal;
273  kpkCanShim->pTableCurrentSensor->energyCounter_Wh[stringNumber] = sensorSignalValue;
274  kpkCanShim->pTableCurrentSensor->previousTimestampEnergyCounting[stringNumber] =
275  kpkCanShim->pTableCurrentSensor->timestampEnergyCounting[stringNumber];
276  kpkCanShim->pTableCurrentSensor->timestampEnergyCounting[stringNumber] = OS_GetTickCount();
277  break;
278 
279  default:
281  break;
282  }
283 
285  return 0;
286 }
287 
288 /*========== Externalized Static Function Implementations (Unit Test) =======*/
289 #ifdef UNITY_UNIT_TEST
290 
291 #endif
CAN callbacks header.
#define CAN_CURRENT_SENSOR_DIAGNOSIS_OVERCURRENT
#define CAN_CURRENT_SENSOR_DIAGNOSIS_ANY_MEASUREMENT_ERROR
uint32_t CAN_RxCurrentSensor(uint32_t id, uint8_t dlc, CAN_ENDIANNESS_e endianness, const uint8_t *const kpkCanData, const CAN_SHIM_s *const kpkCanShim)
can rx callback function for current sensor measurements
#define CAN_CURRENT_SENSOR_DIAGNOSIS_ACTUAL_MEASUREMENT_ERROR
#define CAN_CURRENT_SENSOR_DIAGNOSIS_SYSTEM_ERROR
#define CAN_ID_STRING1_VOLTAGE1
Definition: can_cfg.h:231
#define CAN_ID_STRING0_CURRENT
Definition: can_cfg.h:220
#define CAN_ID_STRING2_TEMPERATURE
Definition: can_cfg.h:244
CAN_ENDIANNESS_e
Definition: can_cfg.h:298
#define CAN_MAX_11BIT_ID
Definition: can_cfg.h:86
#define CAN_ID_STRING2_VOLTAGE2
Definition: can_cfg.h:242
#define CAN_ID_STRING1_TEMPERATURE
Definition: can_cfg.h:234
#define CAN_ID_STRING2_CURRENT_COUNTER
Definition: can_cfg.h:246
#define CAN_ID_STRING0_CURRENT_COUNTER
Definition: can_cfg.h:226
#define CAN_ID_STRING0_TEMPERATURE
Definition: can_cfg.h:224
#define CAN_ID_STRING0_VOLTAGE3
Definition: can_cfg.h:223
#define CAN_ID_STRING1_VOLTAGE3
Definition: can_cfg.h:233
#define CAN_ID_STRING1_CURRENT_COUNTER
Definition: can_cfg.h:236
#define CAN_ID_STRING1_ENERGY_COUNTER
Definition: can_cfg.h:237
#define CAN_ID_STRING0_VOLTAGE2
Definition: can_cfg.h:222
#define CAN_ID_STRING2_VOLTAGE1
Definition: can_cfg.h:241
#define CAN_ID_STRING1_CURRENT
Definition: can_cfg.h:230
#define CAN_ID_STRING2_ENERGY_COUNTER
Definition: can_cfg.h:247
#define CAN_ID_STRING2_POWER
Definition: can_cfg.h:245
#define CAN_ID_STRING1_VOLTAGE2
Definition: can_cfg.h:232
#define CAN_ID_STRING2_VOLTAGE3
Definition: can_cfg.h:243
#define CAN_ID_STRING0_VOLTAGE1
Definition: can_cfg.h:221
#define CAN_MAX_DLC
Definition: can_cfg.h:88
#define CAN_ID_STRING0_POWER
Definition: can_cfg.h:225
#define CAN_ID_STRING1_POWER
Definition: can_cfg.h:235
#define CAN_ID_STRING2_CURRENT
Definition: can_cfg.h:240
#define CAN_ID_STRING0_ENERGY_COUNTER
Definition: can_cfg.h:227
void CAN_RxGetMessageDataFromCanData(uint64_t *pMessage, const uint8_t *const kpkCanData, CAN_ENDIANNESS_e endianness)
Copy CAN data from 8 bytes to a 64-bit variable.
Definition: can_helper.c:289
void CAN_RxGetSignalDataFromMessageData(uint64_t message, uint64_t bitStart, uint8_t bitLength, uint64_t *pCanSignal, CAN_ENDIANNESS_e endianness)
Gets CAN signal data from a 64-bit variable. This function is used to get signal data from a 64-bit C...
Definition: can_helper.c:249
Headers for the helper functions for the CAN module.
#define DATA_WRITE_DATA(...)
Definition: database.h:93
#define FAS_ASSERT(x)
Assertion macro that asserts that x is true.
Definition: fassert.h:252
#define FAS_TRAP
Define that evaluates to essential boolean false thus tripping an assert.
Definition: fassert.h:126
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:76
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:139
DATA_BLOCK_CURRENT_SENSOR_s * pTableCurrentSensor
Definition: can_cfg.h:316
uint8_t bitLength
Definition: can_helper.h:82
uint8_t bitStart
Definition: can_helper.h:81
uint32_t previousTimestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:215
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:216
uint32_t previousTimestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:237
int32_t current_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:212
uint32_t timestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:239
uint32_t previousTimestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:222
uint8_t invalidSensorTemperatureMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:218
int32_t energyCounter_Wh[BS_NR_OF_STRINGS]
Definition: database_cfg.h:228
uint32_t timestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:223
uint32_t previousTimestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:230
int32_t highVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:234
uint8_t invalidCurrentMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:213
uint8_t invalidHighVoltageMeasurement[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:233
uint8_t invalidCurrentCountingMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:225
uint32_t timestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:231
int32_t power_W[BS_NR_OF_STRINGS]
Definition: database_cfg.h:219
int32_t currentCounter_As[BS_NR_OF_STRINGS]
Definition: database_cfg.h:224
uint32_t timestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:227
int32_t sensorTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:217
uint32_t previousTimestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:226
uint8_t invalidPowerMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:220
uint8_t invalidEnergyCountingMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:229