foxBMS  1.6.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 - 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 can_cbs_rx_current-sensor.c
44  * @author foxBMS Team
45  * @date 2021-04-20 (date of creation)
46  * @updated 2023-10-12 (date of last update)
47  * @version v1.6.0
48  * @ingroup DRIVER
49  * @prefix CANRX
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_rx.h"
58 #include "can_helper.h"
59 
60 #include <stdint.h>
61 
62 /*========== Macros and Definitions =========================================*/
63 
64 /** Overcurrent flag */
65 #define CANRX_CURRENT_SENSOR_DIAGNOSIS_OVERCURRENT_BITMASK (0x1u)
66 /** Actual measurement error flag */
67 #define CANRX_CURRENT_SENSOR_DIAGNOSIS_ACTUAL_MEASUREMENT_ERROR_BITMASK (0x2u)
68 /** Any measurement error flag */
69 #define CANRX_CURRENT_SENSOR_DIAGNOSIS_ANY_MEASUREMENT_ERROR_BITMASK (0x4u)
70 /** System error flag */
71 #define CANRX_CURRENT_SENSOR_DIAGNOSIS_SYSTEM_ERROR_BITMASK (0x8u)
72 
73 /*========== Static Constant and Variable Definitions =======================*/
74 
75 /*========== Extern Constant and Variable Definitions =======================*/
76 
77 /*========== Static Function Prototypes =====================================*/
78 
79 /*========== Static Function Implementations ================================*/
80 
81 /*========== Extern Function Implementations ================================*/
82 extern uint32_t CANRX_CurrentSensor(
84  const uint8_t *const kpkCanData,
85  const CAN_SHIM_s *const kpkCanShim) {
89  FAS_ASSERT(kpkCanData != NULL_PTR);
90  FAS_ASSERT(kpkCanShim != NULL_PTR);
91 
92  /**
93  * CAN signals used in this message
94  * Parameters:
95  * bit start, bit length, factor, offset, minimum value, maximum value
96  */
97  const CAN_SIGNAL_TYPE_s currentSensorStatus = {7u, 8u, 1.0f, 0.0f, 0.0f, 255.0f};
98  const CAN_SIGNAL_TYPE_s currentSensorData = {23u, 32u, 1.0f, 0.0f, -2147483648.0f, 2147483648.0f};
99 
100  uint64_t messageData = 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 (message.id <= CANRX_STRING0_ENERGY_COUNTER_ID) {
108  stringNumber = 0u;
109  }
110 
111  CAN_RxGetMessageDataFromCanData(&messageData, kpkCanData, message.endianness);
112 
113  /* Get status*/
115  messageData, currentSensorStatus.bitStart, currentSensorStatus.bitLength, &canSignal, message.endianness);
116 
117  /* only high nibble contains diag info */
118  diagInfo = canSignal & 0xF0u;
119  diagInfo >>= 4u;
120 
122  /* Overcurrent detected. This feature is currently not supported. */
123  }
125  switch (message.id) {
126  case CANRX_STRING0_CURRENT_ID: /* Current status */
127  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 1;
128  break;
129  case CANRX_STRING0_VOLTAGE1_ID: /* Voltage status */
130  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 1;
131  break;
133  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 1;
134  break;
136  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 1;
137  break;
138  case CANRX_STRING0_TEMPERATURE_ID: /* Temperature status */
139  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 1;
140  break;
141  case CANRX_STRING0_POWER_ID: /* Power status */
142  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 1;
143  break;
144  case CANRX_STRING0_CURRENT_COUNTER_ID: /* CC status */
145  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 1;
146  break;
147  case CANRX_STRING0_ENERGY_COUNTER_ID: /* EC status */
148  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 1;
149  break;
150  default:
151  /* No error detected */
152  break;
153  }
154  } else {
155  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 0;
156  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 0;
157  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 0;
158  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 0;
159  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 0;
160  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 0;
161  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 0;
162  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 0;
163  }
164 
167  kpkCanShim->pTableCurrentSensor->invalidCurrentMeasurement[stringNumber] = 1;
168  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][0] = 1;
169  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][1] = 1;
170  kpkCanShim->pTableCurrentSensor->invalidHighVoltageMeasurement[stringNumber][2] = 1;
171  kpkCanShim->pTableCurrentSensor->invalidSensorTemperatureMeasurement[stringNumber] = 1;
172  kpkCanShim->pTableCurrentSensor->invalidPowerMeasurement[stringNumber] = 1;
173  kpkCanShim->pTableCurrentSensor->invalidCurrentCountingMeasurement[stringNumber] = 1;
174  kpkCanShim->pTableCurrentSensor->invalidEnergyCountingMeasurement[stringNumber] = 1;
175  }
176 
177  /* Get measurement */
179  messageData, currentSensorData.bitStart, currentSensorData.bitLength, &canSignal, message.endianness);
180  switch (message.id) {
181  /* Current measurement */
183  sensorSignalValue = (int32_t)canSignal;
184  kpkCanShim->pTableCurrentSensor->current_mA[stringNumber] = sensorSignalValue;
185  kpkCanShim->pTableCurrentSensor->newCurrent++;
186  kpkCanShim->pTableCurrentSensor->previousTimestampCurrent[stringNumber] =
187  kpkCanShim->pTableCurrentSensor->timestampCurrent[stringNumber];
188  kpkCanShim->pTableCurrentSensor->timestampCurrent[stringNumber] = OS_GetTickCount();
189  break;
190  /* Voltage measurement U1 */
192  sensorSignalValue = (int32_t)canSignal;
193  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][0] = sensorSignalValue;
194  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][0] =
195  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][0];
196  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][0] = OS_GetTickCount();
197  break;
198  /* Voltage measurement U2 */
200  sensorSignalValue = (int32_t)canSignal;
201  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][1] = sensorSignalValue;
202  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][1] =
203  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][1];
204  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][1] = OS_GetTickCount();
205  break;
206  /* Voltage measurement U3 */
208  sensorSignalValue = (int32_t)canSignal;
209  kpkCanShim->pTableCurrentSensor->highVoltage_mV[stringNumber][2] = sensorSignalValue;
210  kpkCanShim->pTableCurrentSensor->previousTimestampHighVoltage[stringNumber][2] =
211  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][2];
212  kpkCanShim->pTableCurrentSensor->timestampHighVoltage[stringNumber][2] = OS_GetTickCount();
213  break;
214  /* Temperature measurement */
216  sensorSignalValue = (int32_t)canSignal;
217  kpkCanShim->pTableCurrentSensor->sensorTemperature_ddegC[stringNumber] = sensorSignalValue;
218  break;
219  /* Power measurement */
221  sensorSignalValue = (int32_t)canSignal;
222  kpkCanShim->pTableCurrentSensor->power_W[stringNumber] = sensorSignalValue;
223  kpkCanShim->pTableCurrentSensor->newPower++;
224  kpkCanShim->pTableCurrentSensor->previousTimestampPower[stringNumber] =
225  kpkCanShim->pTableCurrentSensor->timestampPower[stringNumber];
226  kpkCanShim->pTableCurrentSensor->timestampPower[stringNumber] = OS_GetTickCount();
227  break;
228  /* CC measurement */
230  sensorSignalValue = (int32_t)canSignal;
231  kpkCanShim->pTableCurrentSensor->previousTimestampCurrentCounting[stringNumber] =
232  kpkCanShim->pTableCurrentSensor->timestampCurrentCounting[stringNumber];
233  kpkCanShim->pTableCurrentSensor->timestampCurrentCounting[stringNumber] = OS_GetTickCount();
234  kpkCanShim->pTableCurrentSensor->currentCounter_As[stringNumber] = sensorSignalValue;
235  break;
236  /* EC measurement */
238  sensorSignalValue = (int32_t)canSignal;
239  kpkCanShim->pTableCurrentSensor->energyCounter_Wh[stringNumber] = sensorSignalValue;
240  kpkCanShim->pTableCurrentSensor->previousTimestampEnergyCounting[stringNumber] =
241  kpkCanShim->pTableCurrentSensor->timestampEnergyCounting[stringNumber];
242  kpkCanShim->pTableCurrentSensor->timestampEnergyCounting[stringNumber] = OS_GetTickCount();
243  break;
244 
245  default:
247  break; /* LCOV_EXCL_LINE */
248  }
249 
251  return 0;
252 }
253 
254 /*========== Externalized Static Function Implementations (Unit Test) =======*/
255 #ifdef UNITY_UNIT_TEST
256 #endif
CAN callbacks header.
#define CANRX_CURRENT_SENSOR_DIAGNOSIS_SYSTEM_ERROR_BITMASK
#define CANRX_CURRENT_SENSOR_DIAGNOSIS_ANY_MEASUREMENT_ERROR_BITMASK
uint32_t CANRX_CurrentSensor(CAN_MESSAGE_PROPERTIES_s message, const uint8_t *const kpkCanData, const CAN_SHIM_s *const kpkCanShim)
can rx callback function for current sensor measurements
#define CANRX_CURRENT_SENSOR_DIAGNOSIS_ACTUAL_MEASUREMENT_ERROR_BITMASK
#define CANRX_CURRENT_SENSOR_DIAGNOSIS_OVERCURRENT_BITMASK
Header for the driver for the CAN module.
#define CANRX_STRING0_POWER_ID
#define CANRX_STRING0_VOLTAGE2_ID
#define CANRX_STRING0_ENERGY_COUNTER_ID
#define CANRX_STRING0_CURRENT_COUNTER_ID
#define CANRX_STRING0_CURRENT_ID
#define CANRX_STRING0_VOLTAGE1_ID
#define CANRX_CURRENT_SENSOR_MESSAGES_DLC
#define CANRX_CURRENT_SENSOR_MESSAGES_ID_TYPE
#define CANRX_STRING0_VOLTAGE3_ID
#define CANRX_STRING0_TEMPERATURE_ID
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:295
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:255
Headers for the helper functions for the CAN module.
#define DATA_WRITE_DATA(...)
Definition: database.h:96
#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
#define NULL_PTR
Null pointer.
Definition: fstd_types.h:77
uint32_t OS_GetTickCount(void)
Returns OS based system tick value.
Definition: os_freertos.c:158
CAN_IDENTIFIER_TYPE_e idType
Definition: can_cfg.h:201
CAN_ENDIANNESS_e endianness
Definition: can_cfg.h:203
DATA_BLOCK_CURRENT_SENSOR_s * pTableCurrentSensor
Definition: can_cfg.h:181
uint8_t bitLength
Definition: can_helper.h:84
uint8_t bitStart
Definition: can_helper.h:83
uint32_t previousTimestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:223
uint32_t timestampCurrent[BS_NR_OF_STRINGS]
Definition: database_cfg.h:224
uint32_t previousTimestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:245
int32_t current_mA[BS_NR_OF_STRINGS]
Definition: database_cfg.h:220
uint32_t timestampHighVoltage[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:247
uint32_t previousTimestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:230
uint8_t invalidSensorTemperatureMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:226
int32_t energyCounter_Wh[BS_NR_OF_STRINGS]
Definition: database_cfg.h:236
uint32_t timestampPower[BS_NR_OF_STRINGS]
Definition: database_cfg.h:231
uint32_t previousTimestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:238
int32_t highVoltage_mV[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:242
uint8_t invalidCurrentMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:221
uint8_t invalidHighVoltageMeasurement[BS_NR_OF_STRINGS][BS_NR_OF_VOLTAGES_FROM_CURRENT_SENSOR]
Definition: database_cfg.h:241
uint8_t invalidCurrentCountingMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:233
uint32_t timestampEnergyCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:239
int32_t power_W[BS_NR_OF_STRINGS]
Definition: database_cfg.h:227
int32_t currentCounter_As[BS_NR_OF_STRINGS]
Definition: database_cfg.h:232
uint32_t timestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:235
int32_t sensorTemperature_ddegC[BS_NR_OF_STRINGS]
Definition: database_cfg.h:225
uint32_t previousTimestampCurrentCounting[BS_NR_OF_STRINGS]
Definition: database_cfg.h:234
uint8_t invalidPowerMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:228
uint8_t invalidEnergyCountingMeasurement[BS_NR_OF_STRINGS]
Definition: database_cfg.h:237