foxBMS  1.2.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 - 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 can_cbs_rx_current_sensor.c
44  * @author foxBMS Team
45  * @date 2021-04-20 (date of creation)
46  * @updated 2021-06-09 (date of last update)
47  * @ingroup DRIVER
48  * @prefix CAN
49  *
50  * @brief CAN driver Rx callback implementation
51  * @details CAN Rx callback for current sensor measurements
52  */
53 
54 /*========== Includes =======================================================*/
55 #include "can_cbs.h"
56 #include "can_helper.h"
57 
58 /*========== Macros and Definitions =========================================*/
59 
60 /* Overcurrent flag */
61 #define CAN_currentSensorDiagOcs (0x1u)
62 /* Actual measurement error flag */
63 #define CAN_currentSensorDiagActualMeasurementError (0x2u)
64 /* Any measurement error flag */
65 #define CAN_currentSensorDiagAnyMeasurementError (0x4u)
66 /* System error flag */
67 #define CAN_currentSensorDiagSystemError (0x8u)
68 
69 /*========== Static Constant and Variable Definitions =======================*/
70 
71 /**
72  * CAN signals used in this message
73  * Parameters:
74  * bit start, bit length, factor, offset, minimum value, maximum value
75  */
76 static const CAN_SIGNAL_TYPE_s currentSensorStatus = {7u, 8u, 1.0f, 0.0f, 0.0f, 255.0f};
77 static const CAN_SIGNAL_TYPE_s currentSensorData = {23u, 32u, 1.0f, 0.0f, -2147483648.0f, 2147483648.0f};
78 
79 /*========== Extern Constant and Variable Definitions =======================*/
80 
81 /*========== Static Function Prototypes =====================================*/
82 
83 /*========== Static Function Implementations ================================*/
84 
85 /*========== Extern Function Implementations ================================*/
86 extern uint32_t CAN_RxCurrentSensor(
87  uint32_t id,
88  uint8_t dlc,
89  CAN_ENDIANNESS_e endianness,
90  uint8_t *pCanData,
91  uint8_t *pMuxId,
92  const CAN_SHIM_s *const kpkCanShim) {
93  /* pMuxId is unused in this callback, therefore has to be a NULL_PTR */
94  FAS_ASSERT(pMuxId == NULL_PTR);
95 
96  FAS_ASSERT(id < CAN_MAX_11BIT_ID); /* Currently standard ID, 11 bit */
97  FAS_ASSERT(dlc <= CAN_MAX_DLC); /* Currently max 8 bytes in a CAN frame */
98  FAS_ASSERT(pCanData != NULL_PTR);
99  FAS_ASSERT(kpkCanShim != NULL_PTR);
100  uint64_t message = 0u;
101  uint64_t canSignal = 0u;
102 
103  int32_t sensorSignalValue = 0;
104  uint8_t diagInfo = 0u;
105  uint8_t stringNumber = 0u;
106 
107  if (id <= CAN_ID_STRING0_ENERGY_COUNTER) {
108  stringNumber = 0u;
109  } else if (id <= CAN_ID_STRING1_ENERGY_COUNTER) {
110  stringNumber = 1u;
111  } else {
112  stringNumber = 2u;
113  }
114 
115  CAN_RxGetMessageDataFromCanData(&message, pCanData, endianness);
116 
117  /* Get status*/
119  message, currentSensorStatus.bitStart, currentSensorStatus.bitLength, &canSignal, endianness);
120 
121  /* only high nibble contains diag info */
122  diagInfo = canSignal & 0xF0u;
123  diagInfo >>= 4u;
124 
125  if ((diagInfo & CAN_currentSensorDiagOcs) != 0u) {
126  /* Overcurrent detected. This feature is currently not supported. */
127  }
128  if ((diagInfo & CAN_currentSensorDiagActualMeasurementError) != 0u) {
129  switch (id) {
130  case CAN_ID_STRING0_CURRENT: /* Current status */
133  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 1;
134  break;
135  case CAN_ID_STRING0_VOLTAGE1: /* Voltage status */
138  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 1;
139  break;
143  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 1;
144  break;
148  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 1;
149  break;
150  case CAN_ID_STRING0_TEMPERATURE: /* Temperature status */
153  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 1;
154  break;
155  case CAN_ID_STRING0_POWER: /* Power status */
158  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 1;
159  break;
160  case CAN_ID_STRING0_CURRENT_COUNTER: /* CC status */
163  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 1;
164  break;
165  case CAN_ID_STRING0_ENERGY_COUNTER: /* EC status */
168  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 1;
169  break;
170  default:
171  /* No error detected */
172  break;
173  }
174  } else {
175  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 0;
176  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 0;
177  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 0;
178  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 0;
179  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 0;
180  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 0;
181  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 0;
182  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 0;
183  }
184 
185  if (((diagInfo & CAN_currentSensorDiagAnyMeasurementError) != 0u) ||
186  ((diagInfo & CAN_currentSensorDiagSystemError) != 0u)) {
187  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 1;
188  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 1;
189  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 1;
190  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 1;
191  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 1;
192  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 1;
193  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 1;
194  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 1;
195  }
196 
197  /* Get measurement */
199  message, currentSensorData.bitStart, currentSensorData.bitLength, &canSignal, endianness);
200  switch (id) {
201  /* Current measurement */
205  sensorSignalValue = (int32_t)canSignal;
206  kpkCanShim->pTableCurrentSensor->current_mA[stringNumber] = sensorSignalValue;
207  kpkCanShim->pTableCurrentSensor->newCurrent++;
208  kpkCanShim->pTableCurrentSensor->previousTimestampCurrent[stringNumber] =
209  kpkCanShim->pTableCurrentSensor->timestampCurrent[stringNumber];
210  kpkCanShim->pTableCurrentSensor->timestampCurrent[stringNumber] = OS_GetTickCount();
211  break;
212  /* Voltage measurement U1 */
216  sensorSignalValue = (int32_t)canSignal;
217  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][0] = sensorSignalValue;
218  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][0] =
219  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][0];
220  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][0] = OS_GetTickCount();
221  break;
222  /* Voltage measurement U2 */
226  sensorSignalValue = (int32_t)canSignal;
227  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][1] = sensorSignalValue;
228  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][1] =
229  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][1];
230  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][1] = OS_GetTickCount();
231  break;
232  /* Voltage measurement U3 */
236  sensorSignalValue = (int32_t)canSignal;
237  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][2] = sensorSignalValue;
238  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][2] =
239  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][2];
240  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][2] = OS_GetTickCount();
241  break;
242  /* Temperature measurement */
246  sensorSignalValue = (int32_t)canSignal;
247  kpkCanShim->pTableCurrentSensor->sensorTemperature_ddegC[stringNumber] = sensorSignalValue;
248  break;
249  /* Power measurement */
253  sensorSignalValue = (int32_t)canSignal;
254  kpkCanShim->pTableCurrentSensor->power_W[stringNumber] = sensorSignalValue;
255  kpkCanShim->pTableCurrentSensor->newPower++;
256  kpkCanShim->pTableCurrentSensor->previousTimestampPower[stringNumber] =
257  kpkCanShim->pTableCurrentSensor->timestampPower[stringNumber];
258  kpkCanShim->pTableCurrentSensor->timestampPower[stringNumber] = OS_GetTickCount();
259  break;
260  /* CC measurement */
264  sensorSignalValue = (int32_t)canSignal;
265  kpkCanShim->pTableCurrentSensor->previousTimestampCurrentCounting[stringNumber] =
266  kpkCanShim->pTableCurrentSensor->timestampCurrentCounting[stringNumber];
267  kpkCanShim->pTableCurrentSensor->timestampCurrentCounting[stringNumber] = OS_GetTickCount();
268  kpkCanShim->pTableCurrentSensor->currentCounter_As[stringNumber] = sensorSignalValue;
269  break;
270  /* EC measurement */
274  sensorSignalValue = (int32_t)canSignal;
275  kpkCanShim->pTableCurrentSensor->energyCounter_Wh[stringNumber] = sensorSignalValue;
276  kpkCanShim->pTableCurrentSensor->previousTimestampEnergyCounting[stringNumber] =
277  kpkCanShim->pTableCurrentSensor->timestampEnergyCounting[stringNumber];
278  kpkCanShim->pTableCurrentSensor->timestampEnergyCounting[stringNumber] = OS_GetTickCount();
279  break;
280 
281  default:
283  break;
284  }
285 
287  return 0;
288 }
289 
290 /*========== Externalized Static Function Implementations (Unit Test) =======*/
291 #ifdef UNITY_UNIT_TEST
292 
293 #endif
CAN callbacks header.
static const CAN_SIGNAL_TYPE_s currentSensorData
static const CAN_SIGNAL_TYPE_s currentSensorStatus
#define CAN_currentSensorDiagActualMeasurementError
uint32_t CAN_RxCurrentSensor(uint32_t id, uint8_t dlc, CAN_ENDIANNESS_e endianness, uint8_t *pCanData, uint8_t *pMuxId, const CAN_SHIM_s *const kpkCanShim)
can rx callback function for current sensor measurements
#define CAN_currentSensorDiagOcs
#define CAN_currentSensorDiagAnyMeasurementError
#define CAN_currentSensorDiagSystemError
#define CAN_ID_STRING1_VOLTAGE1
Definition: can_cfg.h:223
#define CAN_ID_STRING0_CURRENT
Definition: can_cfg.h:212
#define CAN_ID_STRING2_TEMPERATURE
Definition: can_cfg.h:236
#define CAN_MAX_11BIT_ID
Definition: can_cfg.h:85
#define CAN_ID_STRING2_VOLTAGE2
Definition: can_cfg.h:234
#define CAN_ID_STRING1_TEMPERATURE
Definition: can_cfg.h:226
#define CAN_ID_STRING2_CURRENT_COUNTER
Definition: can_cfg.h:238
#define CAN_ID_STRING0_CURRENT_COUNTER
Definition: can_cfg.h:218
#define CAN_ID_STRING0_TEMPERATURE
Definition: can_cfg.h:216
enum CAN_ENDIANNESS CAN_ENDIANNESS_e
#define CAN_ID_STRING0_VOLTAGE3
Definition: can_cfg.h:215
#define CAN_ID_STRING1_VOLTAGE3
Definition: can_cfg.h:225
#define CAN_ID_STRING1_CURRENT_COUNTER
Definition: can_cfg.h:228
#define CAN_ID_STRING1_ENERGY_COUNTER
Definition: can_cfg.h:229
#define CAN_ID_STRING0_VOLTAGE2
Definition: can_cfg.h:214
#define CAN_ID_STRING2_VOLTAGE1
Definition: can_cfg.h:233
#define CAN_ID_STRING1_CURRENT
Definition: can_cfg.h:222
#define CAN_ID_STRING2_ENERGY_COUNTER
Definition: can_cfg.h:239
#define CAN_ID_STRING2_POWER
Definition: can_cfg.h:237
#define CAN_ID_STRING1_VOLTAGE2
Definition: can_cfg.h:224
#define CAN_ID_STRING2_VOLTAGE3
Definition: can_cfg.h:235
#define CAN_ID_STRING0_VOLTAGE1
Definition: can_cfg.h:213
#define CAN_MAX_DLC
Definition: can_cfg.h:87
#define CAN_ID_STRING0_POWER
Definition: can_cfg.h:217
#define CAN_ID_STRING1_POWER
Definition: can_cfg.h:227
#define CAN_ID_STRING2_CURRENT
Definition: can_cfg.h:232
#define CAN_ID_STRING0_ENERGY_COUNTER
Definition: can_cfg.h:219
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:288
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:248
Headers for the helper functions for the CAN module.
#define DATA_WRITE_DATA(...)
Definition: database.h:86
#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
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:66
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os.c:182
DATA_BLOCK_CURRENT_SENSOR_s * pTableCurrentSensor
Definition: can_cfg.h:308
uint8_t bitStart
Definition: can_helper.h:80
uint8_t bitLength
Definition: can_helper.h:81
uint8_t invalidCurrentMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:204
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:207
uint32_t previousTimestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:217
uint32_t timestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:214
int32_t power_W[BS_NR_OF_STRINGS]
Definition: database_cfg.h:210
uint8_t invalidSensorTemperatureMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:209
uint8_t invalidHighVoltageMeasurement[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:224
uint32_t previousTimestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:213
int32_t current_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:203
uint8_t invalidCurrentCountingMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:216
uint32_t timestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:230
uint8_t invalidPowerMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:211
uint32_t previousTimestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:228
int32_t sensorTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:208
uint32_t timestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:222
int32_t currentCounter_As[BS_NR_OF_STRINGS]
Definition: database_cfg.h:215
int32_t highVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:225
uint8_t invalidEnergyCountingMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:220
uint32_t previousTimestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:221
int32_t energyCounter_Wh[BS_NR_OF_STRINGS]
Definition: database_cfg.h:219
uint32_t timestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:218
uint32_t previousTimestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:206